diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gdm-control/Makefile | 4 | ||||
-rw-r--r-- | tools/gdm-control/gdm-control.c | 295 | ||||
-rw-r--r-- | tools/gnome-panel-control/Makefile | 4 | ||||
-rw-r--r-- | tools/gnome-panel-control/gnome-panel-control.c | 100 | ||||
-rw-r--r-- | tools/obxprop/Makefile | 4 | ||||
-rw-r--r-- | tools/obxprop/obxprop.c | 351 | ||||
-rwxr-xr-x | tools/themeupdate/themeupdate.py | 410 |
7 files changed, 1168 insertions, 0 deletions
diff --git a/tools/gdm-control/Makefile b/tools/gdm-control/Makefile new file mode 100644 index 0000000..cfc4653 --- /dev/null +++ b/tools/gdm-control/Makefile @@ -0,0 +1,4 @@ +all clean install: + $(MAKE) -C ../.. -$(MAKEFLAGS) $@ + +.PHONY: all clean install diff --git a/tools/gdm-control/gdm-control.c b/tools/gdm-control/gdm-control.c new file mode 100644 index 0000000..db28841 --- /dev/null +++ b/tools/gdm-control/gdm-control.c @@ -0,0 +1,295 @@ +#include <string.h> +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <X11/Xlib.h> +#include <X11/Xauth.h> + +#include <glib.h> + +typedef enum +{ + INVALID, + NONE, + SHUTDOWN, + REBOOT, + SUSPEND, + SWITCHUSER +} Action; + +#define GDM_PROTOCOL_SOCKET_PATH1 "/var/run/gdm_socket" +#define GDM_PROTOCOL_SOCKET_PATH2 "/tmp/.gdm_socket" + +#define GDM_PROTOCOL_MSG_CLOSE "CLOSE" +#define GDM_PROTOCOL_MSG_VERSION "VERSION" +#define GDM_PROTOCOL_MSG_AUTHENTICATE "AUTH_LOCAL" +#define GDM_PROTOCOL_MSG_QUERY_ACTION "QUERY_LOGOUT_ACTION" +#define GDM_PROTOCOL_MSG_SET_ACTION "SET_SAFE_LOGOUT_ACTION" +#define GDM_PROTOCOL_MSG_FLEXI_XSERVER "FLEXI_XSERVER" + +#define GDM_ACTION_STR_NONE GDM_PROTOCOL_MSG_SET_ACTION" NONE" +#define GDM_ACTION_STR_SHUTDOWN GDM_PROTOCOL_MSG_SET_ACTION" HALT" +#define GDM_ACTION_STR_REBOOT GDM_PROTOCOL_MSG_SET_ACTION" REBOOT" +#define GDM_ACTION_STR_SUSPEND GDM_PROTOCOL_MSG_SET_ACTION" SUSPEND" + +#define GDM_MIT_MAGIC_COOKIE_LEN 16 + +static int fd = 0; + +static void gdm_disconnect() +{ + if (fd > 0) + close(fd); + fd = 0; +} + +static char* get_display_number(void) +{ + char *display_name; + char *retval; + char *p; + + display_name = XDisplayName(NULL); + + p = strchr(display_name, ':'); + if (!p) + return g_strdup ("0"); + + while (*p == ':') p++; + + retval = g_strdup (p); + + p = strchr (retval, '.'); + if (p != NULL) + *p = '\0'; + + return retval; +} + +static char* gdm_send_protocol_msg (const char *msg) +{ + GString *retval; + char buf[256]; + char *p; + int len; + + p = g_strconcat(msg, "\n", NULL); + if (write (fd, p, strlen(p)) < 0) { + g_free (p); + + g_warning ("Failed to send message to GDM: %s", + g_strerror (errno)); + return NULL; + } + g_free (p); + + p = NULL; + retval = NULL; + while ((len = read(fd, buf, sizeof(buf) - 1)) > 0) { + buf[len] = '\0'; + + if (!retval) + retval = g_string_new(buf); + else + retval = g_string_append(retval, buf); + + if ((p = strchr(retval->str, '\n'))) + break; + } + + if (p) *p = '\0'; + + return retval ? g_string_free(retval, FALSE) : NULL; +} + +static gboolean gdm_authenticate() +{ + FILE *f; + Xauth *xau; + const char *xau_path; + char *display_number; + gboolean retval; + + if (!(xau_path = XauFileName())) + return FALSE; + + if (!(f = fopen(xau_path, "r"))) + return FALSE; + + retval = FALSE; + display_number = get_display_number(); + + while ((xau = XauReadAuth(f))) { + char buffer[40]; /* 2*16 == 32, so 40 is enough */ + char *msg; + char *response; + int i; + + if (xau->family != FamilyLocal || + strncmp (xau->number, display_number, xau->number_length) || + strncmp (xau->name, "MIT-MAGIC-COOKIE-1", xau->name_length) || + xau->data_length != GDM_MIT_MAGIC_COOKIE_LEN) + { + XauDisposeAuth(xau); + continue; + } + + for (i = 0; i < GDM_MIT_MAGIC_COOKIE_LEN; i++) + g_snprintf(buffer + 2*i, 3, "%02x", (guint)(guchar)xau->data[i]); + + XauDisposeAuth(xau); + + msg = g_strdup_printf(GDM_PROTOCOL_MSG_AUTHENTICATE " %s", buffer); + response = gdm_send_protocol_msg(msg); + g_free (msg); + + if (response && !strcmp(response, "OK")) { + /*auth_cookie = g_strdup(buffer);*/ + g_free(response); + retval = TRUE; + break; + } + + g_free (response); + } + + fclose(f); + return retval; +} + +static gboolean gdm_connect() +{ + struct sockaddr_un addr; + char *response; + + assert(fd <= 0); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + g_warning("Failed to create GDM socket: %s", g_strerror (errno)); + gdm_disconnect(); + return FALSE; + } + + if (g_file_test(GDM_PROTOCOL_SOCKET_PATH1, G_FILE_TEST_EXISTS)) + strcpy(addr.sun_path, GDM_PROTOCOL_SOCKET_PATH1); + else + strcpy(addr.sun_path, GDM_PROTOCOL_SOCKET_PATH2); + + addr.sun_family = AF_UNIX; + + if (connect(fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { + g_warning("Failed to establish a connection with GDM: %s", + g_strerror(errno)); + gdm_disconnect(); + return FALSE; + } + + response = gdm_send_protocol_msg(GDM_PROTOCOL_MSG_VERSION); + if (!response || strncmp(response, "GDM ", strlen("GDM ") != 0)) { + g_free(response); + + g_warning("Failed to get protocol version from GDM"); + gdm_disconnect(); + return FALSE; + } + g_free(response); + + if (!gdm_authenticate()) { + g_warning("Failed to authenticate with GDM"); + gdm_disconnect(); + return FALSE; + } + + return TRUE; +} + +int main(int argc, char **argv) +{ + int i; + Action a = INVALID; + + for (i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--help")) { + a = INVALID; + break; + } + if (!strcmp(argv[i], "--none")) { + a = NONE; + break; + } + if (!strcmp(argv[i], "--shutdown")) { + a = SHUTDOWN; + break; + } + if (!strcmp(argv[i], "--reboot")) { + a = REBOOT; + break; + } + if (!strcmp(argv[i], "--suspend")) { + a = SUSPEND; + break; + } + if (!strcmp(argv[i], "--switch-user")) { + a = SWITCHUSER; + break; + } + } + + if (!a) { + printf("Usage: gdm-control ACTION\n\n"); + printf("Actions:\n"); + printf(" --help Display this help and exit\n"); + printf(" --none Do nothing special when the current session ends\n"); + printf(" --shutdown Shutdown the computer when the current session ends\n"); + printf(" --reboot Reboot the computer when the current session ends\n"); + printf(" --suspend Suspend the computer when the current session ends\n"); + printf(" --switch-user Log in as a new user (this works immediately)\n\n"); + return 0; + } + + { + char *d, *response; + const char *action_string; + + d = XDisplayName(NULL); + if (!d) { + fprintf(stderr, + "Unable to find the X display specified by the DISPLAY " + "environment variable. Ensure that it is set correctly."); + return 1; + } + + switch (a) { + case NONE: + action_string = GDM_ACTION_STR_NONE; + break; + case SHUTDOWN: + action_string = GDM_ACTION_STR_SHUTDOWN; + break; + case REBOOT: + action_string = GDM_ACTION_STR_REBOOT; + break; + case SUSPEND: + action_string = GDM_ACTION_STR_SUSPEND; + break; + case SWITCHUSER: + action_string = GDM_PROTOCOL_MSG_FLEXI_XSERVER; + break; + default: + assert(0); + } + + if (gdm_connect()) { + response = gdm_send_protocol_msg(action_string); + g_free(response); + gdm_disconnect(); + } + } + + return 0; +} diff --git a/tools/gnome-panel-control/Makefile b/tools/gnome-panel-control/Makefile new file mode 100644 index 0000000..cfc4653 --- /dev/null +++ b/tools/gnome-panel-control/Makefile @@ -0,0 +1,4 @@ +all clean install: + $(MAKE) -C ../.. -$(MAKEFLAGS) $@ + +.PHONY: all clean install diff --git a/tools/gnome-panel-control/gnome-panel-control.c b/tools/gnome-panel-control/gnome-panel-control.c new file mode 100644 index 0000000..67aa039 --- /dev/null +++ b/tools/gnome-panel-control/gnome-panel-control.c @@ -0,0 +1,100 @@ +#include <X11/Xlib.h> +#include <string.h> +#include <stdio.h> +#include <assert.h> + +typedef enum +{ + NONE, + MAIN_MENU, + RUN_DIALOG +} Action; + +int main(int argc, char **argv) +{ + int i; + Action a = NONE; + + for (i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--help")) { + a = NONE; + break; + } + if (!strcmp(argv[i], "--main-menu")) { + a = MAIN_MENU; + break; + } + if (!strcmp(argv[i], "--run-dialog")) { + a = RUN_DIALOG; + break; + } + } + + if (!a) { + printf("Usage: gnome-panel-control ACTION\n\n"); + printf("Actions:\n"); + printf(" --help Display this help and exit\n"); + printf(" --main-menu Show the main menu\n"); + printf(" --run-dialog Show the run dialog\n\n"); + return 0; + } + + { + Display *d; + Window root; + XClientMessageEvent ce; + Atom act_atom; + Time timestamp; + + d = XOpenDisplay(NULL); + if (!d) { + fprintf(stderr, + "Unable to open the X display specified by the DISPLAY " + "environment variable. Ensure you have permission to " + "connect to the display."); + return 1; + } + root = RootWindowOfScreen(DefaultScreenOfDisplay(d)); + + switch (a) { + case MAIN_MENU: + act_atom = XInternAtom(d, "_GNOME_PANEL_ACTION_MAIN_MENU", False); + break; + case RUN_DIALOG: + act_atom = XInternAtom(d, "_GNOME_PANEL_ACTION_RUN_DIALOG", False); + break; + default: + assert(0); + } + + /* Generate a timestamp */ + { + XEvent event; + Window win; + + win = XCreateSimpleWindow(d, root, 0, 0, 1, 1, 0, 0, 0); + + XSelectInput(d, win, PropertyChangeMask); + + XChangeProperty(d, win, act_atom, act_atom, 8, + PropModeAppend, NULL, 0); + XWindowEvent(d, win, PropertyChangeMask, &event); + + XDestroyWindow(d, win); + + timestamp = event.xproperty.time; + } + + ce.type = ClientMessage; + ce.window = root; + ce.message_type = XInternAtom(d, "_GNOME_PANEL_ACTION", False); + ce.format = 32; + ce.data.l[0] = act_atom; + ce.data.l[1] = timestamp; + XSendEvent(d, root, False, StructureNotifyMask, (XEvent*) &ce); + + XCloseDisplay(d); + } + + return 0; +} diff --git a/tools/obxprop/Makefile b/tools/obxprop/Makefile new file mode 100644 index 0000000..cfc4653 --- /dev/null +++ b/tools/obxprop/Makefile @@ -0,0 +1,4 @@ +all clean install: + $(MAKE) -C ../.. -$(MAKEFLAGS) $@ + +.PHONY: all clean install diff --git a/tools/obxprop/obxprop.c b/tools/obxprop/obxprop.c new file mode 100644 index 0000000..83ff54a --- /dev/null +++ b/tools/obxprop/obxprop.c @@ -0,0 +1,351 @@ +#include <X11/Xlib.h> +#include <X11/cursorfont.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <assert.h> +#include <glib.h> + +gint fail(const gchar *s) { + if (s) + fprintf(stderr, "%s\n", s); + else + fprintf + (stderr, + "Usage: obxprop [OPTIONS] [--] [PROPERTIES ...]\n\n" + "Options:\n" + " --help Display this help and exit\n" + " --display DISPLAY Connect to this X display\n" + " --id ID Show the properties for this window\n" + " --root Show the properties for the root window\n"); + return 1; +} + +gint parse_hex(gchar *s) { + gint result = 0; + while (*s) { + gint add; + if (*s >= '0' && *s <='9') + add = *s-'0'; + else if (*s >= 'A' && *s <='F') + add = *s-'A'+10; + else if (*s >= 'a' && *s <='f') + add = *s-'a'+10; + else + break; + + result *= 16; + result += add; + ++s; + } + return result; +} + +Window find_client(Display *d, Window win) +{ + Window r, *children; + guint n, i; + Atom state = XInternAtom(d, "WM_STATE", True); + Atom ret_type; + gint ret_format, res; + gulong ret_items, ret_bytesleft, *xdata; + + XQueryTree(d, win, &r, &r, &children, &n); + for (i = 0; i < n; ++i) { + Window w = find_client(d, children[i]); + if (w) return w; + } + + // try me + res = XGetWindowProperty(d, win, state, 0, 1, + False, state, &ret_type, &ret_format, + &ret_items, &ret_bytesleft, + (unsigned char**) &xdata); + XFree(xdata); + if (res != Success || ret_type == None || ret_items < 1) + return None; + return win; // found it! +} + +static gboolean get_all(Display *d, Window win, Atom prop, + Atom *type, gint *size, + guchar **data, guint *num) +{ + gboolean ret = FALSE; + gint res; + guchar *xdata = NULL; + gulong ret_items, bytes_left; + + res = XGetWindowProperty(d, win, prop, 0l, G_MAXLONG, + FALSE, AnyPropertyType, type, size, + &ret_items, &bytes_left, &xdata); + if (res == Success) { + if (ret_items > 0) { + 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] = ((gushort*)xdata)[i]; + break; + case 32: + ((guint32*)*data)[i] = ((gulong*)xdata)[i]; + break; + default: + g_assert_not_reached(); /* unhandled size */ + } + } + *num = ret_items; + ret = TRUE; + XFree(xdata); + } + return ret; +} + +gchar *append_string(gchar *before, gchar *after, gboolean quote) +{ + gchar *tmp; + const gchar *q = quote ? "\"" : ""; + if (before) + tmp = g_strdup_printf("%s, %s%s%s", before, q, after, q); + else + tmp = g_strdup_printf("%s%s%s", q, after, q); + g_free(before); + return tmp; +} + +gchar *append_int(gchar *before, guint after) +{ + gchar *tmp; + if (before) + tmp = g_strdup_printf("%s, %u", before, after); + else + tmp = g_strdup_printf("%u", after); + g_free(before); + return tmp; +} + +gchar* read_strings(gchar *val, guint n, gboolean utf8) +{ + GSList *strs = NULL, *it; + gchar *ret, *p; + guint i; + + p = val; + while (p < val + n) { + strs = g_slist_append(strs, g_strndup(p, n - (p - val))); + p += strlen(p) + 1; /* next string */ + } + + ret = NULL; + for (i = 0, it = strs; it; ++i, it = g_slist_next(it)) { + char *data; + + if (utf8) { + if (g_utf8_validate(it->data, -1, NULL)) + data = g_strdup(it->data); + else + data = g_strdup(""); + } + else + data = g_locale_to_utf8(it->data, -1, NULL, NULL, NULL); + + ret = append_string(ret, data, TRUE); + g_free(data); + } + + while (strs) { + g_free(strs->data); + strs = g_slist_delete_link(strs, strs); + } + return ret; +} + +gchar* read_atoms(Display *d, guchar *val, guint n) +{ + gchar *ret; + guint i; + + ret = NULL; + for (i = 0; i < n; ++i) + ret = append_string(ret, XGetAtomName(d, ((guint32*)val)[i]), FALSE); + return ret; +} + +gchar* read_numbers(guchar *val, guint n, guint size) +{ + gchar *ret; + guint i; + + ret = NULL; + for (i = 0; i < n; ++i) + switch (size) { + case 8: + ret = append_int(ret, ((guint8*)val)[i]); + break; + case 16: + ret = append_int(ret, ((guint16*)val)[i]); + break; + case 32: + ret = append_int(ret, ((guint32*)val)[i]); + break; + default: + g_assert_not_reached(); /* unhandled size */ + } + + return ret; +} + +gboolean read_prop(Display *d, Window w, Atom prop, const gchar **type, gchar **val) +{ + guchar *ret; + guint nret; + gint size; + Atom ret_type; + + ret = NULL; + if (get_all(d, w, prop, &ret_type, &size, &ret, &nret)) { + *type = XGetAtomName(d, ret_type); + + if (strcmp(*type, "STRING") == 0) + *val = read_strings((gchar*)ret, nret, FALSE); + else if (strcmp(*type, "UTF8_STRING") == 0) + *val = read_strings((gchar*)ret, nret, TRUE); + else if (strcmp(*type, "ATOM") == 0) { + g_assert(size == 32); + *val = read_atoms(d, ret, nret); + } + else + *val = read_numbers(ret, nret, size); + + g_free(ret); + return TRUE; + } + return FALSE; +} + +void show_properties(Display *d, Window w, int argc, char **argv) +{ + Atom* props; + int i, n; + + props = XListProperties(d, w, &n); + + for (i = 0; i < n; ++i) { + const char *type; + char *name, *val; + + name = XGetAtomName(d, props[i]); + + if (read_prop(d, w, props[i], &type, &val)) { + int found = 1; + if (argc) { + int i; + + found = 0; + for (i = 0; i < argc; i++) + if (!strcmp(name, argv[i])) { + found = 1; + break; + } + } + if (found) + g_print("%s(%s) = %s\n", name, type, (val ? val : "")); + g_free(val); + } + + XFree(name); + } + + XFree(props); +} + +int main(int argc, char **argv) +{ + Display *d; + Window id, userid = None; + int i; + char *dname = NULL; + gboolean root = FALSE; + + for (i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--help")) { + return fail(NULL); + } + else if (!strcmp(argv[i], "--root")) + root = TRUE; + else if (!strcmp(argv[i], "--id")) { + if (++i == argc) + return fail(NULL); + if (argv[i][0] == '0' && argv[i][1] == 'x') { + /* hex */ + userid = parse_hex(argv[i]+2); + } + else { + /* decimal */ + userid = atoi(argv[i]); + } + if (!userid) + return fail("Unable to parse argument to --id."); + } + else if (!strcmp(argv[i], "--display")) { + if (++i == argc) + return fail(NULL); + dname = argv[i]; + } + else if (*argv[i] != '-') + break; + else if (!strcmp(argv[i], "--")) { + i++; + break; + } + else + return fail(NULL); + } + + d = XOpenDisplay(dname); + if (!d) { + return fail("Unable to find an X display. " + "Ensure you have permission to connect to the display."); + } + + if (root) + userid = RootWindow(d, DefaultScreen(d)); + + if (userid == None) { + int j; + j = XGrabPointer(d, RootWindow(d, DefaultScreen(d)), + False, ButtonPressMask, + GrabModeAsync, GrabModeAsync, + None, XCreateFontCursor(d, XC_crosshair), + CurrentTime); + if (j != GrabSuccess) + return fail("Unable to grab the pointer device"); + while (1) { + XEvent ev; + + XNextEvent(d, &ev); + if (ev.type == ButtonPress) { + XUngrabPointer(d, CurrentTime); + userid = ev.xbutton.subwindow; + break; + } + } + id = find_client(d, userid); + } + else + id = userid; /* they picked this one */ + + if (id == None) + return fail("Unable to find window with the requested ID"); + + show_properties(d, id, argc - i, &argv[i]); + + XCloseDisplay(d); + + return 0; +} diff --git a/tools/themeupdate/themeupdate.py b/tools/themeupdate/themeupdate.py new file mode 100755 index 0000000..c2ad6a7 --- /dev/null +++ b/tools/themeupdate/themeupdate.py @@ -0,0 +1,410 @@ +#! /usr/bin/python + +# themeupdate.py for the Openbox window manager +# This utility is for updating old themes from Blackbox, Fluxbox, and Openbox2 +# to Openbox3 +# +# Copyright (c) 2003-2007 Dana Jansens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# See the COPYING file for a copy of the GNU General Public License. + +import sys + +data = [] +valid = True + +def out(str): + sys.stderr.write(str) + sys.stderr.flush() + +def read_bool(): + while True: + inp = sys.stdin.readline(1).strip() + if inp == 'y' or inp == '': return True + if inp == 'n': return False + +def getkeyval(line): + key = line[:line.find(':')].strip() + value = line[line.find(':') + 1:].strip() + if not (key and value): + key = value = None + return key, value + +def find_key(data, keysubstr, exact = False): + i = 0 + n = len(data) + while i < n: + l = data[i] + key, value = getkeyval(l) + if key and value: + if (exact and key == keysubstr) or \ + (not exact and key.find(keysubstr) != -1): + return i, key, value + i += 1 + return -1, None, None + +def simple_replace(data): + pairs = {} + pairs['.picColor'] = '.imageColor' + pairs['menu.frame'] = 'menu.items' + pairs['menu.hilite'] = 'menu.selected' + pairs['borderColor'] = 'border.color' + pairs['imageColor'] = 'image.color' + pairs['textColor'] = 'text.color' + pairs['interlaceColor'] = 'interlace.color' + + for k in pairs.keys(): + while 1: + i, key, nul = find_key(data, k); + if i >= 0: + newl = data[i].replace(k, pairs[k]) + out('Updating "' + key + + '" to "' + key.replace(k, pairs[k]) + '"\n') + data[i] = newl + else: + break + + pairs = {} + pairs['window.focus.font'] = 'window.active.label.text.font' + pairs['window.unfocus.font'] = 'window.inactive.label.text.font' + pairs['window.justify'] = 'window.label.justify' + pairs['menu.frame.disableColor'] = 'menu.disabled.textColor' + pairs['window.label.focus.font'] = 'window.active.label.text.font' + pairs['window.label.unfocus.font'] = 'window.inactive.label.text.font' + pairs['window.label.justify'] = 'window.label.text.justify' + pairs['menu.title.font'] = 'menu.title.text.font' + pairs['menu.title.justify'] = 'menu.title.text.justify' + pairs['menuOverlap'] = 'menu.overlap' + pairs['handleWidth'] = 'window.handle.width' + pairs['borderWidth'] = 'border.width' + pairs['bevelWidth'] = 'padding.width' + pairs['frameWidth'] = 'window.client.padding.width' + pairs['window.frame.focusColor'] = 'window.active.client.color' + pairs['window.frame.unfocusColor'] = 'window.inactive.client.color' + pairs['window.title.focus'] = 'window.active.title.bg' + pairs['window.title.unfocus'] = 'window.inactive.title.bg' + pairs['window.label.focus'] = 'window.active.label.bg' + pairs['window.label.unfocus'] = 'window.inactive.label.bg' + pairs['window.handle.focus'] = 'window.active.handle.bg' + pairs['window.handle.unfocus'] = 'window.inactive.handle.bg' + pairs['window.grip.focus'] = 'window.active.grip.bg' + pairs['window.grip.unfocus'] = 'window.inactive.grip.bg' + pairs['menu.items'] = 'menu.items.bg' + pairs['menu.title'] = 'menu.title.bg' + pairs['menu.selected'] = 'menu.items.active.bg' + pairs['window.title.focus'] = 'window.active.title.bg' + pairs['window.label.focus'] = 'window.active.label.bg' + pairs['window.title.unfocus'] = 'window.inactive.title.bg' + pairs['window.label.unfocus'] = 'window.inactive.label.bg' + pairs['window.button.disabled.focus'] = 'window.active.button.disabled.bg' + pairs['window.button.disabled.unfocus'] = \ + 'window.inactive.button.disabled.bg' + pairs['window.button.pressed.focus'] = 'window.active.button.pressed.bg' + pairs['window.button.pressed.unfocus'] = \ + 'window.inactive.button.pressed.bg' + pairs['window.button.toggled.focus'] = 'window.active.button.toggled.bg' + pairs['window.button.toggled.unfocus'] = \ + 'window.inactive.button.toggled.bg' + pairs['window.button.focus'] = 'window.active.button.unpressed.bg' + pairs['window.button.unfocus'] = 'window.inactive.button.unpressed.bg' + pairs['window.button.hover.focus'] = 'window.active.button.hover.bg' + pairs['window.button.hover.unfocus'] = 'window.inactive.button.hover.bg' + + for k in pairs.keys(): + while 1: + i, key, nul = find_key(data, k, True); + if i >= 0: + newl = data[i].replace(k, pairs[k]) + out('Updating "' + key + + '" to "' + key.replace(k, pairs[k]) + '"\n') + data[i] = newl + else: + break + + pairs = {} + pairs['window.title.focus'] = 'window.active.title' + pairs['window.title.unfocus'] = 'window.inactive.title' + pairs['window.label.focus'] = 'window.active.label' + pairs['window.label.unfocus'] = 'window.inactive.label' + pairs['window.handle.focus'] = 'window.active.handle' + pairs['window.handle.unfocus'] = 'window.inactive.handle' + pairs['window.grip.focus'] = 'window.active.grip' + pairs['window.grip.unfocus'] = 'window.inactive.grip' + pairs['menu.selected'] = 'menu.items.active' + pairs['window.title.focus'] = 'window.active.title' + pairs['window.label.focus'] = 'window.active.label' + pairs['window.title.unfocus'] = 'window.inactive.title' + pairs['window.label.unfocus'] = 'window.inactive.label' + pairs['window.button.disabled.focus'] = 'window.active.button.disabled' + pairs['window.button.disabled.unfocus'] = \ + 'window.inactive.button.disabled' + pairs['window.button.pressed.focus'] = 'window.active.button.pressed' + pairs['window.button.pressed.unfocus'] = \ + 'window.inactive.button.pressed' + pairs['window.button.toggled.focus'] = 'window.active.button.toggled' + pairs['window.button.toggled.unfocus'] = \ + 'window.inactive.button.toggled' + pairs['window.button.focus'] = 'window.active.button' + pairs['window.button.unfocus'] = 'window.inactive.button' + pairs['window.button.hover.focus'] = 'window.active.button.hover' + pairs['window.button.hover.unfocus'] = 'window.inactive.button.hover' + pairs['window.label.unfocus'] = 'window.inactive.label' + pairs['window.label.focus'] = 'window.active.label' + pairs['window.button.focus'] = 'window.active.button.unpressed' + pairs['menu.disabled'] = 'menu.items.disabled' + pairs['menu.selected'] = 'menu.items.active' + pairs['window.button.unfocus'] = 'window.inactive.button.unpressed' + pairs['window.button.pressed.focus'] = 'window.active.button.pressed' + pairs['window.button.pressed.unfocus'] = 'window.inactive.button.pressed' + pairs['window.button.disabled.focus'] = 'window.active.button.disabled' + pairs['window.button.disabled.unfocus'] = 'window.inactive.button.disabled' + pairs['window.button.hover.focus'] = 'window.active.button.hover' + pairs['window.button.hover.unfocus'] = 'window.inactive.button.hover' + pairs['window.button.toggled.focus'] = 'window.active.button.toggled' + pairs['window.button.toggled.unfocus'] = 'window.inactive.button.toggled' + + for k in pairs.keys(): + while 1: + i, key, nul = find_key(data, k); + if i >= 0: + newl = data[i].replace(k, pairs[k]) + out('Updating "' + key + + '" to "' + key.replace(k, pairs[k]) + '"\n') + data[i] = newl + else: + break + +def replace_colors(data): + i = 0 + n = len(data) + while i < n: + l = data[i] + key, value = getkeyval(l) + if key and value: + if key.find('.color') != -1: + if key.find('client.color') == -1 \ + and key.find('image.color') == -1 \ + and key.find('bg.color') == -1 \ + and key.find('border.color') == -1 \ + and key.find('interlace.color') == -1 \ + and key.find('text.color') == -1: + newl = data[i].replace('.color', '.bg.color') + out('Updating "' + key + + '" to "' + key.replace('.color', '.bg.color') + '"\n') + data[i] = newl + if key.find('.border.color') != -1 \ + and key.find('bg.border.color') == -1: + newl = data[i].replace('.border.color', '.bg.border.color') + out('Updating "' + key + + '" to "' + key.replace('.border.color', + '.bg.border.color') + '"\n') + data[i] = newl + if key.find('.interlace.color') != -1 \ + and key.find('bg.interlace.color') == -1: + newl = data[i].replace('.interlace.color', + '.bg.interlace.color') + out('Updating "' + key + + '" to "' + key.replace('.interlace.color', + '.bg.interlace.color') + '"\n') + data[i] = newl + i += 1 + +def remove(data): + invalid = [] + invalid.append('toolbar') + for inv in invalid: + while 1: + i, key, nul = find_key(data, inv) + if i >= 0: + out(key + ' is no longer supported.\nRemove (Y/n)? ') + if read_bool(): + out('Removing "' + key + '"\n') + data.pop(i) + else: + break + invalid.append('rootCommand') + invalid.append('menu.bullet') + invalid.append('menu.bullet.image.color') + invalid.append('menu.bullet.selected.image.color') + invalid.append('menu.frame.justify') + for inv in invalid: + while 1: + i, key, nul = find_key(data, inv, True) + if i >= 0: + out(key + ' is no longer supported.\nRemove (Y/n)? ') + if read_bool(): + out('Removing "' + key + '"\n') + data.pop(i) + else: + break + +def pressed(data): + i, nul, nul = find_key(data, 'window.button.pressed', True) + if i >= 0: + out('The window.button.pressed option has been replaced by ' + + 'window.button.pressed.focus and ' + + 'window.button.pressed.unfocus.\nUpdate (Y/n)? ') + if read_bool(): + l = data[i] + out('Removing "window.button.pressed"\n') + data.pop(i) + out('Adding "window.button.pressed.unfocus"\n') + data.insert(i, l.replace('window.button.pressed', + 'window.button.pressed.unfocus')) + out('Adding "window.button.pressed.focus"\n') + data.insert(i, l.replace('window.button.pressed', + 'window.button.pressed.focus')) + +def x_fonts(data): + i, nul, nul = find_key(data, 'window.font') + if i >= 0: + out('You appear to specify fonts using the old X fonts ' + + 'syntax.\nShall I remove all fonts from the theme (Y/n)? ') + if not read_bool(): + return + else: return + while 1: + i, key, nul = find_key(data, '.font') + if i < 0: + break + out('Removing "' + key + '"\n') + data.pop(i) + +def xft_fonts(data): + i, nul, nul = find_key(data, '.xft.') + if i >= 0: + out('You appear to specify fonts using the old Xft fonts ' + + 'syntax.\nShall I update these to the new syntax (Y/n)? ') + if not read_bool(): + return + else: return + fonts = {} + fonts['window'] = 'window.label.focus.font' + fonts['menu.items'] = 'menu.items.font' + fonts['menu.title'] = 'menu.title.font' + for f in fonts.keys(): + li, nul, flags = find_key(data, f + '.xft.flags') + if li < 0: + li, nul, flags = find_key(data, '*.xft.flags') + else: + out('Removing ' + f + '.xft.flags\n') + data.pop(li) + oi, nul, offset = find_key(data, f + '.xft.shadow.offset') + if oi < 0: + oi, nul, offset = find_key(data, '*.xft.shadow.offset') + else: + out('Removing ' + f + '.xft.shadow.offset\n') + data.pop(oi) + ti, nul, tint = find_key(data, f + '.xft.shadow.tint') + if ti < 0: + ti, nul, tint = find_key(data, '*.xft.shadow.tint') + else: + out('Removing ' + f + '.xft.shadow.tint\n') + data.pop(ti) + fi, nul, face = find_key(data, f + '.xft.font') + if fi < 0: + fi, nul, face = find_key(data, '*.xft.font') + if fi >= 0: fi = len(data) - 1 + else: + out('Removing ' + f + '.xft.font\n') + data.pop(fi) + + if fi >= 0: + s = face + if li >= 0: + if flags.find('bold'): + s = s + ':bold' + if flags.find('shadow'): + s = s + ':shadow=y' + if oi >= 0: + s = s + ':shadowoffset=' + offset + if ti >= 0: + s = s + ':shadowtint=' + tint + out('Adding ' + fonts[f] + '\n') + data.insert(fi, fonts[f] + ': ' + s) + + for stars in ('*.xft.flags', '*.xft.shadow.offset' , + '*.xft.shadow.tint', '*.xft.font'): + i, key, nul = find_key(data, stars) + if i >= 0: + out('Removing ' + key + '\n') + data.pop(i) + +def pixelsize(data): + fonts = ('window.label.focus.font', + 'menu.items.font', + 'menu.title.font') + for f in fonts: + i, key, value = find_key(data, f, True) + if value: + if value.find('pixelsize') == -1: + out('*** ERROR *** The ' + key + ' font size is not being ' + 'specified by pixelsize. It is recommended that you use ' + 'pixelsize instead of pointsize for specifying theme ' + 'fonts. e.g. "sans:pixelsize=12"\n') + global valid + valid = False + +def warn_missing(data): + need = ('window.active.button.hover', 'window.inactive.button.hover', + 'menu.overlap') + for n in need: + i, nul, nul = find_key(data, n) + if i < 0: + out('The ' + n + ' value was not found in the theme, but it ' + 'can optionally be set.\n') + +def err_missing(data): + need = ('window.active.button.disabled', + 'window.inactive.button.disabled', + 'window.active.client.color', + 'window.inactive.client.color') + for n in need: + i, nul, nul = find_key(data, n) + if i < 0: + out('*** ERROR *** The ' + n + ' value was not found in the ' + 'theme, but it is required to be set.\n') + global valid + valid = False + + +def usage(): + out('Usage: themupdate.py /path/to/themerc > newthemerc\n\n') + sys.exit() + +try: + file = open(sys.argv[1]) +except IndexError: + usage() +except IOError: + out('Unable to open file "' + sys.argv[1] + '"\n\n') + usage() + +data = file.readlines() +for i in range(len(data)): + data[i] = data[i].strip() + +simple_replace(data) +replace_colors(data) +remove(data) +pressed(data) +x_fonts(data) +xft_fonts(data) +pixelsize(data) +warn_missing(data) +err_missing(data) + +for l in data: + print l + +sys.exit(not valid) |