Esempio n. 1
0
/* We start the exposition when the user touch triangle reactangle at the top left. */
static int _handle_motion_notify(xcb_motion_notify_event_t *e) {
    if (e->root_x + e->root_y < 20 && _this.state == _IDLE && gd.win_count >= 2) {
        _show();
    } else {
        xcb_ungrab_pointer(gd.conn, XCB_TIME_CURRENT_TIME);
        e->time = XCB_CURRENT_TIME;
        xcb_send_event(gd.conn, 1, e->child, 0, (char *) e);
        xcb_grab_pointer(gd.conn, 1, gd.def_screen->root,
                XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_BUTTON_PRESS,
                XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_CURRENT_TIME);
        xcb_flush(gd.conn);
    }
    return 1;
}
Esempio n. 2
0
void menuwin_grab_mouse() {

	if (key_win.mouse_grabed==0) {
		xcb_grab_pointer_cookie_t grab_cookie;
		xcb_grab_pointer_reply_t *grab_reply;
		uint16_t mask=XCB_EVENT_MASK_BUTTON_RELEASE|XCB_EVENT_MASK_BUTTON_PRESS|XCB_EVENT_MASK_LEAVE_WINDOW;

		grab_cookie=xcb_grab_pointer(conn,1,key_win.window,mask,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC,XCB_WINDOW_NONE,XCB_CURSOR_NONE,XCB_CURRENT_TIME);
		xcb_flush(conn);
		grab_reply=xcb_grab_pointer_reply(conn,grab_cookie,0);
		if (grab_reply->status==0) {
			key_win.mouse_grabed=1;
		}
		free(grab_reply);
	}
}
Esempio n. 3
0
File: event.c Progetto: nqv/nilwm
/** Handle the ButtonPress event
 */
static
void handle_button_press(xcb_button_press_event_t *e) {
    NIL_LOG("event: mouse %d pressed: event %d, child %d (%d,%d)",
        e->detail, e->event, e->child, e->event_x, e->event_y);

    if (e->event == bar_.win) {
        if (click_bar(e->event_x)) {
            xcb_flush(nil_.con);
        }
        return;
    }
    /* click on client with modkey */
    if (MOD_MASK_(e->state) == cfg_.mod_key) {
        mouse_evt_.client = find_client(e->child, &mouse_evt_.ws);
        if (!mouse_evt_.client) {
            NIL_ERR("no client %d", e->child);
            goto end;
        }
        NIL_LOG("button on win=%d", mouse_evt_.client->win);
        switch (e->detail) {
        case XCB_BUTTON_INDEX_3:
            mouse_evt_.mode = CURSOR_RESIZE;
            /* warp pointer to lower right */
            mouse_evt_.x1 = mouse_evt_.client->x + mouse_evt_.client->w;
            mouse_evt_.y1 = mouse_evt_.client->y + mouse_evt_.client->h;
            xcb_warp_pointer(nil_.con, XCB_NONE, mouse_evt_.client->win,
                0, 0, 0, 0, mouse_evt_.x1, mouse_evt_.y1);
            break;
        case XCB_BUTTON_INDEX_1:
        default:
            mouse_evt_.mode = CURSOR_MOVE;
            mouse_evt_.x1 = e->event_x;
            mouse_evt_.y1 = e->event_y;
            break;
        }
        /* take control of the pointer in the root window */
        xcb_grab_pointer(nil_.con, 0, nil_.scr->root,
            XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_MOTION,
            XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE,
            nil_.cursor[mouse_evt_.mode], XCB_CURRENT_TIME);
        xcb_flush(nil_.con);
        return;
    }
end:
    /* if unhandled, forward the click to the application */
    xcb_allow_events(nil_.con, XCB_ALLOW_REPLAY_POINTER, e->time);
}
Esempio n. 4
0
static bool grab_pointer(xcb_connection_t *conn, xcb_screen_t *screen) {
    xcb_grab_pointer_cookie_t cookie = xcb_grab_pointer(conn,
        false,
        screen->root,
        XCB_NONE,
        XCB_GRAB_MODE_ASYNC,
        XCB_GRAB_MODE_ASYNC,
        XCB_NONE,
        XCB_NONE,
        XCB_CURRENT_TIME);

    xcb_grab_pointer_reply_t *reply;
    if ((reply = xcb_grab_pointer_reply(conn, cookie, NULL))) {
        if (reply->status == XCB_GRAB_STATUS_SUCCESS) {
            free(reply);
            return true;
        }
        free(reply);
    }
    return false;
}
Esempio n. 5
0
xcb_window_t Select_Window(xcb_connection_t *dpy,
			   const xcb_screen_t *screen,
			   int descend)
{
    xcb_cursor_t cursor;
    xcb_generic_event_t *event;
    xcb_window_t target_win = XCB_WINDOW_NONE;
    xcb_window_t root = screen->root;
    int buttons = 0;
    xcb_generic_error_t *err;
    xcb_grab_pointer_cookie_t grab_cookie;
    xcb_grab_pointer_reply_t *grab_reply;

    /* Make the target cursor */
    cursor = Create_Font_Cursor (dpy, XC_crosshair);

    /* Grab the pointer using target cursor, letting it room all over */
    grab_cookie = xcb_grab_pointer
	(dpy, False, root,
	 XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
	 XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
	 root, cursor, XCB_TIME_CURRENT_TIME);
    grab_reply = xcb_grab_pointer_reply (dpy, grab_cookie, &err);
    if (grab_reply->status != XCB_GRAB_STATUS_SUCCESS)
	Fatal_Error ("Can't grab the mouse.");

    /* Let the user select a window... */
    while ((target_win == XCB_WINDOW_NONE) || (buttons != 0)) {
	/* allow one more event */
	xcb_allow_events (dpy, XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME);
	xcb_flush (dpy);
	event = xcb_wait_for_event (dpy);
	switch (event->response_type & 0x7f) {
	case XCB_BUTTON_PRESS:
	{
	    xcb_button_press_event_t *bp = (xcb_button_press_event_t *)event;

	    if (target_win == XCB_WINDOW_NONE) {
		target_win = bp->child; /* window selected */
		if (target_win == XCB_WINDOW_NONE)
		    target_win = root;
	    }
	    buttons++;
	    break;
	}
	case XCB_BUTTON_RELEASE:
	    if (buttons > 0) /* there may have been some down before we started */
		buttons--;
	    break;
	default:
	    /* just discard all other events */
	    break;
	}
	free (event);
    }

    xcb_ungrab_pointer (dpy, XCB_TIME_CURRENT_TIME); /* Done with pointer */

    if (!descend || (target_win == root))
	return (target_win);

    target_win = Find_Client (dpy, root, target_win);

    return (target_win);
}
Esempio n. 6
0
File: xcb.c Progetto: eplanet/i3lock
/*
 * Repeatedly tries to grab pointer and keyboard (up to the specified number of
 * tries).
 *
 * Returns true if the grab succeeded, false if not.
 *
 */
bool grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor, int tries) {
    xcb_grab_pointer_cookie_t pcookie;
    xcb_grab_pointer_reply_t *preply;

    xcb_grab_keyboard_cookie_t kcookie;
    xcb_grab_keyboard_reply_t *kreply;

    const suseconds_t screen_redraw_timeout = 100000; /* 100ms */

    /* Using few variables to trigger a redraw_screen() if too many tries */
    bool redrawn = false;
    struct timeval start;
    if (gettimeofday(&start, NULL) == -1) {
        err(EXIT_FAILURE, "gettimeofday");
    }

    while (tries-- > 0) {
        pcookie = xcb_grab_pointer(
            conn,
            false,               /* get all pointer events specified by the following mask */
            screen->root,        /* grab the root window */
            XCB_NONE,            /* which events to let through */
            XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
            XCB_GRAB_MODE_ASYNC, /* keyboard mode */
            XCB_NONE,            /* confine_to = in which window should the cursor stay */
            cursor,              /* we change the cursor to whatever the user wanted */
            XCB_CURRENT_TIME);

        if ((preply = xcb_grab_pointer_reply(conn, pcookie, NULL)) &&
            preply->status == XCB_GRAB_STATUS_SUCCESS) {
            free(preply);
            break;
        }

        /* Make this quite a bit slower */
        usleep(50);

        struct timeval now;
        if (gettimeofday(&now, NULL) == -1) {
            err(EXIT_FAILURE, "gettimeofday");
        }

        struct timeval elapsed;
        timersub(&now, &start, &elapsed);

        if (!redrawn &&
            (tries % 100) == 0 &&
            elapsed.tv_usec >= screen_redraw_timeout) {
            redraw_screen();
            redrawn = true;
        }
    }

    while (tries-- > 0) {
        kcookie = xcb_grab_keyboard(
            conn,
            true,         /* report events */
            screen->root, /* grab the root window */
            XCB_CURRENT_TIME,
            XCB_GRAB_MODE_ASYNC, /* process events as normal, do not require sync */
            XCB_GRAB_MODE_ASYNC);

        if ((kreply = xcb_grab_keyboard_reply(conn, kcookie, NULL)) &&
            kreply->status == XCB_GRAB_STATUS_SUCCESS) {
            free(kreply);
            break;
        }

        /* Make this quite a bit slower */
        usleep(50);

        struct timeval now;
        if (gettimeofday(&now, NULL) == -1) {
            err(EXIT_FAILURE, "gettimeofday");
        }

        struct timeval elapsed;
        timersub(&now, &start, &elapsed);

        /* Trigger a screen redraw if 100ms elapsed */
        if (!redrawn &&
            (tries % 100) == 0 &&
            elapsed.tv_usec >= screen_redraw_timeout) {
            redraw_screen();
            redrawn = true;
        }
    }

    return (tries > 0);
}
Esempio n. 7
0
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;

	/* 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;

  G.conn = c;
  G.s= s;

  //enable mouse event
  xcb_cursor_t cursor;
  xcb_font_t cursor_font=0;
  short glyph = 0x34; //cross
  xcb_grab_pointer_cookie_t grab_cookie;
  xcb_grab_pointer_reply_t *grab_reply;
  xcb_generic_error_t *err;
  cursor = xcb_generate_id (c);
  if (!cursor_font) {
    cursor_font = xcb_generate_id (c);
    xcb_open_font (c, cursor_font, strlen ("cursor"), "cursor");
  }

  xcb_create_glyph_cursor (c, cursor, cursor_font, cursor_font,
      glyph, glyph + 1,
      0, 0, 0, 0xffff, 0xffff, 0xffff);  /* rgb, rgb */

  grab_cookie = xcb_grab_pointer(c, 0, s->root,
  		XCB_EVENT_MASK_POINTER_MOTION |
     XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
     XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
     s->root, cursor, XCB_TIME_CURRENT_TIME);

  assert(grab_reply!=NULL);
  grab_reply = xcb_grab_pointer_reply (c, grab_cookie, &err);
  if (grab_reply->status != XCB_GRAB_STATUS_SUCCESS)
    printf("Can't grab the mouse.");

  printf("grab pointer cookie=0x%x\n", grab_cookie);
  xcb_allow_events (c, XCB_ALLOW_ASYNC_POINTER, XCB_TIME_CURRENT_TIME);  xcb_flush (c);
//  xcb_allow_events (c, XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME);  xcb_flush (c);

	while (!done ) {
 e = xcb_wait_for_event(c);
 if(e==NULL) printf("wait event error\n");
		//printf("\revent=>%d", e->response_type);
		switch (e->response_type & ~0x80) {
			case XCB_EXPOSE:    /* draw or redraw the window */
          printf("XCB_EXPOSE\n");
          draw_gc(w);
				break;
			case XCB_MOTION_NOTIFY:
				{
					static xcb_window_t    oldw;
        xcb_button_press_event_t *bp = (xcb_button_press_event_t *)e;
        w = bp->child; /* window selected */
        if(oldw!=w){
					oldw = w;
					printf("windowid = %x\n", w);
				}
				//draw it 
				draw_gc(w);
					}
				break;
      case XCB_BUTTON_PRESS:
        {
        xcb_button_press_event_t *bp = (xcb_button_press_event_t *)e;
        w = bp->child; /* window selected */
        if (w== XCB_WINDOW_NONE){
          printf("window select is root\n");
          w=s->root;
        }
        else
          printf("window = %x\n", w);
				draw_gc(w);
        done=1; printf("grab a child\n");
        break;
        }
		}
		free(e);
	}

  xcb_ungrab_pointer(c, XCB_TIME_CURRENT_TIME);

  draw_byxid(w);
  return 0;

#if 0
	/* 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, 1,
			XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual,
			mask, values);

	/* map (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 & ~0x80) {
			case XCB_EXPOSE:    /* draw or redraw the window */
				xcb_poly_fill_rectangle(c, w, g,  1, &r);
				xcb_flush(c);
				break;
			case XCB_KEY_PRESS:  /* exit on key press */
				//gwj done = 1;
				break;
		}
		free(e);
	}
	/* close connection to server */
	xcb_disconnect(c);

	return 0;
  if(0){
  //draw image with xcb_put_image
  // creat gc and draw to parent window
	xcb_gcontext_t       g;
	g = xcb_generate_id(c);
	xcb_create_gc(c, g, child, 0,NULL);
  //xcb_poly_fill_rectangle(c, w, g,  1, &r); xcb_flush(c);

  int psize=geo->width * geo->height* (geo->depth/8);
  uint8_t *pbuf = malloc(psize);
  xcb_void_cookie_t ck;
  printf("malloc pbuf=0x%x size=%d\n",pbuf, psize);
  memset(pbuf, 0x18, psize);

  ck = xcb_put_image_checked(c, XCB_IMAGE_FORMAT_Z_PIXMAP,
      child, g,
      geo->width, geo->height , 0, 0,
       0, geo->depth,
     psize, pbuf);

	//BadMatch=8 BadLength=16
    xcb_generic_error_t *err;
    err = xcb_request_check (c, ck);
    if (err)
    {
      int code = err->error_code;
      free (err);
      printf("put image error %d\n", code);
      assert (code != 0);
    }   
  }
  printf("depth =%d\n", geo->depth);
	/* create black graphics context */
#endif
}
Esempio n. 8
0
/*
 * Repeatedly tries to grab pointer and keyboard (up to 10000 times).
 *
 */
void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor) {
    xcb_grab_pointer_cookie_t pcookie;
    xcb_grab_pointer_reply_t *preply;

    xcb_grab_keyboard_cookie_t kcookie;
    xcb_grab_keyboard_reply_t *kreply;

    int tries = 10000;

    /* Using few variables to trigger a redraw_screen() if too many tries */
    bool redrawn = false;
    time_t start = clock();

    while (tries-- > 0) {
        pcookie = xcb_grab_pointer(
            conn,
            false,               /* get all pointer events specified by the following mask */
            screen->root,        /* grab the root window */
            XCB_NONE,            /* which events to let through */
            XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
            XCB_GRAB_MODE_ASYNC, /* keyboard mode */
            XCB_NONE,            /* confine_to = in which window should the cursor stay */
            cursor,              /* we change the cursor to whatever the user wanted */
            XCB_CURRENT_TIME);

        if ((preply = xcb_grab_pointer_reply(conn, pcookie, NULL)) &&
            preply->status == XCB_GRAB_STATUS_SUCCESS) {
            free(preply);
            break;
        }

        /* Make this quite a bit slower */
        usleep(50);

        /* Measure elapsed time and trigger a screen redraw if elapsed > 250000 */
        if (!redrawn &&
            (tries % 100) == 0 &&
            (clock() - start) > 250000) {
            redraw_screen();
            redrawn = true;
        }
    }

    while (tries-- > 0) {
        kcookie = xcb_grab_keyboard(
            conn,
            true,         /* report events */
            screen->root, /* grab the root window */
            XCB_CURRENT_TIME,
            XCB_GRAB_MODE_ASYNC, /* process events as normal, do not require sync */
            XCB_GRAB_MODE_ASYNC);

        if ((kreply = xcb_grab_keyboard_reply(conn, kcookie, NULL)) &&
            kreply->status == XCB_GRAB_STATUS_SUCCESS) {
            free(kreply);
            break;
        }

        /* Make this quite a bit slower */
        usleep(50);

        /* Measure elapsed time and trigger a screen redraw if elapsed > 250000 */
        if (!redrawn &&
            (tries % 100) == 0 &&
            (clock() - start) > 250000) {
            redraw_screen();
            redrawn = true;
        }
    }

    /* After trying for 10000 times, i3lock will display an error message
     * for 2 sec prior to terminate. */
    if (tries <= 0) {
        pam_state = STATE_I3LOCK_LOCK_FAILED;
        redraw_screen();
        sleep(1);
        errx(EXIT_FAILURE, "Cannot grab pointer/keyboard");
    }
}
Esempio n. 9
0
File: swm.c Progetto: JuliusP/swm
static void
events_loop (void) {
	uint32_t values[3];
	xcb_generic_event_t *ev;
	xcb_get_geometry_reply_t *geom;
	xcb_window_t win = 0;

	/* loop */
	for (;;) {
		ev = xcb_wait_for_event(conn);

		if (ev == NULL)
			errx(1, "xcb connection broken");

		switch (ev->response_type & ~0x80) {

		case XCB_CREATE_NOTIFY: {
			xcb_create_notify_event_t *e;
			e = (xcb_create_notify_event_t *)ev;

			if (!e->override_redirect) {
				setup_win(e->window);
				focus(e->window, ACTIVE);
			}
		} break;

		case XCB_DESTROY_NOTIFY: {
			xcb_destroy_notify_event_t *e;
			e = (xcb_destroy_notify_event_t *)ev;

			xcb_kill_client(conn, e->window);
		} break;

		case XCB_KEY_PRESS: {
			xcb_key_press_event_t *e;
			e = (xcb_key_press_event_t *)ev;

			xcb_keysym_t keysym = xcb_get_keysym(e->detail);

			for (unsigned int i=0; i < LENGTH(keys); i++) {
				if (keys[i].keysym == keysym
				&& CLEANMASK(keys[i].mod) == CLEANMASK(e->state)
				&& keys[i].mfunc) {
					keys[i].mfunc(keys[i].x, keys[i].y);
				}
				else if (keys[i].keysym == keysym
				&& CLEANMASK(keys[i].mod) == CLEANMASK(e->state)
				&& keys[i].func) {
					keys[i].func();
				}
			}
				} break;

		case XCB_ENTER_NOTIFY: {
			xcb_enter_notify_event_t *e;
			e = (xcb_enter_notify_event_t *)ev;

			focus(e->event, ACTIVE);
		} break;

		case XCB_MAP_NOTIFY: {
			xcb_map_notify_event_t *e;
			e = (xcb_map_notify_event_t *)ev;

			if (!e->override_redirect) {
				xcb_map_window(conn, e->window);
				xcb_set_input_focus(conn,
					XCB_INPUT_FOCUS_POINTER_ROOT,
					e->window, XCB_CURRENT_TIME);
			}
		} break;

		case XCB_BUTTON_PRESS: {
			xcb_button_press_event_t *e;
			e = ( xcb_button_press_event_t *)ev;
			win = e->child;
			if (!win || win == scr->root)
				break;
			values[0] = XCB_STACK_MODE_ABOVE;
			xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_STACK_MODE, values);
			geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
			if (1 == e->detail) {
				values[2] = 1;
				center_pointer(win);
			} else {
				values[2] = 3;
				xcb_warp_pointer(conn, XCB_NONE, win, 0, 0, 0,
						0, geom->width, geom->height);
			}
			xcb_grab_pointer(conn, 0, scr->root,
				XCB_EVENT_MASK_BUTTON_RELEASE
				| XCB_EVENT_MASK_BUTTON_MOTION
				| XCB_EVENT_MASK_POINTER_MOTION_HINT,
				XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
				scr->root, XCB_NONE, XCB_CURRENT_TIME);
			xcb_flush(conn);
		} break;

		case XCB_MOTION_NOTIFY: {
			xcb_query_pointer_reply_t *pointer;
			pointer = xcb_query_pointer_reply(conn,
					xcb_query_pointer(conn, scr->root), 0);
			if (values[2] == 1) {
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				if (!geom) {
					break;
				}

				values[0] = (pointer->root_x + geom->width / 2
					> scr->width_in_pixels
					- (BORDERWIDTH*2))
					? scr->width_in_pixels - geom->width
					- (BORDERWIDTH*2)
					: pointer->root_x - geom->width / 2;
				values[1] = (pointer->root_y + geom->height / 2
					> scr->height_in_pixels
					- (BORDERWIDTH*2))
					? (scr->height_in_pixels - geom->height
					- (BORDERWIDTH*2))
					: pointer->root_y - geom->height / 2;

				if (pointer->root_x < geom->width/2)
					values[0] = 0;
				if (pointer->root_y < geom->height/2)
					values[1] = 0;

				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_X
					| XCB_CONFIG_WINDOW_Y, values);
				xcb_flush(conn);
			} else if (values[2] == 3) {
				focus(win, RESIZE);
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				values[0] = pointer->root_x - geom->x;
				values[1] = pointer->root_y - geom->y;
				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_WIDTH
					| XCB_CONFIG_WINDOW_HEIGHT, values);
				xcb_flush(conn);
			}
		} break;

		case XCB_BUTTON_RELEASE:
			focus(win, ACTIVE);
			xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
			break;
		}

		xcb_flush(conn);
		free(ev);
	}
}
Esempio n. 10
0
static void
ephyrProcessKeyRelease(xcb_generic_event_t *xev)
{
    xcb_connection_t *conn = hostx_get_xcbconn();
    xcb_key_release_event_t *key = (xcb_key_release_event_t *)xev;
    static xcb_key_symbols_t *keysyms;
    static int grabbed_screen = -1;
    int mod1_down = ephyrUpdateGrabModifierState(key->state);

    if (!keysyms)
        keysyms = xcb_key_symbols_alloc(conn);

    if (!EphyrWantNoHostGrab &&
        (((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_L
          || xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_R)
         && (key->state & XCB_MOD_MASK_CONTROL)) ||
        ((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_L
          || xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Control_R)
         && (key->state & XCB_MOD_MASK_SHIFT)))) {
        KdScreenInfo *screen = screen_from_window(key->event);
        EphyrScrPriv *scrpriv = screen->driver;

        if (grabbed_screen != -1) {
            xcb_ungrab_keyboard(conn, XCB_TIME_CURRENT_TIME);
            xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME);
            grabbed_screen = -1;
            hostx_set_win_title(screen,
                                "(ctrl+shift grabs mouse and keyboard)");
        }
        else if (!mod1_down) {
            /* Attempt grab */
            xcb_grab_keyboard_cookie_t kbgrabc =
                xcb_grab_keyboard(conn,
                                  TRUE,
                                  scrpriv->win,
                                  XCB_TIME_CURRENT_TIME,
                                  XCB_GRAB_MODE_ASYNC,
                                  XCB_GRAB_MODE_ASYNC);
            xcb_grab_keyboard_reply_t *kbgrabr;
            xcb_grab_pointer_cookie_t pgrabc =
                xcb_grab_pointer(conn,
                                 TRUE,
                                 scrpriv->win,
                                 0,
                                 XCB_GRAB_MODE_ASYNC,
                                 XCB_GRAB_MODE_ASYNC,
                                 scrpriv->win,
                                 XCB_NONE,
                                 XCB_TIME_CURRENT_TIME);
            xcb_grab_pointer_reply_t *pgrabr;
            kbgrabr = xcb_grab_keyboard_reply(conn, kbgrabc, NULL);
            if (!kbgrabr || kbgrabr->status != XCB_GRAB_STATUS_SUCCESS) {
                xcb_discard_reply(conn, pgrabc.sequence);
                xcb_ungrab_pointer(conn, XCB_TIME_CURRENT_TIME);
            } else {
                pgrabr = xcb_grab_pointer_reply(conn, pgrabc, NULL);
                if (!pgrabr || pgrabr->status != XCB_GRAB_STATUS_SUCCESS)
                    {
                        xcb_ungrab_keyboard(conn,
                                            XCB_TIME_CURRENT_TIME);
                    } else {
                    grabbed_screen = scrpriv->mynum;
                    hostx_set_win_title
                        (screen,
                         "(ctrl+shift releases mouse and keyboard)");
                }
            }
        }
    }

    if (!ephyrKbd ||
        !((EphyrKbdPrivate *) ephyrKbd->driverPrivate)->enabled) {
        return;
    }

    /* Still send the release event even if above has happened server
     * will get confused with just an up event.  Maybe it would be
     * better to just block shift+ctrls getting to kdrive all
     * together.
     */
    ephyrUpdateModifierState(key->state);
    KdEnqueueKeyboardEvent(ephyrKbd, key->detail, TRUE);
}
Esempio n. 11
0
/*
 * Repeatedly tries to grab pointer and keyboard (up to 1000 times).
 *
 */
void grab_pointer_and_keyboard(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_t cursor) {
    xcb_grab_pointer_cookie_t pcookie;
    xcb_grab_pointer_reply_t *preply;

    xcb_grab_keyboard_cookie_t kcookie;
    xcb_grab_keyboard_reply_t *kreply;

    // do we need it?
    //xcb_void_cookie_t bcookie;

    int tries = 10000;

    while (tries-- > 0) {
        pcookie = xcb_grab_pointer(
            conn,
            true,               /* get all pointer events specified by the following mask */
            screen->root,        /* grab the root window */
            XCB_NONE,            /* which events to let through */
            XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
            XCB_GRAB_MODE_ASYNC, /* keyboard mode */
            XCB_NONE,            /* confine_to = in which window should the cursor stay */
            cursor,              /* we change the cursor to whatever the user wanted */
            XCB_CURRENT_TIME);

        if ((preply = xcb_grab_pointer_reply(conn, pcookie, NULL)) &&
            preply->status == XCB_GRAB_STATUS_SUCCESS) {
            free(preply);
            break;
        }

        /* Make this quite a bit slower */
        usleep(50);
    }

    while (tries-- > 0) {
        kcookie = xcb_grab_keyboard(
            conn,
            true,         /* report events */
            screen->root, /* grab the root window */
            XCB_CURRENT_TIME,
            XCB_GRAB_MODE_ASYNC, /* process events as normal, do not require sync */
            XCB_GRAB_MODE_ASYNC);

        if ((kreply = xcb_grab_keyboard_reply(conn, kcookie, NULL)) &&
            kreply->status == XCB_GRAB_STATUS_SUCCESS) {
            free(kreply);
            break;
        }

        /* Make this quite a bit slower */
        usleep(50);
    }
/*
    bcookie = xcb_grab_button(
        conn,
        true,         // report events
        screen->root, // grab the root window
        XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
        XCB_GRAB_MODE_SYNC, // process events as normal, do not require sync 
        XCB_GRAB_MODE_ASYNC,
        screen->root, // confine_to
        XCB_NONE,
        XCB_BUTTON_INDEX_ANY,
        XCB_MOD_MASK_ANY); // cursor
   */ 
    if (tries <= 0)
        errx(EXIT_FAILURE, "Cannot grab pointer/keyboard");
}
Esempio n. 12
0
static void
events_loop(void)
{
	xcb_generic_event_t *ev;
#ifdef ENABLE_MOUSE
	uint32_t values[3];
	xcb_get_geometry_reply_t *geom;
	xcb_window_t win = 0;
#endif

	/* loop */
	for (;;) {
		ev = xcb_wait_for_event(conn);

		if (!ev)
			errx(1, "xcb connection broken");

		switch (CLEANMASK(ev->response_type)) {

		case XCB_CREATE_NOTIFY: {
			xcb_create_notify_event_t *e;
			e = (xcb_create_notify_event_t *)ev;

			if (!e->override_redirect) {
				subscribe(e->window);
				focus(e->window, ACTIVE);
			}
		} break;

		case XCB_DESTROY_NOTIFY: {
			xcb_destroy_notify_event_t *e;
			e = (xcb_destroy_notify_event_t *)ev;

			xcb_kill_client(conn, e->window);
		} break;

#ifdef ENABLE_SLOPPY
		case XCB_ENTER_NOTIFY: {
			xcb_enter_notify_event_t *e;
			e = (xcb_enter_notify_event_t *)ev;
			focus(e->event, ACTIVE);
		} break;
#endif

		case XCB_MAP_NOTIFY: {
			xcb_map_notify_event_t *e;
			e = (xcb_map_notify_event_t *)ev;

			if (!e->override_redirect) {
				xcb_map_window(conn, e->window);
				focus(e->window, ACTIVE);
			}
		} break;

#ifdef ENABLE_MOUSE
		case XCB_BUTTON_PRESS: {
			xcb_button_press_event_t *e;
			e = ( xcb_button_press_event_t *)ev;
			win = e->child;

			if (!win || win == scr->root)
				break;

			values[0] = XCB_STACK_MODE_ABOVE;
			xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_STACK_MODE, values);
			geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
			if (e->detail == 1) {
				values[2] = 1;
				xcb_warp_pointer(conn, XCB_NONE, win, 0, 0, 0,
					0, geom->width/2, geom->height/2);
			} else {
				values[2] = 3;
				xcb_warp_pointer(conn, XCB_NONE, win, 0, 0, 0,
						0, geom->width, geom->height);
			}
			xcb_grab_pointer(conn, 0, scr->root,
				XCB_EVENT_MASK_BUTTON_RELEASE
				| XCB_EVENT_MASK_BUTTON_MOTION
				| XCB_EVENT_MASK_POINTER_MOTION_HINT,
				XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
				scr->root, XCB_NONE, XCB_CURRENT_TIME);
			xcb_flush(conn);
		} break;

		case XCB_MOTION_NOTIFY: {
			xcb_query_pointer_reply_t *pointer;
			pointer = xcb_query_pointer_reply(conn,
					xcb_query_pointer(conn, scr->root), 0);
			if (values[2] == 1) {
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				if (!geom)
					break;

				values[0] = (pointer->root_x + geom->width / 2
					> scr->width_in_pixels
					- (BORDERWIDTH*2))
					? scr->width_in_pixels - geom->width
					- (BORDERWIDTH*2)
					: pointer->root_x - geom->width / 2;
				values[1] = (pointer->root_y + geom->height / 2
					> scr->height_in_pixels
					- (BORDERWIDTH*2))
					? (scr->height_in_pixels - geom->height
					- (BORDERWIDTH*2))
					: pointer->root_y - geom->height / 2;

				if (pointer->root_x < geom->width/2)
					values[0] = 0;
				if (pointer->root_y < geom->height/2)
					values[1] = 0;

				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_X
					| XCB_CONFIG_WINDOW_Y, values);
				xcb_flush(conn);
			} else if (values[2] == 3) {
				geom = xcb_get_geometry_reply(conn,
					xcb_get_geometry(conn, win), NULL);
				values[0] = pointer->root_x - geom->x;
				values[1] = pointer->root_y - geom->y;
				xcb_configure_window(conn, win,
					XCB_CONFIG_WINDOW_WIDTH
					| XCB_CONFIG_WINDOW_HEIGHT, values);
				xcb_flush(conn);
			}
		} break;

		case XCB_BUTTON_RELEASE:
			focus(win, ACTIVE);
			xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
			break;
#endif

		case XCB_CONFIGURE_NOTIFY: {
			xcb_configure_notify_event_t *e;
			e = (xcb_configure_notify_event_t *)ev;

			if (e->window != focuswin)
				focus(e->window, INACTIVE);

			focus(focuswin, ACTIVE);
		} break;

		}

		xcb_flush(conn);
		free(ev);
	}
}