/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/rdesktop/ewmhints.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/branches/seamlessrdp-branch/rdesktop/ewmhints.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

sourceforge.net/trunk/rdesktop/ewmhints.c revision 466 by astrand, Mon Sep 8 08:27:57 2003 UTC sourceforge.net/branches/seamlessrdp-branch/rdesktop/ewmhints.c revision 1137 by ossman_, Wed Mar 15 15:10:21 2006 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3    
4     Support functions for Extended Window Manager Hints,     Support functions for Extended Window Manager Hints,
5     http://www.freedesktop.org/standards/wm-spec.html     http://www.freedesktop.org/wiki/Standards_2fwm_2dspec
6    
7     Copyright (C) Matthew Chapman 1999-2002     Copyright (C) Peter Astrand <astrand@cendio.se> 2005
    Copyright (C) Peter Astrand <peter@cendio.se> 2003  
8        
9     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 23  Line 22 
22  */  */
23    
24  #include <X11/Xlib.h>  #include <X11/Xlib.h>
25    #include <X11/Xatom.h>
26  #include "rdesktop.h"  #include "rdesktop.h"
27    
28    #define _NET_WM_STATE_REMOVE        0   /* remove/unset property */
29    #define _NET_WM_STATE_ADD           1   /* add/set property */
30    #define _NET_WM_STATE_TOGGLE        2   /* toggle property  */
31    
32  extern Display *g_display;  extern Display *g_display;
33    static Atom g_net_wm_state_maximized_vert_atom, g_net_wm_state_maximized_horz_atom,
34            g_net_wm_state_hidden_atom, g_net_wm_state_skip_taskbar_atom,
35            g_net_wm_state_skip_pager_atom;
36    Atom g_net_wm_state_atom, g_net_wm_desktop_atom;
37    
38  /*  /*
39     Get window property value (32 bit format)     Get window property value (32 bit format)
40     Returns zero on success, -1 on error     Returns zero on success, -1 on error
41  */  */
42  static int  static int
43  get_property_value(char *propname, long max_length,  get_property_value(Window wnd, char *propname, long max_length,
44                     unsigned long *nitems_return, unsigned char **prop_return)                     unsigned long *nitems_return, unsigned char **prop_return)
45  {  {
46          int result;          int result;
# Line 48  get_property_value(char *propname, long Line 56  get_property_value(char *propname, long
56                  return (-1);                  return (-1);
57          }          }
58    
59          result = XGetWindowProperty(g_display, DefaultRootWindow(g_display), property, 0,       /* long_offset */          result = XGetWindowProperty(g_display, wnd, property, 0,        /* long_offset */
60                                      max_length, /* long_length */                                      max_length, /* long_length */
61                                      False,      /* delete */                                      False,      /* delete */
62                                      AnyPropertyType,    /* req_type */                                      AnyPropertyType,    /* req_type */
# Line 64  get_property_value(char *propname, long Line 72  get_property_value(char *propname, long
72    
73          if (actual_type_return == None || actual_format_return == 0)          if (actual_type_return == None || actual_format_return == 0)
74          {          {
75                  fprintf(stderr, "Root window is missing property %s\n", propname);                  fprintf(stderr, "Window is missing property %s\n", propname);
76                  return (-1);                  return (-1);
77          }          }
78    
# Line 94  get_current_desktop(void) Line 102  get_current_desktop(void)
102          unsigned char *prop_return;          unsigned char *prop_return;
103          int current_desktop;          int current_desktop;
104    
105          if (get_property_value("_NET_CURRENT_DESKTOP", 1, &nitems_return,          if (get_property_value
106                                 &prop_return) < 0)              (DefaultRootWindow(g_display), "_NET_CURRENT_DESKTOP", 1, &nitems_return,
107                 &prop_return) < 0)
108                  return (-1);                  return (-1);
109    
110          if (nitems_return != 1)          if (nitems_return != 1)
# Line 127  get_current_workarea(uint32 * x, uint32 Line 136  get_current_workarea(uint32 * x, uint32
136          const uint32 net_workarea_height_offset = 3;          const uint32 net_workarea_height_offset = 3;
137          const uint32 max_prop_length = 32 * 4;  /* Max 32 desktops */          const uint32 max_prop_length = 32 * 4;  /* Max 32 desktops */
138    
139          if (get_property_value("_NET_WORKAREA", max_prop_length, &nitems_return,          if (get_property_value
140                                 &prop_return) < 0)              (DefaultRootWindow(g_display), "_NET_WORKAREA", max_prop_length, &nitems_return,
141                 &prop_return) < 0)
142                  return (-1);                  return (-1);
143    
144          if (nitems_return % 4)          if (nitems_return % 4)
# Line 142  get_current_workarea(uint32 * x, uint32 Line 152  get_current_workarea(uint32 * x, uint32
152          if (current_desktop < 0)          if (current_desktop < 0)
153                  return -1;                  return -1;
154    
155          return_words = (uint32 *)prop_return;          return_words = (uint32 *) prop_return;
156    
157          *x = return_words[current_desktop * 4 + net_workarea_x_offset];          *x = return_words[current_desktop * 4 + net_workarea_x_offset];
158          *y = return_words[current_desktop * 4 + net_workarea_y_offset];          *y = return_words[current_desktop * 4 + net_workarea_y_offset];
# Line 154  get_current_workarea(uint32 * x, uint32 Line 164  get_current_workarea(uint32 * x, uint32
164          return (0);          return (0);
165    
166  }  }
167    
168    
169    
170    void
171    ewmh_init()
172    {
173            g_net_wm_state_maximized_vert_atom =
174                    XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
175            g_net_wm_state_maximized_horz_atom =
176                    XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
177            g_net_wm_state_hidden_atom = XInternAtom(g_display, "_NET_WM_STATE_HIDDEN", False);
178            g_net_wm_state_skip_taskbar_atom =
179                    XInternAtom(g_display, "_NET_WM_STATE_SKIP_TASKBAR", False);
180            g_net_wm_state_skip_pager_atom = XInternAtom(g_display, "_NET_WM_STATE_SKIP_PAGER", False);
181            g_net_wm_state_atom = XInternAtom(g_display, "_NET_WM_STATE", False);
182            g_net_wm_desktop_atom = XInternAtom(g_display, "_NET_WM_DESKTOP", False);
183    }
184    
185    
186    /*
187       Get the window state: normal/minimized/maximized.
188    */
189    #ifndef MAKE_PROTO
190    int
191    ewmh_get_window_state(Window w)
192    {
193            unsigned long nitems_return;
194            unsigned char *prop_return;
195            uint32 *return_words;
196            unsigned long item;
197            BOOL maximized_vert, maximized_horz, hidden;
198    
199            maximized_vert = maximized_horz = hidden = False;
200    
201            if (get_property_value(w, "_NET_WM_STATE", 64, &nitems_return, &prop_return) < 0)
202                    return SEAMLESSRDP_NORMAL;
203    
204            return_words = (uint32 *) prop_return;
205    
206            for (item = 0; item < nitems_return; item++)
207            {
208                    if (return_words[item] == g_net_wm_state_maximized_vert_atom)
209                            maximized_vert = True;
210                    if (return_words[item] == g_net_wm_state_maximized_horz_atom)
211                            maximized_horz = True;
212                    if (return_words[item] == g_net_wm_state_hidden_atom)
213                            hidden = True;
214            }
215    
216            XFree(prop_return);
217    
218            if (maximized_vert && maximized_horz)
219                    return SEAMLESSRDP_MAXIMIZED;
220            else if (hidden)
221                    return SEAMLESSRDP_MINIMIZED;
222            else
223                    return SEAMLESSRDP_NORMAL;
224    }
225    
226    /*
227       Set the window state: normal/minimized/maximized.
228       Returns -1 on failure.
229    */
230    int
231    ewmh_change_state(Window wnd, int state)
232    {
233            Status status;
234            XEvent xevent;
235    
236            /*
237             * Deal with the hidden atom
238             */
239            xevent.type = ClientMessage;
240            xevent.xclient.window = wnd;
241            xevent.xclient.message_type = g_net_wm_state_atom;
242            xevent.xclient.format = 32;
243            if (state == SEAMLESSRDP_MINIMIZED)
244                    xevent.xclient.data.l[0] = _NET_WM_STATE_ADD;
245            else
246                    xevent.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
247            xevent.xclient.data.l[1] = g_net_wm_state_hidden_atom;
248            xevent.xclient.data.l[2] = 0;
249            xevent.xclient.data.l[3] = 0;
250            xevent.xclient.data.l[4] = 0;
251            status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
252                                SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
253            if (!status)
254                    return -1;
255    
256    
257            /*
258             * Deal with the max atoms
259             */
260            xevent.type = ClientMessage;
261            xevent.xclient.window = wnd;
262            xevent.xclient.message_type = g_net_wm_state_atom;
263            xevent.xclient.format = 32;
264            if (state == SEAMLESSRDP_MAXIMIZED)
265                    xevent.xclient.data.l[0] = _NET_WM_STATE_ADD;
266            else
267                    xevent.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
268            xevent.xclient.data.l[1] = g_net_wm_state_maximized_vert_atom;
269            xevent.xclient.data.l[2] = g_net_wm_state_maximized_horz_atom;
270            xevent.xclient.data.l[3] = 0;
271            xevent.xclient.data.l[4] = 0;
272            status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
273                                SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
274            if (!status)
275                    return -1;
276    
277            return 0;
278    }
279    
280    
281    int
282    ewmh_get_window_desktop(Window wnd)
283    {
284            unsigned long nitems_return;
285            unsigned char *prop_return;
286            int desktop;
287    
288            if (get_property_value(wnd, "_NET_WM_DESKTOP", 1, &nitems_return, &prop_return) < 0)
289                    return (-1);
290    
291            if (nitems_return != 1)
292            {
293                    fprintf(stderr, "_NET_WM_DESKTOP has bad length\n");
294                    return (-1);
295            }
296    
297            desktop = *prop_return;
298            XFree(prop_return);
299            return desktop;
300    }
301    
302    
303    int
304    ewmh_move_to_desktop(Window wnd, unsigned int desktop)
305    {
306            Status status;
307            XEvent xevent;
308    
309            xevent.type = ClientMessage;
310            xevent.xclient.window = wnd;
311            xevent.xclient.message_type = g_net_wm_desktop_atom;
312            xevent.xclient.format = 32;
313            xevent.xclient.data.l[0] = desktop;
314            xevent.xclient.data.l[1] = 0;
315            xevent.xclient.data.l[2] = 0;
316            xevent.xclient.data.l[3] = 0;
317            xevent.xclient.data.l[4] = 0;
318            status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
319                                SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
320            if (!status)
321                    return -1;
322    
323            return 0;
324    }
325    
326    void
327    ewmh_set_window_popup(Window wnd)
328    {
329            Atom atoms[2] = { g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom };
330    
331            XChangeProperty(g_display, wnd, g_net_wm_state_atom, XA_ATOM, 32, PropModeAppend, atoms, 2);
332    }
333    
334    #endif /* MAKE_PROTO */
335    
336    
337    #if 0
338    
339    /* FIXME: _NET_MOVERESIZE_WINDOW is for pagers, not for
340       applications. We should implement _NET_WM_MOVERESIZE instead */
341    
342    int
343    ewmh_net_moveresize_window(Window wnd, int x, int y, int width, int height)
344    {
345            Status status;
346            XEvent xevent;
347            Atom moveresize;
348    
349            moveresize = XInternAtom(g_display, "_NET_MOVERESIZE_WINDOW", False);
350            if (!moveresize)
351            {
352                    return -1;
353            }
354    
355            xevent.type = ClientMessage;
356            xevent.xclient.window = wnd;
357            xevent.xclient.message_type = moveresize;
358            xevent.xclient.format = 32;
359            xevent.xclient.data.l[0] = StaticGravity | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11);
360            xevent.xclient.data.l[1] = x;
361            xevent.xclient.data.l[2] = y;
362            xevent.xclient.data.l[3] = width;
363            xevent.xclient.data.l[4] = height;
364    
365            status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
366                                SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
367            if (!status)
368                    return -1;
369            return 0;
370    }
371    
372    #endif

Legend:
Removed from v.466  
changed lines
  Added in v.1137

  ViewVC Help
Powered by ViewVC 1.1.26