3 This file is part of libmspgbase
4 Copyright © 2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
10 #include <X11/Xutil.h>
11 #include <msp/core/except.h>
18 DisplayOptions::DisplayOptions():
26 Initializes the class but does not open the window. Intended for use by
34 Window::Window(unsigned w, unsigned h)
42 Window::Window(const DisplayOptions &dopt):
51 XDestroyWindow(display, window);
53 XCloseDisplay(display);
56 void Window::set_title(const string &title)
58 vector<unsigned char> buf(title.begin(), title.end());
61 prop.encoding=XA_STRING;
63 prop.nitems=title.size();
64 XSetWMName(display, window, &prop);
69 XMapRaised(display, window);
74 XUnmapWindow(display, window);
81 int pending=XPending(display);
85 for(int i=0; i<pending; ++i)
88 XNextEvent(display, &event);
94 void Window::prepare()
96 if(options.display.empty())
97 display=XOpenDisplay(0);
99 display=XOpenDisplay(options.display.c_str());
101 throw Exception("Couldn't open X display");
103 wm_delete_window=XInternAtom(display, "WM_DELETE_WINDOW", true);
105 /* Throwing from the error handler doesn't work too well and I don't know
106 how to dig up all the information that Xlib gives by default, so disable
107 custom error handling for now. */
108 //XSetErrorHandler(x_error_handler);
111 void Window::set_window(Handle wnd)
115 XSelectInput(display, window, ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask);
117 XSetWMProtocols(display, window, &wm_delete_window, 1);
124 Handle wnd=XCreateWindow(display, DefaultRootWindow(display), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0);
128 void Window::process_event(const XEvent &event)
133 signal_button_press.emit(event.xbutton.x, event.xbutton.y, event.xbutton.button, event.xbutton.state);
136 signal_button_release.emit(event.xbutton.x, event.xbutton.y, event.xbutton.button, event.xbutton.state);
139 signal_pointer_motion.emit(event.xmotion.x, event.xmotion.y);
144 XLookupString(const_cast<XKeyEvent *>(&event.xkey), buf, sizeof(buf), 0, 0);
145 // XXX Handle the result according to locale
146 signal_key_press.emit(event.xkey.keycode, event.xkey.state, buf[0]);
150 signal_key_release.emit(event.xkey.keycode, event.xkey.state);
152 case ConfigureNotify:
153 options.width=event.xconfigure.width;
154 options.height=event.xconfigure.height;
155 signal_resize.emit(options.width, options.height);
158 if(event.xclient.data.l[0]==static_cast<long>(wm_delete_window))
167 int Window::x_error_handler(Display *display, XErrorEvent *error)
170 XGetErrorText(display, error->error_code, buf, sizeof(buf));
171 /*string request_code=lexical_cast(error->request_code);
173 XGetErrorDatabaseText(display, "XRequest", request_code.c_str(), buf, buf2, sizeof(buf2));*/
174 throw Exception(buf);