#include "focus.h"
#include "stacking.h"
#include "dispatch.h"
+#include "openbox.h"
#include "group.h"
#include "config.h"
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);
(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();
}
} 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);
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)
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];
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)
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 */
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 */
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;
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);
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("");
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 */
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)
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) {
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);
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)
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);
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);
}
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;
}
}
if (max) {
if (savearea) {
- long dimensions[4];
- long *readdim;
+ gint32 dimensions[4];
+ gint32 *readdim;
+ guint num;
dimensions[0] = x;
dimensions[1] = y;
/* 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);
}
}
#include "prop.h"
#include "openbox.h"
+
#include <X11/Xatom.h>
Atoms prop_atoms;
void prop_startup()
{
- g_assert(ob_display != NULL);
-
CREATE(cardinal, "CARDINAL");
CREATE(window, "WINDOW");
CREATE(pixmap, "PIXMAP");
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");
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"); */
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;
&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:
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;
&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;
}
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);
}
# include <string.h>
#endif
-#include "openbox.h"
-
/*! The atoms on the X server which this class will cache */
typedef struct Atoms {
/* types */
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;
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; */
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
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;
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 */
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;
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;
void screen_shutdown()
{
- guint i;
-
XSelectInput(ob_display, ob_root, NoEventMask);
PROP_ERASE(ob_root, openbox_pid); /* we're not running here no more! */
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);
}
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];
void screen_set_num_desktops(guint num)
{
guint i, old;
- gulong *viewport;
+ guint32 *viewport;
GList *it;
g_assert(num > 0);
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 */
void screen_update_layout()
{
- unsigned long *data = NULL;
+ guint32 *data = NULL;
+ guint num;
/* defaults */
screen_desktop_layout.orientation = prop_atoms.net_wm_orientation_horz;
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);
}
}
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)
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];
/*
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);
}
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();
} 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);