X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fprop.c;h=5cc101092a2819ebfeaecc7ff29a38929c3dac2b;hb=35418ca0fcd3fd28ef579f4435b8bad3b7c87f04;hp=97f5fb94b7832059dbc28547be71da3176af4ffc;hpb=71badb0790c8595a0ab6dedfbf8027c698369210;p=chaz%2Fopenbox diff --git a/openbox/prop.c b/openbox/prop.c index 97f5fb94..5cc10109 100644 --- a/openbox/prop.c +++ b/openbox/prop.c @@ -1,5 +1,6 @@ #include "prop.h" #include "openbox.h" + #include 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,13 @@ 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_moveresize_window, "_NET_MOVERESIZE_WINDOW"); -/* 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 +55,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"); */ @@ -74,15 +70,18 @@ void prop_startup() CREATE(net_wm_window_type_dialog, "_NET_WM_WINDOW_TYPE_DIALOG"); CREATE(net_wm_window_type_normal, "_NET_WM_WINDOW_TYPE_NORMAL"); - CREATE(net_wm_moveresize_size_topleft, "_NET_WM_MOVERESIZE_SIZE_TOPLEFT"); - CREATE(net_wm_moveresize_size_topright, - "_NET_WM_MOVERESIZE_SIZE_TOPRIGHT"); - CREATE(net_wm_moveresize_size_bottomleft, - "_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT"); - CREATE(net_wm_moveresize_size_bottomright, - "_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT"); - CREATE(net_wm_moveresize_move, "_NET_WM_MOVERESIZE_MOVE"); - + prop_atoms.net_wm_moveresize_size_topleft = 0; + prop_atoms.net_wm_moveresize_size_top = 1; + prop_atoms.net_wm_moveresize_size_topright = 2; + prop_atoms.net_wm_moveresize_size_right = 3; + prop_atoms.net_wm_moveresize_size_bottomright = 4; + prop_atoms.net_wm_moveresize_size_bottom = 5; + prop_atoms.net_wm_moveresize_size_bottomleft = 6; + prop_atoms.net_wm_moveresize_size_left = 7; + prop_atoms.net_wm_moveresize_move = 8; + prop_atoms.net_wm_moveresize_size_keyboard = 9; + prop_atoms.net_wm_moveresize_move_keyboard = 10; + CREATE(net_wm_action_move, "_NET_WM_ACTION_MOVE"); CREATE(net_wm_action_resize, "_NET_WM_ACTION_RESIZE"); CREATE(net_wm_action_minimize, "_NET_WM_ACTION_MINIMIZE"); @@ -131,8 +130,13 @@ void prop_startup() CREATE(openbox_premax, "_OPENBOX_PREMAX"); } -gboolean prop_get(Window win, Atom prop, Atom type, int size, - guchar **data, gulong num) +#include +#include +#include + +/* 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; @@ -140,9 +144,9 @@ gboolean prop_get(Window win, Atom prop, Atom type, int size, Atom ret_type; int ret_size; gulong ret_items, bytes_left; - long num32 = 32 / size * num; /* num in 32-bit elements */ + long num32 = 32 / size * num; /\* num in 32-bit elements *\/ - res = XGetWindowProperty(ob_display, win, prop, 0l, num32, + res = XGetWindowProperty(display, win, prop, 0l, num32, FALSE, type, &ret_type, &ret_size, &ret_items, &bytes_left, &xdata); if (res == Success && ret_items && xdata) { @@ -154,9 +158,10 @@ gboolean prop_get(Window win, Atom prop, Atom type, int size, } 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; @@ -171,7 +176,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: @@ -181,7 +186,7 @@ gboolean prop_get_prealloc(Window win, Atom prop, Atom type, int size, ((guint16*)data)[i] = ((guint16*)xdata)[i]; break; case 32: - ((guint32*)data)[i] = ((guint32*)xdata)[i]; + ((guint32*)data)[i] = ((gulong*)xdata)[i]; break; default: g_assert_not_reached(); /* unhandled size */ @@ -193,8 +198,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; @@ -208,7 +213,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] = ((gulong*)xdata)[i]; + break; + default: + g_assert_not_reached(); /* unhandled size */ + } *num = ret_items; ret = TRUE; } @@ -217,65 +238,154 @@ 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; +} + +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_convert(list[0], strlen(list[0]), "UTF-8", "ISO-8859-1", + NULL, NULL, NULL); + XFreeStringList(list); + if (*ret) return TRUE; + } + return FALSE; +} + +gboolean prop_get_strings_locale(Window win, Atom prop, char ***ret) +{ + GSList *strs = NULL, *it; + char *raw, *p; + guint num, i, count = 0; + + if (get_all(win, prop, prop_atoms.string, 8, (guchar**)&raw, &num)) { - *data = (guchar*)g_string_free(str, FALSE); + p = raw; + while (p < raw + num - 1) { + ++count; + strs = g_slist_append(strs, p); + p += strlen(p) + 1; /* next string */ + } + + *ret = g_new0(char*, count + 1); + (*ret)[count] = NULL; /* null terminated list */ + + for (i = 0, it = strs; it; ++i, it = g_slist_next(it)) { + (*ret)[i] = g_convert(it->data, -1, "UTF-8", "ISO-8859-1", + NULL, NULL, NULL); + /* make sure translation did not fail */ + if (!(*ret)[i]) + (*ret)[i] = g_strdup(""); + } + g_free(raw); + g_slist_free(strs); return TRUE; } return FALSE; } -gboolean prop_get_strings(Window win, Atom prop, Atom type, - GPtrArray *data) +gboolean prop_get_string_utf8(Window win, Atom prop, char **ret) { - guchar *raw; - gulong num; - GString *str, *str2; - guint i, start; + char *raw; + char *str; + guint num; - 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.. */ - + if (get_all(win, prop, prop_atoms.utf8, 8, (guchar**)&raw, &num)) { + str = g_strndup(raw, num); /* grab the first string from the list */ g_free(raw); + if (g_utf8_validate(str, -1, NULL)) { + *ret = str; + return TRUE; + } + g_free(str); + } + 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_strings_utf8(Window win, Atom prop, char ***ret) +{ + GSList *strs = NULL, *it; + char *raw, *p; + guint num, i, count = 0; + + if (get_all(win, prop, prop_atoms.utf8, 8, (guchar**)&raw, &num)) { + + p = raw; + while (p < raw + num - 1) { + ++count; + strs = g_slist_append(strs, p); + p += strlen(p) + 1; /* next string */ + } + + *ret = g_new0(char*, count + 1); - if (data->len > 0) - return TRUE; + for (i = 0, it = strs; it; ++i, it = g_slist_next(it)) { + if (g_utf8_validate(it->data, -1, NULL)) + (*ret)[i] = g_strdup(it->data); + else + (*ret)[i] = g_strdup(""); + } + g_free(raw); + g_slist_free(strs); + 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; + char **s; str = g_string_sized_new(0); - for (i = 0; i < data->len; ++i) { - str = g_string_append(str, data->pdata[i]); + for (s = strs; *s; ++s) { + str = g_string_append(str, *s); 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); } @@ -297,6 +407,6 @@ void prop_message(Window about, Atom messagetype, long data0, long data1, ce.xclient.data.l[1] = data1; ce.xclient.data.l[2] = data2; ce.xclient.data.l[3] = data3; - XSendEvent(ob_display, ob_root, FALSE, + XSendEvent(ob_display, RootWindow(ob_display, ob_screen), FALSE, SubstructureNotifyMask | SubstructureRedirectMask, &ce); }