#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);
screen = xcb_aux_get_screen (data.conn, screen_num);
data.depth = xcb_aux_get_depth (data.conn, screen);
- win.window = screen->root;
+ win = screen->root;
- data.gc = xcb_gcontext_new (data.conn);
+ data.gc = xcb_generate_id (data.conn);
mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
valgc[0] = screen->black_pixel;
valgc[1] = 0; /* no graphics exposures */
xcb_create_gc (data.conn, data.gc, win, mask, valgc);
- bgcolor = xcb_gcontext_new (data.conn);
+ bgcolor = xcb_generate_id (data.conn);
mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
valgc[0] = screen->white_pixel;
valgc[1] = 0; /* no graphics exposures */
xcb_create_gc (data.conn, bgcolor, win, mask, valgc);
- data.draw.window = xcb_window_new (data.conn);
+ 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.window,
+ data.draw,
screen->root,
0, 0, W_W, W_H,
10,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
mask, valwin);
- xcb_map_window (data.conn, data.draw.window);
+ xcb_map_window (data.conn, data.draw);
- rect.pixmap = xcb_pixmap_new (data.conn);
+ rect = xcb_generate_id (data.conn);
xcb_create_pixmap (data.conn, data.depth,
- rect.pixmap, data.draw,
+ rect, data.draw,
W_W, W_H);
xcb_poly_fill_rectangle(data.conn, rect, bgcolor, 1, &rect_coord);
- xcb_map_window (data.conn, data.draw.window);
+ xcb_map_window (data.conn, data.draw);
data.format = XCB_IMAGE_FORMAT_Z_PIXMAP;
- data.cmap = xcb_colormap_new (data.conn);
+ data.cmap = xcb_generate_id (data.conn);
xcb_create_colormap (data.conn,
XCB_COLORMAP_ALLOC_NONE,
data.cmap,
- data.draw.window,
+ data.draw,
screen->root_visual);
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;
}