1/* 2 * Various util-ish functions for event handling. 3 * 4 * Many, probably most, are internal to the event code, but a few are 5 * used elsewhere. 6 */ 7 8#include "ctwm.h" 9 10#include <stdio.h> 11 12#include "event_handlers.h" 13#include "event_internal.h" 14#include "events.h" 15#include "list.h" 16#include "otp.h" 17#include "screen.h" 18#include "vscreen.h" 19#include "win_iconify.h" 20#include "workspace_manager.h" 21 22 23static ScreenInfo *FindScreenInfo(Window w); 24 25 26void 27AutoRaiseWindow(TwmWindow *tmp) 28{ 29 OtpRaise(tmp, WinWin); 30 31 if(ActiveMenu && ActiveMenu->w) { 32 XRaiseWindow(dpy, ActiveMenu->w); 33 } 34 XSync(dpy, 0); 35 enter_win = NULL; 36 enter_flag = true; 37 raise_win = tmp; 38 WMapRaise(tmp); 39} 40 41void 42SetRaiseWindow(TwmWindow *tmp) 43{ 44 enter_flag = true; 45 enter_win = NULL; 46 raise_win = tmp; 47 leave_win = NULL; 48 leave_flag = false; 49 lower_win = NULL; 50 XSync(dpy, 0); 51} 52 53void 54AutoPopupMaybe(TwmWindow *tmp) 55{ 56 if(LookInList(Scr->AutoPopupL, tmp->name, &tmp->class) 57 || Scr->AutoPopup) { 58 if(OCCUPY(tmp, Scr->currentvs->wsw->currentwspc)) { 59 if(!tmp->mapped) { 60 DeIconify(tmp); 61 SetRaiseWindow(tmp); 62 } 63 } 64 else { 65 tmp->mapped = true; 66 } 67 } 68} 69 70void 71AutoLowerWindow(TwmWindow *tmp) 72{ 73 OtpLower(tmp, WinWin); 74 75 if(ActiveMenu && ActiveMenu->w) { 76 XRaiseWindow(dpy, ActiveMenu->w); 77 } 78 XSync(dpy, 0); 79 enter_win = NULL; 80 enter_flag = false; 81 raise_win = NULL; 82 leave_win = NULL; 83 leave_flag = true; 84 lower_win = tmp; 85 WMapLower(tmp); 86} 87 88 89/* 90 * WindowOfEvent - return the window about which this event is concerned; this 91 * window may not be the same as XEvent.xany.window (the first window listed 92 * in the structure). 93 */ 94Window 95WindowOfEvent(XEvent *e) 96{ 97 /* 98 * Each window subfield is marked with whether or not it is the same as 99 * XEvent.xany.window or is different (which is the case for some of the 100 * notify events). 101 */ 102 switch(e->type) { 103 case KeyPress: 104 case KeyRelease: 105 return e->xkey.window; /* same */ 106 case ButtonPress: 107 case ButtonRelease: 108 return e->xbutton.window; /* same */ 109 case MotionNotify: 110 return e->xmotion.window; /* same */ 111 case EnterNotify: 112 case LeaveNotify: 113 return e->xcrossing.window; /* same */ 114 case FocusIn: 115 case FocusOut: 116 return e->xfocus.window; /* same */ 117 case KeymapNotify: 118 return e->xkeymap.window; /* same */ 119 case Expose: 120 return e->xexpose.window; /* same */ 121 case GraphicsExpose: 122 return e->xgraphicsexpose.drawable; /* same */ 123 case NoExpose: 124 return e->xnoexpose.drawable; /* same */ 125 case VisibilityNotify: 126 return e->xvisibility.window; /* same */ 127 case CreateNotify: 128 return e->xcreatewindow.window; /* DIFF */ 129 case DestroyNotify: 130 return e->xdestroywindow.window; /* DIFF */ 131 case UnmapNotify: 132 return e->xunmap.window; /* DIFF */ 133 case MapNotify: 134 return e->xmap.window; /* DIFF */ 135 case MapRequest: 136 return e->xmaprequest.window; /* DIFF */ 137 case ReparentNotify: 138 return e->xreparent.window; /* DIFF */ 139 case ConfigureNotify: 140 return e->xconfigure.window; /* DIFF */ 141 case ConfigureRequest: 142 return e->xconfigurerequest.window; /* DIFF */ 143 case GravityNotify: 144 return e->xgravity.window; /* DIFF */ 145 case ResizeRequest: 146 return e->xresizerequest.window; /* same */ 147 case CirculateNotify: 148 return e->xcirculate.window; /* DIFF */ 149 case CirculateRequest: 150 return e->xcirculaterequest.window; /* DIFF */ 151 case PropertyNotify: 152 return e->xproperty.window; /* same */ 153 case SelectionClear: 154 return e->xselectionclear.window; /* same */ 155 case SelectionRequest: 156 return e->xselectionrequest.requestor; /* DIFF */ 157 case SelectionNotify: 158 return e->xselection.requestor; /* same */ 159 case ColormapNotify: 160 return e->xcolormap.window; /* same */ 161 case ClientMessage: 162 return e->xclient.window; /* same */ 163 case MappingNotify: 164 return None; 165 } 166 return None; 167} 168 169 170void 171FixRootEvent(XEvent *e) 172{ 173 if(Scr->Root == Scr->RealRoot) { 174 return; 175 } 176 177 switch(e->type) { 178 case KeyPress: 179 case KeyRelease: 180 e->xkey.x_root -= Scr->rootx; 181 e->xkey.y_root -= Scr->rooty; 182 e->xkey.root = Scr->Root; 183 break; 184 case ButtonPress: 185 case ButtonRelease: 186 e->xbutton.x_root -= Scr->rootx; 187 e->xbutton.y_root -= Scr->rooty; 188 e->xbutton.root = Scr->Root; 189 break; 190 case MotionNotify: 191 e->xmotion.x_root -= Scr->rootx; 192 e->xmotion.y_root -= Scr->rooty; 193 e->xmotion.root = Scr->Root; 194 break; 195 case EnterNotify: 196 case LeaveNotify: 197 e->xcrossing.x_root -= Scr->rootx; 198 e->xcrossing.y_root -= Scr->rooty; 199 e->xcrossing.root = Scr->Root; 200 break; 201 default: 202 break; 203 } 204} 205 206 207/* Move this next to GetTwmWindow()? */ 208ScreenInfo * 209GetTwmScreen(XEvent *event) 210{ 211 ScreenInfo *scr; 212 213 if(XFindContext(dpy, event->xany.window, ScreenContext, 214 (XPointer *)&scr) == XCNOENT) { 215 scr = FindScreenInfo(WindowOfEvent(event)); 216 } 217 218 return scr; 219} 220 221 222/*********************************************************************** 223 * 224 * Procedure: 225 * FindScreenInfo - get ScreenInfo struct associated with a given window 226 * 227 * Returned Value: 228 * ScreenInfo struct 229 * 230 * Inputs: 231 * w - the window 232 * 233 *********************************************************************** 234 */ 235static ScreenInfo * 236FindScreenInfo(Window w) 237{ 238 XWindowAttributes attr; 239 int scrnum; 240 241 attr.screen = NULL; 242 if(XGetWindowAttributes(dpy, w, &attr)) { 243 for(scrnum = 0; scrnum < NumScreens; scrnum++) { 244 if(ScreenList[scrnum] != NULL && 245 (ScreenOfDisplay(dpy, ScreenList[scrnum]->screen) == 246 attr.screen)) { 247 return ScreenList[scrnum]; 248 } 249 } 250 } 251 252 return NULL; 253} 254 255 256void 257SynthesiseFocusOut(Window w) 258{ 259 XEvent event; 260 261#ifdef TRACE_FOCUS 262 fprintf(stderr, "Synthesizing FocusOut on %x\n", w); 263#endif 264 265 event.type = FocusOut; 266 event.xfocus.window = w; 267 event.xfocus.mode = NotifyNormal; 268 event.xfocus.detail = NotifyPointer; 269 270 XPutBackEvent(dpy, &event); 271} 272 273 274void 275SynthesiseFocusIn(Window w) 276{ 277 XEvent event; 278 279#ifdef TRACE_FOCUS 280 fprintf(stderr, "Synthesizing FocusIn on %x\n", w); 281#endif 282 283 event.type = FocusIn; 284 event.xfocus.window = w; 285 event.xfocus.mode = NotifyNormal; 286 event.xfocus.detail = NotifyPointer; 287 288 XPutBackEvent(dpy, &event); 289 290} 291 292 293/* 294 * This is actually never called anywhere in event code, but it digs into 295 * the innards of events to do somewhat scary things. 296 */ 297void 298SimulateMapRequest(Window w) 299{ 300 Event.xmaprequest.window = w; 301 HandleMapRequest(); 302} 303