Пример #1
0
/** Get the pointer position.
 * \param window The window to get position on.
 * \param x will be set to the Pointer-x-coordinate relative to window
 * \param y will be set to the Pointer-y-coordinate relative to window
 * \param child Will be set to the window under the pointer.
 * \param mask will be set to the current buttons state
 * \return true on success, false if an error occurred
 **/
bool
mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask)
{
    xcb_query_pointer_cookie_t query_ptr_c;
    xcb_query_pointer_reply_t *query_ptr_r;

    query_ptr_c = xcb_query_pointer_unchecked(globalconf.connection, window);
    query_ptr_r = xcb_query_pointer_reply(globalconf.connection, query_ptr_c, NULL);

    if(!query_ptr_r || !query_ptr_r->same_screen)
    {
        p_delete(&query_ptr_r);
        return false;
    }

    *x = query_ptr_r->win_x;
    *y = query_ptr_r->win_y;

    if(mask)
        *mask = query_ptr_r->mask;
    if(child)
        *child = query_ptr_r->child;

    p_delete(&query_ptr_r);

    return true;
}
Пример #2
0
void auto_focus_pointer(void)
{
    xcb_query_pointer_cookie_t c = xcb_query_pointer_unchecked(wm_conf.connection,
                                                               wm_conf.screen->root);
    xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(wm_conf.connection,
                                                               c,
                                                               NULL);
    if (reply) {
        client_t *focus_client = get_focus_client();
        client_t *pointer_client = find_client(reply->child);
        if (!wm_conf.pointer_window)  /* pointer_window hasn't been initialized yet */
            wm_conf.pointer_window = reply->child;
        if (pointer_client) {
            if (wm_conf.pointer_window != pointer_client->window) {
                set_focus_client(pointer_client);
                draw_border(pointer_client);
            }
            wm_conf.pointer_window = pointer_client->window;
        }
        free(reply);
    }
}
Пример #3
0
int main(int argc, char *argv[])
{
    /*
     * variables
     */

    char c;
    int i, screen_num;

    xcb_connection_t *connection;
    xcb_screen_t *next_screen;
    xcb_screen_t *current_screen;
    xcb_screen_iterator_t iterator;
    xcb_query_pointer_reply_t *pointer;

    /*
     * handle the arguments
     */

    while (-1 != (c = getopt_long(argc, argv, "hv", long_options, NULL)))
    {
        switch (c)
        {
            case 'h':
                usage(argv);
                return 0;

            case 'v':
                printf("GPL %s: %s\n"
                        "Copyright (C) 2011 Joško Nikolić\n", PROGRAM_NAME,
                        PROGRAM_VERSION);
                return 0;

            default:
                usage(argv);
                break;
        }
    }

    /*
     * open the connection
     */

    connection = xcb_connect(NULL, &screen_num);

    if (xcb_connection_has_error(connection))
    {
        puts("ERROR: couldn't open display");
        exit(EXIT_FAILURE);
    }

    const xcb_setup_t *setup = xcb_get_setup(connection);
    iterator = xcb_setup_roots_iterator(setup);

    /*
     * find the current screen
     */

    for (i = 0; i < screen_num; ++i)
        xcb_screen_next(&iterator);

    current_screen = iterator.data;

    /*
     * get the next screen to switch to
     */

    xcb_screen_next(&iterator);

    /*
     * if the next screen doesn't exist move the iterator to start
     */

    if (0 == (iterator.data)->width_in_pixels
            && 0 == (iterator.data)->height_in_pixels)
    {
        iterator = xcb_setup_roots_iterator(setup);
    }

    next_screen = iterator.data;

    /*
     * get pointer information
     */

    pointer = xcb_query_pointer_reply(connection,
            xcb_query_pointer_unchecked(connection, current_screen->root),
            NULL);

    if (NULL != pointer)
    {
        /*
         * warp the pointer and focus the new screen
         */

        xcb_warp_pointer(connection, XCB_NONE, next_screen->root, 0, 0, 0, 0,
                pointer->win_x, pointer->win_y);

        xcb_set_input_focus(connection, XCB_INPUT_FOCUS_PARENT,
                next_screen->root, XCB_CURRENT_TIME);

        xcb_flush(connection);
        free(pointer);
    }
    else
        puts("ERROR: couldn't query pointer");

    xcb_disconnect(connection);

    return EXIT_SUCCESS;
}
Пример #4
0
int main(int argc,char**argv){
	xcb_connection_t*d=xcb_connect(0,0);
	int32_t*x,*y,*tx=0,mx,my,rt=xcb_setup_roots_iterator(xcb_get_setup(d)).data->root,cs[255],*cz=cs+1;
	uint8_t mz,mZ;
	xcb_change_window_attributes(d,rt,XCB_CW_EVENT_MASK,&cwa);
	xcb_grab_key(d,1,rt,0,64,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC);
	xcb_grab_key(d,1,rt,8,XCB_GRAB_ANY,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC);
	xcb_grab_button(d,1,rt,XCB_EVENT_MASK_BUTTON_PRESS,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC,XCB_NONE,XCB_NONE,XCB_GRAB_ANY,8);
	#ifdef COMPOSITE
	xcb_composite_redirect_subwindows(d,rt,XCB_COMPOSITE_REDIRECT_AUTOMATIC);
	#endif
	xcb_generic_event_t*e=0;
main:xcb_flush(d);
	waitpid(-1,0,WNOHANG);
noflush:x=y=cz-1;
again:free(e);
	switch((e=xcb_wait_for_event(d))->response_type&127){
	case XCB_BUTTON_PRESS:
		for(;x>cs;x--)
			if(*x==((xcb_button_press_event_t*)e)->child){
				if(((xcb_key_press_event_t*)e)->detail==2)goto pocus;
			case XCB_KEY_PRESS:
				mz=128|((xcb_key_press_event_t*)e)->detail;
				my=((xcb_key_press_event_t*)e)->state;
				goto*(cz==cs+1?&&kcode:&&stack);
			}
		goto noflush;
	case XCB_KEY_RELEASE:
		if(((xcb_key_press_event_t*)e)->detail!=64||!tx)default:goto again;
		xt:x=tx;
		tx=0;
		goto stack;
	case XCB_CONFIGURE_REQUEST:{
		void*p=buf;
		for(mz=0;mz<5;mz++)
			if(((xcb_configure_request_event_t*)e)->value_mask&1<<mz){*(uint32_t*)p=*(int16_t*)(((void*)e)+16+mz*2);p+=4;}
		if(((xcb_configure_request_event_t*)e)->value_mask&XCB_CONFIG_WINDOW_SIBLING){*(uint32_t*)p=((xcb_configure_request_event_t*)e)->sibling;p+=4;}
		if(mz=((xcb_configure_request_event_t*)e)->value_mask&XCB_CONFIG_WINDOW_STACK_MODE)*(uint32_t*)p=((xcb_configure_request_event_t*)e)->stack_mode;
		xcb_configure_window(d,((xcb_configure_request_event_t*)e)->window,((xcb_configure_request_event_t*)e)->value_mask,buf);
		if(mz){
			p=xcb_query_tree_reply(d,xcb_query_tree_unchecked(d,rt),0);
			int32_t*cl=p+32+((xcb_query_tree_reply_t*)p)->children_len*4;
			for(y=p+32;y<cl;y++){
				for(x=cs+1;x<cz;x++)
					if(*x==*y)goto nono;
				*y=0;
				nono:;
			}
			x=cs;
			for(y=p+32;y<cl;y++)
				if(*y)*++x=*y;
			free(p);
			goto pocus;
		}else goto main;}
	case XCB_MAP_REQUEST:{
		void*p=xcb_get_window_attributes_reply(d,xcb_get_window_attributes_unchecked(d,((xcb_map_request_event_t*)e)->window),0);
		if(((xcb_get_window_attributes_reply_t*)p)->override_redirect){
			free(p);
			goto pocus;
		}
		free(p);
		for(;x>cs;x--)
			if(*x==((xcb_map_request_event_t*)e)->window)goto noflush;
		xcb_map_window(d,*cz++=((xcb_map_request_event_t*)e)->window);
		goto hocus;}
	case XCB_MOTION_NOTIFY:
		*buf=mZ&&((xcb_motion_notify_event_t*)e)->root_x<=mx?:((xcb_motion_notify_event_t*)e)->root_x-mx;
		buf[1]=mZ&&((xcb_motion_notify_event_t*)e)->root_y<=my?:((xcb_motion_notify_event_t*)e)->root_y-my;
		xcb_configure_window(d,*x,mZ?XCB_CONFIG_WINDOW_WIDTH|XCB_CONFIG_WINDOW_HEIGHT:XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y,buf);
		goto main;
	case XCB_BUTTON_RELEASE:
		xcb_ungrab_pointer(d,XCB_CURRENT_TIME);
		goto main;
	case XCB_UNMAP_NOTIFY:unmap:goto*(x==cs?&&noflush:*x==((xcb_unmap_notify_event_t*)e)->window&&--cz>cs+1?&&stack:(x--,&&unmap));
	}
stack:mx=*x;
	for(;x!=y;x+=x<y?:-1)*x=x[x<y?:-1];
	*x=mx;
hocus:x=cz-1;
	xcb_configure_window(d,*x,XCB_CONFIG_WINDOW_STACK_MODE,di);
pocus:xcb_set_input_focus(d,XCB_INPUT_FOCUS_POINTER_ROOT,*x,XCB_CURRENT_TIME);
	if(!(mz&128))goto main;
kcode:switch(mz&=127){
	void*p;
	case 1:case 3:
		p=xcb_grab_pointer_reply(d,xcb_grab_pointer_unchecked(d,0,rt,XCB_EVENT_MASK_BUTTON_RELEASE|XCB_EVENT_MASK_POINTER_MOTION,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC,XCB_NONE,XCB_NONE,XCB_CURRENT_TIME),0);
		if(((xcb_grab_pointer_reply_t*)p)->status!=XCB_GRAB_STATUS_SUCCESS){
			free(p);
			goto noflush;
		}
		free(p);
		p=xcb_get_geometry_reply(d,xcb_get_geometry_unchecked(d,*y),0);
		mx=((xcb_get_geometry_reply_t*)p)->x;
		my=((xcb_get_geometry_reply_t*)p)->y;
		free(p);
		if(mZ=mz==1){
			p=xcb_query_pointer_reply(d,xcb_query_pointer_unchecked(d,rt),0);
			mx=((xcb_query_pointer_reply_t*)p)->root_x-mx;
			my=((xcb_query_pointer_reply_t*)p)->root_y-my;
			free(p);
		}
		goto noflush;
	case 23:case 49:
		if(cz-cs<3)goto main;
		y=tx;
		tx=mz==23?(y!=cs+1?(y?:x)-1:x):!y||y==x?cs+1:y+1;
		if(y&&y<cz-1){
			*buf=y[mz==23?:-1];
			buf[1]=mz==23;
			xcb_configure_window(d,*y,XCB_CONFIG_WINDOW_SIBLING|XCB_CONFIG_WINDOW_STACK_MODE,buf);
		}
		xcb_configure_window(d,*tx,XCB_CONFIG_WINDOW_STACK_MODE,di);
		goto main;
	case 32:return 0;
	case 44:
		if(cz>cs+1)xcb_configure_window(d,*y,XCB_CONFIG_WINDOW_X|XCB_CONFIG_WINDOW_Y|XCB_CONFIG_WINDOW_WIDTH|XCB_CONFIG_WINDOW_HEIGHT,di);
		goto main;
	case 46:
		if(cz==cs+1)goto main;
		if(tx)goto*(mz|=128,&&xt);
		{xcb_intern_atom_cookie_t c1=xcb_intern_atom_unchecked(d,0,12,"WM_PROTOCOLS"),c2=xcb_intern_atom_unchecked(d,0,16,"WM_DELETE_WINDOW");
		p=xcb_intern_atom_reply(d,c1,0);
		mx=((xcb_intern_atom_reply_t*)p)->atom;
		free(p);
		p=xcb_intern_atom_reply(d,c2,0);}
		my=((xcb_intern_atom_reply_t*)p)->atom;
		free(p);
		p=xcb_get_property_reply(d,xcb_get_property_unchecked(d,0,*y,mx,XCB_ATOM_ATOM,0,-1),0);
		xcb_send_event(d,0,*y,XCB_EVENT_MASK_NO_EVENT,(void*)(xcb_client_message_event_t[]){{.response_type=XCB_CLIENT_MESSAGE,.window=*y,.type=mx,.format=32,.data.data32={my,XCB_CURRENT_TIME}}});