2 #include <X11/Xlib-xcb.h>
4 #include "cube.h"
5 #include "cube-egl.h"
6 #include "cube-gles2.h"
8 #include "test.h"
10 using namespace std;
12 void main_x11()
13 {
14 Display* dpy = XOpenDisplay(NULL);
16 xcb_connection_t *c = XGetXCBConnection(dpy);
18 /* Acquire event queue ownership */
19 XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
21 /* Get the first screen */
22 const xcb_setup_t *setup = xcb_get_setup (c);
23 xcb_screen_t *screen = xcb_setup_roots_iterator (setup).data;
25 /* Create the window */
27 uint32_t width;
28 uint32_t height;
30 if (s_fullscreen) {
31 width = screen->width_in_pixels;
32 height = screen->height_in_pixels;
33 } else {
34 width = 600;
35 height = 600;
36 }
38 const uint32_t xcb_window_attrib_mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
39 const uint32_t xcb_window_attrib_list[] = {
40 // OVERRIDE_REDIRECT
41 0,
42 // EVENT_MASK
43 XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS,
44 };
46 xcb_window_t window = xcb_generate_id (c);
47 xcb_create_window (c, /* Connection */
48 XCB_COPY_FROM_PARENT, /* depth (same as root)*/
49 window, /* window Id */
50 screen->root, /* parent window */
51 0, 0, /* x, y */
52 width, height, /* width, height */
53 0, /* border_width */
54 XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
55 screen->root_visual, /* visual */
56 xcb_window_attrib_mask,
57 xcb_window_attrib_list);
59 #if 0 // Doesn't work
60 if (s_fullscreen) {
62 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(c, 0, 12, "_NET_WM_STATE");
63 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(c, cookie, 0);
65 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(c, 0, 24, "_NET_WM_STATE_FULLSCREEN");
66 xcb_intern_atom_reply_t* reply2 = xcb_intern_atom_reply(c, cookie2, 0);
68 xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, reply->atom, XCB_ATOM_ATOM , 32, 1, (void*)&reply2->atom);
69 }
70 #endif
72 xcb_map_window (c, window);
73 xcb_flush (c);
75 {
76 EglState egl(dpy);
77 EglSurface surface(egl, (void*)(uintptr_t)window);
78 GlScene scene;
80 scene.set_viewport(width, height);
82 unsigned framenum = 0;
84 surface.make_current();
85 surface.swap_buffers();
87 bool need_exit = false;
89 xcb_generic_event_t *event;
90 while (!need_exit && (event = xcb_wait_for_event (c))) {
91 switch (event->response_type & ~0x80) {
92 case XCB_EXPOSE: {
94 break;
95 }
96 case XCB_KEY_PRESS: {
97 xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
98 if (kp->detail == 24) {
99 printf("Exit due to keypress\n");
100 need_exit = true;
101 }
103 break;
104 }
105 }
107 free(event);
109 if (s_num_frames && framenum >= s_num_frames)
110 need_exit = true;
112 // this should be in XCB_EXPOSE, but we don't get the event after swaps...
113 scene.draw(framenum++);
114 surface.swap_buffers();
115 }
116 }
118 xcb_flush(c);
119 xcb_unmap_window(c, window);
120 xcb_destroy_window(c, window);
122 XCloseDisplay(dpy);
123 }