aboutsummaryrefslogtreecommitdiffstats
path: root/xcb_fixed.c
diff options
context:
space:
mode:
Diffstat (limited to 'xcb_fixed.c')
-rw-r--r--xcb_fixed.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/xcb_fixed.c b/xcb_fixed.c
new file mode 100644
index 0000000..b230b78
--- /dev/null
+++ b/xcb_fixed.c
@@ -0,0 +1,211 @@
+/* XCB application drawing an updating bitmap in a window
+*
+* Inspired by the xcb black rectangle in a window example
+*
+* Copyright 2010 V. R. Sanders, released under the MIT licence
+*/
+
+/* compile with:
+* gcc -Wall -lxcb-icccm -lxcb -lxcb-image -o disp disp.c
+*/
+
+#include <string.h>
+
+#include <xcb/xcb.h>
+#include <xcb/xcb_image.h>
+#include <xcb/xcb_atom.h>
+#include <xcb/xcb_icccm.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+static xcb_format_t *
+find_format (xcb_connection_t * c, uint8_t depth, uint8_t bpp)
+{
+ const xcb_setup_t *setup = xcb_get_setup(c);
+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
+ for(; fmt != fmtend; ++fmt)
+ if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp)) {
+ /* printf("fmt %p has pad %d depth %d, bpp %d\n",
+ fmt,fmt->scanline_pad, depth,bpp); */
+ return fmt;
+ }
+ return 0;
+}
+
+void
+fillimage(unsigned char *p, int width, int height)
+{
+ int i, j;
+ for(j=0; j < height; j++)
+ {
+ for(i=0; i < width; i++)
+ {
+ if((i < 256)&&(j < 256))
+ {
+ *p++=rand()%256; // blue
+ *p++=rand()%256; // green
+ *p++=rand()%256; // red
+ } else {
+ *p++=i%256; // blue
+ *p++=j%256; // green
+ if(i < 256)
+ *p++=i%256; // red
+ else if(j < 256)
+ *p++=j%256; // red
+ else
+ *p++=(256-j)%256; // red
+ }
+ p++; /* unused byte */
+ }
+ }
+}
+
+xcb_image_t *
+CreateTrueColorImage(xcb_connection_t *c,
+ int width,
+ int height)
+{
+ const xcb_setup_t *setup = xcb_get_setup(c);
+ unsigned char *image32=(unsigned char *)malloc(width*height*4);
+ xcb_format_t *fmt = find_format(c, 24, 32);
+ if (fmt == NULL)
+ return NULL;
+
+ fillimage(image32, width, height);
+
+ return xcb_image_create(width,
+ height,
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ fmt->scanline_pad,
+ fmt->depth,
+ fmt->bits_per_pixel,
+ 0,
+ setup->image_byte_order,
+ XCB_IMAGE_ORDER_LSB_FIRST,
+ image32,
+ width*height*4,
+ image32);
+}
+
+int
+main (int argc, char **argv)
+{
+ xcb_connection_t *c;
+ xcb_screen_t *s;
+ xcb_window_t w;
+ xcb_pixmap_t pmap;
+ xcb_gcontext_t gc;
+ xcb_generic_event_t *e;
+ uint32_t mask;
+ uint32_t values[2];
+ int done=0;
+ xcb_image_t *image;
+ uint8_t *image32;
+ xcb_expose_event_t *ee;
+ char *title="Hello World!";
+ xcb_size_hints_t *hints;
+
+ /* open connection with the server */
+ c = xcb_connect (NULL, NULL);
+
+ if (!c) {
+ printf ("Cannot open display\n");
+ exit (1);
+ }
+
+ s = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
+
+ /* printf("root depth %d\n",s->root_depth); */
+
+ /* create image */
+ image = CreateTrueColorImage(c, 640, 480);
+ if (image == NULL) {
+ printf ("Cannot create iamge\n");
+ xcb_disconnect(c);
+ return 1;
+ }
+ image32 = image->data;
+
+ /* create window */
+ mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+ values[0] = s->white_pixel;
+ values[1] = XCB_EVENT_MASK_EXPOSURE |
+ XCB_EVENT_MASK_KEY_PRESS |
+ XCB_EVENT_MASK_BUTTON_PRESS;
+
+ w = xcb_generate_id (c);
+ xcb_create_window (c, XCB_COPY_FROM_PARENT, w, s->root,
+ 10, 10, image->width, image->height, 1,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ s->root_visual,
+ mask, values);
+
+ /*[> set size hits on window <]*/
+ /*hints = xcb_alloc_size_hints();*/
+ /*xcb_size_hints_set_max_size(hints, image->width,image->height);*/
+ /*xcb_size_hints_set_min_size(hints, image->width,image->height);*/
+ /*xcb_set_wm_size_hints(c, w, WM_NORMAL_HINTS, hints);*/
+
+ /* create backing pixmap */
+ pmap = xcb_generate_id(c);
+ xcb_create_pixmap(c, 24, pmap, w, image->width, image->height);
+
+ /* create pixmap plot gc */
+ mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
+ values[0] = s->black_pixel;
+ values[1] = 0xffffff;
+
+ gc = xcb_generate_id (c);
+ xcb_create_gc (c, gc, pmap, mask, values);
+
+ /* put the image into the pixmap */
+ xcb_image_put(c, pmap, gc, image, 0, 0, 0);
+
+ /* show the window */
+ xcb_map_window (c, w);
+ xcb_flush (c);
+
+ /* event loop */
+ while (!done && (e = xcb_wait_for_event (c))) {
+ switch (e->response_type) {
+ case XCB_EXPOSE:
+ ee=(xcb_expose_event_t *)e;
+ /* printf ("expose %d,%d - %d,%d\n",
+ ee->x,ee->y,ee->width,ee->height); */
+ xcb_copy_area(c, pmap, w, gc,
+ ee->x,
+ ee->y,
+ ee->x,
+ ee->y,
+ ee->width,
+ ee->height);
+ xcb_flush (c);
+ image32+=16;
+ break;
+
+ /*case XCB_KEY_PRESS:*/
+ /*[> exit on keypress <]*/
+ /*done = 1;*/
+ /*break;*/
+
+ case XCB_BUTTON_PRESS:
+ fillimage(image->data, image->width, image->height);
+ memset(image->data, 0, image32 - image->data);
+ xcb_image_put(c, pmap, gc, image, 0, 0, 0);
+ xcb_copy_area(c, pmap, w, gc, 0,0,0,0,image->width,image->height);
+ xcb_flush (c);
+ break;
+ }
+ free (e);
+ }
+
+ /* free pixmap */
+ xcb_free_pixmap(c, pmap);
+
+ /* close connection to server */
+ xcb_disconnect (c);
+
+ return 0;
+}