Skip to content

Instantly share code, notes, and snippets.

@yshui
Created March 13, 2012 13:18
Show Gist options
  • Save yshui/2028698 to your computer and use it in GitHub Desktop.
Save yshui/2028698 to your computer and use it in GitHub Desktop.
Test case for window dragging
/* Simple XCB application to test configure request handling */
/* Run this problem, enable floating mode, and press a key while the window is focused.
* The window will follow the mouse */
/* to compile it use :
gcc -Wall x.c -lxcb
*/
#include <xcb/xcb.h>
#include <stdio.h>
#include <stdlib.h>
void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, int *r) {
xcb_void_cookie_t cookie;
cookie = xcb_configure_window(conn, window,
XCB_CONFIG_WINDOW_X |
XCB_CONFIG_WINDOW_Y,
r);
}
static void get_window_position(xcb_connection_t *c, xcb_window_t w, int *x, int *y){
xcb_query_tree_reply_t *tree = xcb_query_tree_reply(c, xcb_query_tree(c, w), NULL);
xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply(c, xcb_get_geometry(c, w), NULL);
xcb_translate_coordinates_reply_t *t = xcb_translate_coordinates_reply(c, xcb_translate_coordinates(c, w, tree->root, geo->x, geo->y), NULL);
*x = t->dst_x;
*y = t->dst_y;
free(tree);
free(geo);
free(t);
}
int main(void)
{
xcb_connection_t *c;
xcb_screen_t *s;
xcb_window_t w;
xcb_gcontext_t g;
xcb_generic_event_t *e;
uint32_t mask;
uint32_t values[2];
int done = 0;
xcb_rectangle_t r = { 20, 20, 60, 60 };
/* open connection with the server */
c = xcb_connect(NULL,NULL);
if (xcb_connection_has_error(c)) {
printf("Cannot open display\n");
exit(1);
}
/* get the first screen */
s = xcb_setup_roots_iterator( xcb_get_setup(c) ).data;
/* create black graphics context */
g = xcb_generate_id(c);
w = s->root;
mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
values[0] = s->black_pixel;
values[1] = 0;
xcb_create_gc(c, g, w, mask, values);
/* create window */
w = xcb_generate_id(c);
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_create_window(c, s->root_depth, w, s->root,
10, 10, 100, 100, 0,
XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual,
mask, values);
/* map (show) the window */
xcb_map_window(c, w);
xcb_flush(c);
xcb_motion_notify_event_t *te;
/* event loop */
int oldm[2]={0};
int co[2]={200,200};
xcb_set_window_rect(c, w, co);
xcb_flush(c);
while (!done && (e = xcb_wait_for_event(c))) {
switch (e->response_type & ~0x80) {
case XCB_EXPOSE: /* draw or redraw the window */
xcb_set_window_rect(c, w, co);
xcb_poly_fill_rectangle(c, w, g, 1, &r);
xcb_flush(c);
break;
case XCB_KEY_PRESS: /* exit on key press */
te = e;
//fprintf(stderr, "%d, %d\n", te->root_x, te->root_y);
int x,y;
get_window_position(c, w, &x, &y);
//fprintf(stderr, "%d, %d/%d, %d/%d, %d\n", oldm[0], oldm[1], te->root_x, te->root_y, x, y);
if(oldm[0] == oldm[1] && oldm[1] == 0){
oldm[0] = te->root_x;
oldm[1] = te->root_y;
}else{
co[0] = x + te->root_x - oldm[0];
co[1] = y + te->root_y - oldm[1];
oldm[0] = te->root_x;
oldm[1] = te->root_y;
}
xcb_set_window_rect(c, w, co);
xcb_flush(c);
get_window_position(c, w, &x, &y);
//fprintf(stderr, "%d, %d / %d, %d / %d, %d\n", oldm[0], oldm[1], co[0], co[1], x, y);
break;
}
free(e);
}
/* close connection to server */
xcb_disconnect(c);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment