#include <stdlib.h>
#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
#include <xcb/xcb.h>
#include <xcb/shm.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_image.h>
+#include <xcb/xcb_atom.h>
+#define XCB_ALL_PLANES ~0
+
+/* Needed for xcb_set_wm_protocols() */
+#include <xcb/xcb_icccm.h>
#include "julia.h"
0, 0, W_W, W_H,
XCB_ALL_PLANES, datap->format);
+ assert(datap->image);
+
for (i = 0 ; i < datap->image->width ; i++)
for (j = 0 ; j < datap->image->height ; j++)
{
}
xcb_image_put (datap->conn, datap->draw, datap->gc, datap->image,
- 0, 0, 0, 0, W_W, W_H);
+ 0, 0, 0);
}
int
uint32_t valgc[2];
uint32_t valwin[3];
xcb_rectangle_t rect_coord = { 0, 0, W_W, W_H};
- xcb_generic_event_t *e;
int screen_num;
data.conn = xcb_connect (0, &screen_num);
data.draw = xcb_generate_id (data.conn);
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
valwin[0] = screen->white_pixel;
- valwin[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE;
+ valwin[1] = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_EXPOSURE;
valwin[2] = XCB_EVENT_MASK_BUTTON_PRESS;
xcb_create_window (data.conn, 0,
data.draw,
palette_julia (&data);
+ xcb_atom_t deleteWindowAtom = xcb_atom_get(data.conn, "WM_DELETE_WINDOW");
+ xcb_atom_t wmprotocolsAtom = xcb_atom_get(data.conn, "WM_PROTOCOLS");
+ /* Listen to X client messages in order to be able to pickup
+ the "delete window" message that is generated for example
+ when someone clicks the top-right X button within the window
+ manager decoration (or when user hits ALT-F4). */
+ xcb_set_wm_protocols (data.conn, wmprotocolsAtom, data.draw, 1, &deleteWindowAtom);
+
xcb_flush (data.conn);
- while ((e = xcb_wait_for_event(data.conn)))
+ bool finished = false;
+ while (!finished)
{
- switch (e->response_type)
+ xcb_generic_event_t *e;
+ if (e = xcb_wait_for_event(data.conn))
{
- case XCB_EXPOSE:
- {
- xcb_copy_area(data.conn, rect, data.draw, bgcolor,
- 0, 0, 0, 0, W_W, W_H);
- draw_julia (&data);
- xcb_flush (data.conn);
- break;
+ switch (XCB_EVENT_RESPONSE_TYPE(e))
+ {
+ case XCB_EXPOSE:
+ {
+ xcb_copy_area(data.conn, rect, data.draw, bgcolor,
+ 0, 0, 0, 0, W_W, W_H);
+ draw_julia (&data);
+ xcb_flush (data.conn);
+ break;
+ }
+ case XCB_CLIENT_MESSAGE:
+ {
+ if (((xcb_client_message_event_t *)e)->data.data32[0] == deleteWindowAtom)
+ {
+ finished = true;
+ }
+ break;
+ }
+ case XCB_BUTTON_PRESS:
+ {
+ finished = true;
+ break;
+ }
}
- case XCB_KEY_RELEASE:
- case XCB_BUTTON_RELEASE:
- {
- if (data.palette)
- free (data.palette);
- if (data.image)
- xcb_image_destroy (data.image);
- free (e);
- xcb_disconnect (data.conn);
- exit (0);
- break;
- }
- }
- free (e);
+ free (e);
+ }
}
- return 1;
+ if (data.palette)
+ free (data.palette);
+ if (data.image)
+ xcb_image_destroy (data.image);
+ xcb_disconnect (data.conn);
+
+ return 0;
}