kbd shortcuts for icon dialog
[wmaker-crm.git] / src / dialog.c
bloba95fd72f9a2ff9a09621a06ee3514702098e3b8c
1 /* dialog.c - dialog windows for internal use
2 *
3 * Window Maker window manager
4 *
5 * Copyright (c) 1997, 1998 Alfredo K. Kojima
6 * Copyright (c) 1999 Dan Pascu
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 * USA.
24 #include "wconfig.h"
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include <X11/keysym.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <dirent.h>
37 #include <limits.h>
39 #ifdef HAVE_MALLOC_H
40 #include <malloc.h>
41 #endif
43 #include <signal.h>
44 #ifdef __FreeBSD__
45 #include <sys/signal.h>
46 #endif
49 #ifndef PATH_MAX
50 #define PATH_MAX DEFAULT_PATH_MAX
51 #endif
53 #include "WindowMaker.h"
54 #include "GNUstep.h"
55 #include "screen.h"
56 #include "dialog.h"
57 #include "funcs.h"
58 #include "stacking.h"
59 #include "framewin.h"
60 #include "window.h"
61 #include "actions.h"
62 #include "defaults.h"
65 extern WPreferences wPreferences;
69 int
70 wMessageDialog(WScreen *scr, char *title, char *message,
71 char *defBtn, char *altBtn, char *othBtn)
73 WMAlertPanel *panel;
74 Window parent;
75 WWindow *wwin;
76 int result;
78 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
79 defBtn, altBtn, othBtn);
81 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
83 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
85 wwin = wManageInternalWindow(scr, parent, None, NULL,
86 (scr->scr_width - 400)/2,
87 (scr->scr_height - 180)/2, 400, 180);
88 wwin->client_leader = WMWidgetXID(panel->win);
90 WMMapWidget(panel->win);
92 wWindowMap(wwin);
94 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
96 result = panel->result;
98 WMUnmapWidget(panel->win);
100 wUnmanageWindow(wwin, False, False);
102 WMDestroyAlertPanel(panel);
104 XDestroyWindow(dpy, parent);
106 return result;
112 wInputDialog(WScreen *scr, char *title, char *message, char **text)
114 WWindow *wwin;
115 Window parent;
116 WMInputPanel *panel;
117 char *result;
120 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text,
121 _("OK"), _("Cancel"));
124 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
125 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
127 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
129 wwin = wManageInternalWindow(scr, parent, None, NULL,
130 (scr->scr_width - 320)/2,
131 (scr->scr_height - 160)/2, 320, 160);
133 wwin->client_leader = WMWidgetXID(panel->win);
135 WMMapWidget(panel->win);
137 wWindowMap(wwin);
139 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
141 if (panel->result == WAPRDefault)
142 result = WMGetTextFieldText(panel->text);
143 else
144 result = NULL;
146 wUnmanageWindow(wwin, False, False);
148 WMDestroyInputPanel(panel);
150 XDestroyWindow(dpy, parent);
152 if (result==NULL)
153 return False;
154 else {
155 if (*text)
156 wfree(*text);
157 *text = result;
159 return True;
165 *****************************************************************
166 * Icon Selection Panel
167 *****************************************************************
170 typedef struct IconPanel {
172 WScreen *scr;
174 WMWindow *win;
176 WMLabel *dirLabel;
177 WMLabel *iconLabel;
179 WMList *dirList;
180 WMList *iconList;
181 WMFont *normalfont;
183 WMButton *previewButton;
185 WMLabel *iconView;
187 WMLabel *fileLabel;
188 WMTextField *fileField;
190 WMButton *okButton;
191 WMButton *cancelButton;
192 #if 0
193 WMButton *chooseButton;
194 #endif
195 short done;
196 short result;
197 short preview;
198 } IconPanel;
202 static void
203 listPixmaps(WScreen *scr, WMList *lPtr, char *path)
205 struct dirent *dentry;
206 DIR *dir;
207 char pbuf[PATH_MAX+16];
208 char *apath;
209 IconPanel *panel = WMGetHangedData(lPtr);
211 panel->preview = False;
213 apath = wexpandpath(path);
214 dir = opendir(apath);
216 if (!dir) {
217 char *msg;
218 char *tmp;
219 tmp = _("Could not open directory ");
220 msg = wmalloc(strlen(tmp)+strlen(path)+6);
221 strcpy(msg, tmp);
222 strcat(msg, path);
224 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
225 wfree(msg);
226 wfree(apath);
227 return;
230 /* list contents in the column */
231 while ((dentry = readdir(dir))) {
232 struct stat statb;
234 if (strcmp(dentry->d_name, ".")==0 ||
235 strcmp(dentry->d_name, "..")==0)
236 continue;
238 strcpy(pbuf, apath);
239 strcat(pbuf, "/");
240 strcat(pbuf, dentry->d_name);
242 if (stat(pbuf, &statb)<0)
243 continue;
245 if (statb.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)
246 && statb.st_mode & (S_IFREG|S_IFLNK)) {
247 WMAddListItem(lPtr, dentry->d_name);
250 WMSortListItems(lPtr);
252 closedir(dir);
253 wfree(apath);
254 panel->preview = True;
259 static void
260 setViewedImage(IconPanel *panel, char *file)
262 WMPixmap *pixmap;
263 RColor color;
265 color.red = 0xae;
266 color.green = 0xaa;
267 color.blue = 0xae;
268 color.alpha = 0;
269 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win),
270 file, &color);
271 if (!pixmap) {
272 WMSetButtonEnabled(panel->okButton, False);
274 WMSetLabelText(panel->iconView, _("Could not load image file "));
276 WMSetLabelImage(panel->iconView, NULL);
277 } else {
278 WMSetButtonEnabled(panel->okButton, True);
280 WMSetLabelText(panel->iconView, NULL);
281 WMSetLabelImage(panel->iconView, pixmap);
282 WMReleasePixmap(pixmap);
287 static void
288 listCallback(void *self, void *data)
290 WMList *lPtr = (WMList*)self;
291 IconPanel *panel = (IconPanel*)data;
292 char *path;
294 if (lPtr==panel->dirList) {
295 WMListItem *item = WMGetListSelectedItem(lPtr);
297 if (item == NULL)
298 return;
299 path = item->text;
301 WMSetTextFieldText(panel->fileField, path);
303 WMSetLabelImage(panel->iconView, NULL);
305 WMSetButtonEnabled(panel->okButton, False);
307 WMClearList(panel->iconList);
308 listPixmaps(panel->scr, panel->iconList, path);
309 } else {
310 char *tmp, *iconFile;
311 WMListItem *item = WMGetListSelectedItem(panel->dirList);
313 if (item == NULL)
314 return;
315 path = item->text;
316 tmp = wexpandpath(path);
318 item = WMGetListSelectedItem(panel->iconList);
319 if (item == NULL)
320 return;
321 iconFile = item->text;
323 path = wmalloc(strlen(tmp)+strlen(iconFile)+4);
324 strcpy(path, tmp);
325 strcat(path, "/");
326 strcat(path, iconFile);
327 wfree(tmp);
328 WMSetTextFieldText(panel->fileField, path);
329 setViewedImage(panel, path);
330 wfree(path);
335 static void
336 listIconPaths(WMList *lPtr)
338 char *paths;
339 char *path;
341 paths = wstrdup(wPreferences.icon_path);
343 path = strtok(paths, ":");
345 do {
346 char *tmp;
348 tmp = wexpandpath(path);
349 /* do not sort, because the order implies the order of
350 * directories searched */
351 if (access(tmp, X_OK)==0)
352 WMAddListItem(lPtr, path);
353 wfree(tmp);
354 } while ((path=strtok(NULL, ":"))!=NULL);
356 wfree(paths);
360 void
361 drawIconProc(WMList *lPtr, int index, Drawable d, char *text,
362 int state, WMRect *rect)
364 IconPanel *panel = WMGetHangedData(lPtr);
365 GC gc = panel->scr->draw_gc;
366 GC copygc = panel->scr->copy_gc;
367 char *buffer, *dirfile;
368 WMPixmap *pixmap;
369 WMColor *blackcolor;
370 WMColor *whitecolor;
371 WMSize size;
372 WMScreen *wmscr=WMWidgetScreen(panel->win);
373 int width;
375 if(!panel->preview) return;
377 width = rect->size.width;
379 blackcolor = WMBlackColor(wmscr);
380 whitecolor = WMWhiteColor(wmscr);
382 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
383 buffer = wmalloc(strlen(dirfile)+strlen(text)+4);
384 sprintf(buffer, "%s/%s", dirfile, text);
385 wfree(dirfile);
387 pixmap = WMCreatePixmapFromFile(WMWidgetScreen(panel->win), buffer);
388 wfree(buffer);
389 if (!pixmap) {
390 WMRemoveListItem(lPtr, index);
391 return;
394 XClearArea(dpy, d, rect->pos.x, rect->pos.y, width, rect->size.height,
395 False);
396 XSetClipMask(dpy, gc, None);
398 XDrawRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x + 5,
399 rect->pos.y +5, width - 10, 54);
401 XDrawLine(dpy, d, WMColorGC(whitecolor), rect->pos.x,
402 rect->pos.y+rect->size.height-1, rect->pos.x+width,
403 rect->pos.y+rect->size.height-1);
406 if (state&WLDSSelected) {
407 XFillRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x,
408 rect->pos.y, width, rect->size.height);
411 size = WMGetPixmapSize(pixmap);
413 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
414 XSetClipOrigin(dpy, copygc, rect->pos.x + (width-size.width)/2,
415 rect->pos.y+2);
416 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
417 size.width>100?100:size.width, size.height>64?64:size.height,
418 rect->pos.x + (width-size.width)/2, rect->pos.y+2);
421 int i,j;
422 int fheight = WMFontHeight(panel->normalfont);
423 int tlen = strlen(text);
424 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
425 int ofx, ofy;
427 ofx = rect->pos.x + (width - twidth)/2;
428 ofy = rect->pos.y + 64 - fheight;
430 for(i=-1;i<2;i++)
431 for(j=-1;j<2;j++)
432 WMDrawString(wmscr, d, WMColorGC(whitecolor),
433 panel->normalfont, ofx+i, ofy+j,
434 text, tlen);
436 WMDrawString(wmscr, d, WMColorGC(blackcolor), panel->normalfont,
437 ofx, ofy, text, tlen);
440 WMReleasePixmap(pixmap);
441 /* I hope it is better to do not use cache / on my box it is fast nuff */
442 XFlush(dpy);
444 WMReleaseColor(blackcolor);
445 WMReleaseColor(whitecolor);
449 static void
450 buttonCallback(void *self, void *clientData)
452 WMButton *bPtr = (WMButton*)self;
453 IconPanel *panel = (IconPanel*)clientData;
456 if (bPtr==panel->okButton) {
457 panel->done = True;
458 panel->result = True;
459 } else if (bPtr==panel->cancelButton) {
460 panel->done = True;
461 panel->result = False;
462 } else if (bPtr==panel->previewButton) {
463 /**** Previewer ****/
464 WMSetButtonEnabled(bPtr, False);
465 WMSetListUserDrawItemHeight(panel->iconList, 68);
466 WMSetListUserDrawProc(panel->iconList, drawIconProc);
467 WMRedisplayWidget(panel->iconList);
468 /* for draw proc to access screen/gc */
469 /*** end preview ***/
471 #if 0
472 else if (bPtr==panel->chooseButton) {
473 WMOpenPanel *op;
475 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
477 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
478 char *path;
479 path = WMGetFilePanelFile(op);
480 WMSetTextFieldText(panel->fileField, path);
481 setViewedImage(panel, path);
482 wfree(path);
484 WMDestroyFilePanel(op);
486 #endif
490 static void
491 keyPressHandler(XEvent *event, void *data)
493 IconPanel *panel = (IconPanel*)data;
494 Display *dpy = event->xany.display;
495 char buffer[32];
496 int count;
497 KeySym ksym;
498 int iidx;
499 int didx;
500 int item;
501 WMList *list = NULL;
503 if (event->type == KeyRelease)
504 return;
506 buffer[0] = 0;
507 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
510 iidx = WMGetListSelectedItemRow(panel->iconList);
511 didx = WMGetListSelectedItemRow(panel->dirList);
513 switch (ksym) {
514 case XK_Up:
515 if (iidx > 0)
516 item = iidx-1;
517 else
518 item = iidx;
519 list = panel->iconList;
520 break;
521 case XK_Down:
522 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
523 item = iidx+1;
524 else
525 item = iidx;
526 list = panel->iconList;
527 break;
528 case XK_Home:
529 item = 0;
530 list = panel->iconList;
531 break;
532 case XK_End:
533 item = WMGetListNumberOfRows(panel->iconList) - 1;
534 list = panel->iconList;
535 break;
536 case XK_Next:
537 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
538 item = didx + 1;
539 else
540 item = didx;
541 list = panel->dirList;
542 break;
543 case XK_Prior:
544 if (didx > 0)
545 item = didx - 1;
546 else
547 item = 0;
548 list = panel->dirList;
549 break;
550 case XK_Return:
551 WMPerformButtonClick(panel->okButton);
552 break;
553 case XK_Escape:
554 WMPerformButtonClick(panel->cancelButton);
555 break;
558 if (list) {
559 WMSelectListItem(list, item);
560 WMSetListPosition(list, item - 5);
561 listCallback(list, panel);
567 Bool
568 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
570 WWindow *wwin;
571 Window parent;
572 IconPanel *panel;
573 WMColor *color;
574 WMFont *boldFont;
576 panel = wmalloc(sizeof(IconPanel));
577 memset(panel, 0, sizeof(IconPanel));
579 panel->scr = scr;
581 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
582 WMResizeWidget(panel->win, 450, 280);
584 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
585 keyPressHandler, panel);
588 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
589 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
591 panel->dirLabel = WMCreateLabel(panel->win);
592 WMResizeWidget(panel->dirLabel, 200, 20);
593 WMMoveWidget(panel->dirLabel, 10, 7);
594 WMSetLabelText(panel->dirLabel, _("Directories"));
595 WMSetLabelFont(panel->dirLabel, boldFont);
596 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
598 WMSetLabelRelief(panel->dirLabel, WRSunken);
600 panel->iconLabel = WMCreateLabel(panel->win);
601 WMResizeWidget(panel->iconLabel, 140, 20);
602 WMMoveWidget(panel->iconLabel, 215, 7);
603 WMSetLabelText(panel->iconLabel, _("Icons"));
604 WMSetLabelFont(panel->iconLabel, boldFont);
605 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
607 WMReleaseFont(boldFont);
609 color = WMWhiteColor(scr->wmscreen);
610 WMSetLabelTextColor(panel->dirLabel, color);
611 WMSetLabelTextColor(panel->iconLabel, color);
612 WMReleaseColor(color);
614 color = WMDarkGrayColor(scr->wmscreen);
615 WMSetWidgetBackgroundColor(panel->iconLabel, color);
616 WMSetWidgetBackgroundColor(panel->dirLabel, color);
617 WMReleaseColor(color);
619 WMSetLabelRelief(panel->iconLabel, WRSunken);
621 panel->dirList = WMCreateList(panel->win);
622 WMResizeWidget(panel->dirList, 200, 170);
623 WMMoveWidget(panel->dirList, 10, 30);
624 WMSetListAction(panel->dirList, listCallback, panel);
626 panel->iconList = WMCreateList(panel->win);
627 WMResizeWidget(panel->iconList, 140, 170);
628 WMMoveWidget(panel->iconList, 215, 30);
629 WMSetListAction(panel->iconList, listCallback, panel);
631 WMHangData(panel->iconList,panel);
633 panel->previewButton = WMCreateCommandButton(panel->win);
634 WMResizeWidget(panel->previewButton, 75, 26);
635 WMMoveWidget(panel->previewButton, 365, 130);
636 WMSetButtonText(panel->previewButton, _("Preview"));
637 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
639 panel->iconView = WMCreateLabel(panel->win);
640 WMResizeWidget(panel->iconView, 75, 75);
641 WMMoveWidget(panel->iconView, 365, 40);
642 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
643 WMSetLabelRelief(panel->iconView, WRSunken);
644 WMSetLabelTextAlignment(panel->iconView, WACenter);
646 panel->fileLabel = WMCreateLabel(panel->win);
647 WMResizeWidget(panel->fileLabel, 80, 20);
648 WMMoveWidget(panel->fileLabel, 10, 210);
649 WMSetLabelText(panel->fileLabel, _("File Name:"));
651 panel->fileField = WMCreateTextField(panel->win);
652 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
653 WMResizeWidget(panel->fileField, 345, 20);
654 WMMoveWidget(panel->fileField, 95, 210);
655 WMSetTextFieldEditable(panel->fileField, False);
657 panel->okButton = WMCreateCommandButton(panel->win);
658 WMResizeWidget(panel->okButton, 80, 26);
659 WMMoveWidget(panel->okButton, 360, 240);
660 WMSetButtonText(panel->okButton, _("OK"));
661 WMSetButtonEnabled(panel->okButton, False);
662 WMSetButtonAction(panel->okButton, buttonCallback, panel);
664 panel->cancelButton = WMCreateCommandButton(panel->win);
665 WMResizeWidget(panel->cancelButton, 80, 26);
666 WMMoveWidget(panel->cancelButton, 270, 240);
667 WMSetButtonText(panel->cancelButton, _("Cancel"));
668 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
669 #if 0
670 panel->chooseButton = WMCreateCommandButton(panel->win);
671 WMResizeWidget(panel->chooseButton, 110, 26);
672 WMMoveWidget(panel->chooseButton, 150, 240);
673 WMSetButtonText(panel->chooseButton, _("Choose File"));
674 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
675 #endif
676 WMRealizeWidget(panel->win);
677 WMMapSubwidgets(panel->win);
679 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
681 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
684 char *tmp;
686 tmp = wmalloc((instance ? strlen(instance) : 0)
687 + (class ? strlen(class) : 0) + 32);
689 if (tmp && (instance || class))
690 sprintf(tmp, "%s [%s.%s]", _("Icon Chooser"), instance, class);
691 else
692 strcpy(tmp, _("Icon Chooser"));
694 wwin = wManageInternalWindow(scr, parent, None, tmp,
695 (scr->scr_width - 450)/2,
696 (scr->scr_height - 280)/2, 450, 280);
697 wfree(tmp);
700 /* put icon paths in the list */
701 listIconPaths(panel->dirList);
703 WMMapWidget(panel->win);
705 wWindowMap(wwin);
707 while (!panel->done) {
708 XEvent event;
710 WMNextEvent(dpy, &event);
711 WMHandleEvent(&event);
714 if (panel->result) {
715 char *defaultPath, *wantedPath;
717 /* check if the file the user selected is not the one that
718 * would be loaded by default with the current search path */
719 *file = WMGetListSelectedItem(panel->iconList)->text;
720 if ((*file)[0]==0) {
721 wfree(*file);
722 *file = NULL;
723 } else {
724 defaultPath = FindImage(wPreferences.icon_path, *file);
725 wantedPath = WMGetTextFieldText(panel->fileField);
726 /* if the file is not the default, use full path */
727 if (strcmp(wantedPath, defaultPath)!=0) {
728 *file = wantedPath;
729 } else {
730 *file = wstrdup(*file);
731 wfree(wantedPath);
733 wfree(defaultPath);
735 } else {
736 *file = NULL;
739 WMReleaseFont(panel->normalfont);
741 WMUnmapWidget(panel->win);
743 WMDestroyWidget(panel->win);
745 wUnmanageWindow(wwin, False, False);
747 wfree(panel);
749 XDestroyWindow(dpy, parent);
751 return panel->result;
756 ***********************************************************************
757 * Info Panel
758 ***********************************************************************
762 typedef struct {
763 WScreen *scr;
765 WWindow *wwin;
767 WMWindow *win;
769 WMLabel *logoL;
770 WMLabel *name1L;
771 WMLabel *name2L;
773 WMLabel *versionL;
775 WMLabel *infoL;
777 WMLabel *copyrL;
779 #ifdef SILLYNESS
780 WMHandlerID timer;
781 int cycle;
782 RImage *icon;
783 RImage *pic;
784 WMPixmap *oldPix;
785 char *str;
786 int x;
787 #endif
788 } InfoPanel;
792 #define COPYRIGHT_TEXT \
793 "Copyright \xa9 1997~2001 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
794 "Copyright \xa9 1998~2001 Dan Pascu <dan@windowmaker.org>"
798 static InfoPanel *thePanel = NULL;
800 static void
801 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
803 #ifdef SILLYNESS
804 if (thePanel->timer) {
805 WMDeleteTimerHandler(thePanel->timer);
807 if (thePanel->oldPix) {
808 WMReleasePixmap(thePanel->oldPix);
810 if (thePanel->icon) {
811 RDestroyImage(thePanel->icon);
813 if (thePanel->pic) {
814 RDestroyImage(thePanel->pic);
816 #endif /* SILLYNESS */
817 WMUnmapWidget(thePanel);
819 wUnmanageWindow(thePanel->wwin, False, False);
821 WMDestroyWidget(thePanel->win);
823 wfree(thePanel);
825 thePanel = NULL;
829 WMPixmap*
830 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
832 WMPixmap *wpix = NULL;
833 Pixmap grad = None;
834 Pixmap mask = None;
835 RContext *rc = WMScreenRContext(scr);
836 XFontStruct *f = NULL;
837 int w, h;
838 GC gc = None;
840 f = XLoadQueryFont(dpy, font);
841 if (!f)
842 return NULL;
844 w = XTextWidth(f, text, strlen(text));
845 h = f->ascent+f->descent;
847 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
848 gc = XCreateGC(dpy, mask, 0, NULL);
849 XSetForeground(dpy, gc, 0);
850 XSetFont(dpy, gc, f->fid);
851 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
853 XSetForeground(dpy, gc, 1);
854 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
855 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
856 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
858 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
860 WMColor *color;
862 color = WMBlackColor(scr);
863 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
864 WMReleaseColor(color);
867 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
869 if (gc)
870 XFreeGC(dpy, gc);
871 XFreeFont(dpy, f);
873 return wpix;
876 #ifdef SILLYNESS
878 extern WMPixmap *DoXThing();
879 extern Bool InitXThing();
881 static void
882 logoPushCallback(void *data)
884 InfoPanel *panel = (InfoPanel*)data;
885 char buffer[512];
886 int i;
887 int len;
888 static int jingobeu[] = {
889 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
890 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
891 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
893 static int c = 0;
895 if (panel->x) {
896 XKeyboardControl kc;
898 if (panel->x > 0) {
899 if(jingobeu[panel->x-1]==0){panel->x=-1;}else if(jingobeu[panel->x
900 -1]<0){panel->x++;c=jingobeu[panel->x-1]/50;panel->x++;}else if(c==0){
901 kc.bell_pitch=jingobeu[panel->x-1];panel->x++;kc.bell_percent=50;c=
902 jingobeu[panel->x-1]/50;kc.bell_duration=jingobeu[panel->x-1];panel->x++;
903 XChangeKeyboardControl(dpy,KBBellPitch|KBBellDuration|KBBellPercent,&kc);
904 XBell(dpy,50);XFlush(dpy);}else{c--;}}
905 if (!(panel->cycle % 4)) {
906 WMPixmap *p;
908 p = DoXThing(panel->wwin);
909 WMSetLabelImage(panel->logoL, p);
911 } else if (panel->cycle < 30) {
912 RImage *image;
913 WMPixmap *pix;
915 image = RCloneImage(panel->icon);
916 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
917 pix = WMCreatePixmapFromRImage(panel->scr->wmscreen, image, 128);
918 RDestroyImage(image);
919 WMSetLabelImage(panel->logoL, pix);
920 WMReleasePixmap(pix);
923 i = panel->cycle%200;
925 len = strlen(panel->str);
927 strncpy(buffer, panel->str, i<len ? i : len);
928 if (i >= len)
929 memset(&buffer[len], ' ', i-len);
931 strncpy(buffer, panel->str, i<len ? i : len);
932 if (i >= len)
933 memset(&buffer[len], ' ', i-len);
934 buffer[i]=0;
935 WMSetLabelText(panel->versionL, buffer);
937 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
938 panel->cycle++;
942 static void
943 handleLogoPush(XEvent *event, void *data)
945 InfoPanel *panel = (InfoPanel*)data;
946 static int broken = 0;
947 static int clicks = 0;
948 static char *pic_data[] = {
949 "45 45 57 1",
950 " c None",
951 ". c #000000",
952 "X c #383C00",
953 "o c #515500",
954 "O c #616100",
955 "+ c #616900",
956 "@ c #696D00",
957 "# c #697100",
958 "$ c #495100",
959 "% c #202800",
960 "& c #969600",
961 "* c #CFCF00",
962 "= c #D7DB00",
963 "- c #D7D700",
964 "; c #C7CB00",
965 ": c #A6AA00",
966 "> c #494900",
967 ", c #8E8E00",
968 "< c #DFE700",
969 "1 c #F7FF00",
970 "2 c #FFFF00",
971 "3 c #E7EB00",
972 "4 c #B6B600",
973 "5 c #595900",
974 "6 c #717500",
975 "7 c #AEB200",
976 "8 c #CFD300",
977 "9 c #E7EF00",
978 "0 c #EFF300",
979 "q c #9EA200",
980 "w c #F7FB00",
981 "e c #F7F700",
982 "r c #BEBE00",
983 "t c #8E9200",
984 "y c #EFF700",
985 "u c #969A00",
986 "i c #414500",
987 "p c #595D00",
988 "a c #E7E700",
989 "s c #C7C700",
990 "d c #797D00",
991 "f c #BEC300",
992 "g c #DFE300",
993 "h c #868600",
994 "j c #EFEF00",
995 "k c #9E9E00",
996 "l c #616500",
997 "z c #DFDF00",
998 "x c #868A00",
999 "c c #969200",
1000 "v c #B6BA00",
1001 "b c #A6A600",
1002 "n c #8E8A00",
1003 "m c #717100",
1004 "M c #AEAE00",
1005 "N c #AEAA00",
1006 "B c #868200",
1007 " ............... ",
1008 " ....XoO+@##+O$%.... ",
1009 " ...%X&*========-;;:o... ",
1010 " ...>.>,<122222222222134@... ",
1011 " ..>5678912222222222222220q%.. ",
1012 " ..$.&-w2222222222222222222er>.. ",
1013 " ..O.t31222222222222222222222y4>.. ",
1014 " ...O5u3222222222222222222222222yri... ",
1015 " ..>p&a22222222222222222222222222wso.. ",
1016 " ..ids91222222222222222222222222222wfi.. ",
1017 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1018 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1019 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1020 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1021 "..io*222222222&...u22222222yt..%*22222220:%. ",
1022 "..>k02222222227...f222222222v..X=222222229t. ",
1023 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1024 ".%vw222222222221y2222222222219*y2222222222wd.",
1025 ".X;2222222222222222222222222222222222222222b.",
1026 ".i*2222222222222222222222222222222222222222v.",
1027 ".i*2222222222222222222222222222222222222222;.",
1028 ".i*22222222222222222222222222222222222222228.",
1029 ".>*2222222222222222222222222222222222222222=.",
1030 ".i*22222222222222222222222222222222222222228.",
1031 ".i*2222222222222222222222222222222222222222;.",
1032 ".X*222222222222222222222222222222we12222222r.",
1033 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1034 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1035 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1036 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1037 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1038 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1039 " ...:e2222218mdz22222222222222a&$vw222220@...",
1040 " ...O-122222y:.u02222222222229q$uj222221r... ",
1041 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1042 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1043 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1044 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1045 " ..Xb9122222109g-****;<y22221zn%... ",
1046 " ..X&801222222222222222222w-h.... ",
1047 " ...o:=022222222222222221=lX... ",
1048 " ..X@:;3w2222222222210fO... ",
1049 " ...XX&v8<30000003-N@... ",
1050 " .....XmnbN:q&Bo.... ",
1051 " ............ "};
1052 static char *msgs[] = {
1053 "Have a nice day!",
1054 "Focus follow mouse users will burn in hell!!!",
1055 "F'ck Canada!!!!",
1056 "F'ck Bastard Imperialists!!!",
1057 "Hi! My name is bobby...",
1058 "AHH! The neurotic monkeys are after me!"
1062 clicks++;
1064 if (!panel->timer && !broken && clicks > 0) {
1065 char *file;
1066 char *path;
1068 panel->x = 0;
1069 clicks = 0;
1070 if (!panel->icon) {
1071 file = wDefaultGetIconFile(panel->scr, "Logo", "WMPanel", False);
1072 if (!file) {
1073 broken = 1;
1074 return;
1077 path = FindImage(wPreferences.icon_path, file);
1078 if (!path) {
1079 broken = 1;
1080 return;
1083 panel->icon = RLoadImage(panel->scr->rcontext, path, 0);
1084 wfree(path);
1085 if (!panel->icon) {
1086 broken = 1;
1087 return;
1090 if (!panel->pic) {
1091 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1092 if (!panel->pic || panel->icon->width!=panel->pic->width
1093 || panel->icon->height!=panel->pic->height) {
1094 broken = 1;
1095 RDestroyImage(panel->icon);
1096 panel->icon = NULL;
1097 if (panel->pic) {
1098 RDestroyImage(panel->pic);
1099 panel->pic = NULL;
1101 return;
1105 RColor color;
1106 color.red = 0xae;
1107 color.green = 0xaa;
1108 color.blue = 0xae;
1109 color.alpha = 255;
1110 RCombineImageWithColor(panel->icon, &color);
1111 RCombineImageWithColor(panel->pic, &color);
1115 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1117 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1118 panel->cycle = 0;
1119 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1120 } else if (panel->timer) {
1121 char version[20];
1123 panel->x = 0;
1124 clicks = 0;
1125 WMSetLabelImage(panel->logoL, panel->oldPix);
1126 WMReleasePixmap(panel->oldPix);
1127 panel->oldPix = NULL;
1129 WMDeleteTimerHandler(panel->timer);
1130 panel->timer = NULL;
1132 sprintf(version, _("Version %s"), VERSION);
1133 WMSetLabelText(panel->versionL, version);
1137 XEvent ev;
1138 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1139 ButtonPress, &ev));
1142 #endif /* SILLYNESS */
1145 void
1146 wShowInfoPanel(WScreen *scr)
1148 InfoPanel *panel;
1149 WMPixmap *logo;
1150 WMSize size;
1151 WMFont *font;
1152 char version[32];
1153 char buffer[512];
1154 Window parent;
1155 WWindow *wwin;
1156 RColor color1, color2;
1157 char **strl;
1158 int i;
1159 char *visuals[] = {
1160 "StaticGray",
1161 "GrayScale",
1162 "StaticColor",
1163 "PseudoColor",
1164 "TrueColor",
1165 "DirectColor"
1169 if (thePanel) {
1170 if (thePanel->scr == scr) {
1171 wRaiseFrame(thePanel->wwin->frame->core);
1172 wSetFocusTo(scr, thePanel->wwin);
1174 return;
1177 panel = wmalloc(sizeof(InfoPanel));
1178 memset(panel, 0, sizeof(InfoPanel));
1180 panel->scr = scr;
1182 panel->win = WMCreateWindow(scr->wmscreen, "info");
1183 WMResizeWidget(panel->win, 382, 230);
1185 logo = WMGetApplicationIconImage(scr->wmscreen);
1186 if (logo) {
1187 size = WMGetPixmapSize(logo);
1188 panel->logoL = WMCreateLabel(panel->win);
1189 WMResizeWidget(panel->logoL, 64, 64);
1190 WMMoveWidget(panel->logoL, 30, 20);
1191 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1192 WMSetLabelImage(panel->logoL, logo);
1193 #ifdef SILLYNESS
1194 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1195 handleLogoPush, panel);
1196 #endif
1199 panel->name1L = WMCreateLabel(panel->win);
1200 WMResizeWidget(panel->name1L, 240, 30);
1201 WMMoveWidget(panel->name1L, 100, 30);
1202 color1.red = 0;
1203 color1.green = 0;
1204 color1.blue = 0;
1205 color2.red = 0x50;
1206 color2.green = 0x50;
1207 color2.blue = 0x70;
1208 logo = renderText(scr->wmscreen, "GNU Window Maker",
1209 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1210 if (logo) {
1211 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1212 WMSetLabelImage(panel->name1L, logo);
1213 WMReleasePixmap(logo);
1214 } else {
1215 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1216 if (font) {
1217 WMSetLabelFont(panel->name1L, font);
1218 WMReleaseFont(font);
1220 WMSetLabelTextAlignment(panel->name1L, WACenter);
1221 WMSetLabelText(panel->name1L, "GNU Window Maker");
1224 panel->name2L = WMCreateLabel(panel->win);
1225 WMResizeWidget(panel->name2L, 240, 24);
1226 WMMoveWidget(panel->name2L, 100, 60);
1227 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1228 if (font) {
1229 WMSetLabelFont(panel->name2L, font);
1230 WMReleaseFont(font);
1231 font = NULL;
1233 WMSetLabelTextAlignment(panel->name2L, WACenter);
1234 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1237 sprintf(version, _("Version %s"), VERSION);
1238 panel->versionL = WMCreateLabel(panel->win);
1239 WMResizeWidget(panel->versionL, 310, 16);
1240 WMMoveWidget(panel->versionL, 30, 95);
1241 WMSetLabelTextAlignment(panel->versionL, WARight);
1242 WMSetLabelText(panel->versionL, version);
1243 WMSetLabelWraps(panel->versionL, False);
1245 panel->copyrL = WMCreateLabel(panel->win);
1246 WMResizeWidget(panel->copyrL, 340, 40);
1247 WMMoveWidget(panel->copyrL, 15, 185);
1248 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1249 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1250 /* we want the (c) character in the helvetica font */
1251 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1252 if (font) {
1253 WMSetLabelFont(panel->copyrL, font);
1256 switch (scr->w_depth) {
1257 case 15:
1258 strcpy(version, _("32 thousand"));
1259 break;
1260 case 16:
1261 strcpy(version, _("64 thousand"));
1262 break;
1263 case 24:
1264 case 32:
1265 strcpy(version, _("16 million"));
1266 break;
1267 default:
1268 sprintf(version, "%d", 1<<scr->w_depth);
1269 break;
1272 sprintf(buffer, _("Using visual 0x%x: %s %ibpp (%s colors)\n"),
1273 (unsigned)scr->w_visual->visualid,
1274 visuals[scr->w_visual->class], scr->w_depth, version);
1276 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1278 struct mallinfo ma = mallinfo();
1279 sprintf(buffer+strlen(buffer),
1280 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1281 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1284 #endif
1286 strcat(buffer, _("Supported image formats: "));
1287 strl = RSupportedFileFormats();
1288 for (i=0; strl[i]!=NULL; i++) {
1289 strcat(buffer, strl[i]);
1290 strcat(buffer, " ");
1293 strcat(buffer, _("\nAdditional Support For: "));
1295 char *list[8];
1296 char buf[80];
1297 int j = 0;
1299 #ifdef MWM_HINTS
1300 list[j++] = "MWM";
1301 #endif
1302 #ifdef KWM_HINTS
1303 list[j++] = "KDE";
1304 #endif
1305 #ifdef GNOME_STUFF
1306 list[j++] = "GNOME";
1307 #endif
1308 #ifdef OLWM_HINTS
1309 list[j++] = "OLWM";
1310 #endif
1311 #ifdef WSOUND
1312 list[j++] = _("Sound");
1313 #endif
1315 buf[0] = 0;
1316 for (i = 0; i < j; i++) {
1317 if (i > 0) {
1318 if (i == j - 1)
1319 strcat(buf, _(" and "));
1320 else
1321 strcat(buf, ", ");
1323 strcat(buf, list[i]);
1325 strcat(buffer, buf);
1329 panel->infoL = WMCreateLabel(panel->win);
1330 WMResizeWidget(panel->infoL, 350, 75);
1331 WMMoveWidget(panel->infoL, 15, 115);
1332 WMSetLabelText(panel->infoL, buffer);
1333 if (font) {
1334 WMSetLabelFont(panel->infoL, font);
1335 WMReleaseFont(font);
1339 WMRealizeWidget(panel->win);
1340 WMMapSubwidgets(panel->win);
1342 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1344 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1346 WMMapWidget(panel->win);
1348 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1349 (scr->scr_width - 382)/2,
1350 (scr->scr_height - 230)/2, 382, 230);
1352 WSETUFLAG(wwin, no_closable, 0);
1353 WSETUFLAG(wwin, no_close_button, 0);
1354 #ifdef XKB_BUTTON_HINT
1355 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1356 #endif
1357 wWindowUpdateButtonImages(wwin);
1358 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1359 wwin->frame->on_click_right = destroyInfoPanel;
1361 wWindowMap(wwin);
1363 panel->wwin = wwin;
1365 thePanel = panel;
1366 #ifdef SILLYNESS
1367 if (InitXThing(panel->scr)) {
1368 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1369 panel->cycle = 0;
1370 panel->x = 1;
1371 panel->str = _("Merry X'mas!");
1372 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1374 #endif
1379 ***********************************************************************
1380 * Legal Panel
1381 ***********************************************************************
1384 typedef struct {
1385 WScreen *scr;
1387 WWindow *wwin;
1389 WMWindow *win;
1391 WMLabel *licenseL;
1392 } LegalPanel;
1395 static LegalPanel *legalPanel = NULL;
1397 static void
1398 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1400 WMUnmapWidget(legalPanel->win);
1402 WMDestroyWidget(legalPanel->win);
1404 wUnmanageWindow(legalPanel->wwin, False, False);
1406 wfree(legalPanel);
1408 legalPanel = NULL;
1412 void
1413 wShowLegalPanel(WScreen *scr)
1415 LegalPanel *panel;
1416 Window parent;
1417 WWindow *wwin;
1419 if (legalPanel) {
1420 if (legalPanel->scr == scr) {
1421 wRaiseFrame(legalPanel->wwin->frame->core);
1422 wSetFocusTo(scr, legalPanel->wwin);
1424 return;
1427 panel = wmalloc(sizeof(LegalPanel));
1429 panel->scr = scr;
1431 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1432 WMResizeWidget(panel->win, 420, 250);
1435 panel->licenseL = WMCreateLabel(panel->win);
1436 WMSetLabelWraps(panel->licenseL, True);
1437 WMResizeWidget(panel->licenseL, 400, 230);
1438 WMMoveWidget(panel->licenseL, 10, 10);
1439 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1440 WMSetLabelText(panel->licenseL,
1441 _(" Window Maker is free software; you can redistribute it and/or\n"
1442 "modify it under the terms of the GNU General Public License as\n"
1443 "published by the Free Software Foundation; either version 2 of the\n"
1444 "License, or (at your option) any later version.\n\n\n"
1445 " Window Maker is distributed in the hope that it will be useful,\n"
1446 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1447 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1448 "See the GNU General Public License for more details.\n\n\n"
1449 " You should have received a copy of the GNU General Public\n"
1450 "License along with this program; if not, write to the Free Software\n"
1451 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1452 "02111-1307, USA."));
1453 WMSetLabelRelief(panel->licenseL, WRGroove);
1455 WMRealizeWidget(panel->win);
1456 WMMapSubwidgets(panel->win);
1458 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1460 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1462 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1463 (scr->scr_width - 420)/2,
1464 (scr->scr_height - 250)/2, 420, 250);
1466 WSETUFLAG(wwin, no_closable, 0);
1467 WSETUFLAG(wwin, no_close_button, 0);
1468 wWindowUpdateButtonImages(wwin);
1469 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1470 #ifdef XKB_BUTTON_HINT
1471 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1472 #endif
1473 wwin->frame->on_click_right = destroyLegalPanel;
1475 panel->wwin = wwin;
1477 WMMapWidget(panel->win);
1479 wWindowMap(wwin);
1481 legalPanel = panel;
1486 ***********************************************************************
1487 * Crashing Dialog Panel
1488 ***********************************************************************
1491 extern WDDomain *WDWindowAttributes;
1494 typedef struct _CrashPanel {
1495 WMWindow *win; /* main window */
1497 WMLabel *iconL; /* application icon */
1498 WMLabel *nameL; /* title of panel */
1500 WMFrame *sepF; /* separator frame */
1502 WMLabel *noteL; /* Title of note */
1503 WMLabel *note2L; /* body of note with what happened */
1505 WMFrame *whatF; /* "what to do next" frame */
1506 WMPopUpButton *whatP; /* action selection popup button */
1508 WMButton *okB; /* ok button */
1510 Bool done; /* if finished with this dialog */
1511 int action; /* what to do after */
1513 KeyCode retKey;
1515 } CrashPanel;
1518 static void
1519 handleKeyPress(XEvent *event, void *clientData)
1521 CrashPanel *panel = (CrashPanel*)clientData;
1523 if (event->xkey.keycode == panel->retKey) {
1524 WMPerformButtonClick(panel->okB);
1529 static void
1530 okButtonCallback(void *self, void *clientData)
1532 CrashPanel *panel = (CrashPanel*)clientData;
1534 panel->done = True;
1538 static void
1539 setCrashAction(void *self, void *clientData)
1541 WMPopUpButton *pop = (WMPopUpButton*)self;
1542 CrashPanel *panel = (CrashPanel*)clientData;
1544 panel->action = WMGetPopUpButtonSelectedItem(pop);
1548 static WMPixmap*
1549 getWindowMakerIconImage(WMScreen *scr)
1551 proplist_t dict, key, option, value=NULL;
1552 WMPixmap *pix=NULL;
1553 char *path;
1555 PLSetStringCmpHook(NULL);
1557 key = PLMakeString("Logo.WMPanel");
1558 option = PLMakeString("Icon");
1560 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
1562 if (dict) {
1563 value = PLGetDictionaryEntry(dict, option);
1566 PLRelease(key);
1567 PLRelease(option);
1569 PLSetStringCmpHook(StringCompareHook);
1571 if (value && PLIsString(value)) {
1572 path = FindImage(wPreferences.icon_path, PLGetString(value));
1574 if (path) {
1575 RImage *image;
1577 image = RLoadImage(WMScreenRContext(scr), path, 0);
1578 if (image) {
1579 pix = WMCreatePixmapFromRImage(scr, image, 0);
1580 RDestroyImage(image);
1582 wfree(path);
1586 return pix;
1590 #define PWIDTH 295
1591 #define PHEIGHT 345
1595 wShowCrashingDialogPanel(int whatSig)
1597 CrashPanel *panel;
1598 WMScreen *scr;
1599 WMFont *font;
1600 WMPixmap *logo;
1601 int screen_no, scr_width, scr_height;
1602 int action;
1603 char buf[256];
1605 panel = wmalloc(sizeof(CrashPanel));
1606 memset(panel, 0, sizeof(CrashPanel));
1608 screen_no = DefaultScreen(dpy);
1609 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1610 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1612 scr = WMCreateScreen(dpy, screen_no);
1613 if (!scr) {
1614 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1615 return WMAbort;
1618 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1620 panel->win = WMCreateWindow(scr, "crashingDialog");
1621 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1622 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1624 logo = getWindowMakerIconImage(scr);
1625 if (logo) {
1626 panel->iconL = WMCreateLabel(panel->win);
1627 WMResizeWidget(panel->iconL, 64, 64);
1628 WMMoveWidget(panel->iconL, 10, 10);
1629 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1630 WMSetLabelImage(panel->iconL, logo);
1633 panel->nameL = WMCreateLabel(panel->win);
1634 WMResizeWidget(panel->nameL, 190, 18);
1635 WMMoveWidget(panel->nameL, 80, 35);
1636 WMSetLabelTextAlignment(panel->nameL, WALeft);
1637 font = WMBoldSystemFontOfSize(scr, 18);
1638 WMSetLabelFont(panel->nameL, font);
1639 WMReleaseFont(font);
1640 WMSetLabelText(panel->nameL, _("Fatal error"));
1642 panel->sepF = WMCreateFrame(panel->win);
1643 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1644 WMMoveWidget(panel->sepF, -2, 80);
1646 panel->noteL = WMCreateLabel(panel->win);
1647 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1648 WMMoveWidget(panel->noteL, 10, 90);
1649 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1650 #ifdef SYS_SIGLIST_DECLARED
1651 sprintf(buf, _("Window Maker received signal %i\n(%s)."),
1652 whatSig, sys_siglist[whatSig]);
1653 #else
1654 sprintf(buf, _("Window Maker received signal %i."), whatSig);
1655 #endif
1656 WMSetLabelText(panel->noteL, buf);
1658 panel->note2L = WMCreateLabel(panel->win);
1659 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1660 WMMoveWidget(panel->note2L, 10, 130);
1661 WMSetLabelTextAlignment(panel->note2L, WALeft);
1662 WMSetLabelText(panel->note2L,
1663 _(" This fatal error occured probably due to a bug."
1664 " Please fill the included BUGFORM and "
1665 "report it to bugs@windowmaker.org."));
1668 panel->whatF = WMCreateFrame(panel->win);
1669 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1670 WMMoveWidget(panel->whatF, 10, 240);
1671 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1673 panel->whatP = WMCreatePopUpButton(panel->whatF);
1674 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1675 WMMoveWidget(panel->whatP, 35, 20);
1676 WMSetPopUpButtonPullsDown(panel->whatP, False);
1677 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1678 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1679 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1680 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1681 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1682 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1683 panel->action = WMRestart;
1685 WMMapSubwidgets(panel->whatF);
1687 panel->okB = WMCreateCommandButton(panel->win);
1688 WMResizeWidget(panel->okB, 80, 26);
1689 WMMoveWidget(panel->okB, 205, 309);
1690 WMSetButtonText(panel->okB, _("OK"));
1691 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1692 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1693 WMSetButtonImagePosition(panel->okB, WIPRight);
1694 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1696 panel->done = 0;
1698 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1699 handleKeyPress, panel);
1701 WMRealizeWidget(panel->win);
1702 WMMapSubwidgets(panel->win);
1704 WMMapWidget(panel->win);
1706 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1708 while (!panel->done) {
1709 XEvent event;
1711 WMNextEvent(dpy, &event);
1712 WMHandleEvent(&event);
1715 action = panel->action;
1717 WMUnmapWidget(panel->win);
1718 WMDestroyWidget(panel->win);
1719 wfree(panel);
1721 return action;
1727 /*****************************************************************************
1728 * About GNUstep Panel
1729 *****************************************************************************/
1732 static void
1733 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1734 unsigned long blackPixel, unsigned long whitePixel)
1736 GC gc;
1737 XGCValues gcv;
1738 XRectangle rects[3];
1740 gcv.foreground = blackPixel;
1741 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1743 XFillArc(dpy, d, gc, width/45, height/45,
1744 width - 2*width/45, height - 2*height/45, 0, 360*64);
1746 rects[0].x = 0;
1747 rects[0].y = 37*height/45;
1748 rects[0].width = width/3;
1749 rects[0].height = height - rects[0].y;
1751 rects[1].x = rects[0].width;
1752 rects[1].y = height/2;
1753 rects[1].width = width - 2*width/3;
1754 rects[1].height = height - rects[1].y;
1756 rects[2].x = 2*width/3;
1757 rects[2].y = height - 37*height/45;
1758 rects[2].width = width/3;
1759 rects[2].height = height - rects[2].y;
1761 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1762 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1764 XSetForeground(dpy, gc, whitePixel);
1765 XFillArc(dpy, d, gc, width/45, height/45,
1766 width - 2*width/45, height - 2*height/45, 0, 360*64);
1768 XFreeGC(dpy, gc);
1772 typedef struct {
1773 WScreen *scr;
1775 WWindow *wwin;
1777 WMWindow *win;
1779 WMLabel *gstepL;
1780 WMLabel *textL;
1781 } GNUstepPanel;
1784 static GNUstepPanel *gnustepPanel = NULL;
1786 static void
1787 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1789 WMUnmapWidget(gnustepPanel->win);
1791 WMDestroyWidget(gnustepPanel->win);
1793 wUnmanageWindow(gnustepPanel->wwin, False, False);
1795 wfree(gnustepPanel);
1797 gnustepPanel = NULL;
1801 void
1802 wShowGNUstepPanel(WScreen *scr)
1804 GNUstepPanel *panel;
1805 Window parent;
1806 WWindow *wwin;
1807 WMPixmap *pixmap;
1808 WMColor *color;
1810 if (gnustepPanel) {
1811 if (gnustepPanel->scr == scr) {
1812 wRaiseFrame(gnustepPanel->wwin->frame->core);
1813 wSetFocusTo(scr, gnustepPanel->wwin);
1815 return;
1818 panel = wmalloc(sizeof(GNUstepPanel));
1820 panel->scr = scr;
1822 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1823 WMResizeWidget(panel->win, 325, 200);
1825 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1826 WMScreenDepth(scr->wmscreen), True);
1828 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1830 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1831 WMColorPixel(color), scr->white_pixel);
1833 WMReleaseColor(color);
1835 XSetForeground(dpy, scr->mono_gc, 0);
1836 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1837 130, 130);
1838 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1840 panel->gstepL = WMCreateLabel(panel->win);
1841 WMResizeWidget(panel->gstepL, 285, 64);
1842 WMMoveWidget(panel->gstepL, 20, 0);
1843 WMSetLabelTextAlignment(panel->gstepL, WARight);
1844 WMSetLabelText(panel->gstepL, "GNUstep");
1846 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1848 WMSetLabelFont(panel->gstepL, font);
1849 WMReleaseFont(font);
1852 panel->textL = WMCreateLabel(panel->win);
1853 WMResizeWidget(panel->textL, 275, 130);
1854 WMMoveWidget(panel->textL, 30, 50);
1855 WMSetLabelTextAlignment(panel->textL, WARight);
1856 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1857 WMSetLabelText(panel->textL,
1858 _("Window Maker is part of the GNUstep project.\n"\
1859 "The GNUstep project aims to create a free\n"\
1860 "implementation of the OpenStep(tm) specification\n"\
1861 "which is a object-oriented framework for\n"\
1862 "creating advanced graphical, multi-platform\n"\
1863 "applications. Additionally, a development and\n"\
1864 "user desktop enviroment will be created on top\n"\
1865 "of the framework. For more information about\n"\
1866 "GNUstep, please visit: www.gnustep.org"));
1867 WMSetLabelImage(panel->textL, pixmap);
1869 WMReleasePixmap(pixmap);
1871 WMRealizeWidget(panel->win);
1872 WMMapSubwidgets(panel->win);
1874 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1876 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1878 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1879 (scr->scr_width - 325)/2,
1880 (scr->scr_height - 200)/2, 325, 200);
1882 WSETUFLAG(wwin, no_closable, 0);
1883 WSETUFLAG(wwin, no_close_button, 0);
1884 wWindowUpdateButtonImages(wwin);
1885 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1886 #ifdef XKB_BUTTON_HINT
1887 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1888 #endif
1889 wwin->frame->on_click_right = destroyGNUstepPanel;
1891 panel->wwin = wwin;
1893 WMMapWidget(panel->win);
1895 wWindowMap(wwin);
1897 gnustepPanel = panel;