/* * simple.c: Simple dialog widgets * * Written by: Ullrich Hafner * * Copyright (C) 1999 Ullrich Hafner * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. */ /* * $Date: 2000/09/03 19:22:05 $ * $Author: hafner $ * $Revision: 1.15 $ * $State: Exp $ */ #include "config.h" #include #include #include #include "proplist_t.h" #include "simple.h" #include "dialog.h" #include "menu.h" #include "texture.h" #include "misc.h" #include "window.h" #include "themebrowser.h" #include "error.h" /******************************************************************************* global variables *******************************************************************************/ extern bool_t changed; /* window.c */ extern proplist_t windowmaker; /* window.c */ /******************************************************************************* local variables *******************************************************************************/ #ifdef HAVE_LIBWMFUN static const char **color_types = NULL; /******************************************************************************* prototypes *******************************************************************************/ static void color_toggle (GtkWidget *widget, gpointer ptr); static void show_color_buttons (text_color_t *text_color); static void update_text_color (proplist_t key, gpointer ptr, proplist_t value, const char *path); #endif /* HAVE_LIBWMFUN */ static void set_bool (GtkWidget *widget, gpointer ptr); static void set_ibool (GtkWidget *widget, gpointer ptr); static void append_dialog (GtkWidget *container, GtkWidget *left, GtkWidget *right, GtkAttachOptions attach); static void set_string (GtkWidget *widget, gpointer ptr); static void set_int (GtkWidget *widget, gpointer ptr); static void set_entry_text (GtkWidget *widget, gpointer ptr); static void convert_pango_to_fontconfig (const char *pangoname, char *fcname); static void convert_fontconfig_to_pango (const char *fcname, char *pangoname); static void set_fontname (GtkWidget *widget, gpointer ptr); static void fontsel_dialog (GtkWidget *widget, gpointer ptr); static void update_entry (proplist_t key, gpointer ptr, proplist_t value, const char *path); static void update_color (proplist_t key, gpointer ptr, proplist_t value, const char *path); static void update_boolean (proplist_t key, gpointer ptr, proplist_t value, const char *path); static void update_iboolean (proplist_t key, gpointer ptr, proplist_t value, const char *path); static void update_int (proplist_t key, gpointer ptr, proplist_t value, const char *path); /******************************************************************************* public code *******************************************************************************/ void boolean_dialog (GtkWidget *table, proplist_t key, proplist_t value, proplist_t info) { GtkWidget *label = gtk_label_new (D_(WMGetFromPLString (info))); GtkWidget *button = gtk_check_button_new (); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), convert_bool (value)); gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (set_bool), (gpointer) key); append_dialog (table, label, button, GTK_SHRINK); connect_update_function (key, button, update_boolean); } void iboolean_dialog (GtkWidget *table, proplist_t key, proplist_t value, proplist_t info) { GtkWidget *label = gtk_label_new (D_(WMGetFromPLString (info))); GtkWidget *button = gtk_check_button_new (); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), convert_bool (value) ? FALSE : TRUE); gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (set_ibool), (gpointer) key); append_dialog (table, label, button, GTK_SHRINK); connect_update_function (key, button, update_iboolean); } void string_dialog (GtkWidget *table, proplist_t key, proplist_t value, proplist_t range, proplist_t rinfo, proplist_t info) { GtkWidget *option_menu; GtkWidget *label = gtk_label_new (D_(WMGetFromPLString (info))); const char **values; unsigned n, current = 0; values = Calloc (WMGetPropListItemCount (range) + 1, sizeof (char *)); for (n = 0; n < WMGetPropListItemCount (range); n++) { proplist_t element = WMGetFromPLArray (range, n); if (strcaseeq (WMGetFromPLString (element), WMGetFromPLString (value))) current = n; values [n] = WMGetFromPLString (element); } values [n] = NULL; option_menu = generate_option_menu (NULL, NULL, NULL, values, values [current], rinfo, set_string, key); append_dialog (table, option_menu, label, GTK_FILL | GTK_SHRINK); { omenudata_t *data = Calloc (1, sizeof (omenudata_t)); data->omenu = GTK_OPTION_MENU (option_menu); data->values = values; connect_update_function (key, data, update_optionmenu); } } void int_dialog (GtkWidget *table, proplist_t key, proplist_t value, proplist_t range, proplist_t rinfo, proplist_t info) { GtkWidget *label = gtk_label_new (D_(WMGetFromPLString (info))); GtkWidget *hbox = gtk_hbox_new (FALSE, 5); GtkEntry **array = Calloc (WMGetPropListItemCount (range) / 2 + 1, sizeof (GtkEntry *)); unsigned n; for (n = 0; n < WMGetPropListItemCount (range); n += 2) { GtkWidget *spinner; GtkObject *adj; char *m = WMGetFromPLString (WMGetFromPLArray (range, n)); char *M = WMGetFromPLString (WMGetFromPLArray (range, n + 1)); char *v; if (WMIsPLArray (value)) v = WMGetFromPLString (WMGetFromPLArray (value, n / 2)); else v = WMGetFromPLString (value); adj = gtk_adjustment_new (strtod (v, NULL), strtod (m, NULL), strtod (M, NULL), 1.0, 5.0, 0.0); spinner = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 0, 0); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinner), TRUE); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE); gtk_widget_show_all (spinner); gtk_object_set_user_data (GTK_OBJECT (adj), (gpointer) spinner); gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 0); gtk_object_set_user_data (GTK_OBJECT (spinner), (gpointer) (spinner + n / 2)); gtk_signal_connect (GTK_OBJECT (adj), "value_changed", GTK_SIGNAL_FUNC (set_int), (gpointer) key); gtk_signal_connect (GTK_OBJECT (>K_SPIN_BUTTON (spinner)->entry), "changed", GTK_SIGNAL_FUNC (set_entry_text), (gpointer) key); array [n / 2] = >K_SPIN_BUTTON (spinner)->entry; } array [n / 2] = NULL; append_dialog (table, hbox, label, GTK_FILL | GTK_SHRINK); connect_update_function (key, array, update_int); } void text_dialog (GtkWidget *table, proplist_t key, proplist_t value, proplist_t info) { GtkWidget *entry = gtk_entry_new (); GtkWidget *label = gtk_label_new (D_(WMGetFromPLString (info))); gtk_widget_set_usize (entry, 100, 0); gtk_entry_set_text (GTK_ENTRY (entry), WMGetFromPLString (value)); gtk_signal_connect (GTK_OBJECT (entry), "changed", GTK_SIGNAL_FUNC (set_entry_text), key); append_dialog (table, entry, label, GTK_FILL | GTK_SHRINK); connect_update_function (key, entry, update_entry); } GtkWidget * font_dialog (GtkWidget *page, proplist_t key, proplist_t value, proplist_t info) { GtkWidget *entry = gtk_entry_new (); GtkWidget *frame = gtk_frame_new (D_(WMGetFromPLString (info))); GtkWidget *hbox = gtk_hbox_new (FALSE, 0); GtkWidget *bbox = gtk_hbutton_box_new (); GtkWidget *button = gtk_button_new_with_label (_("Browse...")); gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); gtk_container_add (GTK_CONTAINER (frame), hbox); gtk_entry_set_text (GTK_ENTRY (entry), WMGetFromPLString (value)); gtk_signal_connect (GTK_OBJECT (entry), "changed", GTK_SIGNAL_FUNC (set_entry_text), key); gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 5); gtk_box_pack_start (GTK_BOX (hbox), bbox, FALSE, TRUE, 5); gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, TRUE, 5); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (fontsel_dialog), (gpointer) entry); gtk_box_pack_end (GTK_BOX (page), frame, TRUE, TRUE, 5); gtk_widget_show_all (frame); connect_update_function (key, entry, update_entry); return frame; } GtkWidget * color_dialog (GtkWidget *page, proplist_t key, proplist_t value, GtkTooltips *tooltips, proplist_t info, proplist_t title) { GtkWidget *frame; GtkWidget *button = color_button (NULL, key, value, tooltips, D_(WMGetFromPLString (info))); GtkWidget *hbox = gtk_hbox_new (TRUE, 0); if (title) frame = gtk_frame_new (D_(WMGetFromPLString (title))); else frame = gtk_frame_new (WMGetFromPLString (key)); gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5); gtk_container_add (GTK_CONTAINER (frame), hbox); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (page), frame, FALSE, TRUE, 5); gtk_widget_show_all (frame); connect_update_function (key, gtk_object_get_user_data (GTK_OBJECT (button)), update_color); return frame; } #ifdef HAVE_LIBWMFUN GtkWidget * extended_color_dialog (GtkWidget *page, proplist_t key, proplist_t value, GtkTooltips *tooltips, proplist_t info, proplist_t title) { GtkWidget *frame; GtkWidget *option_menu; text_color_t *text_color = Calloc (1, sizeof (text_color_t)); GtkWidget *hbox = gtk_hbox_new (FALSE, 5); gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); frame = gtk_frame_new (_("Color of title text")); text_color->key = key; if (!color_types) { color_types = Calloc (TCOLOR_LAST, sizeof (char *)); color_types [TCOLOR_SIMPLE] = _("Solid color"); color_types [TCOLOR_COLORSET] = _("Drop shadow"); color_types [TCOLOR_LAST] = NULL; } option_menu = generate_option_menu (NULL, tooltips, _("A solid color or a drop shadow."), color_types, color_types [0], NULL, color_toggle, text_color); text_color->option_menu = option_menu; gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5); gtk_container_add (GTK_CONTAINER (frame), hbox); gtk_box_pack_start (GTK_BOX (hbox), option_menu, FALSE, FALSE, 0); text_color->solid_color = color_button (NULL, key, NULL, NULL, NULL); gtk_box_pack_start (GTK_BOX (hbox), text_color->solid_color, FALSE, TRUE, 0); text_color->color_set [0] = color_button (NULL, key, NULL, tooltips, _("Foreground")); gtk_box_pack_start (GTK_BOX (hbox), text_color->color_set [0], FALSE, TRUE, 0); text_color->color_set [1] = color_button (NULL, key, NULL, tooltips, _("Shadow 1")); gtk_box_pack_start (GTK_BOX (hbox), text_color->color_set [1], FALSE, TRUE, 0); text_color->color_set [2] = color_button (NULL, key, NULL, tooltips, _("Shadow 2")); gtk_box_pack_start (GTK_BOX (hbox), text_color->color_set [2], FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0); gtk_widget_show_all (frame); show_color_buttons (text_color); connect_update_function (key, text_color, update_text_color); return frame; } #endif /* HAVE_LIBWMFUN */ void update_optionmenu (proplist_t key, gpointer ptr, proplist_t value, const char *path) { omenudata_t *data = (omenudata_t *) ptr; if (WMIsPLString (value)) set_option_menu_default (data->omenu, data->values, WMGetFromPLString (value)); } bool_t convert_bool (proplist_t p) /* * Parse boolean values of WindowMaker file. * * Return value: * converted value */ { char *val; assert (p && (WMIsPLString (p) || WMIsPLData (p))); val = WMGetFromPLString (p); if (strcaseeq (val, "y") || strcaseeq (val, "yes") || strcaseeq (val, "t") || strcaseeq (val, "true") || strcaseeq (val, "1")) return TRUE; else if (strcaseeq (val, "n") || strcaseeq (val, "no") || strcaseeq (val, "f") || strcaseeq (val, "false") || strcaseeq (val, "0")) return FALSE; else { warning (_("Undefined boolean value '%s' converted to true."), val); return TRUE; } } /******************************************************************************* private code *******************************************************************************/ #ifdef HAVE_LIBWMFUN static void color_toggle (GtkWidget *widget, gpointer ptr) { char *text = gtk_object_get_user_data (GTK_OBJECT (widget)); text_color_t *text_color = (text_color_t *) ptr; proplist_t value = WMGetFromPLDictionary (windowmaker, text_color->key); if (text == color_types [TCOLOR_SIMPLE]) { if (!WMIsPLString (value)) { WMPutInPLDictionary (windowmaker, text_color->key, WMCreatePLString ("tan")); toggle_save (changed = YES, text_color->key); show_color_buttons (text_color); } } else { if (!WMIsPLArray (value)) { proplist_t pl; pl = WMCreatePLArray (WMCreatePLString ("function"), WMCreatePLString ("libwmfun.so"), WMCreatePLString ("drawPlainString"), WMCreatePLString ("white"), WMCreatePLString ("black"), WMCreatePLString ("red"), NULL); WMPutInPLDictionary (windowmaker, text_color->key, pl); toggle_save (changed = YES, text_color->key); show_color_buttons (text_color); } } } static void show_color_buttons (text_color_t *text_color) { proplist_t value = WMGetFromPLDictionary (windowmaker, text_color->key); if (WMIsPLArray (value)) /* check syntax of value */ { if (!(WMGetPropListItemCount (value) == 6 && strcaseeq (WMGetFromPLString (WMGetFromPLArray (value, 0)), "function") && strncaseeq (WMGetFromPLString (WMGetFromPLArray (value, 1)), "libwmfun", strlen ("libwmfun")) && strcaseeq (WMGetFromPLString (WMGetFromPLArray (value, 2)), "drawPlainString"))) { proplist_t pl; pl = WMCreatePLArray (WMCreatePLString ("function"), WMCreatePLString ("libwmfun.so"), WMCreatePLString ("drawPlainString"), WMCreatePLString ("white"), WMCreatePLString ("black"), WMCreatePLString ("red"), NULL); WMPutInPLDictionary (windowmaker, text_color->key, pl); value = pl; } set_option_menu_default (GTK_OPTION_MENU (text_color->option_menu), color_types, color_types [TCOLOR_COLORSET]); /* * Set colors */ { GtkWidget *preview; preview = gtk_object_get_user_data (GTK_OBJECT (text_color->color_set [0])); fill_preview (GTK_PREVIEW (preview), WMGetFromPLString (WMGetFromPLArray (value, 3))); gtk_object_set_user_data (GTK_OBJECT (preview), WMGetFromPLArray (value, 3)); preview = gtk_object_get_user_data (GTK_OBJECT (text_color->color_set [1])); fill_preview (GTK_PREVIEW (preview), WMGetFromPLString (WMGetFromPLArray (value, 4))); gtk_object_set_user_data (GTK_OBJECT (preview), WMGetFromPLArray (value, 4)); preview = gtk_object_get_user_data (GTK_OBJECT (text_color->color_set [2])); fill_preview (GTK_PREVIEW (preview), WMGetFromPLString (WMGetFromPLArray (value, 5))); gtk_object_set_user_data (GTK_OBJECT (preview), WMGetFromPLArray (value, 5)); } gtk_widget_show (text_color->color_set [0]); gtk_widget_show (text_color->color_set [1]); gtk_widget_show (text_color->color_set [2]); gtk_widget_hide (text_color->solid_color); } else { gtk_widget_hide (text_color->color_set [0]); gtk_widget_hide (text_color->color_set [1]); gtk_widget_hide (text_color->color_set [2]); gtk_widget_show (text_color->solid_color); set_option_menu_default (GTK_OPTION_MENU (text_color->option_menu), color_types, color_types [TCOLOR_SIMPLE]); /* * Set default color */ { GtkWidget *preview; preview = gtk_object_get_user_data (GTK_OBJECT (text_color->solid_color)); fill_preview (GTK_PREVIEW (preview), WMGetFromPLString (value)); gtk_object_set_user_data (GTK_OBJECT (preview), value); } } } #endif /* HAVE_LIBWMFUN */ static void append_dialog (GtkWidget *container, GtkWidget *left, GtkWidget *right, GtkAttachOptions attach) { if (GTK_IS_TABLE (container)) { unsigned *number = (unsigned *) gtk_object_get_user_data (GTK_OBJECT (container)); unsigned row, col; row = ++*number; col = (row % 2) * 2; row /= 2; gtk_table_attach (GTK_TABLE (container), left, col, col + 1, row, row + 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); gtk_table_attach (GTK_TABLE (container), right, col + 1, col + 2, row, row + 1, attach, attach, 0, 0); gtk_widget_show_all (left); gtk_widget_show_all (right); } else if (GTK_IS_VBOX (container)) { GtkWidget *hbox = gtk_hbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (container), 5); gtk_box_pack_start (GTK_BOX (hbox), right, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), left, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (container), hbox, FALSE, FALSE, 0); gtk_widget_show_all (hbox); } } static void set_bool (GtkWidget *widget, gpointer ptr) /* * Update boolean value. * * No return value. */ { proplist_t key = (proplist_t) ptr; char *text = GTK_TOGGLE_BUTTON (widget)->active ? "Yes" : "No"; proplist_t pl = WMCreatePLString (text); WMPutInPLDictionary (windowmaker, key, pl); WMReleasePropList (pl); toggle_save (changed = YES, key); if (strcaseeq (WMGetFromPLString (key), "NewStyle")) check_widgetstyle (); } static void set_ibool (GtkWidget *widget, gpointer ptr) /* * Update boolean value. * * No return value. */ { proplist_t key = (proplist_t) ptr; char *text = GTK_TOGGLE_BUTTON (widget)->active ? "No" : "Yes"; proplist_t pl = WMCreatePLString (text); WMPutInPLDictionary (windowmaker, key, pl); WMReleasePropList (pl); toggle_save (changed = YES, key); if (strcaseeq (WMGetFromPLString (key), "NewStyle")) check_widgetstyle (); } static void set_string (GtkWidget *widget, gpointer ptr) /* * Update string value. * * No return value. */ { proplist_t key = (proplist_t) ptr; char *text = gtk_object_get_user_data (GTK_OBJECT (widget)); proplist_t pl = WMCreatePLString (text); WMPutInPLDictionary (windowmaker, key, pl); WMReleasePropList (pl); toggle_save (changed = YES, key); } static void set_int (GtkWidget *widget, gpointer ptr) /* * Update unsigned value. * * No return value. */ { proplist_t key = (proplist_t) ptr; GtkSpinButton *spinner; int val; char tmp [MAXSTRLEN]; spinner = GTK_SPIN_BUTTON (gtk_object_get_user_data (GTK_OBJECT (widget))); val = gtk_spin_button_get_value_as_int (spinner); sprintf (tmp, "%d", val); if (WMIsPLArray (WMGetFromPLDictionary (windowmaker, key))) { proplist_t array = WMGetFromPLDictionary (windowmaker, key); unsigned n; n = (GtkWidget *) gtk_object_get_user_data (GTK_OBJECT (spinner)) - GTK_WIDGET (spinner); WMDeleteFromPLArray (array, n); WMInsertInPLArray (array, n, WMCreatePLString (tmp)); } else { proplist_t pl = WMCreatePLString (tmp); WMPutInPLDictionary (windowmaker, key, pl); WMReleasePropList (pl); } toggle_save (changed = YES, key); } static void set_entry_text (GtkWidget *widget, gpointer ptr) /* * Update string value. * * No return value. */ { proplist_t element; proplist_t key = (proplist_t) ptr; proplist_t array = WMGetFromPLDictionary (windowmaker, key); element = WMCreatePLString ((char *) gtk_entry_get_text (GTK_ENTRY (widget))); if (WMIsPLArray (array)) { WMDeleteFromPLArray (array, 1); /* filename */ WMInsertInPLArray (array, 1, element); } else { WMPutInPLDictionary (windowmaker, key, element); WMReleasePropList (element); } toggle_save (changed = YES, key); } static void fontsel_dialog (GtkWidget *widget, gpointer ptr) { static GtkWidget *fontsel = NULL; if (!fontsel) { GtkWidget *entry; const char *text; char *pangotext; GtkFontSelectionDialog *fs; entry = GTK_WIDGET (ptr); text = gtk_entry_get_text (GTK_ENTRY (entry)); pangotext = malloc (strlen (text) + 1); fontsel = gtk_font_selection_dialog_new (_("Font selection")); fs = GTK_FONT_SELECTION_DIALOG (fontsel); gtk_window_set_position (GTK_WINDOW (fontsel), GTK_WIN_POS_MOUSE); gtk_object_set_user_data (GTK_OBJECT (fontsel), entry); convert_fontconfig_to_pango (text, pangotext); gtk_font_selection_dialog_set_font_name (fs, pangotext); free (pangotext); gtk_object_set_data (GTK_OBJECT (entry), "fontsel", fontsel); gtk_signal_connect (GTK_OBJECT (fontsel), "destroy", GTK_SIGNAL_FUNC (gtk_widget_destroyed), &fontsel); gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked", GTK_SIGNAL_FUNC (set_fontname), fontsel); gtk_signal_connect_object (GTK_OBJECT (fs->ok_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (fontsel)); gtk_signal_connect_object (GTK_OBJECT (fs->cancel_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (fontsel)); } if (!GTK_WIDGET_VISIBLE (fontsel)) gtk_widget_show (fontsel); else gtk_widget_destroy (fontsel); } struct font_attr_t { int slant; int weight; int width; int size; }; /* Function to convert from GTK+ 2's Pango font names to the slightly * different format used by WindowMaker 0.90 (fontconfig?) * fcname must already be allocated and have a length of at least * strlen(pangoname) + 50. */ static void convert_pango_to_fontconfig (const char *pangoname, char *fcname) { const char * posn; char * base; int size; struct font_attr_t attr = { 0, 80, 100, 12 }; posn = pangoname + strlen(pangoname) - 1; while (posn > pangoname && isdigit(*posn)) posn--; size = atoi(posn); if (size) attr.size = size; /* check for italic */ if (posn - pangoname > 6 && strncmp(posn - 6, "Italic", 6) == 0) { attr.slant = 100; posn -= 7; } /* check for condensed */ if (posn - pangoname > 9 && strncmp(posn - 9, "Condensed", 9) == 0) { attr.width = 75; posn -= 10; } /* check for bold */ if (posn - pangoname > 9 && strncmp(posn - 9, "Semi-Bold", 9) == 0) { attr.weight = 100; posn -= 10; } else if (posn - pangoname > 4 && strncmp(posn - 4, "Bold", 4) == 0) { attr.weight = 200; posn -= 5; } if (posn > pangoname && *(posn - 1) == ',') posn--; base = malloc(posn - pangoname + 10); strncpy(base, pangoname, posn - pangoname); base[posn - pangoname] = 0; /* Sans and Serif aliases are slightly different in Pango vs. fontconfig */ if (strcmp(base, "Sans") == 0) strcpy(base, "sans serif"); else if (strcmp(base, "Serif") == 0) strcpy(base, "serif"); sprintf(fcname, "%s:slant=%d:weight=%d:width=%d:pixelsize=%d", base, attr.slant, attr.weight, attr.width, attr.size); free(base); } /* Function to convert from WindowMaker 0.90's fontconfig font name format * to that used by Pango in GTK+ 2. * pangoname must already be allocated and have a length of at least * strlen(fcname). */ static void convert_fontconfig_to_pango (const char *fcname, char *pangoname) { char * base, * posn, * posn2; char slant[8] = { 0 }, weight[11] = { 0 }, width[11] = { 0 }; int size = 12; /* Find the first ':' or ',' and assume this is the end of the font name */ posn = strchr(fcname, ':'); posn2 = strchr(fcname, ','); if (!posn || posn2 && posn2 < posn) posn = posn2; if (posn) { base = malloc(posn - fcname + 1); strncpy(base, fcname, posn - fcname); base[posn - fcname] = 0; } else { /* maybe XLFD, don't touch */ strcpy(pangoname, fcname); return; } /* Sans and Serif aliases are slightly different in Pango vs. fontconfig */ if (strcmp(base, "sans serif") == 0) strcpy(base, "Sans"); else if (strcmp(base, "serif") == 0) strcpy(base, "Serif"); if ((posn = strstr(fcname, ":weight="))) { int wt = atoi(posn + 8); if (wt >= 150) strcpy(weight, "Bold "); else if (wt >= 90) strcpy(weight, "Semi-Bold "); } if ((posn = strstr(fcname, ":bold"))) strcpy(weight, "Bold "); if ((posn = strstr(fcname, ":width="))) if (atoi(posn + 7) < 90) strcpy(width, "Condensed "); if ((posn = strstr(fcname, ":slant="))) if (atoi(posn + 7)) strcpy(slant, "Italic "); if ((posn = strstr(fcname, ":pixelsize="))) { int sz = atoi(posn + 11); if (sz) size = sz; } sprintf(pangoname, "%s, %s%s%s%d", base, weight, width, slant, size); free(base); } static void set_fontname (GtkWidget *widget, gpointer ptr) { GtkWidget *fontsel = GTK_WIDGET (ptr); GtkWidget *entry = gtk_object_get_user_data (GTK_OBJECT (fontsel)); gchar *fontname; gchar *fontconfigname; fontname = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (fontsel)); fontconfigname = malloc(strlen(fontname) + 50); convert_pango_to_fontconfig(fontname, fontconfigname); gtk_entry_set_text (GTK_ENTRY (entry), fontconfigname); free(fontconfigname); } static void update_entry (proplist_t key, gpointer ptr, proplist_t value, const char *path) { if (WMIsPLString (value)) gtk_entry_set_text (GTK_ENTRY (ptr), WMGetFromPLString (value)); } static void update_color (proplist_t key, gpointer ptr, proplist_t value, const char *path) { if (WMIsPLString (value)) { GtkWidget *preview = GTK_WIDGET (ptr); //the below wasn't used; was it supposed to be? //proplist_t oldvalue = gtk_object_get_user_data (GTK_OBJECT (preview)); WMRetainPropList (value); gtk_object_set_user_data (GTK_OBJECT (preview), value); fill_preview (GTK_PREVIEW (preview), WMGetFromPLString (value)); WMPutInPLDictionary (windowmaker, key, value); toggle_save (changed = YES, key); } } #ifdef HAVE_LIBWMFUN static void update_text_color (proplist_t key, gpointer ptr, proplist_t value, const char *path) { if (WMIsPLString (value) || WMIsPLArray (value)) { text_color_t *text_color = (text_color_t *) ptr; WMPutInPLDictionary (windowmaker, key, value); toggle_save (changed = YES, key); show_color_buttons (text_color); } } #endif /* HAVE_LIBWMFUN */ static void update_boolean (proplist_t key, gpointer ptr, proplist_t value, const char *path) { if (WMIsPLString (value)) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptr), convert_bool (value)); set_bool (GTK_WIDGET (ptr), key); } } static void update_iboolean (proplist_t key, gpointer ptr, proplist_t value, const char *path) { if (WMIsPLString (value)) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptr), convert_bool (value) ? FALSE : TRUE); set_bool (GTK_WIDGET (ptr), key); } } static void update_int (proplist_t key, gpointer ptr, proplist_t value, const char *path) { GtkEntry **entry = (GtkEntry **) ptr; if (WMIsPLString (value)) gtk_entry_set_text (entry [0], WMGetFromPLString (value)); else if (WMIsPLArray (value)) { unsigned n; for (n = 0; n < WMGetPropListItemCount (value); n++) if (entry [n]) gtk_entry_set_text (entry [n], WMGetFromPLString (WMGetFromPLArray (value, n))); else break; } }