610 lines
17 KiB
C
610 lines
17 KiB
C
/*
|
|
* wview_x11.c - X11 view backend for WINGs
|
|
*
|
|
* Implements W_ViewBackend using Xlib calls.
|
|
*/
|
|
|
|
#include "WINGsP.h"
|
|
#include "WINGs/WINGsX11.h"
|
|
#include "wwindow_p.h"
|
|
#include <X11/Xresource.h>
|
|
#include <X11/Xatom.h>
|
|
#include "../src/GNUstep.h"
|
|
|
|
extern void W_X11PlatformInit(W_Screen *scr);
|
|
|
|
static XContext ViewContext = 0;
|
|
|
|
static void *x11_screen_init(W_Screen *scr)
|
|
{
|
|
if (ViewContext == 0)
|
|
ViewContext = XUniqueContext();
|
|
return scr; /* no separate context needed; use scr as token */
|
|
}
|
|
|
|
static void x11_screen_fini(void *vctx)
|
|
{
|
|
(void)vctx;
|
|
}
|
|
|
|
static void x11_create_root(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
/* Always use the real root window as parent for toplevel windows,
|
|
* even when RContext->drawable is an intermediate window created
|
|
* for a non-default visual. Otherwise MapRequest won't reach the
|
|
* window manager (which selects SubstructureRedirect on root). */
|
|
view->window = RootWindow(scr->display, scr->screen);
|
|
view->size.width = WidthOfScreen(ScreenOfDisplay(scr->display, scr->screen));
|
|
view->size.height = HeightOfScreen(ScreenOfDisplay(scr->display, scr->screen));
|
|
}
|
|
|
|
static void x11_realize(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
Display *dpy = scr->display;
|
|
Window parentWID = view->parent->window;
|
|
|
|
/* Build XSetWindowAttributes from the backend-neutral W_View
|
|
* attribs. W_View.attribs no longer has the X11 layout (so the
|
|
* shared header can be Xlib-free); copy field-by-field here. */
|
|
XSetWindowAttributes xattribs;
|
|
memset(&xattribs, 0, sizeof(xattribs));
|
|
xattribs.background_pixmap = view->attribs.background_pixmap;
|
|
xattribs.background_pixel = view->attribs.background_pixel;
|
|
xattribs.border_pixel = view->attribs.border_pixel;
|
|
xattribs.colormap = view->attribs.colormap;
|
|
xattribs.cursor = view->attribs.cursor;
|
|
xattribs.override_redirect = view->attribs.override_redirect;
|
|
xattribs.save_under = view->attribs.save_under;
|
|
xattribs.event_mask = view->attribs.event_mask;
|
|
xattribs.do_not_propagate_mask = view->attribs.do_not_propagate_mask;
|
|
xattribs.bit_gravity = NorthWestGravity;
|
|
xattribs.win_gravity = NorthWestGravity;
|
|
xattribs.backing_store = NotUseful;
|
|
|
|
view->window = XCreateWindow(dpy, parentWID, view->pos.x, view->pos.y,
|
|
view->size.width, view->size.height, 0,
|
|
scr->depth, InputOutput,
|
|
scr->visual, view->attribFlags, &xattribs);
|
|
|
|
XSaveContext(dpy, view->window, ViewContext, (XPointer)view);
|
|
}
|
|
|
|
static void x11_map(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XMapRaised(scr->display, view->window);
|
|
XFlush(scr->display);
|
|
}
|
|
|
|
static void x11_unmap(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XUnmapWindow(scr->display, view->window);
|
|
XFlush(scr->display);
|
|
}
|
|
|
|
static void x11_map_subviews(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XMapSubwindows(scr->display, view->window);
|
|
XFlush(scr->display);
|
|
}
|
|
|
|
static void x11_unmap_subviews(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XUnmapSubwindows(scr->display, view->window);
|
|
XFlush(scr->display);
|
|
}
|
|
|
|
static void x11_move(void *vctx, W_View *view, int x, int y)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XMoveWindow(scr->display, view->window, x, y);
|
|
}
|
|
|
|
static void x11_resize(void *vctx, W_View *view, unsigned int w, unsigned int h)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XResizeWindow(scr->display, view->window, w, h);
|
|
}
|
|
|
|
static void x11_raise(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XRaiseWindow(scr->display, view->window);
|
|
}
|
|
|
|
static void x11_lower(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XLowerWindow(scr->display, view->window);
|
|
}
|
|
|
|
static void x11_reparent(void *vctx, W_View *view, W_View *newParent, int x, int y)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XReparentWindow(scr->display, view->window, newParent->window, x, y);
|
|
}
|
|
|
|
static void x11_destroy(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XDeleteContext(scr->display, view->window, ViewContext);
|
|
if (!view->flags.parentDying || view->flags.topLevel)
|
|
XDestroyWindow(scr->display, view->window);
|
|
}
|
|
|
|
static void x11_set_background_color(void *vctx, W_View *view, WMColor *color)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XSetWindowBackground(scr->display, view->window, W_PIXEL(color));
|
|
XClearWindow(scr->display, view->window);
|
|
}
|
|
|
|
static void x11_set_cursor(void *vctx, W_View *view, Cursor cursor)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XDefineCursor(scr->display, view->window, cursor);
|
|
}
|
|
|
|
static void x11_redisplay(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
XEvent xev;
|
|
WMEvent ev;
|
|
|
|
memset(&xev, 0, sizeof(xev));
|
|
xev.xexpose.type = Expose;
|
|
xev.xexpose.display = scr->display;
|
|
xev.xexpose.window = view->window;
|
|
xev.xexpose.count = 0;
|
|
xev.xexpose.serial = 0;
|
|
|
|
memset(&ev, 0, sizeof(ev));
|
|
ev.type = WME_EXPOSE;
|
|
ev.window = (WNativeWindow)view->window;
|
|
ev.u.expose.window = (WNativeWindow)view->window;
|
|
ev.u.expose.count = 0;
|
|
ev._x11_raw = &xev;
|
|
ev._view_target = view;
|
|
|
|
WMHandleEvent(&ev);
|
|
}
|
|
|
|
static WMPoint x11_get_screen_position(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
Window foo;
|
|
int x, y, topX, topY;
|
|
unsigned int bar;
|
|
W_View *topView;
|
|
|
|
topView = view;
|
|
while (topView->parent && topView->parent != scr->rootView)
|
|
topView = topView->parent;
|
|
|
|
if (!XGetGeometry(scr->display, topView->window, &foo, &topX, &topY, &bar, &bar, &bar, &bar)) {
|
|
topX = topY = 0;
|
|
}
|
|
|
|
XTranslateCoordinates(scr->display, view->window, scr->rootWin, 0, 0, &x, &y, &foo);
|
|
|
|
return wmkpoint(x - topX, y - topY);
|
|
}
|
|
|
|
W_View *W_GetViewForXWindow(Display *display, Window window)
|
|
{
|
|
W_View *view;
|
|
|
|
if (ViewContext == 0)
|
|
return NULL;
|
|
if (XFindContext(display, window, ViewContext, (XPointer *)&view) == 0)
|
|
return view;
|
|
return NULL;
|
|
}
|
|
|
|
static Bool x11_selection_acquire(void *vctx, W_View *view, Atom selection, Time timestamp)
|
|
{
|
|
(void)vctx;
|
|
Display *dpy = view->screen->display;
|
|
XSetSelectionOwner(dpy, selection, W_VIEW_DRAWABLE(view), timestamp);
|
|
return (XGetSelectionOwner(dpy, selection) == W_VIEW_DRAWABLE(view));
|
|
}
|
|
|
|
static void x11_selection_release(void *vctx, W_View *view, Atom selection)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
Display *dpy = scr->display;
|
|
Window win = W_VIEW_DRAWABLE(view);
|
|
XGrabServer(dpy);
|
|
if (XGetSelectionOwner(dpy, selection) == win)
|
|
XSetSelectionOwner(dpy, selection, WM_NATIVE_NONE, WM_CURRENT_TIME);
|
|
XUngrabServer(dpy);
|
|
}
|
|
|
|
static Bool x11_selection_request(void *vctx, W_View *view, Atom selection, Atom target, Time timestamp)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
Display *dpy = scr->display;
|
|
if (XGetSelectionOwner(dpy, selection) == WM_NATIVE_NONE)
|
|
return False;
|
|
return XConvertSelection(dpy, selection, target,
|
|
scr->clipboardAtom, W_VIEW_DRAWABLE(view), timestamp) != 0;
|
|
}
|
|
|
|
static void x11_clipboard_store(void *vctx, const char *text, int len)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
XStoreBuffer(scr->display, text, len, 0);
|
|
}
|
|
|
|
static char *x11_clipboard_fetch(void *vctx, int *len_out)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
int n = 0;
|
|
char *xtext = XFetchBuffer(scr->display, &n, 0);
|
|
if (!xtext || n <= 0) {
|
|
if (len_out)
|
|
*len_out = 0;
|
|
return NULL;
|
|
}
|
|
char *copy = wmalloc(n + 1);
|
|
memcpy(copy, xtext, n);
|
|
copy[n] = '\0';
|
|
XFree(xtext);
|
|
if (len_out)
|
|
*len_out = n;
|
|
return copy;
|
|
}
|
|
|
|
static void x11_pointer_grab(void *vctx, W_View *view, int owner_events, unsigned long time)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
XGrabPointer(scr->display, view->window, owner_events,
|
|
WM_EVMASK_BUTTON_RELEASE | WM_EVMASK_BUTTON_MOTION | WM_EVMASK_ENTER_WINDOW | WM_EVMASK_LEAVE_WINDOW,
|
|
WM_GRAB_MODE_ASYNC, WM_GRAB_MODE_ASYNC, WM_NATIVE_NONE, WM_NATIVE_NONE, time);
|
|
}
|
|
|
|
static void x11_pointer_ungrab(void *vctx, unsigned long time)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
XUngrabPointer(scr->display, time);
|
|
}
|
|
|
|
static void x11_bell(void *vctx)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
XBell(scr->display, 0);
|
|
}
|
|
|
|
static Atom XA_Targets = WM_NATIVE_NONE;
|
|
static Atom XA_Format_Text = WM_NATIVE_NONE;
|
|
static Atom XA_Format_Compound_Text = WM_NATIVE_NONE;
|
|
|
|
static void x11_text_init(void *vctx, W_View *view, void *stipple_gc_out)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
Display *dpy = scr->display;
|
|
GC *gc_out = (GC *)stipple_gc_out;
|
|
XGCValues gcv;
|
|
|
|
if (XA_Targets == WM_NATIVE_NONE) {
|
|
XA_Targets = XInternAtom(dpy, "TARGETS", False);
|
|
XA_Format_Text = XInternAtom(dpy, "TEXT", False);
|
|
XA_Format_Compound_Text = XInternAtom(dpy, "COMPOUND_TEXT", False);
|
|
}
|
|
|
|
gcv.graphics_exposures = False;
|
|
gcv.foreground = W_PIXEL(scr->gray);
|
|
gcv.background = W_PIXEL(scr->darkGray);
|
|
gcv.fill_style = FillStippled;
|
|
gcv.stipple = XCreateBitmapFromData(dpy, W_DRAWABLE(scr),
|
|
"\xaa\x55\xaa\x55\xaa\x55\xaa\x55", 8, 8);
|
|
*gc_out = XCreateGC(dpy, W_DRAWABLE(scr),
|
|
GCForeground | GCBackground | GCStipple
|
|
| GCFillStyle | GCGraphicsExposures, &gcv);
|
|
}
|
|
|
|
static void x11_balloon_draw(void *vctx, W_View *view, int x, int y,
|
|
int w, int h, const char *text)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
(void)scr;
|
|
extern void W_BalloonShowText(void *bPtr, int x, int y, int w, int h, const char *text);
|
|
W_BalloonShowText(view->screen->balloon, x, y, w, h, text);
|
|
}
|
|
|
|
static void x11_flush(void *vctx)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
XFlush(scr->display);
|
|
}
|
|
|
|
static void x11_window_set_title(void *vctx, W_View *view, const char *title)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
XTextProperty property;
|
|
int result;
|
|
|
|
result = XmbTextListToTextProperty(scr->display, (char **)&title, 1, XStdICCTextStyle, &property);
|
|
if (result == XNoMemory || result == XLocaleNotSupported) {
|
|
XStoreName(scr->display, view->window, title);
|
|
} else {
|
|
XSetWMName(scr->display, view->window, &property);
|
|
if (property.value)
|
|
XFree(property.value);
|
|
}
|
|
|
|
XChangeProperty(scr->display, view->window,
|
|
scr->netwmName, scr->utf8String, 8,
|
|
PropModeReplace, (unsigned char *)title, strlen(title));
|
|
}
|
|
|
|
static void x11_window_set_icon_title(void *vctx, W_View *view, const char *title)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
XTextProperty property;
|
|
int result;
|
|
|
|
result = XmbTextListToTextProperty(scr->display, (char **)&title, 1, XStdICCTextStyle, &property);
|
|
if (result == XNoMemory || result == XLocaleNotSupported) {
|
|
XSetIconName(scr->display, view->window, title);
|
|
} else {
|
|
XSetWMIconName(scr->display, view->window, &property);
|
|
if (property.value)
|
|
XFree(property.value);
|
|
}
|
|
|
|
XChangeProperty(scr->display, view->window,
|
|
scr->netwmIconName, scr->utf8String, 8,
|
|
PropModeReplace, (unsigned char *)title, strlen(title));
|
|
}
|
|
|
|
static void x11_window_set_icon_image(void *vctx, W_View *view, RImage *image)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
unsigned long *data;
|
|
int x, y, o;
|
|
|
|
if (!image)
|
|
return;
|
|
|
|
data = wmalloc((image->width * image->height + 2) * sizeof(long));
|
|
|
|
o = 0;
|
|
data[o++] = image->width;
|
|
data[o++] = image->height;
|
|
|
|
for (y = 0; y < image->height; y++) {
|
|
for (x = 0; x < image->width; x++) {
|
|
unsigned long pixel;
|
|
int offs = (x + y * image->width);
|
|
|
|
if (image->format == RRGBFormat) {
|
|
pixel = ((unsigned long) image->data[offs * 3 ]) << 16;
|
|
pixel |= ((unsigned long) image->data[offs * 3 + 1]) << 8;
|
|
pixel |= ((unsigned long) image->data[offs * 3 + 2]);
|
|
} else {
|
|
pixel = ((unsigned long) image->data[offs * 4 ]) << 16;
|
|
pixel |= ((unsigned long) image->data[offs * 4 + 1]) << 8;
|
|
pixel |= ((unsigned long) image->data[offs * 4 + 2]);
|
|
pixel |= ((unsigned long) image->data[offs * 4 + 3]) << 24;
|
|
}
|
|
|
|
data[o++] = pixel;
|
|
}
|
|
}
|
|
|
|
XChangeProperty(scr->display, view->window, scr->netwmIcon,
|
|
XA_CARDINAL, 32, PropModeReplace,
|
|
(unsigned char *)data, (image->width * image->height + 2));
|
|
|
|
wfree(data);
|
|
}
|
|
|
|
static void x11_writeGNUstepWMAttr(W_Screen *scr, Window window, GNUstepWMAttributes *attr)
|
|
{
|
|
unsigned long data[9];
|
|
|
|
data[0] = attr->flags;
|
|
data[1] = attr->window_style;
|
|
data[2] = attr->window_level;
|
|
data[3] = 0;
|
|
data[4] = attr->miniaturize_pixmap;
|
|
data[5] = attr->close_pixmap;
|
|
data[6] = attr->miniaturize_mask;
|
|
data[7] = attr->close_mask;
|
|
data[8] = attr->extra_flags;
|
|
XChangeProperty(scr->display, window, scr->attribsAtom, scr->attribsAtom,
|
|
32, PropModeReplace, (unsigned char *)data, 9);
|
|
}
|
|
|
|
static void x11_window_realize(void *vctx, W_View *view, const char *name,
|
|
const char *class, W_View *owner)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
_Window *win = (_Window *)view->self;
|
|
XWMHints *hints;
|
|
XClassHint *classHint;
|
|
Atom atoms[4];
|
|
int count;
|
|
GNUstepWMAttributes attribs;
|
|
|
|
classHint = XAllocClassHint();
|
|
classHint->res_name = (char *)name;
|
|
classHint->res_class = (char *)class;
|
|
XSetClassHint(scr->display, view->window, classHint);
|
|
XFree(classHint);
|
|
|
|
hints = XAllocWMHints();
|
|
hints->flags = 0;
|
|
if (!scr->aflags.simpleApplication) {
|
|
hints->flags |= WindowGroupHint;
|
|
hints->window_group = scr->groupLeader;
|
|
}
|
|
if (win->miniImage) {
|
|
hints->flags |= IconPixmapHint;
|
|
hints->icon_pixmap = WMGetPixmapXID(win->miniImage);
|
|
hints->icon_mask = WMGetPixmapMaskXID(win->miniImage);
|
|
if (hints->icon_mask != WM_NATIVE_NONE) {
|
|
hints->flags |= IconMaskHint;
|
|
}
|
|
}
|
|
if (hints->flags != 0)
|
|
XSetWMHints(scr->display, view->window, hints);
|
|
XFree(hints);
|
|
|
|
count = 0;
|
|
if (win->closeAction)
|
|
atoms[count++] = scr->deleteWindowAtom;
|
|
if (count > 0)
|
|
XSetWMProtocols(scr->display, view->window, atoms, count);
|
|
|
|
if (win->title || win->miniTitle)
|
|
XmbSetWMProperties(scr->display, view->window, win->title,
|
|
win->miniTitle, NULL, 0, NULL, NULL, NULL);
|
|
|
|
/* GNUstep/Window Maker attributes */
|
|
memset(&attribs, 0, sizeof(GNUstepWMAttributes));
|
|
attribs.flags = GSWindowStyleAttr | GSWindowLevelAttr | GSExtraFlagsAttr;
|
|
if (win->minSize.width == win->maxSize.width && win->minSize.height == win->maxSize.height)
|
|
win->flags.style &= ~WMResizableWindowMask;
|
|
attribs.window_style = win->flags.style;
|
|
attribs.window_level = win->level;
|
|
attribs.extra_flags = win->flags.documentEdited ? GSDocumentEditedFlag : 0;
|
|
x11_writeGNUstepWMAttr(scr, view->window, &attribs);
|
|
|
|
if (owner)
|
|
XSetTransientForHint(scr->display, view->window, owner->window);
|
|
|
|
if (win->title)
|
|
x11_window_set_title(vctx, view, win->title);
|
|
}
|
|
|
|
static void x11_window_set_geometry(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
_Window *win = (_Window *)view->self;
|
|
XSizeHints *hints;
|
|
|
|
hints = XAllocSizeHints();
|
|
if (!hints)
|
|
return;
|
|
|
|
hints->flags = 0;
|
|
|
|
if (win->flags.setPPos) {
|
|
hints->flags |= PPosition;
|
|
hints->x = win->ppos.x;
|
|
hints->y = win->ppos.y;
|
|
}
|
|
if (win->flags.setUPos) {
|
|
hints->flags |= USPosition;
|
|
hints->x = win->upos.x;
|
|
hints->y = win->upos.y;
|
|
}
|
|
if (win->minSize.width > 0 && win->minSize.height > 0) {
|
|
hints->flags |= PMinSize;
|
|
hints->min_width = win->minSize.width;
|
|
hints->min_height = win->minSize.height;
|
|
}
|
|
if (win->maxSize.width > 0 && win->maxSize.height > 0) {
|
|
hints->flags |= PMaxSize;
|
|
hints->max_width = win->maxSize.width;
|
|
hints->max_height = win->maxSize.height;
|
|
}
|
|
if (win->baseSize.width > 0 && win->baseSize.height > 0) {
|
|
hints->flags |= PBaseSize;
|
|
hints->base_width = win->baseSize.width;
|
|
hints->base_height = win->baseSize.height;
|
|
}
|
|
if (win->resizeIncrement.width > 0 && win->resizeIncrement.height > 0) {
|
|
hints->flags |= PResizeInc;
|
|
hints->width_inc = win->resizeIncrement.width;
|
|
hints->height_inc = win->resizeIncrement.height;
|
|
}
|
|
if (win->flags.setAspect) {
|
|
hints->flags |= PAspect;
|
|
hints->min_aspect.x = win->minAspect.x;
|
|
hints->min_aspect.y = win->minAspect.y;
|
|
hints->max_aspect.x = win->maxAspect.x;
|
|
hints->max_aspect.y = win->maxAspect.y;
|
|
}
|
|
|
|
if (hints->flags)
|
|
XSetWMNormalHints(scr->display, view->window, hints);
|
|
XFree(hints);
|
|
}
|
|
|
|
static void x11_window_withdraw(void *vctx, W_View *view)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
|
|
XWithdrawWindow(scr->display, view->window, scr->screen);
|
|
}
|
|
|
|
static void x11_xor_fill_rect(void *vctx, W_View *view, int x, int y, int w, int h)
|
|
{
|
|
W_Screen *scr = (W_Screen *)vctx;
|
|
XFillRectangle(scr->display, view->window, scr->ixorGC, x, y, w, h);
|
|
}
|
|
|
|
const W_ViewBackend W_ViewBackendX11 = {
|
|
.screen_init = x11_screen_init,
|
|
.screen_fini = x11_screen_fini,
|
|
.create_root = x11_create_root,
|
|
.realize = x11_realize,
|
|
.map = x11_map,
|
|
.unmap = x11_unmap,
|
|
.map_subviews = x11_map_subviews,
|
|
.unmap_subviews = x11_unmap_subviews,
|
|
.move = x11_move,
|
|
.resize = x11_resize,
|
|
.raise = x11_raise,
|
|
.lower = x11_lower,
|
|
.reparent = x11_reparent,
|
|
.destroy = x11_destroy,
|
|
.set_background_color = x11_set_background_color,
|
|
.set_cursor = x11_set_cursor,
|
|
.redisplay = x11_redisplay,
|
|
.get_screen_position = x11_get_screen_position,
|
|
.selection_acquire = x11_selection_acquire,
|
|
.selection_release = x11_selection_release,
|
|
.selection_request = x11_selection_request,
|
|
.selection_fetch = NULL,
|
|
.platform_init = W_X11PlatformInit,
|
|
.flush = x11_flush,
|
|
.clipboard_store = x11_clipboard_store,
|
|
.clipboard_fetch = x11_clipboard_fetch,
|
|
.drag_begin = NULL,
|
|
.window_set_title = x11_window_set_title,
|
|
.window_set_icon_title = x11_window_set_icon_title,
|
|
.window_set_icon_image = x11_window_set_icon_image,
|
|
.window_realize = x11_window_realize,
|
|
.window_set_geometry = x11_window_set_geometry,
|
|
.window_withdraw = x11_window_withdraw,
|
|
.pointer_grab = x11_pointer_grab,
|
|
.pointer_ungrab = x11_pointer_ungrab,
|
|
.bell = x11_bell,
|
|
.balloon_draw = x11_balloon_draw,
|
|
.text_init = x11_text_init,
|
|
.xor_fill_rect = x11_xor_fill_rect,
|
|
.magnify_callback = W_ColorPanelMagnify,
|
|
};
|