4 #include <msp/core/systemerror.h>
5 #include "display_private.h"
7 #include "window_private.h"
13 Bool match_event_type(Display *, XEvent *event, XPointer arg)
15 return event->type==*reinterpret_cast<int *>(arg);
23 void Window::platform_init()
25 DisplayHandle dpy = display.get_private().display;
27 priv->wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", true);
28 priv->invisible_cursor = 0;
30 XSetWindowAttributes attr;
31 attr.override_redirect = options.fullscreen;
32 attr.event_mask = ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask|ExposureMask;
34 priv->window = XCreateWindow(dpy,
35 DefaultRootWindow(dpy),
37 options.width, options.height,
42 CWOverrideRedirect|CWEventMask, &attr);
44 XSetWMProtocols(dpy, priv->window, &priv->wm_delete_window, 1);
46 if(!options.resizable)
49 hints.flags = PMinSize|PMaxSize;
50 hints.min_width=hints.max_width = options.width;
51 hints.min_height=hints.max_height = options.height;
52 XSetWMNormalHints(dpy, priv->window, &hints);
56 void Window::platform_cleanup()
59 XDestroyWindow(display.get_private().display, priv->window);
61 if(priv->invisible_cursor)
62 XFreeCursor(display.get_private().display, priv->invisible_cursor);
65 void Window::set_title(const string &title)
67 vector<unsigned char> buf(title.begin(), title.end());
70 prop.encoding = XA_STRING;
72 prop.nitems = title.size();
73 XSetWMName(display.get_private().display, priv->window, &prop);
74 display.check_error();
77 void Window::platform_reconfigure(bool fullscreen_changed)
79 DisplayHandle dpy = display.get_private().display;
81 bool was_visible = visible;
82 if(fullscreen_changed)
88 // Wait for the window to be unmapped. This makes window managers happy.
90 int ev_type = UnmapNotify;
91 XPeekIfEvent(dpy, &ev, match_event_type, reinterpret_cast<char *>(&ev_type));
94 XSetWindowAttributes attr;
95 attr.override_redirect = options.fullscreen;
96 XChangeWindowAttributes(dpy, priv->window, CWOverrideRedirect, &attr);
100 if(options.resizable)
104 hints.flags = PMinSize|PMaxSize;
105 hints.min_width = hints.max_width = options.width;
106 hints.min_height = hints.max_height = options.height;
108 XSetWMNormalHints(dpy, priv->window, &hints);
110 if(options.fullscreen)
111 XMoveResizeWindow(dpy, priv->window, 0, 0, options.width, options.height);
113 XResizeWindow(dpy, priv->window, options.width, options.height);
115 if(fullscreen_changed && was_visible)
119 void Window::show_cursor(bool s)
121 DisplayHandle dpy = display.get_private().display;
124 XUndefineCursor(dpy, priv->window);
127 if(!priv->invisible_cursor)
129 int screen = DefaultScreen(dpy);
131 Pixmap pm = XCreatePixmap(dpy, priv->window, 1, 1, 1);
132 GC gc = XCreateGC(dpy, pm, 0, 0);
133 XSetFunction(dpy, gc, GXclear);
134 XDrawPoint(dpy, pm, gc, 0, 0);
138 black.pixel = BlackPixel(dpy, screen);
139 XQueryColor(dpy, DefaultColormap(dpy, screen), &black);
141 priv->invisible_cursor = XCreatePixmapCursor(dpy, pm, pm, &black, &black, 0, 0);
143 XFreePixmap(dpy, pm);
145 XDefineCursor(dpy, priv->window, priv->invisible_cursor);
149 void Window::warp_pointer(int x, int y)
151 XWarpPointer(display.get_private().display, None, priv->window, 0, 0, 0, 0, x, y);
154 void Window::platform_set_touch_input()
158 void Window::platform_show()
160 XMapRaised(display.get_private().display, priv->window);
163 void Window::platform_hide()
165 XUnmapWindow(display.get_private().display, priv->window);
168 bool Window::event(const Event &evnt)
170 const XEvent &ev = evnt.xevent;
178 signal_input_event.emit(evnt);
180 case ConfigureNotify:
181 if((ev.xconfigure.width==static_cast<int>(options.width) && ev.xconfigure.height==static_cast<int>(options.height)) == resizing)
183 options.width = ev.xconfigure.width;
184 options.height = ev.xconfigure.height;
186 signal_resize.emit(options.width, options.height);
190 if(ev.xclient.data.l[0]==static_cast<long>(priv->wm_delete_window))
194 if(options.fullscreen)
195 XSetInputFocus(display.get_private().display, priv->window, RevertToParent, CurrentTime);
198 if(options.fullscreen)
199 XGrabPointer(display.get_private().display, priv->window, true, None, GrabModeAsync, GrabModeAsync, priv->window, None, CurrentTime);
202 signal_expose.emit(ev.xexpose.x, ev.xexpose.y, ev.xexpose.width, ev.xexpose.height, evnt);
211 } // namespace Graphics