Browse Source

properly handle configure notify events, and key press events

master
Wesley Kerfoot 5 years ago
parent
commit
e0e344ebf3
  1. 133
      blit_cairo.c

133
blit_cairo.c

@ -8,6 +8,11 @@
#include <unistd.h> #include <unistd.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
/* Macro definition to parse X server events
* The ~0x80 is needed to get the lower 7 bits
*/
#define RECEIVE_EVENT(ev) (ev->response_type & ~0x80)
void void
print_cairo_format(cairo_format_t format) { print_cairo_format(cairo_format_t format) {
switch (format) { switch (format) {
@ -79,21 +84,24 @@ allocScreen(xcb_connection_t *display) {
} }
void void
swapBuffers(cairo_t *front_cr, draw(cairo_surface_t *backbuffer_surface,
cairo_surface_t *backbuffer_surface, int v,
unsigned char v, uint16_t width,
int height) { uint16_t height) {
int stride = cairo_image_surface_get_stride(backbuffer_surface); int stride = cairo_image_surface_get_stride(backbuffer_surface);
unsigned char *data = cairo_image_surface_get_data(backbuffer_surface); unsigned char *data = cairo_image_surface_get_data(backbuffer_surface);
/* Manpiulate the actual pixel data here */
memset(data, v, stride*height);
}
void
swapBuffers(cairo_t *front_cr,
cairo_surface_t *backbuffer_surface) {
/* Needed to ensure all pending draw operations are done */ /* Needed to ensure all pending draw operations are done */
cairo_surface_flush(backbuffer_surface); cairo_surface_flush(backbuffer_surface);
/* Manpiulate the actual pixel data here */
memset(data, v, stride*height);
/* Make sure that cached areas are re-read */ /* Make sure that cached areas are re-read */
/* Since we modified the pixel data directly without using cairo */ /* Since we modified the pixel data directly without using cairo */
cairo_surface_mark_dirty(backbuffer_surface); cairo_surface_mark_dirty(backbuffer_surface);
@ -173,7 +181,11 @@ allocWindow(xcb_connection_t *display,
/* XCB_EVENT_MASK_EXPOSURE is the "exposure" event */ /* XCB_EVENT_MASK_EXPOSURE is the "exposure" event */
/* I.e. it fires when our window shows up on the screen */ /* I.e. it fires when our window shows up on the screen */
uint32_t valwin[2] = {screen->white_pixel, XCB_EVENT_MASK_EXPOSURE}; uint32_t eventmask = (XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
XCB_EVENT_MASK_KEY_PRESS);
uint32_t valwin[2] = {screen->white_pixel, eventmask};
xcb_create_window(display, xcb_create_window(display,
XCB_COPY_FROM_PARENT, /* depth (same as root) */ XCB_COPY_FROM_PARENT, /* depth (same as root) */
@ -201,12 +213,89 @@ genSleep(time_t sec,
return t; return t;
} }
int void
main (void) { message_loop(xcb_connection_t *display,
/* Used to handle the event loop */ xcb_screen_t *screen,
cairo_surface_t *frontbuffer_surface,
cairo_surface_t *backbuffer_surface,
cairo_t *front_cr) {
struct timespec req = genSleep(0, 20000000); struct timespec req = genSleep(0, 20000000);
struct timespec rem = genSleep(0, 0); struct timespec rem = genSleep(0, 0);
xcb_configure_notify_event_t *configure_notify;
xcb_key_press_event_t *key_event;
int exposed = 0;
int running = 1;
uint16_t window_height = screen->height_in_pixels;
uint16_t window_width = screen->width_in_pixels;
int v = 0;
while (running) {
/* Poll for events */
xcb_generic_event_t *event = xcb_poll_for_event(display);
if (event != NULL) {
switch (RECEIVE_EVENT(event)) {
case XCB_KEY_PRESS:
/* Quit on key press */
key_event = (xcb_key_press_event_t *)event;
printf("%u\n", key_event->detail);
if (key_event->detail == 24) {
running = 0;
}
break;
case XCB_EXPOSE:
printf("Got expose event\n");
exposed = 1;
break;
case XCB_CONFIGURE_NOTIFY:
configure_notify = (xcb_configure_notify_event_t *)event;
cairo_surface_flush(frontbuffer_surface);
cairo_surface_flush(backbuffer_surface);
cairo_xcb_surface_set_size(frontbuffer_surface,
configure_notify->width,
configure_notify->height);
window_height = configure_notify->height;
window_width = configure_notify->width;
printf("Got configure_notify event, w = %u, h = %u\n",
window_width,
window_height);
break;
default:
break;
}
free(event);
}
if (exposed) {
draw(backbuffer_surface,
v,
window_width,
window_height);
/* This is where the magic happens */
swapBuffers(front_cr,
backbuffer_surface);
xcb_flush(display);
nanosleep(&req, &rem);
v++;
}
}
}
int
main (void) {
/* Open up the display */ /* Open up the display */
xcb_connection_t *display = allocDisplay(); xcb_connection_t *display = allocDisplay();
@ -242,19 +331,11 @@ main (void) {
cairo_t *back_cr = cairo_create(backbuffer_surface); cairo_t *back_cr = cairo_create(backbuffer_surface);
unsigned char v = 0; message_loop(display,
screen,
while (1) { frontbuffer_surface,
swapBuffers(front_cr, backbuffer_surface,
backbuffer_surface, front_cr);
v,
window_height);
xcb_flush(display);
nanosleep(&req, &rem);
v++;
}
pause();
cairo_destroy(back_cr); cairo_destroy(back_cr);
cairo_surface_destroy(backbuffer_surface); cairo_surface_destroy(backbuffer_surface);

Loading…
Cancel
Save