rip the prop code i wrote in cwmcc out and make it all 64bit friendly (i think!). stop using gulong for values from the xserver, using guint32 instead.

This commit is contained in:
Dana Jansens 2003-04-14 21:34:35 +00:00
parent 3d6e0f941d
commit d4b20aef31
6 changed files with 388 additions and 338 deletions

View 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;
if (!PROP_GETS(self->window, wm_icon_name, locale, &data))
data = g_strdup("Unnamed Window");
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");
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;
guint num;
guint32 *dimensions;
if (PROP_GET32A(self->window, openbox_premax, cardinal,
dimensions, 4)) {
x = dimensions[0];
y = dimensions[1];
w = dimensions[2];
h = dimensions[3];
/* 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;
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;
}
/* 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);
}
}

View 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;
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_locale_to_utf8(list[0], -1, NULL, NULL, NULL);
XFreeStringList(list);
if (ret) return TRUE;
}
return FALSE;
}
gboolean prop_get_strings_locale(Window win, Atom prop, char ***ret)
{
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;
}
*data = (guchar*)g_string_free(str, FALSE);
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(Window win, Atom prop, Atom type,
GPtrArray *data)
gboolean prop_get_strings_utf8(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.utf8, 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_strdup(p);
p = strchr(p, '\0');
}
g_free(raw);
/* 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);
if (data->len > 0)
return TRUE;
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);
}

View 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_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_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_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

View 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];
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];
}
/* 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;
}
/* 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);
}

View 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();

View 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);