all repos — openbox @ f317ceeaf28bc656e59a0f089ac11818ca5e8bd3

openbox fork - make it a bit more like ryudo

add get functions for all the client properties
Dana Jansens danakj@orodu.net
commit

f317ceeaf28bc656e59a0f089ac11818ca5e8bd3

parent

d8fc08f33d5148be6294a8469066cf6a4604e940

6 files changed, 395 insertions(+), 13 deletions(-)

jump to
M cwmcc/.cvsignorecwmcc/.cvsignore

@@ -3,3 +3,4 @@ cwmcc.lo

libcwmcc.la atom.lo prop.lo +client_props.lo
A cwmcc/client_props.c

@@ -0,0 +1,292 @@

+#include "cwmcc_internal.h" +#include "atom.h" +#include "prop.h" +#include "client_props.h" +#include "render/render.h" + +#include <X11/Xutil.h> + +void cwmcc_client_get_protocols(Window win, Atom **protocols) +{ + gulong num; + + if (!prop_get_array32(win, CWMCC_ATOM(client, wm_protocols), + CWMCC_ATOM(type, atom), protocols, &num)) { + *protocols = NULL; + } +} + +int cwmcc_client_get_wm_state(Window win) +{ + gulong s; + + if (!prop_get32(win, CWMCC_ATOM(client, wm_state), + CWMCC_ATOM(client, wm_state), &s)) { + g_warning("Failed to read WM_STATE from 0x%lx", win); + s = NormalState; + } + return s; +} + +void cwmcc_client_get_name(Window win, char **name) +{ + if (!prop_get_string_utf8(win, CWMCC_ATOM(client, net_wm_name), name)) + if (!prop_get_string_locale(win, CWMCC_ATOM(client, wm_name), name)) { + g_warning("Failed to read a name from 0x%lx", win); + *name = g_strdup("Unnamed Window"); + } +} + +void cwmcc_client_get_icon_name(Window win, char **name) +{ + if (!prop_get_string_utf8(win, CWMCC_ATOM(client, net_wm_icon_name), name)) + if (!prop_get_string_locale(win, + CWMCC_ATOM(client, wm_icon_name), name)) { + g_warning("Failed to read an icon name from 0x%lx", win); + *name = g_strdup("Unnamed Window"); + } +} + +void cwmcc_client_get_class(Window win, char **class, char **name) +{ + char **s; + + if (!prop_get_strings_locale(win, CWMCC_ATOM(client, wm_class), &s)) { + g_warning("Failed to read WM_CLASS from 0x%lx", win); + *class = g_strdup(""); + *name = g_strdup(""); + } else { + if (!s[0]) { + g_warning("Failed to read class element of WM_CLASS from 0x%lx", + win); + *class = g_strdup(""); + } else + *class = g_strdup(s[0]); + if (!s[0] || !s[1]) { + g_warning("Failed to read name element of WM_CLASS from 0x%lx", + win); + *name = g_strdup(""); + } else + *name = g_strdup(s[1]); + } + g_strfreev(s); +} + +void cwmcc_client_get_role(Window win, char **role) +{ + if (!prop_get_string_locale(win, + CWMCC_ATOM(client, wm_window_role), role)) { + g_warning("Failed to read WM_WINDOW_ROLE from 0x%lx", win); + *role = g_strdup(""); + } +} + +void cwmcc_client_get_mwmhints(Window win, struct Cwmcc_MwmHints *hints) +{ + gulong *l = NULL, num; + + if (!prop_get_array32(win, CWMCC_ATOM(client, motif_wm_hints), + CWMCC_ATOM(client, motif_wm_hints), &l, &num)) { + g_warning("Failed to read Motif WM Hints from 0x%lx", win); + hints->flags = 0; + } else if (num < 3) { + g_warning("Read incomplete Motif WM Hints from 0x%lx", win); + hints->flags = 0; + } else { + hints->flags = l[0]; + hints->functions = l[1]; + hints->decorations = l[2]; + } + g_free(l); +} + +void cwmcc_client_get_desktop(Window win, gulong *desk) +{ + if (!prop_get32(win, CWMCC_ATOM(client, net_wm_desktop), + CWMCC_ATOM(type, cardinal), desk)) { + g_warning("Failed to read NET_WM_DESKTOP from 0x%lx", win); + *desk = 0; + } +} + +void cwmcc_client_get_type(Window win, gulong **types) +{ + gulong num; + + if (!prop_get_array32(win, CWMCC_ATOM(client, net_wm_window_type), + CWMCC_ATOM(type, atom), types, &num)) { + g_warning("Failed to read NET_WM_WINDOW_TYPE from 0x%lx", win); + *types = g_new(Atom, 2); + (*types)[0] = CWMCC_ATOM(data, net_wm_window_type_normal); + (*types)[1] = 0; + } +} + +void cwmcc_client_get_state(Window win, gulong **states) +{ + gulong num; + + if (!prop_get_array32(win, CWMCC_ATOM(client, net_wm_state), + CWMCC_ATOM(type, atom), states, &num)) { + g_warning("Failed to read NET_WM_STATE from 0x%lx", win); + *states = g_new(Atom, 1); + (*states)[0] = 0; + } +} + +void cwmcc_client_get_strut(Window win, int *l, int *t, int *r, int *b) +{ + gulong *data = NULL, num; + + if (!prop_get_array32(win, CWMCC_ATOM(client, net_wm_strut), + CWMCC_ATOM(type, cardinal), &data, &num)) { + g_warning("Failed to read NET_WM_STRUT from 0x%lx", win); + *l = *t = *r = *b = 0; + } else if (num != 4) { + g_warning("Read invalid NET_WM_STRUT from 0x%lx", win); + *l = *t = *r = *b = 0; + } else { + *l = data[0]; + *r = data[1]; + *t = data[2]; + *b = data[3]; + } + g_free(l); +} + +static void convert_pixmap_to_icon(Pixmap pix, Pixmap mask, + struct Cwmcc_Icon *icon) +{ +/* + guint pw, ph, mw, mh, depth; + Window wjunk; + int ijunk; + guint uijunk; + guint x, y; + + if (!XGetGeometry(cwmcc_display, pix, &wjunk, &ijunk, &ijunk, &pw, &ph, + &uijunk, &depth)) { + g_message("Unable to read pixmap icon's geometry"); + icon->width = icon->height = 0; + icon->data = NULL; + return; + } + if (!XGetGeometry(cwmcc_display, mask, &wjunk, &ijunk, &ijunk, &mw, &mh, + &uijunk, &ujunk)) { + g_message("Unable to read pixmap icon's mask's geometry"); + icon->width = icon->height = 0; + icon->data = NULL; + return; + } + if (pw != mw || ph !_ mh) { + g_warning("Pixmap icon's mask does not match icon's dimensions"); + icon->width = icon->height = 0; + icon->data = NULL; + return; + } + + for (y = 0; y < ph; ++y) + for (x = 0; x < pw; ++x) { + } +*/ + icon->width = icon->height = 0; + icon->data = NULL; +} + +void cwmcc_client_get_icon(Window win, struct Cwmcc_Icon **icons) +{ + gulong *data = NULL, num; + gulong w, h, i; + int j; + int nicons; + + if (!prop_get_array32(win, CWMCC_ATOM(client, net_wm_icon), + CWMCC_ATOM(type, cardinal), &data, &num)) { + g_warning("Failed to read NET_WM_ICON from 0x%lx", win); + *icons = NULL; + nicons = 0; + } else { + /* figure out how many valid icons are in here */ + i = 0; + nicons = 0; + while (num - i > 2) { + w = data[i++]; + h = data[i++]; + i += w * h; + if (i > num) break; + ++nicons; + } + + *icons = g_new(struct Cwmcc_Icon, nicons + 1); + (*icons)[nicons].data = NULL; + + /* store the icons */ + i = 0; + for (j = 0; j < nicons; ++j) { + w = (*icons)[j].width = data[i++]; + h = (*icons)[j].height = data[i++]; + (*icons)[j].data = + g_memdup(&data[i], w * h * sizeof(gulong)); + i += w * h; + g_assert(i <= num); + } + } + g_free(data); + + data = NULL; + if (!prop_get_array32(win, CWMCC_ATOM(client, kwm_win_icon), + CWMCC_ATOM(client, kwm_win_icon), &data, &num)) { + g_warning("Failed to read KWM_WIN_ICON from 0x%lx", win); + } else if (num != 2) { + g_warning("Read invalid KWM_WIN_ICON from 0x%lx", win); + } else { + Pixmap p, m; + struct Cwmcc_Icon icon; + + p = data[0]; + m = data[1]; + + convert_pixmap_to_icon(p, m, &icon); + + if (icon.data) { + *icons = g_renew(struct Cwmcc_Icon, *icons, nicons + 2); + (*icons[nicons + 1]).data = NULL; + g_memmove(&(*icons)[nicons], &icon, sizeof(struct Cwmcc_Icon)); + } + } + g_free(data); + +} + +void cwmcc_client_get_premax(Window win, int *x, int *y, int *w, int *h) +{ + gulong *l = NULL, num; + + if (!prop_get_array32(win, CWMCC_ATOM(client, openbox_premax), + CWMCC_ATOM(type, cardinal), &l, &num)) { + g_warning("Failed to read OPENBOX_PREMAX from 0x%lx", win); + *x = *y = *w = *h = 0; + } else if (num != 4) { + g_warning("Read invalid OPENBOX_PREMAX from 0x%lx", win); + *x = *y = *w = *h = 0; + } else { + *x = l[0]; + *y = l[1]; + *w = l[2]; + *h = l[3]; + } + g_free(l); +} + +void cwmcc_client_set_premax(Window win, int x, int y, int w, int h) +{ + gulong l[4]; + + l[0] = x; + l[1] = y; + l[2] = w; + l[3] = h; + XChangeProperty(cwmcc_display, win, CWMCC_ATOM(client, openbox_premax), + CWMCC_ATOM(type, cardinal), 32, PropModeReplace, + (guchar*)l, 4); +}
A cwmcc/client_props.h

@@ -0,0 +1,78 @@

+#ifndef __cwmcc_client_get_props_h +#define __cwmcc_client_get_props_h + +void cwmcc_client_get_protocols(Window win, Atom **protocols); + +int cwmcc_client_get_wm_state(Window win); + +void cwmcc_client_get_name(Window win, char **name); + +void cwmcc_client_get_icon_name(Window win, char **name); + +void cwmcc_client_get_class(Window win, char **class, char **name); + +/*! Possible flags for MWM Hints (defined by Motif 2.0) */ +enum Cwmcc_MwmFlags { + Cwmcc_MwmFlag_Functions = 1 << 0, /*!< The Hints define functions */ + Cwmcc_MwmFlag_Decorations = 1 << 1 /*!< The Hints define decorations */ +}; + +/*! Possible functions for MWM Hints (defined by Motif 2.0) */ +enum Cwmcc_MwmFunctions { + Cwmcc_MwmFunc_All = 1 << 0, /*!< All functions */ + Cwmcc_MwmFunc_Resize = 1 << 1, /*!< Allow resizing */ + Cwmcc_MwmFunc_Move = 1 << 2, /*!< Allow moving */ + Cwmcc_MwmFunc_Iconify = 1 << 3, /*!< Allow to be iconfied */ + Cwmcc_MwmFunc_Maximize = 1 << 4 /*!< Allow to be maximized */ + /*MwmFunc_Close = 1 << 5 /!< Allow to be closed */ +}; + +/*! Possible decorations for MWM Hints (defined by Motif 2.0) */ +enum Cwmcc_MwmDecorations { + Cwmcc_MwmDecor_All = 1 << 0, /*!< All decorations */ + Cwmcc_MwmDecor_Border = 1 << 1, /*!< Show a border */ + Cwmcc_MwmDecor_Handle = 1 << 2, /*!< Show a handle (bottom) */ + Cwmcc_MwmDecor_Title = 1 << 3, /*!< Show a titlebar */ + Cwmcc_MwmDecor_Menu = 1 << 4, /*!< Show a menu */ + Cwmcc_MwmDecor_Iconify = 1 << 5, /*!< Show an iconify button */ + Cwmcc_MwmDecor_Maximize = 1 << 6 /*!< Show a maximize button */ +}; + +/*! The MWM Hints as retrieved from the window property + This structure only contains 3 elements, even though the Motif 2.0 + structure contains 5. We only use the first 3, so that is all gets + defined. +*/ +struct Cwmcc_MwmHints { + /*! A bitmask of Cwmcc_MwmFlags values */ + gulong flags; + /*! A bitmask of Cwmcc_MwmFunctions values */ + gulong functions; + /*! A bitmask of Cwmcc_MwmDecorations values */ + gulong decorations; +}; + +void cwmcc_client_get_mwmhints(Window win, struct Cwmcc_MwmHints *hints); + +void cwmcc_client_get_desktop(Window win, gulong *desk); + +void cwmcc_client_get_type(Window win, gulong **types); + +void cwmcc_client_get_state(Window win, gulong **states); + +void cwmcc_client_get_strut(Window win, int *l, int *t, int *r, int *b); + +/*! Holds an icon in ARGB format */ +struct Cwmcc_Icon { + gulong width, height; + gulong *data; +}; + +/* Returns an array of Cwms_Icons. The array is terminated by a Cwmcc_Icon with + its data member set to NULL */ +void cwmcc_client_get_icon(Window win, struct Cwmcc_Icon **icons); + +void cwmcc_client_get_premax(Window win, int *x, int *y, int *w, int *h); +void cwmcc_client_set_premax(Window win, int x, int y, int w, int h); + +#endif
A cwmcc/cwmcc.h

@@ -0,0 +1,6 @@

+#ifndef __cwmcc_cwmcc_h +#define __cwmcc_cwmcc_h + +void cwmcc_startup(Display *d); + +#endif
M cwmcc/prop.ccwmcc/prop.c

@@ -1,4 +1,5 @@

#include "cwmcc_internal.h" +#include "atom.h" #include <X11/Xutil.h> #include <glib.h>

@@ -85,7 +86,9 @@ FALSE, type, &ret_type, &ret_size,

&ret_items, &bytes_left, &xdata); if (res == Success) { if (ret_size == size && ret_items > 0) { - *data = g_memdup(xdata, ret_items * (size / 8)); + *data = g_malloc(ret_items * (size / 8) + sizeof(guchar*)); + g_memmove(*data, xdata, ret_items * (size / 8)); + data[ret_items * (size / 8)] = NULL; *num = ret_items; ret = TRUE; }

@@ -131,12 +134,12 @@ }

return FALSE; } -gboolean prop_get_string_utf(Window win, Atom prop, Atom type, char **ret) +gboolean prop_get_string_utf8(Window win, Atom prop, char **ret) { char *raw; gulong num; - if (get_all(win, prop, type, 8, (guchar**)&raw, &num)) { + if (get_all(win, prop, CWMCC_ATOM(type, utf8), 8, (guchar**)&raw, &num)) { *ret = g_strdup(raw); /* grab the first string from the list */ g_free(raw); return TRUE;

@@ -144,12 +147,12 @@ }

return FALSE; } -gboolean prop_get_strings_utf(Window win, Atom prop, Atom type, char ***ret) +gboolean prop_get_strings_utf8(Window win, Atom prop, char ***ret) { char *raw, *p; gulong num, i; - if (get_all(win, prop, type, 8, (guchar**)&raw, &num)) { + if (get_all(win, prop, CWMCC_ATOM(type, utf8), 8, (guchar**)&raw, &num)) { *ret = g_new(char*, num + 1); (*ret)[num] = NULL; /* null terminated list */

@@ -164,11 +167,12 @@ }

return FALSE; } -gboolean prop_get_strings_locale(Window win, Atom prop, Atom type,char ***ret){ +gboolean prop_get_strings_locale(Window win, Atom prop, char ***ret) +{ char *raw, *p; gulong num, i; - if (get_all(win, prop, type, 8, (guchar**)&raw, &num)) { + if (get_all(win, prop, CWMCC_ATOM(type, string), 8, (guchar**)&raw, &num)){ *ret = g_new(char*, num + 1); (*ret)[num] = NULL; /* null terminated list */

@@ -189,7 +193,7 @@ }

return FALSE; } -void prop_set_strings_utf(Window win, Atom prop, Atom type, char **strs) +void prop_set_strings_utf8(Window win, Atom prop, char **strs) { GString *str; guint i;

@@ -199,7 +203,7 @@ for (i = 0; strs[i]; ++i) {

str = g_string_append(str, strs[i]); str = g_string_append_c(str, '\0'); } - XChangeProperty(cwmcc_display, win, prop, type, 8, + XChangeProperty(cwmcc_display, win, prop, CWMCC_ATOM(type, utf8), 8, PropModeReplace, (guchar*)str->str, str->len); }
M cwmcc/prop.hcwmcc/prop.h

@@ -1,6 +1,7 @@

#ifndef __prop_h #define __prop_h +#include <glib.h> #include <X11/Xlib.h> /* with the exception of prop_get32, all other prop_get_* functions require

@@ -15,7 +16,7 @@

gboolean prop_get_string(Window win, Atom prop, Atom type, char **ret); /*! Gets a string from a property which is stored in UTF-8 encoding. */ -gboolean prop_get_string_utf(Window win, Atom prop, char **ret); +gboolean prop_get_string_utf8(Window win, Atom prop, char **ret); /*! Gets a string from a property which is stored in the current local encoding. The returned string is in UTF-8 encoding. */

@@ -23,14 +24,14 @@ gboolean prop_get_string_locale(Window win, Atom prop, char **ret);

/*! Gets a null terminated array of strings from a property which is stored in UTF-8 encoding. */ -gboolean prop_get_strings_utf(Window win, Atom prop, Atom type, char ***ret); +gboolean prop_get_strings_utf8(Window win, Atom prop, char ***ret); /*! Gets a null terminated array of strings from a property which is stored in the current locale encoding. The returned string is in UTF-8 encoding. */ -gboolean prop_get_strings_locale(Window win, Atom prop, Atom type,char ***ret); +gboolean prop_get_strings_locale(Window win, Atom prop, char ***ret); /*! Sets a null terminated array of strings in a property encoded as UTF-8. */ -void prop_set_strings_utf(Window win, Atom prop, Atom type, char **strs); +void prop_set_strings_utf8(Window win, Atom prop, char **strs); void prop_erase(Window win, Atom prop);