rip the prop code i wrote in cwmcc out and make it all 64bit friendly (i think!)...
authorDana Jansens <danakj@orodu.net>
Mon, 14 Apr 2003 21:34:35 +0000 (21:34 +0000)
committerDana Jansens <danakj@orodu.net>
Mon, 14 Apr 2003 21:34:35 +0000 (21:34 +0000)
openbox/client.c
openbox/prop.c
openbox/prop.h
openbox/screen.c
openbox/screen.h
openbox/stacking.c

index 7f59d99..097ca12 100644 (file)
@@ -8,6 +8,7 @@
 #include "focus.h"
 #include "stacking.h"
 #include "dispatch.h"
+#include "openbox.h"
 #include "group.h"
 #include "config.h"
 
@@ -25,7 +26,7 @@ GList      *client_list      = NULL;
 GHashTable *client_map       = NULL;
 
 static Window *client_startup_stack_order = NULL;
-static gulong  client_startup_stack_size = 0;
+static guint  client_startup_stack_size = 0;
 
 static void client_get_all(Client *self);
 static void client_toggle_border(Client *self, gboolean show);
@@ -52,8 +53,8 @@ void client_startup()
                                  (GEqualFunc)map_key_comp);
 
     /* save the stacking order on startup! */
-    PROP_GET32U(ob_root, net_client_list_stacking, window,
-                client_startup_stack_order, client_startup_stack_size);
+    PROP_GETA32(ob_root, net_client_list_stacking, window,
+                &client_startup_stack_order, &client_startup_stack_size);
 
     client_set_list();
 }
@@ -78,7 +79,7 @@ void client_set_list()
     } else
        windows = NULL;
 
-    PROP_SET32A(ob_root, net_client_list, window, windows, size);
+    PROP_SETA32(ob_root, net_client_list, window, windows, size);
 
     if (windows)
        g_free(windows);
@@ -555,14 +556,14 @@ static void client_get_desktop(Client *self)
 
 static void client_get_state(Client *self)
 {
-    gulong *state;
-    gulong num;
+    Atom *state;
+    guint num;
   
     self->modal = self->shaded = self->max_horz = self->max_vert =
        self->fullscreen = self->above = self->below = self->iconic =
        self->skip_taskbar = self->skip_pager = FALSE;
 
-    if (PROP_GET32U(self->window, net_wm_state, atom, state, num)) {
+    if (PROP_GETA32(self->window, net_wm_state, atom, &state, &num)) {
        gulong i;
        for (i = 0; i < num; ++i) {
            if (state[i] == prop_atoms.net_wm_state_modal)
@@ -668,12 +669,13 @@ void client_update_transient_for(Client *self)
 
 static void client_get_mwm_hints(Client *self)
 {
-    unsigned long num;
-    unsigned long *hints;
+    guint num;
+    guint32 *hints;
 
     self->mwmhints.flags = 0; /* default to none */
 
-    if (PROP_GET32U(self->window, motif_wm_hints, motif_wm_hints, hints, num)) {
+    if (PROP_GETA32(self->window, motif_wm_hints, motif_wm_hints,
+                    &hints, &num)) {
        if (num >= MWM_ELEMENTS) {
            self->mwmhints.flags = hints[0];
            self->mwmhints.functions = hints[1];
@@ -685,11 +687,12 @@ static void client_get_mwm_hints(Client *self)
 
 void client_get_type(Client *self)
 {
-    gulong *val, num, i;
+    guint num, i;
+    Atom *val;
 
     self->type = -1;
   
-    if (PROP_GET32U(self->window, net_wm_window_type, atom, val, num)) {
+    if (PROP_GETA32(self->window, net_wm_window_type, atom, &val, &num)) {
        /* use the first value that we know about in the array */
        for (i = 0; i < num; ++i) {
            if (val[i] == prop_atoms.net_wm_window_type_desktop)
@@ -736,12 +739,12 @@ void client_get_type(Client *self)
 void client_update_protocols(Client *self)
 {
     Atom *proto;
-    gulong num_return, i;
+    guint num_return, i;
 
     self->focus_notify = FALSE;
     self->delete_window = FALSE;
 
-    if (PROP_GET32U(self->window, wm_protocols, atom, proto, num_return)) {
+    if (PROP_GETA32(self->window, wm_protocols, atom, &proto, &num_return)) {
        for (i = 0; i < num_return; ++i) {
            if (proto[i] == prop_atoms.wm_delete_window) {
                /* this means we can request the window to close */
@@ -968,7 +971,7 @@ static void client_change_allowed_actions(Client *self)
        actions[num++] = prop_atoms.net_wm_action_maximize_vert;
     }
 
-    PROP_SET32A(self->window, net_wm_allowed_actions, atom, actions, num);
+    PROP_SETA32(self->window, net_wm_allowed_actions, atom, actions, num);
 
     /* make sure the window isn't breaking any rules now */
 
@@ -1076,31 +1079,19 @@ void client_update_wmhints(Client *self)
 
 void client_update_title(Client *self)
 {
-    gchar *data = NULL;
+    char *data = NULL;
 
     g_free(self->title);
      
     /* try netwm */
-    if (!PROP_GETS(self->window, net_wm_name, utf8, data)) {
+    if (!PROP_GETS(self->window, net_wm_name, utf8, &data))
        /* try old x stuff */
-       if (PROP_GETS(self->window, wm_name, string, data)) {
-           /* convert it to UTF-8 */
-           gsize r, w;
-           gchar *u;
-
-           u = g_locale_to_utf8(data, -1, &r, &w, NULL);
-           if (u == NULL) {
-               g_warning("Unable to convert string to UTF-8");
-           } else {
-               g_free(data);
-               data = u;
-           }
-       }
-       if (data == NULL)
+       if (!PROP_GETS(self->window, wm_name, locale, &data))
            data = g_strdup("Unnamed Window");
 
-       PROP_SETS(self->window, net_wm_visible_name, utf8, data);
-    }
+    /* look for duplicates and append a number */
+
+    PROP_SETS(self->window, net_wm_visible_name, data);
 
     self->title = data;
 
@@ -1110,40 +1101,25 @@ void client_update_title(Client *self)
 
 void client_update_icon_title(Client *self)
 {
-    gchar *data = NULL;
+    char *data = NULL;
 
     g_free(self->icon_title);
      
     /* try netwm */
-    if (!PROP_GETS(self->window, net_wm_icon_name, utf8, data)) {
+    if (!PROP_GETS(self->window, net_wm_icon_name, utf8, &data))
        /* try old x stuff */
-       if (PROP_GETS(self->window, wm_icon_name, string, data)) {
-           /* convert it to UTF-8 */
-           gsize r, w;
-           gchar *u;
-
-           u = g_locale_to_utf8(data, -1, &r, &w, NULL);
-           if (u == NULL) {
-               g_warning("Unable to convert string to UTF-8");
-           } else {
-               g_free(data);
-               data = u;
-           }
-       }
-       if (data == NULL)
-           data = g_strdup("Unnamed Window");
+       if (!PROP_GETS(self->window, wm_icon_name, locale, &data))
+            data = g_strdup("Unnamed Window");
 
-       PROP_SETS(self->window, net_wm_visible_icon_name, utf8, data);
-    }
+    PROP_SETS(self->window, net_wm_visible_icon_name, data);
 
     self->icon_title = data;
 }
 
 void client_update_class(Client *self)
 {
-    GPtrArray *data;
-    gchar *s;
-    guint i;
+    char **data;
+    char *s;
 
     if (self->name) g_free(self->name);
     if (self->class) g_free(self->class);
@@ -1151,20 +1127,17 @@ void client_update_class(Client *self)
 
     self->name = self->class = self->role = NULL;
 
-    data = g_ptr_array_new();
-     
-    if (PROP_GETSA(self->window, wm_class, string, data)) {
-       if (data->len > 0)
-           self->name = g_strdup(g_ptr_array_index(data, 0));
-       if (data->len > 1)
-           self->class = g_strdup(g_ptr_array_index(data, 1));
+    if (PROP_GETSS(self->window, wm_class, locale, &data)) {
+        if (data[0]) {
+           self->name = g_strdup(data[0]);
+            if (data[1])
+                self->class = g_strdup(data[1]);
+        }
     }
-     
-    for (i = 0; i < data->len; ++i)
-       g_free(g_ptr_array_index(data, i));
-    g_ptr_array_free(data, TRUE);
 
-    if (PROP_GETS(self->window, wm_window_role, string, s))
+    g_strfreev(data);     
+
+    if (PROP_GETS(self->window, wm_window_role, locale, &s))
        self->role = g_strdup(s);
 
     if (self->name == NULL) self->name = g_strdup("");
@@ -1174,13 +1147,18 @@ void client_update_class(Client *self)
 
 void client_update_strut(Client *self)
 {
-    gulong *data;
+    guint num;
+    guint32 *data;
 
-    if (PROP_GET32A(self->window, net_wm_strut, cardinal, data, 4)) {
-       STRUT_SET(self->strut, data[0], data[2], data[1], data[3]);
-       g_free(data);
-    } else
+    if (!PROP_GETA32(self->window, net_wm_strut, cardinal, &data, &num)) {
        STRUT_SET(self->strut, 0, 0, 0, 0);
+    } else {
+        if (num == 4)
+            STRUT_SET(self->strut, data[0], data[2], data[1], data[3]);
+        else
+            STRUT_SET(self->strut, 0, 0, 0, 0);
+       g_free(data);
+    }
 
     /* updating here is pointless while we're being mapped cuz we're not in
        the client list yet */
@@ -1190,9 +1168,9 @@ void client_update_strut(Client *self)
 
 void client_update_icons(Client *self)
 {
-    unsigned long num;
-    unsigned long *data;
-    unsigned long w, h, i;
+    guint num;
+    guint32 *data;
+    guint w, h, i;
     int j;
 
     for (j = 0; j < self->nicons; ++j)
@@ -1201,7 +1179,7 @@ void client_update_icons(Client *self)
        g_free(self->icons);
     self->nicons = 0;
 
-    if (PROP_GET32U(self->window, net_wm_icon, cardinal, data, num)) {
+    if (PROP_GETA32(self->window, net_wm_icon, cardinal, &data, &num)) {
        /* figure out how many valid icons are in here */
        i = 0;
        while (num - i > 2) {
@@ -1234,14 +1212,18 @@ void client_update_icons(Client *self)
 
 void client_update_kwm_icon(Client *self)
 {
+    guint num;
     Pixmap *data;
 
-    if (PROP_GET32A(self->window, kwm_win_icon, kwm_win_icon, data, 2)) {
-       self->pixmap_icon = data[0];
-       self->pixmap_icon_mask = data[1];
-       g_free(data);
-    } else {
+    if (!PROP_GETA32(self->window, kwm_win_icon, kwm_win_icon, &data, &num)) {
        self->pixmap_icon = self->pixmap_icon_mask = None;
+    } else {
+        if (num == 2) {
+            self->pixmap_icon = data[0];
+            self->pixmap_icon_mask = data[1];
+        } else
+            self->pixmap_icon = self->pixmap_icon_mask = None;
+       g_free(data);
     }
     if (self->frame)
        frame_adjust_icon(self->frame);
@@ -1255,7 +1237,7 @@ static void client_change_state(Client *self)
 
     state[0] = self->wmstate;
     state[1] = None;
-    PROP_SET32A(self->window, wm_state, wm_state, state, 2);
+    PROP_SETA32(self->window, wm_state, wm_state, state, 2);
 
     num = 0;
     if (self->modal)
@@ -1278,7 +1260,7 @@ static void client_change_state(Client *self)
        netstate[num++] = prop_atoms.net_wm_state_above;
     if (self->below)
        netstate[num++] = prop_atoms.net_wm_state_below;
-    PROP_SET32A(self->window, net_wm_state, atom, netstate, num);
+    PROP_SETA32(self->window, net_wm_state, atom, netstate, num);
 
     client_calc_layer(self);
 
@@ -1589,13 +1571,13 @@ void client_fullscreen(Client *self, gboolean fs, gboolean savearea)
 
     if (fs) {
        if (savearea) {
-           long dimensions[4];
+           guint32 dimensions[4];
            dimensions[0] = self->area.x;
            dimensions[1] = self->area.y;
            dimensions[2] = self->area.width;
            dimensions[3] = self->area.height;
   
-           PROP_SET32A(self->window, openbox_premax, cardinal,
+           PROP_SETA32(self->window, openbox_premax, cardinal,
                        dimensions, 4);
        }
 
@@ -1603,23 +1585,26 @@ void client_fullscreen(Client *self, gboolean fs, gboolean savearea)
            as appropriate when the window is fullscreened */
         x = y = w = h = 0;
     } else {
-       long *dimensions;
-
-       if (PROP_GET32A(self->window, openbox_premax, cardinal,
-                       dimensions, 4)) {
-           x = dimensions[0];
-           y = dimensions[1];
-           w = dimensions[2];
-           h = dimensions[3];
+        guint num;
+       guint32 *dimensions;
+
+        /* pick some fallbacks... */
+        x = screen_area(self->desktop)->x +
+            screen_area(self->desktop)->width / 4;
+        y = screen_area(self->desktop)->y +
+            screen_area(self->desktop)->height / 4;
+        w = screen_area(self->desktop)->width / 2;
+        h = screen_area(self->desktop)->height / 2;
+
+       if (PROP_GETA32(self->window, openbox_premax, cardinal,
+                        dimensions, &num)) {
+            if (num == 4) {
+                x = dimensions[0];
+                y = dimensions[1];
+                w = dimensions[2];
+                h = dimensions[3];
+            }
            g_free(dimensions);
-       } else {
-           /* pick some fallbacks... */
-           x = screen_area(self->desktop)->x +
-               screen_area(self->desktop)->width / 4;
-           y = screen_area(self->desktop)->y +
-               screen_area(self->desktop)->height / 4;
-           w = screen_area(self->desktop)->width / 2;
-           h = screen_area(self->desktop)->height / 2;
        }
     }
 
@@ -1718,8 +1703,9 @@ void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
 
     if (max) {
        if (savearea) {
-           long dimensions[4];
-           long *readdim;
+           gint32 dimensions[4];
+           gint32 *readdim;
+            guint num;
 
            dimensions[0] = x;
            dimensions[1] = y;
@@ -1728,48 +1714,53 @@ void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
 
            /* get the property off the window and use it for the dimensions
               we are already maxed on */
-           if (PROP_GET32A(self->window, openbox_premax, cardinal,
-                           readdim, 4)) {
-               if (self->max_horz) {
-                   dimensions[0] = readdim[0];
-                   dimensions[2] = readdim[2];
-               }
-               if (self->max_vert) {
-                   dimensions[1] = readdim[1];
-                   dimensions[3] = readdim[3];
-               }
+           if (PROP_GETA32(self->window, openbox_premax, cardinal,
+                           &readdim, &num)) {
+                if (num == 4) {
+                    if (self->max_horz) {
+                        dimensions[0] = readdim[0];
+                        dimensions[2] = readdim[2];
+                    }
+                    if (self->max_vert) {
+                        dimensions[1] = readdim[1];
+                        dimensions[3] = readdim[3];
+                    }
+                }
                g_free(readdim);
            }
 
-           PROP_SET32A(self->window, openbox_premax, cardinal,
+           PROP_SETA32(self->window, openbox_premax, cardinal,
                        dimensions, 4);
        }
     } else {
-       long *dimensions;
+        guint num;
+       gint32 *dimensions;
+
+        /* pick some fallbacks... */
+        if (dir == 0 || dir == 1) { /* horz */
+            x = screen_area(self->desktop)->x +
+                screen_area(self->desktop)->width / 4;
+            w = screen_area(self->desktop)->width / 2;
+        }
+        if (dir == 0 || dir == 2) { /* vert */
+            y = screen_area(self->desktop)->y +
+                screen_area(self->desktop)->height / 4;
+            h = screen_area(self->desktop)->height / 2;
+        }
 
-       if (PROP_GET32A(self->window, openbox_premax, cardinal,
-                       dimensions, 4)) {
-           if (dir == 0 || dir == 1) { /* horz */
-               x = dimensions[0];
-               w = dimensions[2];
-           }
-           if (dir == 0 || dir == 2) { /* vert */
-               y = dimensions[1];
-               h = dimensions[3];
-           }
-           g_free(dimensions);
-       } else {
-           /* pick some fallbacks... */
-           if (dir == 0 || dir == 1) { /* horz */
-               x = screen_area(self->desktop)->x +
-                   screen_area(self->desktop)->width / 4;
-               w = screen_area(self->desktop)->width / 2;
-           }
-           if (dir == 0 || dir == 2) { /* vert */
-               y = screen_area(self->desktop)->y +
-                   screen_area(self->desktop)->height / 4;
-               h = screen_area(self->desktop)->height / 2;
-           }
+       if (PROP_GETA32(self->window, openbox_premax, cardinal,
+                       &dimensions, &num)) {
+            if (num == 4) {
+                if (dir == 0 || dir == 1) { /* horz */
+                    x = dimensions[0];
+                    w = dimensions[2];
+                }
+                if (dir == 0 || dir == 2) { /* vert */
+                    y = dimensions[1];
+                    h = dimensions[3];
+                }
+            }
+            g_free(dimensions);
        }
     }
 
index 52562f8..27941ac 100644 (file)
@@ -1,5 +1,6 @@
 #include "prop.h"
 #include "openbox.h"
+
 #include <X11/Xatom.h>
 
 Atoms prop_atoms;
@@ -9,8 +10,6 @@ Atoms prop_atoms;
 
 void prop_startup()
 {
-    g_assert(ob_display != NULL);
-
     CREATE(cardinal, "CARDINAL");
     CREATE(window, "WINDOW");
     CREATE(pixmap, "PIXMAP");
@@ -41,14 +40,12 @@ void prop_startup()
     CREATE(net_active_window, "_NET_ACTIVE_WINDOW");
     CREATE(net_workarea, "_NET_WORKAREA");
     CREATE(net_supporting_wm_check, "_NET_SUPPORTING_WM_CHECK");
-/*   CREATE(net_virtual_roots, "_NET_VIRTUAL_ROOTS"); */
     CREATE(net_desktop_layout, "_NET_DESKTOP_LAYOUT");
     CREATE(net_showing_desktop, "_NET_SHOWING_DESKTOP");
 
     CREATE(net_close_window, "_NET_CLOSE_WINDOW");
     CREATE(net_wm_moveresize, "_NET_WM_MOVERESIZE");
 
-/*   CREATE(net_properties, "_NET_PROPERTIES"); */
     CREATE(net_wm_name, "_NET_WM_NAME");
     CREATE(net_wm_visible_name, "_NET_WM_VISIBLE_NAME");
     CREATE(net_wm_icon_name, "_NET_WM_ICON_NAME");
@@ -57,10 +54,8 @@ void prop_startup()
     CREATE(net_wm_window_type, "_NET_WM_WINDOW_TYPE");
     CREATE(net_wm_state, "_NET_WM_STATE");
     CREATE(net_wm_strut, "_NET_WM_STRUT");
-/*   CREATE(net_wm_icon_geometry, "_NET_WM_ICON_GEOMETRY"); */
     CREATE(net_wm_icon, "_NET_WM_ICON");
 /*   CREATE(net_wm_pid, "_NET_WM_PID"); */
-/*   CREATE(net_wm_handled_icons, "_NET_WM_HANDLED_ICONS"); */
     CREATE(net_wm_allowed_actions, "_NET_WM_ALLOWED_ACTIONS");
 
 /*   CREATE(net_wm_ping, "_NET_WM_PING"); */
@@ -131,30 +126,38 @@ void prop_startup()
     CREATE(openbox_premax, "_OPENBOX_PREMAX");
 }
 
-gboolean prop_get32(Window win, Atom prop, Atom type, gulong **data,gulong num)
+#include <X11/Xutil.h>
+#include <glib.h>
+#include <string.h>
+
+/* this just isn't used... and it also breaks on 64bit, watch out
+static gboolean get(Window win, Atom prop, Atom type, int size,
+                    guchar **data, gulong num)
 {
     gboolean ret = FALSE;
     int res;
-    gulong *xdata = NULL;
+    guchar *xdata = NULL;
     Atom ret_type;
     int ret_size;
     gulong ret_items, bytes_left;
+    long num32 = 32 / size * num; /\* num in 32-bit elements *\/
 
-    res = XGetWindowProperty(ob_display, win, prop, 0l, num,
+    res = XGetWindowProperty(display, win, prop, 0l, num32,
                             FALSE, type, &ret_type, &ret_size,
-                            &ret_items, &bytes_left, (guchar**)&xdata);
+                            &ret_items, &bytes_left, &xdata);
     if (res == Success && ret_items && xdata) {
-       if (ret_size == 32 && ret_items >= num) {
-           *data = g_memdup(xdata, num * sizeof(gulong));
+       if (ret_size == size && ret_items >= num) {
+           *data = g_memdup(xdata, num * (size / 8));
            ret = TRUE;
        }
        XFree(xdata);
     }
     return ret;
 }
+*/
 
-gboolean prop_get_prealloc(Window win, Atom prop, Atom type, int size,
-                          guchar *data, gulong num)
+static gboolean get_prealloc(Window win, Atom prop, Atom type, int size,
+                             guchar *data, gulong num)
 {
     gboolean ret = FALSE;
     int res;
@@ -169,7 +172,7 @@ gboolean prop_get_prealloc(Window win, Atom prop, Atom type, int size,
                             &ret_items, &bytes_left, &xdata);
     if (res == Success && ret_items && xdata) {
        if (ret_size == size && ret_items >= num) {
-           gulong i;
+           guint i;
            for (i = 0; i < num; ++i)
                switch (size) {
                case 8:
@@ -191,8 +194,8 @@ gboolean prop_get_prealloc(Window win, Atom prop, Atom type, int size,
     return ret;
 }
 
-gboolean prop_get_all(Window win, Atom prop, Atom type, int size,
-                     guchar **data, gulong *num)
+static gboolean get_all(Window win, Atom prop, Atom type, int size,
+                        guchar **data, guint *num)
 {
     gboolean ret = FALSE;
     int res;
@@ -206,7 +209,23 @@ gboolean prop_get_all(Window win, Atom prop, Atom type, int size,
                             &ret_items, &bytes_left, &xdata);
     if (res == Success) {
        if (ret_size == size && ret_items > 0) {
-           *data = g_memdup(xdata, ret_items * (size / 8));
+           guint i;
+
+           *data = g_malloc(ret_items * (size / 8));
+           for (i = 0; i < ret_items; ++i)
+               switch (size) {
+               case 8:
+                   (*data)[i] = xdata[i];
+                   break;
+               case 16:
+                   ((guint16*)*data)[i] = ((guint16*)xdata)[i];
+                   break;
+               case 32:
+                   ((guint32*)*data)[i] = ((guint32*)xdata)[i];
+                   break;
+               default:
+                   g_assert_not_reached(); /* unhandled size */
+               }
            *num = ret_items;
            ret = TRUE;
        }
@@ -215,65 +234,132 @@ gboolean prop_get_all(Window win, Atom prop, Atom type, int size,
     return ret;
 }
 
-gboolean prop_get_string(Window win, Atom prop, Atom type, guchar **data)
+static gboolean get_stringlist(Window win, Atom prop, char ***list, int *nstr)
 {
-    guchar *raw;
-    gulong num;
-    GString *str;
-     
-    if (prop_get_all(win, prop, type, 8, &raw, &num)) {
-       str = g_string_new_len((char*)raw, num);
-       g_assert(str->str[num] == '\0');
+    XTextProperty tprop;
+    gboolean ret = FALSE;
 
-       g_free(raw);
+    if (XGetTextProperty(ob_display, win, &tprop, prop) && tprop.nitems) {
+        if (XTextPropertyToStringList(&tprop, list, nstr))
+            ret = TRUE;
+        XFree(tprop.value);
+    }
+    return ret;
+}
 
-       *data = (guchar*)g_string_free(str, FALSE);
-       return TRUE;
+gboolean prop_get32(Window win, Atom prop, Atom type, guint32 *ret)
+{
+    return get_prealloc(win, prop, type, 32, (guchar*)ret, 1);
+}
+
+gboolean prop_get_array32(Window win, Atom prop, Atom type, guint32 **ret,
+                          guint *nret)
+{
+    return get_all(win, prop, type, 32, (guchar**)ret, nret);
+}
+
+gboolean prop_get_string_locale(Window win, Atom prop, char **ret)
+{
+    char **list;
+    int nstr;
+
+    if (get_stringlist(win, prop, &list, &nstr) && nstr) {
+        *ret = g_locale_to_utf8(list[0], -1, NULL, NULL, NULL);
+        XFreeStringList(list);
+        if (ret) return TRUE;
     }
     return FALSE;
 }
 
-gboolean prop_get_strings(Window win, Atom prop, Atom type,
-                         GPtrArray *data)
+gboolean prop_get_strings_locale(Window win, Atom prop, char ***ret)
 {
-    guchar *raw;
-    gulong num;
-    GString *str, *str2;
-    guint i, start;
-     
-    if (prop_get_all(win, prop, type, 8, &raw, &num)) {
-       str = g_string_new_len((gchar*)raw, num);
-       g_assert(str->str[num] == '\0'); /* assuming this is always true.. */
+    char *raw, *p;
+    guint num, i;
 
+    if (get_all(win, prop, prop_atoms.string, 8, (guchar**)&raw, &num)){
+        *ret = g_new(char*, num + 1);
+        (*ret)[num] = NULL; /* null terminated list */
+
+        p = raw;
+        for (i = 0; i < num; ++i) {
+            (*ret)[i] = g_locale_to_utf8(p, -1, NULL, NULL, NULL);
+            /* make sure translation did not fail */
+            if (!(*ret)[i]) {
+                g_strfreev(*ret); /* free what we did so far */
+                break; /* the force is not strong with us */
+            }
+            p = strchr(p, '\0');
+        }
        g_free(raw);
+        if (i == num)
+            return TRUE;
+    }
+    return FALSE;
+}
 
-       /* split it into the list */
-       for (start = 0, i = 0; i < str->len; ++i) {
-           if (str->str[i] == '\0') {
-               str2 = g_string_new_len(&str->str[start], i - start);
-               g_ptr_array_add(data, g_string_free(str2, FALSE));
-               start = i + 1;
-           }
-       }
-       g_string_free(str, TRUE);
+gboolean prop_get_string_utf8(Window win, Atom prop, char **ret)
+{
+    char *raw;
+    guint num;
+     
+    if (get_all(win, prop, prop_atoms.utf8, 8, (guchar**)&raw, &num)) {
+       *ret = g_strdup(raw); /* grab the first string from the list */
+       g_free(raw);
+       return TRUE;
+    }
+    return FALSE;
+}
+
+gboolean prop_get_strings_utf8(Window win, Atom prop, char ***ret)
+{
+    char *raw, *p;
+    guint num, i;
+
+    if (get_all(win, prop, prop_atoms.utf8, 8, (guchar**)&raw, &num)) {
+        *ret = g_new(char*, num + 1);
+        (*ret)[num] = NULL; /* null terminated list */
 
-       if (data->len > 0)
-           return TRUE;
+        p = raw;
+        for (i = 0; i < num; ++i) {
+            (*ret)[i] = g_strdup(p);
+            p = strchr(p, '\0');
+        }
+       g_free(raw);
+       return TRUE;
     }
     return FALSE;
 }
 
-void prop_set_strings(Window win, Atom prop, Atom type, GPtrArray *data)
+void prop_set32(Window win, Atom prop, Atom type, guint32 val)
+{
+    XChangeProperty(ob_display, win, prop, type, 32, PropModeReplace,
+                    (guchar*)&val, 1);
+}
+
+void prop_set_array32(Window win, Atom prop, Atom type, guint32 *val,
+                      guint num)
+{
+    XChangeProperty(ob_display, win, prop, type, 32, PropModeReplace,
+                    (guchar*)val, num);
+}
+
+void prop_set_string_utf8(Window win, Atom prop, char *val)
+{
+    XChangeProperty(ob_display, win, prop, prop_atoms.utf8, 8,
+                    PropModeReplace, (guchar*)val, strlen(val));
+}
+
+void prop_set_strings_utf8(Window win, Atom prop, char **strs)
 {
     GString *str;
     guint i;
 
     str = g_string_sized_new(0);
-    for (i = 0; i < data->len; ++i) {
-        str = g_string_append(str, data->pdata[i]);
+    for (i = 0; strs[i]; ++i) {
+        str = g_string_append(str, strs[i]);
         str = g_string_append_c(str, '\0');
     }
-    XChangeProperty(ob_display, win, prop, type, 8,
+    XChangeProperty(ob_display, win, prop, prop_atoms.utf8, 8,
                     PropModeReplace, (guchar*)str->str, str->len);
 }
 
index 7899507..e7c861c 100644 (file)
@@ -7,8 +7,6 @@
 #  include <string.h>
 #endif
 
-#include "openbox.h"
-
 /*! The atoms on the X server which this class will cache */
 typedef struct Atoms {
     /* types */
@@ -46,14 +44,12 @@ typedef struct Atoms {
     Atom net_active_window;
     Atom net_workarea;
     Atom net_supporting_wm_check;
-/*  Atom net_virtual_roots; */
     Atom net_desktop_layout;
     Atom net_showing_desktop;
     /* root window messages */
     Atom net_close_window;
     Atom net_wm_moveresize;
     /* application window properties */
-/*  Atom net_properties; */
     Atom net_wm_name;
     Atom net_wm_visible_name;
     Atom net_wm_icon_name;
@@ -62,10 +58,8 @@ typedef struct Atoms {
     Atom net_wm_window_type;
     Atom net_wm_state;
     Atom net_wm_strut;
-/*  Atom net_wm_icon_geometry; */
     Atom net_wm_icon;
 /*  Atom net_wm_pid; */
-/*  Atom net_wm_handled_icons; */
     Atom net_wm_allowed_actions;
     /* application protocols */
 /*  Atom   Atom net_wm_ping; */
@@ -139,75 +133,47 @@ Atoms prop_atoms;
 
 void prop_startup();
 
-gboolean prop_get32(Window win, Atom prop, Atom type,
-                    gulong **data, gulong num);
-
-gboolean prop_get_prealloc(Window win, Atom prop, Atom type, int size,
-                          guchar *data, gulong num);
-
-gboolean prop_get_all(Window win, Atom prop, Atom type, int size,
-                     guchar **data, gulong *num);
+gboolean prop_get32(Window win, Atom prop, Atom type, guint32 *ret);
+gboolean prop_get_array32(Window win, Atom prop, Atom type, guint32 **ret,
+                          guint *nret);
+gboolean prop_get_string_locale(Window win, Atom prop, char **ret);
+gboolean prop_get_string_utf8(Window win, Atom prop, char **ret);
+gboolean prop_get_strings_locale(Window win, Atom prop, char ***ret);
+gboolean prop_get_strings_utf8(Window win, Atom prop, char ***ret);
 
-gboolean prop_get_string(Window win, Atom prop, Atom type, guchar **data);
-gboolean prop_get_strings(Window win, Atom prop, Atom type,
-                         GPtrArray *data);
-
-void prop_set_strings(Window win, Atom prop, Atom type, GPtrArray *data);
+void prop_set32(Window win, Atom prop, Atom type, guint32 val);
+void prop_set_array32(Window win, Atom prop, Atom type, guint32 *val,
+                      guint num);
+void prop_set_string_utf8(Window win, Atom prop, char *val);
+void prop_set_strings_utf8(Window win, Atom prop, char **strs);
 
 void prop_erase(Window win, Atom prop);
 
 void prop_message(Window about, Atom messagetype, long data0, long data1,
                  long data2, long data3);
 
+#define PROP_GET32(win, prop, type, ret) \
+    (prop_get32(win, prop_atoms.prop, prop_atoms.type, (guint32*)ret))
+#define PROP_GETA32(win, prop, type, ret, nret) \
+    (prop_get_array32(win, prop_atoms.prop, prop_atoms.type, (guint32**)ret, \
+                      nret))
+#define PROP_GETS(win, prop, type, ret) \
+    (prop_get_string_##type(win, prop_atoms.prop, ret))
+#define PROP_GETSS(win, prop, type, ret) \
+    (prop_get_strings_##type(win, prop_atoms.prop, ret))
+
+#define PROP_SET32(win, prop, type, val) \
+    prop_set32(win, prop_atoms.prop, prop_atoms.type, val)
+#define PROP_SETA32(win, prop, type, val, num) \
+    prop_set_array32(win, prop_atoms.prop, prop_atoms.type, (guint32*)val, num)
+#define PROP_SETS(win, prop, val) \
+    prop_set_string_utf8(win, prop_atoms.prop, val)
+#define PROP_SETSS(win, prop, strs) \
+    prop_set_strings_utf8(win, prop_atoms.prop, strs)
+
+#define PROP_ERASE(win, prop) prop_erase(win, prop_atoms.prop)
+
 #define PROP_MSG(about, msgtype, data0, data1, data2, data3) \
   (prop_message(about, prop_atoms.msgtype, data0, data1, data2, data3))
 
-/* Set an 8-bit property from a string */
-#define PROP_SETS(win, prop, type, value) \
-  (XChangeProperty(ob_display, win, prop_atoms.prop, prop_atoms.type, 8, \
-                  PropModeReplace, (guchar*)value, strlen(value)))
-/* Set an 8-bit property array from a GPtrArray of strings */
-#define PROP_SETSA(win, prop, type, value) \
-  (prop_set_strings(win, prop_atoms.prop, prop_atoms.type, value))
-
-/* Set a 32-bit property from a single value */
-#define PROP_SET32(win, prop, type, value) \
-  (XChangeProperty(ob_display, win, prop_atoms.prop, prop_atoms.type, 32, \
-                  PropModeReplace, (guchar*)&value, 1))
-/* Set a 32-bit property from an array */
-#define PROP_SET32A(win, prop, type, value, num) \
-  (XChangeProperty(ob_display, win, prop_atoms.prop, prop_atoms.type, 32, \
-                  PropModeReplace, (guchar*)value, num))
-
-/* Get an 8-bit property into a string */
-#define PROP_GETS(win, prop, type, value) \
-  (prop_get_string(win, prop_atoms.prop, prop_atoms.type, \
-                          (guchar**)&value))
-/* Get an 8-bit property into a GPtrArray of strings
-   (The strings must be freed, the GPtrArray must already be created.) */
-#define PROP_GETSA(win, prop, type, value) \
-  (prop_get_strings(win, prop_atoms.prop, prop_atoms.type, \
-                           value))
-
-/* Get an entire 8-bit property into an array (which must be freed) */
-#define PROP_GET8U(win, prop, type, value, num) \
-  (prop_get_all(win, prop_atoms.prop, prop_atoms.type, 8, \
-                (guchar**)&value, &num))
-
-/* Get 1 element of a 32-bit property into a given variable */
-#define PROP_GET32(win, prop, type, value) \
-  (prop_get_prealloc(win, prop_atoms.prop, prop_atoms.type, 32, \
-                    (guchar*)&value, 1))
-
-/* Get an amount of a 32-bit property into an array (which must be freed) */
-#define PROP_GET32A(win, prop, type, value, num) \
-  (prop_get32(win, prop_atoms.prop, prop_atoms.type, (gulong**)&value, num))
-
-/* Get an entire 32-bit property into an array (which must be freed) */
-#define PROP_GET32U(win, prop, type, value, num) \
-  (prop_get_all(win, prop_atoms.prop, prop_atoms.type, 32, \
-               (guchar**)&value, &num))
-
-#define PROP_ERASE(win, prop) (prop_erase(win, prop_atoms.prop))
-
 #endif
index 9f14ea8..174f645 100644 (file)
@@ -25,7 +25,7 @@ guint    screen_desktop         = 0;
 Size     screen_physical_size;
 gboolean screen_showing_desktop;
 DesktopLayout screen_desktop_layout;
-GPtrArray *screen_desktop_names;
+char   **screen_desktop_names;
 
 static Rect  *area = NULL;
 static Strut *strut = NULL;
@@ -74,7 +74,7 @@ gboolean screen_annex()
     PROP_SET32(ob_root, net_supporting_wm_check, window, support_window);
 
     /* set properties on the supporting window */
-    PROP_SETS(support_window, net_wm_name, utf8, "Openbox");
+    PROP_SETS(support_window, net_wm_name, "Openbox");
     PROP_SET32(support_window, net_supporting_wm_check, window,support_window);
 
     /* set the _NET_SUPPORTED_ATOMS hint */
@@ -140,7 +140,7 @@ gboolean screen_annex()
   supported[] = prop_atoms.net_wm_action_stick;
 */
 
-    PROP_SET32A(ob_root, net_supported, atom, supported, num_support);
+    PROP_SETA32(ob_root, net_supported, atom, supported, num_support);
     g_free(supported);
 
     return TRUE;
@@ -149,20 +149,20 @@ gboolean screen_annex()
 void screen_startup()
 {
     GSList *it;
+    guint i;
 
-    screen_desktop_names = g_ptr_array_new();
-     
     /* get the initial size */
     screen_resize();
 
     /* set the names */
-    for (it = config_desktops_names; it; it = it->next)
-        g_ptr_array_add(screen_desktop_names, it->data); /* dont strdup */
-    PROP_SETSA(ob_root, net_desktop_names, utf8, screen_desktop_names);
-    g_ptr_array_set_size(screen_desktop_names, 0); /* rm the ptrs so they dont
-                                                      get frees when we
-                                                      update the desktop
-                                                      names */
+    screen_desktop_names = g_new(char*,
+                                 g_slist_length(config_desktops_names) + 1);
+    for (i = 0, it = config_desktops_names; it; ++i, it = it->next)
+        screen_desktop_names[i] = it->data; /* dont strdup */
+    PROP_SETSS(ob_root, net_desktop_names, screen_desktop_names);
+    g_free(screen_desktop_names); /* dont free the individual strings */
+    screen_desktop_names = NULL;
+
     screen_num_desktops = 0;
     screen_set_num_desktops(config_desktops_num);
     screen_desktop = 0;
@@ -177,8 +177,6 @@ void screen_startup()
 
 void screen_shutdown()
 {
-    guint i;
-
     XSelectInput(ob_display, ob_root, NoEventMask);
 
     PROP_ERASE(ob_root, openbox_pid); /* we're not running here no more! */
@@ -187,9 +185,7 @@ void screen_shutdown()
 
     XDestroyWindow(ob_display, support_window);
 
-    for (i = 0; i < screen_desktop_names->len; ++i)
-       g_free(g_ptr_array_index(screen_desktop_names, i));
-    g_ptr_array_free(screen_desktop_names, TRUE);
+    g_strfreev(screen_desktop_names);
     g_free(strut);
     g_free(area);
 }
@@ -197,12 +193,12 @@ void screen_shutdown()
 void screen_resize()
 {
     /* XXX RandR support here? */
-    int geometry[2];
+    guint32 geometry[2];
 
     /* Set the _NET_DESKTOP_GEOMETRY hint */
     geometry[0] = WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen));
     geometry[1] = HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen));
-    PROP_SET32A(ob_root, net_desktop_geometry, cardinal, geometry, 2);
+    PROP_SETA32(ob_root, net_desktop_geometry, cardinal, geometry, 2);
     screen_physical_size.width = geometry[0];
     screen_physical_size.height = geometry[1];
 
@@ -217,7 +213,7 @@ void screen_resize()
 void screen_set_num_desktops(guint num)
 {
     guint i, old;
-    gulong *viewport;
+    guint32 *viewport;
     GList *it;
 
     g_assert(num > 0);
@@ -227,8 +223,8 @@ void screen_set_num_desktops(guint num)
     PROP_SET32(ob_root, net_number_of_desktops, cardinal, num);
 
     /* set the viewport hint */
-    viewport = g_new0(gulong, num * 2);
-    PROP_SET32A(ob_root, net_desktop_viewport, cardinal, viewport, num * 2);
+    viewport = g_new0(guint32, num * 2);
+    PROP_SETA32(ob_root, net_desktop_viewport, cardinal, viewport, num * 2);
     g_free(viewport);
 
     /* change our struts/area to match */
@@ -307,7 +303,8 @@ void screen_set_desktop(guint num)
 
 void screen_update_layout()
 {
-    unsigned long *data = NULL;
+    guint32 *data = NULL;
+    guint num;
 
     /* defaults */
     screen_desktop_layout.orientation = prop_atoms.net_wm_orientation_horz;
@@ -315,54 +312,61 @@ void screen_update_layout()
     screen_desktop_layout.rows = 1;
     screen_desktop_layout.columns = screen_num_desktops;
 
-    if (PROP_GET32A(ob_root, net_desktop_layout, cardinal, data, 4)) {
-       if (data[0] == prop_atoms.net_wm_orientation_vert)
-           screen_desktop_layout.orientation = data[0];
-       if (data[3] == prop_atoms.net_wm_topright)
-           screen_desktop_layout.start_corner = data[3];
-       else if (data[3] == prop_atoms.net_wm_bottomright)
-           screen_desktop_layout.start_corner = data[3];
-       else if (data[3] == prop_atoms.net_wm_bottomleft)
-           screen_desktop_layout.start_corner = data[3];
-
-       /* fill in a zero rows/columns */
-       if (!(data[1] == 0 && data[2] == 0)) { /* both 0's is bad data.. */
-           if (data[1] == 0) {
-               data[1] = (screen_num_desktops +
-                          screen_num_desktops % data[2]) / data[2];
-           } else if (data[2] == 0) {
-               data[2] = (screen_num_desktops +
-                          screen_num_desktops % data[1]) / data[1];
-           }
-           screen_desktop_layout.columns = data[1];
-           screen_desktop_layout.rows = data[2];
-       }
-
-       /* bounds checking */
-       if (screen_desktop_layout.orientation ==
-           prop_atoms.net_wm_orientation_horz) {
-           if (screen_desktop_layout.rows > screen_num_desktops)
-               screen_desktop_layout.rows = screen_num_desktops;
-           if (screen_desktop_layout.columns > ((screen_num_desktops +
-                                                 screen_num_desktops %
-                                                 screen_desktop_layout.rows) /
-                                                screen_desktop_layout.rows))
-               screen_desktop_layout.columns =
-                   (screen_num_desktops + screen_num_desktops %
-                    screen_desktop_layout.rows) /
-                   screen_desktop_layout.rows;
-       } else {
-           if (screen_desktop_layout.columns > screen_num_desktops)
-               screen_desktop_layout.columns = screen_num_desktops;
-           if (screen_desktop_layout.rows > ((screen_num_desktops +
-                                              screen_num_desktops %
-                                              screen_desktop_layout.columns) /
-                                             screen_desktop_layout.columns))
-               screen_desktop_layout.rows =
-                   (screen_num_desktops + screen_num_desktops %
-                    screen_desktop_layout.columns) /
-                   screen_desktop_layout.columns;
-       }
+    if (PROP_GETA32(ob_root, net_desktop_layout, cardinal, data, &num)) {
+        if (num == 3 || num == 4) {
+            if (data[0] == prop_atoms.net_wm_orientation_vert)
+                screen_desktop_layout.orientation = data[0];
+            if (num == 3)
+                screen_desktop_layout.start_corner =
+                    prop_atoms.net_wm_topright;
+            else {
+                if (data[3] == prop_atoms.net_wm_topright)
+                    screen_desktop_layout.start_corner = data[3];
+                else if (data[3] == prop_atoms.net_wm_bottomright)
+                    screen_desktop_layout.start_corner = data[3];
+                else if (data[3] == prop_atoms.net_wm_bottomleft)
+                    screen_desktop_layout.start_corner = data[3];
+            }
+
+            /* fill in a zero rows/columns */
+            if (!(data[1] == 0 && data[2] == 0)) { /* both 0's is bad data.. */
+                if (data[1] == 0) {
+                    data[1] = (screen_num_desktops +
+                               screen_num_desktops % data[2]) / data[2];
+                } else if (data[2] == 0) {
+                    data[2] = (screen_num_desktops +
+                               screen_num_desktops % data[1]) / data[1];
+                }
+                screen_desktop_layout.columns = data[1];
+                screen_desktop_layout.rows = data[2];
+            }
+
+            /* bounds checking */
+            if (screen_desktop_layout.orientation ==
+                prop_atoms.net_wm_orientation_horz) {
+                if (screen_desktop_layout.rows > screen_num_desktops)
+                    screen_desktop_layout.rows = screen_num_desktops;
+                if (screen_desktop_layout.columns >
+                    ((screen_num_desktops + screen_num_desktops %
+                      screen_desktop_layout.rows) /
+                     screen_desktop_layout.rows))
+                    screen_desktop_layout.columns =
+                        (screen_num_desktops + screen_num_desktops %
+                         screen_desktop_layout.rows) /
+                        screen_desktop_layout.rows;
+            } else {
+                if (screen_desktop_layout.columns > screen_num_desktops)
+                    screen_desktop_layout.columns = screen_num_desktops;
+                if (screen_desktop_layout.rows >
+                    ((screen_num_desktops + screen_num_desktops %
+                      screen_desktop_layout.columns) /
+                     screen_desktop_layout.columns))
+                    screen_desktop_layout.rows =
+                        (screen_num_desktops + screen_num_desktops %
+                         screen_desktop_layout.columns) /
+                        screen_desktop_layout.columns;
+            }
+        }
        g_free(data);
     }
 }
@@ -372,14 +376,17 @@ void screen_update_desktop_names()
     guint i;
 
     /* empty the array */
-    for (i = 0; i < screen_desktop_names->len; ++i)
-       g_free(g_ptr_array_index(screen_desktop_names, i));
-    g_ptr_array_set_size(screen_desktop_names, 0);
+    g_strfreev(screen_desktop_names);
 
-    PROP_GETSA(ob_root, net_desktop_names, utf8, screen_desktop_names);
+    PROP_GETSS(ob_root, net_desktop_names, utf8, &screen_desktop_names);
 
-    while (screen_desktop_names->len < screen_num_desktops)
-       g_ptr_array_add(screen_desktop_names, g_strdup("Unnamed Desktop"));
+    for (i = 0; screen_desktop_names[i] && i < screen_num_desktops; ++i);
+    if (i < screen_num_desktops) {
+        screen_desktop_names = g_renew(char*, screen_desktop_names,
+                                       screen_num_desktops + 1);
+        for (; i < screen_num_desktops; ++i)
+            screen_desktop_names[i] = g_strdup("Unnamed Desktop");
+    }
 }
 
 void screen_show_desktop(gboolean show)
@@ -460,12 +467,12 @@ void screen_update_struts()
 static void screen_update_area()
 {
     guint i;
-    gulong *dims;
+    guint32 *dims;
 
     g_free(area);
     area = g_new0(Rect, screen_num_desktops + 1);
      
-    dims = g_new(unsigned long, 4 * screen_num_desktops);
+    dims = g_new(guint32, 4 * screen_num_desktops);
     for (i = 0; i < screen_num_desktops + 1; ++i) {
        Rect old_area = area[i];
 /*
@@ -528,7 +535,7 @@ static void screen_update_area()
            dims[(i * 4) + 3] = area[i].height;
        }
     }
-    PROP_SET32A(ob_root, net_workarea, cardinal,
+    PROP_SETA32(ob_root, net_workarea, cardinal,
                dims, 4 * screen_num_desktops);
     g_free(dims);
 }
index 1e96970..f68b3be 100644 (file)
@@ -32,7 +32,7 @@ typedef struct DesktopLayout {
 extern DesktopLayout screen_desktop_layout;
 
 /*! An array of gchar*'s which are desktop names in UTF-8 format */
-extern GPtrArray *screen_desktop_names;
+extern char **screen_desktop_names;
 
 /*! Take over the screen, set the basic hints on it claming it as ours */
 gboolean screen_annex();
index b7e0fd9..4702baa 100644 (file)
@@ -30,7 +30,7 @@ void stacking_set_list()
     } else
        windows = NULL;
 
-    PROP_SET32A(ob_root, net_client_list_stacking, window, windows, size);
+    PROP_SETA32(ob_root, net_client_list_stacking, window, windows, size);
 
     if (windows)
        g_free(windows);