10bbfda8aSnia/* 20bbfda8aSnia * Various util-ish functions for event handling. 30bbfda8aSnia * 40bbfda8aSnia * Many, probably most, are internal to the event code, but a few are 50bbfda8aSnia * used elsewhere. 60bbfda8aSnia */ 70bbfda8aSnia 80bbfda8aSnia#include "ctwm.h" 90bbfda8aSnia 100bbfda8aSnia#include <stdio.h> 110bbfda8aSnia 120bbfda8aSnia#include "event_handlers.h" 130bbfda8aSnia#include "event_internal.h" 140bbfda8aSnia#include "events.h" 150bbfda8aSnia#include "list.h" 160bbfda8aSnia#include "otp.h" 170bbfda8aSnia#include "screen.h" 180bbfda8aSnia#include "vscreen.h" 190bbfda8aSnia#include "win_iconify.h" 200bbfda8aSnia#include "workspace_manager.h" 210bbfda8aSnia 220bbfda8aSnia 230bbfda8aSniastatic ScreenInfo *FindScreenInfo(Window w); 240bbfda8aSnia 250bbfda8aSnia 260bbfda8aSniavoid 270bbfda8aSniaAutoRaiseWindow(TwmWindow *tmp) 280bbfda8aSnia{ 290bbfda8aSnia OtpRaise(tmp, WinWin); 300bbfda8aSnia 310bbfda8aSnia if(ActiveMenu && ActiveMenu->w) { 320bbfda8aSnia XRaiseWindow(dpy, ActiveMenu->w); 330bbfda8aSnia } 340bbfda8aSnia XSync(dpy, 0); 350bbfda8aSnia enter_win = NULL; 360bbfda8aSnia enter_flag = true; 370bbfda8aSnia raise_win = tmp; 380bbfda8aSnia WMapRaise(tmp); 390bbfda8aSnia} 400bbfda8aSnia 410bbfda8aSniavoid 420bbfda8aSniaSetRaiseWindow(TwmWindow *tmp) 430bbfda8aSnia{ 440bbfda8aSnia enter_flag = true; 450bbfda8aSnia enter_win = NULL; 460bbfda8aSnia raise_win = tmp; 470bbfda8aSnia leave_win = NULL; 480bbfda8aSnia leave_flag = false; 490bbfda8aSnia lower_win = NULL; 500bbfda8aSnia XSync(dpy, 0); 510bbfda8aSnia} 520bbfda8aSnia 530bbfda8aSniavoid 540bbfda8aSniaAutoPopupMaybe(TwmWindow *tmp) 550bbfda8aSnia{ 560bbfda8aSnia if(LookInList(Scr->AutoPopupL, tmp->name, &tmp->class) 570bbfda8aSnia || Scr->AutoPopup) { 580bbfda8aSnia if(OCCUPY(tmp, Scr->currentvs->wsw->currentwspc)) { 590bbfda8aSnia if(!tmp->mapped) { 600bbfda8aSnia DeIconify(tmp); 610bbfda8aSnia SetRaiseWindow(tmp); 620bbfda8aSnia } 630bbfda8aSnia } 640bbfda8aSnia else { 650bbfda8aSnia tmp->mapped = true; 660bbfda8aSnia } 670bbfda8aSnia } 680bbfda8aSnia} 690bbfda8aSnia 700bbfda8aSniavoid 710bbfda8aSniaAutoLowerWindow(TwmWindow *tmp) 720bbfda8aSnia{ 730bbfda8aSnia OtpLower(tmp, WinWin); 740bbfda8aSnia 750bbfda8aSnia if(ActiveMenu && ActiveMenu->w) { 760bbfda8aSnia XRaiseWindow(dpy, ActiveMenu->w); 770bbfda8aSnia } 780bbfda8aSnia XSync(dpy, 0); 790bbfda8aSnia enter_win = NULL; 800bbfda8aSnia enter_flag = false; 810bbfda8aSnia raise_win = NULL; 820bbfda8aSnia leave_win = NULL; 830bbfda8aSnia leave_flag = true; 840bbfda8aSnia lower_win = tmp; 850bbfda8aSnia WMapLower(tmp); 860bbfda8aSnia} 870bbfda8aSnia 880bbfda8aSnia 890bbfda8aSnia/* 900bbfda8aSnia * WindowOfEvent - return the window about which this event is concerned; this 910bbfda8aSnia * window may not be the same as XEvent.xany.window (the first window listed 920bbfda8aSnia * in the structure). 930bbfda8aSnia */ 940bbfda8aSniaWindow 950bbfda8aSniaWindowOfEvent(XEvent *e) 960bbfda8aSnia{ 970bbfda8aSnia /* 980bbfda8aSnia * Each window subfield is marked with whether or not it is the same as 990bbfda8aSnia * XEvent.xany.window or is different (which is the case for some of the 1000bbfda8aSnia * notify events). 1010bbfda8aSnia */ 1020bbfda8aSnia switch(e->type) { 1030bbfda8aSnia case KeyPress: 1040bbfda8aSnia case KeyRelease: 1050bbfda8aSnia return e->xkey.window; /* same */ 1060bbfda8aSnia case ButtonPress: 1070bbfda8aSnia case ButtonRelease: 1080bbfda8aSnia return e->xbutton.window; /* same */ 1090bbfda8aSnia case MotionNotify: 1100bbfda8aSnia return e->xmotion.window; /* same */ 1110bbfda8aSnia case EnterNotify: 1120bbfda8aSnia case LeaveNotify: 1130bbfda8aSnia return e->xcrossing.window; /* same */ 1140bbfda8aSnia case FocusIn: 1150bbfda8aSnia case FocusOut: 1160bbfda8aSnia return e->xfocus.window; /* same */ 1170bbfda8aSnia case KeymapNotify: 1180bbfda8aSnia return e->xkeymap.window; /* same */ 1190bbfda8aSnia case Expose: 1200bbfda8aSnia return e->xexpose.window; /* same */ 1210bbfda8aSnia case GraphicsExpose: 1220bbfda8aSnia return e->xgraphicsexpose.drawable; /* same */ 1230bbfda8aSnia case NoExpose: 1240bbfda8aSnia return e->xnoexpose.drawable; /* same */ 1250bbfda8aSnia case VisibilityNotify: 1260bbfda8aSnia return e->xvisibility.window; /* same */ 1270bbfda8aSnia case CreateNotify: 1280bbfda8aSnia return e->xcreatewindow.window; /* DIFF */ 1290bbfda8aSnia case DestroyNotify: 1300bbfda8aSnia return e->xdestroywindow.window; /* DIFF */ 1310bbfda8aSnia case UnmapNotify: 1320bbfda8aSnia return e->xunmap.window; /* DIFF */ 1330bbfda8aSnia case MapNotify: 1340bbfda8aSnia return e->xmap.window; /* DIFF */ 1350bbfda8aSnia case MapRequest: 1360bbfda8aSnia return e->xmaprequest.window; /* DIFF */ 1370bbfda8aSnia case ReparentNotify: 1380bbfda8aSnia return e->xreparent.window; /* DIFF */ 1390bbfda8aSnia case ConfigureNotify: 1400bbfda8aSnia return e->xconfigure.window; /* DIFF */ 1410bbfda8aSnia case ConfigureRequest: 1420bbfda8aSnia return e->xconfigurerequest.window; /* DIFF */ 1430bbfda8aSnia case GravityNotify: 1440bbfda8aSnia return e->xgravity.window; /* DIFF */ 1450bbfda8aSnia case ResizeRequest: 1460bbfda8aSnia return e->xresizerequest.window; /* same */ 1470bbfda8aSnia case CirculateNotify: 1480bbfda8aSnia return e->xcirculate.window; /* DIFF */ 1490bbfda8aSnia case CirculateRequest: 1500bbfda8aSnia return e->xcirculaterequest.window; /* DIFF */ 1510bbfda8aSnia case PropertyNotify: 1520bbfda8aSnia return e->xproperty.window; /* same */ 1530bbfda8aSnia case SelectionClear: 1540bbfda8aSnia return e->xselectionclear.window; /* same */ 1550bbfda8aSnia case SelectionRequest: 1560bbfda8aSnia return e->xselectionrequest.requestor; /* DIFF */ 1570bbfda8aSnia case SelectionNotify: 1580bbfda8aSnia return e->xselection.requestor; /* same */ 1590bbfda8aSnia case ColormapNotify: 1600bbfda8aSnia return e->xcolormap.window; /* same */ 1610bbfda8aSnia case ClientMessage: 1620bbfda8aSnia return e->xclient.window; /* same */ 1630bbfda8aSnia case MappingNotify: 1640bbfda8aSnia return None; 1650bbfda8aSnia } 1660bbfda8aSnia return None; 1670bbfda8aSnia} 1680bbfda8aSnia 1690bbfda8aSnia 1700bbfda8aSniavoid 1710bbfda8aSniaFixRootEvent(XEvent *e) 1720bbfda8aSnia{ 1730bbfda8aSnia if(Scr->Root == Scr->RealRoot) { 1740bbfda8aSnia return; 1750bbfda8aSnia } 1760bbfda8aSnia 1770bbfda8aSnia switch(e->type) { 1780bbfda8aSnia case KeyPress: 1790bbfda8aSnia case KeyRelease: 1800bbfda8aSnia e->xkey.x_root -= Scr->rootx; 1810bbfda8aSnia e->xkey.y_root -= Scr->rooty; 1820bbfda8aSnia e->xkey.root = Scr->Root; 1830bbfda8aSnia break; 1840bbfda8aSnia case ButtonPress: 1850bbfda8aSnia case ButtonRelease: 1860bbfda8aSnia e->xbutton.x_root -= Scr->rootx; 1870bbfda8aSnia e->xbutton.y_root -= Scr->rooty; 1880bbfda8aSnia e->xbutton.root = Scr->Root; 1890bbfda8aSnia break; 1900bbfda8aSnia case MotionNotify: 1910bbfda8aSnia e->xmotion.x_root -= Scr->rootx; 1920bbfda8aSnia e->xmotion.y_root -= Scr->rooty; 1930bbfda8aSnia e->xmotion.root = Scr->Root; 1940bbfda8aSnia break; 1950bbfda8aSnia case EnterNotify: 1960bbfda8aSnia case LeaveNotify: 1970bbfda8aSnia e->xcrossing.x_root -= Scr->rootx; 1980bbfda8aSnia e->xcrossing.y_root -= Scr->rooty; 1990bbfda8aSnia e->xcrossing.root = Scr->Root; 2000bbfda8aSnia break; 2010bbfda8aSnia default: 2020bbfda8aSnia break; 2030bbfda8aSnia } 2040bbfda8aSnia} 2050bbfda8aSnia 2060bbfda8aSnia 2070bbfda8aSnia/* Move this next to GetTwmWindow()? */ 2080bbfda8aSniaScreenInfo * 2090bbfda8aSniaGetTwmScreen(XEvent *event) 2100bbfda8aSnia{ 2110bbfda8aSnia ScreenInfo *scr; 2120bbfda8aSnia 2130bbfda8aSnia if(XFindContext(dpy, event->xany.window, ScreenContext, 2140bbfda8aSnia (XPointer *)&scr) == XCNOENT) { 2150bbfda8aSnia scr = FindScreenInfo(WindowOfEvent(event)); 2160bbfda8aSnia } 2170bbfda8aSnia 2180bbfda8aSnia return scr; 2190bbfda8aSnia} 2200bbfda8aSnia 2210bbfda8aSnia 2220bbfda8aSnia/*********************************************************************** 2230bbfda8aSnia * 2240bbfda8aSnia * Procedure: 2250bbfda8aSnia * FindScreenInfo - get ScreenInfo struct associated with a given window 2260bbfda8aSnia * 2270bbfda8aSnia * Returned Value: 2280bbfda8aSnia * ScreenInfo struct 2290bbfda8aSnia * 2300bbfda8aSnia * Inputs: 2310bbfda8aSnia * w - the window 2320bbfda8aSnia * 2330bbfda8aSnia *********************************************************************** 2340bbfda8aSnia */ 2350bbfda8aSniastatic ScreenInfo * 2360bbfda8aSniaFindScreenInfo(Window w) 2370bbfda8aSnia{ 2380bbfda8aSnia XWindowAttributes attr; 2390bbfda8aSnia int scrnum; 2400bbfda8aSnia 2410bbfda8aSnia attr.screen = NULL; 2420bbfda8aSnia if(XGetWindowAttributes(dpy, w, &attr)) { 2430bbfda8aSnia for(scrnum = 0; scrnum < NumScreens; scrnum++) { 2440bbfda8aSnia if(ScreenList[scrnum] != NULL && 2450bbfda8aSnia (ScreenOfDisplay(dpy, ScreenList[scrnum]->screen) == 2460bbfda8aSnia attr.screen)) { 2470bbfda8aSnia return ScreenList[scrnum]; 2480bbfda8aSnia } 2490bbfda8aSnia } 2500bbfda8aSnia } 2510bbfda8aSnia 2520bbfda8aSnia return NULL; 2530bbfda8aSnia} 2540bbfda8aSnia 2550bbfda8aSnia 2560bbfda8aSniavoid 2570bbfda8aSniaSynthesiseFocusOut(Window w) 2580bbfda8aSnia{ 2590bbfda8aSnia XEvent event; 2600bbfda8aSnia 2610bbfda8aSnia#ifdef TRACE_FOCUS 2620bbfda8aSnia fprintf(stderr, "Synthesizing FocusOut on %x\n", w); 2630bbfda8aSnia#endif 2640bbfda8aSnia 2650bbfda8aSnia event.type = FocusOut; 2660bbfda8aSnia event.xfocus.window = w; 2670bbfda8aSnia event.xfocus.mode = NotifyNormal; 2680bbfda8aSnia event.xfocus.detail = NotifyPointer; 2690bbfda8aSnia 2700bbfda8aSnia XPutBackEvent(dpy, &event); 2710bbfda8aSnia} 2720bbfda8aSnia 2730bbfda8aSnia 2740bbfda8aSniavoid 2750bbfda8aSniaSynthesiseFocusIn(Window w) 2760bbfda8aSnia{ 2770bbfda8aSnia XEvent event; 2780bbfda8aSnia 2790bbfda8aSnia#ifdef TRACE_FOCUS 2800bbfda8aSnia fprintf(stderr, "Synthesizing FocusIn on %x\n", w); 2810bbfda8aSnia#endif 2820bbfda8aSnia 2830bbfda8aSnia event.type = FocusIn; 2840bbfda8aSnia event.xfocus.window = w; 2850bbfda8aSnia event.xfocus.mode = NotifyNormal; 2860bbfda8aSnia event.xfocus.detail = NotifyPointer; 2870bbfda8aSnia 2880bbfda8aSnia XPutBackEvent(dpy, &event); 2890bbfda8aSnia 2900bbfda8aSnia} 2910bbfda8aSnia 2920bbfda8aSnia 2930bbfda8aSnia/* 2940bbfda8aSnia * This is actually never called anywhere in event code, but it digs into 2950bbfda8aSnia * the innards of events to do somewhat scary things. 2960bbfda8aSnia */ 2970bbfda8aSniavoid 2980bbfda8aSniaSimulateMapRequest(Window w) 2990bbfda8aSnia{ 3000bbfda8aSnia Event.xmaprequest.window = w; 3010bbfda8aSnia HandleMapRequest(); 3020bbfda8aSnia} 303