XCloseDisplay(display);
}
+void Window::show()
+{
+ XMapWindow(display, window);
+}
+
+void Window::tick()
+{
+ while(1)
+ {
+ int pending=XPending(display);
+ if(pending==0)
+ break;
+
+ for(int i=0; i<pending; ++i)
+ {
+ XEvent event;
+ XNextEvent(display, &event);
+ process_event(event);
+ }
+ }
+}
+
void Window::init(const DisplayOptions &dopt)
{
+ options=dopt;
+
display=XOpenDisplay(0);
if(!display)
throw Exception("Couldn't open X display");
throw Exception("Couldn't get a matching visual");
window=XCreateWindow(display, DefaultRootWindow(display), 0, 0, dopt.width, dopt.height, 0, CopyFromParent, InputOutput, visual->visual, 0, 0);
+
+ XSelectInput(display, window, ButtonPressMask|ButtonReleaseMask|MotionMask|KeyPressMask|KeyReleaseMask);
+}
+
+void Window::process_event(const XEvent &event)
+{
+ switch(event.type)
+ {
+ case ButtonPress:
+ signal_button_press.emit(event.button.x, event.button.y, event.button.button, event.button.state);
+ break;
+ case ButtonRelease:
+ signal_button_release.emit(event.button.x, event.button.y, event.button.button, event.button.state);
+ break;
+ case PointerMotion:
+ signal_pointer_motion.emit(event.motion.x, event.motion.y);
+ break;
+ case KeyPress:
+ {
+ char buf[16];
+ XLookupString(event.key, buf, sizeof(buf), 0, 0);
+ // XXX Handle the result according to locale
+ signal_key_press.emit(event.key.keycode, event.key.state, buf[0]);
+ }
+ break;
+ case KeyRelease:
+ signal_key_release.emit(event.key.keycode, event.key.state);
+ break;
+ default:;
+ }
}
} // namespace GLtk
class Window
{
public:
+ sigc::signal<int, int, unsigned, unsigned> signal_button_press;
+ sigc::signal<int, int, unsigned, unsigned> signal_button_release;
+ sigc::signal<int, int> signal_pointer_motion;
+ sigc::signal<unsigned, unsigned, wchar_t> signal_key_press;
+ sigc::signal<unsigned, unsigned> signal_key_release;
+
Window(unsigned, unsigned);
Window(const DisplayOptions &);
~Window();
+
+ unsigned get_width() const { return options.width; }
+ unsigned get_height() const { return options.height; }
+ void show();
+ void add(Widget &);
+ void tick();
private:
Display *display;
+ DisplayOptions options;
::Window window;
void init(const DisplayOptions &);
+ void process_event(const XEvent &);
};
} // namespace GLtk