4 #ifdef WITH_XF86VIDMODE
5 #include <X11/extensions/xf86vmode.h>
7 #include <msp/core/systemerror.h>
8 #include "display_private.h"
10 #include "window_private.h"
16 Bool match_event_type(Display *, XEvent *event, XPointer arg)
18 return event->type==*reinterpret_cast<int *>(arg);
26 void Window::platform_init()
28 DisplayHandle dpy = display.get_private().display;
30 priv->wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", true);
31 priv->invisible_cursor = 0;
33 XSetWindowAttributes attr;
34 attr.override_redirect = options.fullscreen;
35 attr.event_mask = ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask;
37 priv->window = XCreateWindow(dpy,
38 DefaultRootWindow(dpy),
40 options.width, options.height,
45 CWOverrideRedirect|CWEventMask, &attr);
47 XSetWMProtocols(dpy, priv->window, &priv->wm_delete_window, 1);
49 if(!options.resizable)
52 hints.flags = PMinSize|PMaxSize;
53 hints.min_width=hints.max_width = options.width;
54 hints.min_height=hints.max_height = options.height;
55 XSetWMNormalHints(dpy, priv->window, &hints);
59 void Window::platform_cleanup()
62 XDestroyWindow(display.get_private().display, priv->window);
64 if(priv->invisible_cursor)
65 XFreeCursor(display.get_private().display, priv->invisible_cursor);
68 void Window::set_title(const string &title)
70 vector<unsigned char> buf(title.begin(), title.end());
73 prop.encoding = XA_STRING;
75 prop.nitems = title.size();
76 XSetWMName(display.get_private().display, priv->window, &prop);
77 display.check_error();
80 void Window::platform_reconfigure(bool fullscreen_changed)
82 DisplayHandle dpy = display.get_private().display;
84 bool was_visible = visible;
85 if(fullscreen_changed)
91 // Wait for the window to be unmapped. This makes window managers happy.
93 int ev_type = UnmapNotify;
94 XPeekIfEvent(dpy, &ev, match_event_type, reinterpret_cast<char *>(&ev_type));
97 XSetWindowAttributes attr;
98 attr.override_redirect = options.fullscreen;
99 XChangeWindowAttributes(dpy, priv->window, CWOverrideRedirect, &attr);
103 if(options.resizable)
107 hints.flags = PMinSize|PMaxSize;
108 hints.min_width = hints.max_width = options.width;
109 hints.min_height = hints.max_height = options.height;
111 XSetWMNormalHints(dpy, priv->window, &hints);
113 if(options.fullscreen)
114 XMoveResizeWindow(dpy, priv->window, 0, 0, options.width, options.height);
116 XResizeWindow(dpy, priv->window, options.width, options.height);
118 if(fullscreen_changed && was_visible)
122 void Window::show_cursor(bool s)
124 DisplayHandle dpy = display.get_private().display;
127 XUndefineCursor(dpy, priv->window);
130 if(!priv->invisible_cursor)
132 int screen = DefaultScreen(dpy);
134 Pixmap pm = XCreatePixmap(dpy, priv->window, 1, 1, 1);
135 GC gc = XCreateGC(dpy, pm, 0, 0);
136 XSetFunction(dpy, gc, GXclear);
137 XDrawPoint(dpy, pm, gc, 0, 0);
141 black.pixel = BlackPixel(dpy, screen);
142 XQueryColor(dpy, DefaultColormap(dpy, screen), &black);
144 priv->invisible_cursor = XCreatePixmapCursor(dpy, pm, pm, &black, &black, 0, 0);
146 XFreePixmap(dpy, pm);
148 XDefineCursor(dpy, priv->window, priv->invisible_cursor);
152 void Window::warp_pointer(int x, int y)
154 XWarpPointer(display.get_private().display, None, priv->window, 0, 0, 0, 0, x, y);
157 void Window::platform_show()
159 XMapRaised(display.get_private().display, priv->window);
162 void Window::platform_hide()
164 XUnmapWindow(display.get_private().display, priv->window);
167 bool Window::event(const Event &evnt)
169 const XEvent &ev = evnt.xevent;
177 signal_input_event.emit(evnt);
179 case ConfigureNotify:
180 if((ev.xconfigure.width==static_cast<int>(options.width) && ev.xconfigure.height==static_cast<int>(options.height)) == resizing)
182 options.width = ev.xconfigure.width;
183 options.height = ev.xconfigure.height;
185 signal_resize.emit(options.width, options.height);
187 #ifdef WITH_XF86VIDMODE
188 if(options.fullscreen)
190 DisplayHandle dpy = display.get_private().display;
191 int screen = DefaultScreen(dpy);
192 XF86VidModeSetViewPort(dpy, screen, ev.xconfigure.x, ev.xconfigure.y);
197 if(ev.xclient.data.l[0]==static_cast<long>(priv->wm_delete_window))
201 if(options.fullscreen)
202 XSetInputFocus(display.get_private().display, priv->window, RevertToParent, CurrentTime);
205 if(options.fullscreen)
206 XGrabPointer(display.get_private().display, priv->window, true, None, GrabModeAsync, GrabModeAsync, priv->window, None, CurrentTime);
215 } // namespace Graphics