213 lines
5.1 KiB
C
213 lines
5.1 KiB
C
/*
|
|
* wview_x11.c - X11 view backend for WINGs
|
|
*
|
|
* Implements W_ViewBackend using Xlib calls.
|
|
*/
|
|
|
|
#include "WINGsP.h"
|
|
#include <X11/Xresource.h>
|
|
|
|
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;
|
|
|
|
view->window = scr->rootWin;
|
|
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;
|
|
|
|
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, &view->attribs);
|
|
|
|
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;
|
|
|
|
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;
|
|
}
|
|
|
|
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,
|
|
};
|