1 /*      $Id$
2 
3         This program is free software; you can redistribute it and/or modify
4         it under the terms of the GNU General Public License as published by
5         the Free Software Foundation; either version 2, or (at your option)
6         any later version.
7 
8         This program is distributed in the hope that it will be useful,
9         but WITHOUT ANY WARRANTY; without even the implied warranty of
10         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11         GNU General Public License for more details.
12 
13         You should have received a copy of the GNU General Public License
14         along with this program; if not, write to the Free Software
15         Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
16         MA 02110-1301, USA.
17 
18 
19         xfwm4    - (c) 2002-2020 Olivier Fourdan
20 
21  */
22 
23 #ifndef INC_DISPLAY_H
24 #define INC_DISPLAY_H
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include <X11/X.h>
31 #include <X11/Xlib.h>
32 #include <X11/Xutil.h>
33 #include <X11/cursorfont.h>
34 #include <X11/extensions/shape.h>
35 
36 #ifndef ShapeInput
37 #define ShapeInput 2
38 #endif
39 
40 #ifdef HAVE_RANDR
41 #include <X11/extensions/Xrandr.h>
42 #endif /* HAVE_RANDR */
43 
44 #ifdef HAVE_XSYNC
45 #include <X11/extensions/sync.h>
46 #endif /* HAVE_XSYNC */
47 
48 #ifdef HAVE_COMPOSITOR
49 #include <X11/extensions/Xcomposite.h>
50 #include <X11/extensions/Xdamage.h>
51 #include <X11/extensions/Xrender.h>
52 #if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2
53 #ifndef HAVE_NAME_WINDOW_PIXMAP
54 #define HAVE_NAME_WINDOW_PIXMAP 1
55 #endif /* HAVE_NAME_WINDOW_PIXMAP */
56 #endif /* COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 2 */
57 #if COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 3
58 #ifndef HAVE_OVERLAYS
59 #define HAVE_OVERLAYS 1
60 #endif /* HAVE_OVERLAYS */
61 #endif /* COMPOSITE_MAJOR > 0 || COMPOSITE_MINOR >= 3 */
62 #endif /* HAVE_COMPOSITOR */
63 
64 #include <gtk/gtk.h>
65 #include <glib.h>
66 #include <libxfce4ui/libxfce4ui.h>
67 
68 #include "event_filter.h"
69 
70 /*
71  * The following macro is taken straight from metacity,
72  * if that needs some explanation, please refer to metacity's
73  * display.h source where it is explaned
74  */
75 #define TIMESTAMP_IS_BEFORE_REAL(time1, time2)  (((time1 < time2) && (time2 - time1 < (G_MAXUINT32 >> 1))) || \
76                                                  ((time1 > time2) && (time1 - time2 > (G_MAXUINT32 >> 1))))
77 #define TIMESTAMP_IS_BEFORE(time1, time2)       ((time1 == 0) ||                                                    \
78                                                 (TIMESTAMP_IS_BEFORE_REAL(time1, time2) &&                          \
79                                                 (time2 != 0)))
80 
81 enum
82 {
83     SEARCH_WINDOW         = (1 << 0),
84     SEARCH_FRAME          = (1 << 1),
85     SEARCH_BUTTON         = (1 << 2),
86     SEARCH_WIN_USER_TIME  = (1 << 3)
87 };
88 
89 enum
90 {
91     TITLE_1 = 0,
92     TITLE_2,
93     TITLE_3,
94     TITLE_4,
95     TITLE_5,
96     TITLE_COUNT
97 };
98 
99 enum
100 {
101     CORNER_BOTTOM_LEFT = 0,
102     CORNER_BOTTOM_RIGHT,
103     CORNER_TOP_LEFT,
104     CORNER_TOP_RIGHT,
105     CORNER_COUNT
106 };
107 
108 enum
109 {
110     SIDE_LEFT = 0,
111     SIDE_RIGHT,
112     SIDE_TOP,
113     SIDE_BOTTOM,
114     SIDE_COUNT
115 };
116 #define NO_HANDLE -1
117 #define HANDLES_COUNT (CORNER_COUNT + SIDE_COUNT - 1)
118 
119 enum
120 {
121     MENU_BUTTON = 0,
122     STICK_BUTTON,
123     SHADE_BUTTON,
124     HIDE_BUTTON,
125     MAXIMIZE_BUTTON,
126     CLOSE_BUTTON,
127     TITLE_SEPARATOR,
128     BUTTON_STRING_COUNT
129 };
130 #define BUTTON_COUNT (BUTTON_STRING_COUNT - 1)
131 
132 enum
133 {
134     ACTIVE = 0,
135     INACTIVE,
136     PRELIGHT,
137     PRESSED,
138     T_ACTIVE,
139     T_INACTIVE,
140     T_PRELIGHT,
141     T_PRESSED,
142     STATE_COUNT
143 };
144 #define STATE_TOGGLED (STATE_COUNT / 2)
145 
146 enum
147 {
148     BUTTON_STATE_NORMAL = 0,
149     BUTTON_STATE_PRELIGHT,
150     BUTTON_STATE_PRESSED,
151     BUTTON_STATE_COUNT
152 };
153 
154 enum
155 {
156     NET_WM_MOVERESIZE_SIZE_TOPLEFT = 0,
157     NET_WM_MOVERESIZE_SIZE_TOP,
158     NET_WM_MOVERESIZE_SIZE_TOPRIGHT,
159     NET_WM_MOVERESIZE_SIZE_RIGHT,
160     NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
161     NET_WM_MOVERESIZE_SIZE_BOTTOM,
162     NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT,
163     NET_WM_MOVERESIZE_SIZE_LEFT,
164     NET_WM_MOVERESIZE_MOVE,
165     NET_WM_MOVERESIZE_SIZE_KEYBOARD,
166     NET_WM_MOVERESIZE_MOVE_KEYBOARD,
167     NET_WM_MOVERESIZE_CANCEL
168 };
169 
170 enum
171 {
172     COMPOSITING_MANAGER = 0,
173     GTK_FRAME_EXTENTS,
174     GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED,
175     GTK_SHOW_WINDOW_MENU,
176     KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
177     KWM_WIN_ICON,
178     MOTIF_WM_HINTS,
179     MOTIF_WM_INFO,
180     NET_ACTIVE_WINDOW,
181     NET_CLIENT_LIST,
182     NET_CLIENT_LIST_STACKING,
183     NET_CLOSE_WINDOW,
184     NET_CURRENT_DESKTOP,
185     NET_DESKTOP_GEOMETRY,
186     NET_DESKTOP_LAYOUT,
187     NET_DESKTOP_NAMES,
188     NET_DESKTOP_VIEWPORT,
189     NET_FRAME_EXTENTS,
190     NET_MOVERESIZE_WINDOW,
191     NET_NUMBER_OF_DESKTOPS,
192     NET_REQUEST_FRAME_EXTENTS,
193     NET_SHOWING_DESKTOP,
194     NET_STARTUP_ID,
195     NET_SUPPORTED,
196     NET_SUPPORTING_WM_CHECK,
197     NET_SYSTEM_TRAY_OPCODE,
198     NET_WM_ACTION_ABOVE,
199     NET_WM_ACTION_BELOW,
200     NET_WM_ACTION_CHANGE_DESKTOP,
201     NET_WM_ACTION_CLOSE,
202     NET_WM_ACTION_FULLSCREEN,
203     NET_WM_ACTION_MAXIMIZE_HORZ,
204     NET_WM_ACTION_MAXIMIZE_VERT,
205     NET_WM_ACTION_MINIMIZE,
206     NET_WM_ACTION_MOVE,
207     NET_WM_ACTION_RESIZE,
208     NET_WM_ACTION_SHADE,
209     NET_WM_ACTION_STICK,
210     NET_WM_ALLOWED_ACTIONS,
211     NET_WM_BYPASS_COMPOSITOR,
212     NET_WM_CONTEXT_HELP,
213     NET_WM_DESKTOP,
214     NET_WM_FULLSCREEN_MONITORS,
215     NET_WM_ICON,
216     NET_WM_ICON_GEOMETRY,
217     NET_WM_ICON_NAME,
218     NET_WM_MOVERESIZE,
219     NET_WM_NAME,
220     NET_WM_OPAQUE_REGION,
221     NET_WM_PID,
222     NET_WM_PING,
223     NET_WM_WINDOW_OPACITY,
224     NET_WM_WINDOW_OPACITY_LOCKED,
225     NET_WM_STATE,
226     NET_WM_STATE_ABOVE,
227     NET_WM_STATE_BELOW,
228     NET_WM_STATE_DEMANDS_ATTENTION,
229     NET_WM_STATE_FOCUSED,
230     NET_WM_STATE_FULLSCREEN,
231     NET_WM_STATE_HIDDEN,
232     NET_WM_STATE_MAXIMIZED_HORZ,
233     NET_WM_STATE_MAXIMIZED_VERT,
234     NET_WM_STATE_MODAL,
235     NET_WM_STATE_SHADED,
236     NET_WM_STATE_SKIP_PAGER,
237     NET_WM_STATE_SKIP_TASKBAR,
238     NET_WM_STATE_STICKY,
239     NET_WM_STRUT,
240     NET_WM_STRUT_PARTIAL,
241     NET_WM_SYNC_REQUEST,
242     NET_WM_SYNC_REQUEST_COUNTER,
243     NET_WM_USER_TIME,
244     NET_WM_USER_TIME_WINDOW,
245     NET_WM_WINDOW_TYPE,
246     NET_WM_WINDOW_TYPE_DESKTOP,
247     NET_WM_WINDOW_TYPE_DIALOG,
248     NET_WM_WINDOW_TYPE_DOCK,
249     NET_WM_WINDOW_TYPE_MENU,
250     NET_WM_WINDOW_TYPE_NORMAL,
251     NET_WM_WINDOW_TYPE_SPLASH,
252     NET_WM_WINDOW_TYPE_TOOLBAR,
253     NET_WM_WINDOW_TYPE_UTILITY,
254     NET_WM_WINDOW_TYPE_NOTIFICATION,
255     NET_WORKAREA,
256     MANAGER,
257     PIXMAP,
258     SM_CLIENT_ID,
259     UTF8_STRING,
260     WM_CHANGE_STATE,
261     WM_CLIENT_LEADER,
262     WM_CLIENT_MACHINE,
263     WM_COLORMAP_WINDOWS,
264     WM_DELETE_WINDOW,
265     WM_HINTS,
266     WM_PROTOCOLS,
267     WM_STATE,
268     WM_TAKE_FOCUS,
269     WM_TRANSIENT_FOR,
270     WM_WINDOW_ROLE,
271     XFWM4_COMPOSITING_MANAGER,
272     XFWM4_TIMESTAMP_PROP,
273     XROOTPMAP,
274     XSETROOT,
275     GTK_READ_RCFILES,
276     ATOM_COUNT
277 };
278 
279 typedef struct _Client            Client;
280 typedef struct _DisplayInfo       DisplayInfo;
281 typedef struct _xfwmPixmap        xfwmPixmap;
282 typedef struct _XfwmParams        XfwmParams;
283 typedef struct _ScreenInfo        ScreenInfo;
284 typedef struct _Settings          Settings;
285 
286 struct _DisplayInfo
287 {
288     GdkDisplay *gdisplay;
289     Display *dpy;
290 
291     XfceSMClient *session;
292     gboolean quit;
293     gboolean reload;
294 
295     Window timestamp_win;
296     Cursor busy_cursor;
297     Cursor move_cursor;
298     Cursor root_cursor;
299     Cursor resize_cursor[SIDE_COUNT + CORNER_COUNT];
300 
301     Atom atoms[ATOM_COUNT];
302 
303     eventFilterSetup *xfilter;
304     XfwmDevices *devices;
305     GSList *screens;
306     GSList *clients;
307 
308     gboolean have_shape;
309     gboolean have_render;
310     gboolean have_xrandr;
311     gboolean have_xsync;
312     gboolean have_xres;
313     gint shape_version;
314     gint shape_event_base;
315     gint double_click_time;
316     gint double_click_distance;
317     gint xgrabcount;
318     gint nb_screens;
319     gchar* hostname;
320 
321     guint32 current_time;
322     guint32 last_user_time;
323 
324     gboolean enable_compositor;
325 
326 #ifdef HAVE_RENDER
327     gint render_error_base;
328     gint render_event_base;
329 #endif /* HAVE_RENDER */
330 #ifdef HAVE_RANDR
331     gint xrandr_error_base;
332     gint xrandr_event_base;
333 #endif /* HAVE_RANDR */
334 #ifdef HAVE_XSYNC
335     gint xsync_event_base;
336     gint xsync_error_base;
337 #endif /* HAVE_XSYNC */
338 #ifdef HAVE_XRES
339     gint xres_event_base;
340     gint xres_error_base;
341 #endif /* HAVE_XRES */
342 #ifdef HAVE_COMPOSITOR
343     gint composite_error_base;
344     gint composite_event_base;
345     gint damage_error_base;
346     gint damage_event_base;
347     gint fixes_error_base;
348     gint fixes_event_base;
349 
350     gboolean have_composite;
351     gboolean have_damage;
352     gboolean have_fixes;
353 
354 #if HAVE_NAME_WINDOW_PIXMAP
355     gboolean have_name_window_pixmap;
356 #endif /* HAVE_NAME_WINDOW_PIXMAP */
357 
358 #if HAVE_OVERLAYS
359     gboolean have_overlays;
360 #endif /* HAVE_OVERLAYS */
361 
362 #ifdef HAVE_PRESENT_EXTENSION
363     gboolean have_present;
364     gint present_opcode;
365     gint present_error_base;
366     gint present_event_base;
367 #endif /* HAVE_PRESENT_EXTENSION */
368 
369 #endif /* HAVE_COMPOSITOR */
370 };
371 
372 DisplayInfo             *myDisplayInit                          (GdkDisplay *);
373 DisplayInfo             *myDisplayClose                         (DisplayInfo *);
374 DisplayInfo             *myDisplayGetDefault                    (void);
375 gboolean                 myDisplayHaveShape                     (DisplayInfo *);
376 gboolean                 myDisplayHaveShapeInput                (DisplayInfo *);
377 gboolean                 myDisplayHaveRender                    (DisplayInfo *);
378 void                     myDisplayCreateCursor                  (DisplayInfo *);
379 void                     myDisplayFreeCursor                    (DisplayInfo *);
380 Cursor                   myDisplayGetCursorBusy                 (DisplayInfo *);
381 Cursor                   myDisplayGetCursorMove                 (DisplayInfo *);
382 Cursor                   myDisplayGetCursorRoot                 (DisplayInfo *);
383 Cursor                   myDisplayGetCursorResize               (DisplayInfo *,
384                                                                  guint);
385 void                     myDisplayGrabServer                    (DisplayInfo *);
386 void                     myDisplayUngrabServer                  (DisplayInfo *);
387 void                     myDisplayAddClient                     (DisplayInfo *,
388                                                                  Client *);
389 void                     myDisplayRemoveClient                  (DisplayInfo *,
390                                                                  Client *);
391 Client                  *myDisplayGetClientFromWindow           (DisplayInfo *,
392                                                                  Window,
393                                                                  unsigned short);
394 void                     myDisplayAddScreen                     (DisplayInfo *,
395                                                                  ScreenInfo *);
396 void                     myDisplayRemoveScreen                  (DisplayInfo *,
397                                                                  ScreenInfo *);
398 ScreenInfo              *myDisplayGetScreenFromRoot             (DisplayInfo *,
399                                                                  Window);
400 ScreenInfo              *myDisplayGetScreenFromOutput           (DisplayInfo *,
401                                                                  Window);
402 ScreenInfo              *myDisplayGetScreenFromNum              (DisplayInfo *,
403                                                                  int);
404 Window                   myDisplayGetRootFromWindow             (DisplayInfo *,
405                                                                  Window w);
406 ScreenInfo              *myDisplayGetScreenFromWindow           (DisplayInfo *,
407                                                                  Window w);
408 #ifdef ENABLE_KDE_SYSTRAY_PROXY
409 ScreenInfo              *myDisplayGetScreenFromSystray          (DisplayInfo *,
410                                                                  Window);
411 #endif /* ENABLE_KDE_SYSTRAY_PROXY */
412 #ifdef HAVE_XSYNC
413 Client                  *myDisplayGetClientFromXSyncAlarm       (DisplayInfo *,
414                                                                  XSyncAlarm);
415 #endif /* HAVE_XSYNC */
416 ScreenInfo              *myDisplayGetDefaultScreen              (DisplayInfo *);
417 guint32                  myDisplayUpdateCurrentTime             (DisplayInfo *,
418                                                                  XfwmEvent *);
419 guint32                  myDisplayGetCurrentTime                (DisplayInfo *);
420 guint32                  myDisplayGetTime                       (DisplayInfo *,
421                                                                  guint32);
422 guint32                  myDisplayGetLastUserTime               (DisplayInfo *);
423 void                     myDisplaySetLastUserTime               (DisplayInfo *,
424                                                                  guint32);
425 void                     myDisplayUpdateLastUserTime            (DisplayInfo *,
426                                                                  guint32);
427 gboolean                 myDisplayTestXrender                   (DisplayInfo *,
428                                                                  gdouble);
429 void                     myDisplayErrorTrapPush                 (DisplayInfo *);
430 gint                     myDisplayErrorTrapPop                  (DisplayInfo *);
431 void                     myDisplayErrorTrapPopIgnored           (DisplayInfo *);
432 void                     myDisplayBeep                          (DisplayInfo *);
433 GdkKeymap               *myDisplayGetKeymap                     (DisplayInfo *);
434 #endif /* INC_DISPLAY_H */
435