summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am6
-rwxr-xr-xautogen.sh12
-rw-r--r--configure.ac8
-rw-r--r--xcb_test.c329
4 files changed, 355 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..04d0abe
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,6 @@
+
+AM_CFLAGS = $(XCB_CFLAGS)
+
+bin_PROGRAMS = xcb-test
+xcb_test_SOURCES = xcb_test.c
+xcb_test_LDADD = $(XCB_LIBS)
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..4e8b11b
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf --force -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..f758a4f
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,8 @@
+AC_INIT([xcb-test], [0.1])
+
+AM_INIT_AUTOMAKE([foreign])
+AM_MAINTAINER_MODE
+AC_PROG_CC
+PKG_CHECK_MODULES([XCB], [xcb])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/xcb_test.c b/xcb_test.c
new file mode 100644
index 0000000..9072eb3
--- /dev/null
+++ b/xcb_test.c
@@ -0,0 +1,329 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "xcb/xcb.h"
+
+#define WIDTH 300
+#define HEIGHT 150
+
+static xcb_gc_t
+ getFontGC (xcb_connection_t *connection,
+ xcb_screen_t *screen,
+ xcb_window_t window,
+ const char *fontName );
+static void
+ testCookie (xcb_void_cookie_t cookie,
+ xcb_connection_t *connection,
+ char *errMessage )
+ {
+ xcb_generic_error_t *error = xcb_request_check (connection, cookie);
+ if (error)
+ {
+ fprintf (stderr, "ERROR: %s : %d\n", errMessage , error->error_code);
+ xcb_disconnect (connection);
+ exit (-1);
+ }
+ }
+
+
+static void
+drawButton (xcb_connection_t *connection,
+ xcb_screen_t *screen,
+ xcb_window_t window,
+ int16_t x1,
+ int16_t y1,
+ const char *label )
+{
+ uint8_t length = strlen (label);
+ int16_t inset = 2;
+ int16_t width = 7 * length + 2 * (inset + 1);
+ int16_t height = 13 + 2 * (inset + 1);
+
+ xcb_point_t points[5];
+ points[0].x = x1;
+ points[0].y = y1;
+ points[1].x = x1 + width;
+ points[1].y = y1;
+ points[2].x = x1 + width;
+ points[2].y = y1 - height;
+ points[3].x = x1;
+ points[3].y = y1 - height;
+ points[4].x = x1;
+ points[4].y = y1;
+
+
+ xcb_gcontext_t gc = getFontGC (connection, screen, window, "7x13");
+
+
+ xcb_void_cookie_t lineCookie = xcb_poly_line_checked (connection,
+ XCB_COORD_MODE_ORIGIN,
+ window,
+ gc,
+ 5,
+ points );
+ testCookie (lineCookie, connection, "can't draw lines");
+
+
+ xcb_void_cookie_t textCookie = xcb_image_text_8_checked (connection,
+ length,
+ window,
+ gc,
+ x1 + inset + 1,
+ y1 - inset - 1,
+ label );
+ testCookie (textCookie, connection, "can't paste text");
+
+
+ xcb_void_cookie_t gcCookie = xcb_free_gc (connection, gc);
+ testCookie (gcCookie, connection, "can't free gc");
+}
+
+
+
+static void
+drawText (xcb_connection_t *connection,
+ xcb_screen_t *screen,
+ xcb_window_t window,
+ int16_t x1,
+ int16_t y1,
+ const char *label )
+{
+
+ xcb_gcontext_t gc = getFontGC (connection, screen, window, "7x13");
+
+
+ xcb_void_cookie_t textCookie = xcb_image_text_8_checked (connection,
+ strlen (label),
+ window,
+ gc,
+ x1,
+ y1,
+ label );
+ testCookie(textCookie, connection, "can't paste text");
+
+
+ xcb_void_cookie_t gcCookie = xcb_free_gc (connection, gc);
+ testCookie (gcCookie, connection, "can't free gc");
+}
+
+
+static xcb_gc_t
+getFontGC (xcb_connection_t *connection,
+ xcb_screen_t *screen,
+ xcb_window_t window,
+ const char *fontName )
+{
+
+ xcb_font_t font = xcb_generate_id (connection);
+ xcb_void_cookie_t fontCookie = xcb_open_font_checked (connection,
+ font,
+ strlen (fontName),
+ fontName );
+ testCookie (fontCookie, connection, "can't open font");
+
+
+ xcb_gcontext_t gc = xcb_generate_id (connection);
+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
+ uint32_t value_list[3];
+ value_list[0] = screen->black_pixel;
+ value_list[1] = screen->white_pixel;
+ value_list[2] = font;
+
+
+ xcb_void_cookie_t gcCookie = xcb_create_gc_checked (connection,
+ gc,
+ window,
+ mask,
+ value_list );
+ testCookie (gcCookie, connection, "can't create gc");
+
+
+ fontCookie = xcb_close_font_checked (connection, font);
+ testCookie (fontCookie, connection, "can't close font");
+
+ return gc;
+}
+
+
+static void
+setCursor (xcb_connection_t *connection,
+ xcb_screen_t *screen,
+ xcb_window_t window,
+ int cursorId )
+{
+ uint32_t mask;
+xcb_font_t font = xcb_generate_id (connection);
+ xcb_void_cookie_t fontCookie = xcb_open_font_checked (connection,
+ font,
+ strlen ("cursor"),
+ "cursor" );
+ testCookie (fontCookie, connection, "can't open font");
+
+
+ xcb_cursor_t cursor = xcb_generate_id (connection);
+ xcb_create_glyph_cursor (connection,
+ cursor,
+ font,
+ font,
+ cursorId,
+ cursorId + 1,
+ 0, 0, 0, 0, 0, 0 );
+
+
+ xcb_gcontext_t gc = xcb_generate_id (connection);
+
+ mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
+ uint32_t values_list[3];
+ values_list[0] = screen->black_pixel;
+ values_list[1] = screen->white_pixel;
+ values_list[2] = font;
+
+ xcb_void_cookie_t gcCookie = xcb_create_gc_checked (connection, gc, window, mask, values_list);
+ testCookie (gcCookie, connection, "can't create gc");
+
+
+ mask = XCB_CW_CURSOR;
+ uint32_t value_list = cursor;
+ xcb_change_window_attributes (connection, window, mask, &value_list);
+
+
+ xcb_free_cursor (connection, cursor);
+
+
+
+ fontCookie = xcb_close_font_checked (connection, font);
+ testCookie (fontCookie, connection, "can't close font");
+}
+
+int
+main ()
+{
+
+
+ int screenNum,i;
+
+ xcb_connection_t *connection = xcb_connect ("127.0.0.1:0.0", &screenNum);
+ if (!connection) {
+ fprintf (stderr, "ERROR: can't connect to an X server\n");
+ return -1;
+ }
+
+
+
+
+ xcb_screen_iterator_t iter = xcb_setup_roots_iterator (xcb_get_setup (connection));
+
+
+ for (i = 0; i < screenNum; ++i) {
+ xcb_screen_next (&iter);
+ }
+
+ xcb_screen_t *screen = iter.data;
+
+ if (!screen) {
+ fprintf (stderr, "ERROR: can't get the current screen\n");
+ xcb_disconnect (connection);
+ return -1;
+ }
+
+
+
+
+ xcb_window_t window = xcb_generate_id (connection);
+ uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+ uint32_t values[2];
+ values[0] = screen->white_pixel;
+ values[1] = XCB_EVENT_MASK_KEY_RELEASE |
+ XCB_EVENT_MASK_BUTTON_PRESS |
+ XCB_EVENT_MASK_EXPOSURE |
+ XCB_EVENT_MASK_POINTER_MOTION;
+
+
+ xcb_void_cookie_t windowCookie = xcb_create_window_checked (connection,
+ screen->root_depth,
+ window,
+ screen->root,
+ 20, 200, WIDTH, HEIGHT,
+ 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ screen->root_visual,
+ mask, values );
+ testCookie (windowCookie, connection, "can't create window");
+
+
+ xcb_void_cookie_t mapCookie = xcb_map_window_checked (connection, window);
+ testCookie (mapCookie, connection, "can't map window");
+
+
+ setCursor (connection, screen, window, 68);
+
+ xcb_flush(connection);
+
+
+
+
+ uint8_t isHand = 0;
+
+ while (1) {
+ xcb_generic_event_t *event = xcb_poll_for_event (connection);
+ if (event) {
+ switch (event->response_type & ~0x80) {
+ case XCB_EXPOSE: {
+ char *text = "click here to change cursor";
+ drawButton (connection,
+ screen,
+ window,
+ (WIDTH - 7 * strlen(text)) / 2,
+ (HEIGHT - 16) / 2,
+ text );
+
+ text = "Press ESC key to exit...";
+ drawText (connection,
+ screen,
+ window,
+ 10,
+ HEIGHT - 10,
+ text );
+ break;
+ }
+ case XCB_BUTTON_PRESS: {
+ xcb_button_press_event_t *press = (xcb_button_press_event_t *)event;
+
+ int length = strlen ("click here to change cursor");
+ if ((press->event_x >= (WIDTH - 7 * length) / 2) &&
+ (press->event_x <= ((WIDTH - 7 * length) / 2 + 7 * length + 6)) &&
+ (press->event_y >= (HEIGHT - 16) / 2 - 19) &&
+ (press->event_y <= ((HEIGHT - 16) / 2))) {
+ isHand = 1 - isHand;
+
+ }
+
+ if (isHand) {
+ setCursor (connection, screen, window, 58);
+ }
+ else {
+ setCursor (connection, screen, window, 68);
+
+ }
+
+ }
+ case XCB_KEY_RELEASE: {
+
+ xcb_key_release_event_t *kr = (xcb_key_release_event_t *)event;
+
+ switch (kr->detail) {
+
+ case 9:
+ free (event);
+ xcb_disconnect (connection);
+ return 0;
+ }
+ }
+ }
+ free (event);
+ }
+ }
+
+ return 0;
+}