/* This does a drag. This is copied somewhat from the dnd Xt code by César Crusius so it should behave almost exactly the way his does. From is the sending window. data_type is a dnd type in coolwidget.h, data is the actual data, and length is its length. pointer state is the state of the pointer. I set the pointer state to that *during* the drag, not before. See eh_editor in editwidget.c for details. */ void CDrag (Window from, int data_type, unsigned char *data, int length, unsigned long pointer_state) { XEvent e; long x, y; Window root; Window target, dispatch; #ifdef DND_DEBUG printf ("Drag start\n"); #endif root = DefaultRootWindow (CDisplay); XChangeProperty (CDisplay, root, DndSelection, XA_STRING, 8, PropModeReplace, data, length); XGrabPointer (CDisplay, root, False, ButtonMotionMask | ButtonPressMask | ButtonReleaseMask, GrabModeSync, GrabModeAsync, root, DndCursor[data_type].CursorID, CurrentTime); do { XAllowEvents (CDisplay, SyncPointer, CurrentTime); XNextEvent (CDisplay, &e); } while (e.type != ButtonRelease); XUngrabPointer (CDisplay, CurrentTime); if (!e.xbutton.subwindow) { #ifdef DND_DEBUG printf ("Pointer on root window, Drag end\n"); #endif return; } target = my_XmuClientWindow (CDisplay, e.xbutton.subwindow); if (target == e.xbutton.subwindow) dispatch = target; else dispatch = PointerWindow; x = e.xbutton.x_root; y = e.xbutton.y_root; e.xclient.type = ClientMessage; e.xclient.display = CDisplay; e.xclient.message_type = DndProtocol; e.xclient.format = 32; e.xclient.window = target; e.xclient.data.l[0] = data_type; e.xclient.data.l[1] = pointer_state; e.xclient.data.l[2] = from; e.xclient.data.l[3] = x + y * 65536L; e.xclient.data.l[4] = 1; /* Send the drop message */ XSendEvent (CDisplay, dispatch, True, NoEventMask, &e); #ifdef DND_DEBUG printf ("Drop send to window %ld from %ld, Drag end\n", target, from); #endif }
/* * Starts a window resize operation */ void RESIZE_EventLoop(ScreenInfo *scr, Window w, MwmWindow *tmp_win, int val1, int val2, int val1_unit, int val2_unit) { Bool finished = False, done = False; int x, y, delta_x, delta_y; Window ResizeWindow; XEvent oevent; if ((w == None) || (tmp_win == NULL)) return; /* Already checked this in functions.c, but its here too incase * there's a resize on initial placement. */ if (tmp_win && !(tmp_win->functions & MWM_FUNC_RESIZE)) { XBell(dpy, scr->screen); return; } /* can't resize icons */ if (tmp_win->flags & ICONIFIED) return; ResizeWindow = tmp_win->frame; if ((val1 != 0) && (val2 != 0)) { dragWidth = val1 * val1_unit / 100; dragHeight = val2 * val2_unit / 100; WIN_ConstrainWindow(scr, tmp_win, &dragWidth, &dragHeight); DEC_ConfigureDecorations(scr, tmp_win, tmp_win->frame_x, tmp_win->frame_y, dragWidth, dragHeight, False); ResizeWindow = None; PAGER_Clear(scr); return; } COLOR_PushRootColorMap(scr); if (menuFromFrameOrWindowOrTitlebar) { /* warp the pointer to the cursor position from before menu appeared */ XWarpPointer(dpy, None, scr->root_win, 0, 0, 0, 0, Stashed_X, Stashed_Y); XFlush(dpy); } if (!MISC_Grab(scr, MOVE_CURS)) { XBell(dpy, scr->screen); return; } if ((!(scr->flags & OpaqueResize)) || ((scr->flags & OpaqueResize) && (!(tmp_win->flags & MAPPED)))) XGrabServer(dpy); pagerOn = False; XGetGeometry(dpy, (Drawable)ResizeWindow, &JunkRoot, &dragx, &dragy, (unsigned int *)&dragWidth, (unsigned int *)&dragHeight, &JunkBW, &JunkDepth); dragx += tmp_win->bw; dragy += tmp_win->bw; origx = dragx; origy = dragy; origWidth = dragWidth; origHeight = dragHeight; ymotion = xmotion = 0; /* pop up a resize dimensions window */ if (Mwm.show_feedback & MWM_FEEDBACK_RESIZE) XMapRaised(dpy, scr->size_win); last_width = 0; last_height = 0; if (Mwm.show_feedback & MWM_FEEDBACK_RESIZE) display_size(scr, tmp_win, origWidth, origHeight, True); /* Get the current position to determine which border to resize */ if ((scr->pressed_win != scr->root_win) && (scr->pressed_win != None)) { if (scr->pressed_win == tmp_win->sides[0]) /* top */ ymotion = 1; if (scr->pressed_win == tmp_win->sides[1]) /* right */ xmotion = -1; if (scr->pressed_win == tmp_win->sides[2]) /* bottom */ ymotion = -1; if (scr->pressed_win == tmp_win->sides[3]) /* left */ xmotion = 1; if (scr->pressed_win == tmp_win->corners[0]) { /* upper-left */ ymotion = 1; xmotion = 1; } if (scr->pressed_win == tmp_win->corners[1]) { /* upper-right */ xmotion = -1; ymotion = 1; } if (scr->pressed_win == tmp_win->corners[2]) { /* lower right */ ymotion = -1; xmotion = 1; } if (scr->pressed_win == tmp_win->corners[3]) { /* lower left */ ymotion = -1; xmotion = -1; } } /* draw the rubber-band window */ if ((!(scr->flags & OpaqueResize)) || ((scr->flags & OpaqueResize) && (!(tmp_win->flags & MAPPED)))) WIN_DrawOutline(scr, scr->root_win, dragx - tmp_win->bw, dragy - tmp_win->bw, dragWidth + 2 * tmp_win->bw, dragHeight + 2 * tmp_win->bw); /* loop to resize */ while (!finished) { XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | KeyPressMask | ButtonMotionMask | PointerMotionMask | ExposureMask, &oevent); MISC_StashEventTime(&oevent); if (oevent.type == MotionNotify) /* discard any extra motion events before a release */ while (XCheckMaskEvent(dpy, ButtonMotionMask | ButtonReleaseMask | PointerMotionMask, &oevent)) { MISC_StashEventTime(&oevent); if (oevent.type == ButtonRelease) break; } done = False; /* Handle a limited number of key press events to allow mouseless * operation */ if (oevent.type == KeyPress) MISC_KeyboardShortcut(scr, &oevent, ButtonRelease); switch (oevent.type) { case ButtonPress: XAllowEvents(dpy, ReplayPointer, CurrentTime); case KeyPress: done = True; break; case ButtonRelease: finished = True; done = True; break; case MotionNotify: x = oevent.xmotion.x_root; y = oevent.xmotion.y_root; /* need to move the viewport */ PAN_PanDesktop(scr, scr->edge_scroll_x, scr->edge_scroll_y, &x, &y, &delta_x, &delta_y, False, &oevent); origx -= delta_x; origy -= delta_y; dragx -= delta_x; dragy -= delta_y; resize_window(scr, x, y, tmp_win); done = True; default: break; } if (!done) { if ((!(scr->flags & OpaqueResize)) || ((scr->flags & OpaqueResize) && (!(tmp_win->flags & MAPPED)))) WIN_DrawOutline(scr, scr->root_win, 0, 0, 0, 0); EVENT_Dispatch(&oevent); if ((!(scr->flags & OpaqueResize)) || ((scr->flags & OpaqueResize) && (!(tmp_win->flags & MAPPED)))) WIN_DrawOutline(scr, scr->root_win, dragx - tmp_win->bw, dragy - tmp_win->bw, dragWidth + 2 * tmp_win->bw, dragHeight + 2 * tmp_win->bw); } } /* erase the rubber-band */ if ((!(scr->flags & OpaqueResize)) || ((scr->flags & OpaqueResize) && (!(tmp_win->flags & MAPPED)))) WIN_DrawOutline(scr, scr->root_win, 0, 0, 0, 0); /* pop down the size window */ if (Mwm.show_feedback & MWM_FEEDBACK_RESIZE) XUnmapWindow(dpy, scr->size_win); pagerOn = True; WIN_ConstrainWindow(scr, tmp_win, &dragWidth, &dragHeight); DEC_ConfigureDecorations(scr, tmp_win, dragx - tmp_win->bw, dragy - tmp_win->bw, dragWidth, dragHeight, False); COLOR_PopRootColorMap(scr); ResizeWindow = None; XUngrabServer(dpy); MISC_Ungrab(scr); PAGER_Clear(scr); }
void KSMServer::performLegacySessionSave() { kdDebug( 1218 ) << "Saving legacy session apps" << endl; // Setup error handler legacyWindows.clear(); windowMapPtr = &legacyWindows; XErrorHandler oldHandler = XSetErrorHandler(winsErrorHandler); // Compute set of leader windows that need legacy session management // and determine which style (WM_COMMAND or WM_SAVE_YOURSELF) KWinModule module; if( wm_save_yourself == (Atom)None ) { Atom atoms[ 3 ]; const char* const names[] = { "WM_SAVE_YOURSELF", "WM_PROTOCOLS", "WM_CLIENT_LEADER" }; XInternAtoms( tqt_xdisplay(), const_cast< char** >( names ), 3, False, atoms ); wm_save_yourself = atoms[ 0 ]; wm_protocols = atoms[ 1 ]; wm_client_leader = atoms[ 2 ]; } for ( TQValueList<WId>::ConstIterator it = module.windows().begin(); it != module.windows().end(); ++it) { WId leader = windowWmClientLeader( *it ); if (!legacyWindows.contains(leader) && windowSessionId( *it, leader ).isEmpty()) { SMType wtype = SM_WMCOMMAND; int nprotocols = 0; Atom *protocols = 0; if( XGetWMProtocols(tqt_xdisplay(), leader, &protocols, &nprotocols)) { for (int i=0; i<nprotocols; i++) if (protocols[i] == wm_save_yourself) { wtype = SM_WMSAVEYOURSELF; break; } XFree((void*) protocols); } SMData data; data.type = wtype; XClassHint classHint; if( XGetClassHint( tqt_xdisplay(), leader, &classHint ) ) { data.wmclass1 = classHint.res_name; data.wmclass2 = classHint.res_class; XFree( classHint.res_name ); XFree( classHint.res_class ); } legacyWindows.insert(leader, data); } } // Open fresh display for sending WM_SAVE_YOURSELF XSync(tqt_xdisplay(), False); Display *newdisplay = XOpenDisplay(DisplayString(tqt_xdisplay())); if (!newdisplay) { windowMapPtr = NULL; XSetErrorHandler(oldHandler); return; } WId root = DefaultRootWindow(newdisplay); XGrabKeyboard(newdisplay, root, False, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(newdisplay, root, False, Button1Mask|Button2Mask|Button3Mask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); // Send WM_SAVE_YOURSELF messages XEvent ev; int awaiting_replies = 0; for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) { if ( (*it).type == SM_WMSAVEYOURSELF ) { WId w = it.key(); awaiting_replies += 1; memset(&ev, 0, sizeof(ev)); ev.xclient.type = ClientMessage; ev.xclient.window = w; ev.xclient.message_type = wm_protocols; ev.xclient.format = 32; ev.xclient.data.l[0] = wm_save_yourself; ev.xclient.data.l[1] = GET_QT_X_TIME(); XSelectInput(newdisplay, w, PropertyChangeMask|StructureNotifyMask); XSendEvent(newdisplay, w, False, 0, &ev); } } // Wait for change in WM_COMMAND with timeout XFlush(newdisplay); TQTime start = TQTime::currentTime(); while (awaiting_replies > 0) { if (XPending(newdisplay)) { /* Process pending event */ XNextEvent(newdisplay, &ev); if ( ( ev.xany.type == UnmapNotify ) || ( ev.xany.type == PropertyNotify && ev.xproperty.atom == XA_WM_COMMAND ) ) { WindowMap::Iterator it = legacyWindows.find( ev.xany.window ); if ( it != legacyWindows.end() && (*it).type != SM_WMCOMMAND ) { awaiting_replies -= 1; if ( (*it).type != SM_ERROR ) (*it).type = SM_WMCOMMAND; } } } else { /* Check timeout */ int msecs = start.elapsed(); if (msecs >= WM_SAVE_YOURSELF_TIMEOUT) break; /* Wait for more events */ fd_set fds; FD_ZERO(&fds); int fd = ConnectionNumber(newdisplay); FD_SET(fd, &fds); struct timeval tmwait; tmwait.tv_sec = (WM_SAVE_YOURSELF_TIMEOUT - msecs) / 1000; tmwait.tv_usec = ((WM_SAVE_YOURSELF_TIMEOUT - msecs) % 1000) * 1000; ::select(fd+1, &fds, NULL, &fds, &tmwait); } } // Terminate work in new display XAllowEvents(newdisplay, ReplayPointer, CurrentTime); XAllowEvents(newdisplay, ReplayKeyboard, CurrentTime); XSync(newdisplay, False); XCloseDisplay(newdisplay); // Restore old error handler XSync(tqt_xdisplay(), False); XSetErrorHandler(oldHandler); for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) { if ( (*it).type != SM_ERROR) { WId w = it.key(); (*it).wmCommand = windowWmCommand(w); (*it).wmClientMachine = windowWmClientMachine(w); } } kdDebug( 1218 ) << "Done saving " << legacyWindows.count() << " legacy session apps" << endl; }
bool Adx::onHotKey(KeySym sym, uint mod) { bool hot = false; qDebug() << "HOTKEY ACTIVATED"; switch (sym) { case XK_F4:{ qDebug() << "F4"; if (mod != ALT_MOD) break; hot = true; if ((client = toppanel->currentApp->getCurrent()) != NULL) { client->destroyClient(); } }break; case XK_F9:{ qDebug() << "F9"; if (mod != ALT_MOD) break; hot = true; if ((client = toppanel->currentApp->getCurrent()) != NULL) { if (client->clientState == NormalState) { qDebug() << "HIDING WINDOW"; client->iconify(); toppanel->windowIsIconified(client); XSetInputFocus(display(), rootWindow(), None, CurrentTime); } else if (client->clientState == IconicState) { qDebug() << "SHOW WINDOW"; client->removeFromDock(); toppanel->iconIsRemoved(client); client->setChildFocus(0, CurrentTime); restack(client); } } }break; case XK_Tab:{ qDebug() << "TAB"; if (mod != ALT_MOD) break; if (m_Process != process_SwitchingWindows) { QTimer::singleShot(220, this, SLOT(onAltTab())); } hot = true; }break; case XK_Shift_L:{ qDebug() << "ALT+SHIFT"; if (mod != ALT_MOD) break; toppanel->kbswitch->nextLayout(); }break; case XK_Escape:{ qDebug() << "CTRL+ALT+ESC"; if (mod != CTRLALT_MOD) break; QProcess::startDetached("xkill"); }break; } XAllowEvents(display(), SyncBoth, CurrentTime); return hot; }
static void HandleEvent(XEvent * ev) { Win win; #if ENABLE_DEBUG_EVENTS if (EDebug(ev->type)) EventShow(ev); #endif win = ELookupXwin(ev->xany.window); switch (ev->type) { case KeyPress: Mode.events.last_keycode = ev->xkey.keycode; Mode.events.last_keystate = ev->xkey.state; /* FALLTHROUGH */ case KeyRelease: Mode.events.time = ev->xkey.time; ModeGetXY(ev->xkey.x_root, ev->xkey.y_root); #if 0 /* FIXME - Why? */ if (ev->xkey.root != WinGetXwin(VROOT)) { XSetInputFocus(disp, ev->xkey.root, RevertToPointerRoot, CurrentTime); ESync(); ev->xkey.time = CurrentTime; EXSendEvent(ev->xkey.root, 0, ev); return; } #endif Mode.events.on_screen = ev->xkey.same_screen; goto do_stuff; case ButtonPress: case ButtonRelease: Mode.events.time = ev->xbutton.time; ModeGetXY(ev->xbutton.x_root, ev->xbutton.y_root); Mode.events.on_screen = ev->xbutton.same_screen; TooltipsHide(); goto do_stuff; case MotionNotify: Mode.events.time = ev->xmotion.time; Mode.events.px = Mode.events.mx; Mode.events.py = Mode.events.my; ModeGetXY(ev->xmotion.x_root, ev->xmotion.y_root); Mode.events.mx = Mode.events.cx; Mode.events.my = Mode.events.cy; Mode.events.on_screen = ev->xmotion.same_screen; break; case EnterNotify: Mode.context_win = win; Mode.events.time = ev->xcrossing.time; Mode.events.on_screen = ev->xcrossing.same_screen; if (ev->xcrossing.mode == NotifyGrab && ev->xcrossing.detail == NotifyInferior) { Mode.grabs.pointer_grab_window = ev->xany.window; if (!Mode.grabs.pointer_grab_active) Mode.grabs.pointer_grab_active = 2; } ModeGetXY(ev->xcrossing.x_root, ev->xcrossing.y_root); TooltipsHide(); goto do_stuff; case LeaveNotify: Mode.events.time = ev->xcrossing.time; Mode.events.on_screen = ev->xcrossing.same_screen; if (ev->xcrossing.mode == NotifyGrab && ev->xcrossing.detail == NotifyInferior) { Mode.grabs.pointer_grab_window = None; Mode.grabs.pointer_grab_active = 0; } ModeGetXY(ev->xcrossing.x_root, ev->xcrossing.y_root); TooltipsHide(); goto do_stuff; case PropertyNotify: Mode.events.time = ev->xproperty.time; break; do_stuff: if (ev->xany.window == WinGetXwin(VROOT)) ActionclassesGlobalEvent(ev); break; } switch (ev->type) { case KeyPress: /* 2 */ case KeyRelease: /* 3 */ /* Unfreeze keyboard in case we got here by keygrab */ XAllowEvents(disp, AsyncKeyboard, CurrentTime); break; case ButtonPress: /* 4 */ SoundPlay(SOUND_BUTTON_CLICK); Mode.events.double_click = ((ev->xbutton.time - Mode.events.last_btime < DOUBLE_CLICK_TIME) && ev->xbutton.button == Mode.events.last_button && ev->xbutton.window == Mode.events.last_bpress2); Mode.events.last_bpress = ev->xbutton.window; Mode.events.last_bpress2 = ev->xbutton.window; Mode.events.last_btime = ev->xbutton.time; Mode.events.last_button = ev->xbutton.button; break; case ButtonRelease: /* 5 */ SoundPlay(SOUND_BUTTON_RAISE); break; } /* The new event dispatcher */ EventCallbacksProcess(win, ev); /* Post-event stuff TBD */ switch (ev->type) { case ButtonRelease: /* 5 */ Mode.events.last_bpress = 0; break; #if 1 /* Do this here? */ case DestroyNotify: EUnregisterXwin(ev->xdestroywindow.window); break; #endif case MappingNotify: XRefreshKeyboardMapping(&ev->xmapping); if (Conf.testing.bindings_reload) ActionclassesReload(); break; } }
void emX11WindowPort::HandleEvent(XEvent & event) { emInputEvent inputEvent; emX11WindowPort * wp; char tmp[256]; char keymap[32]; KeySym ks; emInputKey key; Status status; int i,x,y,w,h,mask,repeat,variant,len; double mx,my; bool inside; // Remember: // - Calling InputToView may delete this window port. // - The grab stuff is very very tricky. switch (event.type) { case MotionNotify: mx=PaneX+event.xmotion.x+Screen.MouseWarpX; my=PaneY+event.xmotion.y+Screen.MouseWarpY; if ( Screen.InputState.GetMouseX()!=mx || Screen.InputState.GetMouseY()!=my ) { Screen.InputState.SetMouse(mx,my); Screen.InputStateClock++; } for (i=0; i<3; i++) { if (i==0) { key=EM_KEY_LEFT_BUTTON ; mask=Button1Mask; } else if (i==1) { key=EM_KEY_MIDDLE_BUTTON; mask=Button2Mask; } else { key=EM_KEY_RIGHT_BUTTON ; mask=Button3Mask; } if (Screen.InputState.Get(key) && (event.xmotion.state&mask)==0) { Screen.InputState.Set(key,false); Screen.InputStateClock++; } } return; case ButtonPress: mx=PaneX+event.xbutton.x+Screen.MouseWarpX; my=PaneY+event.xbutton.y+Screen.MouseWarpY; if ( Screen.InputState.GetMouseX()!=mx || Screen.InputState.GetMouseY()!=my ) { Screen.InputState.SetMouse(mx,my); Screen.InputStateClock++; } wp=SearchOwnedPopupAt(mx,my); if (wp) { if (wp->Mapped) { event.xbutton.x+=PaneX-wp->PaneX; event.xbutton.y+=PaneY-wp->PaneY; wp->HandleEvent(event); } return; } if (ModalDescendants>0) { FocusModalDescendant(true); return; } inside=( mx>=PaneX && mx<PaneX+PaneW && my>=PaneY && my<PaneY+PaneH ); if ( !inside && Screen.GrabbingWinPort==this && (GetWindowFlags()&emWindow::WF_POPUP)!=0 ) { XMutex.Lock(); XAllowEvents(Disp,ReplayPointer,CurrentTime); XMutex.Unlock(); Screen.GrabbingWinPort=NULL; LastButtonPress=EM_KEY_NONE; SignalWindowClosing(); } for (i=Screen.WinPorts.GetCount()-1; i>=0; i--) { wp=Screen.WinPorts[i]; if ( (wp->GetWindowFlags()&emWindow::WF_POPUP)!=0 && wp!=this && !wp->IsAncestorOf(this) ) { wp->SignalWindowClosing(); } } if (!inside) return; if (!Focused && event.xbutton.button>=1 && event.xbutton.button<=5) { RequestFocus(); Screen.UpdateKeymapAndInputState(); } if (event.xbutton.button>=1 && event.xbutton.button<=3) { if (event.xbutton.button==1) key=EM_KEY_LEFT_BUTTON; else if (event.xbutton.button==2) key=EM_KEY_MIDDLE_BUTTON; else key=EM_KEY_RIGHT_BUTTON; if (!Screen.InputState.Get(key)) { Screen.InputState.Set(key,true); Screen.InputStateClock++; if ( key==LastButtonPress && event.xbutton.time>LastButtonPressTime && event.xbutton.time-LastButtonPressTime<=330 && event.xbutton.x>=LastButtonPressX-10 && event.xbutton.x<=LastButtonPressX+10 && event.xbutton.y>=LastButtonPressY-10 && event.xbutton.y<=LastButtonPressY+10 ) { repeat=LastButtonPressRepeat+1; } else { repeat=0; } LastButtonPress=key; LastButtonPressTime=event.xbutton.time; LastButtonPressX=event.xbutton.x; LastButtonPressY=event.xbutton.y; LastButtonPressRepeat=repeat; inputEvent.Setup(key,"",repeat,0); InputStateClock=Screen.InputStateClock; InputToView(inputEvent,Screen.InputState); return; } } else if (event.xbutton.button==4) { inputEvent.Setup(EM_KEY_WHEEL_UP,"",0,0); InputStateClock=Screen.InputStateClock; InputToView(inputEvent,Screen.InputState); return; } else if (event.xbutton.button==5) { inputEvent.Setup(EM_KEY_WHEEL_DOWN,"",0,0); InputStateClock=Screen.InputStateClock; InputToView(inputEvent,Screen.InputState); return; } return; case ButtonRelease: mx=PaneX+event.xbutton.x+Screen.MouseWarpX; my=PaneY+event.xbutton.y+Screen.MouseWarpY; if ( Screen.InputState.GetMouseX()!=mx || Screen.InputState.GetMouseY()!=my ) { Screen.InputState.SetMouse(mx,my); Screen.InputStateClock++; } if (event.xbutton.button>=1 && event.xbutton.button<=3) { if (event.xbutton.button==1) key=EM_KEY_LEFT_BUTTON; else if (event.xbutton.button==2) key=EM_KEY_MIDDLE_BUTTON; else key=EM_KEY_RIGHT_BUTTON; if (Screen.InputState.Get(key)) { Screen.InputState.Set(key,false); Screen.InputStateClock++; inputEvent.Eat(); InputStateClock=Screen.InputStateClock; InputToView(inputEvent,Screen.InputState); return; } } return; case KeyPress: i=event.xkey.keycode/8; mask=1<<(event.xkey.keycode&7); if (i<32 && (Screen.Keymap[i]&mask)==0) { Screen.Keymap[i]|=mask; Screen.UpdateInputStateFromKeymap(); } if (InputContext) { XMutex.Lock(); len=XmbLookupString( InputContext, &event.xkey, tmp, sizeof(tmp)-1, &ks, &status ); XMutex.Unlock(); if (status!=XLookupChars && status!=XLookupBoth) len=0; if (status!=XLookupKeySym && status!=XLookupBoth) ks=0; } else { XMutex.Lock(); len=XLookupString( &event.xkey, tmp, sizeof(tmp)-1, &ks, &ComposeStatus ); XMutex.Unlock(); } tmp[len]=0; key=emX11Screen::ConvertKey(ks,&variant); if (key==EM_KEY_NONE && !tmp[0]) return; repeat=0; if ( key!=EM_KEY_NONE && Screen.InputState.Get(key) && RepeatKey==key ) { repeat=KeyRepeat+1; } if (ModalDescendants>0) return; RepeatKey=key; KeyRepeat=repeat; inputEvent.Setup(key,tmp,repeat,variant); InputStateClock=Screen.InputStateClock; InputToView(inputEvent,Screen.InputState); return; case KeyRelease: memset(keymap,0,sizeof(keymap)); XMutex.Lock(); XQueryKeymap(Disp,keymap); XMutex.Unlock(); i=event.xkey.keycode/8; mask=1<<(event.xkey.keycode&7); if (i<32 && (keymap[i]&mask)==0) { RepeatKey=EM_KEY_NONE; if ((Screen.Keymap[i]&mask)!=0) { Screen.Keymap[i]&=~mask; Screen.UpdateInputStateFromKeymap(); } } return; case Expose: x=event.xexpose.x; y=event.xexpose.y; w=event.xexpose.width; h=event.xexpose.height; InvalidatePainting(PaneX+x,PaneY+y,w,h); return; case FocusIn: if ( event.xfocus.mode==NotifyNormal || event.xfocus.mode==NotifyWhileGrabbed ) { if (InputContext) { XMutex.Lock(); XSetICFocus(InputContext); XMutex.Unlock(); } Screen.UpdateKeymapAndInputState(); RepeatKey=EM_KEY_NONE; if (!Focused) { Focused=true; SetViewFocused(true); } if (ModalDescendants>0) FocusModalDescendant(); } return; case FocusOut: if ( event.xfocus.mode==NotifyNormal || event.xfocus.mode==NotifyWhileGrabbed ) { if (InputContext) { XMutex.Lock(); XUnsetICFocus(InputContext); XMutex.Unlock(); } if (Focused) { Focused=false; SetViewFocused(false); } LastButtonPress=EM_KEY_NONE; RepeatKey=EM_KEY_NONE; } return; case ConfigureNotify: // The meaning of the coordinates from event.xconfigure depends on // the window manager. Therefore: GetAbsWinGeometry(Disp,Win,&x,&y,&w,&h); if (PaneX!=x || PaneY!=y || PaneW!=w || PaneH!=h) { PaneX=x; PaneY=y; PaneW=w; PaneH=h; ClipX1=PaneX; ClipY1=PaneY; ClipX2=PaneX+PaneW; ClipY2=PaneY+PaneH; InvalidRects.Set(PaneX,PaneY,PaneX+PaneW,PaneY+PaneH); WakeUp(); if (!PosPending && !SizePending) { SetViewGeometry( PaneX,PaneY, PaneW,PaneH, Screen.PixelTallness ); } else if (!PosPending) { SetViewGeometry( PaneX,PaneY, GetViewWidth(),GetViewHeight(), Screen.PixelTallness ); } else if (!SizePending) { SetViewGeometry( GetViewX(),GetViewY(), PaneW,PaneH, Screen.PixelTallness ); } Screen.InputStateClock++; } return; case MapNotify: if (event.xmap.window==Win && !Mapped) { Mapped=true; WakeUp(); } return; case UnmapNotify: if (event.xmap.window==Win && Mapped) { Mapped=false; } return; case ClientMessage: if (event.xclient.data.l[0]==(long)Screen.WM_DELETE_WINDOW) { if (ModalDescendants<=0) SignalWindowClosing(); else FocusModalDescendant(true); } return; } }
static GdkNativeWindow select_window (GdkScreen *screen) { #define MASK (ButtonPressMask | ButtonReleaseMask) Display *x_dpy; Cursor x_cursor; XEvent x_event; Window x_win; Window x_root; gint x_scr; gint status; gint buttons; x_dpy = GDK_SCREEN_XDISPLAY (screen); x_scr = GDK_SCREEN_XNUMBER (screen); x_win = None; x_root = RootWindow (x_dpy, x_scr); x_cursor = XCreateFontCursor (x_dpy, GDK_CROSSHAIR); buttons = 0; status = XGrabPointer (x_dpy, x_root, False, MASK, GrabModeSync, GrabModeAsync, x_root, x_cursor, CurrentTime); if (status != GrabSuccess) { g_message (_("Error grabbing the pointer %d"), status); return 0; } while ((x_win == None) || (buttons != 0)) { XAllowEvents (x_dpy, SyncPointer, CurrentTime); XWindowEvent (x_dpy, x_root, MASK, &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; } buttons++; break; case ButtonRelease: if (buttons > 0) buttons--; break; default: g_assert_not_reached (); } } XUngrabPointer (x_dpy, CurrentTime); XFreeCursor (x_dpy, x_cursor); return x_win; }
/*======================================================== DndHandleDragging * Takes care of the drag and drop process. Wait until the pointer had moved * a little. Then takes control over the pointer until the buttons are * released. After that send a Drag And Drop ClientMessage event. Returns * non-zero if a drop did take place. *===========================================================================*/ int MwDndHandleDragging(Widget widget,XEvent *event) { XEvent Event; Window root = RootWindowOfScreen(XtScreenOfObject(widget)); XtAppContext app= XtWidgetToApplicationContext(widget); Window DispatchWindow; int DropX,DropY; if(Dragging) return 0; if(abs(StartEvent.x_root - event->xmotion.x_root) < DragPrecision && abs(StartEvent.y_root - event->xmotion.y_root) < DragPrecision) return 0; XUngrabPointer(dpy,CurrentTime); /* Take control over the pointer */ XGrabPointer(dpy,root,False, ButtonMotionMask|ButtonPressMask|ButtonReleaseMask, GrabModeSync,GrabModeAsync,root, DndCursor[DataType].CursorID, CurrentTime); /* Wait for button release */ Dragging=1; RootFlag=0; while(Dragging) { XAllowEvents(dpy,SyncPointer,CurrentTime); XtAppNextEvent(app,&Event); switch(Event.type) { case ButtonRelease: if(Event.xbutton.subwindow) RootFlag=0; else RootFlag=1; Dragging=0; break; default: XtDispatchEvent(&Event); break; } } DataOK=0; /* Now release the pointer */ XUngrabPointer(dpy,CurrentTime); /* Try to guess if the drop occurred in the root window */ if(!RootFlag) { Target=XmuClientWindow(dpy,Event.xbutton.subwindow); if(Target==Event.xbutton.subwindow) DispatchWindow=Target; else DispatchWindow=PointerWindow; } else Target=DispatchWindow=XtWindow(MwDndGetMainWidget(widget)); /* Now build the event structure */ DropX=Event.xbutton.x_root; DropY=Event.xbutton.y_root; Event.xclient.type = ClientMessage; Event.xclient.display = dpy; Event.xclient.message_type = MwDndProtocol; Event.xclient.format = 32; Event.xclient.window = Target; Event.xclient.data.l[0] = DataType; Event.xclient.data.l[1] = (long)event->xbutton.state; Event.xclient.data.l[2] = (long)XtWindow(widget); Event.xclient.data.l[3] = DropX + 65536L*(long)DropY; Event.xclient.data.l[4] = 1; /* Send the drop message */ XSendEvent(dpy,DispatchWindow,True,NoEventMask,&Event); /* Send an old style version of the message just in case */ Event.xclient.message_type = OldDndProtocol; XSendEvent(dpy,DispatchWindow,True,NoEventMask,&Event); #ifdef DEBUG fprintf(stderr,"ClientMessage sent to 0x%x(0x%x).\n", DispatchWindow,Target); fprintf(stderr,"The drop coordinates are (%d,%d).\n",DropX,DropY); #endif return 1; }
static void spi_device_event_controller_forward_mouse_event (SpiDEController *controller, XEvent *xevent) { Accessibility_DeviceEvent mouse_e; gchar event_detail[3]; gboolean is_consumed = FALSE; gboolean xkb_mod_unlatch_occurred; XButtonEvent *xbutton_event = (XButtonEvent *) xevent; dbus_uint32_t ix, iy; int button = xbutton_event->button; unsigned int mouse_button_state = xbutton_event->state; switch (button) { case 1: mouse_button_state |= Button1Mask; break; case 2: mouse_button_state |= Button2Mask; break; case 3: mouse_button_state |= Button3Mask; break; case 4: mouse_button_state |= Button4Mask; break; case 5: mouse_button_state |= Button5Mask; break; } last_mouse_pos->x = ((XButtonEvent *) xevent)->x_root; last_mouse_pos->y = ((XButtonEvent *) xevent)->y_root; #ifdef SPI_DEBUG fprintf (stderr, "mouse button %d %s (%x)\n", xbutton_event->button, (xevent->type == ButtonPress) ? "Press" : "Release", mouse_button_state); #endif snprintf (event_detail, 3, "%d%c", button, (xevent->type == ButtonPress) ? 'p' : 'r'); /* TODO: FIXME distinguish between physical and logical buttons */ mouse_e.type = (xevent->type == ButtonPress) ? Accessibility_BUTTON_PRESSED_EVENT : Accessibility_BUTTON_RELEASED_EVENT; mouse_e.id = button; mouse_e.hw_code = button; mouse_e.modifiers = (dbus_uint16_t) xbutton_event->state; mouse_e.timestamp = (dbus_uint32_t) xbutton_event->time; mouse_e.event_string = ""; mouse_e.is_text = FALSE; if ((mouse_button_state & mouse_button_mask) != (mouse_mask_state & mouse_button_mask)) { if ((mouse_mask_state & key_modifier_mask) != (mouse_button_state & key_modifier_mask)) spi_dec_x11_emit_modifier_event (controller, mouse_mask_state, mouse_button_state); mouse_mask_state = mouse_button_state; is_consumed = spi_controller_notify_mouselisteners (controller, &mouse_e); ix = last_mouse_pos->x; iy = last_mouse_pos->y; spi_dec_dbus_emit(controller, SPI_DBUS_INTERFACE_EVENT_MOUSE, "Button", event_detail, ix, iy); } xkb_mod_unlatch_occurred = (xevent->type == ButtonPress || xevent->type == ButtonRelease); /* if client wants to consume this event, and XKB latch state was * unset by this button event, we reset it */ if (is_consumed && xkb_mod_unlatch_occurred) spi_dec_set_unlatch_pending (controller, mouse_mask_state); XAllowEvents (spi_get_display (), (is_consumed) ? SyncPointer : ReplayPointer, CurrentTime); }
static void global_filter_fn (XEvent *xevent, void *data) { SpiDEController *controller; DEControllerPrivateData *priv; Display *display = spi_get_display (); controller = SPI_DEVICE_EVENT_CONTROLLER (data); priv = controller->priv; if (xevent->type == MappingNotify) xmkeymap = NULL; if (xevent->type == KeyPress || xevent->type == KeyRelease) { if (priv->xevie_display == NULL) { gboolean is_consumed; is_consumed = spi_device_event_controller_forward_key_event (controller, xevent); if (is_consumed) { int n_events; int i; XEvent next_event; n_events = XPending (display); #ifdef SPI_KEYEVENT_DEBUG g_print ("Number of events pending: %d\n", n_events); #endif for (i = 0; i < n_events; i++) { XNextEvent (display, &next_event); if (next_event.type != KeyPress && next_event.type != KeyRelease) g_warning ("Unexpected event type %d in queue", next_event.type); } XAllowEvents (display, AsyncKeyboard, CurrentTime); if (n_events) XUngrabKeyboard (display, CurrentTime); } else { if (xevent->type == KeyPress) wait_for_release_event (xevent, controller); XAllowEvents (display, ReplayKeyboard, CurrentTime); } } return; } if (xevent->type == ButtonPress || xevent->type == ButtonRelease) { spi_device_event_controller_forward_mouse_event (controller, xevent); } if (xevent->type == priv->xkb_base_event_code) { XkbAnyEvent * xkb_ev = (XkbAnyEvent *) xevent; /* ugly but probably necessary...*/ XSynchronize (display, TRUE); if (xkb_ev->xkb_type == XkbStateNotify) { XkbStateNotifyEvent *xkb_snev = (XkbStateNotifyEvent *) xkb_ev; /* check the mouse, to catch mouse events grabbed by * another client; in case we should revert this XKB delatch */ if (!priv->pending_xkb_mod_relatch_mask) { int x, y; gboolean moved; spi_dec_x11_mouse_check (controller, &x, &y, &moved); } /* we check again, since the previous call may have changed this flag */ if (priv->pending_xkb_mod_relatch_mask) { unsigned int feedback_mask; #ifdef SPI_XKB_DEBUG fprintf (stderr, "relatching %x\n", priv->pending_xkb_mod_relatch_mask); #endif /* temporarily turn off the latch bell, if it's on */ XkbGetControls (display, XkbAccessXFeedbackMask, priv->xkb_desc); feedback_mask = priv->xkb_desc->ctrls->ax_options; if (feedback_mask & XkbAX_StickyKeysFBMask) { XkbControlsChangesRec changes = {XkbAccessXFeedbackMask, 0, False}; priv->xkb_desc->ctrls->ax_options &= ~(XkbAX_StickyKeysFBMask); XkbChangeControls (display, priv->xkb_desc, &changes); } /* TODO: account for lock as well as latch */ XkbLatchModifiers (display, XkbUseCoreKbd, priv->pending_xkb_mod_relatch_mask, priv->pending_xkb_mod_relatch_mask); if (feedback_mask & XkbAX_StickyKeysFBMask) { XkbControlsChangesRec changes = {XkbAccessXFeedbackMask, 0, False}; priv->xkb_desc->ctrls->ax_options = feedback_mask; XkbChangeControls (display, priv->xkb_desc, &changes); } #ifdef SPI_XKB_DEBUG fprintf (stderr, "relatched %x\n", priv->pending_xkb_mod_relatch_mask); #endif priv->pending_xkb_mod_relatch_mask = 0; } else { priv->xkb_latch_mask = xkb_snev->latched_mods; } } XSynchronize (display, FALSE); } return; }
void button(XButtonEvent *e) { int n, shift; Client *c; Window dw; ScreenInfo *s; curtime = e->time; s = getscreen(e->root); if(s == 0) return; c = getclient(e->window, 0); if(c) { if(debug) fprintf(stderr, "but: e x=%d y=%d c x=%d y=%d dx=%d dy=%d BORDR %d\n", e->x, e->y, c->x, c->y, c->dx, c->dy, BORDER); if(borderorient(c, e->x, e->y) != BorderUnknown) { switch (e->button) { case Button1: case Button2: reshape(c, e->button, pull, e); return; case Button3: move(c, Button3); return; default: return; } } e->x += c->x - BORDER; e->y += c->y - BORDER; } else if(e->window != e->root) { if(debug) fprintf(stderr, "but no client: e x=%d y=%d\n", e->x, e->y); XTranslateCoordinates(dpy, e->window, s->root, e->x, e->y, &e->x, &e->y, &dw); } switch (e->button) { case Button1: if(c) { XMapRaised(dpy, c->parent); top(c); active(c); } return; case Button2: if(c) { XMapRaised(dpy, c->parent); active(c); XAllowEvents (dpy, ReplayPointer, curtime); } else if((e->state&(ShiftMask|ControlMask))==(ShiftMask|ControlMask)) { menuhit(e, &egg); } else if(numvirtuals > 1 && (n = menuhit(e, &b2menu)) > -1) button2(n); return; case Button3: break; case Button4: /* scroll up changes to previous virtual screen */ if(!c && e->type == ButtonPress) if(numvirtuals > 1 && virt > 0) switch_to(virt - 1); return; case Button5: /* scroll down changes to next virtual screen */ if(!c && e->type == ButtonPress) if(numvirtuals > 1 && virt < numvirtuals - 1) switch_to(virt + 1); return; default: return; } if(current && current->screen == s) cmapnofocus(s); switch (n = menuhit(e, &b3menu)) { case New: spawn(s, termFn); break; case Acme: spawn(s, editorFn); break; case Launcher: spawn(s, launcherFn); break; case Reshape: reshape(selectwin(1, 0, s), Button3, sweep, 0); break; case Move: move(selectwin(0, 0, s), Button3); break; case Delete: shift = 0; c = selectwin(1, &shift, s); delete(c, shift); break; case Hide: hide(selectwin(1, 0, s)); break; default: /* unhide window */ unhide(n - B3FIXED, 1); break; case -1: /* nothing */ break; } if(current && current->screen == s) cmapfocus(current); }
bool ManglerSettings::settingsPTTMouseDetect(void) {/*{{{*/ GdkWindow *rootwin = gdk_get_default_root_window(); Glib::ustring buttonname; char mousebutton[8]; static bool grabbed = false; int flag = 0; //int x, y; XEvent ev; // TODO: window close event needs to set isDetectingKey if (!isDetectingMouse) { return false; } if (! grabbed) { XUngrabPointer(GDK_WINDOW_XDISPLAY(rootwin), CurrentTime); XGrabPointer(GDK_WINDOW_XDISPLAY(rootwin), GDK_ROOT_WINDOW(), False, ButtonPress, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); grabbed = true; } while (flag == 0) { while (!XPending(GDK_WINDOW_XDISPLAY(rootwin))) { usleep(100000); } XNextEvent(GDK_WINDOW_XDISPLAY(rootwin), &ev); switch (ev.type) { case ButtonPress: snprintf(mousebutton, 7, "%d", ev.xbutton.button); buttonname = "Button" + Glib::ustring(mousebutton); flag = 1; XUngrabPointer(GDK_WINDOW_XDISPLAY(rootwin), CurrentTime); grabbed = false; isDetectingMouse = false; //x = ev.xbutton.x_root; //y = ev.xbutton.y_root; break; case MotionNotify: break; default: break; } XAllowEvents(GDK_WINDOW_XDISPLAY(rootwin), AsyncBoth, CurrentTime); } isDetectingMouse = false; builder->get_widget("settingsPTTMouseValueLabel", label); label->set_markup(buttonname); builder->get_widget("settingsCancelButton", button); button->set_sensitive(true); builder->get_widget("settingsApplyButton", button); button->set_sensitive(true); builder->get_widget("settingsOkButton", button); button->set_sensitive(true); builder->get_widget("settingsOkButton", button); button->set_sensitive(true); builder->get_widget("settingsPTTMouseButton", button); button->set_sensitive(true); builder->get_widget("settingsMouseDeviceComboBox", combobox); combobox->set_sensitive(true); return(true); }/*}}}*/
/* * Set window properties that are not settable in builder */ settingsWindow->set_keep_above(true); settingsWindow->signal_show().connect(sigc::mem_fun(this, &ManglerSettings::settingsWindow_show_cb)); settingsWindow->signal_hide().connect(sigc::mem_fun(this, &ManglerSettings::settingsWindow_hide_cb)); builder->get_widget("settingsCancelButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsCancelButton_clicked_cb)); builder->get_widget("settingsApplyButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsApplyButton_clicked_cb)); builder->get_widget("settingsOkButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsOkButton_clicked_cb)); builder->get_widget("settingsEnablePTTKeyCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnablePTTKeyCheckButton_toggled_cb)); builder->get_widget("settingsPTTKeyButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsPTTKeyButton_clicked_cb)); builder->get_widget("settingsEnablePTTMouseCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnablePTTMouseCheckButton_toggled_cb)); builder->get_widget("settingsPTTMouseButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsPTTMouseButton_clicked_cb)); builder->get_widget("settingsEnableAudioIntegrationCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnableAudioIntegrationCheckButton_toggled_cb)); builder->get_widget("settingsAudioIntegrationComboBox", audioPlayerComboBox); audioPlayerTreeModel = Gtk::ListStore::create(audioPlayerColumns); audioPlayerComboBox->set_model(audioPlayerTreeModel); // create a "none" row Gtk::TreeModel::Row audioPlayerNoneRow = *(audioPlayerTreeModel->append()); audioPlayerNoneRow[audioPlayerColumns.id] = MusicClient_None; audioPlayerNoneRow[audioPlayerColumns.name] = "None"; #ifdef HAVE_LIBMPDCLIENT // add MPD row Gtk::TreeModel::Row audioPlayerMPDRow = *(audioPlayerTreeModel->append()); audioPlayerMPDRow[audioPlayerColumns.id] = MusicClient_MPD; audioPlayerMPDRow[audioPlayerColumns.name] = "MPD"; #endif #ifdef HAVE_DBUS // add DBUS client rows // rhythmbox Gtk::TreeModel::Row audioPlayerRBRow = *(audioPlayerTreeModel->append()); audioPlayerRBRow[audioPlayerColumns.id] = MusicClient_Rhythmbox; audioPlayerRBRow[audioPlayerColumns.name] = "Rhythmbox"; // amarok Gtk::TreeModel::Row audioPlayerAmarokRow = *(audioPlayerTreeModel->append()); audioPlayerAmarokRow[audioPlayerColumns.id] = MusicClient_Amarok; audioPlayerAmarokRow[audioPlayerColumns.name] = "Amarok"; #endif audioPlayerComboBox->pack_start(audioPlayerColumns.name); audioPlayerComboBox->set_active(audioPlayerNoneRow); builder->get_widget("settingsEnableVoiceActivationCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnableVoiceActivationCheckButton_toggled_cb)); #ifdef HAVE_XOSD builder->get_widget("settingsOSD", vbox); vbox->set_sensitive(true); builder->get_widget("settingsEnableOnScreenDisplayCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnableOnScreenDisplayCheckButton_toggled_cb)); builder->get_widget("settingsOSDverticalPos", osdPosition); osdPositionModel = Gtk::ListStore::create(osdPositionColumns); osdPosition->set_model(osdPositionModel); osdPosition->pack_start(osdPositionColumns.name); Gtk::TreeModel::Row posrow; posrow = *osdPositionModel->append(); posrow[osdPositionColumns.id] = XOSD_top; posrow[osdPositionColumns.name] = "Top"; posrow = *osdPositionModel->append(); posrow[osdPositionColumns.id] = XOSD_middle; posrow[osdPositionColumns.name] = "Middle"; posrow = *osdPositionModel->append(); posrow[osdPositionColumns.id] = XOSD_bottom; posrow[osdPositionColumns.name] = "Bottom"; builder->get_widget("settingsOSDhorizontalPos", osdAlignment); osdAlignmentModel = Gtk::ListStore::create(osdAlignmentColumns); osdAlignment->set_model(osdAlignmentModel); osdAlignment->pack_start(osdAlignmentColumns.name); Gtk::TreeModel::Row alnrow; alnrow = *osdAlignmentModel->append(); alnrow[osdAlignmentColumns.id] = XOSD_center; alnrow[osdAlignmentColumns.name] = "Center"; alnrow = *osdAlignmentModel->append(); alnrow[osdAlignmentColumns.id] = XOSD_left; alnrow[osdAlignmentColumns.name] = "Left"; alnrow = *osdAlignmentModel->append(); alnrow[osdAlignmentColumns.id] = XOSD_right; alnrow[osdAlignmentColumns.name] = "Right"; builder->get_widget("settingsOSDfontsize", osdFontSize); builder->get_widget("settingsOSDcolor", osdColor); #endif builder->get_widget("audioSubsystemComboBox", audioSubsystemComboBox); audioSubsystemTreeModel = Gtk::ListStore::create(audioSubsystemColumns); audioSubsystemComboBox->set_model(audioSubsystemTreeModel); audioSubsystemComboBox->pack_start(audioSubsystemColumns.name); audioSubsystemComboBox->signal_changed().connect(sigc::mem_fun(this, &ManglerSettings::audioSubsystemComboBox_changed_cb)); builder->get_widget("inputDeviceComboBox", inputDeviceComboBox); inputDeviceTreeModel = Gtk::ListStore::create(inputColumns); inputDeviceComboBox->set_model(inputDeviceTreeModel); inputDeviceComboBox->pack_start(inputColumns.description); inputDeviceComboBox->signal_changed().connect(sigc::mem_fun(this, &ManglerSettings::inputDeviceComboBox_changed_cb)); builder->get_widget("inputDeviceCustomName", inputDeviceCustomName); builder->get_widget("outputDeviceComboBox", outputDeviceComboBox); outputDeviceTreeModel = Gtk::ListStore::create(outputColumns); outputDeviceComboBox->set_model(outputDeviceTreeModel); outputDeviceComboBox->pack_start(outputColumns.description); outputDeviceComboBox->signal_changed().connect(sigc::mem_fun(this, &ManglerSettings::outputDeviceComboBox_changed_cb)); builder->get_widget("outputDeviceCustomName", outputDeviceCustomName); builder->get_widget("notificationDeviceComboBox", notificationDeviceComboBox); notificationDeviceTreeModel = Gtk::ListStore::create(notificationColumns); notificationDeviceComboBox->set_model(notificationDeviceTreeModel); notificationDeviceComboBox->pack_start(notificationColumns.description); notificationDeviceComboBox->signal_changed().connect(sigc::mem_fun(this, &ManglerSettings::notificationDeviceComboBox_changed_cb)); builder->get_widget("notificationDeviceCustomName", notificationDeviceCustomName); mouseInputDevices = getInputDeviceList(); builder->get_widget("settingsMouseDeviceComboBox", mouseDeviceComboBox); mouseDeviceTreeModel = Gtk::ListStore::create(mouseColumns); mouseDeviceComboBox->set_model(mouseDeviceTreeModel); mouseDeviceComboBox->pack_start(mouseColumns.name); // Audio Subsystem audioSubsystemTreeModel->clear(); Gtk::TreeModel::Row audioSubsystemRow; #ifdef HAVE_PULSE audioSubsystemRow = *(audioSubsystemTreeModel->append()); audioSubsystemRow[audioSubsystemColumns.id] = "pulse"; audioSubsystemRow[audioSubsystemColumns.name] = "PulseAudio"; #endif #ifdef HAVE_ALSA audioSubsystemRow = *(audioSubsystemTreeModel->append()); audioSubsystemRow[audioSubsystemColumns.id] = "alsa"; audioSubsystemRow[audioSubsystemColumns.name] = "ALSA"; #endif #ifdef HAVE_OSS audioSubsystemRow = *(audioSubsystemTreeModel->append()); audioSubsystemRow[audioSubsystemColumns.id] = "oss"; audioSubsystemRow[audioSubsystemColumns.name] = "OSS"; #endif // Master Volume volumeAdjustment = new Gtk::Adjustment(79, 0, 158, 1, 10, 10); volumehscale = new Gtk::HScale(*volumeAdjustment); volumehscale->add_mark(148, Gtk::POS_LEFT, "200%"); volumehscale->add_mark(79, Gtk::POS_LEFT, "100%"); volumehscale->add_mark(0, Gtk::POS_LEFT, "0%"); volumehscale->set_inverted(false); volumehscale->set_draw_value(false); builder->get_widget("masterVolumeVbox", vbox); vbox->pack_start(*volumehscale); volumehscale->show(); // Input Gain gainAdjustment = new Gtk::Adjustment(79, 0, 158, 1, 10, 10); gainhscale = new Gtk::HScale(*gainAdjustment); gainhscale->add_mark(148, Gtk::POS_LEFT, "200%"); gainhscale->add_mark(79, Gtk::POS_LEFT, "100%"); gainhscale->add_mark(0, Gtk::POS_LEFT, "0%"); gainhscale->set_inverted(false); gainhscale->set_draw_value(false); builder->get_widget("inputGainVbox", vbox); vbox->pack_start(*gainhscale); gainhscale->show(); }/*}}}*/ void ManglerSettings::applySettings(void) {/*{{{*/ Gtk::TreeModel::iterator iter; GdkWindow *rootwin = gdk_get_default_root_window(); // Key Push to Talk builder->get_widget("settingsEnablePTTKeyCheckButton", checkbutton); Mangler::config["PushToTalkKeyEnabled"] = checkbutton->get_active(); builder->get_widget("settingsPTTKeyValueLabel", label); if (label->get_label() != PTT_KEY_GET && label->get_label() != PTT_KEY_SET) { Mangler::config["PushToTalkKeyValue"] = label->get_text(); } else { Mangler::config["PushToTalkKeyValue"] = ""; } //Mangler::config.parsePushToTalkValue(config.PushToTalkKeyValue); // Mouse Push to Talk builder->get_widget("settingsMouseDeviceComboBox", combobox); iter = combobox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["MouseDeviceName"] = Glib::ustring( row[mouseColumns.name] ); } builder->get_widget("settingsEnablePTTMouseCheckButton", checkbutton); Mangler::config["PushToTalkMouseEnabled"] = checkbutton->get_active(); builder->get_widget("settingsPTTMouseValueLabel", label); if (label->get_label() != PTT_MOUSE_GET && label->get_label() != PTT_MOUSE_SET) { Glib::ustring PushToTalkMouseValue = label->get_text(); if (PushToTalkMouseValue.length() > 6) { Mangler::config["PushToTalkMouseValue"] = PushToTalkMouseValue.substr(6); } else { Mangler::config["PushToTalkMouseValue"] = PushToTalkMouseValue; } } else { Mangler::config["PushToTalkMouseValue"] = ""; } XUngrabButton(GDK_WINDOW_XDISPLAY(rootwin), AnyButton, AnyModifier, GDK_ROOT_WINDOW()); XAllowEvents (GDK_WINDOW_XDISPLAY(rootwin), AsyncBoth, CurrentTime); /* if (checkbutton->get_active()) { XGrabButton(GDK_WINDOW_XDISPLAY(rootwin), config.PushToTalkMouseValueInt, AnyModifier, GDK_ROOT_WINDOW(), False, ButtonPressMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None); } */ // Audio Player Integration builder->get_widget("settingsEnableAudioIntegrationCheckButton", checkbutton); Mangler::config["AudioIntegrationEnabled"] = checkbutton->get_active(); iter = audioPlayerComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; uint8_t id = row[audioPlayerColumns.id]; Mangler::config["AudioIntegrationPlayer"] = id; if (Mangler::config["AudioIntegrationEnabled"].toBool()) { mangler->integration->setClient((MusicClient)id); } else { mangler->integration->setClient(MusicClient_None); } } mangler->integration->update(true); // Voice Activation builder->get_widget("settingsEnableVoiceActivationCheckButton", checkbutton); Mangler::config["VoiceActivationEnabled"] = checkbutton->get_active(); builder->get_widget("settingsVoiceActivationSilenceDurationSpinButton", spinbutton); Mangler::config["VoiceActivationSilenceDuration"] = spinbutton->get_value() * 1000.0; builder->get_widget("settingsVoiceActivationSensitivitySpinButton", spinbutton); Mangler::config["VoiceActivationSensitivity"] = spinbutton->get_value_as_int(); #ifdef HAVE_XOSD // On-Screen Display builder->get_widget("settingsEnableOnScreenDisplayCheckButton", checkbutton); Mangler::config["OnScreenDisplayEnabled"] = checkbutton->get_active(); if (checkbutton->get_active()) { Gtk::TreeModel::iterator pos_iter = osdPosition->get_active(); if (pos_iter) { int vert_pos_int = (*pos_iter)[osdPositionColumns.id]; Mangler::config["OnScreenDisplayVerticalPosition"] = vert_pos_int; } Gtk::TreeModel::iterator aln_iter = osdAlignment->get_active(); if (aln_iter) { int horz_aln_int = (*aln_iter)[osdAlignmentColumns.id]; Mangler::config["OnScreenDisplayHorizontalAlignment"] = horz_aln_int; } Mangler::config["OnScreenDisplayFontSize"] = osdFontSize->get_value(); Gdk::Color color = osdColor->get_color(); char colorstr[16]; snprintf(colorstr, 15, "#%02x%02x%02x", color.get_red() / 256, color.get_green() / 256, color.get_blue() / 256); Mangler::config["OnScreenDisplayColor"] = colorstr; mangler->osd->destroyOsd(); } #endif // Audio Devices iter = inputDeviceComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["InputDeviceName"] = Glib::ustring( row[inputColumns.name] ); } Mangler::config["InputDeviceCustomName"] = inputDeviceCustomName->get_text(); iter = outputDeviceComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["OutputDeviceName"] = Glib::ustring( row[outputColumns.name] ); } Mangler::config["OutputDeviceCustomName"] = outputDeviceCustomName->get_text(); iter = notificationDeviceComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["NotificationDeviceName"] = Glib::ustring( row[notificationColumns.name] ); } Mangler::config["NotificationDeviceCustomName"] = notificationDeviceCustomName->get_text(); iter = audioSubsystemComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["AudioSubsystem"] = Glib::ustring( row[audioSubsystemColumns.id] ); } // Master Volume Mangler::config["MasterVolumeLevel"] = volumeAdjustment->get_value(); v3_set_volume_master(Mangler::config["MasterVolumeLevel"].toInt()); mangler->setTooltip(); // Input Gain Mangler::config["InputGainLevel"] = gainAdjustment->get_value(); v3_set_volume_xmit(Mangler::config["InputGainLevel"].toInt()); // Notification Sounds builder->get_widget("notificationLoginLogoutCheckButton", checkbutton); Mangler::config["NotificationLoginLogout"] = checkbutton->get_active(); builder->get_widget("notificationChannelEnterLeaveCheckButton", checkbutton); Mangler::config["NotificationChannelEnterLeave"] = checkbutton->get_active(); builder->get_widget("notificationTalkStartEndCheckButton", checkbutton); Mangler::config["NotificationTransmitStartStop"] = checkbutton->get_active(); builder->get_widget("notificationTTSCheckButton", checkbutton); Mangler::config["NotificationTextToSpeech"] = checkbutton->get_active(); // Debug Level uint32_t debuglevel = 0; builder->get_widget("debugStatus", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_STATUS : 0; builder->get_widget("debugError", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_ERROR : 0; builder->get_widget("debugStack", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_STACK : 0; builder->get_widget("debugInternalNet", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_INTERNAL : 0; builder->get_widget("debugPacketDump", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_PACKET : 0; builder->get_widget("debugPacketParse", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_PACKET_PARSE : 0; builder->get_widget("debugEventQueue", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_EVENT : 0; builder->get_widget("debugSocket", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_SOCKET : 0; builder->get_widget("debugNotice", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_NOTICE : 0; builder->get_widget("debugInfo", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_INFO : 0; builder->get_widget("debugMutex", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_MUTEX : 0; builder->get_widget("debugMemory", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_MEMORY : 0; builder->get_widget("debugEncryptedPacket", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_PACKET_ENCRYPTED : 0; Mangler::config["lv3_debuglevel"] = debuglevel; v3_debuglevel(debuglevel); Mangler::config.config.save(); }/*}}}*/
/**************************************************************************** * * Move the rubberband around, return with the new window location * ****************************************************************************/ void moveLoop(FvwmWindow *tmp_win, int XOffset, int YOffset, int Width, int Height, int *FinalX, int *FinalY,Bool opaque_move, Bool AddWindow) { Bool finished = False; Bool done; int xl,yt,delta_x,delta_y; #ifndef NO_PAGER unsigned int pagerwidth,pagerheight; int ww,wh; int wx,wy; int MaxH,MaxW; int last_x = -10000, last_y = -10000; #endif XQueryPointer(dpy, Scr.Root, &JunkRoot, &JunkChild,&xl, &yt, &JunkX, &JunkY, &JunkMask); xl += XOffset; yt += YOffset; if(((!opaque_move)&&(!(Scr.flags & MWMMenus)))||(AddWindow)) MoveOutline(Scr.Root, xl, yt, Width,Height); DisplayPosition(tmp_win,xl+Scr.Vx,yt+Scr.Vy,True); while (!finished) { /* block until there is an interesting event */ XMaskEvent(dpy, ButtonPressMask | ButtonReleaseMask | KeyPressMask | PointerMotionMask | ButtonMotionMask | ExposureMask, &Event); StashEventTime(&Event); /* discard any extra motion events before a logical release */ if (Event.type == MotionNotify) { while(XCheckMaskEvent(dpy, PointerMotionMask | ButtonMotionMask | ButtonPressMask |ButtonRelease, &Event)) { StashEventTime(&Event); if(Event.type == ButtonRelease) break; } } done = FALSE; /* Handle a limited number of key press events to allow mouseless * operation */ if(Event.type == KeyPress) Keyboard_shortcuts(&Event,ButtonRelease); switch(Event.type) { case KeyPress: done = TRUE; break; case ButtonPress: XAllowEvents(dpy,ReplayPointer,CurrentTime); if(((Event.xbutton.button == 2)&&(!(Scr.flags & MWMMenus)))|| ((Event.xbutton.button == 1)&&(Scr.flags & MWMMenus)&& (Event.xbutton.state & ShiftMask))) { NeedToResizeToo = True; /* Fallthrough to button-release */ } else { done = 1; break; } case ButtonRelease: if(!opaque_move) MoveOutline(Scr.Root, 0, 0, 0, 0); xl = Event.xmotion.x_root + XOffset; yt = Event.xmotion.y_root + YOffset; /* Resist moving windows over the edge of the screen! */ if(((xl + Width) >= Scr.MyDisplayWidth)&& ((xl + Width) < Scr.MyDisplayWidth+Scr.MoveResistance)) xl = Scr.MyDisplayWidth - Width - tmp_win->bw; if((xl <= 0)&&(xl > -Scr.MoveResistance)) xl = 0; if(((yt + Height) >= Scr.MyDisplayHeight)&& ((yt + Height) < Scr.MyDisplayHeight+Scr.MoveResistance)) yt = Scr.MyDisplayHeight - Height - tmp_win->bw; if((yt <= 0)&&(yt > -Scr.MoveResistance)) yt = 0; *FinalX = xl; *FinalY = yt; done = TRUE; finished = TRUE; break; case MotionNotify: /* update location of the pager_view window */ #ifndef NO_PAGER if((Scr.FvwmPager != NULL)&& (xl < Scr.FvwmPager->frame_x + Scr.FvwmPager->frame_width)&& (xl+Width > Scr.FvwmPager->frame_x)&& (yt < Scr.FvwmPager->frame_y + Scr.FvwmPager->frame_height)&& (yt+ Height > Scr.FvwmPager->frame_y)&&(!opaque_move)) MoveOutline(Scr.Root,0,0,0,0); #endif xl = Event.xmotion.x_root; yt = Event.xmotion.y_root; HandlePaging(Scr.MyDisplayWidth,Scr.MyDisplayHeight,&xl,&yt, &delta_x,&delta_y,False); /* redraw the rubberband */ xl += XOffset; yt += YOffset; /* Resist moving windows over the edge of the screen! */ if(((xl + Width) >= Scr.MyDisplayWidth)&& ((xl + Width) < Scr.MyDisplayWidth+Scr.MoveResistance)) xl = Scr.MyDisplayWidth - Width - tmp_win->bw; if((xl <= 0)&&(xl > -Scr.MoveResistance)) xl = 0; if(((yt + Height) >= Scr.MyDisplayHeight)&& ((yt + Height) < Scr.MyDisplayHeight+Scr.MoveResistance)) yt = Scr.MyDisplayHeight - Height - tmp_win->bw; if((yt <= 0)&&(yt > -Scr.MoveResistance)) yt = 0; #ifndef NO_PAGER if(Scr.FvwmPager) { pagerwidth = Scr.FvwmPager->frame_width - 2*Scr.FvwmPager->boundary_width; pagerheight = Scr.FvwmPager->frame_height - Scr.FvwmPager->title_height - 2*Scr.FvwmPager->boundary_width; MaxW = Scr.VxMax + Scr.MyDisplayWidth; MaxH = Scr.VyMax + Scr.MyDisplayHeight; if(!(tmp_win->flags & STICKY)&& (!(tmp_win->flags&ICONIFIED)|| (!(tmp_win->flags&SUPPRESSICON)))&& (!(tmp_win->flags&ICONIFIED)||(!(Scr.flags & StickyIcons)))) { /* show the actual window */ wx = (xl + Scr.Vx)*(int)pagerwidth/MaxW; wy = (yt + Scr.Vy)*(int)pagerheight/MaxH; if((last_x - wx >= 2)||(last_x - wx <= -2)|| (last_y - wy >= 2)||(last_y - wy <= -2)) { ww = Width*(int)pagerwidth/MaxW; wh = Height*(int)pagerheight/MaxH; if(ww<2)ww=2; if(wh<2)wh=2; XMoveResizeWindow(dpy, tmp_win->pager_view, wx, wy, ww, wh); last_x = wx; last_y = wy; } } } #endif if(!opaque_move) MoveOutline(Scr.Root, xl, yt, Width,Height); else { if (tmp_win->flags & ICONIFIED) { tmp_win->icon_x_loc = xl ; tmp_win->icon_xl_loc = xl - (tmp_win->icon_w_width - tmp_win->icon_p_width)/2; tmp_win->icon_y_loc = yt; if(tmp_win->icon_pixmap_w != None) XMoveWindow (dpy, tmp_win->icon_pixmap_w, tmp_win->icon_x_loc,yt); else if (tmp_win->icon_w != None) XMoveWindow(dpy, tmp_win->icon_w,tmp_win->icon_xl_loc, yt+tmp_win->icon_p_height); } else XMoveWindow(dpy,tmp_win->frame,xl,yt); } DisplayPosition(tmp_win,xl+Scr.Vx,yt+Scr.Vy,False); done = TRUE; break; default: break; } if(!done) { if(!opaque_move) MoveOutline(Scr.Root,0,0,0,0); DispatchEvent(); if(!opaque_move) MoveOutline(Scr.Root, xl, yt, Width, Height); } } }
/*********************************************************************** * * Procedure: * HandleButtonPress - ButtonPress event handler * ***********************************************************************/ void HandleButtonPress() { unsigned int modifier; Binding *MouseEntry; Window x; int LocalContext; DBUG("HandleButtonPress","Routine Entered"); /* click to focus stuff goes here */ if((Tmp_win)&&(Tmp_win->flags & ClickToFocus)&&(Tmp_win != Scr.Ungrabbed) && ((Event.xbutton.state& (ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) == 0)) { SetFocus(Tmp_win->w,Tmp_win,1); /* #ifdef CLICKY_MODE_1 */ if (Scr.ClickToFocusRaises || ((Event.xany.window != Tmp_win->w)&& (Event.xbutton.subwindow != Tmp_win->w)&& (Event.xany.window != Tmp_win->Parent)&& (Event.xbutton.subwindow != Tmp_win->Parent))) /* #endif */ { RaiseWindow(Tmp_win); } KeepOnTop(); /* Why is this here? Seems to cause breakage with * non-focusing windows! */ if(!(Tmp_win->flags & ICONIFIED)) { XSync(dpy,0); /* pass click event to just clicked to focus window? */ if (Scr.ClickToFocusPassesClick) XAllowEvents(dpy,ReplayPointer,CurrentTime); else /* don't pass click to just focused window */ XAllowEvents(dpy,AsyncPointer,CurrentTime); XSync(dpy,0); return; } } else if ((Tmp_win) && !(Tmp_win->flags & ClickToFocus) && (Event.xbutton.window == Tmp_win->frame) && Scr.MouseFocusClickRaises) { if (Tmp_win != Scr.LastWindowRaised && (Event.xbutton.state & (ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) == 0 && GetContext(Tmp_win,&Event, &PressedW) == C_WINDOW) { RaiseWindow(Tmp_win); KeepOnTop(); } XSync(dpy,0); XAllowEvents(dpy,ReplayPointer,CurrentTime); XSync(dpy,0); return; } XSync(dpy,0); XAllowEvents(dpy,ReplayPointer,CurrentTime); XSync(dpy,0); Context = GetContext(Tmp_win,&Event, &PressedW); LocalContext = Context; x= PressedW; if(Context == C_TITLE) SetTitleBar(Tmp_win,(Scr.Hilite == Tmp_win),False); else SetBorder(Tmp_win,(Scr.Hilite == Tmp_win),True,True,PressedW); ButtonWindow = Tmp_win; /* we have to execute a function or pop up a menu */ modifier = (Event.xbutton.state & mods_used); /* need to search for an appropriate mouse binding */ for (MouseEntry = Scr.AllBindings; MouseEntry != NULL; MouseEntry= MouseEntry->NextBinding) { if(((MouseEntry->Button_Key == Event.xbutton.button)|| (MouseEntry->Button_Key == 0))&& (MouseEntry->Context & Context)&& ((MouseEntry->Modifier == AnyModifier)|| (MouseEntry->Modifier == (modifier& (~LockMask))))&& (MouseEntry->IsMouse == 1)) { /* got a match, now process it */ ExecuteFunction(MouseEntry->Action,Tmp_win, &Event,Context,-1); break; } } PressedW = None; if(LocalContext!=C_TITLE) SetBorder(ButtonWindow,(Scr.Hilite == ButtonWindow),True,True,x); else SetTitleBar(ButtonWindow,(Scr.Hilite==ButtonWindow),False); ButtonWindow = NULL; }
/* Owen magic */ static GdkFilterReturn filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) { XEvent *xev = (XEvent *) xevent; guint keyval; gint group; GdkScreen *screen = (GdkScreen *)data; if (xev->type == ButtonPress) { XAllowEvents (xev->xbutton.display, ReplayPointer, xev->xbutton.time); XUngrabButton (xev->xbutton.display, AnyButton, AnyModifier, xev->xbutton.window); XUngrabKeyboard (xev->xbutton.display, xev->xbutton.time); } if (xev->type == KeyPress || xev->type == KeyRelease) { /* get the keysym */ group = (xev->xkey.state & KEYBOARD_GROUP_MASK) >> KEYBOARD_GROUP_SHIFT; gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), xev->xkey.keycode, xev->xkey.state, group, &keyval, NULL, NULL, NULL); if (keyval == GDK_KEY_Control_L || keyval == GDK_KEY_Control_R) { if (xev->type == KeyPress) { XAllowEvents (xev->xkey.display, SyncKeyboard, xev->xkey.time); XGrabButton (xev->xkey.display, AnyButton, AnyModifier, xev->xkey.window, False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None); } else { XUngrabButton (xev->xkey.display, AnyButton, AnyModifier, xev->xkey.window); XAllowEvents (xev->xkey.display, AsyncKeyboard, xev->xkey.time); csd_locate_pointer (screen); } } else { XAllowEvents (xev->xkey.display, ReplayKeyboard, xev->xkey.time); XUngrabButton (xev->xkey.display, AnyButton, AnyModifier, xev->xkey.window); XUngrabKeyboard (xev->xkey.display, xev->xkey.time); } }
Window GetClientWindow(Widget w, int *x, int *y) { int status; Cursor cursor; XEvent event; int buttons = 0; Display * dpy = XtDisplayOfObject(w); Window target_win = None, root = RootWindowOfScreen(XtScreenOfObject(w)); XtAppContext app = XtWidgetToApplicationContext(w); /* Make the target cursor */ cursor = XCreateFontCursor(dpy, XC_crosshair); /* Grab the pointer using target cursor, letting it room all over */ status = XGrabPointer(dpy, root, False, ButtonPressMask|ButtonReleaseMask, GrabModeSync, GrabModeAsync, root, cursor, CurrentTime); if (status != GrabSuccess) { SetMessage(global_screen_data.info_label, res_labels[5]); return(None); } /* Let the user select a window... */ while ((target_win == None) || (buttons != 0)) { /* allow one more event */ XAllowEvents(dpy, SyncPointer, CurrentTime); XtAppNextEvent(app, &event); switch (event.type) { case ButtonPress: if (event.xbutton.window != root) { XtDispatchEvent(&event); break; } if (target_win == None) { target_win = event.xbutton.subwindow; /* window selected */ if (x != NULL) *x = event.xbutton.x_root; if (y != NULL) *y = event.xbutton.y_root; } buttons++; break; case ButtonRelease: if (event.xbutton.window != root) { XtDispatchEvent(&event); break; } if (buttons > 0) /* There may have been some down before we started */ buttons--; break; default: XtDispatchEvent(&event); break; } } XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ return(XmuClientWindow(dpy, target_win)); }
main() { Window w2; Display *dpy = XOpenDisplay(NIL); assert(dpy); Screen *scr = DefaultScreenOfDisplay(dpy); // CreateWindow Window w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XDestroyWindow(dpy, w); // CreateWindow with arguments XSetWindowAttributes swa; swa.background_pixel = WhitePixelOfScreen(scr); swa.bit_gravity = NorthWestGravity; swa.border_pixel = BlackPixelOfScreen(scr); swa.colormap = DefaultColormapOfScreen(scr); swa.cursor = None; swa.win_gravity = NorthGravity; w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel | CWBitGravity | CWBorderPixel | CWColormap | CWCursor | CWWinGravity, &swa); // CreateWindow with other arguments XDestroyWindow(dpy, w); Pixmap pixmap = XCreatePixmap(dpy, RootWindowOfScreen(scr), 45, 25, DefaultDepthOfScreen(scr)); assert(pixmap); swa.background_pixmap = pixmap; swa.border_pixmap = pixmap; w = XCreateWindow(dpy, RootWindowOfScreen(scr), 10, 100, 200, 300, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixmap | CWBorderPixmap, &swa); // ChangeWindowAttributes swa.backing_planes = 0x1; swa.backing_pixel = WhitePixelOfScreen(scr); swa.save_under = True; swa.event_mask = KeyPressMask | KeyReleaseMask; swa.do_not_propagate_mask = ButtonPressMask | Button4MotionMask; swa.override_redirect = False; XChangeWindowAttributes(dpy, w, CWBackingPlanes | CWBackingPixel | CWSaveUnder | CWEventMask | CWDontPropagate | CWOverrideRedirect, &swa); // GetWindowAttributes XWindowAttributes wa; Status success = XGetWindowAttributes(dpy, w, &wa); // DestroyWindow (done) // DestroySubwindows w2 = XCreateWindow(dpy, w, 20, 30, 40, 50, 3, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XDestroySubwindows(dpy, w); // ChangeSaveSet // Display *dpy2 = XOpenDisplay(NIL); // assert(dpy2); // XAddToSaveSet(dpy2, w); // XCloseDisplay(dpy2); // ReparentWindow w2 = XCreateWindow(dpy, RootWindowOfScreen(scr), 20, 30, 40, 50, 3, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XReparentWindow(dpy, w2, w, 10, 5); // MapWindow XMapWindow(dpy, w); // MapSubwindows XMapSubwindows(dpy, w); // UnmapWindow XUnmapWindow(dpy, w); // UnmapSubwindows XMapWindow(dpy, w); XUnmapSubwindows(dpy, w2); XMapSubwindows(dpy, w); // ConfigureWindow Window w3 = XCreateWindow(dpy, w, 10, 50, 100, 10, 2, CopyFromParent, CopyFromParent, CopyFromParent, 0, NIL); XMapWindow(dpy, w3); XWindowChanges wc; wc.x = -5; wc.y = -10; wc.width = 50; wc.height = 40; wc.border_width = 7; wc.sibling = w2; wc.stack_mode = Opposite; XConfigureWindow(dpy, w3, CWX | CWY | CWWidth | CWHeight | CWBorderWidth | CWSibling | CWStackMode, &wc); // CirculateWindow XCirculateSubwindows(dpy, w, RaiseLowest); // GetGeometry Window root; int x, y; unsigned width, height, border_width, depth; XGetGeometry(dpy, w, &root, &x, &y, &width, &height, &border_width, &depth); // QueryTree Window parent; Window *children; unsigned nchildren; success = XQueryTree(dpy, w, &root, &parent, &children, &nchildren); XFree(children); // InternAtom Atom a = XInternAtom(dpy, "WM_PROTOCOLS", True); // GetAtomName char *string = XGetAtomName(dpy, XA_PRIMARY); XFree(string); // ChangeProperty XStoreName(dpy, w, "test window"); // DeleteProperty XDeleteProperty(dpy, w, XA_WM_NAME); // GetProperty // TODO // ListProperties int num_prop; Atom *list = XListProperties(dpy, w, &num_prop); XFree(list); // SetSelectionOwner XSetSelectionOwner(dpy, XA_PRIMARY, w, 12000); XSetSelectionOwner(dpy, XA_SECONDARY, w, CurrentTime); // GetSelectionOwner Window wx = XGetSelectionOwner(dpy, XA_PRIMARY); // ConvertSelection XConvertSelection(dpy, XA_SECONDARY, XA_CURSOR, XA_POINT, w, CurrentTime); // SendEvent // GrabPointer std::cerr << "Grabbing" << std::endl; int res = XGrabPointer(dpy, w, False, Button5MotionMask | PointerMotionHintMask, GrabModeSync, GrabModeAsync, w, None, CurrentTime); XSync(dpy, False); // sleep(5); // UngrabPointer std::cerr << "Ungrabbing" << std::endl; XUngrabPointer(dpy, CurrentTime); // GrabButton XGrabButton(dpy, 3, ShiftMask | ControlMask, w, False, PointerMotionHintMask | Button2MotionMask, GrabModeAsync, GrabModeSync, None, None); XGrabButton(dpy, 2, AnyModifier, w, False, PointerMotionHintMask | Button2MotionMask, GrabModeAsync, GrabModeSync, None, None); // UngrabButton XUngrabButton(dpy, 2, LockMask, w); // ChangeActivePointerGrab XChangeActivePointerGrab(dpy, ButtonPressMask, None, CurrentTime); // GrabKeyboard XGrabKeyboard(dpy, w, True, GrabModeSync, GrabModeSync, 12000); // UngrabKeyboard XUngrabKeyboard(dpy, 13000); // GrabKey XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Tab), ShiftMask | Mod3Mask, w, True, GrabModeSync, GrabModeSync); // UngrabKey XUngrabKey(dpy, AnyKey, AnyModifier, w); // AllowEvents XAllowEvents(dpy, AsyncPointer, 14000); // GrabServer XGrabServer(dpy); // UngrabServer XUngrabServer(dpy); // QueryPointer Window child; int root_x, root_y, win_x, win_y; unsigned mask; Bool bres = XQueryPointer(dpy, w, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask); // GetMotionEvents int nevents; XGetMotionEvents(dpy, w, 15000, 16000, &nevents); // TranslateCoordinates int dest_x, dest_y; XTranslateCoordinates(dpy, w, w2, 10, 20, &dest_x, &dest_y, &child); // WarpPointer XWarpPointer(dpy, w, w2, 0, 0, 100, 100, 20, 30); // SetInputFocus XSetInputFocus(dpy,w, RevertToPointerRoot, 17000); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, 17000); // GetInputFocus Window focus; int revert_to; XGetInputFocus(dpy, &focus, &revert_to); // QueryKeymap char keys_return[32]; XQueryKeymap(dpy, keys_return); // OpenFont Font fid = XLoadFont(dpy, "cursor"); // CloseFont XUnloadFont(dpy, fid); // QueryFont XFontStruct *fs = XLoadQueryFont(dpy, "cursor"); assert(fs); // QueryTextExtents int direction, font_ascent, font_descent; XCharStruct overall; XQueryTextExtents(dpy, fs -> fid, "toto", 4, &direction, &font_ascent, &font_descent, &overall); XQueryTextExtents(dpy, fs -> fid, "odd__length", 11, &direction, &font_ascent, &font_descent, &overall); XChar2b c2bs; c2bs.byte1 = '$'; c2bs.byte2 = 'B'; XQueryTextExtents16(dpy, fs -> fid, &c2bs, 1, &direction, &font_ascent, &font_descent, &overall); XQueryTextExtents(dpy, fs -> fid, longString, strlen(longString), &direction, &font_ascent, &font_descent, &overall); // ListFonts int actual_count; char **fontList = XListFonts(dpy, "*", 100, &actual_count); XFree((char *)fontList); // ListFontsWithInfo int count; XFontStruct *info; char **names = XListFontsWithInfo(dpy, "*", 100, &count, &info); XFreeFontInfo(names, info, count); // SetFontPath // GetFontPath int npaths; char **charList = XGetFontPath(dpy, &npaths); char **charList2 = new char *[npaths + 1]; memcpy(charList2, charList, npaths * sizeof(char *)); charList2[npaths] = charList2[0]; XSetFontPath(dpy, charList2, npaths + 1); XSetFontPath(dpy, charList, npaths); // Reset to some reasonnable value XFreeFontPath(charList); delete [] charList2; // CreatePixmap Pixmap pix2 = XCreatePixmap(dpy, w, 100, 200, DefaultDepthOfScreen(scr)); // FreePixmap XFreePixmap(dpy, pix2); // CreateGC Pixmap bitmap = XCreateBitmapFromData(dpy, RootWindowOfScreen(scr), "\000\000\001\000\000\001\000\000\001\377\377\377", 3, 4); XGCValues gcv; gcv.function = GXand; gcv.plane_mask = 0x1; gcv.foreground = WhitePixelOfScreen(scr); gcv.background = BlackPixelOfScreen(scr); gcv.line_width = 2; gcv.line_style = LineDoubleDash; gcv.cap_style = CapProjecting; gcv.join_style = JoinRound; gcv.fill_style = FillStippled; gcv.fill_rule = EvenOddRule; gcv.arc_mode = ArcPieSlice; gcv.tile = pixmap; gcv.stipple = bitmap; gcv.ts_x_origin = 3; gcv.ts_y_origin = 4; gcv.font = fs -> fid; gcv.subwindow_mode = ClipByChildren; gcv.graphics_exposures = True; gcv.clip_x_origin = 5; gcv.clip_y_origin = 6; gcv.clip_mask = bitmap; gcv.dash_offset = 1; gcv.dashes = 0xc2; GC gc = XCreateGC(dpy, w, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle | GCFillRule | GCTile | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCFont | GCSubwindowMode | GCGraphicsExposures | GCClipXOrigin | GCClipYOrigin | GCClipMask | GCDashOffset | GCDashList | GCArcMode, &gcv); // ChangeGC gcv.function = GXandReverse; // Only a few of these should appear, since the values are cached on the client side by the Xlib. XChangeGC(dpy, gc, GCFunction | GCLineStyle | GCStipple | GCGraphicsExposures | GCDashList, &gcv); // CopyGC GC gc2 = XCreateGC(dpy, w, 0, NIL); XCopyGC(dpy, gc, GCFunction | GCLineStyle | GCStipple | GCGraphicsExposures | GCDashList, gc2); // SetDashes XSetDashes(dpy, gc, 3, "\001\377\001", 3); // SetClipRectangles XRectangle rectangles[] = { { 10, 20, 30, 40 }, { 100, 200, 5, 3 }, { -5, 1, 12, 24 } }; XSetClipRectangles(dpy, gc, 12, 9, rectangles, SIZEOF(rectangles), Unsorted); // FreeGC // done already // ClearArea XClearArea(dpy, w, 30, 10, 10, 100, False); // CopyArea XCopyArea(dpy, w, pixmap, gc, 0, 0, 100, 100, 10, 10); // CopyPlane // This won't work if the Screen doesn't have at least 3 planes XCopyPlane(dpy, pixmap, w, gc, 20, 10, 40, 30, 0, 0, 0x4); // PolyPoint XDrawPoint(dpy, w, gc, 1, 2); XPoint points[] = { { 3, 4 }, { 5, 6 } }; XDrawPoints(dpy, w, gc, points, SIZEOF(points), CoordModeOrigin); // PolyLine XDrawLines(dpy, w, gc, points, SIZEOF(points), CoordModePrevious); // PolySegment XSegment segments[] = { { 7, 8, 9, 10 }, { 11, 12, 13, 14 }, { 15, 16, 17, 18 } }; XDrawSegments(dpy, w, gc, segments, SIZEOF(segments)); // PolyRectangle XDrawRectangles(dpy, w, gc, rectangles, SIZEOF(rectangles)); // PolyArc XArc arcs[] = { { 10, 20, 30, 40, 50, 60 }, { -70, 80, 90, 100, 110, 120 }, { 10, 20, 30, 40, 50, -30 } }; XDrawArcs(dpy, w, gc, arcs, SIZEOF(arcs)); // FillPoly XFillPolygon(dpy, w, gc, points, SIZEOF(points), Convex, CoordModePrevious); // PolyFillRectangle XFillRectangles(dpy, w, gc, rectangles, SIZEOF(rectangles)); // PolyFillArc XFillArcs(dpy, w, gc, arcs, SIZEOF(arcs)); // PutImage // GetImage XImage *image = XGetImage(dpy, w, 10, 20, 40, 30, AllPlanes, ZPixmap); XPutImage(dpy, w, gc, image, 0, 0, 50, 60, 40, 30); XSync(dpy, False); // Make the next request starts at the beginning of a packet // PolyText8 XTextItem textItems[3]; textItems[0].chars = "toto"; textItems[0].nchars = strlen(textItems[0].chars); textItems[0].delta = -3; textItems[0].font = fs->fid; textItems[1].chars = "titi"; textItems[1].nchars = strlen(textItems[1].chars); textItems[1].delta = 3; textItems[1].font = None; textItems[2].chars = "tutu"; textItems[2].nchars = strlen(textItems[2].chars); textItems[2].delta = 0; textItems[2].font = fs->fid; XDrawText(dpy, w, gc, 10, 10, textItems, 3); XTextItem textItems2[3]; textItems2[0].chars = "totox"; textItems2[0].nchars = strlen(textItems2[0].chars); textItems2[0].delta = -3; textItems2[0].font = fs->fid; textItems2[1].chars = "titi"; textItems2[1].nchars = strlen(textItems2[1].chars); textItems2[1].delta = 3; textItems2[1].font = None; textItems2[2].chars = "tutu"; textItems2[2].nchars = strlen(textItems2[2].chars); textItems2[2].delta = 0; textItems2[2].font = fs->fid; XDrawText(dpy, w, gc, 10, 10, textItems2, 3); // PolyText16 XChar2b c2b2[] = { 0, 't', 0, 'x' }; XTextItem16 items16[] = { { &c2bs, 1, -5, None }, { NULL, 0, 0, None }, { c2b2, 2, 0, fs -> fid } }; XDrawText16(dpy, w, gc, 10, 0, items16, SIZEOF(items16)); // ImageText8 XDrawImageString(dpy, w, gc, 10, 10, "toto", 4); // ImageText16 XDrawImageString16(dpy, w, gc, 10, 10, &c2bs, 1); XDrawImageString16(dpy, w, gc, 10, 20, c2b2, 2); // CreateColormap // Don't forget to tell the kids how it was when we had only 8 bits per pixel. Colormap colormap = XCreateColormap(dpy, w, DefaultVisualOfScreen(scr), None); // FreeColormap XFreeColormap(dpy, colormap); colormap = XCreateColormap(dpy, w, DefaultVisualOfScreen(scr), None); // CopyColormapAndFree Colormap colormap2 = XCopyColormapAndFree(dpy, colormap); // InstallColormap XInstallColormap(dpy, colormap2); // UninstallColormap XUninstallColormap(dpy, colormap2); // ListInstalledColormaps int num; Colormap *colormapList = XListInstalledColormaps(dpy, w, &num); // AllocColor XColor screen; screen.red = 0; screen.green = 32767; screen.blue = 65535; screen.flags = DoRed | DoGreen | DoBlue; success = XAllocColor(dpy, colormap, &screen); // AllocNamedColor XColor screen2, exact; success = XAllocNamedColor(dpy, colormap, "Wheat", &screen2, &exact); // AllocColorCells unsigned long plane_masks, pixels; success = XAllocColorCells(dpy, colormap, False, &plane_masks, 1, &pixels, 1); // AllocColorPlanes unsigned long rmask, gmask, bmask; success = XAllocColorPlanes(dpy, colormap, False, &pixels, 1, 0, 0, 0, &rmask, &gmask, &bmask); // FreeColors unsigned long pixels2[2] = { screen.pixel, screen2.pixel }; XFreeColors(dpy, colormap, pixels2, 2, 0); // StoreColors success = XAllocColorCells(dpy, colormap, False, NIL, 0, pixels2, 2); // On many contemporary (that is, year 2000) video cards, you can't allocate read / write cells // I want my requests to be sent, however. if (!success) { XSetErrorHandler(errorHandler); } XColor colors[2]; colors[0] = screen; colors[0].pixel = pixels2[0]; colors[1] = screen2; colors[1].pixel = pixels2[1]; XStoreColors(dpy, colormap, colors, 2); // StoreNamedColor XStoreNamedColor(dpy, colormap, "Wheat", colors[0].pixel, DoBlue); XSync(dpy, False); XSetErrorHandler(NIL); // Restore the default handler // QueryColors screen2.pixel = WhitePixelOfScreen(scr); XQueryColor(dpy, colormap, &screen2); // LookupColor success = XLookupColor(dpy, colormap, "DarkCyan", &exact, &screen); // CreateCursor Cursor cursor = XCreatePixmapCursor(dpy, pixmap, None, &exact, colors, 10, 10); // CreateGlyphCursor Cursor cursor2 = XCreateGlyphCursor(dpy, fs -> fid, fs -> fid, 'X', 0, &exact, colors); // FreeCursor XFreeCursor(dpy, cursor2); // RecolorCursor XRecolorCursor(dpy, cursor, colors, &exact); // QueryBestSize success = XQueryBestSize(dpy, CursorShape, RootWindowOfScreen(scr), 100, 20, &width, &height); // QueryExtension int major_opcode, first_event, first_error; XQueryExtension(dpy, "toto", &major_opcode, &first_event, &first_error); // ListExtensions int nextensions; char **extensionList = XListExtensions(dpy, &nextensions); for(char **p = extensionList; nextensions; nextensions--, p++) std::cout << *p << std::endl; XFree(extensionList); // ChangeKeyboardMapping // GetKeyboardMapping int min_keycodes, max_keycodes; XDisplayKeycodes(dpy, &min_keycodes, &max_keycodes); int keysyms_per_keycode; KeySym *keysyms = XGetKeyboardMapping(dpy, min_keycodes, max_keycodes - min_keycodes + 1, &keysyms_per_keycode); XChangeKeyboardMapping(dpy, min_keycodes, keysyms_per_keycode, keysyms, max_keycodes - min_keycodes + 1); // ChangeKeyboardControl // GetKeyboardControl XKeyboardState keyboardState; XGetKeyboardControl(dpy, &keyboardState); XKeyboardControl keyboardValues; keyboardValues.key_click_percent = keyboardState.key_click_percent; keyboardValues.bell_percent = keyboardState.bell_percent; keyboardValues.bell_pitch = keyboardState.bell_pitch; keyboardValues.bell_duration = keyboardState.bell_duration; keyboardValues.led = 1; keyboardValues.led_mode = LedModeOn; keyboardValues.key = min_keycodes; keyboardValues.auto_repeat_mode = AutoRepeatModeDefault; XChangeKeyboardControl(dpy, KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration | KBLed | KBLedMode | KBKey | KBAutoRepeatMode, &keyboardValues); // Bell XBell(dpy, 90); // ChangePointerControl // GetPointerControl int accel_numerator, accel_denominator, threshold; XGetPointerControl(dpy, &accel_numerator, &accel_denominator, &threshold); XChangePointerControl(dpy, True, True, accel_numerator, accel_denominator, threshold); // SetScreenSaver // GetScreenSaver int timeout, interval, prefer_blanking, allow_exposures; XGetScreenSaver(dpy, &timeout, &interval, &prefer_blanking, &allow_exposures); XSetScreenSaver(dpy, timeout, interval, prefer_blanking, allow_exposures); // ChangeHosts // ListHosts int nhosts; Bool state; XHostAddress *hostList = XListHosts(dpy, &nhosts, &state); XHostAddress host; host.family = FamilyInternet; host.length = 4; host.address = "\001\002\003\004"; XAddHost(dpy, &host); // SetAccessControl XSetAccessControl(dpy, EnableAccess); // SetCloseDownMode XSetCloseDownMode(dpy, RetainTemporary); // KillClient XKillClient(dpy, AllTemporary); // RotateProperties Atom properties[] = { XInternAtom(dpy, "CUT_BUFFER0", False), XInternAtom(dpy, "CUT_BUFFER1", False), XInternAtom(dpy, "CUT_BUFFER2", False) }; XRotateWindowProperties(dpy, RootWindowOfScreen(scr), properties, SIZEOF(properties), -1); // ForceScreenSaver XForceScreenSaver(dpy, ScreenSaverReset); // SetPointerMapping // GetPointerMapping unsigned char map[64]; int map_length = XGetPointerMapping(dpy, map, 64); XSetPointerMapping(dpy, map, map_length); // SetModifierMapping // GetModifierMapping XModifierKeymap *modmap = XGetModifierMapping(dpy); XSetModifierMapping(dpy, modmap); // NoOperation XNoOp(dpy); for(;;) { XEvent e; XNextEvent(dpy, &e); std::cout << "Got an event of type " << e.type << std::endl; } }
VALUE subSubtleSingSelect(VALUE self) { int i, format = 0, buttons = 0; unsigned int nwins = 0; unsigned long nitems = 0, bytes = 0; unsigned char *data = NULL; XEvent event; Window win = None; Atom type = None, rtype = None; Window wroot = None, parent = None, root = None, *wins = NULL; Cursor cursor = None; subSubtlextConnect(NULL); ///< Implicit open connection root = DefaultRootWindow(display); cursor = XCreateFontCursor(display, XC_cross); type = XInternAtom(display, "WM_STATE", True); /* Grab pointer */ if(XGrabPointer(display, root, False, ButtonPressMask|ButtonReleaseMask, GrabModeSync, GrabModeAsync, root, cursor, CurrentTime)) { XFreeCursor(display, cursor); return Qnil; } /* Select a window */ while(None == win || 0 != buttons) { XAllowEvents(display, SyncPointer, CurrentTime); XWindowEvent(display, root, ButtonPressMask|ButtonReleaseMask, &event); switch(event.type) { case ButtonPress: if(None == win) win = event.xbutton.subwindow ? event.xbutton.subwindow : root; ///< Sanitize buttons++; break; case ButtonRelease: if(0 < buttons) buttons--; break; } } /* Find children with WM_STATE atom */ XQueryTree(display, win, &wroot, &parent, &wins, &nwins); for(i = 0; i < nwins; i++) { if(Success == XGetWindowProperty(display, wins[i], type, 0, 0, False, AnyPropertyType, &rtype, &format, &nitems, &bytes, &data)) { if(data) { XFree(data); data = NULL; } if(type == rtype) { win = wins[i]; break; } } } if(wins) XFree(wins); XFreeCursor(display, cursor); XUngrabPointer(display, CurrentTime); XSync(display, False); ///< Sync all changes return None != win ? LONG2NUM(win) : Qnil; } /* }}} */
void emX11WindowPort::PostConstruct() { int i,r; if ((GetWindowFlags()&( emWindow::WF_POPUP|emWindow::WF_UNDECORATED|emWindow::WF_FULLSCREEN ))!=0) { XMutex.Lock(); XMapRaised(Disp,Win); XMutex.Unlock(); } else { XMutex.Lock(); XMapWindow(Disp,Win); XMutex.Unlock(); } if (Focused) { if (MakeViewable()) { if ((GetWindowFlags()&emWindow::WF_MODAL)!=0 && Owner) { XMutex.Lock(); XSetInputFocus(Disp,Win,RevertToParent,CurrentTime); XMutex.Unlock(); } else { XMutex.Lock(); XSetInputFocus(Disp,Win,RevertToNone,CurrentTime); XMutex.Unlock(); } } else { Focused=false; SetViewFocused(false); } } if ( (GetWindowFlags()&emWindow::WF_FULLSCREEN)!=0 || ( (GetWindowFlags()&emWindow::WF_POPUP)!=0 && ( !Screen.GrabbingWinPort || (Screen.GrabbingWinPort->GetWindowFlags()&emWindow::WF_FULLSCREEN)==0 ) ) ) { if (MakeViewable()) { for (i=0; ; i++) { XMutex.Lock(); r=XGrabKeyboard( Disp, Win, True, GrabModeSync, GrabModeAsync, CurrentTime ); XMutex.Unlock(); if (r==GrabSuccess) break; if (i>10) emFatalError("XGrabKeyboard failed."); emWarning("XGrabKeyboard failed - trying again..."); emSleepMS(50); } for (i=0; ; i++) { XMutex.Lock(); r=XGrabPointer( Disp, Win, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask| ButtonMotionMask|EnterWindowMask|LeaveWindowMask, GrabModeSync, GrabModeAsync, (GetWindowFlags()&emWindow::WF_FULLSCREEN)!=0 ? Win : None, None, CurrentTime ); XMutex.Unlock(); if (r==GrabSuccess) break; if (i>10) emFatalError("XGrabPointer failed."); emWarning("XGrabPointer failed - trying again..."); emSleepMS(50); } XMutex.Lock(); XAllowEvents(Disp,SyncPointer,CurrentTime); XMutex.Unlock(); Screen.GrabbingWinPort=this; } } if ((GetWindowFlags()&emWindow::WF_FULLSCREEN)!=0) { FullscreenUpdateTimer=new emTimer(GetScheduler()); AddWakeUpSignal(FullscreenUpdateTimer->GetSignal()); FullscreenUpdateTimer->Start(500,true); } if ((GetWindowFlags()&emWindow::WF_MODAL)!=0) { SetModalState(true); } }
void ignore_button(Display * dpy, XEvent ev) { XAllowEvents(dpy, SyncBoth, ev.xbutton.time); XFlush(dpy); }
bool Gesture::x11Event( XEvent* ev_P ) { /* kDebug() << " ( type = " << ev_P->type << " )" << KeyRelease << " " << KeyPress ; if( ev_P->type == XKeyPress || ev_P->type == XKeyRelease ) { return voice_handler->x11Event( ev_P ); }*/ if( ev_P->type == ButtonPress && ev_P->xbutton.button == button ) { kDebug() << "GESTURE: mouse press"; stroke.reset(); stroke.record( ev_P->xbutton.x, ev_P->xbutton.y ); nostroke_timer.start( timeout ); recording = true; start_x = ev_P->xbutton.x_root; start_y = ev_P->xbutton.y_root; return true; } // if stroke is finished... postprocess the data and send a signal. // then wait for incoming matching scores and execute the best fit. else if( ev_P->type == ButtonRelease && ev_P->xbutton.button == button && recording ) { recording = false; nostroke_timer.stop(); stroke.record( ev_P->xbutton.x, ev_P->xbutton.y ); StrokePoints gesture( stroke.processData() ); if( gesture.isEmpty() ) { kDebug() << "GESTURE: replay"; XAllowEvents( QX11Info::display(), AsyncPointer, CurrentTime ); XUngrabPointer( QX11Info::display(), CurrentTime ); mouse_replay( true ); return true; } // prepare for the incoming scores from different triggers maxScore = 0.0; bestFit = NULL; emit handle_gesture( gesture ); // the signal is emitted directly, so we get all trigger scores before // the next lines are executed. bestFit should now contain // a pointer to the ActionData with the best-matching gesture. if( bestFit != NULL ) { // set up the windows_handler WId window = windows_handler->window_at_position( start_x, start_y ); windows_handler->set_action_window( window ); // then execute the action associated with the best match. bestFit->execute(); } return true; } else if( ev_P->type == MotionNotify && recording ) { // ignore small initial movement if( nostroke_timer.isActive() && abs( start_x - ev_P->xmotion.x_root ) < 10 && abs( start_y - ev_P->xmotion.y_root ) < 10 ) return true; nostroke_timer.stop(); stroke.record( ev_P->xmotion.x, ev_P->xmotion.y ); } return false; }
void passthru_button(Display * dpy, XEvent ev) { XAllowEvents(dpy, ReplayPointer, ev.xbutton.time); XFlush(dpy); }
void MCScreenDC::make_clipboard_persistant(void) { XEvent xevent ; Atom clipboard_manager, save_targets, rev_targets; clipboard_manager = make_atom ("CLIPBOARD_MANAGER"); save_targets = make_atom ("SAVE_TARGETS"); if ( ownsclipboard() ) { XConvertSelection ( dpy, clipboard_manager, save_targets, None, NULLWindow, MCeventtime ); bool done = false ; while ( !done ) { XAllowEvents (dpy , SyncPointer, CurrentTime); XNextEvent( dpy , &xevent); if ( xevent.type == SelectionNotify ) done = true ; if ( xevent.type == SelectionRequest ) { XSelectionRequestEvent * srevent ; srevent = &xevent.xselectionrequest ; XSelectionEvent sendevent; sendevent.type = SelectionNotify; sendevent.send_event = True; sendevent.display = srevent->display; sendevent.requestor = srevent->requestor; sendevent.selection = srevent->selection; sendevent.time = srevent->time; sendevent.target = srevent->target; sendevent.property = srevent->property ; if ( srevent->target == XA_TARGETS) { uint4 t_count ; Atom *t_atoms ; t_atoms = m_Clipboard_store -> QueryAtoms ( t_count ); if ( t_atoms != NULL) { XChangeProperty(dpy, srevent -> requestor, srevent -> property, XA_ATOM, 32, PropModeReplace, (const unsigned char *)t_atoms, t_count) ; sendevent.property = srevent->target; XSendEvent(dpy, srevent -> requestor, False, 0, (XEvent *)&sendevent); free(t_atoms) ; } } else if ( srevent->target == make_atom("MULTIPLE") ) { unsigned long remaining; unsigned long count; unsigned char *s = NULL ; Atom actual; int format; XGetWindowProperty (dpy, srevent->requestor , srevent->property, 0, 65536, false, AnyPropertyType, &actual, &format, &count, &remaining, &s) ; Atom *atoms ; uint4 t_bytes = count * ( format / 8 ); atoms = (Atom*)malloc ( t_bytes ) ; memset ( atoms, 0, t_bytes ) ; memcpy(atoms, s, t_bytes ) ; XFree(s); Atom property, target ; for (uint4 a=0; a<count; a++) { property = target = atoms[a] ; a++; MCSharedString * t_data; if ( ( target != make_atom("TARGETS") ) && ( target != make_atom("TIMESTAMP") ) && ( target != make_atom("SAVE_TARGETS") )) { if (m_Clipboard_store -> Fetch( new MCMIMEtype(dpy, target), t_data, None, None, DNULL, DNULL, MCeventtime )) { XChangeProperty(dpy, srevent -> requestor, property, XA_STRING, 8, PropModeReplace, (const unsigned char *)t_data -> Get() . getstring(), t_data -> Get() . getlength()); } else { XChangeProperty(dpy, srevent -> requestor, property, XInternAtom(dpy, "None", false), 8, PropModeReplace, (const unsigned char *)NULL, 0 ); } } } sendevent.property = srevent->property ; XSendEvent (dpy, sendevent.requestor, False, 0, (XEvent *)&sendevent ); for (uint4 a=0; a<count; a++) { a++; XDeleteProperty(dpy, srevent->requestor, target); } XDeleteProperty(dpy, srevent->requestor, srevent->property); free(atoms); } } } } }
int set_full_screen(Display *dpy) { signal(SIGUSR1, fake_right_button); fulldisplay = dpy; Window curwin, rootw; Cursor hand_cursor; int x1, y1, winx, winy; unsigned int mask; XEvent ev; int screen_num; if (!dpy) { fprintf(stderr, "WTPEN : cannot get default display\n"); exit(1); } /* style for line */ unsigned int line_width = 8; int line_style = LineSolid; int cap_style = CapRound; int join_style = JoinRound; screen_num = DefaultScreen(dpy); rootw = DefaultRootWindow(dpy); if (rootw == None) { fprintf(stderr, "WTPEN : full screen mode cannot get root window\n"); exit(1); } hand_cursor = XCreateFontCursor(dpy, XC_hand2); drawgc = XCreateGC(dpy, rootw, 0, NULL); // hier wordt getekend (met xor) XSetSubwindowMode(dpy, drawgc, IncludeInferiors); XSetForeground(dpy, drawgc, WhitePixel(dpy, screen_num) ^ BlackPixel(dpy, screen_num)); XSetLineAttributes(dpy, drawgc, line_width, line_style, cap_style, join_style); XSetFunction(dpy, drawgc, GXandInverted); //XSetFunction(dpy, drawgc, GXxor); fprintf(stderr, "full screen mode grab button\n"); XGrabButton(dpy, AnyButton, 0, rootw, False, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | OwnerGrabButtonMask, GrabModeSync, GrabModeAsync, None, hand_cursor); while (1) { fprintf (stderr, "fullscreen\n"); // wordt bij tekenen aangeroepen XAllowEvents(dpy, SyncPointer, CurrentTime); XWindowEvent(dpy, rootw, ButtonPressMask|ButtonReleaseMask|ButtonMotionMask, &ev); switch(ev.type) { case ButtonPress: kill(getppid(), SIGUSR2); if(ev.xbutton.button != Button1) { int num; XUngrabButton(dpy, AnyButton, 0, rootw); XFlush(dpy); record_coordinate(0xff, 0xff); clear_draw_area(dpy, rootw, drawgc); num = get_coordinates_num(); return num; } XQueryPointer(dpy, rootw, &rootw, &curwin, &x1, &y1, //root x, root y &winx, &winy, &mask); record_coordinate(x1, y1); break; case ButtonRelease: if (ev.xbutton.button == Button1) { if (get_coordinates_num() == 2) { free_coordinates(); XUngrabButton(dpy, AnyButton, 0, rootw); forward_click_event(dpy, &ev); XFlush(dpy); return 0; } record_coordinate(0xff, 0x00); kill(getppid(), SIGALRM); } break; case MotionNotify: if (ev.xmotion.state & Button1MotionMask) { CoordinateList *cl_end; XQueryPointer(dpy, rootw, &rootw, &curwin, &x1, &y1, //root x, root y &winx, &winy, &mask); cl_end = coordinate_list_end(); if (cl_end) { if (!(cl_end->x == 0xff && cl_end->y == 0x00)) { XDrawLine(dpy, rootw, drawgc, x1, y1, cl_end->x, cl_end->y); record_coordinate(x1, y1); } } else { record_coordinate(x1, y1); } } break; default: break; } } fprintf(stderr, "exit fullscreen\n"); // wordt nooit bereikt return 1; }
void glutMainLoop() { char buffer[10]={0}; char pressed = 0; int i; XAllowEvents(dpy, AsyncBoth, CurrentTime); while (gRunning) { while (XPending(dpy) > 0) { XEvent event; XNextEvent(dpy, &event); switch (event.type) { case ClientMessage: if (event.xclient.data.l[0] == (signed)wmDeleteMessage) // quit! gRunning = 0; break; case Expose: break; // Update event! Should do draw here. case ConfigureNotify: if (gReshape) gReshape(event.xconfigure.width, event.xconfigure.height); else { glViewport(0, 0, event.xconfigure.width, event.xconfigure.height); } animate = 1; break; case KeyPress: case KeyRelease: if (event.type == KeyPress) { if ((gKey)){ gKey(event.xkey.keycode, event.xkey.x, event.xkey.y,event.xkey.state & ShiftMask ? 1 : 0); gKeymap[(int)buffer[0]] = 1; } } else { if (gKeyUp) gKeyUp(buffer[0], 0, 0,0); gKeymap[(int)buffer[0]] = 0;} break; case ButtonPress: gButtonPressed[event.xbutton.button] = 1; if (gMouseFunc != NULL) gMouseFunc(GLUT_LEFT_BUTTON, GLUT_DOWN, event.xbutton.x, event.xbutton.y); break; case ButtonRelease: gButtonPressed[event.xbutton.button] = 0; if (gMouseFunc != NULL) gMouseFunc(GLUT_LEFT_BUTTON, GLUT_UP, event.xbutton.x, event.xbutton.y); break; case MotionNotify: pressed = 0; for (i = 0; i < 5; i++) if (gButtonPressed[i]) pressed = 1; if (pressed && gMouseDragged) gMouseDragged(event.xbutton.x, event.xbutton.y); else if (gMouseMoved) gMouseMoved(event.xbutton.x, event.xbutton.y); break; default: break; } } if (animate) { animate = 0; if (gDisplay) gDisplay(); else printf("No display function!\n"); } else if (gIdle) gIdle(); checktimers(); } glXMakeCurrent(dpy, None, NULL); glXDestroyContext(dpy, ctx); XDestroyWindow(dpy, win); XCloseDisplay(dpy); }
/* Function Name: * GetClientWindow * * Description: * Gets the Client's window by asking the user. * * Arguments: * w - a widget. * * Returns: * a clients window, or None. * * Calls: * SetMessage - utils.c * * Global Data: */ Window GetClientWindow(Widget w, int *x, int *y) { int status; Cursor cursor; XEvent event; int buttons = 0; int keys = 0; Display *dpy = XtDisplayOfObject(w); Window target_win = None; Window root_win = RootWindowOfScreen(XtScreenOfObject(w)); XtAppContext context = XtWidgetToApplicationContext(w); char buffer[10]; int len; KeySym keycode; /* >>>>> HACK for batchres */ if (global_winID != None) { /* we submit the winID given by parameter only once! */ /* otherwise there is an infinite loop */ target_win = global_winID; global_winID = None; return(target_win); } /* <<<<< HACK for batchres */ /* Make the target cursor */ cursor = XCreateFontCursor(dpy, XC_crosshair); /* Grab the pointer using target cursor, letting it room all over */ status = XGrabPointer(dpy, /* Display */ root_win, /* grab_window */ False, /* owner_events */ ButtonPressMask | ButtonReleaseMask, GrabModeSync, /* pointer_mode */ GrabModeAsync, /* keyboard_mode */ root_win, /* confine_to */ cursor, /* cursor */ CurrentTime); /* time, when grab took place */ if (status != GrabSuccess) { /* "Can't grab the mouse" */ SetMessage(global_screen_data.info_label, res_labels[5], "Can't grab the mouse"); return(None); } /* if (grab of mouse pointer unsuccessful) */ /* Grab the keyboard, letting it room all over */ status = XGrabKeyboard(dpy, /* Display */ root_win, /* grab_window */ False, /* owner_events */ GrabModeAsync, /* pointer_mode */ GrabModeAsync, /* keyboard_mode */ CurrentTime); /* time, when grab took place */ if (status != GrabSuccess) { /* "Can't grab the keyboard" */ SetMessage(global_screen_data.info_label, res_labels[37], "Can't grab the keyboard"); return(None); } /* if (grab of keyboard unsuccessful) */ /* Let the user select a window... */ while ( (target_win == None) || (buttons != 0) ) { /* printf("targetwin: 0x%x, buttons: %d\n", target_win, buttons); */ /* allow one more event */ XAllowEvents(dpy, SyncPointer, CurrentTime); XtAppNextEvent(context, &event); switch (event.type) { case ButtonPress: /* printf("ButtonWindow 0x%x\n", event.xbutton.window); */ if (event.xbutton.window != root_win) { XtDispatchEvent(&event); break; } if (target_win == None) { target_win = event.xbutton.subwindow; /* window selected */ if (x != NULL) { *x = event.xbutton.x_root; } if (y != NULL) { *y = event.xbutton.y_root; } } buttons++; break; /* ButtonPress */ case ButtonRelease: if (event.xbutton.window != root_win) { XtDispatchEvent(&event); break; } if (buttons > 0) /* There may have been some */ { /* down before we started */ buttons--; } break; /* ButtonRelease */ case KeyPress: /* <Key>ESC aborts, <Key>Return + <Key>Spacebar select */ len = (XLookupString(&(event.xkey), buffer, sizeof(buffer), &keycode, (XComposeStatus*)NULL)); /* printf("keycode: 0x%x\n", keycode); */ switch (keycode) { case XK_Return: case XK_space: case XK_Select: case XK_KP_Space: case XK_KP_Enter: /* printf("Ret, space, Select, ...\n"); */ /* printf("KeyWindow 0x%x\n", event.xkey.window); */ /* if (event.xkey.window != root_win) */ /* { */ /* XtDispatchEvent(&event); */ /* break; */ /* } */ /* printf(" window root \n"); */ if (target_win == None) { /* printf(" subwindow 0x%x\n", event.xkey.subwindow); */ target_win = event.xkey.subwindow; /* window selected */ if (x != NULL) { *x = event.xkey.x_root; } if (y != NULL) { *y = event.xkey.y_root; } } break; /* XK_Return */ case XK_Escape: case XK_Cancel: case XK_Break: XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ XUngrabKeyboard(dpy, CurrentTime); /* Done with keyboard */ return ((Window)None); break; /* XK_Escape */ default: fprintf(stderr, "Unknown key! Press <ESC> to abort, <Return> to select\n"); break; } /* switch (keycode) */ break; /* KeyPress */ default: XtDispatchEvent(&event); break; /* default */ } /* switch (event.type) */ } /* while () */ /* If the XServer supports KeyRelease, we throw it away */ while ((event.type == KeyRelease) || (event.type == KeyPress)) { XtDispatchEvent(&event); } /* while (discard Keyboard-Events) */ XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ XUngrabKeyboard(dpy, CurrentTime); /* Done with keyboard */ /* printf("[GetClientWindow] target_win 0x%x, XmuClientWindow 0x%x\n", */ /* target_win, */ /* XmuClientWindow(dpy, target_win)); */ return (XmuClientWindow(dpy, target_win)); } /* GetClientWindow() */
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; }
void handle_event(XEvent *ev) { client *c = owner(ev->xany.window); #ifdef DEBUG_EVENTS if(ev->type != Expose && ev->type != MotionNotify && !(ev->type == ConfigureNotify && ev->xconfigure.window != root)) /* this makes the output slightly more manageable */ printf(NAME ": handle_event(): got %s\n\twindow: 0x%X (%s)\n", event_name(ev), (unsigned int) ev->xany.window, c ? c->name : ((ev->xany.window == root) ? "root" : "unknown")); #endif if((evh && evh(ev)) || button_handle_event(ev) || ewmh_handle_event(ev) || screens_handle_event(ev)) { #ifdef DEBUG_EVENTS if(ev->type != Expose && ev->type != MotionNotify && (ev->type != ConfigureNotify && ev->xconfigure.window != root)) printf(NAME ": handle_event(): external event handler claimed last event\n"); #endif return; } if(c) { if(!has_child(c->parent, c->window) && ev->type != DestroyNotify && ev->type != UnmapNotify) return; switch(ev->type) { case UnmapNotify: if(c->window == ev->xunmap.window) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling UnmapNotify event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif if(has_child(c->parent, c->window)) { client_deparent(c); set_wm_state(c->window, WithdrawnState); } client_remove(c); ewmh_update_clist(); } return; case PropertyNotify: if(ev->xproperty.atom == XA_WM_NAME) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling PropertyNotify event\n\twindow: 0x%X (%s)\n\tproperty: XA_WM_NAME\n", (unsigned int) c->window, c->name); #endif if(c->name != no_title) XFree(c->name); #ifdef USE_XFT if(xftfont) XftDrawDestroy(c->title_draw); #endif XFreePixmap(dpy, c->title_pixmap); XFetchName(dpy, c->window, &c->name); client_update_name(c); XClearWindow(dpy, c->title); if(evh == wlist_handle_event) { XClearWindow(dpy, c->wlist_item); wlist_item_draw(c); } } if(ev->xproperty.atom == XA_WM_NORMAL_HINTS) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling PropertyNotify event\n\twindow: 0x%X (%s)\n\tproperty: XA_WM_NORMAL_HINTS\n", (unsigned int) c->window, c->name); #endif get_normal_hints(c); } return; case ClientMessage: if(ev->xclient.message_type == xa_wm_change_state && ev->xclient.data.l[0] == IconicState) { #ifdef DEBUG_EVENTS printf(NAME ": handling ClientMessage event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif client_iconify(c); return; } break; /* we might later need this event */ case EnterNotify: if(c != current && !(c->flags & CLICK_FOCUS) && !click_focus && ev->xcrossing.mode != NotifyGrab && ev->xcrossing.mode != NotifyUngrab && ev->xcrossing.detail != NotifyInferior && (ev->xcrossing.window == c->parent || ev->xcrossing.window == c->wlist_item) && ev->xcrossing.send_event == False) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling EnterNotify event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif client_focus(c, true); } return; case Expose: if(ev->xexpose.count == 0 && evh == wlist_handle_event && c && ev->xexpose.window == c->wlist_item) wlist_item_draw(c); return; case ButtonPress: #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling ButtonPress event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif if(c != current) client_focus(c, true); XAllowEvents(dpy, ReplayPointer, CurrentTime); if(ev->xbutton.window != c->window) { if(lastclick + doubleclick_time > ev->xbutton.time && lastbutton == ev->xbutton.button && lastclick_client == c) { client_action(c, buttonaction(ev->xbutton.button, true), ev); lastclick = 0; lastclick_client = NULL; lastbutton = None; return; } lastclick = ev->xbutton.time; lastclick_client = c; lastbutton = ev->xbutton.button; client_action(c, buttonaction(ev->xbutton.button, false), ev); } else if(click_raise) client_raise(c); return; case FocusIn: /* we ignore pointer events, these happen if the input focus is on the root window */ if(allow_focus_stealing && c != current && ev->xfocus.mode != NotifyGrab && ev->xfocus.mode != NotifyUngrab && ev->xfocus.detail != NotifyPointer) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling FocusIn event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif client_focus(c, false); } return; case FocusOut: if(c == current && ev->xfocus.mode != NotifyGrab && ev->xfocus.mode != NotifyUngrab && ev->xfocus.detail != NotifyInferior) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling FocusOut event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif if(allow_focus_stealing && ev->xfocus.detail != NotifyAncestor) { #ifdef DEBUG_EVENTS printf("\tfocus lost\n"); #endif client_focus(NULL, false); /* we do this so windows that aren't managed can take focus */ } else { #ifdef DEBUG_EVENTS printf("\tre-focussing this window\n"); #endif take_focus(c); } } return; #ifdef USE_SHAPE default: if(ev->type == shape_event) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling ShapeNotify event\n\twindow 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif set_shape(c); return; } #endif } } switch(ev->type) { case MapRequest: c = owner(ev->xmaprequest.window); #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling MapRequest event\n\twindow: 0x%X (%s)\n", (unsigned int) ev->xmaprequest.window, c ? c->name : "unknown"); #endif if(c) { if(c->flags & ICONIC && has_child(c->parent, c->window)) { client_restore(c); if(focus_new) client_focus(c, true); } } else if(has_child(root, ev->xmaprequest.window)) client_add(ev->xmaprequest.window, false); return; case DestroyNotify: c = owner(ev->xdestroywindow.window); if(c) if(c->window == ev->xdestroywindow.window) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling DestroyNotify event\n\twindow 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif client_remove(c); } return; case ConfigureRequest: c = owner(ev->xconfigurerequest.window); #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling ConfigureRequest event\n\twindow 0x%X (%s)\n", (unsigned int) ev->xconfigurerequest.window, c ? c->name : "unknown"); #endif if(correct_center) screens_correct_center(&ev->xconfigurerequest.x, &ev->xconfigurerequest.y, &ev->xconfigurerequest.width, &ev->xconfigurerequest.height); if(c) { if(!has_child(c->parent, c->window)) return; if(ev->xconfigurerequest.value_mask & CWX) c->x = ev->xconfigurerequest.x - gxo(c, false); if(ev->xconfigurerequest.value_mask & CWY) c->y = ev->xconfigurerequest.y - gyo(c, false); if(ev->xconfigurerequest.value_mask & CWWidth) c->width = ev->xconfigurerequest.width; if(ev->xconfigurerequest.value_mask & CWHeight) c->height = ev->xconfigurerequest.height; client_update(c); #ifdef DEBUG printf(NAME ": handle_event(): reconfigured client 0x%X (%s) to %ix%i+%i+%i\n", (unsigned int) c->window, c->name, c->width, c->height, c->x, c->y); #endif } else if(has_child(root, ev->xconfigurerequest.window)) { XWindowChanges wc; wc.sibling = ev->xconfigurerequest.above; wc.stack_mode = ev->xconfigurerequest.detail; wc.x = ev->xconfigurerequest.x; wc.y = ev->xconfigurerequest.y; wc.width = ev->xconfigurerequest.width; wc.height = ev->xconfigurerequest.height; XConfigureWindow(dpy, ev->xconfigurerequest.window, ev->xconfigurerequest.value_mask, &wc); } return; case MapNotify: if(correct_center_unmanaged && ev->xany.window == root && !owner(ev->xmap.window)) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling MapNotify event\n\twindow 0x%X (unknown)\n", (unsigned int) ev->xmap.window); #endif window_correct_center(ev->xmap.window); } return; case MappingNotify: if(ev->xmapping.request != MappingPointer) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling MappingNotify event\n"); #endif keys_ungrab(); XRefreshKeyboardMapping(&ev->xmapping); keys_update(); } return; case KeyPress: #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling KeyPress event\n"); #endif client_action(current, keyaction(ev), ev); return; case ButtonPress: if(ev->xbutton.window != root) return; #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling ButtonPress event\n"); #endif if(lastclick + doubleclick_time > ev->xbutton.time && lastbutton == ev->xbutton.button && lastclick_client == NULL) { client_action(current, root_buttonaction(ev->xbutton.button, true), ev); lastclick = 0; lastclick_client = NULL; lastbutton = None; return; } lastclick = ev->xbutton.time; lastclick_client = NULL; lastbutton = ev->xbutton.button; client_action(current, root_buttonaction(ev->xbutton.button, false), ev); return; case ClientMessage: if(ev->xclient.message_type == xa_internal_message) { if(((Atom) ev->xclient.data.l[0]) == xa_quit) { #ifdef DEBUG printf(NAME ": handle_event(): quit message received\n"); #endif exit(0); } if(((Atom) ev->xclient.data.l[0]) == xa_reinit) { #ifdef DEBUG printf(NAME ": handle_event(): reinitialize message received\n"); #endif cfg_reinitialize(); } } } }