X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fdemo.c;h=bec72e0e8a4bf52185bc086063712cff504ae1e8;hb=72c1f4c1dc6ab07fe121a327ff1c30bf51ef74c1;hp=76e8917d6843797325700804f0cfa9d6884f7fe9;hpb=3210e7e80ee2b5a7d2049a5aaff9f17b9c93dcc9;p=xscreensaver diff --git a/driver/demo.c b/driver/demo.c index 76e8917d..bec72e0e 100644 --- a/driver/demo.c +++ b/driver/demo.c @@ -14,10 +14,24 @@ # include "config.h" #endif -#ifdef HAVE_ATHENA_KLUDGE /* don't ask */ + +#ifdef FORCE_ATHENA # undef HAVE_MOTIF # define HAVE_ATHENA 1 #endif +#ifdef FORCE_MOTIF +# undef HAVE_ATHENA +# define HAVE_MOTIF 1 +#endif + +/* Only one, please. */ +#ifdef HAVE_MOTIF +# undef HAVE_ATHENA +#endif +#ifdef HAVE_ATHENA +# undef HAVE_MOTIF +#endif + #include @@ -37,6 +51,8 @@ #include +#include /* for CARD32 */ +#include /* for XA_INTEGER */ #include #include @@ -45,6 +61,17 @@ #include #include +#ifdef HAVE_XMU +# ifndef VMS +# include +# else /* VMS */ +# include +# endif +#else +# include "xmu.h" +#endif + + #ifdef HAVE_MOTIF # include # include @@ -54,7 +81,7 @@ # include # include -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) /* Athena demo code contributed by Jon A. Christopher */ /* Copyright 1997, with the same permissions as above. */ # include @@ -67,6 +94,7 @@ # include # include # include + #endif /* HAVE_ATHENA */ #include "version.h" @@ -80,6 +108,9 @@ #include #include +#define WIDGET Widget +#define POINTER XtPointer + char *progname = 0; char *progclass = "XScreenSaver"; @@ -102,25 +133,39 @@ static char *short_version = 0; Atom XA_VROOT; Atom XA_SCREENSAVER, XA_SCREENSAVER_RESPONSE, XA_SCREENSAVER_VERSION; -Atom XA_SCREENSAVER_TIME, XA_SCREENSAVER_ID, XA_SELECT, XA_DEMO, XA_RESTART; +Atom XA_SCREENSAVER_ID, XA_SCREENSAVER_STATUS, XA_SELECT, XA_DEMO; +Atom XA_BLANK, XA_LOCK, XA_RESTART, XA_EXIT; extern void create_demo_dialog (Widget, Visual *, Colormap); extern void create_preferences_dialog (Widget, Visual *, Colormap); -extern Widget demo_dialog; -extern Widget label1; -extern Widget text_line; -extern Widget demo_form; -extern Widget demo_list; -extern Widget next, prev, done, restart, edit; - -extern Widget preferences_dialog; -extern Widget preferences_form; -extern Widget prefs_done, prefs_cancel; -extern Widget timeout_text, cycle_text, fade_text, fade_ticks_text; -extern Widget lock_timeout_text, passwd_timeout_text; -extern Widget verbose_toggle, install_cmap_toggle, fade_toggle, unfade_toggle, - lock_toggle; +extern WIDGET demo_dialog; +extern WIDGET label1; +extern WIDGET text_line; +extern WIDGET text_activate; +extern WIDGET demo_form; +extern WIDGET demo_list; +extern WIDGET next; +extern WIDGET prev; +extern WIDGET done; +extern WIDGET restart; +extern WIDGET edit; + +extern WIDGET preferences_dialog; +extern WIDGET preferences_form; +extern WIDGET prefs_done; +extern WIDGET prefs_cancel; +extern WIDGET timeout_text; +extern WIDGET cycle_text; +extern WIDGET fade_text; +extern WIDGET fade_ticks_text; +extern WIDGET lock_timeout_text; +extern WIDGET passwd_timeout_text; +extern WIDGET verbose_toggle; +extern WIDGET install_cmap_toggle; +extern WIDGET fade_toggle; +extern WIDGET unfade_toggle; +extern WIDGET lock_toggle; #ifdef HAVE_MOTIF @@ -134,8 +179,14 @@ extern Widget verbose_toggle, install_cmap_toggle, fade_toggle, unfade_toggle, # define add_toggle_callback(button,cb,arg) \ XtAddCallback ((button), XmNvalueChangedCallback, (cb), (arg)) # define add_text_callback add_toggle_callback +# define disable_widget(widget) \ + XtVaSetValues((widget), XtNsensitive, False, 0) +# define widget_name(widget) XtName(widget) +# define widget_display(widget) XtDisplay(widget) +# define widget_screen(widget) XtScreen(widget) +# define CB_ARGS(a,b,c) (a,b,c) -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) # define set_toggle_button_state(toggle,state) \ XtVaSetValues((toggle), XtNstate, (state), 0) @@ -145,20 +196,24 @@ extern Widget verbose_toggle, install_cmap_toggle, fade_toggle, unfade_toggle, XtAddCallback ((button), XtNcallback, (cb), (arg)) # define add_toggle_callback add_button_callback # define add_text_callback(b,c,a) ERROR! +# define disable_widget(widget) \ + XtVaSetValues((widget), XtNsensitive, False, 0) +# define widget_name(widget) XtName(widget) +# define widget_display(widget) XtDisplay(widget) +# define widget_screen(widget) XtScreen(widget) +# define CB_ARGS(a,b,c) (a,b,c) #endif /* HAVE_ATHENA */ -#define disable_widget(widget) \ - XtVaSetValues((widget), XtNsensitive, False, 0) static char * -get_text_string (Widget text_widget) +get_text_string (WIDGET text_widget) { #ifdef HAVE_MOTIF return XmTextGetString (text_widget); -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) char *string = 0; if (XtIsSubclass(text_widget, textWidgetClass)) XtVaGetValues (text_widget, XtNstring, &string, 0); @@ -171,8 +226,9 @@ get_text_string (Widget text_widget) #endif /* HAVE_ATHENA */ } + static char * -get_label_string (Widget label_widget) +get_label_string (WIDGET label_widget) { #ifdef HAVE_MOTIF char *label = 0; @@ -182,7 +238,7 @@ get_label_string (Widget label_widget) return 0; XmStringGetLtoR (xm_label, XmSTRING_DEFAULT_CHARSET, &label); return label; -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) char *label = 0; XtVaGetValues (label_widget, XtNlabel, &label, 0); return (label ? strdup(label) : 0); @@ -191,25 +247,28 @@ get_label_string (Widget label_widget) static void -set_label_string (Widget label_widget, char *string) +set_label_string (WIDGET label_widget, char *string) { #ifdef HAVE_MOTIF XmString xm_string = XmStringCreate (string, XmSTRING_DEFAULT_CHARSET); XtVaSetValues (label_widget, XmNlabelString, xm_string, 0); XmStringFree (xm_string); -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) XtVaSetValues (label_widget, XtNlabel, string, 0); #endif /* HAVE_ATHENA */ } +/* Given a label widget that has a %s in it, do the printf thing. + If the label's string is obviously wrong, complain about resource lossage. + */ static void -format_into_label (Widget label, const char *arg) +format_into_label (WIDGET label, const char *arg) { char *text = get_label_string (label); char *buf = (char *) malloc ((text ? strlen(text) : 0) + strlen(arg) + 100); - if (!text || !strcmp (text, XtName (label))) + if (!text || !*text || !strcmp (text, widget_name (label))) strcpy (buf, "ERROR: RESOURCES ARE NOT INSTALLED CORRECTLY"); else sprintf (buf, text, arg); @@ -223,7 +282,7 @@ format_into_label (Widget label, const char *arg) /* Why this behavior isn't automatic in *either* toolkit, I'll never know. */ static void -ensure_selected_item_visible (Widget list) +ensure_selected_item_visible (WIDGET list) { #ifdef HAVE_MOTIF int *pos_list = 0; @@ -250,7 +309,7 @@ ensure_selected_item_visible (Widget list) if (pos_list) XtFree ((char *) pos_list); -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) # ifdef HAVE_XawViewportSetCoordinates int margin = 16; /* should be line height or something. */ @@ -303,6 +362,31 @@ ensure_selected_item_visible (Widget list) } +#ifdef HAVE_ATHENA +static void +set_hack_list (Widget demo_list, saver_preferences *p) +{ + char **strings = (char **) calloc (sizeof (char *), p->screenhacks_count); + int i; + for (i = 0; i < p->screenhacks_count; i++) + strings[i] = format_hack (p->screenhacks[i], False); + XtVaSetValues (demo_list, + XtNlist, strings, + XtNnumberStrings, p->screenhacks_count, + 0); +# if 0 + for (i = 0; i < p->screenhacks_count; i++) + { + free (strings[i]); + strings[i] = (char *) 0xDEADBEEF; + } + free (strings); +# endif +} +#endif /* HAVE_ATHENA */ + + + /* Callback for the text area: - note the text the user has entered; - change the corresponding element in `screenhacks'; @@ -310,41 +394,40 @@ ensure_selected_item_visible (Widget list) - tell the xscreensaver daemon to run that hack. */ static void -text_cb (Widget text_widget, XtPointer client_data, XtPointer call_data) +text_cb (WIDGET text_widget, POINTER client_data, POINTER call_data) { - Display *dpy = XtDisplay (text_widget); saver_preferences *p = (saver_preferences *) client_data; char *new_text = get_text_string (text_widget); + Display *dpy = widget_display (text_widget); + Bool save = TRUE; int hack_number = -1; /* 0-based */ #ifdef HAVE_ATHENA XawListReturnStruct *current = XawListShowCurrent(demo_list); hack_number = current->list_index; -#else /* HAVE_MOTIF */ +#elif defined(HAVE_MOTIF) int *pos_list = 0; int pos_count = 0; if (XmListGetSelectedPos (demo_list, &pos_list, &pos_count)) hack_number = pos_list[0] - 1; if (pos_list) XtFree ((char *) pos_list); -#endif /* HAVE_MOTIF */ +#endif /* HAVE_ATHENA */ ensure_selected_item_visible (demo_list); if (hack_number < 0 || hack_number >= p->screenhacks_count) { set_text_string (text_widget, ""); - XBell (dpy, 0); + XBell (XtDisplay (text_widget), 0); } else { -fprintf(stderr, "%d:\nold: %s\nnew: %s\n", - hack_number, p->screenhacks [hack_number], new_text); - + screenhack *new_hack = parse_screenhack (new_text); if (p->screenhacks [hack_number]) - free (p->screenhacks [hack_number]); - p->screenhacks [hack_number] = strdup (new_text); + free_screenhack (p->screenhacks [hack_number]); + p->screenhacks [hack_number] = new_hack; #ifdef HAVE_MOTIF @@ -356,7 +439,7 @@ fprintf(stderr, "%d:\nold: %s\nnew: %s\n", } XmListSelectPos (demo_list, hack_number+1, True); -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) { Widget vp = XtParent(demo_list); @@ -366,22 +449,20 @@ fprintf(stderr, "%d:\nold: %s\nnew: %s\n", float sb_top = 0; XawListUnhighlight (demo_list); - XtVaGetValues (vp, XtNx, &vp_x, 0); XtVaGetValues (sb, XtNtopOfThumb, &sb_top, 0); XtVaGetValues (demo_list, XtNheight, &list_h, 0); vp_y = (sb_top * list_h); - XtVaSetValues (demo_list, - XtNlist, p->screenhacks, - XtNnumberStrings, p->screenhacks_count, - 0); + set_hack_list (demo_list, p); XawViewportSetCoordinates (vp, vp_x, vp_y); XawListHighlight (demo_list, hack_number); } #endif /* HAVE_ATHENA */ - write_init_file (p, short_version); + if (save) + write_init_file (p, short_version); + XSync (dpy, False); usleep (500000); /* give the disk time to settle down */ @@ -411,7 +492,7 @@ static char translations[] = ("Return: done()\n" /* Callback for the Run Next button. */ static void -next_cb (Widget button, XtPointer client_data, XtPointer call_data) +next_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) { #ifdef HAVE_ATHENA XawListReturnStruct *current = XawListShowCurrent(demo_list); @@ -430,7 +511,7 @@ next_cb (Widget button, XtPointer client_data, XtPointer call_data) run_hack (XtDisplay (button), current->list_index + 1); -#else /* HAVE_MOTIF */ +#elif defined(HAVE_MOTIF) saver_preferences *p = (saver_preferences *) client_data; int *pos_list = 0; @@ -463,7 +544,7 @@ next_cb (Widget button, XtPointer client_data, XtPointer call_data) /* Callback for the Run Previous button. */ static void -prev_cb (Widget button, XtPointer client_data, XtPointer call_data) +prev_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) { #ifdef HAVE_ATHENA XawListReturnStruct *current = XawListShowCurrent(demo_list); @@ -482,7 +563,7 @@ prev_cb (Widget button, XtPointer client_data, XtPointer call_data) run_hack (XtDisplay (button), current->list_index + 1); -#else /* HAVE_MOTIF */ +#elif defined(HAVE_MOTIF) saver_preferences *p = (saver_preferences *) client_data; int *pos_list = 0; @@ -515,7 +596,7 @@ prev_cb (Widget button, XtPointer client_data, XtPointer call_data) /* Callback run when a list element is double-clicked. */ static void -select_cb (Widget button, XtPointer client_data, XtPointer call_data) +select_cb (WIDGET button, POINTER client_data, POINTER call_data) { /* saver_preferences *p = (saver_preferences *) client_data; */ @@ -524,7 +605,7 @@ select_cb (Widget button, XtPointer client_data, XtPointer call_data) XtVaSetValues(text_line, XtNstring, item->string, 0); run_hack (XtDisplay (button), item->list_index + 1); -#else /* HAVE_MOTIF */ +#elif defined(HAVE_MOTIF) XmListCallbackStruct *lcb = (XmListCallbackStruct *) call_data; char *string = 0; if (lcb->item) @@ -536,18 +617,18 @@ select_cb (Widget button, XtPointer client_data, XtPointer call_data) if (string) XtFree (string); + #endif /* HAVE_MOTIF */ } - static void pop_preferences_dialog (prefs_pair *pair); static void make_preferences_dialog (prefs_pair *pair, Widget parent); /* Callback for the Preferences button. */ static void -preferences_cb (Widget button, XtPointer client_data, XtPointer call_data) +preferences_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) { prefs_pair *pair = (prefs_pair *) client_data; Widget parent = button; @@ -558,13 +639,15 @@ preferences_cb (Widget button, XtPointer client_data, XtPointer call_data) if (! preferences_dialog) make_preferences_dialog (pair, parent); + *pair->b = *pair->a; pop_preferences_dialog (pair); } + /* Callback for the Quit button. */ static void -quit_cb (Widget button, XtPointer client_data, XtPointer call_data) +quit_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) { /* Save here? Right now we don't need to, because we save every time the text field is edited, or the Preferences OK button is pressed. @@ -576,22 +659,77 @@ quit_cb (Widget button, XtPointer client_data, XtPointer call_data) /* Callback for the (now unused) Restart button. */ static void -restart_cb (Widget button, XtPointer client_data, XtPointer call_data) +restart_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) { - xscreensaver_command (XtDisplay (button), XA_RESTART, 0, False); + xscreensaver_command (widget_display (button), XA_RESTART, 0, False); } +/* Finds the number of the last hack to run, and makes that item be + selected by default. + */ static void -pop_up_dialog_box (Widget dialog, Widget form) +scroll_to_current_hack (WIDGET dialog) +{ + Atom type; + int format; + unsigned long nitems, bytesafter; + CARD32 *data = 0; + Display *dpy = widget_display (dialog); + int hack = 0; + + if (XGetWindowProperty (dpy, RootWindow (dpy, 0), /* always screen #0 */ + XA_SCREENSAVER_STATUS, + 0, 3, False, XA_INTEGER, + &type, &format, &nitems, &bytesafter, + (unsigned char **) &data) + == Success + && type == XA_INTEGER + && nitems >= 3 + && data) + hack = (int) data[2]; + + if (data) free (data); + + if (hack <= 0) + return; + +#ifdef HAVE_MOTIF + XmListDeselectAllItems (demo_list); /* LessTif lossage */ + XmListSelectPos (demo_list, hack, False); + ensure_selected_item_visible (demo_list); + +#elif defined(HAVE_ATHENA) + XawListUnhighlight (demo_list); + XawListHighlight (demo_list, hack - 1); + +#endif /* HAVE_ATHENA */ +} + + +static void +pop_up_dialog_box (WIDGET dialog, WIDGET form) { #ifdef HAVE_ATHENA XtRealizeWidget (dialog); XtPopup (dialog, XtGrabNone); -#else /* HAVE_MOTIF */ +#elif defined(HAVE_MOTIF) XtRealizeWidget (form); XtManageChild (form); + + /* Motif likes to make the dialog wider than the screen; throttle it. */ + { + Dimension w=0, h=0, bw=0; + Dimension max_w; + Screen *screen = 0; + XtVaGetValues (dialog, XtNscreen, &screen, 0); + max_w = WidthOfScreen (screen) * 0.8; + XtVaGetValues(dialog, XtNwidth, &w, XtNheight, &h, XtNborderWidth, &bw, 0); + if (w > max_w) + XtResizeWidget(dialog, max_w, h, bw); + } #endif /* HAVE_MOTIF */ + XMapRaised (XtDisplay (dialog), XtWindow (dialog)); } @@ -601,38 +739,41 @@ make_demo_dialog (Widget toplevel_shell, prefs_pair *pair) { saver_preferences *p = pair->a; /* saver_preferences *p2 = pair->b; */ - Widget parent = toplevel_shell; - char **hacks = p->screenhacks; +#ifdef HAVE_MOTIF + screenhack **hacks = p->screenhacks; +#endif /* HAVE_MOTIF */ create_demo_dialog (parent, - DefaultVisualOfScreen (XtScreen (parent)), - DefaultColormapOfScreen (XtScreen (parent))); - format_into_label (label1, short_version); + DefaultVisualOfScreen (widget_screen (parent)), + DefaultColormapOfScreen (widget_screen (parent))); - add_button_callback (next, next_cb, (XtPointer) p); - add_button_callback (prev, prev_cb, (XtPointer) p); - add_button_callback (done, quit_cb, (XtPointer) p); + format_into_label (label1, short_version); + add_button_callback (next, next_cb, (POINTER) p); + add_button_callback (prev, prev_cb, (POINTER) p); + add_button_callback (done, quit_cb, (POINTER) p); if (restart) - add_button_callback(restart,restart_cb, (XtPointer) p); - add_button_callback (edit, preferences_cb, (XtPointer) pair); + add_button_callback(restart,restart_cb, (POINTER) p); + add_button_callback (edit, preferences_cb, (POINTER) pair); #ifdef HAVE_MOTIF XtAddCallback (demo_list, XmNbrowseSelectionCallback, - select_cb, (XtPointer) p); + select_cb, (POINTER) p); XtAddCallback (demo_list, XmNdefaultActionCallback, - select_cb, (XtPointer) p); - XtAddCallback (text_line, XmNactivateCallback, text_cb, (XtPointer) p); + select_cb, (POINTER) p); + XtAddCallback (text_line, XmNactivateCallback, text_cb, (POINTER) p); if (hacks) for (; *hacks; hacks++) { - XmString xmstr = XmStringCreate (*hacks, XmSTRING_DEFAULT_CHARSET); + char *hs = format_hack (*hacks, False); + XmString xmstr = XmStringCreate (hs, XmSTRING_DEFAULT_CHARSET); XmListAddItem (demo_list, xmstr, 0); XmStringFree (xmstr); + free (hs); } -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) /* Hook up the text line. */ @@ -646,10 +787,7 @@ make_demo_dialog (Widget toplevel_shell, prefs_pair *pair) */ XtRealizeWidget (demo_dialog); - XtVaSetValues (demo_list, - XtNlist, hacks, - XtNnumberStrings, p->screenhacks_count, - 0); + set_hack_list (demo_list, p); XtAddCallback (demo_list, XtNcallback, select_cb, p); /* Now that we've populated the list, make sure that the list is as @@ -695,10 +833,12 @@ make_demo_dialog (Widget toplevel_shell, prefs_pair *pair) #endif /* HAVE_ATHENA */ + scroll_to_current_hack (demo_dialog); + pop_up_dialog_box(demo_dialog, demo_form); -#ifdef HAVE_ATHENA - /* For Athena, have to do this after the dialog is managed. */ +#if defined(HAVE_ATHENA) + /* For Athena and Gtk, have to do this after the dialog is managed. */ ensure_selected_item_visible (demo_list); #endif /* HAVE_ATHENA */ } @@ -727,13 +867,13 @@ hack_time_text (Display *dpy, char *line, Time *store, Bool sec_p) /* Callback for text fields that hold a time that default to seconds, - when not fully spelled out. client_data is an Time* where the value goes. + when not fully spelled out. client_data is a Time* where the value goes. */ static void -prefs_sec_cb (Widget button, XtPointer client_data, XtPointer call_data) +prefs_sec_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) { - hack_time_text (XtDisplay (button), get_text_string (button), - (Time *) client_data, True); + hack_time_text (widget_display (button), get_text_string (button), + (Time *) client_data, True); } @@ -741,10 +881,10 @@ prefs_sec_cb (Widget button, XtPointer client_data, XtPointer call_data) when not fully spelled out. client_data is an Time* where the value goes. */ static void -prefs_min_cb (Widget button, XtPointer client_data, XtPointer call_data) +prefs_min_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) { - hack_time_text (XtDisplay (button), get_text_string (button), - (Time *) client_data, False); + hack_time_text (widget_display (button), get_text_string (button), + (Time *) client_data, False); } @@ -752,7 +892,7 @@ prefs_min_cb (Widget button, XtPointer client_data, XtPointer call_data) client_data is an int* where the value goes. */ static void -prefs_int_cb (Widget button, XtPointer client_data, XtPointer call_data) +prefs_int_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) { char *line = get_text_string (button); int *store = (int *) client_data; @@ -766,15 +906,16 @@ prefs_int_cb (Widget button, XtPointer client_data, XtPointer call_data) *store = value; } -/* Callback for toggle buttons. client_data is an Bool* where the value goes. + +/* Callback for toggle buttons. client_data is a Bool* where the value goes. */ static void -prefs_bool_cb (Widget button, XtPointer client_data, XtPointer call_data) +prefs_bool_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER call_data) { Bool *store = (Bool *) client_data; #ifdef HAVE_MOTIF *store = ((XmToggleButtonCallbackStruct *) call_data)->set; -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) Boolean state = FALSE; XtVaGetValues (button, XtNstate, &state, 0); *store = state; @@ -785,7 +926,7 @@ prefs_bool_cb (Widget button, XtPointer client_data, XtPointer call_data) /* Callback for the Cancel button on the Preferences dialog. */ static void -prefs_cancel_cb (Widget button, XtPointer client_data, XtPointer call_data) +prefs_cancel_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER ignored) { XtDestroyWidget (preferences_dialog); preferences_dialog = 0; @@ -796,23 +937,23 @@ prefs_cancel_cb (Widget button, XtPointer client_data, XtPointer call_data) /* Callback for the OK button on the Preferences dialog. */ static void -prefs_ok_cb (Widget button, XtPointer client_data, XtPointer call_data) +prefs_ok_cb CB_ARGS(WIDGET button, POINTER client_data, POINTER call_data) { prefs_pair *pair = (prefs_pair *) client_data; saver_preferences *p = pair->a; saver_preferences *p2 = pair->b; - prefs_cancel_cb (button, 0, call_data); + prefs_cancel_cb CB_ARGS(button, client_data, call_data); #ifdef HAVE_ATHENA /* Athena doesn't let us put callbacks on these widgets, so run all the callbacks by hand when OK is pressed. */ - prefs_min_cb (timeout_text, (XtPointer) &p2->timeout, 0); - prefs_min_cb (cycle_text, (XtPointer) &p2->cycle, 0); - prefs_sec_cb (fade_text, (XtPointer) &p2->fade_seconds, 0); - prefs_int_cb (fade_ticks_text, (XtPointer) &p2->fade_ticks, 0); - prefs_min_cb (lock_timeout_text, (XtPointer) &p2->lock_timeout, 0); - prefs_sec_cb (passwd_timeout_text, (XtPointer) &p2->passwd_timeout, 0); + prefs_min_cb (timeout_text, (POINTER) &p2->timeout, 0); + prefs_min_cb (cycle_text, (POINTER) &p2->cycle, 0); + prefs_sec_cb (fade_text, (POINTER) &p2->fade_seconds, 0); + prefs_int_cb (fade_ticks_text, (POINTER) &p2->fade_ticks, 0); + prefs_min_cb (lock_timeout_text, (POINTER) &p2->lock_timeout, 0); + prefs_sec_cb (passwd_timeout_text, (POINTER) &p2->passwd_timeout, 0); #endif /* HAVE_ATHENA */ p->timeout = p2->timeout; @@ -837,24 +978,24 @@ make_preferences_dialog (prefs_pair *pair, Widget parent) saver_preferences *p = pair->a; saver_preferences *p2 = pair->b; - Screen *screen = XtScreen (parent); - Display *dpy = XtDisplay (parent); + Screen *screen = widget_screen (parent); + Display *dpy = widget_display (parent); *p2 = *p; /* copy all slots of p into p2. */ create_preferences_dialog (parent, - DefaultVisualOfScreen (screen), - DefaultColormapOfScreen (screen)); + DefaultVisualOfScreen (screen), + DefaultColormapOfScreen (screen)); - add_button_callback (prefs_done, prefs_ok_cb, (XtPointer) pair); + add_button_callback (prefs_done, prefs_ok_cb, (POINTER) pair); add_button_callback (prefs_cancel, prefs_cancel_cb, 0); #define CB(widget,type,slot) \ - add_text_callback ((widget), (type), (XtPointer) (slot)) + add_text_callback ((widget), (type), (POINTER) (slot)) #define CBT(widget,type,slot) \ - add_toggle_callback ((widget), (type), (XtPointer) (slot)) + add_toggle_callback ((widget), (type), (POINTER) (slot)) -#ifdef HAVE_MOTIF +#ifndef HAVE_ATHENA /* When using Athena widgets, we can't set callbacks for these, so in that case, we run them by hand when "OK" is pressed. */ CB (timeout_text, prefs_min_cb, &p2->timeout); @@ -863,7 +1004,8 @@ make_preferences_dialog (prefs_pair *pair, Widget parent) CB (fade_ticks_text, prefs_int_cb, &p2->fade_ticks); CB (lock_timeout_text, prefs_min_cb, &p2->lock_timeout); CB (passwd_timeout_text, prefs_sec_cb, &p2->passwd_timeout); -#endif /* HAVE_MOTIF */ + +#endif /* !HAVE_ATHENA */ CBT (verbose_toggle, prefs_bool_cb, &p2->verbose_p); CBT (install_cmap_toggle, prefs_bool_cb, &p2->install_cmap_p); @@ -953,22 +1095,23 @@ run_hack (Display *dpy, int n) static void -warning_dialog_dismiss_cb (Widget button, XtPointer client_data, - XtPointer call_data) +warning_dialog_dismiss_cb CB_ARGS(WIDGET button, POINTER client_data, + POINTER ignored) { - Widget shell = (Widget) client_data; + WIDGET shell = (WIDGET) client_data; XtDestroyWidget (shell); } + static void -warning_dialog (Widget parent, const char *message) +warning_dialog (WIDGET parent, const char *message) { char *msg = strdup (message); char *head; - Widget dialog = 0; - Widget label = 0; - Widget ok = 0; + WIDGET dialog = 0; + WIDGET label = 0; + WIDGET ok = 0; int i = 0; #ifdef HAVE_MOTIF @@ -999,13 +1142,12 @@ warning_dialog (Widget parent, const char *message) XtSetArg (av[ac], XmNspacing, 0); ac++; container = XmCreateRowColumn (dialog, "container", av, ac); -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) Widget form; dialog = XtVaCreatePopupShell("warning_dialog", transientShellWidgetClass, parent, 0); form = XtVaCreateManagedWidget("warning_form", formWidgetClass, dialog, 0); - #endif /* HAVE_ATHENA */ head = msg; @@ -1024,7 +1166,7 @@ warning_dialog (Widget parent, const char *message) label = XmCreateLabelGadget (container, name, av, ac); XtManageChild (label); XmStringFree (xmstr); -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) label = XtVaCreateManagedWidget (name, labelWidgetClass, form, @@ -1049,7 +1191,7 @@ warning_dialog (Widget parent, const char *message) XtRealizeWidget (dialog); XtManageChild (dialog); -#else /* HAVE_ATHENA */ +#elif defined(HAVE_ATHENA) ok = XtVaCreateManagedWidget ("ok", commandWidgetClass, form, XtNleft, XtChainLeft, @@ -1059,10 +1201,9 @@ warning_dialog (Widget parent, const char *message) XtRealizeWidget (dialog); XtPopup (dialog, XtGrabNone); - #endif /* HAVE_ATHENA */ - add_button_callback (ok, warning_dialog_dismiss_cb, dialog); + add_button_callback (ok, warning_dialog_dismiss_cb, (POINTER) dialog); free (msg); } @@ -1095,10 +1236,11 @@ mapper (XrmDatabase *db, XrmBindingList bindings, XrmQuarkList quarks, } #endif + static void -the_network_is_not_the_computer (Widget parent) +the_network_is_not_the_computer (WIDGET parent) { - Display *dpy = XtDisplay (parent); + Display *dpy = widget_display (parent); char *rversion, *ruser, *rhost; char *luser, *lhost; char *msg = 0; @@ -1206,6 +1348,21 @@ the_network_is_not_the_computer (Widget parent) } +/* We use this error handler so that X errors are preceeded by the name + of the program that generated them. + */ +static int +demo_ehandler (Display *dpy, XErrorEvent *error) +{ + fprintf (stderr, "\nX error in %s:\n", progname); + if (XmuPrintDefaultErrorMessage (dpy, error, stderr)) + exit (-1); + else + fprintf (stderr, " (nonfatal.)\n"); + return 0; +} + + static char *defaults[] = { #include "XScreenSaver_ad.h" 0 @@ -1235,19 +1392,27 @@ main (int argc, char **argv) memset (p, 0, sizeof (*p)); memset (p2, 0, sizeof (*p2)); + progname = real_progname; + /* We must read exactly the same resources as xscreensaver. That means we must have both the same progclass *and* progname, at least as far as the resource database is concerned. So, put "xscreensaver" in argv[0] while initializing Xt. */ argv[0] = "xscreensaver"; + progname = argv[0]; + toplevel_shell = XtAppInitialize (&app, progclass, 0, 0, &argc, argv, defaults, 0, 0); + dpy = XtDisplay (toplevel_shell); db = XtDatabase (dpy); XtGetApplicationNameAndClass (dpy, &progname, &progclass); + XSetErrorHandler (demo_ehandler); + /* Complain about unrecognized command-line arguments. + */ for (i = 1; i < argc; i++) { char *s = argv[i]; @@ -1267,14 +1432,18 @@ main (int argc, char **argv) memcpy (short_version, screensaver_id + 17, 4); short_version [4] = 0; + /* Load the init file, which may end up consulting the X resource database + and the site-wide app-defaults file. Note that at this point, it's + important that `progname' be "xscreensaver", rather than whatever + was in argv[0]. + */ p->db = db; - p->fading_possible_p = True; load_init_file (p); *p2 = *p; - - /* Now that Xt has been initialized, we can set our `progname' variable - to something that makes more sense (like our "real" argv[0].) + /* Now that Xt has been initialized, and the resources have been read, + we can set our `progname' variable to something more in line with + reality. */ progname = real_progname; @@ -1289,7 +1458,7 @@ main (int argc, char **argv) XrmClass class = { 0 }; int count = 0; XrmEnumerateDatabase (db, &name, &class, XrmEnumAllLevels, mapper, - (XtPointer) &count); + (POINTER) &count); } #endif @@ -1297,11 +1466,14 @@ main (int argc, char **argv) XA_VROOT = XInternAtom (dpy, "__SWM_VROOT", False); XA_SCREENSAVER = XInternAtom (dpy, "SCREENSAVER", False); XA_SCREENSAVER_VERSION = XInternAtom (dpy, "_SCREENSAVER_VERSION",False); - XA_SCREENSAVER_TIME = XInternAtom (dpy, "_SCREENSAVER_TIME", False); + XA_SCREENSAVER_STATUS = XInternAtom (dpy, "_SCREENSAVER_STATUS", False); XA_SCREENSAVER_ID = XInternAtom (dpy, "_SCREENSAVER_ID", False); XA_SCREENSAVER_RESPONSE = XInternAtom (dpy, "_SCREENSAVER_RESPONSE", False); XA_SELECT = XInternAtom (dpy, "SELECT", False); XA_DEMO = XInternAtom (dpy, "DEMO", False); + XA_BLANK = XInternAtom (dpy, "BLANK", False); + XA_LOCK = XInternAtom (dpy, "LOCK", False); + XA_EXIT = XInternAtom (dpy, "EXIT", False); XA_RESTART = XInternAtom (dpy, "RESTART", False); make_demo_dialog (toplevel_shell, pair); @@ -1316,6 +1488,7 @@ main (int argc, char **argv) ? preferences_dialog : demo_dialog); - XtAppMainLoop(app); + XtAppMainLoop (app); + exit (0); }