X-Git-Url: https://git.ti.com/gitweb?p=android%2Fexternal-libkmsxx.git;a=blobdiff_plain;f=kmscube%2Fcube-x11.cpp;h=dde4f61148214347522c0561fa2cc744fb2ad566;hp=7f01ae840827f513e4d744b7fea40eab4bf0af88;hb=17d180891f1e237ea5d25835999a8b23a6e7946d;hpb=f902b289c2a3956176fc328afb31ea4fc91f8984 diff --git a/kmscube/cube-x11.cpp b/kmscube/cube-x11.cpp index 7f01ae8..dde4f61 100644 --- a/kmscube/cube-x11.cpp +++ b/kmscube/cube-x11.cpp @@ -1,35 +1,122 @@ #include +#include +#include "cube.h" #include "cube-egl.h" #include "cube-gles2.h" -#include "test.h" +#include using namespace std; +static void main_loop(Display* dpy, xcb_connection_t *c, xcb_window_t window, uint32_t width, uint32_t height) +{ + EglState egl(dpy); + EglSurface surface(egl, (void*)(uintptr_t)window); + GlScene scene; + + scene.set_viewport(width, height); + + unsigned framenum = 0; + + surface.make_current(); + surface.swap_buffers(); + + bool need_exit = false; + + xcb_generic_event_t *event; + while (true) { + + while ((event = xcb_poll_for_event (c))) { + bool handled = false; + uint8_t response_type = event->response_type & ~0x80; + + switch (response_type) { + case XCB_EXPOSE: { + handled = true; + break; + } + case XCB_KEY_PRESS: { + handled = true; + + xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event; + if (kp->detail == 24) { + printf("Exit due to keypress\n"); + need_exit = true; + } + + break; + } + } + + if (!handled) { + // Check if a custom XEvent constructor was registered in xlib for this event type, and call it discarding the constructed XEvent if any. + // XESetWireToEvent might be used by libraries to intercept messages from the X server e.g. the OpenGL lib waiting for DRI2 events. + + XLockDisplay(dpy); + Bool (*proc)(Display*, XEvent*, xEvent*) = XESetWireToEvent(dpy, response_type, NULL); + if (proc) { + XESetWireToEvent(dpy, response_type, proc); + XEvent dummy; + event->sequence = LastKnownRequestProcessed(dpy); + proc(dpy, &dummy, (xEvent*)event); + } + XUnlockDisplay(dpy); + } + + free(event); + } + + if (s_num_frames && framenum >= s_num_frames) + need_exit = true; + + if (need_exit) + break; + + // this should be in XCB_EXPOSE, but we don't get the event after swaps... + scene.draw(framenum++); + surface.swap_buffers(); + } +} + void main_x11() { - Display* display = XOpenDisplay(NULL); + Display* dpy = XOpenDisplay(NULL); + FAIL_IF(!dpy, "Failed to connect to the X server"); - xcb_connection_t *connection = XGetXCBConnection(display); + xcb_connection_t *c = XGetXCBConnection(dpy); + + /* Acquire event queue ownership */ + XSetEventQueueOwner(dpy, XCBOwnsEventQueue); /* Get the first screen */ - const xcb_setup_t *setup = xcb_get_setup (connection); + const xcb_setup_t *setup = xcb_get_setup (c); xcb_screen_t *screen = xcb_setup_roots_iterator (setup).data; /* Create the window */ - uint32_t width = 600; - uint32_t height = 600; + uint32_t width; + uint32_t height; + + if (s_fullscreen) { + width = screen->width_in_pixels; + height = screen->height_in_pixels; + } else { + width = 600; + height = 600; + } - const uint32_t xcb_window_attrib_mask = XCB_CW_EVENT_MASK; + const uint32_t xcb_window_attrib_mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK; const uint32_t xcb_window_attrib_list[] = { - XCB_EVENT_MASK_EXPOSURE, + // OVERRIDE_REDIRECT + 0, + // EVENT_MASK + XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS, }; - xcb_window_t window = xcb_generate_id (connection); - xcb_create_window (connection, /* Connection */ + xcb_window_t window = xcb_generate_id (c); + xcb_create_window (c, /* Connection */ XCB_COPY_FROM_PARENT, /* depth (same as root)*/ window, /* window Id */ screen->root, /* parent window */ @@ -41,27 +128,27 @@ void main_x11() xcb_window_attrib_mask, xcb_window_attrib_list); - xcb_map_window (connection, window); - xcb_flush (connection); +#if 0 // Doesn't work + if (s_fullscreen) { - EglState egl(display); - EglSurface surface(egl, (void*)(uintptr_t)window); - GlScene scene; + xcb_intern_atom_cookie_t cookie = xcb_intern_atom(c, 0, 12, "_NET_WM_STATE"); + xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(c, cookie, 0); - scene.set_viewport(width, height); + xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(c, 0, 24, "_NET_WM_STATE_FULLSCREEN"); + xcb_intern_atom_reply_t* reply2 = xcb_intern_atom_reply(c, cookie2, 0); - int framenum = 0; + xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, reply->atom, XCB_ATOM_ATOM , 32, 1, (void*)&reply2->atom); + } +#endif - surface.make_current(); - surface.swap_buffers(); + xcb_map_window (c, window); + xcb_flush (c); - xcb_generic_event_t *event; - while ( (event = xcb_poll_for_event (connection)) ) { + main_loop(dpy, c, window, width, height); - surface.make_current(); - scene.draw(framenum++); - surface.swap_buffers(); - } + xcb_flush(c); + xcb_unmap_window(c, window); + xcb_destroy_window(c, window); - xcb_disconnect (connection); + XCloseDisplay(dpy); }