/[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 963 by astrand, Wed Aug 3 10:56:16 2005 UTC sourceforge.net/branches/seamlessrdp-branch/rdesktop/ewmhints.c revision 1141 by ossman_, Thu Mar 16 08:09:41 2006 UTC
# Line 2  Line 2 
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) Peter Astrand <peter@cendio.se> 2003     Copyright (C) Peter Astrand <astrand@cendio.se> 2005
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 22  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    
34    static Atom g_net_wm_state_maximized_vert_atom, g_net_wm_state_maximized_horz_atom,
35            g_net_wm_state_hidden_atom, g_net_wm_name_atom, g_utf8_string_atom,
36            g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom;
37    
38    Atom g_net_wm_state_atom, g_net_wm_desktop_atom;
39    
40  /*  /*
41     Get window property value (32 bit format)     Get window property value (32 bit format)
42     Returns zero on success, -1 on error     Returns zero on success, -1 on error
43  */  */
44  static int  static int
45  get_property_value(char *propname, long max_length,  get_property_value(Window wnd, char *propname, long max_length,
46                     unsigned long *nitems_return, unsigned char **prop_return)                     unsigned long *nitems_return, unsigned char **prop_return)
47  {  {
48          int result;          int result;
# Line 47  get_property_value(char *propname, long Line 58  get_property_value(char *propname, long
58                  return (-1);                  return (-1);
59          }          }
60    
61          result = XGetWindowProperty(g_display, DefaultRootWindow(g_display), property, 0,       /* long_offset */          result = XGetWindowProperty(g_display, wnd, property, 0,        /* long_offset */
62                                      max_length, /* long_length */                                      max_length, /* long_length */
63                                      False,      /* delete */                                      False,      /* delete */
64                                      AnyPropertyType,    /* req_type */                                      AnyPropertyType,    /* req_type */
# Line 63  get_property_value(char *propname, long Line 74  get_property_value(char *propname, long
74    
75          if (actual_type_return == None || actual_format_return == 0)          if (actual_type_return == None || actual_format_return == 0)
76          {          {
77                  fprintf(stderr, "Root window is missing property %s\n", propname);                  fprintf(stderr, "Window is missing property %s\n", propname);
78                  return (-1);                  return (-1);
79          }          }
80    
# Line 93  get_current_desktop(void) Line 104  get_current_desktop(void)
104          unsigned char *prop_return;          unsigned char *prop_return;
105          int current_desktop;          int current_desktop;
106    
107          if (get_property_value("_NET_CURRENT_DESKTOP", 1, &nitems_return, &prop_return) < 0)          if (get_property_value
108                (DefaultRootWindow(g_display), "_NET_CURRENT_DESKTOP", 1, &nitems_return,
109                 &prop_return) < 0)
110                  return (-1);                  return (-1);
111    
112          if (nitems_return != 1)          if (nitems_return != 1)
# Line 125  get_current_workarea(uint32 * x, uint32 Line 138  get_current_workarea(uint32 * x, uint32
138          const uint32 net_workarea_height_offset = 3;          const uint32 net_workarea_height_offset = 3;
139          const uint32 max_prop_length = 32 * 4;  /* Max 32 desktops */          const uint32 max_prop_length = 32 * 4;  /* Max 32 desktops */
140    
141          if (get_property_value("_NET_WORKAREA", max_prop_length, &nitems_return, &prop_return) < 0)          if (get_property_value
142                (DefaultRootWindow(g_display), "_NET_WORKAREA", max_prop_length, &nitems_return,
143                 &prop_return) < 0)
144                  return (-1);                  return (-1);
145    
146          if (nitems_return % 4)          if (nitems_return % 4)
# Line 151  get_current_workarea(uint32 * x, uint32 Line 166  get_current_workarea(uint32 * x, uint32
166          return (0);          return (0);
167    
168  }  }
169    
170    
171    
172    void
173    ewmh_init()
174    {
175            /* FIXME: Use XInternAtoms */
176            g_net_wm_state_maximized_vert_atom =
177                    XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
178            g_net_wm_state_maximized_horz_atom =
179                    XInternAtom(g_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
180            g_net_wm_state_hidden_atom = XInternAtom(g_display, "_NET_WM_STATE_HIDDEN", False);
181            g_net_wm_state_skip_taskbar_atom =
182                    XInternAtom(g_display, "_NET_WM_STATE_SKIP_TASKBAR", False);
183            g_net_wm_state_skip_pager_atom = XInternAtom(g_display, "_NET_WM_STATE_SKIP_PAGER", False);
184            g_net_wm_state_atom = XInternAtom(g_display, "_NET_WM_STATE", False);
185            g_net_wm_desktop_atom = XInternAtom(g_display, "_NET_WM_DESKTOP", False);
186            g_net_wm_name_atom = XInternAtom(g_display, "_NET_WM_NAME", False);
187            g_utf8_string_atom = XInternAtom(g_display, "UTF8_STRING", False);
188    }
189    
190    
191    /*
192       Get the window state: normal/minimized/maximized.
193    */
194    #ifndef MAKE_PROTO
195    int
196    ewmh_get_window_state(Window w)
197    {
198            unsigned long nitems_return;
199            unsigned char *prop_return;
200            uint32 *return_words;
201            unsigned long item;
202            BOOL maximized_vert, maximized_horz, hidden;
203    
204            maximized_vert = maximized_horz = hidden = False;
205    
206            if (get_property_value(w, "_NET_WM_STATE", 64, &nitems_return, &prop_return) < 0)
207                    return SEAMLESSRDP_NORMAL;
208    
209            return_words = (uint32 *) prop_return;
210    
211            for (item = 0; item < nitems_return; item++)
212            {
213                    if (return_words[item] == g_net_wm_state_maximized_vert_atom)
214                            maximized_vert = True;
215                    if (return_words[item] == g_net_wm_state_maximized_horz_atom)
216                            maximized_horz = True;
217                    if (return_words[item] == g_net_wm_state_hidden_atom)
218                            hidden = True;
219            }
220    
221            XFree(prop_return);
222    
223            if (maximized_vert && maximized_horz)
224                    return SEAMLESSRDP_MAXIMIZED;
225            else if (hidden)
226                    return SEAMLESSRDP_MINIMIZED;
227            else
228                    return SEAMLESSRDP_NORMAL;
229    }
230    
231    /*
232       Set the window state: normal/minimized/maximized.
233       Returns -1 on failure.
234    */
235    int
236    ewmh_change_state(Window wnd, int state)
237    {
238            Status status;
239            XEvent xevent;
240    
241            /*
242             * Deal with the max atoms
243             */
244            xevent.type = ClientMessage;
245            xevent.xclient.window = wnd;
246            xevent.xclient.message_type = g_net_wm_state_atom;
247            xevent.xclient.format = 32;
248            if (state == SEAMLESSRDP_MAXIMIZED)
249                    xevent.xclient.data.l[0] = _NET_WM_STATE_ADD;
250            else
251                    xevent.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
252            xevent.xclient.data.l[1] = g_net_wm_state_maximized_vert_atom;
253            xevent.xclient.data.l[2] = g_net_wm_state_maximized_horz_atom;
254            xevent.xclient.data.l[3] = 0;
255            xevent.xclient.data.l[4] = 0;
256            status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
257                                SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
258            if (!status)
259                    return -1;
260    
261            return 0;
262    }
263    
264    
265    int
266    ewmh_get_window_desktop(Window wnd)
267    {
268            unsigned long nitems_return;
269            unsigned char *prop_return;
270            int desktop;
271    
272            if (get_property_value(wnd, "_NET_WM_DESKTOP", 1, &nitems_return, &prop_return) < 0)
273                    return (-1);
274    
275            if (nitems_return != 1)
276            {
277                    fprintf(stderr, "_NET_WM_DESKTOP has bad length\n");
278                    return (-1);
279            }
280    
281            desktop = *prop_return;
282            XFree(prop_return);
283            return desktop;
284    }
285    
286    
287    int
288    ewmh_move_to_desktop(Window wnd, unsigned int desktop)
289    {
290            Status status;
291            XEvent xevent;
292    
293            xevent.type = ClientMessage;
294            xevent.xclient.window = wnd;
295            xevent.xclient.message_type = g_net_wm_desktop_atom;
296            xevent.xclient.format = 32;
297            xevent.xclient.data.l[0] = desktop;
298            xevent.xclient.data.l[1] = 0;
299            xevent.xclient.data.l[2] = 0;
300            xevent.xclient.data.l[3] = 0;
301            xevent.xclient.data.l[4] = 0;
302            status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
303                                SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
304            if (!status)
305                    return -1;
306    
307            return 0;
308    }
309    
310    void
311    ewmh_set_wm_name(Window wnd, const char *title)
312    {
313            int len;
314    
315            len = strlen(title);
316            XChangeProperty(g_display, wnd, g_net_wm_name_atom, g_utf8_string_atom,
317                            8, PropModeReplace, (unsigned char *) title, len);
318    }
319    
320    
321    void
322    ewmh_set_window_popup(Window wnd)
323    {
324            Atom atoms[2] = { g_net_wm_state_skip_taskbar_atom, g_net_wm_state_skip_pager_atom };
325    
326            XChangeProperty(g_display, wnd, g_net_wm_state_atom, XA_ATOM, 32, PropModeAppend, atoms, 2);
327    }
328    
329    #endif /* MAKE_PROTO */
330    
331    
332    #if 0
333    
334    /* FIXME: _NET_MOVERESIZE_WINDOW is for pagers, not for
335       applications. We should implement _NET_WM_MOVERESIZE instead */
336    
337    int
338    ewmh_net_moveresize_window(Window wnd, int x, int y, int width, int height)
339    {
340            Status status;
341            XEvent xevent;
342            Atom moveresize;
343    
344            moveresize = XInternAtom(g_display, "_NET_MOVERESIZE_WINDOW", False);
345            if (!moveresize)
346            {
347                    return -1;
348            }
349    
350            xevent.type = ClientMessage;
351            xevent.xclient.window = wnd;
352            xevent.xclient.message_type = moveresize;
353            xevent.xclient.format = 32;
354            xevent.xclient.data.l[0] = StaticGravity | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11);
355            xevent.xclient.data.l[1] = x;
356            xevent.xclient.data.l[2] = y;
357            xevent.xclient.data.l[3] = width;
358            xevent.xclient.data.l[4] = height;
359    
360            status = XSendEvent(g_display, DefaultRootWindow(g_display), False,
361                                SubstructureNotifyMask | SubstructureRedirectMask, &xevent);
362            if (!status)
363                    return -1;
364            return 0;
365    }
366    
367    #endif

Legend:
Removed from v.963  
changed lines
  Added in v.1141

  ViewVC Help
Powered by ViewVC 1.1.26