void ude_grab_pointer(UDEDesktop *desk, Window win, Bool owner_events, unsigned int event_mask, int pointer_mode, int keyboard_mode, Window confine_to, Cursor cursor) { _UDE_INTERNAL_pgrabstat *gs; gs = malloc (sizeof(_UDE_INTERNAL_pgrabstat)); if (!gs) ude_error_exit(1,"FATAL: out of memory."); gs->next = desk->internal.pgrabstat; gs->win = win; gs->owner_events = owner_events; gs->mask = event_mask; gs->pointer_mode = pointer_mode; gs->keyboard_mode = keyboard_mode; gs->confine_to = confine_to; gs->mouse = cursor; while(XGrabPointer(desk->disp, gs->win, gs->owner_events, gs->mask, gs->pointer_mode, gs->keyboard_mode, gs->confine_to, gs->mouse, CurrentTime) != GrabSuccess); desk->internal.pgrabstat = gs; }
static void fullscreen_grab(glw_x11_t *gx11) { XSync(gx11->display, False); while( GrabSuccess != XGrabPointer(gx11->display, gx11->win, True, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, gx11->win, None, CurrentTime)) usleep(100); XSetInputFocus(gx11->display, gx11->win, RevertToNone, CurrentTime); XWarpPointer(gx11->display, None, gx11->root, 0, 0, 0, 0, gx11->gr.gr_width / 2, gx11->gr.gr_height / 2); XGrabKeyboard(gx11->display, gx11->win, False, GrabModeAsync, GrabModeAsync, CurrentTime); }
static void resizemouse(Client *c) { int ocx, ocy; int nw, nh; XEvent ev; ocx = c->x; ocy = c->y; if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, cursor[CurResize], CurrentTime) != GrabSuccess) return; c->ismax = False; XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1); for(;;) { XMaskEvent(dpy, MOUSEMASK | SubstructureRedirectMask , &ev); switch(ev.type) { case ButtonRelease: resize(c, True); XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1); XUngrabPointer(dpy, CurrentTime); while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); return; case ConfigureRequest: case MapRequest: handler[ev.type](&ev); break; case MotionNotify: XSync(dpy, False); nw = ev.xmotion.x - ocx - 2 * c->border + 1; c->w = nw > 0 ? nw : 1; nh = ev.xmotion.y - ocy - 2 * c->border + 1; c->h = nh > 0 ? nh : 1; resize(c, True); break; } } }
struct Area *display_X11_select_area(void) { Cursor cursor = XCreateFontCursor(disp, XC_left_ptr); Cursor cursor2 = XCreateFontCursor(disp, XC_lr_angle); GC gc = display_X11_create_gc(); if (XGrabPointer(disp, scr->root, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, scr->root, cursor, CurrentTime) != GrabSuccess) return NULL; XEvent ev = {0}; while (ev.type != ButtonPress) XNextEvent(disp, &ev); int start_x = ev.xbutton.x; int start_y = ev.xbutton.y; XChangeActivePointerGrab(disp, PointerMotionMask | ButtonReleaseMask, cursor2, CurrentTime); struct Area *area = calloc(1, sizeof(*area)); while (display_X11_process_events(gc, start_x, start_y, area)) { fd_set fdset; FD_ZERO(&fdset); FD_SET(ConnectionNumber(disp), &fdset); select(ConnectionNumber(disp)+1, &fdset, NULL, NULL, NULL); } XUngrabPointer(disp, CurrentTime); XFreeCursor(disp, cursor); XFreeCursor(disp, cursor2); XFreeGC(disp, gc); XSync(disp, True); display_X11_area_sanitize(area); return area; }
void initialize( uint32_t const xW, uint32_t const xH, const char * xFilename ) { DevILImage image( xFilename ); Sprite * pT = new Sprite( ); pT->texData = image.toGLTextureBuffer( ); pT->tex.initialize( ( pT->w = xW ) , ( pT->h = xH ) , ( uint8_t* )pT->texData ); mCursor = pT; #if 0 // Linux Window w; int revert; XGetInputFocus( mDisplay, &w, &revert ); int result = GrabSuccess; if ( result = XGrabPointer( mDisplay , w , False , 0 , GrabModeAsync , GrabModeAsync , w , None , CurrentTime ) != GrabSuccess ) { std::cerr << "XGrabPointer failed!" << std::endl; exit( -1 ); } mCursorGrabbed = true; #endif }
void IN_GrabMouse(void) { int err; if (mouse_available && !mouse_grab_active) { XDefineCursor(x_disp, x_win, CreateNullCursor()); err = XGrabPointer(x_disp, x_win, True, 0, GrabModeAsync, GrabModeAsync, x_win, None, CurrentTime); if (err) { if (err == GrabNotViewable) Con_DPrintf("%s: GrabNotViewable\n", __func__); if (err == AlreadyGrabbed) Con_DPrintf("%s: AlreadyGrabbed\n", __func__); if (err == GrabFrozen) Con_DPrintf("%s: GrabFrozen\n", __func__); if (err == GrabInvalidTime) Con_DPrintf("%s: GrabInvalidTime\n", __func__); mouse_grab_active = true; return; } else { mouse_grab_active = true; } #ifdef USE_XF86DGA // FIXME - need those cvar callbacks to fix changed values... if (dga_available) { if (in_dgamouse.value) IN_ActivateDGAMouse(); } else { in_dgamouse.value = 0; } #endif } else { Sys_Error("Bad grab?"); } }
gboolean xfwm_device_grab (XfwmDevices *devices, XfwmDevice *device, Display *display, Window grab_window, gboolean owner_events, guint event_mask, gint grab_mode, Window confine_to, Cursor cursor, Time time) { gboolean result; Status status; #ifdef HAVE_XI2 XIEventMask xievent_mask; #endif #ifdef HAVE_XI2 if (device->xi2_device != None) { xfwm_device_fill_xi2_event_mask (&xievent_mask, event_mask); status = XIGrabDevice (display, device->xi2_device, grab_window, time, cursor, grab_mode, grab_mode, owner_events, &xievent_mask); g_free (xievent_mask.mask); result = (status == XIGrabSuccess); } else #endif if (device->keyboard) { status = XGrabKeyboard (display, grab_window, owner_events, grab_mode, grab_mode, time); result = (status == GrabSuccess); } else { status = XGrabPointer (display, grab_window, owner_events, event_mask, grab_mode, grab_mode, confine_to, cursor, time); result = (status == GrabSuccess); } return result; }
static void install_grabs(void) { int MajorVersion, MinorVersion; input_grabbed = true; // don't show mouse cursor icon XDefineCursor(x_disp, x_win, CreateNullCursor(x_disp, x_win)); XGrabPointer(x_disp, x_win, True, 0, GrabModeAsync, GrabModeAsync, x_win, None, CurrentTime); #ifdef USE_DGA if (!COM_CheckParm("-nodga") && XF86DGAQueryVersion(x_disp, &MajorVersion, &MinorVersion)) { // let us hope XF86DGADirectMouse will work XF86DGADirectVideo(x_disp, DefaultScreen(x_disp), XF86DGADirectMouse); dgamouse = true; XWarpPointer(x_disp, None, x_win, 0, 0, 0, 0, 0, 0); // oldman: this should be here really } else #endif XWarpPointer(x_disp, None, x_win, 0, 0, 0, 0, vid.width / 2, vid.height / 2); XGrabKeyboard(x_disp, x_win, False, GrabModeAsync, GrabModeAsync, CurrentTime); }
/** * * @param disp * @param root * @param rect * @return */ int selectWindow( Display *disp, Window *root, Rect *rect ) { int rx = 0, ry = 0, rw = 0, rh = 0; int rect_x = 0, rect_y = 0, rect_w = 0, rect_h = 0; int btn_pressed = 0, done = 0; XEvent ev; Cursor cursor, cursor2; cursor = XCreateFontCursor(disp, XC_left_ptr); cursor2 = XCreateFontCursor(disp, XC_lr_angle); if ((XGrabPointer (disp, *root, False, ButtonPressMask, GrabModeAsync, GrabModeAsync, *root, cursor, CurrentTime) != GrabSuccess)) { printf("couldn't grab pointer:\n"); return -1; } while (1) { while (XPending(disp)) { XNextEvent(disp, &ev); switch (ev.type) { case ButtonPress: return getWindowGeometry(disp, &ev.xbutton.subwindow, rect); default: break; } } } }
gboolean myScreenGrabPointer (ScreenInfo *screen_info, gboolean owner_events, unsigned int event_mask, Cursor cursor, guint32 timestamp) { gboolean grab; g_return_val_if_fail (screen_info, FALSE); TRACE ("entering myScreenGrabPointer"); grab = TRUE; if (screen_info->pointer_grabs == 0) { grab = (XGrabPointer (myScreenGetXDisplay (screen_info), screen_info->xroot, owner_events, event_mask, GrabModeAsync, GrabModeAsync, screen_info->xroot, cursor, (Time) timestamp) == GrabSuccess); } screen_info->pointer_grabs++; TRACE ("global pointer grabs %i", screen_info->pointer_grabs); return grab; }
int confine_pointer (int x, int y, int w, int h) { if (display.pointer_confined) return 0; display.confinewin = XCreateSimpleWindow(display.dpy, display.win, 10, 10, w, h, 0, 0, 0); XMapWindow(display.dpy, display.confinewin); XGrabPointer(display.dpy, display.root, 1, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, display.confinewin, None, CurrentTime); display.pointer_confined = 1; return 1; }
int XMenuActivate( register Display *display, /* Display to put menu on. */ register XMenu *menu, /* Menu to activate. */ int *p_num, /* Pane number selected. */ int *s_num, /* Selection number selected. */ int x_pos, /* X coordinate of menu position. */ int y_pos, /* Y coordinate of menu position. */ unsigned int event_mask, /* Mouse button event mask. */ char **data, /* Pointer to return data value. */ void (*help_callback) (char const *, int, int)) /* Help callback. */ { int status; /* X routine call status. */ int orig_x; /* Upper left menu origin X coord. */ int orig_y; /* Upper left menu origin Y coord. */ int ret_val; /* Return value. */ register XMPane *p_ptr; /* Current XMPane. */ register XMPane *event_xmp; /* Event XMPane pointer. */ register XMPane *cur_p; /* Current pane. */ register XMSelect *cur_s; /* Current selection. */ XMWindow *event_xmw; /* Event XMWindow pointer. */ XEvent event; /* X input event. */ XEvent peek_event; /* X input peek ahead event. */ Bool selection = False; /* Selection has been made. */ Bool forward = True; /* Moving forward in the pane list. */ Window root, child; int root_x, root_y, win_x, win_y; unsigned int mask; KeySym keysym; /* * Define and allocate a foreign event queue to hold events * that don't belong to XMenu. These events are later restored * to the X event queue. */ typedef struct _xmeventque { XEvent event; struct _xmeventque *next; } XMEventQue; XMEventQue *feq = NULL; /* Foreign event queue. */ XMEventQue *feq_tmp; /* Foreign event queue temporary. */ /* * If there are no panes in the menu then return failure * because the menu is not initialized. */ if (menu->p_count == 0) { _XMErrorCode = XME_NOT_INIT; return(XM_FAILURE); } /* * Find the desired current pane. */ cur_p = _XMGetPanePtr(menu, *p_num); if (cur_p == NULL) { return(XM_FAILURE); } cur_p->activated = cur_p->active; /* * Find the desired current selection. * If the current selection index is out of range a null current selection * will be assumed and the cursor will be placed in the current pane * header. */ cur_s = _XMGetSelectionPtr(cur_p, *s_num); /* * Compute origin of menu so that cursor is in * Correct pane and selection. */ _XMTransToOrigin(display, menu, cur_p, cur_s, x_pos, y_pos, &orig_x, &orig_y); menu->x_pos = orig_x; /* Store X and Y coords of menu. */ menu->y_pos = orig_y; if (XMenuRecompute(display, menu) == XM_FAILURE) { return(XM_FAILURE); } /* * Flush the window creation queue. * This batches all window creates since lazy evaluation * is more efficient than individual evaluation. * This routine also does an XFlush(). */ if (_XMWinQueFlush(display, menu, cur_p, cur_s) == _FAILURE) { return(XM_FAILURE); } /* * Make sure windows are in correct order (in case we were passed * an already created menu in incorrect order.) */ for(p_ptr = menu->p_list->next; p_ptr != cur_p; p_ptr = p_ptr->next) XRaiseWindow(display, p_ptr->window); for(p_ptr = menu->p_list->prev; p_ptr != cur_p->prev; p_ptr = p_ptr->prev) XRaiseWindow(display, p_ptr->window); /* * Make sure all selection windows are mapped. */ for ( p_ptr = menu->p_list->next; p_ptr != menu->p_list; p_ptr = p_ptr->next ){ XMapSubwindows(display, p_ptr->window); } /* * Synchronize the X buffers and the event queue. * From here on, all events in the queue that don't belong to * XMenu are sent back to the application via an application * provided event handler or discarded if the application has * not provided an event handler. */ XSync(display, 0); /* * Grab the mouse for menu input. */ status = XGrabPointer( display, menu->parent, True, event_mask, GrabModeAsync, GrabModeAsync, None, menu->mouse_cursor, CurrentTime ); if (status == Success && x_menu_grab_keyboard) { status = XGrabKeyboard (display, menu->parent, False, GrabModeAsync, GrabModeAsync, CurrentTime); if (status != Success) XUngrabPointer(display, CurrentTime); } if (status == _X_FAILURE) { _XMErrorCode = XME_GRAB_MOUSE; return(XM_FAILURE); } /* * Map the menu panes. */ XMapWindow(display, cur_p->window); for (p_ptr = menu->p_list->next; p_ptr != cur_p; p_ptr = p_ptr->next) XMapWindow(display, p_ptr->window); for (p_ptr = cur_p->next; p_ptr != menu->p_list; p_ptr = p_ptr->next) XMapWindow(display, p_ptr->window); XRaiseWindow(display, cur_p->window); /* Make sure current */ /* pane is on top. */ cur_s = NULL; /* Clear current selection. */ /* * Begin event processing loop. */ while (1) { if (wait_func) (*wait_func) (wait_data); XNextEvent(display, &event); /* Get next event. */ switch (event.type) { /* Dispatch on the event type. */ case Expose: event_xmp = (XMPane *)XLookUpAssoc(display, menu->assoc_tab, event.xexpose.window); if (event_xmp == NULL) { /* * If AEQ mode is enabled then queue the event. */ if (menu->aeq) { feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue)); if (feq_tmp == NULL) { _XMErrorCode = XME_CALLOC; return(XM_FAILURE); } feq_tmp->event = event; feq_tmp->next = feq; feq = feq_tmp; } else if (_XMEventHandler) (*_XMEventHandler)(&event); break; } if (event_xmp->activated) { XSetWindowBackground(display, event_xmp->window, menu->bkgnd_color); } else { XSetWindowBackgroundPixmap(display, event_xmp->window, menu->inact_pixmap); } _XMRefreshPane(display, menu, event_xmp); break; case EnterNotify: /* * First wait a small period of time, and see * if another EnterNotify event follows hard on the * heels of this one. i.e., the user is simply * "passing through". If so, ignore this one. */ event_xmw = (XMWindow *)XLookUpAssoc(display, menu->assoc_tab, event.xcrossing.window); if (event_xmw == NULL) break; if (event_xmw->type == SELECTION) { /* * We have entered a selection. */ /* if (XPending(display) == 0) usleep(150000); */ if (XPending(display) != 0) { XPeekEvent(display, &peek_event); if(peek_event.type == LeaveNotify) { break; } } cur_s = (XMSelect *)event_xmw; help_callback (cur_s->help_string, cur_p->serial, cur_s->serial); /* * If the pane we are in is active and the * selection entered is active then activate * the selection. */ if (cur_p->active && cur_s->active > 0) { cur_s->activated = 1; _XMRefreshSelection(display, menu, cur_s); } } else { /* * We have entered a pane. */ /* if (XPending(display) == 0) usleep(150000); */ if (XPending(display) != 0) { XPeekEvent(display, &peek_event); if (peek_event.type == EnterNotify) break; } XQueryPointer(display, menu->parent, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask); event_xmp = (XMPane *)XLookUpAssoc(display, menu->assoc_tab, child); if (event_xmp == NULL) break; if (event_xmp == cur_p) break; if (event_xmp->serial > cur_p->serial) forward = True; else forward = False; p_ptr = cur_p; while (p_ptr != event_xmp) { if (forward) p_ptr = p_ptr->next; else p_ptr = p_ptr->prev; XRaiseWindow(display, p_ptr->window); } if (cur_p->activated) { cur_p->activated = False; XSetWindowBackgroundPixmap(display, cur_p->window, menu->inact_pixmap); _XMRefreshPane(display, menu, cur_p); } if (event_xmp->active) event_xmp->activated = True; #if 1 /* * i suspect the we don't get an EXPOSE event when backing * store is enabled; the menu windows content is probably * not drawn in when it should be in that case. * in that case, this is probably an ugly fix! * i hope someone more familiar with this code would * take it from here. -- [email protected]. */ XSetWindowBackground(display, event_xmp->window, menu->bkgnd_color); _XMRefreshPane(display, menu, event_xmp); #endif cur_p = event_xmp; } break; case LeaveNotify: event_xmw = (XMWindow *)XLookUpAssoc( display, menu->assoc_tab, event.xcrossing.window ); if (event_xmw == NULL) break; if(cur_s == NULL) break; /* * If the current selection was activated then * deactivate it. */ if (cur_s->activated) { cur_s->activated = False; _XMRefreshSelection(display, menu, cur_s); } cur_s = NULL; break; case ButtonPress: case ButtonRelease: *p_num = cur_p->serial; /* * Check to see if there is a current selection. */ if (cur_s != NULL) { /* * Set the selection number to the current selection. */ *s_num = cur_s->serial; /* * If the current selection was activated then * we have a valid selection otherwise we have * an inactive selection. */ if (cur_s->activated) { *data = cur_s->data; ret_val = XM_SUCCESS; } else { ret_val = XM_IA_SELECT; } } else { /* * No selection was current. */ ret_val = XM_NO_SELECT; } selection = True; break; case KeyPress: case KeyRelease: keysym = XLookupKeysym (&event.xkey, 0); /* Pop down on C-g and Escape. */ if ((keysym == XK_g && (event.xkey.state & ControlMask) != 0) || keysym == XK_Escape) /* Any escape, ignore modifiers. */ { ret_val = XM_NO_SELECT; selection = True; } break; default: /* * If AEQ mode is enabled then queue the event. */ if (menu->aeq) { feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue)); if (feq_tmp == NULL) { _XMErrorCode = XME_CALLOC; return(XM_FAILURE); } feq_tmp->event = event; feq_tmp->next = feq; feq = feq_tmp; } else if (_XMEventHandler) (*_XMEventHandler)(&event); } /* * If a selection has been made, break out of the event loop. */ if (selection == True) break; } /* * Unmap the menu. */ for ( p_ptr = menu->p_list->next; p_ptr != menu->p_list; p_ptr = p_ptr->next) { XUnmapWindow(display, p_ptr->window); } /* * Ungrab the mouse. */ XUngrabPointer(display, CurrentTime); XUngrabKeyboard(display, CurrentTime); /* * Restore bits under where the menu was if we managed * to save them and free the pixmap. */ /* * If there is a current selection deactivate it. */ if (cur_s != NULL) cur_s->activated = 0; /* * Deactivate the current pane. */ cur_p->activated = 0; XSetWindowBackgroundPixmap(display, cur_p->window, menu->inact_pixmap); /* * Synchronize the X buffers and the X event queue. */ XSync(display, 0); /* * Dispatch any events remaining on the queue. */ while (QLength(display)) { /* * Fetch the next event. */ XNextEvent(display, &event); /* * Discard any events left on the queue that belong to XMenu. * All others are held and then returned to the event queue. */ switch (event.type) { case Expose: case EnterNotify: case LeaveNotify: case ButtonPress: case ButtonRelease: /* * Does this event belong to one of XMenu's windows? * If so, discard it and process the next event. * If not fall through and treat it as a foreign event. */ event_xmp = (XMPane *)XLookUpAssoc( display, menu->assoc_tab, event.xbutton.window ); if (event_xmp != NULL) continue; default: /* * This is a foreign event. * Queue it for later return to the X event queue. */ feq_tmp = (XMEventQue *)malloc(sizeof(XMEventQue)); if (feq_tmp == NULL) { _XMErrorCode = XME_CALLOC; return(XM_FAILURE); } feq_tmp->event = event; feq_tmp->next = feq; feq = feq_tmp; } } /* * Return any foreign events that were queued to the X event queue. */ while (feq != NULL) { feq_tmp = feq; XPutBackEvent(display, &feq_tmp->event); feq = feq_tmp->next; free((char *)feq_tmp); } wait_func = 0; /* * Return successfully. */ _XMErrorCode = XME_NO_ERROR; return(ret_val); }
GLWindow::GLWindow(const char * title, int width, int height, int bits, bool fullscreen, WNDPROC wndproc) { #ifdef _WIN32 GLuint PixelFormat; // Holds The Results After Searching For A Match WNDCLASS wc; // Windows Class Structure DWORD dwExStyle; // Window Extended Style DWORD dwStyle; // Window Style RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values WindowRect.left = (long) 0; // Set Left Value To 0 WindowRect.right =(long) width; // Set Right Value To Requested Width WindowRect.top = (long) 0; // Set Top Value To 0 WindowRect.bottom = (long) height; // Set Bottom Value To Requested Height bool result = true; mInitialized = false; if(result) { mhInstance = GetModuleHandle(NULL); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC) wndproc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = mhInstance; wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGL"; } if(result) { if(!RegisterClass(&wc)) { result = false; } } if(result) { DEVMODE dmScreenSettings; memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); dmScreenSettings.dmSize=sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth = width; dmScreenSettings.dmPelsHeight = height; dmScreenSettings.dmBitsPerPel = bits; dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; if(fullscreen) { ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN); dwExStyle = WS_EX_APPWINDOW; dwStyle = WS_POPUP; } else { dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; dwStyle = WS_OVERLAPPEDWINDOW; } AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); } if(result) { dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; mhWnd = CreateWindowEx(dwExStyle, "OpenGL", title, dwStyle, 0, 0, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, NULL, NULL, mhInstance, NULL); if(!mhWnd) { free(); result = false; } } if(result) { mhDC = GetDC(mhWnd); if(!mhDC) { free(); result = false; } } static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, bits, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; if(result) { PixelFormat = ChoosePixelFormat(mhDC, &pfd); if(!PixelFormat) { free(); result = false; } } if(result) { if(!SetPixelFormat(mhDC, PixelFormat, &pfd)) { free(); result = false; } } if(result) { mhRC = wglCreateContext(mhDC); if(!mhRC) { free(); result = false; } } if(result) { if(!wglMakeCurrent(mhDC, mhRC)) { free(); result = false; } } if(result) { ShowCursor(FALSE); ShowWindow(mhWnd, SW_SHOW); SetForegroundWindow(mhWnd); SetFocus(mhWnd); } if(result) { if(!initOpenGL()) { free(); result = false; } } mInitialized = result; #else XVisualInfo *vi; Colormap cmap; int i, dpyWidth, dpyHeight; int glxMajor, glxMinor, vmMajor, vmMinor; XF86VidModeModeInfo **modes; int modeNum, bestMode; Atom wmDelete; Window winDummy; unsigned int borderDummy; mFullscreen = fullscreen; /* set best mode to current */ bestMode = 0; /* get a connection */ mDisplay = XOpenDisplay(0); mScreen = DefaultScreen(mDisplay); XF86VidModeQueryVersion(mDisplay, &vmMajor, &vmMinor); XF86VidModeGetAllModeLines(mDisplay, mScreen, &modeNum, &modes); /* save desktop-resolution before switching modes */ mDeskMode = *modes[0]; /* look for mode with requested resolution */ for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height)) bestMode = i; } /* get an appropriate visual */ vi = glXChooseVisual(mDisplay, mScreen, attrListDbl); if (vi == NULL) { vi = glXChooseVisual(mDisplay, mScreen, attrListSgl); mDoubleBuffered = False; } else { mDoubleBuffered = True; } glXQueryVersion(mDisplay, &glxMajor, &glxMinor); Debug::Log("GLX-Version %d.%d\n", glxMajor, glxMinor); /* create a GLX context */ mCtx = glXCreateContext(mDisplay, vi, 0, GL_TRUE); /* create a color map */ cmap = XCreateColormap(mDisplay, RootWindow(mDisplay, vi->screen), vi->visual, AllocNone); mWinAttr.colormap = cmap; mWinAttr.border_pixel = 0; if(fullscreen) { /* switch to fullscreen */ XF86VidModeSwitchToMode(mDisplay, mScreen, modes[bestMode]); XF86VidModeSetViewPort(mDisplay, mScreen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; XFree(modes); /* set window attributes */ mWinAttr.override_redirect = True; mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask; mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &mWinAttr); XWarpPointer(mDisplay, None, mWindow, 0, 0, 0, 0, 0, 0); XMapRaised(mDisplay, mWindow); XGrabKeyboard(mDisplay, mWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(mDisplay, mWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, mWindow, None, CurrentTime); } else { /* create a window in window mode*/ mWinAttr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask; mWindow = XCreateWindow(mDisplay, RootWindow(mDisplay, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &mWinAttr); /* only set window title and handle wm_delete_events if in windowed mode */ wmDelete = XInternAtom(mDisplay, "WM_DELETE_WINDOW", True); XSetWMProtocols(mDisplay, mWindow, &wmDelete, 1); XSetStandardProperties(mDisplay, mWindow, title, title, None, NULL, 0, NULL); XMapRaised(mDisplay, mWindow); } /* connect the glx-context to the window */ glXMakeCurrent(mDisplay, mWindow, mCtx); initOpenGL(); mInitialized = true; #endif }
static GdkNativeWindow select_window_x11 (GdkScreen *screen) { Display *x_dpy = GDK_SCREEN_XDISPLAY (screen); gint x_scr = GDK_SCREEN_XNUMBER (screen); Window x_root = RootWindow (x_dpy, x_scr); Window x_win = None; GC x_gc = None; Cursor x_cursor = XCreateFontCursor (x_dpy, GDK_CROSSHAIR); GdkKeymapKey *keys = NULL; gint status; gint i, num_keys; gint buttons = 0; gint mask = ButtonPressMask | ButtonReleaseMask; gboolean cancel = FALSE; if (shootvals.shoot_type == SHOOT_REGION) mask |= PointerMotionMask; status = XGrabPointer (x_dpy, x_root, False, mask, GrabModeSync, GrabModeAsync, x_root, x_cursor, CurrentTime); if (status != GrabSuccess) { gint x, y; guint xmask; /* if we can't grab the pointer, return the window under the pointer */ XQueryPointer (x_dpy, x_root, &x_root, &x_win, &x, &y, &x, &y, &xmask); if (x_win == None || x_win == x_root) g_message (_("Error selecting the window")); } if (shootvals.shoot_type == SHOOT_REGION) { XGCValues gc_values; gc_values.function = GXxor; gc_values.plane_mask = AllPlanes; gc_values.foreground = WhitePixel (x_dpy, x_scr); gc_values.background = BlackPixel (x_dpy, x_scr); gc_values.line_width = 0; gc_values.line_style = LineSolid; gc_values.fill_style = FillSolid; gc_values.cap_style = CapButt; gc_values.join_style = JoinMiter; gc_values.graphics_exposures = FALSE; gc_values.clip_x_origin = 0; gc_values.clip_y_origin = 0; gc_values.clip_mask = None; gc_values.subwindow_mode = IncludeInferiors; x_gc = XCreateGC (x_dpy, x_root, GCFunction | GCPlaneMask | GCForeground | GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | GCGraphicsExposures | GCBackground | GCFillStyle | GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode, &gc_values); } if (gdk_keymap_get_entries_for_keyval (NULL, GDK_Escape, &keys, &num_keys)) { gdk_error_trap_push (); #define X_GRAB_KEY(index, modifiers) \ XGrabKey (x_dpy, keys[index].keycode, modifiers, x_root, False, \ GrabModeAsync, GrabModeAsync) for (i = 0; i < num_keys; i++) { X_GRAB_KEY (i, 0); X_GRAB_KEY (i, LockMask); /* CapsLock */ X_GRAB_KEY (i, Mod2Mask); /* NumLock */ X_GRAB_KEY (i, Mod5Mask); /* ScrollLock */ X_GRAB_KEY (i, LockMask | Mod2Mask); /* CapsLock + NumLock */ X_GRAB_KEY (i, LockMask | Mod5Mask); /* CapsLock + ScrollLock */ X_GRAB_KEY (i, Mod2Mask | Mod5Mask); /* NumLock + ScrollLock */ X_GRAB_KEY (i, LockMask | Mod2Mask | Mod5Mask); /* all */ } #undef X_GRAB_KEY gdk_flush (); gdk_error_trap_pop (); } while (! cancel && ((x_win == None) || (buttons != 0))) { XEvent x_event; gint x, y, w, h; XAllowEvents (x_dpy, SyncPointer, CurrentTime); XWindowEvent (x_dpy, x_root, mask | KeyPressMask, &x_event); switch (x_event.type) { case ButtonPress: if (x_win == None) { x_win = x_event.xbutton.subwindow; if (x_win == None) x_win = x_root; #ifdef HAVE_X11_XMU_WINUTIL_H else if (! shootvals.decorate) x_win = XmuClientWindow (x_dpy, x_win); #endif shootvals.x2 = shootvals.x1 = x_event.xbutton.x_root; shootvals.y2 = shootvals.y1 = x_event.xbutton.y_root; } buttons++; break; case ButtonRelease: if (buttons > 0) buttons--; if (! buttons && shootvals.shoot_type == SHOOT_REGION) { x = MIN (shootvals.x1, shootvals.x2); y = MIN (shootvals.y1, shootvals.y2); w = ABS (shootvals.x2 - shootvals.x1); h = ABS (shootvals.y2 - shootvals.y1); if (w > 0 && h > 0) XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h); shootvals.x2 = x_event.xbutton.x_root; shootvals.y2 = x_event.xbutton.y_root; } break; case MotionNotify: if (buttons > 0) { x = MIN (shootvals.x1, shootvals.x2); y = MIN (shootvals.y1, shootvals.y2); w = ABS (shootvals.x2 - shootvals.x1); h = ABS (shootvals.y2 - shootvals.y1); if (w > 0 && h > 0) XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h); shootvals.x2 = x_event.xmotion.x_root; shootvals.y2 = x_event.xmotion.y_root; x = MIN (shootvals.x1, shootvals.x2); y = MIN (shootvals.y1, shootvals.y2); w = ABS (shootvals.x2 - shootvals.x1); h = ABS (shootvals.y2 - shootvals.y1); if (w > 0 && h > 0) XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h); } break; case KeyPress: { guint *keyvals; gint n; if (gdk_keymap_get_entries_for_keycode (NULL, x_event.xkey.keycode, NULL, &keyvals, &n)) { gint i; for (i = 0; i < n && ! cancel; i++) if (keyvals[i] == GDK_Escape) cancel = TRUE; g_free (keyvals); } } break; default: break; } } if (keys) { #define X_UNGRAB_KEY(index, modifiers) \ XUngrabKey (x_dpy, keys[index].keycode, modifiers, x_root) for (i = 0; i < num_keys; i++) { X_UNGRAB_KEY (i, 0); X_UNGRAB_KEY (i, LockMask); /* CapsLock */ X_UNGRAB_KEY (i, Mod2Mask); /* NumLock */ X_UNGRAB_KEY (i, Mod5Mask); /* ScrollLock */ X_UNGRAB_KEY (i, LockMask | Mod2Mask); /* CapsLock + NumLock */ X_UNGRAB_KEY (i, LockMask | Mod5Mask); /* CapsLock + ScrollLock */ X_UNGRAB_KEY (i, Mod2Mask | Mod5Mask); /* NumLock + ScrollLock */ X_UNGRAB_KEY (i, LockMask | Mod2Mask | Mod5Mask); /* all */ } #undef X_UNGRAB_KEY g_free (keys); } if (status == GrabSuccess) XUngrabPointer (x_dpy, CurrentTime); XFreeCursor (x_dpy, x_cursor); if (x_gc != None) XFreeGC (x_dpy, x_gc); return x_win; }
int main(int argc, char **argv) { char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; char buf[32], passwd[256]; int num, screen; #ifndef HAVE_BSD_AUTH const char *pws; #endif unsigned int len; Bool running = True; Cursor invisible; Display *dpy; KeySym ksym; Pixmap pmap; Window root, w; XColor black, dummy; XEvent ev; XSetWindowAttributes wa; if((argc == 2) && !strcmp("-v", argv[1])) die("slock-"VERSION", © 2006-2008 Anselm R Garbe\n"); else if(argc != 1) die("usage: slock [-vb]\n"); backlight_of(); #ifndef HAVE_BSD_AUTH pws = get_password(); #endif if(!(dpy = XOpenDisplay(0))) die("slock: cannot open display\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); /* init */ wa.override_redirect = 1; wa.background_pixel = BlackPixel(dpy, screen); w = XCreateWindow(dpy, root, 0, 0, DisplayWidth(dpy, screen), DisplayHeight(dpy, screen), 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixel, &wa); XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "black", &black, &dummy); pmap = XCreateBitmapFromData(dpy, w, curs, 8, 8); invisible = XCreatePixmapCursor(dpy, pmap, pmap, &black, &black, 0, 0); XDefineCursor(dpy, w, invisible); XMapRaised(dpy, w); for(len = 1000; len; len--) { if(XGrabPointer(dpy, root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess) break; usleep(1000); } if((running = running && (len > 0))) { for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) break; usleep(1000); } running = (len > 0); } len = 0; XSync(dpy, False); /* main event loop */ while(running && !XNextEvent(dpy, &ev)) { if(len == 0 && DPMSCapable(dpy)) { DPMSEnable(dpy); DPMSForceLevel(dpy, DPMSModeOff); } if(ev.type == KeyPress) { buf[0] = 0; num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) ksym = XK_Return; else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; switch(ksym) { case XK_Return: passwd[len] = 0; #ifdef HAVE_BSD_AUTH running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); #else running = strcmp(crypt(passwd, pws), pws); #endif if (running != 0) XBell(dpy, 100); len = 0; break; case XK_Escape: len = 0; break; case XK_BackSpace: if(len) --len; break; default: if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) { memcpy(passwd + len, buf, num); len += num; } break; } } } XUngrabPointer(dpy, CurrentTime); XFreePixmap(dpy, pmap); XDestroyWindow(dpy, w); XCloseDisplay(dpy); backlight_on(); return 0; }
void OS_X11::process_xevents() { //printf("checking events %i\n", XPending(x11_display)); bool do_mouse_warp=false; while (XPending(x11_display) > 0) { XEvent event; XNextEvent(x11_display, &event); switch (event.type) { case Expose: Main::force_redraw(); break; case NoExpose: minimized = true; break; case VisibilityNotify: { XVisibilityEvent * visibility = (XVisibilityEvent *)&event; minimized = (visibility->state == VisibilityFullyObscured); } break; case FocusIn: main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); if (mouse_mode==MOUSE_MODE_CAPTURED) { XGrabPointer(x11_display, x11_window, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime); } break; case FocusOut: main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); if (mouse_mode==MOUSE_MODE_CAPTURED) { //dear X11, I try, I really try, but you never work, you do whathever you want. XUngrabPointer(x11_display, CurrentTime); } break; case ConfigureNotify: /* call resizeGLScene only if our window-size changed */ if ((event.xconfigure.width == current_videomode.width) && (event.xconfigure.height == current_videomode.height)) break; current_videomode.width=event.xconfigure.width; current_videomode.height=event.xconfigure.height; break; case ButtonPress: case ButtonRelease: { /* exit in case of a mouse button press */ last_timestamp=event.xbutton.time; if (mouse_mode==MOUSE_MODE_CAPTURED) { event.xbutton.x=last_mouse_pos.x; event.xbutton.y=last_mouse_pos.y; } InputEvent mouse_event; mouse_event.ID=++event_id; mouse_event.type = InputEvent::MOUSE_BUTTON; mouse_event.device=0; mouse_event.mouse_button.mod = get_key_modifier_state(event.xbutton.state); mouse_event.mouse_button.button_mask = get_mouse_button_state(event.xbutton.state); mouse_event.mouse_button.x=event.xbutton.x; mouse_event.mouse_button.y=event.xbutton.y; mouse_event.mouse_button.global_x=event.xbutton.x; mouse_event.mouse_button.global_y=event.xbutton.y; mouse_event.mouse_button.button_index=event.xbutton.button; if (mouse_event.mouse_button.button_index==2) mouse_event.mouse_button.button_index=3; else if (mouse_event.mouse_button.button_index==3) mouse_event.mouse_button.button_index=2; mouse_event.mouse_button.pressed=(event.type==ButtonPress); if (event.type==ButtonPress && event.xbutton.button==1) { uint64_t diff = get_ticks_usec()/1000 - last_click_ms; if (diff<400 && Point2(last_click_pos).distance_to(Point2(event.xbutton.x,event.xbutton.y))<5) { last_click_ms=0; last_click_pos = Point2(-100,-100); mouse_event.mouse_button.doubleclick=true; mouse_event.ID=++event_id; } else { last_click_ms+=diff; last_click_pos = Point2(event.xbutton.x,event.xbutton.y); } } input->parse_input_event( mouse_event); } break; case MotionNotify: { last_timestamp=event.xmotion.time; // Motion is also simple. // A little hack is in order // to be able to send relative motion events. Point2i pos( event.xmotion.x, event.xmotion.y ); if (mouse_mode==MOUSE_MODE_CAPTURED) { #if 1 Vector2 c = Point2i(current_videomode.width/2,current_videomode.height/2); if (pos==Point2i(current_videomode.width/2,current_videomode.height/2)) { //this sucks, it's a hack, etc and is a little inaccurate, etc. //but nothing I can do, X11 sucks. center=pos; break; } Point2i ncenter = pos; pos = last_mouse_pos + ( pos-center ); center=ncenter; do_mouse_warp=true; #else //Dear X11, thanks for making my life miserable center.x = current_videomode.width/2; center.y = current_videomode.height/2; pos = last_mouse_pos + ( pos-center ); if (pos==last_mouse_pos) break; XWarpPointer(x11_display, None, x11_window, 0,0,0,0, (int)center.x, (int)center.y); #endif } if (!last_mouse_pos_valid) { last_mouse_pos=pos; last_mouse_pos_valid=true; } Point2i rel = pos - last_mouse_pos; InputEvent motion_event; motion_event.ID=++event_id; motion_event.type=InputEvent::MOUSE_MOTION; motion_event.device=0; motion_event.mouse_motion.mod = get_key_modifier_state(event.xmotion.state); motion_event.mouse_motion.button_mask = get_mouse_button_state(event.xmotion.state); motion_event.mouse_motion.x=pos.x; motion_event.mouse_motion.y=pos.y; input->set_mouse_pos(pos); motion_event.mouse_motion.global_x=pos.x; motion_event.mouse_motion.global_y=pos.y; motion_event.mouse_motion.speed_x=input->get_mouse_speed().x; motion_event.mouse_motion.speed_y=input->get_mouse_speed().y; motion_event.mouse_motion.relative_x=rel.x; motion_event.mouse_motion.relative_y=rel.y; last_mouse_pos=pos; input->parse_input_event( motion_event); } break; case KeyPress: case KeyRelease: { last_timestamp=event.xkey.time; // key event is a little complex, so // it will be handled in it's own function. handle_key_event( (XKeyEvent*)&event ); } break; case SelectionRequest: { XSelectionRequestEvent *req; XEvent e, respond; e = event; req=&(e.xselectionrequest); if (req->target == XA_STRING || req->target == XInternAtom(x11_display, "COMPOUND_TEXT", 0) || req->target == XInternAtom(x11_display, "UTF8_STRING", 0)) { CharString clip = OS::get_clipboard().utf8(); XChangeProperty (x11_display, req->requestor, req->property, req->target, 8, PropModeReplace, (unsigned char*)clip.get_data(), clip.length()); respond.xselection.property=req->property; } else if (req->target == XInternAtom(x11_display, "TARGETS", 0)) { Atom data[2]; data[0] = XInternAtom(x11_display, "UTF8_STRING", 0); data[1] = XA_STRING; XChangeProperty (x11_display, req->requestor, req->property, req->target, 8, PropModeReplace, (unsigned char *) &data, sizeof (data)); respond.xselection.property=req->property; } else { printf ("No String %x\n", (int)req->target); respond.xselection.property= None; } respond.xselection.type= SelectionNotify; respond.xselection.display= req->display; respond.xselection.requestor= req->requestor; respond.xselection.selection=req->selection; respond.xselection.target= req->target; respond.xselection.time = req->time; XSendEvent (x11_display, req->requestor,0,0,&respond); XFlush (x11_display); } break; case ClientMessage: if ((unsigned int)event.xclient.data.l[0]==(unsigned int)wm_delete) main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); break; default: break; } } XFlush(x11_display); if (do_mouse_warp) { XWarpPointer(x11_display, None, x11_window, 0,0,0,0, (int)current_videomode.width/2, (int)current_videomode.height/2); } }
/* read an X event */ void ReadXServer (void) { static XEvent event; int old_cursor = 0, keypress; Item *item, *old_item; KeySym ks; char *sp, *dp; static unsigned char buf[10]; /* unsigned for international */ static int n; while (FEventsQueued(dpy, QueuedAfterReading)) { FNextEvent(dpy, &event); if (event.xany.window == CF.frame) { switch (event.type) { case ClientMessage: { if(event.xclient.format == 32 && event.xclient.data.l[0] == wm_del_win) { exit(0); } } break; case ConfigureNotify: /* has window be reconfigured */ { XEvent tmpe; while (FCheckTypedWindowEvent( dpy, CF.frame, ConfigureNotify, &tmpe)) { if (!tmpe.xconfigure.send_event) continue; event.xconfigure.x = tmpe.xconfigure.x; event.xconfigure.y = tmpe.xconfigure.y; event.xconfigure.send_event = True; } if (CF.max_width != event.xconfigure.width || CF.total_height != event.xconfigure.height) { /* adjust yourself... do noting */ ResizeFrame(); CF.max_width = event.xconfigure.width; CF.total_height = event.xconfigure.height; UpdateRootTransapency(False, True); if (!CSET_IS_TRANSPARENT(colorset)) { RedrawFrame(NULL); } } else if (event.xconfigure.send_event) { UpdateRootTransapency(False, True); } } break; #if 0 case SelectionClear: selection_clear (); break; case SelectionNotify: selection_paste (); break; case SelectionRequest: selection_send (); break; #endif case Expose: { int ex = event.xexpose.x; int ey = event.xexpose.y; int ex2 = event.xexpose.x + event.xexpose.width; int ey2 = event.xexpose.y + event.xexpose.height; while (FCheckTypedWindowEvent(dpy, CF.frame, Expose, &event)) { ex = min(ex, event.xexpose.x); ey = min(ey, event.xexpose.y); ex2 = max(ex2, event.xexpose.x + event.xexpose.width); ey2 = max(ey2 , event.xexpose.y + event.xexpose.height); } event.xexpose.x = ex; event.xexpose.y = ey; event.xexpose.width = ex2 - ex; event.xexpose.height = ey2 - ey; RedrawFrame(&event); if (CF.grab_server && !CF.server_grabbed) { if (GrabSuccess == XGrabPointer(dpy, CF.frame, True, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime)) CF.server_grabbed = 1; } } break; case VisibilityNotify: if (CF.server_grabbed && event.xvisibility.state != VisibilityUnobscured) { /* raise our window to the top */ XRaiseWindow(dpy, CF.frame); XSync(dpy, 0); } break; case KeyPress: /* we do text input here */ n = XLookupString(&event.xkey, (char *)buf, sizeof(buf), &ks, NULL); keypress = buf[0]; myfprintf((stderr, "Keypress [%s]\n", buf)); if (n == 0) { /* not a regular key, translate it into one */ switch (ks) { case XK_Home: case XK_Begin: buf[0] = '\001'; /* ^A */ break; case XK_End: buf[0] = '\005'; /* ^E */ break; case XK_Left: buf[0] = '\002'; /* ^B */ break; case XK_Right: buf[0] = '\006'; /* ^F */ break; case XK_Up: buf[0] = '\020'; /* ^P */ break; case XK_Down: buf[0] = '\016'; /* ^N */ break; default: if (ks >= XK_F1 && ks <= XK_F35) { buf[0] = '\0'; keypress = 257 + ks - XK_F1; } else goto no_redraw; /* no action for this event */ } } switch (ks) { /* regular key, may need adjustment */ case XK_Tab: #ifdef XK_XKB_KEYS case XK_ISO_Left_Tab: #endif if (event.xkey.state & ShiftMask) { /* shifted key */ buf[0] = '\020'; /* chg shift tab to ^P */ } break; case '>': if (event.xkey.state & Mod1Mask) { /* Meta, shift > */ process_history(1); goto redraw_newcursor; } break; case '<': if (event.xkey.state & Mod1Mask) { /* Meta, shift < */ process_history(-1); goto redraw_newcursor; } break; } if (!CF.cur_input) { /* no text input fields */ for (item = root_item_ptr; item != 0; item = item->header.next) {/* all items */ if (item->type == I_BUTTON && item->button.keypress == keypress) { RedrawItem(item, 1, NULL); usleep(MICRO_S_FOR_10MS); RedrawItem(item, 0, NULL); DoCommand(item); goto no_redraw; } } break; } else if (CF.cur_input == CF.cur_input->input.next_input) { /* 1 ip field */ switch (buf[0]) { case '\020': /* ^P previous field */ process_history(-1); goto redraw_newcursor; break; case '\016': /* ^N next field */ process_history(1); goto redraw_newcursor; break; } /* end switch */ } /* end one input field */ switch (buf[0]) { case '\001': /* ^A */ old_cursor = CF.abs_cursor; CF.rel_cursor = 0; CF.abs_cursor = 0; CF.cur_input->input.left = 0; goto redraw_newcursor; break; case '\005': /* ^E */ old_cursor = CF.abs_cursor; CF.rel_cursor = CF.cur_input->input.n; if ((CF.cur_input->input.left = CF.rel_cursor - CF.cur_input->input.size) < 0) CF.cur_input->input.left = 0; CF.abs_cursor = CF.rel_cursor - CF.cur_input->input.left; goto redraw_newcursor; break; case '\002': /* ^B */ old_cursor = CF.abs_cursor; if (CF.rel_cursor > 0) { CF.rel_cursor--; CF.abs_cursor--; if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) { CF.abs_cursor++; CF.cur_input->input.left--; } } goto redraw_newcursor; break; case '\006': /* ^F */ old_cursor = CF.abs_cursor; if (CF.rel_cursor < CF.cur_input->input.n) { CF.rel_cursor++; CF.abs_cursor++; if (CF.abs_cursor >= CF.cur_input->input.size && CF.rel_cursor < CF.cur_input->input.n) { CF.abs_cursor--; CF.cur_input->input.left++; } } goto redraw_newcursor; break; case '\010': /* ^H */ old_cursor = CF.abs_cursor; if (CF.rel_cursor > 0) { sp = CF.cur_input->input.value + CF.rel_cursor; dp = sp - 1; for (; *dp = *sp, *sp != '\0'; dp++, sp++); CF.cur_input->input.n--; CF.rel_cursor--; if (CF.rel_cursor < CF.abs_cursor) { CF.abs_cursor--; if (CF.abs_cursor <= 0 && CF.rel_cursor > 0) { CF.abs_cursor++; CF.cur_input->input.left--; } } else CF.cur_input->input.left--; } goto redraw_newcursor; break; case '\177': /* DEL */ case '\004': /* ^D */ if (CF.rel_cursor < CF.cur_input->input.n) { sp = CF.cur_input->input.value + CF.rel_cursor + 1; dp = sp - 1; for (; *dp = *sp, *sp != '\0'; dp++, sp++); CF.cur_input->input.n--; goto redraw_newcursor; } break; case '\013': /* ^K */ CF.cur_input->input.value[CF.rel_cursor] = '\0'; CF.cur_input->input.n = CF.rel_cursor; goto redraw_newcursor; case '\025': /* ^U */ CF.cur_input->input.value[0] = '\0'; CF.cur_input->input.n = CF.cur_input->input.left = 0; CF.rel_cursor = CF.abs_cursor = 0; goto redraw_newcursor; case '\020': /* ^P previous field */ old_item = CF.cur_input; CF.cur_input = old_item->input.prev_input; /* new current input fld */ RedrawItem(old_item, 1, NULL); CF.rel_cursor = CF.abs_cursor = 0; /* home cursor in new input field */ goto redraw; break; case '\t': case '\n': case '\015': case '\016': /* LINEFEED, TAB, RETURN, ^N, jump to the next field */ switch (process_tabtypes(&buf[0])) { case 0: goto no_redraw;break; case 1: goto redraw;break; } break; default: old_cursor = CF.abs_cursor; if((buf[0] >= ' ' && buf[0] < '\177') || (buf[0] >= 160)) { /* regular or intl char */ process_regular_char_input(&buf[0]); /* insert into input field */ goto redraw_newcursor; } /* unrecognized key press, check for buttons */ for (item = root_item_ptr; item != 0; item = item->header.next) { /* all items */ myfprintf((stderr, "Button: keypress==%d\n", item->button.keypress)); if (item->type == I_BUTTON && item->button.keypress == keypress) { RedrawItem(item, 1, NULL); usleep(MICRO_S_FOR_10MS); /* .1 seconds */ RedrawItem(item, 0, NULL); DoCommand(item); goto no_redraw; } } break; } redraw_newcursor: { XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC, CF.cur_input->header.dt_ptr->dt_colors[c_item_bg]); /* Since DrawString is being used, I changed this to clear the entire input field. dje 10/24/99. */ XClearArea(dpy, CF.cur_input->header.win, BOX_SPC + TEXT_SPC - 1, BOX_SPC, CF.cur_input->header.size_x - (2 * BOX_SPC) - 2 - TEXT_SPC, (CF.cur_input->header.size_y - 1) - 2 * BOX_SPC + 1, False); } redraw: { int len, x, dy; len = CF.cur_input->input.n - CF.cur_input->input.left; XSetForeground(dpy, CF.cur_input->header.dt_ptr->dt_item_GC, CF.cur_input->header.dt_ptr->dt_colors[c_item_fg]); if (len > CF.cur_input->input.size) len = CF.cur_input->input.size; CF.cur_input->header.dt_ptr->dt_Fstr->win = CF.cur_input->header.win; CF.cur_input->header.dt_ptr->dt_Fstr->gc = CF.cur_input->header.dt_ptr->dt_item_GC; CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = False; if (itemcolorset >= 0) { CF.cur_input->header.dt_ptr->dt_Fstr->colorset = &Colorset[itemcolorset]; CF.cur_input->header.dt_ptr->dt_Fstr->flags.has_colorset = True; } CF.cur_input->header.dt_ptr->dt_Fstr->str = CF.cur_input->input.value; CF.cur_input->header.dt_ptr->dt_Fstr->x = BOX_SPC + TEXT_SPC; CF.cur_input->header.dt_ptr->dt_Fstr->y = BOX_SPC + TEXT_SPC + CF.cur_input->header.dt_ptr->dt_Ffont->ascent; CF.cur_input->header.dt_ptr->dt_Fstr->len = len; FlocaleDrawString(dpy, CF.cur_input->header.dt_ptr->dt_Ffont, CF.cur_input->header.dt_ptr->dt_Fstr, FWS_HAVE_LENGTH); x = BOX_SPC + TEXT_SPC + FlocaleTextWidth(CF.cur_input->header.dt_ptr->dt_Ffont, CF.cur_input->input.value,CF.abs_cursor) - 1; dy = CF.cur_input->header.size_y - 1; XDrawLine(dpy, CF.cur_input->header.win, CF.cur_input->header.dt_ptr->dt_item_GC, x, BOX_SPC, x, dy - BOX_SPC); myfprintf((stderr,"Line %d/%d - %d/%d (char)\n", x, BOX_SPC, x, dy - BOX_SPC)); } no_redraw: break; /* end of case KeyPress */ } /* end of switch (event.type) */ continue; } /* end of if (event.xany.window == CF.frame) */ for (item = root_item_ptr; item != 0; item = item->header.next) { /* all items */ if (event.xany.window == item->header.win) { switch (event.type) { case Expose: { int ex = event.xexpose.x; int ey = event.xexpose.y; int ex2 = event.xexpose.x + event.xexpose.width; int ey2 = event.xexpose.y + event.xexpose.height; while (FCheckTypedWindowEvent( dpy, item->header.win, Expose, &event)) { ex = min(ex, event.xexpose.x); ey = min(ey, event.xexpose.y); ex2 = max(ex2, event.xexpose.x + event.xexpose.width); ey2 = max(ey2 , event.xexpose.y + event.xexpose.height); } event.xexpose.x = ex; event.xexpose.y = ey; event.xexpose.width = ex2 - ex; event.xexpose.height = ey2 - ey; RedrawItem(item, 0, &event); } break; case ButtonPress: if (item->type == I_INPUT) { old_item = CF.cur_input; CF.cur_input = item; RedrawItem(old_item, 1, NULL); { Bool done = False; CF.abs_cursor = 0; while(CF.abs_cursor <= item->input.size && !done) { if (FlocaleTextWidth(item->header.dt_ptr->dt_Ffont, item->input.value, CF.abs_cursor) >= event.xbutton.x - BOX_SPC - TEXT_SPC) { done = True; CF.abs_cursor--; } else { CF.abs_cursor++; } } } if (CF.abs_cursor < 0) CF.abs_cursor = 0; if (CF.abs_cursor > item->input.size) CF.abs_cursor = item->input.size; CF.rel_cursor = CF.abs_cursor + item->input.left; if (CF.rel_cursor < 0) CF.rel_cursor = 0; if (CF.rel_cursor > item->input.n) CF.rel_cursor = item->input.n; if (CF.rel_cursor > 0 && CF.rel_cursor == item->input.left) item->input.left--; if (CF.rel_cursor < item->input.n && CF.rel_cursor == item->input.left + item->input.size) item->input.left++; CF.abs_cursor = CF.rel_cursor - item->input.left; if (event.xbutton.button == Button2) { /* if paste request */ process_paste_request (&event, item); } RedrawItem(item, 0, NULL); } if (item->type == I_CHOICE) ToggleChoice(item); if (item->type == I_BUTTON) { RedrawItem(item, 1, NULL); /* push button in */ if (CF.activate_on_press) { usleep(MICRO_S_FOR_10MS); /* make sure its visible */ RedrawItem(item, 0, NULL); /* pop button out */ DoCommand(item); /* execute the button command */ } else { XGrabPointer(dpy, item->header.win, False, /* owner of events */ ButtonReleaseMask, /* events to report */ GrabModeAsync, /* keyboard mode */ GrabModeAsync, /* pointer mode */ None, /* confine to */ /* I sort of like this, the hand points in the other direction and the color is reversed. I don't know what other GUIs do, Java doesn't do anything, neither does anything else I can find...dje */ CF.pointer[button_in_pointer], /* cursor */ CurrentTime); } /* end activate on press */ } break; case ButtonRelease: if (!CF.activate_on_press) { RedrawItem(item, 0, NULL); if (CF.grab_server && CF.server_grabbed) { /* You have to regrab the pointer, or focus can go to another window. grab... */ XGrabPointer(dpy, CF.frame, True, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); XFlush(dpy); } else { XUngrabPointer(dpy, CurrentTime); XFlush(dpy); } if (event.xbutton.x >= 0 && event.xbutton.x < item->header.size_x && event.xbutton.y >= 0 && event.xbutton.y < item->header.size_y) { DoCommand(item); } } break; } } } /* end of for (i = 0) */ } /* while loop */ }
GdkGrabStatus _gdk_windowing_pointer_grab (GdkWindow *window, GdkWindow *native, gboolean owner_events, GdkEventMask event_mask, GdkWindow *confine_to, GdkCursor *cursor, guint32 time) { gint return_val; GdkCursorPrivate *cursor_private; GdkDisplayX11 *display_x11; guint xevent_mask; Window xwindow; Window xconfine_to; Cursor xcursor; int i; if (confine_to) confine_to = _gdk_window_get_impl_window (confine_to); display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (native)); cursor_private = (GdkCursorPrivate*) cursor; xwindow = GDK_WINDOW_XID (native); if (!confine_to || GDK_WINDOW_DESTROYED (confine_to)) xconfine_to = None; else xconfine_to = GDK_WINDOW_XID (confine_to); if (!cursor) xcursor = None; else { _gdk_x11_cursor_update_theme (cursor); xcursor = cursor_private->xcursor; } xevent_mask = 0; for (i = 0; i < _gdk_nenvent_masks; i++) { if (event_mask & (1 << (i + 1))) xevent_mask |= _gdk_event_mask_table[i]; } /* We don't want to set a native motion hint mask, as we're emulating motion * hints. If we set a native one we just wouldn't get any events. */ xevent_mask &= ~PointerMotionHintMask; return_val = _gdk_input_grab_pointer (window, native, owner_events, event_mask, confine_to, time); if (return_val == GrabSuccess || G_UNLIKELY (!display_x11->trusted_client && return_val == AlreadyGrabbed)) { if (!GDK_WINDOW_DESTROYED (native)) { #ifdef G_ENABLE_DEBUG if (_gdk_debug_flags & GDK_DEBUG_NOGRABS) return_val = GrabSuccess; else #endif return_val = XGrabPointer (GDK_WINDOW_XDISPLAY (native), xwindow, owner_events, xevent_mask, GrabModeAsync, GrabModeAsync, xconfine_to, xcursor, time); } else return_val = AlreadyGrabbed; } if (return_val == GrabSuccess) _gdk_x11_roundtrip_async (GDK_DISPLAY_OBJECT (display_x11), has_pointer_grab_callback, NULL); return gdk_x11_convert_grab_status (return_val); }
gint main (gint argc, gchar *argv[]) { Window root; //gettext bindtextdomain( "gamine", LOCALDIR ); textdomain( "gamine" ); gamine_t cb; GtkWidget *window; GdkWindow *gdkwindow; GtkWindow *gtkwindow; GdkScreen *screen; GdkPixbuf *cursor_pixbuf; GdkPixbuf *icon_pixbuf; GdkCursor *cursor; GdkColor bg_color; gchar *cursorfile; gchar *iconfile; cb.is_cairo = FALSE; gtk_init (&argc, &argv); gst_init (&argc, &argv); gconf_init(argc, argv, NULL); gst_play_background (cb.bus, "BachJSBrandenburgConcertNo2inFMajorBWV1047mvmt1.ogg", TRUE); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* Create the drawing area and configuration */ cb.da = gtk_drawing_area_new (); bg_color.red = 65535; bg_color.green = 65535; bg_color.blue = 65535; gtk_widget_modify_bg (cb.da, GTK_STATE_NORMAL, &bg_color); gtk_container_add (GTK_CONTAINER (window), cb.da); cb.gc = gconf_client_get_default(); gtkwindow = GTK_WINDOW(window); gtk_window_set_title (gtkwindow, "Gamine"); gtk_window_set_wmclass(gtkwindow, "gamine", "Gamine"); gtk_container_set_border_width (GTK_CONTAINER (gtkwindow), 0); /* Event signals */ g_signal_connect (gtkwindow, "destroy", G_CALLBACK (gtk_main_quit), >kwindow); g_signal_connect (G_OBJECT (cb.da), "expose-event", G_CALLBACK (display_help), &cb); g_signal_connect (cb.da, "motion_notify_event", G_CALLBACK (draw_line), &cb); g_signal_connect (cb.da, "button_press_event", G_CALLBACK (draw_star), &cb); g_signal_connect (gtkwindow, "key-press-event", G_CALLBACK (gamine_on_key), &cb); gtk_widget_set_events (cb.da, gtk_widget_get_events (cb.da) | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); /* Set fullscreen, grab mouse/keyboard, ...*/ gtk_widget_show_all (GTK_WIDGET(gtkwindow)); gdkwindow = GDK_WINDOW(GTK_WIDGET(gtkwindow)->window); screen = gtk_widget_get_screen (cb.da); gtk_window_present (gtkwindow); gtk_window_stick(gtkwindow); //gtk_window_set_keep_above (gtkwindow), True); //gtk_window_set_transient_for (gtkwindow, NULL); //set fullscreen gdk_window_fullscreen (gdkwindow); gtk_window_fullscreen (gtkwindow); gdk_window_raise (gdkwindow); //set full screen without window manager XMoveResizeWindow(GDK_WINDOW_XDISPLAY(gdkwindow), GDK_WINDOW_XID(gdkwindow), 0, 0, gdk_screen_get_width (screen), gdk_screen_get_height (screen)); root = DefaultRootWindow(GDK_WINDOW_XDISPLAY (gdkwindow)); XGrabPointer(GDK_WINDOW_XDISPLAY (gdkwindow), root, True, PointerMotionMask, GrabModeAsync, GrabModeAsync, root, None, CurrentTime); XGrabKeyboard(GDK_WINDOW_XDISPLAY (gdkwindow), root, True, GrabModeAsync, GrabModeAsync, CurrentTime); //remove keyboard repeat XAutoRepeatOff(GDK_WINDOW_XDISPLAY (gdkwindow)); gtk_window_has_toplevel_focus (gtkwindow); /*cursor*/ cursorfile = g_build_filename(DATADIR, "pencil.png", NULL); if (!g_file_test (cursorfile, G_FILE_TEST_EXISTS)) { printf(gettext("*** error: %s does not exists***\n"), cursorfile); } else { cursor_pixbuf = gdk_pixbuf_new_from_file(cursorfile, NULL); cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), cursor_pixbuf, 0, 38); gdk_window_set_cursor(gdkwindow, cursor); gdk_cursor_unref(cursor); gdk_pixbuf_unref(cursor_pixbuf); } g_free(cursorfile); /*Set icon*/ iconfile = g_build_filename(DATADIR, "gamine.png", NULL); if (!g_file_test (iconfile, G_FILE_TEST_EXISTS)) printf(gettext("*** error: %s does not exists***\n"), iconfile); else { icon_pixbuf = gdk_pixbuf_new_from_file(iconfile, NULL); gtk_window_set_icon (gtkwindow, icon_pixbuf); gdk_pixbuf_unref (icon_pixbuf); } g_free(iconfile); load_conf(&cb); gtk_main (); //set keyboard repeat XAutoRepeatOn(GDK_WINDOW_XDISPLAY (gdkwindow)); XCloseDisplay(GDK_WINDOW_XDISPLAY (gdkwindow)); return 0; }
int TkPointerEvent( register XEvent *eventPtr, /* Pointer to the event. */ TkWindow *winPtr) /* Tk's information for window where event was * reported. */ { register TkWindow *winPtr2; TkDisplay *dispPtr = winPtr->dispPtr; unsigned int serial; int outsideGrabTree = 0; int ancestorOfGrab = 0; int appGrabbed = 0; /* Non-zero means event is being reported to * an application that is affected by the * grab. */ /* * Collect information about the grab (if any). */ switch (TkGrabState(winPtr)) { case TK_GRAB_IN_TREE: appGrabbed = 1; break; case TK_GRAB_ANCESTOR: appGrabbed = 1; outsideGrabTree = 1; ancestorOfGrab = 1; break; case TK_GRAB_EXCLUDED: appGrabbed = 1; outsideGrabTree = 1; break; } if ((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify)) { /* * Keep track of what window the mouse is *really* over. Any events * that we generate have a special send_event value, which is detected * below and used to ignore the event for purposes of setting * serverWinPtr. */ if (eventPtr->xcrossing.send_event != GENERATED_GRAB_EVENT_MAGIC) { if ((eventPtr->type == LeaveNotify) && (winPtr->flags & TK_TOP_HIERARCHY)) { dispPtr->serverWinPtr = NULL; } else { dispPtr->serverWinPtr = winPtr; } } /* * When a grab is active, X continues to report enter and leave events * for windows outside the tree of the grab window: * 1. Detect these events and ignore them except for windows above the * grab window. * 2. Allow Enter and Leave events to pass through the windows above * the grab window, but never let them end up with the pointer *in* * one of those windows. */ if (dispPtr->grabWinPtr != NULL) { if (outsideGrabTree && appGrabbed) { if (!ancestorOfGrab) { return 0; } switch (eventPtr->xcrossing.detail) { case NotifyInferior: return 0; case NotifyAncestor: eventPtr->xcrossing.detail = NotifyVirtual; break; case NotifyNonlinear: eventPtr->xcrossing.detail = NotifyNonlinearVirtual; break; } } /* * Make buttons have the same grab-like behavior inside a grab as * they do outside a grab: do this by ignoring enter and leave * events except for the window in which the button was pressed. */ if ((dispPtr->buttonWinPtr != NULL) && (winPtr != dispPtr->buttonWinPtr)) { return 0; } } return 1; } if (!appGrabbed) { return 1; } if (eventPtr->type == MotionNotify) { /* * When grabs are active, X reports motion events relative to the * window under the pointer. Instead, it should report the events * relative to the window the button went down in, if there is a * button down. Otherwise, if the pointer window is outside the * subtree of the grab window, the events should be reported relative * to the grab window. Otherwise, the event should be reported to the * pointer window. */ winPtr2 = winPtr; if (dispPtr->buttonWinPtr != NULL) { winPtr2 = dispPtr->buttonWinPtr; } else if (outsideGrabTree || (dispPtr->serverWinPtr == NULL)) { winPtr2 = dispPtr->grabWinPtr; } if (winPtr2 != winPtr) { TkChangeEventWindow(eventPtr, winPtr2); Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD); return 0; } return 1; } /* * Process ButtonPress and ButtonRelease events: * 1. Keep track of whether a button is down and what window it went down * in. * 2. If the first button goes down outside the grab tree, pretend it went * down in the grab window. Note: it's important to redirect events to * the grab window like this in order to make things like menus work, * where button presses outside the grabbed menu need to be seen. An * application can always ignore the events if they occur outside its * window. * 3. If a button press or release occurs outside the window where the * first button was pressed, retarget the event so it's reported to the * window where the first button was pressed. * 4. If the last button is released in a window different than where the * first button was pressed, generate Enter/Leave events to move the * mouse from the button window to its current window. * 5. If the grab is set at a time when a button is already down, or if * the window where the button was pressed was deleted, then * dispPtr->buttonWinPtr will stay NULL. Just forget about the * auto-grab for the button press; events will go to whatever window * contains the pointer. If this window isn't in the grab tree then * redirect events to the grab window. * 6. When a button is pressed during a local grab, the X server sets a * grab of its own, since it doesn't even know about our local grab. * This causes enter and leave events no longer to be generated in the * same way as for global grabs. To eliminate this problem, set a * temporary global grab when the first button goes down and release it * when the last button comes up. */ if ((eventPtr->type == ButtonPress) || (eventPtr->type == ButtonRelease)) { winPtr2 = dispPtr->buttonWinPtr; if (winPtr2 == NULL) { if (outsideGrabTree) { winPtr2 = dispPtr->grabWinPtr; /* Note 5. */ } else { winPtr2 = winPtr; /* Note 5. */ } } if (eventPtr->type == ButtonPress) { if ((eventPtr->xbutton.state & ALL_BUTTONS) == 0) { if (outsideGrabTree) { TkChangeEventWindow(eventPtr, dispPtr->grabWinPtr); Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD); return 0; /* Note 2. */ } if (!(dispPtr->grabFlags & GRAB_GLOBAL)) { /* Note 6. */ serial = NextRequest(dispPtr->display); if (XGrabPointer(dispPtr->display, dispPtr->grabWinPtr->window, True, ButtonPressMask|ButtonReleaseMask|ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime) == 0) { EatGrabEvents(dispPtr, serial); if (XGrabKeyboard(dispPtr->display, winPtr->window, False, GrabModeAsync, GrabModeAsync, CurrentTime) == 0) { dispPtr->grabFlags |= GRAB_TEMP_GLOBAL; } else { XUngrabPointer(dispPtr->display, CurrentTime); } } } dispPtr->buttonWinPtr = winPtr; return 1; } } else { if ((eventPtr->xbutton.state & ALL_BUTTONS) == buttonStates[eventPtr->xbutton.button - Button1]) { ReleaseButtonGrab(dispPtr); /* Note 4. */ } } if (winPtr2 != winPtr) { TkChangeEventWindow(eventPtr, winPtr2); Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD); return 0; /* Note 3. */ } } return 1; }
int Tk_Grab( Tcl_Interp *interp, /* Used for error reporting. */ Tk_Window tkwin, /* Window on whose behalf the pointer is to be * grabbed. */ int grabGlobal) /* Non-zero means issue a grab to the server * so that no other application gets mouse or * keyboard events. Zero means the grab only * applies within this application. */ { int grabResult, numTries; TkWindow *winPtr = (TkWindow *) tkwin; TkDisplay *dispPtr = winPtr->dispPtr; TkWindow *winPtr2; unsigned int serial; ReleaseButtonGrab(dispPtr); if (dispPtr->eventualGrabWinPtr != NULL) { if ((dispPtr->eventualGrabWinPtr == winPtr) && (grabGlobal == ((dispPtr->grabFlags & GRAB_GLOBAL) != 0))) { return TCL_OK; } if (dispPtr->eventualGrabWinPtr->mainPtr != winPtr->mainPtr) { alreadyGrabbed: Tcl_SetResult(interp, "grab failed: another application has grab", TCL_STATIC); return TCL_ERROR; } Tk_Ungrab((Tk_Window) dispPtr->eventualGrabWinPtr); } Tk_MakeWindowExist(tkwin); #ifndef MAC_OSX_TK if (!grabGlobal) #else if (0) #endif { Window dummy1, dummy2; int dummy3, dummy4, dummy5, dummy6; unsigned int state; /* * Local grab. However, if any mouse buttons are down, turn it into a * global grab temporarily, until the last button goes up. This does * two things: (a) it makes sure that we see the button-up event; and * (b) it allows us to track mouse motion among all of the windows of * this application. */ dispPtr->grabFlags &= ~(GRAB_GLOBAL|GRAB_TEMP_GLOBAL); XQueryPointer(dispPtr->display, winPtr->window, &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &state); if ((state & ALL_BUTTONS) != 0) { dispPtr->grabFlags |= GRAB_TEMP_GLOBAL; goto setGlobalGrab; } } else { dispPtr->grabFlags |= GRAB_GLOBAL; setGlobalGrab: /* * Tricky point: must ungrab before grabbing. This is needed in case * there is a button auto-grab already in effect. If there is, and the * mouse has moved to a different window, X won't generate enter and * leave events to move the mouse if we grab without ungrabbing. */ XUngrabPointer(dispPtr->display, CurrentTime); serial = NextRequest(dispPtr->display); /* * Another tricky point: there are races with some window managers * that can cause grabs to fail because the window manager hasn't * released its grab quickly enough. To work around this problem, * retry a few times after AlreadyGrabbed errors to give the grab * release enough time to register with the server. */ grabResult = 0; /* Needed only to prevent gcc compiler * warnings. */ for (numTries = 0; numTries < 10; numTries++) { grabResult = XGrabPointer(dispPtr->display, winPtr->window, True, ButtonPressMask|ButtonReleaseMask|ButtonMotionMask |PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); if (grabResult != AlreadyGrabbed) { break; } Tcl_Sleep(100); } if (grabResult != 0) { grabError: if (grabResult == GrabNotViewable) { Tcl_SetResult(interp, "grab failed: window not viewable", TCL_STATIC); } else if (grabResult == AlreadyGrabbed) { goto alreadyGrabbed; } else if (grabResult == GrabFrozen) { Tcl_SetResult(interp, "grab failed: keyboard or pointer frozen", TCL_STATIC); } else if (grabResult == GrabInvalidTime) { Tcl_SetResult(interp, "grab failed: invalid time", TCL_STATIC); } else { char msg[64 + TCL_INTEGER_SPACE]; sprintf(msg, "grab failed for unknown reason (code %d)", grabResult); Tcl_AppendResult(interp, msg, NULL); } return TCL_ERROR; } grabResult = XGrabKeyboard(dispPtr->display, Tk_WindowId(tkwin), False, GrabModeAsync, GrabModeAsync, CurrentTime); if (grabResult != 0) { XUngrabPointer(dispPtr->display, CurrentTime); goto grabError; } /* * Eat up any grab-related events generated by the server for the * grab. There are several reasons for doing this: * * 1. We have to synthesize the events for local grabs anyway, since * the server doesn't participate in them. * 2. The server doesn't always generate the right events for global * grabs (e.g. it generates events even if the current window is in * the grab tree, which we don't want). * 3. We want all the grab-related events to be processed immediately * (before other events that are already queued); events coming * from the server will be in the wrong place, but events we * synthesize here will go to the front of the queue. */ EatGrabEvents(dispPtr, serial); } /* * Synthesize leave events to move the pointer from its current window up * to the lowest ancestor that it has in common with the grab window. * However, only do this if the pointer is outside the grab window's * subtree but inside the grab window's application. */ if ((dispPtr->serverWinPtr != NULL) && (dispPtr->serverWinPtr->mainPtr == winPtr->mainPtr)) { for (winPtr2 = dispPtr->serverWinPtr; ; winPtr2 = winPtr2->parentPtr) { if (winPtr2 == winPtr) { break; } if (winPtr2 == NULL) { MovePointer2(dispPtr->serverWinPtr, winPtr, NotifyGrab, 1, 0); break; } } } QueueGrabWindowChange(dispPtr, winPtr); return TCL_OK; }
void UXViewport::CaptureInputs() { guard(UXViewport::CaptureInputs); // Check keyboard state. XKeyboardState KeyState; XGetKeyboardControl(XDisplay, &KeyState); if( KeyState.global_auto_repeat == AutoRepeatModeOn ) { RestoreAutoRepeat = true; XAutoRepeatOff( XDisplay ); } // Examine root window. Window RootRoot; int r_x, r_y; unsigned int r_width, r_height, r_border, r_depth; XGetGeometry( XDisplay, DefaultRootWindow(XDisplay), &RootRoot, &r_x, &r_y, &r_width, &r_height, &r_border, &r_depth ); XWarpPointer(XDisplay, None, XWindow, 0, 0, 0, 0, r_width/2, r_height/2); XSync(XDisplay, False); //XDefineCursor(XDisplay, XWindow, GetNullCursor()); // Capture the pointer. XGrabPointer(XDisplay, XWindow, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, XWindow, None, CurrentTime ); // Control acceleration. XChangePointerControl(XDisplay, True, True, 2, 1, 0); XSync(XDisplay, False); // Query DGA capabilities. UXClient* C = GetOuterUXClient(); if (C->DGAMouseEnabled) { INT VersionMajor, VersionMinor; if (!XF86DGAQueryVersion(XDisplay, &VersionMajor, &VersionMinor)) { debugf( TEXT("XF86DGA disabled.") ); UseDGA = false; } else { debugf( TEXT("XF86DGA enabled.") ); UseDGA = true; XF86DGADirectVideo(XDisplay, DefaultScreen(XDisplay), XF86DGADirectMouse); XWarpPointer(XDisplay, None, XWindow, 0, 0, 0, 0, 0, 0); } } else UseDGA = false; XGrabKeyboard(XDisplay, XWindow, False, GrabModeAsync, GrabModeAsync, CurrentTime); XSync(XDisplay, False); unguard; }
static void I_VerifyPointerGrabState(void) { #ifndef AGGR_FOCUS boolean focused; // Are we the focused window? { Window fwin = None; int revert_to = 0; XGetInputFocus(X_display, &fwin, &revert_to); // WARNING: non-portable? focused = (fwin == X_mainWindow) ? true : false; } #endif if (!grabMouse) return; // CPhipps - do not grab the mouse if paused // or not playing a level or the window is obscured // or during demo playback // DO grab in menus, because needed for key bindings screen if (paused || (gamestate != GS_LEVEL) || (vis_flag != VisibilityUnobscured) #ifndef AGGR_FOCUS || !focused #endif || demoplayback) { if (grabbed) { // Release the mouse XUngrabPointer(X_display, CurrentTime); // Post a Doom event saying there is no movement and no buttons event.type = ev_mouse; event.data1 = event.data2 = event.data3 = 0; } grabbed = false; } else { #ifdef AGGR_FOCUS XSetInputFocus(X_display, X_mainWindow, RevertToParent, CurrentTime); #endif // grabs the pointer so it is restricted to this window if (!grabbed && (vis_flag == VisibilityUnobscured)) { XGrabPointer(X_display, X_mainWindow, True, #ifndef POLL_POINTER ButtonPressMask|ButtonReleaseMask|PointerMotionMask, #else 0, #endif GrabModeAsync, GrabModeAsync, X_mainWindow, None, CurrentTime); I_QueryPointer(&newmouse, NULL); } grabbed = true; /* Warp the pointer back to the middle of the window * or it could end up stuck on an edge * Only warping if needed */ if (abs(newmouse.x - X_width/2) > (X_width/2 - 32) || abs(newmouse.y - X_height/2) > (X_height/2 - 20)) { /*mead allow larger deltas by preserving pre-warp portion.*/ lastmouse.x = (X_width/2 - (newmouse.x - lastmouse.x)); lastmouse.y = (X_height/2 - (newmouse.y - lastmouse.y)); XWarpPointer( X_display, None, X_mainWindow, 0, 0, 0, 0, X_width/2, X_height/2); } else { lastmouse = newmouse; } } }
Error ContextGL_X11::initialize() { GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = NULL; // const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display)); glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); ERR_FAIL_COND_V( !glXCreateContextAttribsARB, ERR_UNCONFIGURED ); static int visual_attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_DOUBLEBUFFER, true, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 24, None }; int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount); ERR_FAIL_COND_V(!fbc,ERR_UNCONFIGURED); XVisualInfo *vi = glXGetVisualFromFBConfig(x11_display, fbc[0]); XSetWindowAttributes swa; swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone); swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; /* char* windowid = getenv("GODOT_WINDOWID"); if (windowid) { //freopen("/home/punto/stdout", "w", stdout); //reopen("/home/punto/stderr", "w", stderr); x11_window = atol(windowid); } else { */ x11MotivHints.flags = 2; x11MotivHints.decorations = 0; xiaNewProperty = XInternAtom( x11_display,"_MOTIF_WM_HINTS", True ); vidModeBest = 0; vidModeCount = 0; windowWidth = 1024; windowHeight = 768; dpyWidth = 0; dpyHeight = 0; screenBackup = vi->screen; XF86VidModeGetAllModeLines( x11_display, vi->screen, &vidModeCount, &vidModes ); printf("Debug: vidModeCount=%d\n", vidModeCount ); desktopMode = *vidModes[ 0 ]; for ( int i = 0; i < vidModeCount; i++ ){ if (( vidModes[i]->hdisplay == windowWidth) && ( vidModes[i]->vdisplay == windowHeight )) vidModeBest = i; } printf("vidModeBest=%d\n",vidModeBest); glXQueryVersion( x11_display, &glxMajor, &glxMinor ); printf( "Debug: GLX-Version %d.%d\n", glxMajor, glxMinor ); context = glXCreateContext( x11_display, vi, 0, GL_TRUE ); cmap = XCreateColormap( x11_display, RootWindow( x11_display, vi->screen ), vi->visual, AllocNone ); winAttr.colormap = cmap; winAttr.border_pixel = 0; XChangeProperty( x11_display, RootWindow( x11_display, vi->screen ), xiaNewProperty, xiaNewProperty, 32, PropModeReplace, ( unsigned char * ) &x11MotivHints, 5 ); XF86VidModeSwitchToMode( x11_display, vi->screen, vidModes[ vidModeBest ] ); XF86VidModeSetViewPort( x11_display, vi->screen, 0, 0 ); XMoveResizeWindow( x11_display, RootWindow( x11_display, vi->screen ), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height ); XMapRaised( x11_display, RootWindow( x11_display, vi->screen ) ); dpyWidth = vidModes[vidModeBest]->hdisplay; dpyHeight = vidModes[vidModeBest]->vdisplay; XFree(vidModes); winAttr.override_redirect = True; winAttr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; x11_window = XCreateWindow( x11_display, RootWindow( x11_display, vi->screen ), 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &winAttr ); XWarpPointer( x11_display, None, x11_window, 0, 0, 0, 0, 0, 0 ); XMapRaised( x11_display, x11_window ); XGrabKeyboard( x11_display, x11_window, True, GrabModeAsync, GrabModeAsync, CurrentTime ); XGrabPointer( x11_display, x11_window, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime ); //x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa); ERR_FAIL_COND_V(!x11_window,ERR_UNCONFIGURED); XMapWindow(x11_display, x11_window); while(true) { // wait for mapnotify (window created) XEvent e; XNextEvent(x11_display, &e); if (e.type == MapNotify) break; } //}; if (!OS::get_singleton()->get_video_mode().resizable) { XSizeHints *xsh; xsh = XAllocSizeHints(); xsh->flags = PMinSize | PMaxSize; xsh->min_width = OS::get_singleton()->get_video_mode().width; xsh->max_width = OS::get_singleton()->get_video_mode().width; xsh->min_height = OS::get_singleton()->get_video_mode().height; xsh->max_height = OS::get_singleton()->get_video_mode().height; XSetWMNormalHints(x11_display, x11_window, xsh); } if (!opengl_3_context) { //oldstyle context: p->glx_context = glXCreateContext(x11_display, vi, 0, GL_TRUE); } else { static int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, None }; p->glx_context = glXCreateContextAttribsARB(x11_display, fbc[0], NULL, true, context_attribs); ERR_FAIL_COND_V(!p->glx_context,ERR_UNCONFIGURED); } glXMakeCurrent(x11_display, x11_window, p->glx_context); /* glWrapperInit(wrapper_get_proc_address); glFlush(); glXSwapBuffers(x11_display,x11_window); */ //glXMakeCurrent(x11_display, None, NULL); return OK; }
static int config(struct vo *vo, uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, uint32_t format) { struct priv *p = vo->priv; Colormap theCmap; const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt; #ifdef CONFIG_XF86VM int vm = flags & VOFLAG_MODESWITCHING; #endif p->Flip_Flag = flags & VOFLAG_FLIPPING; p->zoomFlag = 1; p->old_vo_dwidth = -1; p->old_vo_dheight = -1; p->in_format = format; p->srcW = width; p->srcH = height; XGetWindowAttributes(vo->x11->display, vo->x11->rootwin, &p->attribs); p->depth = p->attribs.depth; if (p->depth != 15 && p->depth != 16 && p->depth != 24 && p->depth != 32) { Visual *visual; p->depth = vo_find_depth_from_visuals(vo->x11->display, vo->x11->screen, &visual); } if (!XMatchVisualInfo(vo->x11->display, vo->x11->screen, p->depth, DirectColor, &p->vinfo) || (WinID > 0 && p->vinfo.visualid != XVisualIDFromVisual(p->attribs.visual))) { XMatchVisualInfo(vo->x11->display, vo->x11->screen, p->depth, TrueColor, &p->vinfo); } /* set image size (which is indeed neither the input nor output size), if zoom is on it will be changed during draw_slice anyway so we don't duplicate the aspect code here */ p->image_width = (width + 7) & (~7); p->image_height = height; { #ifdef CONFIG_XF86VM if (vm) vo_vm_switch(vo); #endif theCmap = vo_x11_create_colormap(vo, &p->vinfo); vo_x11_create_vo_window(vo, &p->vinfo, vo->dx, vo->dy, vo->dwidth, vo->dheight, flags, theCmap, "x11"); if (WinID > 0) p->depth = vo_x11_update_geometry(vo, true); #ifdef CONFIG_XF86VM if (vm) { /* Grab the mouse pointer in our window */ if (vo_grabpointer) XGrabPointer(vo->x11->display, vo->x11->window, True, 0, GrabModeAsync, GrabModeAsync, vo->x11->window, None, CurrentTime); XSetInputFocus(vo->x11->display, vo->x11->window, RevertToNone, CurrentTime); } #endif } if (p->myximage) { freeMyXImage(p); sws_freeContext(p->swsContext); } getMyXImage(p); while (fmte->mpfmt) { int depth = IMGFMT_RGB_DEPTH(fmte->mpfmt); /* bits_per_pixel in X seems to be set to 16 for 15 bit formats => force depth to 16 so that only the color masks are used for the format check */ if (depth == 15) depth = 16; if (depth == p->myximage->bits_per_pixel && fmte->byte_order == p->myximage->byte_order && fmte->red_mask == p->myximage->red_mask && fmte->green_mask == p->myximage->green_mask && fmte->blue_mask == p->myximage->blue_mask) break; fmte++; } if (!fmte->mpfmt) { mp_msg( MSGT_VO, MSGL_ERR, "X server image format not supported, please contact the developers\n"); return -1; } p->out_format = fmte->mpfmt; p->bpp = p->myximage->bits_per_pixel; p->out_offset = 0; // We can easily "emulate" non-native RGB32 and BGR32 if (p->out_format == (IMGFMT_BGR32 | 128) || p->out_format == (IMGFMT_RGB32 | 128)) { p->out_format &= ~128; #if BYTE_ORDER == BIG_ENDIAN p->out_offset = 1; #else p->out_offset = -1; #endif } /* always allocate swsContext as size could change between frames */ p->swsContext = sws_getContextFromCmdLine(width, height, p->in_format, width, height, p->out_format); if (!p->swsContext) return -1; p->dst_width = width; return 0; }
bool fxwt::init_graphics(GraphicsInitParameters *gparams) { Display *dpy; Window win; info("Initializing GLX"); if(!(dpy = XOpenDisplay(0))) { error("Could not connect to the X server"); return false; } int screen = DefaultScreen(dpy); Window root_win = RootWindow(dpy, screen); info("Trying to set video mode %dx%dx%d, d:%d s:%d %s", gparams->x, gparams->y, gparams->bpp, gparams->depth_bits, gparams->stencil_bits, gparams->fullscreen ? "fullscreen" : "windowed"); // determine color bits int color_bits = 1; if(!(gparams->dont_care_flags & DONT_CARE_BPP)) { switch(gparams->bpp) { case 32: case 24: color_bits = 8; break; case 16: case 15: color_bits = 5; break; case 12: color_bits = 4; break; default: error("%s: Tried to set unsupported pixel format: %d bpp", __func__, gparams->bpp); } } // determine stencil bits int stencil_bits = gparams->stencil_bits; if(gparams->dont_care_flags & DONT_CARE_STENCIL) { stencil_bits = 1; } // determine zbuffer bits int zbits = gparams->depth_bits == 32 ? 24 : gparams->depth_bits; if(gparams->dont_care_flags & DONT_CARE_BPP) { zbits = 1; } int glx_attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, color_bits, GLX_GREEN_SIZE, color_bits, GLX_BLUE_SIZE, color_bits, GLX_DEPTH_SIZE, zbits, GLX_STENCIL_SIZE, stencil_bits, None }; XVisualInfo *vis_info; if(!(vis_info = glXChooseVisual(dpy, screen, glx_attrib))) { error("%s: Could not set requested video mode", __func__); XCloseDisplay(dpy); return false; } // check the video mode we got int arbits, agbits, abbits, azbits, astencilbits; glXGetConfig(dpy, vis_info, GLX_RED_SIZE, &arbits); glXGetConfig(dpy, vis_info, GLX_GREEN_SIZE, &agbits); glXGetConfig(dpy, vis_info, GLX_BLUE_SIZE, &abbits); glXGetConfig(dpy, vis_info, GLX_DEPTH_SIZE, &azbits); glXGetConfig(dpy, vis_info, GLX_STENCIL_SIZE, &astencilbits); info("Initialized video mode:"); info(" bpp: %d (%d%d%d)", arbits + agbits + abbits, arbits, agbits, abbits); info("zbuffer: %d", azbits); info("stencil: %d", astencilbits); /* if the dont_care_flags does not contain DONT_CARE_BPP and our color bits * does not match, we should return failure, however we test against * the difference allowing a +/-1 difference in order to allow for 16bpp * formats of either 565 or 555 and consider them equal. */ if(!(gparams->dont_care_flags & DONT_CARE_BPP) && abs(arbits - color_bits) > 1 && abs(agbits - color_bits) > 1 && abs(abbits - color_bits) > 1) { error("%s: Could not set requested exact bpp mode", __func__); XFree(vis_info); XCloseDisplay(dpy); return false; } // now if we don't have DONT_CARE_DEPTH in the dont_care_flags check for // exact depth buffer format, however consider 24 and 32 bit the same if(!(gparams->dont_care_flags & DONT_CARE_DEPTH) && azbits != zbits) { if(!(zbits == 32 && azbits == 24 || zbits == 24 && azbits == 32)) { error("%s: Could not set requested exact zbuffer depth", __func__); XFree(vis_info); XCloseDisplay(dpy); return false; } } // if we don't have DONT_CARE_STENCIL make sure we have the stencil format // that was asked. if(!(gparams->dont_care_flags & DONT_CARE_STENCIL) && astencilbits != gparams->stencil_bits) { error("%s: Could not set exact stencil format", __func__); XFree(vis_info); XCloseDisplay(dpy); return false; } // everything is ok, create the context if(!(glx_ctx = glXCreateContext(dpy, vis_info, 0, True))) { error("%s: Failed to create GLX context", __func__); XFree(vis_info); XCloseDisplay(dpy); return false; } XSetWindowAttributes xattr; xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, screen); xattr.colormap = XCreateColormap(dpy, root_win, vis_info->visual, AllocNone); if(gparams->fullscreen) { // TODO: also test for "XFree86-VidModeExtension" #ifdef USE_XF86VIDMODE info("Using XF86VidMode extension for fullscreen resolution switch."); XF86VidModeModeInfo **modes; XF86VidModeModeInfo *vid_mode = 0; int mode_count; XF86VidModeGetAllModeLines(dpy, screen, &mode_count, &modes); orig_mode = *modes[0]; for(int i=0; i<mode_count; i++) { if(modes[i]->hdisplay == gparams->x && modes[i]->vdisplay == gparams->y) { vid_mode = modes[i]; } } if(!vid_mode) { error("Could not set requested video mode"); XFree(modes); XFree(vis_info); XCloseDisplay(dpy); return -1; } XF86VidModeSwitchToMode(dpy, screen, vid_mode); XF86VidModeSetViewPort(dpy, screen, 0, 0); XFree(modes); xattr.override_redirect = True; win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth, InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr); XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0); XMapRaised(dpy, win); XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime); #else info("Resolution switching is not compiled or not supported by the X server, using a full-screen window."); XWindowAttributes root_attr; XGetWindowAttributes(dpy, root_win, &root_attr); gparams->x = root_attr.width; gparams->y = root_attr.height; xattr.override_redirect = True; win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth, InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, &xattr); XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0); XMapRaised(dpy, win); XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(dpy, win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime); #endif // USE_XF86VIDMODE fullscreen = true; } else { win = XCreateWindow(dpy, root_win, 0, 0, gparams->x, gparams->y, 0, vis_info->depth, InputOutput, vis_info->visual, CWColormap | CWBackPixel | CWBorderPixel, &xattr); } long events = ExposureMask | StructureNotifyMask | KeyPressMask; // expose and key events events |= ButtonPressMask | ButtonReleaseMask | PointerMotionMask; // mouse events XSelectInput(dpy, win, events); // set WM cooperation settings Atom wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(dpy, win, &wm_delete, 1); XTextProperty tp_wname; static char *win_title = "3dengfx/X"; XStringListToTextProperty(&win_title, 1, &tp_wname); XSetWMName(dpy, win, &tp_wname); XFree(tp_wname.value); XClassHint class_hint; class_hint.res_name = "3dengfx"; class_hint.res_class = "3dengfx_graphics"; XSetClassHint(dpy, win, &class_hint); XFree(vis_info); if(glXMakeCurrent(dpy, win, glx_ctx) == False) { error("%s: Failed to make the GLX context current", __func__); glXDestroyContext(dpy, glx_ctx); XDestroyWindow(dpy, win); XCloseDisplay(dpy); return false; } if(!glXIsDirect(dpy, glx_ctx)) { warning("using indirect rendering, which might be slow..."); } XMapWindow(dpy, win); XFlush(dpy); fxwt_x_dpy = dpy; fxwt_x_win = win; return true; }
static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) { // int screen; // int interval, prefer_blank, allow_exp, nothing; Colormap theCmap; const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt; #ifdef CONFIG_XF86VM int vm = flags & VOFLAG_MODESWITCHING; #endif Flip_Flag = flags & VOFLAG_FLIPPING; zoomFlag = flags & VOFLAG_SWSCALE; old_vo_dwidth = -1; old_vo_dheight = -1; int_pause = 0; if (!title) title = "MPlayer X11 (XImage/Shm) render"; in_format = format; srcW = width; srcH = height; XGetWindowAttributes(mDisplay, mRootWin, &attribs); depth = attribs.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) { Visual *visual; depth = vo_find_depth_from_visuals(mDisplay, mScreen, &visual); } if (!XMatchVisualInfo(mDisplay, mScreen, depth, DirectColor, &vinfo) || (WinID > 0 && vinfo.visualid != XVisualIDFromVisual(attribs.visual))) XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); /* set image size (which is indeed neither the input nor output size), if zoom is on it will be changed during draw_slice anyway so we don't duplicate the aspect code here */ image_width = (width + 7) & (~7); image_height = height; { #ifdef CONFIG_XF86VM if (vm) { vo_vm_switch(); } #endif theCmap = vo_x11_create_colormap(&vinfo); vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, vo_dwidth, vo_dheight, flags, theCmap, "x11", title); if (WinID > 0) depth = vo_x11_update_geometry(); #ifdef CONFIG_XF86VM if (vm) { /* Grab the mouse pointer in our window */ if (vo_grabpointer) XGrabPointer(mDisplay, vo_window, True, 0, GrabModeAsync, GrabModeAsync, vo_window, None, CurrentTime); XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime); } #endif } if (myximage) { freeMyXImage(); sws_freeContext(swsContext); } getMyXImage(); while (fmte->mpfmt) { int depth = IMGFMT_RGB_DEPTH(fmte->mpfmt); /* bits_per_pixel in X seems to be set to 16 for 15 bit formats => force depth to 16 so that only the color masks are used for the format check */ if (depth == 15) depth = 16; if (depth == myximage->bits_per_pixel && fmte->byte_order == myximage->byte_order && fmte->red_mask == myximage->red_mask && fmte->green_mask == myximage->green_mask && fmte->blue_mask == myximage->blue_mask) break; fmte++; } if (!fmte->mpfmt) { mp_msg(MSGT_VO, MSGL_ERR, "X server image format not supported, please contact the developers\n"); return -1; } out_format = fmte->mpfmt; switch ((bpp = myximage->bits_per_pixel)) { case 24: draw_alpha_fnc = draw_alpha_24; break; case 32: draw_alpha_fnc = draw_alpha_32; break; case 15: case 16: if (depth == 15) draw_alpha_fnc = draw_alpha_15; else draw_alpha_fnc = draw_alpha_16; break; default: draw_alpha_fnc = draw_alpha_null; } out_offset = 0; // for these formats conversion is currently not support and // we can easily "emulate" them. if (out_format & 64 && (IMGFMT_IS_RGB(out_format) || IMGFMT_IS_BGR(out_format))) { out_format &= ~64; #if HAVE_BIGENDIAN out_offset = 1; #else out_offset = -1; #endif } /* always allocate swsContext as size could change between frames */ swsContext = sws_getContextFromCmdLine(width, height, in_format, width, height, out_format); if (!swsContext) return -1; dst_width = width; //printf( "X11 bpp: %d color mask: R:%lX G:%lX B:%lX\n",bpp,myximage->red_mask,myximage->green_mask,myximage->blue_mask ); return 0; }
//--------------------------------------------------------------------------- bool hxc_popup::create(Display *d,Window daddy,int _x,int _y,HXC_POPUPNOTIFYPROC np,void *o) { if (handle) close(true); XD=d; notifyproc=np; owner=o; sy=0; sel=-1; clicked_in=0; hxc::load_res(XD); if (itemheight==0){ itemheight=hxc::font->ascent+hxc::font->descent+2; if (lpig) itemheight=max(itemheight,lpig->IconHeight+2); } w=0; int iw=0; if (lpig) iw=lpig->IconWidth+2; for (int n=0;n<menu.NumStrings;n++){ w=max(border+6+iw+(int)hxc::get_text_width(XD,menu[n].String)+6+border,w); } h=menu.NumStrings*itemheight+border*2; int move_h=0; if (daddy==0){ if (_x==POP_CURSORPOS){ Window in_win,in_child; int rootx,rooty; x=XDisplayWidth(XD,XDefaultScreen(XD))/2; y=XDisplayWidth(XD,XDefaultScreen(XD))/2; UINT mask; XQueryPointer(XD,XDefaultRootWindow(XD),&in_win,&in_child, &rootx,&rooty,&x,&y,&mask); }else{ x=_x,y=_y; } }else{ Window child; XTranslateCoordinates(XD,daddy,XDefaultRootWindow(XD),_x,_y,&x,&y,&child); XWindowAttributes wa; XGetWindowAttributes(XD,daddy,&wa); move_h=wa.height; } int sw=XDisplayWidth(XD,XDefaultScreen(XD)); int sh=XDisplayHeight(XD,XDefaultScreen(XD)); if (move_h>=sh) move_h=0; if (x+w>sw) x=sw-w; if (y+h>sh){ if (y-h-move_h>=0){ y-=h+move_h; }else{ y-=(y+h)-sh; } } XSetWindowAttributes swa; swa.backing_store=NotUseful; swa.override_redirect=True; swa.cursor=hxc::arrow_cursor; handle=XCreateWindow(XD,XDefaultRootWindow(XD),x,y,w,h,0, CopyFromParent,InputOutput,CopyFromParent, CWBackingStore | CWOverrideRedirect | CWCursor, &swa); SetProp(XD,handle,cWinProc,(DWORD)WinProc); SetProp(XD,handle,cWinThis,(DWORD)this); SetProp(XD,handle,hxc::cModal,(DWORD)0xffffffff); XSelectInput(XD,handle,KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | FocusChangeMask | PointerMotionMask | LeaveWindowMask); XMapWindow(XD,handle); XGrabPointer(XD,handle,False,PointerMotionMask | ButtonPressMask | ButtonReleaseMask,GrabModeAsync,GrabModeAsync,None, None,CurrentTime); hxc::popup_active=handle; return false; }
void AnalyzeKeyEvent(int pad, keyEvent &evt) { KeySym key = (KeySym)evt.key; int index = get_keyboard_key(pad, key); switch (evt.evt) { case KeyPress: // Shift F12 is not yet use by pcsx2. So keep it to grab/ungrab input // I found it very handy vs the automatic fullscreen detection // 1/ Does not need to detect full-screen // 2/ Can use a debugger in full-screen // 3/ Can grab input in window without the need of a pixelated full-screen if (key == XK_Shift_R || key == XK_Shift_L) s_Shift = true; if (key == XK_F12 && s_Shift) { if(!s_grab_input) { s_grab_input = true; XGrabPointer(GSdsp, GSwin, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, GSwin, None, CurrentTime); XGrabKeyboard(GSdsp, GSwin, True, GrabModeAsync, GrabModeAsync, CurrentTime); } else { s_grab_input = false; XUngrabPointer(GSdsp, CurrentTime); XUngrabKeyboard(GSdsp, CurrentTime); } } // Analog controls. if (IsAnalogKey(index)) { switch (index) { case PAD_R_LEFT: case PAD_R_UP: case PAD_L_LEFT: case PAD_L_UP: key_status->press(pad, index, -MAX_ANALOG_VALUE); break; case PAD_R_RIGHT: case PAD_R_DOWN: case PAD_L_RIGHT: case PAD_L_DOWN: key_status->press(pad, index, MAX_ANALOG_VALUE); break; } } else if (index != -1) key_status->press(pad, index); //PAD_LOG("Key pressed:%d\n", index); event.evt = KEYPRESS; event.key = key; break; case KeyRelease: if (key == XK_Shift_R || key == XK_Shift_L) s_Shift = false; if (index != -1) key_status->release(pad, index); event.evt = KEYRELEASE; event.key = key; break; case FocusIn: //XAutoRepeatOff(GSdsp); break; case FocusOut: //XAutoRepeatOn(GSdsp); s_Shift = false; break; case ButtonPress: if (index != -1) key_status->press(pad, index); break; case ButtonRelease: if (index != -1) key_status->release(pad, index); break; case MotionNotify: // FIXME: How to handle when the mouse does not move, no event generated!!! // 1/ small move == no move. Cons : can not do small movement // 2/ use a watchdog timer thread // 3/ ??? idea welcome ;) if (conf->pad_options[pad].mouse_l|conf->pad_options[pad].mouse_r) { unsigned int pad_x; unsigned int pad_y; // Note when both PADOPTION_MOUSE_R and PADOPTION_MOUSE_L are set, take only the right one if (conf->pad_options[pad].mouse_r) { pad_x = PAD_R_RIGHT; pad_y = PAD_R_UP; } else { pad_x = PAD_L_RIGHT; pad_y = PAD_L_UP; } unsigned x = evt.key & 0xFFFF; unsigned int value = (s_previous_mouse_x > x) ? s_previous_mouse_x - x : x - s_previous_mouse_x; value *= conf->get_sensibility(); if (x == 0) key_status->press(pad, pad_x, -MAX_ANALOG_VALUE); else if (x == 0xFFFF) key_status->press(pad, pad_x, MAX_ANALOG_VALUE); else if (x < (s_previous_mouse_x -2)) key_status->press(pad, pad_x, -value); else if (x > (s_previous_mouse_x +2)) key_status->press(pad, pad_x, value); else key_status->release(pad, pad_x); unsigned y = evt.key >> 16; value = (s_previous_mouse_y > y) ? s_previous_mouse_y - y : y - s_previous_mouse_y; value *= conf->get_sensibility(); if (y == 0) key_status->press(pad, pad_y, -MAX_ANALOG_VALUE); else if (y == 0xFFFF) key_status->press(pad, pad_y, MAX_ANALOG_VALUE); else if (y < (s_previous_mouse_y -2)) key_status->press(pad, pad_y, -value); else if (y > (s_previous_mouse_y +2)) key_status->press(pad, pad_y, value); else key_status->release(pad, pad_y); s_previous_mouse_x = x; s_previous_mouse_y = y; } break; }
void EvtMousePopupMenu(struct XObj *xobj, XButtonEvent *EvtButton) { static XEvent event; int x,y,hOpt,yMenu,hMenu; int x1,y1,x2,y2,oldy; int oldvalue = 0; int newvalue = 0; Window Win1,Win2,WinPop; unsigned int modif; unsigned long mask; unsigned long while_mask; XSetWindowAttributes Attr; Time start_time = 0; KeySym ks; unsigned char buf[10]; Bool End = 1; int asc = xobj->Ffont->ascent; hOpt = xobj->Ffont->height + 10; xobj->value3 = CountOption(xobj->title); yMenu = xobj->y - ((xobj->value-1) * hOpt); hMenu = xobj->value3 * hOpt; /* Creation de la fenetre menu */ XTranslateCoordinates(dpy, *xobj->ParentWin, Root, xobj->x, yMenu, &x, &y, &Win1); if (x < 0) x = 0; if (y < 0) y = 0; if (x+xobj->width > XDisplayWidth(dpy, screen)) x = XDisplayWidth(dpy, screen) - xobj->width; if (y+hMenu > XDisplayHeight(dpy, screen)) y = XDisplayHeight(dpy, screen) - hMenu; mask = 0; Attr.background_pixel = xobj->TabColor[back]; mask |= CWBackPixel; Attr.border_pixel = 0; mask |= CWBorderPixel; Attr.colormap = Pcmap; mask |= CWColormap; Attr.cursor = XCreateFontCursor(dpy, XC_hand2); mask |= CWCursor; /* Curseur pour la fenetre / Window cursor */ Attr.override_redirect = True; mask |= CWOverrideRedirect; WinPop = XCreateWindow(dpy, Root, x, y, xobj->width, hMenu, 0, Pdepth, InputOutput, Pvisual, mask, &Attr); if (xobj->colorset >= 0) SetWindowBackground(dpy, WinPop, xobj->width, hMenu, &Colorset[xobj->colorset], Pdepth, xobj->gc, True); XMapRaised(dpy, WinPop); /* Dessin du menu / Drawing the menu */ DrawPMenu(xobj, WinPop, hOpt, 0); XGrabPointer(dpy, WinPop, True, GRAB_EVMASK, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); if (EvtButton == NULL) { while_mask = ButtonPress; } else { start_time = EvtButton->time; while_mask = ButtonRelease; } while (End) { FQueryPointer(dpy, Root, &Win1, &Win2, &x1, &y1, &x2, &y2, &modif); /* Determiner l'option courante / Current option */ y2 = y2 - y; x2 = x2 - x; oldy = y2; /* calcule de xobj->value / compute xobj->value */ if ((x2 > 0) && (x2 < xobj->width) && (y2 > 0) && (y2 < hMenu)) newvalue = y2 / hOpt+1; else newvalue = 0; if (newvalue != oldvalue) { UnselectMenu(xobj, WinPop, hOpt, oldvalue, xobj->width, asc, 0); SelectMenu(xobj, WinPop, hOpt, newvalue); oldvalue = newvalue; } FNextEvent(dpy, &event); switch (event.type) { case KeyPress: XLookupString(&event.xkey, (char *)buf, sizeof(buf), &ks, NULL); if (ks == XK_Escape) { newvalue = 0; End = 0; } else if (ks == XK_Return) { End = 0; } else if (ks == XK_Up && y2 >= hOpt) { FWarpPointer(dpy, None, None, 0, 0, 0, 0, 0, -hOpt); } else if (ks == XK_Down && y2 + hOpt <= hMenu) { FWarpPointer(dpy, None, None, 0, 0, 0, 0, 0, hOpt); } break; case ButtonPress: if (while_mask == ButtonPress) End = 0; break; case ButtonRelease: if (start_time != 0 && event.xbutton.time - start_time < MENU_DRAG_TIME) { while_mask = ButtonPress; start_time = 0; } if (while_mask == ButtonRelease) End = 0; break; } } #if 0 do { FQueryPointer(dpy, Root, &Win1, &Win2, &x1, &y1, &x2, &y2, &modif); /* Determiner l'option courante / Current option */ y2 = y2 - y; x2 = x2 - x; { oldy = y2; /* calcule de xobj->value / compute xobj->value */ if ((x2 > 0) && (x2 < xobj->width) && (y2 > 0) && (y2 < hMenu)) newvalue = y2 / hOpt+1; else newvalue = 0; if (newvalue != oldvalue) { UnselectMenu(xobj, WinPop, hOpt, oldvalue, xobj->width, asc, 0); SelectMenu(xobj, WinPop, hOpt, newvalue); oldvalue = newvalue; } } FD_ZERO(&in_fdset); FD_SET(x_fd, &in_fdset); select(32, SELECT_FD_SET_CAST &in_fdset, NULL, NULL, NULL); } while (!FCheckTypedEvent(dpy, while_mask, &event)); #endif XUngrabPointer(dpy, CurrentTime); XSync(dpy,0); XDestroyWindow(dpy, WinPop); if (newvalue != 0) { xobj->value = newvalue; SendMsg(xobj, SingleClic); } }