From 52917e53de6090635d53ea9fb79405dfe90bfa39 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 16 Apr 1999 20:05:26 +0000 Subject: [PATCH] rearranged the crashing dialog panel code. --- src/dialog.c | 248 +++++++++++++++++++++++++++++++++++++++++++++ src/dialog.h | 9 ++ src/misc.c | 2 +- src/moveres.c | 1 + src/shutdown.c | 1 + src/startup.c | 266 +++---------------------------------------------- src/texture.c | 2 +- 7 files changed, 276 insertions(+), 253 deletions(-) diff --git a/src/dialog.c b/src/dialog.c index dbaf0c68..d1a2e8be 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -3,6 +3,7 @@ * Window Maker window manager * * Copyright (c) 1997, 1998 Alfredo K. Kojima + * Copyright (c) 1999 Dan Pascu * * 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 @@ -35,6 +36,12 @@ #include #include +#include +#ifdef __FreeBSD__ +#include +#endif + + #ifndef PATH_MAX #define PATH_MAX DEFAULT_PATH_MAX #endif @@ -1258,3 +1265,244 @@ wShowLegalPanel(WScreen *scr) legalPanel = panel; } + +/* + *********************************************************************** + * Crashing Dialog Panel + *********************************************************************** + */ + +extern WDDomain *WDWindowAttributes; + + +typedef struct _CrashPanel { + WMWindow *win; /* main window */ + + WMLabel *iconL; /* application icon */ + WMLabel *nameL; /* title of panel */ + + WMFrame *sepF; /* separator frame */ + + WMLabel *noteL; /* Title of note */ + WMLabel *note2L; /* body of note with what happened */ + + WMFrame *whatF; /* "what to do next" frame */ + WMPopUpButton *whatP; /* action selection popup button */ + + WMButton *okB; /* ok button */ + + Bool done; /* if finished with this dialog */ + int action; /* what to do after */ + + KeyCode retKey; + +} CrashPanel; + + +static void +handleKeyPress(XEvent *event, void *clientData) +{ + CrashPanel *panel = (CrashPanel*)clientData; + + if (event->xkey.keycode == panel->retKey) { + WMPerformButtonClick(panel->okB); + } +} + + +static void +okButtonCallback(void *self, void *clientData) +{ + CrashPanel *panel = (CrashPanel*)clientData; + + panel->done = True; +} + + +static void +setCrashAction(void *self, void *clientData) +{ + WMPopUpButton *pop = (WMPopUpButton*)self; + CrashPanel *panel = (CrashPanel*)clientData; + + panel->action = WMGetPopUpButtonSelectedItem(pop); +} + + +static WMPixmap* +getWindowMakerIconImage(WMScreen *scr) +{ + proplist_t dict, key, option, value=NULL; + WMPixmap *pix=NULL; + char *path; + + PLSetStringCmpHook(NULL); + + key = PLMakeString("Logo.WMPanel"); + option = PLMakeString("Icon"); + + dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key); + + if (dict) { + value = PLGetDictionaryEntry(dict, option); + } + + PLRelease(key); + PLRelease(option); + + PLSetStringCmpHook(StringCompareHook); + + if (value && PLIsString(value)) { + path = FindImage(wPreferences.icon_path, PLGetString(value)); + + if (path) { + RImage *image; + + image = RLoadImage(WMScreenRContext(scr), path, 0); + if (image) { + pix = WMCreatePixmapFromRImage(scr, image, 0); + RDestroyImage(image); + } + free(path); + } + } + + return pix; +} + + +#define PWIDTH 295 +#define PHEIGHT 345 + + +int +wShowCrashingDialogPanel(int whatSig) +{ + CrashPanel *panel; + WMScreen *scr; + WMFont *font; + WMPixmap *logo; + int screen_no, scr_width, scr_height; + int action; + char buf[256]; + + panel = wmalloc(sizeof(CrashPanel)); + memset(panel, 0, sizeof(CrashPanel)); + + screen_no = DefaultScreen(dpy); + scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no)); + scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no)); + + scr = WMCreateScreen(dpy, screen_no); + if (!scr) { + wsyserror(_("cannot open connection for crashing dialog panel. Aborting.")); + return WMAbort; + } + + panel->retKey = XKeysymToKeycode(dpy, XK_Return); + + panel->win = WMCreateWindow(scr, "crashingDialog"); + WMResizeWidget(panel->win, PWIDTH, PHEIGHT); + WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2); + + logo = getWindowMakerIconImage(scr); + if (logo) { + panel->iconL = WMCreateLabel(panel->win); + WMResizeWidget(panel->iconL, 64, 64); + WMMoveWidget(panel->iconL, 10, 10); + WMSetLabelImagePosition(panel->iconL, WIPImageOnly); + WMSetLabelImage(panel->iconL, logo); + } + + panel->nameL = WMCreateLabel(panel->win); + WMResizeWidget(panel->nameL, 190, 18); + WMMoveWidget(panel->nameL, 80, 35); + WMSetLabelTextAlignment(panel->nameL, WALeft); + font = WMBoldSystemFontOfSize(scr, 18); + WMSetLabelFont(panel->nameL, font); + WMReleaseFont(font); + WMSetLabelText(panel->nameL, _("Fatal error")); + + panel->sepF = WMCreateFrame(panel->win); + WMResizeWidget(panel->sepF, PWIDTH+4, 2); + WMMoveWidget(panel->sepF, -2, 80); + + panel->noteL = WMCreateLabel(panel->win); + WMResizeWidget(panel->noteL, PWIDTH-20, 40); + WMMoveWidget(panel->noteL, 10, 90); + WMSetLabelTextAlignment(panel->noteL, WAJustified); +#ifdef SYS_SIGLIST_DECLARED + sprintf(buf, _("Window Maker received signal %i\n(%s)."), + whatSig, sys_siglist[whatSig]); +#else + sprintf(buf, _("Window Maker received signal %i."), whatSig); +#endif + WMSetLabelText(panel->noteL, buf); + + panel->note2L = WMCreateLabel(panel->win); + WMResizeWidget(panel->note2L, PWIDTH-20, 100); + WMMoveWidget(panel->note2L, 10, 130); + WMSetLabelTextAlignment(panel->note2L, WALeft); + WMSetLabelText(panel->note2L, + _(" This fatal error occured probably due to a bug." + " Please fill the included BUGFORM and " + "report it to bugs@windowmaker.org.")); + + + panel->whatF = WMCreateFrame(panel->win); + WMResizeWidget(panel->whatF, PWIDTH-20, 50); + WMMoveWidget(panel->whatF, 10, 240); + WMSetFrameTitle(panel->whatF, _("What do you want to do now?")); + + panel->whatP = WMCreatePopUpButton(panel->whatF); + WMResizeWidget(panel->whatP, PWIDTH-20-70, 20); + WMMoveWidget(panel->whatP, 35, 20); + WMSetPopUpButtonPullsDown(panel->whatP, False); + WMSetPopUpButtonText(panel->whatP, _("Select action")); + WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file")); + WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker")); + WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager")); + WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel); + WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart); + panel->action = WMRestart; + + WMMapSubwidgets(panel->whatF); + + panel->okB = WMCreateCommandButton(panel->win); + WMResizeWidget(panel->okB, 80, 26); + WMMoveWidget(panel->okB, 205, 309); + WMSetButtonText(panel->okB, _("OK")); + WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow)); + WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow)); + WMSetButtonImagePosition(panel->okB, WIPRight); + WMSetButtonAction(panel->okB, okButtonCallback, panel); + + panel->done = 0; + + WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, + handleKeyPress, panel); + + WMRealizeWidget(panel->win); + WMMapSubwidgets(panel->win); + + WMMapWidget(panel->win); + + XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime); + + while (!panel->done) { + XEvent event; + + WMNextEvent(dpy, &event); + WMHandleEvent(&event); + } + + action = panel->action; + + WMUnmapWidget(panel->win); + WMDestroyWidget(panel->win); + free(panel); + + return action; +} + + diff --git a/src/dialog.h b/src/dialog.h index 2324a2de..2a886cbc 100644 --- a/src/dialog.h +++ b/src/dialog.h @@ -24,6 +24,13 @@ #define WMDIALOG_H_ +enum { + WMAbort=0, + WMRestart, + WMStartAlternate +}; + + int wMessageDialog(WScreen *scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn); int wInputDialog(WScreen *scr, char *title, char *message, char **text); @@ -34,4 +41,6 @@ void wShowInfoPanel(WScreen *scr); void wShowLegalPanel(WScreen *scr); +int wShowCrashingDialogPanel(int whatSig); + #endif diff --git a/src/misc.c b/src/misc.c index 772ef145..48cf0ce4 100644 --- a/src/misc.c +++ b/src/misc.c @@ -782,7 +782,7 @@ getuserinput(WScreen *scr, char *line, int *ptr) char *title; char *prompt; int j, state; - int begin; + int begin = 0; char tbuffer[256], pbuffer[256]; title = _("Program Arguments"); diff --git a/src/moveres.c b/src/moveres.c index 5b511467..2481e1a0 100644 --- a/src/moveres.c +++ b/src/moveres.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "WindowMaker.h" #include "wcore.h" diff --git a/src/shutdown.c b/src/shutdown.c index c8e2b84a..774ce173 100644 --- a/src/shutdown.c +++ b/src/shutdown.c @@ -34,6 +34,7 @@ #include "client.h" #include "funcs.h" #include "properties.h" +#include "session.h" #include "winspector.h" #ifdef KWM_HINTS # include "kwm.h" diff --git a/src/startup.c b/src/startup.c index 3cf178cd..e583f06f 100644 --- a/src/startup.c +++ b/src/startup.c @@ -56,6 +56,7 @@ #include "session.h" #include "defaults.h" #include "properties.h" +#include "dialog.h" #include "xutil.h" @@ -157,256 +158,6 @@ static void manageAllWindows(); extern void NotifyDeadProcess(pid_t pid, unsigned char status); -typedef struct _CrashPanel { - WMWindow *win; /* main window */ - - WMLabel *iconL; /* application icon */ - WMLabel *nameL; /* title of panel */ - - WMFrame *sepF; /* separator frame */ - - WMLabel *noteL; /* Title of note */ - WMLabel *note2L; /* body of note with what happened */ - - WMFrame *whatF; /* "what to do next" frame */ - WMPopUpButton *whatP; /* action selection popup button */ - - WMButton *okB; /* ok button */ - - Bool done; /* if finished with this dialog */ - int action; /* what to do after */ - - KeyCode retKey; - -} CrashPanel; - - -enum { - WMAbort=0, - WMRestart, - WMStartAlternate -}; - - -static void -handleKeyPress(XEvent *event, void *clientData) -{ - CrashPanel *panel = (CrashPanel*)clientData; - - if (event->xkey.keycode == panel->retKey) { - WMPerformButtonClick(panel->okB); - } -} - - -static void -buttonCallback(void *self, void *clientData) -{ - CrashPanel *panel = (CrashPanel*)clientData; - - panel->done = True; -} - - -static void -setAction(void *self, void *clientData) -{ - WMPopUpButton *pop = (WMPopUpButton*)self; - CrashPanel *panel = (CrashPanel*)clientData; - - panel->action = WMGetPopUpButtonSelectedItem(pop); -} - - -static WMPixmap* -getWindowMakerIconImage(WMScreen *scr) -{ - proplist_t dict, key, option, value=NULL; - WMPixmap *pix=NULL; - char *path; - - PLSetStringCmpHook(NULL); - - key = PLMakeString("Logo.WMPanel"); - option = PLMakeString("Icon"); - - dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key); - - if (dict) { - value = PLGetDictionaryEntry(dict, option); - } - - PLRelease(key); - PLRelease(option); - - PLSetStringCmpHook(StringCompareHook); - - if (value && PLIsString(value)) { - path = FindImage(wPreferences.icon_path, PLGetString(value)); - - if (path) { - RImage *image; - - image = RLoadImage(WMScreenRContext(scr), path, 0); - if (image) { - pix = WMCreatePixmapFromRImage(scr, image, 0); - RDestroyImage(image); - } - free(path); - } - } - - return pix; -} - - -#define PWIDTH 295 -#define PHEIGHT 345 - - -static int -showCrashPanel(int whatSig) -{ - CrashPanel *panel; - WMScreen *scr; - WMFont *font; - WMPixmap *logo; - Display *newdpy; - int screen_no, scr_width, scr_height; - int action; - char buf[256]; - - panel = wmalloc(sizeof(CrashPanel)); - memset(panel, 0, sizeof(CrashPanel)); - - /* Close the X connection and open a new one. This is to avoid messing - * Xlib because we call to Xlib functions in a signal handler. - */ - XCloseDisplay(dpy); - newdpy = XOpenDisplay(""); - if (!newdpy) { - wfatal(_("cannot open connection for crashing dialog panel. Aborting.")); - return WMAbort; - } - - screen_no = DefaultScreen(newdpy); - scr_width = WidthOfScreen(ScreenOfDisplay(newdpy, screen_no)); - scr_height = HeightOfScreen(ScreenOfDisplay(newdpy, screen_no)); - - scr = WMCreateScreen(newdpy, screen_no); - if (!scr) { - wfatal(_("cannot open connection for crashing dialog panel. Aborting.")); - return WMAbort; - } - - panel->retKey = XKeysymToKeycode(newdpy, XK_Return); - - panel->win = WMCreateWindow(scr, "crashingDialog"); - WMResizeWidget(panel->win, PWIDTH, PHEIGHT); - WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2); - - logo = getWindowMakerIconImage(scr); - if (logo) { - panel->iconL = WMCreateLabel(panel->win); - WMResizeWidget(panel->iconL, 64, 64); - WMMoveWidget(panel->iconL, 10, 10); - WMSetLabelImagePosition(panel->iconL, WIPImageOnly); - WMSetLabelImage(panel->iconL, logo); - } - - panel->nameL = WMCreateLabel(panel->win); - WMResizeWidget(panel->nameL, 190, 18); - WMMoveWidget(panel->nameL, 80, 35); - WMSetLabelTextAlignment(panel->nameL, WALeft); - font = WMBoldSystemFontOfSize(scr, 18); - WMSetLabelFont(panel->nameL, font); - WMReleaseFont(font); - WMSetLabelText(panel->nameL, _("Fatal error")); - - panel->sepF = WMCreateFrame(panel->win); - WMResizeWidget(panel->sepF, PWIDTH+4, 2); - WMMoveWidget(panel->sepF, -2, 80); - - panel->noteL = WMCreateLabel(panel->win); - WMResizeWidget(panel->noteL, PWIDTH-20, 40); - WMMoveWidget(panel->noteL, 10, 90); - WMSetLabelTextAlignment(panel->noteL, WAJustified); -#ifdef SYS_SIGLIST_DECLARED - sprintf(buf, _("Window Maker received signal %i\n(%s)."), - whatSig, sys_siglist[whatSig]); -#else - sprintf(buf, _("Window Maker received signal %i."), whatSig); -#endif - WMSetLabelText(panel->noteL, buf); - - panel->note2L = WMCreateLabel(panel->win); - WMResizeWidget(panel->note2L, PWIDTH-20, 100); - WMMoveWidget(panel->note2L, 10, 130); - WMSetLabelTextAlignment(panel->note2L, WALeft); - WMSetLabelText(panel->note2L, - _(" This fatal error occured probably due to a bug." - " Please fill the included BUGFORM and " - "report it to bugs@windowmaker.org.")); - - - panel->whatF = WMCreateFrame(panel->win); - WMResizeWidget(panel->whatF, PWIDTH-20, 50); - WMMoveWidget(panel->whatF, 10, 240); - WMSetFrameTitle(panel->whatF, _("What do you want to do now?")); - - panel->whatP = WMCreatePopUpButton(panel->whatF); - WMResizeWidget(panel->whatP, PWIDTH-20-70, 20); - WMMoveWidget(panel->whatP, 35, 20); - WMSetPopUpButtonPullsDown(panel->whatP, False); - WMSetPopUpButtonText(panel->whatP, _("Select action")); - WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file")); - WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker")); - WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager")); - WMSetPopUpButtonAction(panel->whatP, setAction, panel); - WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart); - panel->action = WMRestart; - - WMMapSubwidgets(panel->whatF); - - panel->okB = WMCreateCommandButton(panel->win); - WMResizeWidget(panel->okB, 80, 26); - WMMoveWidget(panel->okB, 205, 309); - WMSetButtonText(panel->okB, _("OK")); - WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow)); - WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow)); - WMSetButtonImagePosition(panel->okB, WIPRight); - WMSetButtonAction(panel->okB, buttonCallback, panel); - - panel->done = 0; - - WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, - handleKeyPress, panel); - - WMRealizeWidget(panel->win); - WMMapSubwidgets(panel->win); - - WMMapWidget(panel->win); - - XSetInputFocus(newdpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime); - - while (!panel->done) { - XEvent event; - - WMNextEvent(newdpy, &event); - WMHandleEvent(&event); - } - - action = panel->action; - - WMUnmapWidget(panel->win); - WMDestroyWidget(panel->win); - free(panel); - XCloseDisplay(newdpy); - - return action; -} - - static int catchXError(Display *dpy, XErrorEvent *error) { @@ -561,7 +312,20 @@ handleSig(int sig) dumpcore = 1; #ifndef NO_EMERGENCY_AUTORESTART - crashAction = showCrashPanel(sig); + /* Close the X connection and open a new one. This is to avoid messing + * Xlib because we call to Xlib functions in a signal handler. + */ + if (dpy) + XCloseDisplay(dpy); + dpy = XOpenDisplay(""); + if (dpy) { + crashAction = wShowCrashingDialogPanel(sig); + XCloseDisplay(dpy); + dpy = NULL; + } else { + wsyserror(_("cannot open connection for crashing dialog panel. Aborting.")); + crashAction = WMAbort; + } if (crashAction == WMAbort) { signal(sig, SIG_DFL); diff --git a/src/texture.c b/src/texture.c index 3d791ece..a4545cfc 100644 --- a/src/texture.c +++ b/src/texture.c @@ -426,7 +426,7 @@ RImage* wTextureRenderImage(WTexture *texture, int width, int height, int relief) { - RImage *image; + RImage *image = NULL; RColor color1; int d; int subtype;