1 #ifndef YWINDOW_H
2 #define YWINDOW_H
3 
4 #include "ypaint.h"
5 #include "yarray.h"
6 #include "ylist.h"
7 #include "yrect.h"
8 #include "logevent.h"
9 
10 class YPopupWindow;
11 class YToolTip;
12 class YTimer;
13 class YAutoScroll;
14 class YRect;
15 class YRect2;
16 
17 struct DesktopScreenInfo {
18     int screen_number;
19     int x_org;
20     int y_org;
21     unsigned width;
22     unsigned height;
23 
DesktopScreenInfoDesktopScreenInfo24     DesktopScreenInfo(int i, int x, int y, unsigned w, unsigned h) :
25         screen_number(i), x_org(x), y_org(y), width(w), height(h)
26     { }
YRectDesktopScreenInfo27     operator YRect() const {
28         return YRect(x_org, y_org, width, height);
29     }
horizontalDesktopScreenInfo30     unsigned horizontal() const {
31         return width + unsigned(x_org);
32     }
verticalDesktopScreenInfo33     unsigned vertical() const {
34         return height + unsigned(y_org);
35     }
horizontalCoverageDesktopScreenInfo36     int horizontalCoverage(int x, unsigned w) {
37         return intersection(x, x + int(w), x_org, x_org + int(width));
38     }
verticalCoverageDesktopScreenInfo39     int verticalCoverage(int y, unsigned h) {
40         return intersection(y, y + int(h), y_org, y_org + int(height));
41     }
coverageDesktopScreenInfo42     long coverage(int x, int y, unsigned w, unsigned h) {
43         return (1L + horizontalCoverage(x, w))
44              * (1L + verticalCoverage(y, h));
45     }
46 };
47 
48 class YWindow : protected YWindowList, private YWindowNode {
49 public:
50     YWindow(YWindow *aParent = nullptr,
51             Window window = None,
52             int depth = CopyFromParent,
53             Visual *visual = nullptr,
54             Colormap colormap = CopyFromParent);
55     virtual ~YWindow();
56 
57     void setStyle(unsigned aStyle);
addStyle(unsigned aStyle)58     void addStyle(unsigned aStyle) { setStyle(fStyle | aStyle); }
getStyle()59     unsigned getStyle() const { return fStyle; }
getEventMask()60     long getEventMask() const { return fEventMask; }
61     void addEventMask(long mask);
62 
63     void setVisible(bool enable);
64     void show();
65     void hide();
66     virtual void raise();
67     virtual void lower();
68 
69     virtual void repaint();
70     virtual void repaintFocus();
71 
72     void readAttributes();
73     void reparent(YWindow *parent, int x, int y);
74     bool getWindowAttributes(XWindowAttributes* attr);
75     void beneath(YWindow* superior);
76     void raiseTo(YWindow* inferior);
77     void setWindowFocus(Time timestamp = CurrentTime);
78 
79     bool fetchTitle(char** title);
80     void setTitle(char const * title);
81     void setClassHint(char const * rName, char const * rClass);
82 
83     void setGeometry(const YRect &r);
84     void setSize(unsigned width, unsigned height);
85     void setPosition(int x, int y);
86     void setBorderWidth(unsigned width);
87     void setBackground(unsigned long pixel);
88     void setBackgroundPixmap(ref<YPixmap> pixmap);
89     void setBackgroundPixmap(Pixmap pixmap);
90     void setParentRelative();
91     virtual void configure(const YRect &r);
92     virtual void configure(const YRect2& r2);
93 
94     virtual void paint(Graphics &g, const YRect &r);
95 
96     virtual void handleEvent(const XEvent &event);
97 
98     virtual void handleExpose(const XExposeEvent &expose);
99     virtual void handleGraphicsExpose(const XGraphicsExposeEvent &graphicsExpose);
100     virtual void handleConfigure(const XConfigureEvent &configure);
101     virtual bool handleKey(const XKeyEvent &key);
102     virtual void handleButton(const XButtonEvent &button);
103     virtual void handleMotion(const XMotionEvent &motion);
104     virtual void handleCrossing(const XCrossingEvent &crossing);
handleProperty(const XPropertyEvent &)105     virtual void handleProperty(const XPropertyEvent &) {}
handleColormap(const XColormapEvent &)106     virtual void handleColormap(const XColormapEvent &) {}
107     virtual void handleFocus(const XFocusChangeEvent &);
108     virtual void handleClientMessage(const XClientMessageEvent &message);
109     virtual void handleSelectionClear(const XSelectionClearEvent &clear);
110     virtual void handleSelectionRequest(const XSelectionRequestEvent &request);
111     virtual void handleSelection(const XSelectionEvent &selection);
112     virtual void handleVisibility(const XVisibilityEvent &visibility);
113     virtual void handleGravityNotify(const XGravityEvent &gravity);
114     virtual void handleMapNotify(const XMapEvent &map);
115     virtual void handleUnmapNotify(const XUnmapEvent &unmap);
116     virtual void handleUnmap(const XUnmapEvent &unmap);
117     virtual void handleDestroyWindow(const XDestroyWindowEvent &destroyWindow);
handleReparentNotify(const XReparentEvent &)118     virtual void handleReparentNotify(const XReparentEvent &) {}
119     virtual void handleConfigureRequest(const XConfigureRequestEvent &);
120     virtual void handleMapRequest(const XMapRequestEvent &);
handleDamageNotify(const XDamageNotifyEvent &)121     virtual void handleDamageNotify(const XDamageNotifyEvent &) {}
122 #ifdef CONFIG_SHAPE
handleShapeNotify(const XShapeEvent &)123     virtual void handleShapeNotify(const XShapeEvent &) {}
124 #endif
125 #ifdef CONFIG_XRANDR
handleRRScreenChangeNotify(const XRRScreenChangeNotifyEvent &)126     virtual void handleRRScreenChangeNotify(const XRRScreenChangeNotifyEvent &) {}
handleRRNotify(const XRRNotifyEvent &)127     virtual void handleRRNotify(const XRRNotifyEvent &) {}
128 #endif
129 
handleClickDown(const XButtonEvent &,int)130     virtual void handleClickDown(const XButtonEvent &, int) {}
handleClick(const XButtonEvent &,int)131     virtual void handleClick(const XButtonEvent &, int) {}
132     virtual bool handleBeginDrag(const XButtonEvent &, const XMotionEvent &);
handleDrag(const XButtonEvent &,const XMotionEvent &)133     virtual void handleDrag(const XButtonEvent &, const XMotionEvent &) {}
handleEndDrag(const XButtonEvent &,const XButtonEvent &)134     virtual void handleEndDrag(const XButtonEvent &, const XButtonEvent &) {}
135 
136     virtual void handleClose();
137 
138     virtual bool handleAutoScroll(const XMotionEvent &mouse);
139     void beginAutoScroll(bool autoScroll, const XMotionEvent *motion);
140 
141     void setPointer(Cursor pointer);
142     void grabKeyM(int key, unsigned modifiers);
143     void grabKey(int key, unsigned modifiers);
144     void grabVKey(int key, unsigned vmodifiers);
145     unsigned VMod(unsigned modifiers);
146     void grabButtonM(int button, unsigned modifiers);
147     void grabButton(int button, unsigned modifiers);
148     void grabVButton(int button, unsigned vmodifiers);
149 
150     void captureEvents();
151     void releaseEvents();
152 
handle()153     Window handle() { return (flags & wfCreated) ? fHandle : create(); }
parent()154     YWindow *parent() const { return fParentWindow; }
window()155     YWindow *window() { return this; }
156 
157     void paintExpose(int ex, int ey, int ew, int eh);
158 
159     Graphics& getGraphics();
getGradient()160     virtual ref<YImage> getGradient() {
161         return (parent() ? parent()->getGradient() : null); }
162 
x()163     int x() const { return fX; }
y()164     int y() const { return fY; }
width()165     unsigned width() const { return fWidth; }
height()166     unsigned height() const { return fHeight; }
depth()167     unsigned depth() const { return fDepth; }
visual()168     Visual *visual() const { return fVisual; }
169     Colormap colormap();
geometry()170     YRect geometry() const { return YRect(fX, fY, fWidth, fHeight); }
dimension()171     YDimension dimension() const { return YDimension(fWidth, fHeight); }
172 
visible()173     bool visible() const { return (flags & wfVisible); }
created()174     bool created() const { return (flags & wfCreated); }
adopted()175     bool adopted() const { return (flags & wfAdopted); }
focused()176     bool focused() const { return (flags & wfFocused); }
destroyed()177     bool destroyed() const { return (flags & wfDestroyed); }
178     void setDestroyed();
179     bool testDestroyed();
180 
181     virtual void donePopup(YPopupWindow * /*command*/);
182 
183     enum WindowStyle {
184         wsOverrideRedirect = 1 << 0,
185         wsSaveUnder        = 1 << 1,
186         wsManager          = 1 << 2,
187         wsInputOnly        = 1 << 3,
188         wsNoExpose         = 1 << 4,
189         wsPointerMotion    = 1 << 5,
190         wsDesktopAware     = 1 << 6,
191         wsToolTip          = 1 << 7,
192         wsBackingMapped    = 1 << 8,
193         wsToolTipping      = 1 << 9,
194         wsTakeFocus        = 1 << 10,
195     };
196 
197     virtual bool isFocusTraversable();
isFocused()198     bool isFocused() const { return focused(); }
199     void nextFocus();
200     void prevFocus();
201     bool changeFocus(bool next);
202     virtual void requestFocus(bool requestUserFocus);
203     void setFocus(YWindow *window);
204     YWindow *getFocusWindow();
205     virtual void gotFocus();
206     virtual void lostFocus();
207 
isToplevel()208     bool isToplevel() const { return hasbit(flags, wfToplevel); }
209     void setToplevel(bool toplevel);
210 
211     YWindow *toplevel();
212 
213     void installAccelerator(unsigned key, unsigned mod, YWindow *win);
214     void removeAccelerator(unsigned key, unsigned mod, YWindow *win);
215 
216     mstring getToolTip();
217     void setToolTip(const mstring &tip);
218 
219     void mapToGlobal(int &x, int &y);
220     void mapToLocal(int &x, int &y);
221 
222     void setWinGravity(int gravity);
223     void setBitGravity(int gravity);
224 
225     void deleteProperty(Atom property);
226     void setProperty(Atom prop, Atom type, const Atom* values, int count);
227     void setProperty(Atom property, Atom propType, Atom value);
228     void setNetName(const char* name);
229     void setNetWindowType(Atom window_type);
230     void setNetOpacity(Atom opacity);
231     void setNetPid();
232 
233     virtual void handleDNDEnter();
234     virtual void handleDNDLeave();
235     virtual void handleDNDPosition(int x, int y);
236 
237     bool getCharFromEvent(const XKeyEvent &key, char *s, int maxLen);
dragging()238     bool dragging() const { return fClickDrag && fClickWindow == this; }
getClickCount()239     int getClickCount() { return fClickCount; }
240     int getScreen();
241 
242     void scrollWindow(int dx, int dy);
243     void clearWindow();
244     void clearArea(int x, int y, unsigned w, unsigned h, bool expos = false);
245     Pixmap createPixmap();
246     XRenderPictFormat* format();
247     Picture createPicture();
248 
249     bool toolTipVisible();
250     void toolTipVisibility(bool visible);
251     virtual void updateToolTip();
252 
253     void acquireSelection(bool selection);
254     void clearSelection(bool selection);
255     void requestSelection(bool selection);
256 
257     bool hasPopup();
258 
259     KeySym keyCodeToKeySym(unsigned keycode, unsigned index = 0);
260     static unsigned long getLastEnterNotifySerial();
261 
unmanageWindow()262     void unmanageWindow() { removeWindow(); }
263 
264 private:
265     enum WindowFlags {
266         wfVisible   = 1 << 0,
267         wfCreated   = 1 << 1,
268         wfAdopted   = 1 << 2,
269         wfDestroyed = 1 << 3,
270         wfToplevel  = 1 << 4,
271         wfNullSize  = 1 << 5,
272         wfFocused   = 1 << 6,
273     };
274 
275     Window create();
276     void adopt();
277     void destroy();
278 
279     void insertWindow();
280     void removeWindow();
281 
282     bool nullGeometry();
283 
284     unsigned fDepth;
285     Visual *fVisual;
286     Colormap fColormap;
287 
288     YWindow *fParentWindow;
289     YWindow *fFocusedWindow;
290 
291     Window fHandle;
292     unsigned flags;
293     unsigned fStyle;
294     int fX, fY;
295     unsigned fWidth, fHeight;
296     int unmapCount;
297     Cursor fPointer;
298     Graphics *fGraphics;
299     long fEventMask;
300     int fWinGravity, fBitGravity;
301 
302     struct YAccelerator {
303         unsigned key;
304         unsigned mod;
305         YWindow *win;
306         YAccelerator *next;
307     };
308 
309     YAccelerator *accel;
310     lazy<YToolTip> fToolTip;
311 
312     static XButtonEvent fClickEvent;
313     static YWindow *fClickWindow;
314     static Time fClickTime;
315     static int fClickCount;
316     static bool fClickDrag;
317     static unsigned fClickButton;
318     static unsigned fClickButtonDown;
319     static unsigned long lastEnterNotifySerial;
320     static void updateEnterNotifySerial(const XEvent& event);
321 
322     static YAutoScroll *fAutoScroll;
323 
addIgnoreUnmap()324     void addIgnoreUnmap()       { ++unmapCount; }
ignoreUnmap()325     bool ignoreUnmap()          { return (0 < unmapCount) && unmapCount--; }
removeAllIgnoreUnmap()326     void removeAllIgnoreUnmap() { unmapCount = 0; }
327 };
328 
329 class YDndWindow : public YWindow {
330 protected:
331     YDndWindow(YWindow* parent = nullptr, Window win = 0, int depth = 0,
332                Visual* visual = nullptr, Colormap colormap = 0);
333     void setDND(bool enabled = true);
334 
335     void handleClientMessage(const XClientMessageEvent& message) override;
336 
337 private:
338     void sendXdndStatus(bool acceptDrop = false, Atom dropAction = None);
339     void handleXdndEnter(const XClientMessageEvent& message);
340     void handleXdndLeave(const XClientMessageEvent& message);
341     void handleXdndPosition(const XClientMessageEvent& message);
342     void handleXdndStatus(const XClientMessageEvent& message);
343     void handleXdndDrop(const XClientMessageEvent& message);
344     void handleXdndFinished(const XClientMessageEvent& message);
345 
346     Window XdndDragSource;
347     Window XdndDropTarget;
348 
349     enum { XdndCurrentVersion = 5, };
350 };
351 
352 class YDesktop: public YWindow {
353 public:
354     YDesktop(YWindow *aParent = nullptr, Window win = 0);
355     virtual ~YDesktop();
356 
357     bool updateXineramaInfo(unsigned& horizontal, unsigned& vertical);
358 
359     const DesktopScreenInfo& getScreenInfo(int screen_no = -1);
360     YRect getScreenGeometry(int screen_no = -1);
361     void getScreenGeometry(int *x, int *y,
362                            unsigned *width, unsigned *height,
363                            int screen_no = -1);
364     int getScreenForRect(int x, int y, unsigned width, unsigned height);
365 
getScreenCount()366     int getScreenCount() const { return xiInfo.getCount(); }
367 
grabKeys()368     virtual void grabKeys() {}
kbLayout()369     virtual void kbLayout() {}
370 
371 protected:
372     YArray<DesktopScreenInfo> xiInfo;
373 };
374 
375 extern YDesktop *desktop;
376 
377 struct YExtension {
378     int eventBase, errorBase;
379     int versionMajor, versionMinor;
380     Bool parameter;
381     bool supported;
382 
383     typedef int (*QueryFunc)(Display *, int *, int *);
384     void init(Display* dis, QueryFunc ext, QueryFunc ver);
385 
386     typedef Bool (*ExistFunc)(Display *);
387     typedef Bool (*ParamFunc)(Display *, int *, int *, Bool *);
388     void init(Display* dis, ExistFunc ext, ParamFunc ver);
389 
isEventYExtension390     bool isEvent(int type, int eventNumber) const {
391         return supported && type == eventBase + eventNumber;
392     }
393 };
394 
395 extern YExtension composite;
396 extern YExtension damage;
397 extern YExtension fixes;
398 extern YExtension render;
399 extern YExtension shapes;
400 extern YExtension xrandr;
401 extern YExtension xinerama;
402 extern YExtension xshm;
403 
404 extern Atom _XA_WM_CHANGE_STATE;
405 extern Atom _XA_WM_CLASS;
406 extern Atom _XA_WM_CLIENT_LEADER;
407 extern Atom _XA_WM_COLORMAP_NOTIFY;
408 extern Atom _XA_WM_COLORMAP_WINDOWS;
409 extern Atom _XA_WM_COMMAND;
410 extern Atom _XA_WM_DELETE_WINDOW;
411 extern Atom _XA_WM_DESKTOP;
412 extern Atom _XA_WM_HINTS;
413 extern Atom _XA_WM_ICON_NAME;
414 extern Atom _XA_WM_ICON_SIZE;
415 extern Atom _XA_WM_LOCALE_NAME;
416 extern Atom _XA_WM_NAME;
417 extern Atom _XA_WM_NORMAL_HINTS;
418 extern Atom _XA_WM_PROTOCOLS;
419 extern Atom _XA_WM_SIZE_HINTS;
420 extern Atom _XA_WM_STATE;
421 extern Atom _XA_WM_TAKE_FOCUS;
422 extern Atom _XA_WM_TRANSIENT_FOR;
423 extern Atom _XA_WM_ZOOM_HINTS;
424 
425 extern Atom _XATOM_MWM_HINTS;
426 extern Atom _XA_WINDOW_ROLE;
427 extern Atom _XA_SM_CLIENT_ID;
428 extern Atom _XA_CLIPBOARD;
429 extern Atom _XA_MANAGER;
430 extern Atom _XA_TARGETS;
431 extern Atom _XA_XEMBED;
432 extern Atom _XA_XEMBED_INFO;
433 extern Atom _XA_UTF8_STRING;
434 
435 /* Xdnd */
436 extern Atom XA_XdndAware;
437 extern Atom XA_XdndEnter;
438 extern Atom XA_XdndLeave;
439 extern Atom XA_XdndPosition;
440 extern Atom XA_XdndProxy;
441 extern Atom XA_XdndStatus;
442 extern Atom XA_XdndDrop;
443 extern Atom XA_XdndFinished;
444 extern Atom XA_XdndActionCopy;
445 extern Atom XA_XdndActionMove;
446 extern Atom XA_XdndActionLink;
447 extern Atom XA_XdndActionAsk;
448 extern Atom XA_XdndActionPrivate;
449 
450 extern Atom _XA_KDE_NET_SYSTEM_TRAY_WINDOWS;
451 extern Atom _XA_NET_SYSTEM_TRAY_OPCODE;
452 extern Atom _XA_NET_SYSTEM_TRAY_ORIENTATION;
453 extern Atom _XA_NET_SYSTEM_TRAY_MESSAGE_DATA;
454 extern Atom _XA_NET_SYSTEM_TRAY_VISUAL;
455 extern Atom _XA_NET_WM_NAME;
456 extern Atom _XA_NET_WM_PID;
457 extern Atom _XA_NET_WM_WINDOW_OPACITY;              // OK
458 extern Atom _XA_NET_WM_WINDOW_TYPE;                 // OK
459 extern Atom _XA_NET_WM_WINDOW_TYPE_COMBO;           // OK
460 extern Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP;         // OK
461 extern Atom _XA_NET_WM_WINDOW_TYPE_DIALOG;          // OK
462 extern Atom _XA_NET_WM_WINDOW_TYPE_DND;             // OK
463 extern Atom _XA_NET_WM_WINDOW_TYPE_DOCK;            // OK
464 extern Atom _XA_NET_WM_WINDOW_TYPE_DROPDOWN_MENU;   // OK
465 extern Atom _XA_NET_WM_WINDOW_TYPE_MENU;            // OK
466 extern Atom _XA_NET_WM_WINDOW_TYPE_NORMAL;          // OK
467 extern Atom _XA_NET_WM_WINDOW_TYPE_NOTIFICATION;    // OK
468 extern Atom _XA_NET_WM_WINDOW_TYPE_POPUP_MENU;      // OK
469 extern Atom _XA_NET_WM_WINDOW_TYPE_SPLASH;          // OK
470 extern Atom _XA_NET_WM_WINDOW_TYPE_TOOLBAR;         // OK
471 extern Atom _XA_NET_WM_WINDOW_TYPE_TOOLTIP;         // OK
472 extern Atom _XA_NET_WM_WINDOW_TYPE_UTILITY;         // OK
473 
474 #endif
475 
476 // vim: set sw=4 ts=4 et:
477