void query_pointer(xcb_window_t *win, xcb_point_t *pt) { xcb_query_pointer_reply_t *qpr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), NULL); if (qpr != NULL) { if (win != NULL) { *win = qpr->child; xcb_point_t pt = {qpr->root_x, qpr->root_y}; for (stacking_list_t *s = stack_tail; s != NULL; s = s->prev) { if (!s->node->client->shown || s->node->hidden) { continue; } xcb_rectangle_t rect = get_rectangle(NULL, s->node); if (is_inside(pt, rect)) { if (s->node->id == qpr->child || is_presel_window(qpr->child)) { *win = s->node->id; } break; } } } if (pt != NULL) { *pt = (xcb_point_t) {qpr->root_x, qpr->root_y}; } } free(qpr); }
//_________________________________________________________ WId DetectDialog::findWindow() { #if BREEZE_HAVE_X11 if (!QX11Info::isPlatformX11()) { return 0; } // check atom if( !m_wmStateAtom ) return 0; xcb_connection_t* connection( QX11Info::connection() ); xcb_window_t parent( QX11Info::appRootWindow() ); // why is there a loop of only 10 here for( int i = 0; i < 10; ++i ) { // query pointer xcb_query_pointer_cookie_t pointerCookie( xcb_query_pointer( connection, parent ) ); QScopedPointer<xcb_query_pointer_reply_t, QScopedPointerPodDeleter> pointerReply( xcb_query_pointer_reply( connection, pointerCookie, nullptr ) ); if( !( pointerReply && pointerReply->child ) ) return 0; const xcb_window_t child( pointerReply->child ); xcb_get_property_cookie_t cookie( xcb_get_property( connection, 0, child, m_wmStateAtom, XCB_GET_PROPERTY_TYPE_ANY, 0, 0 ) ); QScopedPointer<xcb_get_property_reply_t, QScopedPointerPodDeleter> reply( xcb_get_property_reply( connection, cookie, nullptr ) ); if( reply && reply->type ) return child; else parent = child; } #endif return 0; }
Vector2i InputImpl::getMousePosition() { // Open a connection with the X server xcb_connection_t* connection = OpenConnection(); ScopedXcbPtr<xcb_generic_error_t> error(NULL); ScopedXcbPtr<xcb_query_pointer_reply_t> pointer( xcb_query_pointer_reply( connection, xcb_query_pointer( connection, XCBDefaultRootWindow(connection) ), &error ) ); // Close the connection with the X server CloseConnection(connection); if (error) { err() << "Failed to query pointer" << std::endl; return Vector2i(0, 0); } return Vector2i(pointer->root_x, pointer->root_y); }
void QXcbCursor::queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask) { if (pos) *pos = QPoint(); xcb_screen_iterator_t it = xcb_setup_roots_iterator(c->setup()); while (it.rem) { xcb_window_t root = it.data->root; xcb_query_pointer_cookie_t cookie = xcb_query_pointer(c->xcb_connection(), root); xcb_generic_error_t *err = 0; xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(c->xcb_connection(), cookie, &err); if (!err && reply) { if (pos) *pos = QPoint(reply->root_x, reply->root_y); if (rootWin) *rootWin = root; if (keybMask) *keybMask = reply->mask; free(reply); return; } free(err); free(reply); xcb_screen_next(&it); } }
/* Get the pointer position. */ void fwm_pointer_getxy(int16_t *x, int16_t *y) { xcb_query_pointer_reply_t *r; r = xcb_query_pointer_reply(gd.conn, xcb_query_pointer(gd.conn, gd.def_screen->root), NULL); *x = r->root_x; *y = r->root_y; /* Tiis implies grabbing pointer, but not doing so by now. * x = _this.root_x; * y = _this.root_y; */ }
ExcCode screen_cursor_get_position(int *x, int *y, int *same_screen) { xcb_query_pointer_cookie_t cookie = xcb_query_pointer(display, root); xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(display, cookie, NULL); if (reply == NULL) PANIC(ERR_X_REQUEST, "screen_cursor_get_position"); *x = reply->root_x; *y = reply->root_y; *same_screen = reply->same_screen; free(reply); return 0; }
/** * @param x The x position of the mouse [out] * @param y The y position of the mouse [out] * * find mouse pointer location * * @returns 1 when found */ static int pointer_get ( xcb_window_t root, int *x, int *y ) { *x = 0; *y = 0; xcb_query_pointer_cookie_t c = xcb_query_pointer ( xcb->connection, root ); xcb_query_pointer_reply_t *r = xcb_query_pointer_reply ( xcb->connection, c, NULL ); if ( r ) { *x = r->root_x; *y = r->root_y; free ( r ); return 1; } return 0; }
bool InputImpl::isMouseButtonPressed(Mouse::Button button) { // Open a connection with the X server xcb_connection_t* connection = OpenConnection(); ScopedXcbPtr<xcb_generic_error_t> error(NULL); // Get pointer mask ScopedXcbPtr<xcb_query_pointer_reply_t> pointer( xcb_query_pointer_reply( connection, xcb_query_pointer( connection, XCBDefaultRootWindow(connection) ), &error ) ); // Close the connection with the X server CloseConnection(connection); if (error) { err() << "Failed to query pointer" << std::endl; return false; } uint16_t buttons = pointer->mask; switch (button) { case Mouse::Left: return buttons & XCB_BUTTON_MASK_1; case Mouse::Right: return buttons & XCB_BUTTON_MASK_3; case Mouse::Middle: return buttons & XCB_BUTTON_MASK_2; case Mouse::XButton1: return false; // not supported by X case Mouse::XButton2: return false; // not supported by X default: return false; } }
/* * Find child window at pointer location */ static xcb_window_t Find_Child_At_Pointer(xcb_connection_t * dpy, xcb_window_t win) { xcb_window_t child_return = XCB_WINDOW_NONE; xcb_query_pointer_cookie_t qp_cookie; xcb_query_pointer_reply_t *qp_reply; qp_cookie = xcb_query_pointer (dpy, win); qp_reply = xcb_query_pointer_reply (dpy, qp_cookie, NULL); if (qp_reply) { child_return = qp_reply->child; free (qp_reply); } return child_return; }
void XQueryPointer(Display *display, Window w, Window *root_return, Window *child_return, int *root_x_return, int *root_y_return, int *win_x_return, int *win_y_return, unsigned int *mask_return) { xcb_query_pointer_cookie_t cookie = xcb_query_pointer(display, w); xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(display, cookie, NULL); if (reply == NULL) fatal("Error in X11 communication\n"); *root_return = reply->root; *child_return = reply->child; *root_x_return = reply->root_x; *root_y_return = reply->root_y; *win_x_return = reply->win_x; *win_y_return = reply->win_y; *mask_return = reply->mask; free(reply); }
void query_pointer(xcb_window_t *win, xcb_point_t *pt) { window_lower(motion_recorder); xcb_query_pointer_reply_t *qpr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), NULL); if (qpr != NULL) { if (win != NULL) { *win = qpr->child; } if (pt != NULL) { *pt = (xcb_point_t) {qpr->root_x, qpr->root_y}; } } free(qpr); window_raise(motion_recorder); }
Vector2i InputImpl::getMousePosition(const Window& relativeTo) { WindowHandle handle = relativeTo.getSystemHandle(); if (handle) { // Open a connection with the X server xcb_connection_t* connection = OpenConnection(); ScopedXcbPtr<xcb_generic_error_t> error(NULL); ScopedXcbPtr<xcb_query_pointer_reply_t> pointer( xcb_query_pointer_reply( connection, xcb_query_pointer( connection, handle ), &error ) ); // Close the connection with the X server CloseConnection(connection); if (error) { err() << "Failed to query pointer" << std::endl; return Vector2i(0, 0); } return Vector2i(pointer->win_x, pointer->win_y); } else { return Vector2i(); } }
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); } }
void ae3d::Window::PumpEvents() { xcb_generic_event_t* event; while ((event = xcb_poll_for_event( WindowGlobal::connection ))) { //const bool synthetic_event = (event->response_type & 0x80) != 0; const uint8_t response_type = event->response_type & ~0x80; switch (response_type) { case XCB_EVENT_MASK_BUTTON_PRESS: case XCB_EVENT_MASK_BUTTON_RELEASE: { const xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply( WindowGlobal::connection, xcb_query_pointer(WindowGlobal::connection, XDefaultRootWindow(WindowGlobal::display)), nullptr ); const bool newb1 = (pointer->mask & XCB_BUTTON_MASK_1) != 0; const bool newb2 = (pointer->mask & XCB_BUTTON_MASK_2) != 0; const bool newb3 = (pointer->mask & XCB_BUTTON_MASK_3) != 0; const xcb_button_press_event_t* be = (xcb_button_press_event_t*)event; const auto b1Type = response_type == XCB_EVENT_MASK_BUTTON_PRESS ? ae3d::WindowEventType::Mouse1Down : ae3d::WindowEventType::Mouse1Up; const auto b2Type = response_type == XCB_EVENT_MASK_BUTTON_PRESS ? ae3d::WindowEventType::Mouse2Down : ae3d::WindowEventType::Mouse2Up; const auto b3Type = response_type == XCB_EVENT_MASK_BUTTON_PRESS ? ae3d::WindowEventType::MouseMiddleDown : ae3d::WindowEventType::MouseMiddleUp; WindowGlobal::IncEventIndex(); if (newb1) { WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b1Type; } else if (newb3) { WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b2Type; } else if (newb2) { WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b3Type; } else { std::cerr << "Unhandled mouse button." << std::endl; WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = b1Type; } WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseX = be->event_x; WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseY = be->event_y; } break; case XCB_KEY_PRESS: case XCB_KEY_RELEASE: { xcb_key_press_event_t *e = (xcb_key_press_event_t *)event; const bool isDown = (response_type == XCB_KEY_PRESS); const auto type = isDown ? ae3d::WindowEventType::KeyDown : ae3d::WindowEventType::KeyUp; WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = type; const xcb_keysym_t keysym = xcb_key_symbols_get_keysym(WindowGlobal::key_symbols, e->detail, 0); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].keyCode = WindowGlobal::keyMap[ keysym ]; } case XCB_MOTION_NOTIFY: { xcb_motion_notify_event_t* e = (xcb_motion_notify_event_t*)event; WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = ae3d::WindowEventType::MouseMove; WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseX = e->event_x; WindowGlobal::eventStack[ WindowGlobal::eventIndex ].mouseY = e->event_y; break; } case XCB_CLIENT_MESSAGE: { xcb_client_message_event_t* client_message_event = (xcb_client_message_event_t*)event; if (client_message_event->type == WindowGlobal::wm_protocols) { if (client_message_event->data.data32[0] == WindowGlobal::wm_delete_window) { exit(1); break; } } break; } case XCB_EXPOSE: { } break; } } if (!WindowGlobal::gamePad.isActive) { return; } js_event j; while (read( WindowGlobal::gamePad.fd, &j, sizeof(js_event) ) == sizeof(js_event)) //read(WindowGlobal::gamePad.fd, &j, sizeof(js_event)); { // Don't care if init or afterwards j.type &= ~JS_EVENT_INIT; if (j.type == JS_EVENT_BUTTON) { if (j.number == WindowGlobal::gamePad.buttonA) { if (j.value > 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonA; } } else if (j.number == WindowGlobal::gamePad.buttonB) { if (j.value > 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonB; } } else if (j.number == WindowGlobal::gamePad.buttonX) { if (j.value > 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonX; } } else if (j.number == WindowGlobal::gamePad.buttonY) { if (j.value > 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonY; } } else if (j.number == WindowGlobal::gamePad.buttonStart) { if (j.value > 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonStart; } } else if (j.number == WindowGlobal::gamePad.buttonBack) { if (j.value > 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonBack; } } else { //std::cout << "pressed button " << (int)j.number << std::endl; } } else if (j.type == JS_EVENT_AXIS) { if (j.number == WindowGlobal::gamePad.leftThumbX) { float x = ProcessGamePadStickValue( j.value, WindowGlobal::gamePad.deadZone ); WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadLeftThumbState; WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbX = x; WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbY = WindowGlobal::lastLeftThumbY; WindowGlobal::lastLeftThumbX = x; } else if (j.number == WindowGlobal::gamePad.leftThumbY) { float y = ProcessGamePadStickValue( j.value, WindowGlobal::gamePad.deadZone ); WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadLeftThumbState; WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbX = WindowGlobal::lastLeftThumbX; WindowGlobal::eventStack[ WindowGlobal::eventIndex ].gamePadThumbY = y; WindowGlobal::lastLeftThumbY = y; } else if (j.number == WindowGlobal::gamePad.dpadXaxis) { if (j.value > 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadRight; } if (j.value < 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadLeft; } } else if (j.number == WindowGlobal::gamePad.dpadYaxis) { if (j.value < 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadUp; } if (j.value > 0) { WindowGlobal::IncEventIndex(); WindowGlobal::eventStack[ WindowGlobal::eventIndex ].type = WindowEventType::GamePadButtonDPadDown; } } } } }
/** * Processing callback */ static void Demux (void *opaque) { demux_t *demux = opaque; demux_sys_t *sys = demux->p_sys; xcb_connection_t *conn = sys->conn; /* Determine capture region */ xcb_get_geometry_cookie_t gc; xcb_query_pointer_cookie_t qc; gc = xcb_get_geometry (conn, sys->window); if (sys->follow_mouse) qc = xcb_query_pointer (conn, sys->window); xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply (conn, gc, NULL); if (geo == NULL) { msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, sys->window); discard: if (sys->follow_mouse) xcb_discard_reply (conn, gc.sequence); return; } int w = sys->w; int h = sys->h; int x, y; if (sys->follow_mouse) { xcb_query_pointer_reply_t *ptr = xcb_query_pointer_reply (conn, qc, NULL); if (ptr == NULL) { free (geo); return; } if (w == 0 || w > geo->width) w = geo->width; x = ptr->win_x; if (x < w / 2) x = 0; else if (x >= (int)geo->width - (w / 2)) x = geo->width - w; else x -= w / 2; if (h == 0 || h > geo->height) h = geo->height; y = ptr->win_y; if (y < h / 2) y = 0; else if (y >= (int)geo->height - (h / 2)) y = geo->height - h; else y -= h / 2; } else { int max; x = sys->x; max = (int)geo->width - x; if (max <= 0) goto discard; if (w == 0 || w > max) w = max; y = sys->y; max = (int)geo->height - y; if (max <= 0) goto discard; if (h == 0 || h > max) h = max; } /* Update elementary stream format (if needed) */ if (w != sys->cur_w || h != sys->cur_h) { if (sys->es != NULL) es_out_Del (demux->out, sys->es); /* Update composite pixmap */ if (sys->window != geo->root) { xcb_free_pixmap (conn, sys->pixmap); /* no-op first time */ xcb_composite_name_window_pixmap (conn, sys->window, sys->pixmap); xcb_create_pixmap (conn, geo->depth, sys->pixmap, geo->root, geo->width, geo->height); } sys->es = InitES (demux, w, h, geo->depth, &sys->bpp); if (sys->es != NULL) { sys->cur_w = w; sys->cur_h = h; sys->bpp /= 8; /* bits -> bytes */ } } /* Capture screen */ xcb_drawable_t drawable = (sys->window != geo->root) ? sys->pixmap : sys->window; free (geo); block_t *block = NULL; #if HAVE_SYS_SHM_H if (sys->shm) { /* Capture screen through shared memory */ size_t size = w * h * sys->bpp; int id = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777); if (id == -1) /* XXX: fallback */ { msg_Err (demux, "shared memory allocation error: %m"); goto noshm; } /* Attach the segment to X and capture */ xcb_shm_get_image_reply_t *img; xcb_shm_get_image_cookie_t ck; xcb_shm_attach (conn, sys->segment, id, 0 /* read/write */); ck = xcb_shm_get_image (conn, drawable, x, y, w, h, ~0, XCB_IMAGE_FORMAT_Z_PIXMAP, sys->segment, 0); xcb_shm_detach (conn, sys->segment); img = xcb_shm_get_image_reply (conn, ck, NULL); xcb_flush (conn); /* ensure eventual detach */ if (img == NULL) { shmctl (id, IPC_RMID, 0); goto noshm; } free (img); /* Attach the segment to VLC */ void *shm = shmat (id, NULL, 0 /* read/write */); shmctl (id, IPC_RMID, 0); if (-1 == (intptr_t)shm) { msg_Err (demux, "shared memory attachment error: %m"); return; } block = block_shm_Alloc (shm, size); if (unlikely(block == NULL)) shmdt (shm); } noshm: #endif if (block == NULL) { /* Capture screen through socket (fallback) */ xcb_get_image_reply_t *img; img = xcb_get_image_reply (conn, xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable, x, y, w, h, ~0), NULL); if (img == NULL) return; uint8_t *data = xcb_get_image_data (img); size_t datalen = xcb_get_image_data_length (img); block = block_heap_Alloc (img, data + datalen - (uint8_t *)img); if (block == NULL) return; block->p_buffer = data; block->i_buffer = datalen; } /* Send block - zero copy */ if (sys->es != NULL) { block->i_pts = block->i_dts = mdate (); es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts); es_out_Send (demux->out, sys->es, block); } }
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); } }
/** * Processing callback */ static void Demux (void *data) { demux_t *demux = data; demux_sys_t *sys = demux->p_sys; xcb_connection_t *conn = sys->conn; /* Determine capture region */ xcb_get_geometry_cookie_t gc; xcb_query_pointer_cookie_t qc; gc = xcb_get_geometry (conn, sys->window); if (sys->follow_mouse) qc = xcb_query_pointer (conn, sys->window); xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply (conn, gc, NULL); if (geo == NULL) { msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, sys->window); discard: if (sys->follow_mouse) xcb_discard_reply (conn, gc.sequence); return; } int w = sys->w; int h = sys->h; int x, y; if (sys->follow_mouse) { xcb_query_pointer_reply_t *ptr = xcb_query_pointer_reply (conn, qc, NULL); if (ptr == NULL) { free (geo); return; } if (w == 0 || w > geo->width) w = geo->width; x = ptr->win_x; if (x < w / 2) x = 0; else if (x >= (int)geo->width - (w / 2)) x = geo->width - w; else x -= w / 2; if (h == 0 || h > geo->height) h = geo->height; y = ptr->win_y; if (y < h / 2) y = 0; else if (y >= (int)geo->height - (h / 2)) y = geo->height - h; else y -= h / 2; } else { int max; x = sys->x; max = (int)geo->width - x; if (max <= 0) goto discard; if (w == 0 || w > max) w = max; y = sys->y; max = (int)geo->height - y; if (max <= 0) goto discard; if (h == 0 || h > max) h = max; } /* Update elementary stream format (if needed) */ if (w != sys->cur_w || h != sys->cur_h) { if (sys->es != NULL) es_out_Del (demux->out, sys->es); /* Update composite pixmap */ if (sys->window != geo->root) { xcb_free_pixmap (conn, sys->pixmap); /* no-op first time */ xcb_composite_name_window_pixmap (conn, sys->window, sys->pixmap); xcb_create_pixmap (conn, geo->depth, sys->pixmap, geo->root, geo->width, geo->height); } sys->es = InitES (demux, w, h, geo->depth); if (sys->es != NULL) { sys->cur_w = w; sys->cur_h = h; } } /* Capture screen */ xcb_drawable_t drawable = (sys->window != geo->root) ? sys->pixmap : sys->window; free (geo); xcb_get_image_reply_t *img; img = xcb_get_image_reply (conn, xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable, x, y, w, h, ~0), NULL); if (img == NULL) return; block_t *block = block_heap_Alloc (img, xcb_get_image_data (img), xcb_get_image_data_length (img)); if (block == NULL) return; /* Send block - zero copy */ if (sys->es != NULL) { if (sys->pts == VLC_TS_INVALID) sys->pts = mdate (); block->i_pts = block->i_dts = sys->pts; es_out_Control (demux->out, ES_OUT_SET_PCR, sys->pts); es_out_Send (demux->out, sys->es, block); sys->pts += sys->interval; } }
static gboolean _eventd_nd_xcb_randr_check_focused(EventdNdBackendContext *self, EventdNdXcbRandrOutput *output) { gint x, y; switch ( self->follow_focus ) { case EVENTD_ND_XCB_FOLLOW_FOCUS_MOUSE: { xcb_query_pointer_cookie_t c; xcb_query_pointer_reply_t *r; c = xcb_query_pointer(self->xcb_connection, self->screen->root); r = xcb_query_pointer_reply(self->xcb_connection, c, NULL); if ( r == NULL ) return FALSE; x = r->root_x; y = r->root_y; free(r); } break; case EVENTD_ND_XCB_FOLLOW_FOCUS_KEYBOARD: { xcb_get_property_cookie_t wc; xcb_get_property_reply_t *wr; wc = xcb_get_property(self->xcb_connection, FALSE, self->screen->root, self->ewmh._NET_ACTIVE_WINDOW, XCB_ATOM_WINDOW, 0, sizeof(xcb_window_t)); wr = xcb_get_property_reply(self->xcb_connection, wc, NULL); if ( wr == NULL ) return FALSE; xcb_window_t w; w = *((xcb_window_t *) xcb_get_property_value(wr)); free(wr); xcb_translate_coordinates_cookie_t cc; xcb_translate_coordinates_reply_t *cr; cc = xcb_translate_coordinates(self->xcb_connection, w, self->screen->root, 0, 0); cr = xcb_translate_coordinates_reply(self->xcb_connection, cc, NULL); if ( cr == NULL ) return FALSE; x = cr->dst_x; y = cr->dst_y; free(cr); } break; default: g_return_val_if_reached(FALSE); } for ( ; output->output != NULL ; ++output ) { if ( ! ( ( x >= output->crtc->x && x <= ( output->crtc->x + output->crtc->width ) ) && ( y >= output->crtc->y && y <= ( output->crtc->y + output->crtc->height ) ) ) ) continue; self->geometry.x = output->crtc->x; self->geometry.y = output->crtc->y; self->geometry.w = output->crtc->width; self->geometry.h = output->crtc->height; return TRUE; } return FALSE; }