1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-20 04:48:06 +01:00
Files
wmaker/src/dialog.c
Christophe CURIS f29fba2c83 InfoPanel: Added display of memory fragmentation information
This information is displayed only when debug mode was enabled to
avoid confusing users.
2013-05-10 15:48:33 +01:00

1653 lines
42 KiB
C

/* dialog.c - dialog windows for internal use
*
* Window Maker window manager
*
* Copyright (c) 1997-2003 Alfredo K. Kojima
* Copyright (c) 1998-2003 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
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "wconfig.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include <signal.h>
#ifdef __FreeBSD__
#include <sys/signal.h>
#endif
#ifndef PATH_MAX
#define PATH_MAX DEFAULT_PATH_MAX
#endif
#include "WindowMaker.h"
#include "GNUstep.h"
#include "screen.h"
#include "dialog.h"
#include "misc.h"
#include "stacking.h"
#include "framewin.h"
#include "window.h"
#include "actions.h"
#include "xinerama.h"
extern WPreferences wPreferences;
static WMPoint getCenter(WScreen * scr, int width, int height)
{
return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
}
int wMessageDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
{
WMAlertPanel *panel;
Window parent;
WWindow *wwin;
int result;
WMPoint center;
panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
center = getCenter(scr, 400, 180);
wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
wwin->client_leader = WMWidgetXID(panel->win);
WMMapWidget(panel->win);
wWindowMap(wwin);
WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
result = panel->result;
WMUnmapWidget(panel->win);
wUnmanageWindow(wwin, False, False);
WMDestroyAlertPanel(panel);
XDestroyWindow(dpy, parent);
return result;
}
static void toggleSaveSession(WMWidget *w, void *data)
{
wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
}
int wExitDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
{
WMAlertPanel *panel;
WMButton *saveSessionBtn;
Window parent;
WWindow *wwin;
WMPoint center;
int result;
panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
/* add save session button */
saveSessionBtn = WMCreateSwitchButton(panel->hbox);
WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, 200, 0, 0);
WMSetButtonText(saveSessionBtn, _("Save workspace state"));
WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
WMRealizeWidget(saveSessionBtn);
WMMapWidget(saveSessionBtn);
parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
center = getCenter(scr, 400, 180);
wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
wwin->client_leader = WMWidgetXID(panel->win);
WMMapWidget(panel->win);
wWindowMap(wwin);
WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
result = panel->result;
WMUnmapWidget(panel->win);
wUnmanageWindow(wwin, False, False);
WMDestroyAlertPanel(panel);
XDestroyWindow(dpy, parent);
return result;
}
typedef struct _WMInputPanelWithHistory {
WMInputPanel *panel;
WMArray *history;
int histpos;
char *prefix;
char *suffix;
char *rest;
WMArray *variants;
int varpos;
} WMInputPanelWithHistory;
static char *HistoryFileName(const char *name)
{
char *filename = NULL;
filename = wstrdup(wusergnusteppath());
filename = wstrappend(filename, "/.AppInfo/WindowMaker/History");
if (name && strlen(name)) {
filename = wstrappend(filename, ".");
filename = wstrappend(filename, name);
}
return filename;
}
static int strmatch(const void *str1, const void *str2)
{
return !strcmp((const char *)str1, (const char *)str2);
}
static WMArray *LoadHistory(const char *filename, int max)
{
WMPropList *plhistory;
WMPropList *plitem;
WMArray *history;
int i, num;
char *str;
history = WMCreateArrayWithDestructor(1, wfree);
WMAddToArray(history, wstrdup(""));
plhistory = WMReadPropListFromFile(filename);
if (plhistory) {
if (WMIsPLArray(plhistory)) {
num = WMGetPropListItemCount(plhistory);
for (i = 0; i < num; ++i) {
plitem = WMGetFromPLArray(plhistory, i);
if (WMIsPLString(plitem)) {
str = WMGetFromPLString(plitem);
if (WMFindInArray(history, strmatch, str) == WANotFound) {
/*
* The string here is duplicated because it will be freed
* automatically when the array is deleted. This is not really
* great because it is already an allocated string,
* unfortunately we cannot re-use it because it will be freed
* when we discard the PL (and we don't want to waste the PL's
* memory either)
*/
WMAddToArray(history, wstrdup(str));
if (--max <= 0)
break;
}
}
}
}
WMReleasePropList(plhistory);
}
return history;
}
static void SaveHistory(WMArray * history, const char *filename)
{
int i;
WMPropList *plhistory;
plhistory = WMCreatePLArray(NULL);
for (i = 0; i < WMGetArrayItemCount(history); ++i)
WMAddToPLArray(plhistory, WMCreatePLString(WMGetFromArray(history, i)));
WMWritePropListToFile(plhistory, filename);
WMReleasePropList(plhistory);
}
static int pstrcmp(const char **str1, const char **str2)
{
return strcmp(*str1, *str2);
}
static void
ScanFiles(const char *dir, const char *prefix, unsigned acceptmask, unsigned declinemask, WMArray * result)
{
int prefixlen;
DIR *d;
struct dirent *de;
struct stat sb;
char *fullfilename, *suffix;
prefixlen = strlen(prefix);
if ((d = opendir(dir)) != NULL) {
while ((de = readdir(d)) != NULL) {
if (strlen(de->d_name) > prefixlen &&
!strncmp(prefix, de->d_name, prefixlen) &&
strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..")) {
fullfilename = wstrconcat((char *)dir, "/");
fullfilename = wstrappend(fullfilename, de->d_name);
if (stat(fullfilename, &sb) == 0 &&
(sb.st_mode & acceptmask) &&
!(sb.st_mode & declinemask) &&
WMFindInArray(result, (WMMatchDataProc *) strmatch,
de->d_name + prefixlen) == WANotFound) {
suffix = wstrdup(de->d_name + prefixlen);
if (sb.st_mode & S_IFDIR)
wstrappend(suffix,"/");
WMAddToArray(result, suffix);
}
wfree(fullfilename);
}
}
closedir(d);
}
}
static WMArray *GenerateVariants(const char *complete)
{
Bool firstWord = True;
WMArray *variants = NULL;
char *pos = NULL, *path = NULL, *tmp = NULL, *dir = NULL, *prefix = NULL;
variants = WMCreateArrayWithDestructor(0, wfree);
while (*complete == ' ')
++complete;
if ((pos = strrchr(complete, ' ')) != NULL) {
complete = pos + 1;
firstWord = False;
}
if ((pos = strrchr(complete, '/')) != NULL) {
tmp = wstrndup((char *)complete, pos - complete + 1);
if (*tmp == '~' && *(tmp + 1) == '/' && getenv("HOME")) {
dir = wstrdup(getenv("HOME"));
dir = wstrappend(dir, tmp + 1);
wfree(tmp);
} else {
dir = tmp;
}
prefix = wstrdup(pos + 1);
ScanFiles(dir, prefix, (unsigned)-1, 0, variants);
wfree(dir);
wfree(prefix);
} else if (*complete == '~') {
WMAddToArray(variants, wstrdup("/"));
} else if (firstWord) {
path = getenv("PATH");
while (path) {
pos = strchr(path, ':');
if (pos) {
tmp = wstrndup(path, pos - path);
path = pos + 1;
} else if (*path != '\0') {
tmp = wstrdup(path);
path = NULL;
} else
break;
ScanFiles(tmp, complete, S_IXOTH | S_IXGRP | S_IXUSR, S_IFDIR, variants);
wfree(tmp);
}
}
WMSortArray(variants, (WMCompareDataProc *) pstrcmp);
return variants;
}
static void handleHistoryKeyPress(XEvent * event, void *clientData)
{
char *text;
unsigned pos;
WMInputPanelWithHistory *p = (WMInputPanelWithHistory *) clientData;
KeySym ksym;
ksym = XLookupKeysym(&event->xkey, 0);
switch (ksym) {
case XK_Up:
if (p->histpos < WMGetArrayItemCount(p->history) - 1) {
if (p->histpos == 0)
wfree(WMReplaceInArray(p->history, 0, WMGetTextFieldText(p->panel->text)));
p->histpos++;
WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
}
break;
case XK_Down:
if (p->histpos > 0) {
p->histpos--;
WMSetTextFieldText(p->panel->text, WMGetFromArray(p->history, p->histpos));
}
break;
case XK_Tab:
if (!p->variants) {
text = WMGetTextFieldText(p->panel->text);
pos = WMGetTextFieldCursorPosition(p->panel->text);
p->prefix = wstrndup(text, pos);
p->suffix = wstrdup(text + pos);
wfree(text);
p->variants = GenerateVariants(p->prefix);
p->varpos = 0;
if (!p->variants) {
wfree(p->prefix);
wfree(p->suffix);
p->prefix = NULL;
p->suffix = NULL;
}
}
if (p->variants && p->prefix && p->suffix) {
p->varpos++;
if (p->varpos > WMGetArrayItemCount(p->variants))
p->varpos = 0;
if (p->varpos > 0)
text = wstrconcat(p->prefix, WMGetFromArray(p->variants, p->varpos - 1));
else
text = wstrdup(p->prefix);
pos = strlen(text);
text = wstrappend(text, p->suffix);
WMSetTextFieldText(p->panel->text, text);
WMSetTextFieldCursorPosition(p->panel->text, pos);
wfree(text);
}
break;
}
if (ksym != XK_Tab) {
if (p->prefix) {
wfree(p->prefix);
p->prefix = NULL;
}
if (p->suffix) {
wfree(p->suffix);
p->suffix = NULL;
}
if (p->variants) {
WMFreeArray(p->variants);
p->variants = NULL;
}
}
}
int wAdvancedInputDialog(WScreen * scr, char *title, char *message, char *name, char **text)
{
WWindow *wwin;
Window parent;
char *result;
WMPoint center;
WMInputPanelWithHistory *p;
char *filename;
filename = HistoryFileName(name);
p = wmalloc(sizeof(WMInputPanelWithHistory));
p->panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
p->history = LoadHistory(filename, wPreferences.history_lines);
p->histpos = 0;
p->prefix = NULL;
p->suffix = NULL;
p->rest = NULL;
p->variants = NULL;
p->varpos = 0;
WMCreateEventHandler(WMWidgetView(p->panel->text), KeyPressMask, handleHistoryKeyPress, p);
parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
XReparentWindow(dpy, WMWidgetXID(p->panel->win), parent, 0, 0);
center = getCenter(scr, 320, 160);
wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
wwin->client_leader = WMWidgetXID(p->panel->win);
WMMapWidget(p->panel->win);
wWindowMap(wwin);
WMRunModalLoop(WMWidgetScreen(p->panel->win), WMWidgetView(p->panel->win));
if (p->panel->result == WAPRDefault) {
result = WMGetTextFieldText(p->panel->text);
wfree(WMReplaceInArray(p->history, 0, wstrdup(result)));
SaveHistory(p->history, filename);
} else
result = NULL;
wUnmanageWindow(wwin, False, False);
WMDestroyInputPanel(p->panel);
WMFreeArray(p->history);
wfree(p);
wfree(filename);
XDestroyWindow(dpy, parent);
if (result == NULL)
return False;
else {
if (*text)
wfree(*text);
*text = result;
return True;
}
}
int wInputDialog(WScreen * scr, char *title, char *message, char **text)
{
WWindow *wwin;
Window parent;
WMInputPanel *panel;
char *result;
WMPoint center;
panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
center = getCenter(scr, 320, 160);
wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
wwin->client_leader = WMWidgetXID(panel->win);
WMMapWidget(panel->win);
wWindowMap(wwin);
WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
if (panel->result == WAPRDefault)
result = WMGetTextFieldText(panel->text);
else
result = NULL;
wUnmanageWindow(wwin, False, False);
WMDestroyInputPanel(panel);
XDestroyWindow(dpy, parent);
if (result == NULL)
return False;
else {
if (*text)
wfree(*text);
*text = result;
return True;
}
}
/*
*****************************************************************
* Icon Selection Panel
*****************************************************************
*/
typedef struct IconPanel {
WScreen *scr;
WMWindow *win;
WMLabel *dirLabel;
WMLabel *iconLabel;
WMList *dirList;
WMList *iconList;
WMFont *normalfont;
WMButton *previewButton;
WMLabel *iconView;
WMLabel *fileLabel;
WMTextField *fileField;
WMButton *okButton;
WMButton *cancelButton;
#if 0
WMButton *chooseButton;
#endif
short done;
short result;
short preview;
} IconPanel;
static void listPixmaps(WScreen * scr, WMList * lPtr, char *path)
{
struct dirent *dentry;
DIR *dir;
char pbuf[PATH_MAX + 16];
char *apath;
IconPanel *panel = WMGetHangedData(lPtr);
panel->preview = False;
apath = wexpandpath(path);
dir = opendir(apath);
if (!dir) {
char *msg;
char *tmp;
tmp = _("Could not open directory ");
msg = wmalloc(strlen(tmp) + strlen(path) + 6);
strcpy(msg, tmp);
strcat(msg, path);
wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
wfree(msg);
wfree(apath);
return;
}
/* list contents in the column */
while ((dentry = readdir(dir))) {
struct stat statb;
if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
continue;
strcpy(pbuf, apath);
strcat(pbuf, "/");
strcat(pbuf, dentry->d_name);
if (stat(pbuf, &statb) < 0)
continue;
if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
&& statb.st_mode & (S_IFREG | S_IFLNK)) {
WMAddListItem(lPtr, dentry->d_name);
}
}
WMSortListItems(lPtr);
closedir(dir);
wfree(apath);
panel->preview = True;
}
static void setViewedImage(IconPanel * panel, char *file)
{
WMPixmap *pixmap;
RColor color;
color.red = 0xae;
color.green = 0xaa;
color.blue = 0xae;
color.alpha = 0;
pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
if (!pixmap) {
WMSetButtonEnabled(panel->okButton, False);
WMSetLabelText(panel->iconView, _("Could not load image file "));
WMSetLabelImage(panel->iconView, NULL);
} else {
WMSetButtonEnabled(panel->okButton, True);
WMSetLabelText(panel->iconView, NULL);
WMSetLabelImage(panel->iconView, pixmap);
WMReleasePixmap(pixmap);
}
}
static void listCallback(void *self, void *data)
{
WMList *lPtr = (WMList *) self;
IconPanel *panel = (IconPanel *) data;
char *path;
if (lPtr == panel->dirList) {
WMListItem *item = WMGetListSelectedItem(lPtr);
if (item == NULL)
return;
path = item->text;
WMSetTextFieldText(panel->fileField, path);
WMSetLabelImage(panel->iconView, NULL);
WMSetButtonEnabled(panel->okButton, False);
WMClearList(panel->iconList);
listPixmaps(panel->scr, panel->iconList, path);
} else {
char *tmp, *iconFile;
WMListItem *item = WMGetListSelectedItem(panel->dirList);
if (item == NULL)
return;
path = item->text;
tmp = wexpandpath(path);
item = WMGetListSelectedItem(panel->iconList);
if (item == NULL)
return;
iconFile = item->text;
path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
strcpy(path, tmp);
strcat(path, "/");
strcat(path, iconFile);
wfree(tmp);
WMSetTextFieldText(panel->fileField, path);
setViewedImage(panel, path);
wfree(path);
}
}
static void listIconPaths(WMList * lPtr)
{
char *paths;
char *path;
paths = wstrdup(wPreferences.icon_path);
path = strtok(paths, ":");
do {
char *tmp;
tmp = wexpandpath(path);
/* do not sort, because the order implies the order of
* directories searched */
if (access(tmp, X_OK) == 0)
WMAddListItem(lPtr, path);
wfree(tmp);
} while ((path = strtok(NULL, ":")) != NULL);
wfree(paths);
}
static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
{
IconPanel *panel = WMGetHangedData(lPtr);
WScreen *scr = panel->scr;
GC gc = scr->draw_gc;
GC copygc = scr->copy_gc;
char *file, *dirfile;
WMPixmap *pixmap;
WMColor *back;
WMSize size;
WMScreen *wmscr = WMWidgetScreen(panel->win);
RColor color;
int x, y, width, height, len;
if (!panel->preview)
return;
x = rect->pos.x;
y = rect->pos.y;
width = rect->size.width;
height = rect->size.height;
back = (state & WLDSSelected) ? scr->white : scr->gray;
dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
len = strlen(dirfile) + strlen(text) + 4;
file = wmalloc(len);
snprintf(file, len, "%s/%s", dirfile, text);
wfree(dirfile);
color.red = WMRedComponentOfColor(back) >> 8;
color.green = WMGreenComponentOfColor(back) >> 8;
color.blue = WMBlueComponentOfColor(back) >> 8;
color.alpha = WMGetColorAlpha(back) >> 8;
pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
wfree(file);
if (!pixmap) {
/*WMRemoveListItem(lPtr, index); */
return;
}
XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
XSetClipMask(dpy, gc, None);
/*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
size = WMGetPixmapSize(pixmap);
XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
x + (width - size.width) / 2, y + 2);
{
int i, j;
int fheight = WMFontHeight(panel->normalfont);
int tlen = strlen(text);
int twidth = WMWidthOfString(panel->normalfont, text, tlen);
int ofx, ofy;
ofx = x + (width - twidth) / 2;
ofy = y + 64 - fheight;
for (i = -1; i < 2; i++)
for (j = -1; j < 2; j++)
WMDrawString(wmscr, d, scr->white, panel->normalfont,
ofx + i, ofy + j, text, tlen);
WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
}
WMReleasePixmap(pixmap);
/* I hope it is better to do not use cache / on my box it is fast nuff */
XFlush(dpy);
}
static void buttonCallback(void *self, void *clientData)
{
WMButton *bPtr = (WMButton *) self;
IconPanel *panel = (IconPanel *) clientData;
if (bPtr == panel->okButton) {
panel->done = True;
panel->result = True;
} else if (bPtr == panel->cancelButton) {
panel->done = True;
panel->result = False;
} else if (bPtr == panel->previewButton) {
/**** Previewer ****/
WMSetButtonEnabled(bPtr, False);
WMSetListUserDrawItemHeight(panel->iconList, 68);
WMSetListUserDrawProc(panel->iconList, drawIconProc);
WMRedisplayWidget(panel->iconList);
/* for draw proc to access screen/gc */
/*** end preview ***/
}
#if 0
else if (bPtr == panel->chooseButton) {
WMOpenPanel *op;
op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
char *path;
path = WMGetFilePanelFile(op);
WMSetTextFieldText(panel->fileField, path);
setViewedImage(panel, path);
wfree(path);
}
WMDestroyFilePanel(op);
}
#endif
}
static void keyPressHandler(XEvent * event, void *data)
{
IconPanel *panel = (IconPanel *) data;
char buffer[32];
KeySym ksym;
int iidx;
int didx;
int item = 0;
WMList *list = NULL;
if (event->type == KeyRelease)
return;
buffer[0] = 0;
XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
iidx = WMGetListSelectedItemRow(panel->iconList);
didx = WMGetListSelectedItemRow(panel->dirList);
switch (ksym) {
case XK_Up:
if (iidx > 0)
item = iidx - 1;
else
item = iidx;
list = panel->iconList;
break;
case XK_Down:
if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
item = iidx + 1;
else
item = iidx;
list = panel->iconList;
break;
case XK_Home:
item = 0;
list = panel->iconList;
break;
case XK_End:
item = WMGetListNumberOfRows(panel->iconList) - 1;
list = panel->iconList;
break;
case XK_Next:
if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
item = didx + 1;
else
item = didx;
list = panel->dirList;
break;
case XK_Prior:
if (didx > 0)
item = didx - 1;
else
item = 0;
list = panel->dirList;
break;
case XK_Return:
WMPerformButtonClick(panel->okButton);
break;
case XK_Escape:
WMPerformButtonClick(panel->cancelButton);
break;
}
if (list) {
WMSelectListItem(list, item);
WMSetListPosition(list, item - 5);
listCallback(list, panel);
}
}
Bool wIconChooserDialog(WScreen * scr, char **file, char *instance, char *class)
{
WWindow *wwin;
Window parent;
IconPanel *panel;
WMColor *color;
WMFont *boldFont;
Bool result;
panel = wmalloc(sizeof(IconPanel));
panel->scr = scr;
panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
WMResizeWidget(panel->win, 450, 280);
WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
panel->dirLabel = WMCreateLabel(panel->win);
WMResizeWidget(panel->dirLabel, 200, 20);
WMMoveWidget(panel->dirLabel, 10, 7);
WMSetLabelText(panel->dirLabel, _("Directories"));
WMSetLabelFont(panel->dirLabel, boldFont);
WMSetLabelTextAlignment(panel->dirLabel, WACenter);
WMSetLabelRelief(panel->dirLabel, WRSunken);
panel->iconLabel = WMCreateLabel(panel->win);
WMResizeWidget(panel->iconLabel, 140, 20);
WMMoveWidget(panel->iconLabel, 215, 7);
WMSetLabelText(panel->iconLabel, _("Icons"));
WMSetLabelFont(panel->iconLabel, boldFont);
WMSetLabelTextAlignment(panel->iconLabel, WACenter);
WMReleaseFont(boldFont);
color = WMWhiteColor(scr->wmscreen);
WMSetLabelTextColor(panel->dirLabel, color);
WMSetLabelTextColor(panel->iconLabel, color);
WMReleaseColor(color);
color = WMDarkGrayColor(scr->wmscreen);
WMSetWidgetBackgroundColor(panel->iconLabel, color);
WMSetWidgetBackgroundColor(panel->dirLabel, color);
WMReleaseColor(color);
WMSetLabelRelief(panel->iconLabel, WRSunken);
panel->dirList = WMCreateList(panel->win);
WMResizeWidget(panel->dirList, 200, 170);
WMMoveWidget(panel->dirList, 10, 30);
WMSetListAction(panel->dirList, listCallback, panel);
panel->iconList = WMCreateList(panel->win);
WMResizeWidget(panel->iconList, 140, 170);
WMMoveWidget(panel->iconList, 215, 30);
WMSetListAction(panel->iconList, listCallback, panel);
WMHangData(panel->iconList, panel);
panel->previewButton = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->previewButton, 75, 26);
WMMoveWidget(panel->previewButton, 365, 130);
WMSetButtonText(panel->previewButton, _("Preview"));
WMSetButtonAction(panel->previewButton, buttonCallback, panel);
panel->iconView = WMCreateLabel(panel->win);
WMResizeWidget(panel->iconView, 75, 75);
WMMoveWidget(panel->iconView, 365, 40);
WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
WMSetLabelRelief(panel->iconView, WRSunken);
WMSetLabelTextAlignment(panel->iconView, WACenter);
panel->fileLabel = WMCreateLabel(panel->win);
WMResizeWidget(panel->fileLabel, 80, 20);
WMMoveWidget(panel->fileLabel, 10, 210);
WMSetLabelText(panel->fileLabel, _("File Name:"));
panel->fileField = WMCreateTextField(panel->win);
WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
WMResizeWidget(panel->fileField, 345, 20);
WMMoveWidget(panel->fileField, 95, 210);
WMSetTextFieldEditable(panel->fileField, False);
panel->okButton = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->okButton, 80, 26);
WMMoveWidget(panel->okButton, 360, 240);
WMSetButtonText(panel->okButton, _("OK"));
WMSetButtonEnabled(panel->okButton, False);
WMSetButtonAction(panel->okButton, buttonCallback, panel);
panel->cancelButton = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->cancelButton, 80, 26);
WMMoveWidget(panel->cancelButton, 270, 240);
WMSetButtonText(panel->cancelButton, _("Cancel"));
WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
#if 0
panel->chooseButton = WMCreateCommandButton(panel->win);
WMResizeWidget(panel->chooseButton, 110, 26);
WMMoveWidget(panel->chooseButton, 150, 240);
WMSetButtonText(panel->chooseButton, _("Choose File"));
WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
#endif
WMRealizeWidget(panel->win);
WMMapSubwidgets(panel->win);
parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
{
char *tmp;
int len = (instance ? strlen(instance) : 0)
+ (class ? strlen(class) : 0) + 32;
WMPoint center;
tmp = wmalloc(len);
if (tmp && (instance || class))
snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
else
strcpy(tmp, _("Icon Chooser"));
center = getCenter(scr, 450, 280);
wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
wfree(tmp);
}
/* put icon paths in the list */
listIconPaths(panel->dirList);
WMMapWidget(panel->win);
wWindowMap(wwin);
while (!panel->done) {
XEvent event;
WMNextEvent(dpy, &event);
WMHandleEvent(&event);
}
if (panel->result) {
char *defaultPath, *wantedPath;
/* check if the file the user selected is not the one that
* would be loaded by default with the current search path */
*file = WMGetListSelectedItem(panel->iconList)->text;
if (**file == 0) {
wfree(*file);
*file = NULL;
} else {
defaultPath = FindImage(wPreferences.icon_path, *file);
wantedPath = WMGetTextFieldText(panel->fileField);
/* if the file is not the default, use full path */
if (strcmp(wantedPath, defaultPath) != 0) {
*file = wantedPath;
} else {
*file = wstrdup(*file);
wfree(wantedPath);
}
wfree(defaultPath);
}
} else {
*file = NULL;
}
result = panel->result;
WMReleaseFont(panel->normalfont);
WMUnmapWidget(panel->win);
WMDestroyWidget(panel->win);
wUnmanageWindow(wwin, False, False);
wfree(panel);
XDestroyWindow(dpy, parent);
return result;
}
/*
***********************************************************************
* Info Panel
***********************************************************************
*/
typedef struct {
WScreen *scr;
WWindow *wwin;
WMWindow *win;
WMLabel *logoL;
WMLabel *name1L;
WMFrame *lineF;
WMLabel *name2L;
WMLabel *versionL;
WMLabel *infoL;
WMLabel *copyrL;
} InfoPanel;
#define COPYRIGHT_TEXT \
"Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
"Copyright \xc2\xa9 1998-2006 Dan Pascu"
static InfoPanel *thePanel = NULL;
static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
{
WMUnmapWidget(thePanel);
wUnmanageWindow(thePanel->wwin, False, False);
WMDestroyWidget(thePanel->win);
wfree(thePanel);
thePanel = NULL;
}
void wShowInfoPanel(WScreen * scr)
{
InfoPanel *panel;
WMPixmap *logo;
WMFont *font;
char *strbuf = NULL;
const char *separator;
char buffer[256];
char *name;
Window parent;
WWindow *wwin;
char **strl;
int i, width = 50, sepHeight;
char *visuals[] = {
"StaticGray",
"GrayScale",
"StaticColor",
"PseudoColor",
"TrueColor",
"DirectColor"
};
if (thePanel) {
if (thePanel->scr == scr) {
wRaiseFrame(thePanel->wwin->frame->core);
wSetFocusTo(scr, thePanel->wwin);
}
return;
}
panel = wmalloc(sizeof(InfoPanel));
panel->scr = scr;
panel->win = WMCreateWindow(scr->wmscreen, "info");
WMResizeWidget(panel->win, 390, 230);
logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
if (!logo) {
logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
}
if (logo) {
panel->logoL = WMCreateLabel(panel->win);
WMResizeWidget(panel->logoL, 64, 64);
WMMoveWidget(panel->logoL, 30, 20);
WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
WMSetLabelImage(panel->logoL, logo);
WMReleasePixmap(logo);
}
sepHeight = 3;
panel->name1L = WMCreateLabel(panel->win);
WMResizeWidget(panel->name1L, 240, 30 + 2);
WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
font = WMCreateFont(scr->wmscreen, name);
strbuf = "Window Maker";
if (font) {
width = WMWidthOfString(font, strbuf, strlen(strbuf));
WMSetLabelFont(panel->name1L, font);
WMReleaseFont(font);
}
WMSetLabelTextAlignment(panel->name1L, WACenter);
WMSetLabelText(panel->name1L, strbuf);
panel->lineF = WMCreateFrame(panel->win);
WMResizeWidget(panel->lineF, width, sepHeight);
WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
WMSetFrameRelief(panel->lineF, WRSimple);
WMSetWidgetBackgroundColor(panel->lineF, scr->black);
panel->name2L = WMCreateLabel(panel->win);
WMResizeWidget(panel->name2L, 240, 24);
WMMoveWidget(panel->name2L, 100, 60);
name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
font = WMCreateFont(scr->wmscreen, name);
if (font) {
WMSetLabelFont(panel->name2L, font);
WMReleaseFont(font);
font = NULL;
}
WMSetLabelTextAlignment(panel->name2L, WACenter);
WMSetLabelText(panel->name2L, _("Window Manager for X"));
snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
panel->versionL = WMCreateLabel(panel->win);
WMResizeWidget(panel->versionL, 310, 16);
WMMoveWidget(panel->versionL, 30, 95);
WMSetLabelTextAlignment(panel->versionL, WARight);
WMSetLabelText(panel->versionL, buffer);
WMSetLabelWraps(panel->versionL, False);
panel->copyrL = WMCreateLabel(panel->win);
WMResizeWidget(panel->copyrL, 360, 40);
WMMoveWidget(panel->copyrL, 15, 185);
WMSetLabelTextAlignment(panel->copyrL, WALeft);
WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
font = WMSystemFontOfSize(scr->wmscreen, 11);
if (font) {
WMSetLabelFont(panel->copyrL, font);
WMReleaseFont(font);
font = NULL;
}
strbuf = NULL;
snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
(unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
strbuf = wstrappend(strbuf, buffer);
switch (scr->w_depth) {
case 15:
strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
break;
case 16:
strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
break;
case 24:
case 32:
strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
break;
default:
snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
strbuf = wstrappend(strbuf, buffer);
break;
}
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
{
struct mallinfo ma = mallinfo();
snprintf(buffer, sizeof(buffer),
#ifdef DEBUG
_("Total memory allocated: %i kB (in use: %i kB, %d free chunks).\n"),
#else
_("Total memory allocated: %i kB (in use: %i kB).\n"),
#endif
(ma.arena + ma.hblkhd) / 1024,
(ma.uordblks + ma.hblkhd) / 1024
#ifdef DEBUG
/*
* This information is representative of the memory
* fragmentation. In ideal case it should be 1, but
* that is never possible
*/
, ma.ordblks
#endif
);
strbuf = wstrappend(strbuf, buffer);
}
#endif
strbuf = wstrappend(strbuf, _("Supported image formats: "));
strl = RSupportedFileFormats();
separator = NULL;
for (i = 0; strl[i] != NULL; i++) {
if (separator != NULL)
strbuf = wstrappend(strbuf, separator);
strbuf = wstrappend(strbuf, strl[i]);
separator = ", ";
}
strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
strbuf = wstrappend(strbuf, "WMSPEC");
#ifdef HAVE_XRANDR
strbuf = wstrappend(strbuf, ", XRandR ");
if (has_randr)
strbuf = wstrappend(strbuf, _("(Supported)"));
else
strbuf = wstrappend(strbuf, _("(Unsupported)"));
#endif
#ifdef MWM_HINTS
strbuf = wstrappend(strbuf, ", MWM");
#endif
#ifdef XINERAMA
strbuf = wstrappend(strbuf, _("\n"));
#ifdef SOLARIS_XINERAMA
strbuf = wstrappend(strbuf, _("Solaris "));
#endif
strbuf = wstrappend(strbuf, _("Xinerama: "));
{
char tmp[128];
snprintf(tmp, sizeof(tmp) - 1, _("%d heads found."), scr->xine_info.count);
strbuf = wstrappend(strbuf, tmp);
}
#endif
panel->infoL = WMCreateLabel(panel->win);
WMResizeWidget(panel->infoL, 350, 75);
WMMoveWidget(panel->infoL, 15, 115);
WMSetLabelText(panel->infoL, strbuf);
font = WMSystemFontOfSize(scr->wmscreen, 11);
if (font) {
WMSetLabelFont(panel->infoL, font);
WMReleaseFont(font);
font = NULL;
}
wfree(strbuf);
WMRealizeWidget(panel->win);
WMMapSubwidgets(panel->win);
parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
WMMapWidget(panel->win);
{
WMPoint center = getCenter(scr, 382, 230);
wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
}
WSETUFLAG(wwin, no_closable, 0);
WSETUFLAG(wwin, no_close_button, 0);
#ifdef XKB_BUTTON_HINT
wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
#endif
wWindowUpdateButtonImages(wwin);
wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
wwin->frame->on_click_right = destroyInfoPanel;
wWindowMap(wwin);
panel->wwin = wwin;
thePanel = panel;
}
/*
***********************************************************************
* Legal Panel
***********************************************************************
*/
typedef struct {
WScreen *scr;
WWindow *wwin;
WMWindow *win;
WMLabel *licenseL;
} LegalPanel;
static LegalPanel *legalPanel = NULL;
static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
{
WMUnmapWidget(legalPanel->win);
WMDestroyWidget(legalPanel->win);
wUnmanageWindow(legalPanel->wwin, False, False);
wfree(legalPanel);
legalPanel = NULL;
}
void wShowLegalPanel(WScreen * scr)
{
LegalPanel *panel;
Window parent;
WWindow *wwin;
if (legalPanel) {
if (legalPanel->scr == scr) {
wRaiseFrame(legalPanel->wwin->frame->core);
wSetFocusTo(scr, legalPanel->wwin);
}
return;
}
panel = wmalloc(sizeof(LegalPanel));
panel->scr = scr;
panel->win = WMCreateWindow(scr->wmscreen, "legal");
WMResizeWidget(panel->win, 420, 250);
panel->licenseL = WMCreateLabel(panel->win);
WMSetLabelWraps(panel->licenseL, True);
WMResizeWidget(panel->licenseL, 400, 230);
WMMoveWidget(panel->licenseL, 10, 10);
WMSetLabelTextAlignment(panel->licenseL, WALeft);
WMSetLabelText(panel->licenseL,
_(" Window Maker is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License as\n"
"published by the Free Software Foundation; either version 2 of the\n"
"License, or (at your option) any later version.\n\n"
" Window Maker is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty\n"
"of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"See the GNU General Public License for more details.\n\n"
" You should have received a copy of the GNU General Public\n"
"License along with this program; if not, write to the Free Software\n"
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n"
"02110-1301 USA."));
WMSetLabelRelief(panel->licenseL, WRGroove);
WMRealizeWidget(panel->win);
WMMapSubwidgets(panel->win);
parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
{
WMPoint center = getCenter(scr, 420, 250);
wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
}
WSETUFLAG(wwin, no_closable, 0);
WSETUFLAG(wwin, no_close_button, 0);
wWindowUpdateButtonImages(wwin);
wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
#ifdef XKB_BUTTON_HINT
wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
#endif
wwin->frame->on_click_right = destroyLegalPanel;
panel->wwin = wwin;
WMMapWidget(panel->win);
wWindowMap(wwin);
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);
}
/* Make this read the logo from a compiled in pixmap -Dan */
static WMPixmap *getWindowMakerIconImage(WMScreen *scr)
{
WMPixmap *pix = NULL;
char *path = NULL;
/* Get the Logo icon, without the default icon */
path = get_icon_filename(NULL, "Logo", "WMPanel", NULL, False);
if (path) {
RColor gray;
gray.red = 0xae;
gray.green = 0xaa;
gray.blue = 0xae;
gray.alpha = 0;
pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
wfree(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));
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) {
werror(_("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, 200, 30);
WMMoveWidget(panel->nameL, 80, 25);
WMSetLabelTextAlignment(panel->nameL, WALeft);
font = WMBoldSystemFontOfSize(scr, 24);
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);
snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
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.info."));
WMSetLabelWraps(panel->note2L, True);
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);
wfree(panel);
return action;
}