Ubuntu 使用XCB

本文介绍了使用XCB库在Linux中创建窗口、注册tablet/touch事件并监听和处理基础与平板设备事件的过程。重点讲解了窗口初始化、XI2 Select Device Events函数和事件处理流程。
摘要由CSDN通过智能技术生成

编译文件

g++ main.cpp -lxcb -lxcb-xinput
./a.out

一、创建窗口

	xcb_connection_t *c = xcb_connect (NULL, NULL);

	/* Get the first screen */
	xcb_screen_t *screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;

	/* Ask for our window's Id */
	xcb_window_t winId = xcb_generate_id(c);

	uint32_t baseMask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
	uint32_t values[2];
	
	// 可以捕获自己关注的事件
	values[0] = screen->white_pixel;
	values[1] = XCB_EVENT_MASK_EXPOSURE   | XCB_EVENT_MASK_BUTTON_PRESS   |
			XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION |
			XCB_EVENT_MASK_ENTER_WINDOW   | XCB_EVENT_MASK_LEAVE_WINDOW   |
			XCB_EVENT_MASK_KEY_PRESS      | XCB_EVENT_MASK_KEY_RELEASE;

	/* Create the window */
	xcb_create_window (c,                             /* Connection          */
					   XCB_COPY_FROM_PARENT,          /* depth (same as root)*/
					   winId,                         /* window Id           */
					   screen->root,                  /* parent window       */
					   0, 0,                          /* x, y                */
					   480, 480,                      /* width, height       */
					   10,                            /* border_width        */
					   XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
					   screen->root_visual,           /* visual              */
					   baseMask, values);             /* masks, not used yet */
					   
	/* Map the window on the screen */
	xcb_map_window (c, winId);

	/* Make sure commands are sent before we pause, so window is shown */
	xcb_flush (c);


二、注册tablet或者touch事件

struct qt_xcb_input_event_mask_t {
    xcb_input_event_mask_t header;
    uint32_t               mask;
};

void xi2SelectDeviceEvents(xcb_connection_t *c, xcb_window_t window)
{
    uint32_t bitMask = XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS;
    bitMask |= XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE;
    bitMask |= XCB_INPUT_XI_EVENT_MASK_MOTION;
    // There is a check for enter/leave events in plain xcb enter/leave event handler,
    // core enter/leave events will be ignored in this case.
    bitMask |= XCB_INPUT_XI_EVENT_MASK_ENTER;
    bitMask |= XCB_INPUT_XI_EVENT_MASK_LEAVE;


    qt_xcb_input_event_mask_t mask;
    mask.header.deviceid = XCB_INPUT_DEVICE_ALL_MASTER;
    mask.header.mask_len = 1;
    mask.mask = bitMask;
    xcb_input_xi_select_events_checked(c, window, 1, &mask.header);
}

// 参数:已经创建好的连接、窗口ID
xi2SelectDeviceEvents(c, winId);


三、不断监听xcb事件

	xcb_generic_event_t *event;

	while ((event = xcb_wait_for_event (c))) {
		processEvent(event);
		while ((event = xcb_poll_for_queued_event(c)))
			processEvent(event);
	}


四、处理基础事件或tablet事件

// 处理tablet事件
void xi2HandleEvent(xcb_ge_event_t *event)
{
	xcb_input_button_press_event_t *xiEvent = reinterpret_cast<xcb_input_button_press_event_t *>(event);
	int sourceDeviceId = xiEvent->deviceid; // may be the master id
	xcb_input_button_press_event_t *xiDeviceEvent = 0;
	xcb_input_enter_event_t *xiEnterEvent = 0;

	switch (xiEvent->event_type) {
	case XCB_INPUT_BUTTON_PRESS:
	case XCB_INPUT_BUTTON_RELEASE:
	case XCB_INPUT_MOTION:
	case XCB_INPUT_TOUCH_BEGIN:
	case XCB_INPUT_TOUCH_UPDATE:
	case XCB_INPUT_TOUCH_END:
	{
		xiDeviceEvent = xiEvent;
		sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master
		break;
	}
	case XCB_INPUT_ENTER:
	case XCB_INPUT_LEAVE: {
		xiEnterEvent = reinterpret_cast<xcb_input_enter_event_t *>(event);
		sourceDeviceId = xiEnterEvent->sourceid; // use the actual device id instead of the master
		break;
	}
	case XCB_INPUT_HIERARCHY:
		return;
	case XCB_INPUT_DEVICE_CHANGED:
		return;
	default:
		break;
	}
}

// 处理基础事件
void processEvent(xcb_generic_event_t *event)
{
	switch (event->response_type & ~0x80) {
	case XCB_EXPOSE: {
		xcb_expose_event_t *expose = (xcb_expose_event_t *)event;
		break;
	}
	case XCB_BUTTON_PRESS: {
		xcb_button_press_event_t *press = (xcb_button_press_event_t *)event;
		printf("xcb_button_press_event_t %d\n", press->response_type);
		break;
	}
	case XCB_BUTTON_RELEASE: {
		xcb_button_release_event_t *release = (xcb_button_release_event_t *)event;
		printf("xcb_button_release_event_t %d\n", release->response_type);
		break;
	}
	case XCB_GE_GENERIC:
		// 如果注册了tablet事件,就可以监听到
		xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
		break;
	default:
		/* Unknown event type, ignore it */
		break;
	}

	free (event);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值