fixed some signal handling bugs
[wmaker-crm.git] / src / dialog.c
blobc61cbc82f05e81ca6b3b9a0241608c9ff042294d
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 WMFont *oldFont;
786 char *str;
787 int x;
788 #endif
789 } InfoPanel;
793 #define COPYRIGHT_TEXT \
794 "Copyright \xa9 1997~2001 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
795 "Copyright \xa9 1998~2001 Dan Pascu <dan@windowmaker.org>"
799 static InfoPanel *thePanel = NULL;
801 static void
802 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
804 #ifdef SILLYNESS
805 if (thePanel->timer) {
806 WMDeleteTimerHandler(thePanel->timer);
808 if (thePanel->oldPix) {
809 WMReleasePixmap(thePanel->oldPix);
811 if (thePanel->icon) {
812 RDestroyImage(thePanel->icon);
814 if (thePanel->pic) {
815 RDestroyImage(thePanel->pic);
817 #endif /* SILLYNESS */
818 WMUnmapWidget(thePanel);
820 wUnmanageWindow(thePanel->wwin, False, False);
822 WMDestroyWidget(thePanel->win);
824 wfree(thePanel);
826 thePanel = NULL;
830 WMPixmap*
831 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
833 WMPixmap *wpix = NULL;
834 Pixmap grad = None;
835 Pixmap mask = None;
836 RContext *rc = WMScreenRContext(scr);
837 XFontStruct *f = NULL;
838 int w, h;
839 GC gc = None;
841 f = XLoadQueryFont(dpy, font);
842 if (!f)
843 return NULL;
845 w = XTextWidth(f, text, strlen(text));
846 h = f->ascent+f->descent;
848 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
849 gc = XCreateGC(dpy, mask, 0, NULL);
850 XSetForeground(dpy, gc, 0);
851 XSetFont(dpy, gc, f->fid);
852 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
854 XSetForeground(dpy, gc, 1);
855 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
856 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
857 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
859 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
861 WMColor *color;
863 color = WMBlackColor(scr);
864 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
865 WMReleaseColor(color);
868 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
870 if (gc)
871 XFreeGC(dpy, gc);
872 XFreeFont(dpy, f);
874 return wpix;
877 #ifdef SILLYNESS
879 extern WMPixmap *DoXThing();
880 extern Bool InitXThing();
882 static void
883 logoPushCallback(void *data)
885 InfoPanel *panel = (InfoPanel*)data;
886 char buffer[512];
887 int i;
888 static int oldi = 0;
889 int len;
890 static int jingobeu[] = {
891 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
892 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
893 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
895 static int c = 0;
897 if (panel->x) {
898 XKeyboardControl kc;
900 if (panel->x > 0) {
901 if(jingobeu[panel->x-1]==0){panel->x=-1;}else if(jingobeu[panel->x
902 -1]<0){panel->x++;c=jingobeu[panel->x-1]/50;panel->x++;}else if(c==0){
903 kc.bell_pitch=jingobeu[panel->x-1];panel->x++;kc.bell_percent=50;c=
904 jingobeu[panel->x-1]/50;kc.bell_duration=jingobeu[panel->x-1];panel->x++;
905 XChangeKeyboardControl(dpy,KBBellPitch|KBBellDuration|KBBellPercent,&kc);
906 XBell(dpy,50);XFlush(dpy);}else{c--;}}
907 if (!(panel->cycle % 4)) {
908 WMPixmap *p;
910 p = DoXThing(panel->wwin);
911 WMSetLabelImage(panel->logoL, p);
913 } else if (panel->cycle < 30) {
914 RImage *image;
915 WMPixmap *pix;
917 image = RCloneImage(panel->icon);
918 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
919 pix = WMCreatePixmapFromRImage(panel->scr->wmscreen, image, 128);
920 RDestroyImage(image);
921 WMSetLabelImage(panel->logoL, pix);
922 WMReleasePixmap(pix);
925 /* slow down text a little */
926 i = (int)(panel->cycle * 50.0/85.0)%200;
928 if (i != oldi) {
929 len = strlen(panel->str);
931 strncpy(buffer, panel->str, i<len ? i : len);
932 if (i >= len)
933 memset(&buffer[len], ' ', i-len);
935 strncpy(buffer, panel->str, i<len ? i : len);
936 if (i >= len)
937 memset(&buffer[len], ' ', i-len);
938 buffer[i]=0;
940 WMSetLabelText(panel->versionL, buffer);
942 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
944 oldi = i;
947 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
948 panel->cycle++;
952 static void
953 handleLogoPush(XEvent *event, void *data)
955 InfoPanel *panel = (InfoPanel*)data;
956 static int broken = 0;
957 static int clicks = 0;
958 static char *pic_data[] = {
959 "45 45 57 1",
960 " c None",
961 ". c #000000",
962 "X c #383C00",
963 "o c #515500",
964 "O c #616100",
965 "+ c #616900",
966 "@ c #696D00",
967 "# c #697100",
968 "$ c #495100",
969 "% c #202800",
970 "& c #969600",
971 "* c #CFCF00",
972 "= c #D7DB00",
973 "- c #D7D700",
974 "; c #C7CB00",
975 ": c #A6AA00",
976 "> c #494900",
977 ", c #8E8E00",
978 "< c #DFE700",
979 "1 c #F7FF00",
980 "2 c #FFFF00",
981 "3 c #E7EB00",
982 "4 c #B6B600",
983 "5 c #595900",
984 "6 c #717500",
985 "7 c #AEB200",
986 "8 c #CFD300",
987 "9 c #E7EF00",
988 "0 c #EFF300",
989 "q c #9EA200",
990 "w c #F7FB00",
991 "e c #F7F700",
992 "r c #BEBE00",
993 "t c #8E9200",
994 "y c #EFF700",
995 "u c #969A00",
996 "i c #414500",
997 "p c #595D00",
998 "a c #E7E700",
999 "s c #C7C700",
1000 "d c #797D00",
1001 "f c #BEC300",
1002 "g c #DFE300",
1003 "h c #868600",
1004 "j c #EFEF00",
1005 "k c #9E9E00",
1006 "l c #616500",
1007 "z c #DFDF00",
1008 "x c #868A00",
1009 "c c #969200",
1010 "v c #B6BA00",
1011 "b c #A6A600",
1012 "n c #8E8A00",
1013 "m c #717100",
1014 "M c #AEAE00",
1015 "N c #AEAA00",
1016 "B c #868200",
1017 " ............... ",
1018 " ....XoO+@##+O$%.... ",
1019 " ...%X&*========-;;:o... ",
1020 " ...>.>,<122222222222134@... ",
1021 " ..>5678912222222222222220q%.. ",
1022 " ..$.&-w2222222222222222222er>.. ",
1023 " ..O.t31222222222222222222222y4>.. ",
1024 " ...O5u3222222222222222222222222yri... ",
1025 " ..>p&a22222222222222222222222222wso.. ",
1026 " ..ids91222222222222222222222222222wfi.. ",
1027 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1028 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1029 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1030 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1031 "..io*222222222&...u22222222yt..%*22222220:%. ",
1032 "..>k02222222227...f222222222v..X=222222229t. ",
1033 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1034 ".%vw222222222221y2222222222219*y2222222222wd.",
1035 ".X;2222222222222222222222222222222222222222b.",
1036 ".i*2222222222222222222222222222222222222222v.",
1037 ".i*2222222222222222222222222222222222222222;.",
1038 ".i*22222222222222222222222222222222222222228.",
1039 ".>*2222222222222222222222222222222222222222=.",
1040 ".i*22222222222222222222222222222222222222228.",
1041 ".i*2222222222222222222222222222222222222222;.",
1042 ".X*222222222222222222222222222222we12222222r.",
1043 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1044 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1045 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1046 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1047 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1048 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1049 " ...:e2222218mdz22222222222222a&$vw222220@...",
1050 " ...O-122222y:.u02222222222229q$uj222221r... ",
1051 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1052 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1053 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1054 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1055 " ..Xb9122222109g-****;<y22221zn%... ",
1056 " ..X&801222222222222222222w-h.... ",
1057 " ...o:=022222222222222221=lX... ",
1058 " ..X@:;3w2222222222210fO... ",
1059 " ...XX&v8<30000003-N@... ",
1060 " .....XmnbN:q&Bo.... ",
1061 " ............ "};
1062 static char *msgs[] = {
1063 "Have a nice day!",
1064 "Focus follow mouse users will burn in hell!!!",
1065 "Mooo Canada!!!!",
1066 "Hi! My name is bobby...",
1067 "AHH! The neurotic monkeys are after me!",
1068 "WHAT YOU SAY??",
1069 "WE GET SIGNAL",
1070 "SOMEBODY SET UP US THE BOMB",
1071 "ALL YOUR BASE ARE BELONG TO US!"
1076 clicks++;
1078 if (!panel->timer && !broken && clicks > 0) {
1079 WMFont *font;
1080 char *file;
1081 char *path;
1083 panel->x = 0;
1084 clicks = 0;
1085 if (!panel->icon) {
1086 file = wDefaultGetIconFile(panel->scr, "Logo", "WMPanel", False);
1087 if (!file) {
1088 broken = 1;
1089 return;
1092 path = FindImage(wPreferences.icon_path, file);
1093 if (!path) {
1094 broken = 1;
1095 return;
1098 panel->icon = RLoadImage(panel->scr->rcontext, path, 0);
1099 wfree(path);
1100 if (!panel->icon) {
1101 broken = 1;
1102 return;
1105 if (!panel->pic) {
1106 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1107 if (!panel->pic || panel->icon->width!=panel->pic->width
1108 || panel->icon->height!=panel->pic->height) {
1109 broken = 1;
1110 RDestroyImage(panel->icon);
1111 panel->icon = NULL;
1112 if (panel->pic) {
1113 RDestroyImage(panel->pic);
1114 panel->pic = NULL;
1116 return;
1120 RColor color;
1121 color.red = 0xae;
1122 color.green = 0xaa;
1123 color.blue = 0xae;
1124 color.alpha = 255;
1125 RCombineImageWithColor(panel->icon, &color);
1126 RCombineImageWithColor(panel->pic, &color);
1130 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1132 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1133 panel->cycle = 0;
1134 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1135 /* If we don't use a fixed font, scrolling will be jumpy */
1136 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1137 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1138 WMRetainFont(panel->oldFont);
1139 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1140 if (font) {
1141 WMSetLabelFont(panel->versionL, font);
1142 WMReleaseFont(font);
1144 WMSetLabelText(panel->versionL, "");
1145 } else if (panel->timer) {
1146 char version[20];
1148 panel->x = 0;
1149 clicks = 0;
1150 WMSetLabelImage(panel->logoL, panel->oldPix);
1151 WMReleasePixmap(panel->oldPix);
1152 panel->oldPix = NULL;
1154 WMDeleteTimerHandler(panel->timer);
1155 panel->timer = NULL;
1157 WMSetLabelFont(panel->versionL, panel->oldFont);
1158 if (panel->oldFont) {
1159 WMReleaseFont(panel->oldFont);
1160 panel->oldFont = NULL;
1162 sprintf(version, _("Version %s"), VERSION);
1163 WMSetLabelText(panel->versionL, version);
1164 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1168 XEvent ev;
1169 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1170 ButtonPress, &ev));
1173 #endif /* SILLYNESS */
1176 void
1177 wShowInfoPanel(WScreen *scr)
1179 InfoPanel *panel;
1180 WMPixmap *logo;
1181 WMSize size;
1182 WMFont *font;
1183 char version[32];
1184 char buffer[512];
1185 Window parent;
1186 WWindow *wwin;
1187 RColor color1, color2;
1188 char **strl;
1189 int i;
1190 char *visuals[] = {
1191 "StaticGray",
1192 "GrayScale",
1193 "StaticColor",
1194 "PseudoColor",
1195 "TrueColor",
1196 "DirectColor"
1200 if (thePanel) {
1201 if (thePanel->scr == scr) {
1202 wRaiseFrame(thePanel->wwin->frame->core);
1203 wSetFocusTo(scr, thePanel->wwin);
1205 return;
1208 panel = wmalloc(sizeof(InfoPanel));
1209 memset(panel, 0, sizeof(InfoPanel));
1211 panel->scr = scr;
1213 panel->win = WMCreateWindow(scr->wmscreen, "info");
1214 WMResizeWidget(panel->win, 382, 230);
1216 logo = WMGetApplicationIconImage(scr->wmscreen);
1217 if (logo) {
1218 size = WMGetPixmapSize(logo);
1219 panel->logoL = WMCreateLabel(panel->win);
1220 WMResizeWidget(panel->logoL, 64, 64);
1221 WMMoveWidget(panel->logoL, 30, 20);
1222 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1223 WMSetLabelImage(panel->logoL, logo);
1224 #ifdef SILLYNESS
1225 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1226 handleLogoPush, panel);
1227 #endif
1230 panel->name1L = WMCreateLabel(panel->win);
1231 WMResizeWidget(panel->name1L, 240, 30);
1232 WMMoveWidget(panel->name1L, 100, 30);
1233 color1.red = 0;
1234 color1.green = 0;
1235 color1.blue = 0;
1236 color2.red = 0x50;
1237 color2.green = 0x50;
1238 color2.blue = 0x70;
1239 logo = renderText(scr->wmscreen, "GNU Window Maker",
1240 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1241 if (logo) {
1242 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1243 WMSetLabelImage(panel->name1L, logo);
1244 WMReleasePixmap(logo);
1245 } else {
1246 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1247 if (font) {
1248 WMSetLabelFont(panel->name1L, font);
1249 WMReleaseFont(font);
1251 WMSetLabelTextAlignment(panel->name1L, WACenter);
1252 WMSetLabelText(panel->name1L, "GNU Window Maker");
1255 panel->name2L = WMCreateLabel(panel->win);
1256 WMResizeWidget(panel->name2L, 240, 24);
1257 WMMoveWidget(panel->name2L, 100, 60);
1258 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1259 if (font) {
1260 WMSetLabelFont(panel->name2L, font);
1261 WMReleaseFont(font);
1262 font = NULL;
1264 WMSetLabelTextAlignment(panel->name2L, WACenter);
1265 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1268 sprintf(version, _("Version %s"), VERSION);
1269 panel->versionL = WMCreateLabel(panel->win);
1270 WMResizeWidget(panel->versionL, 310, 16);
1271 WMMoveWidget(panel->versionL, 30, 95);
1272 WMSetLabelTextAlignment(panel->versionL, WARight);
1273 WMSetLabelText(panel->versionL, version);
1274 WMSetLabelWraps(panel->versionL, False);
1276 panel->copyrL = WMCreateLabel(panel->win);
1277 WMResizeWidget(panel->copyrL, 340, 40);
1278 WMMoveWidget(panel->copyrL, 15, 185);
1279 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1280 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1281 /* we want the (c) character in the helvetica font */
1282 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1283 if (font) {
1284 WMSetLabelFont(panel->copyrL, font);
1287 switch (scr->w_depth) {
1288 case 15:
1289 strcpy(version, _("32 thousand"));
1290 break;
1291 case 16:
1292 strcpy(version, _("64 thousand"));
1293 break;
1294 case 24:
1295 case 32:
1296 strcpy(version, _("16 million"));
1297 break;
1298 default:
1299 sprintf(version, "%d", 1<<scr->w_depth);
1300 break;
1303 sprintf(buffer, _("Using visual 0x%x: %s %ibpp (%s colors)\n"),
1304 (unsigned)scr->w_visual->visualid,
1305 visuals[scr->w_visual->class], scr->w_depth, version);
1307 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1309 struct mallinfo ma = mallinfo();
1310 sprintf(buffer+strlen(buffer),
1311 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1312 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1315 #endif
1317 strcat(buffer, _("Supported image formats: "));
1318 strl = RSupportedFileFormats();
1319 for (i=0; strl[i]!=NULL; i++) {
1320 strcat(buffer, strl[i]);
1321 strcat(buffer, " ");
1324 strcat(buffer, _("\nAdditional Support For: "));
1326 char *list[8];
1327 char buf[80];
1328 int j = 0;
1330 #ifdef MWM_HINTS
1331 list[j++] = "MWM";
1332 #endif
1333 #ifdef KWM_HINTS
1334 list[j++] = "KDE";
1335 #endif
1336 #ifdef GNOME_STUFF
1337 list[j++] = "GNOME";
1338 #endif
1339 #ifdef OLWM_HINTS
1340 list[j++] = "OLWM";
1341 #endif
1342 #ifdef WSOUND
1343 list[j++] = _("Sound");
1344 #endif
1346 buf[0] = 0;
1347 for (i = 0; i < j; i++) {
1348 if (i > 0) {
1349 if (i == j - 1)
1350 strcat(buf, _(" and "));
1351 else
1352 strcat(buf, ", ");
1354 strcat(buf, list[i]);
1356 strcat(buffer, buf);
1360 panel->infoL = WMCreateLabel(panel->win);
1361 WMResizeWidget(panel->infoL, 350, 75);
1362 WMMoveWidget(panel->infoL, 15, 115);
1363 WMSetLabelText(panel->infoL, buffer);
1364 if (font) {
1365 WMSetLabelFont(panel->infoL, font);
1366 WMReleaseFont(font);
1370 WMRealizeWidget(panel->win);
1371 WMMapSubwidgets(panel->win);
1373 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1375 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1377 WMMapWidget(panel->win);
1379 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1380 (scr->scr_width - 382)/2,
1381 (scr->scr_height - 230)/2, 382, 230);
1383 WSETUFLAG(wwin, no_closable, 0);
1384 WSETUFLAG(wwin, no_close_button, 0);
1385 #ifdef XKB_BUTTON_HINT
1386 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1387 #endif
1388 wWindowUpdateButtonImages(wwin);
1389 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1390 wwin->frame->on_click_right = destroyInfoPanel;
1392 wWindowMap(wwin);
1394 panel->wwin = wwin;
1396 thePanel = panel;
1397 #ifdef SILLYNESS
1398 if (InitXThing(panel->scr)) {
1399 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1400 panel->cycle = 0;
1401 panel->x = 1;
1402 panel->str = _("Merry X'mas!");
1403 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1405 #endif
1410 ***********************************************************************
1411 * Legal Panel
1412 ***********************************************************************
1415 typedef struct {
1416 WScreen *scr;
1418 WWindow *wwin;
1420 WMWindow *win;
1422 WMLabel *licenseL;
1423 } LegalPanel;
1426 static LegalPanel *legalPanel = NULL;
1428 static void
1429 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1431 WMUnmapWidget(legalPanel->win);
1433 WMDestroyWidget(legalPanel->win);
1435 wUnmanageWindow(legalPanel->wwin, False, False);
1437 wfree(legalPanel);
1439 legalPanel = NULL;
1443 void
1444 wShowLegalPanel(WScreen *scr)
1446 LegalPanel *panel;
1447 Window parent;
1448 WWindow *wwin;
1450 if (legalPanel) {
1451 if (legalPanel->scr == scr) {
1452 wRaiseFrame(legalPanel->wwin->frame->core);
1453 wSetFocusTo(scr, legalPanel->wwin);
1455 return;
1458 panel = wmalloc(sizeof(LegalPanel));
1460 panel->scr = scr;
1462 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1463 WMResizeWidget(panel->win, 420, 250);
1466 panel->licenseL = WMCreateLabel(panel->win);
1467 WMSetLabelWraps(panel->licenseL, True);
1468 WMResizeWidget(panel->licenseL, 400, 230);
1469 WMMoveWidget(panel->licenseL, 10, 10);
1470 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1471 WMSetLabelText(panel->licenseL,
1472 _(" Window Maker is free software; you can redistribute it and/or\n"
1473 "modify it under the terms of the GNU General Public License as\n"
1474 "published by the Free Software Foundation; either version 2 of the\n"
1475 "License, or (at your option) any later version.\n\n\n"
1476 " Window Maker is distributed in the hope that it will be useful,\n"
1477 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1478 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1479 "See the GNU General Public License for more details.\n\n\n"
1480 " You should have received a copy of the GNU General Public\n"
1481 "License along with this program; if not, write to the Free Software\n"
1482 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1483 "02111-1307, USA."));
1484 WMSetLabelRelief(panel->licenseL, WRGroove);
1486 WMRealizeWidget(panel->win);
1487 WMMapSubwidgets(panel->win);
1489 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1491 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1493 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1494 (scr->scr_width - 420)/2,
1495 (scr->scr_height - 250)/2, 420, 250);
1497 WSETUFLAG(wwin, no_closable, 0);
1498 WSETUFLAG(wwin, no_close_button, 0);
1499 wWindowUpdateButtonImages(wwin);
1500 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1501 #ifdef XKB_BUTTON_HINT
1502 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1503 #endif
1504 wwin->frame->on_click_right = destroyLegalPanel;
1506 panel->wwin = wwin;
1508 WMMapWidget(panel->win);
1510 wWindowMap(wwin);
1512 legalPanel = panel;
1517 ***********************************************************************
1518 * Crashing Dialog Panel
1519 ***********************************************************************
1522 extern WDDomain *WDWindowAttributes;
1525 typedef struct _CrashPanel {
1526 WMWindow *win; /* main window */
1528 WMLabel *iconL; /* application icon */
1529 WMLabel *nameL; /* title of panel */
1531 WMFrame *sepF; /* separator frame */
1533 WMLabel *noteL; /* Title of note */
1534 WMLabel *note2L; /* body of note with what happened */
1536 WMFrame *whatF; /* "what to do next" frame */
1537 WMPopUpButton *whatP; /* action selection popup button */
1539 WMButton *okB; /* ok button */
1541 Bool done; /* if finished with this dialog */
1542 int action; /* what to do after */
1544 KeyCode retKey;
1546 } CrashPanel;
1549 static void
1550 handleKeyPress(XEvent *event, void *clientData)
1552 CrashPanel *panel = (CrashPanel*)clientData;
1554 if (event->xkey.keycode == panel->retKey) {
1555 WMPerformButtonClick(panel->okB);
1560 static void
1561 okButtonCallback(void *self, void *clientData)
1563 CrashPanel *panel = (CrashPanel*)clientData;
1565 panel->done = True;
1569 static void
1570 setCrashAction(void *self, void *clientData)
1572 WMPopUpButton *pop = (WMPopUpButton*)self;
1573 CrashPanel *panel = (CrashPanel*)clientData;
1575 panel->action = WMGetPopUpButtonSelectedItem(pop);
1579 static WMPixmap*
1580 getWindowMakerIconImage(WMScreen *scr)
1582 proplist_t dict, key, option, value=NULL;
1583 WMPixmap *pix=NULL;
1584 char *path;
1586 PLSetStringCmpHook(NULL);
1588 key = PLMakeString("Logo.WMPanel");
1589 option = PLMakeString("Icon");
1591 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
1593 if (dict) {
1594 value = PLGetDictionaryEntry(dict, option);
1597 PLRelease(key);
1598 PLRelease(option);
1600 PLSetStringCmpHook(StringCompareHook);
1602 if (value && PLIsString(value)) {
1603 path = FindImage(wPreferences.icon_path, PLGetString(value));
1605 if (path) {
1606 RImage *image;
1608 image = RLoadImage(WMScreenRContext(scr), path, 0);
1609 if (image) {
1610 pix = WMCreatePixmapFromRImage(scr, image, 0);
1611 RDestroyImage(image);
1613 wfree(path);
1617 return pix;
1621 #define PWIDTH 295
1622 #define PHEIGHT 345
1626 wShowCrashingDialogPanel(int whatSig)
1628 CrashPanel *panel;
1629 WMScreen *scr;
1630 WMFont *font;
1631 WMPixmap *logo;
1632 int screen_no, scr_width, scr_height;
1633 int action;
1634 char buf[256];
1636 panel = wmalloc(sizeof(CrashPanel));
1637 memset(panel, 0, sizeof(CrashPanel));
1639 screen_no = DefaultScreen(dpy);
1640 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1641 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1643 scr = WMCreateScreen(dpy, screen_no);
1644 if (!scr) {
1645 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1646 return WMAbort;
1649 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1651 panel->win = WMCreateWindow(scr, "crashingDialog");
1652 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1653 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1655 logo = getWindowMakerIconImage(scr);
1656 if (logo) {
1657 panel->iconL = WMCreateLabel(panel->win);
1658 WMResizeWidget(panel->iconL, 64, 64);
1659 WMMoveWidget(panel->iconL, 10, 10);
1660 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1661 WMSetLabelImage(panel->iconL, logo);
1664 panel->nameL = WMCreateLabel(panel->win);
1665 WMResizeWidget(panel->nameL, 190, 18);
1666 WMMoveWidget(panel->nameL, 80, 35);
1667 WMSetLabelTextAlignment(panel->nameL, WALeft);
1668 font = WMBoldSystemFontOfSize(scr, 18);
1669 WMSetLabelFont(panel->nameL, font);
1670 WMReleaseFont(font);
1671 WMSetLabelText(panel->nameL, _("Fatal error"));
1673 panel->sepF = WMCreateFrame(panel->win);
1674 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1675 WMMoveWidget(panel->sepF, -2, 80);
1677 panel->noteL = WMCreateLabel(panel->win);
1678 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1679 WMMoveWidget(panel->noteL, 10, 90);
1680 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1681 #ifdef SYS_SIGLIST_DECLARED
1682 sprintf(buf, _("Window Maker received signal %i\n(%s)."),
1683 whatSig, sys_siglist[whatSig]);
1684 #else
1685 sprintf(buf, _("Window Maker received signal %i."), whatSig);
1686 #endif
1687 WMSetLabelText(panel->noteL, buf);
1689 panel->note2L = WMCreateLabel(panel->win);
1690 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1691 WMMoveWidget(panel->note2L, 10, 130);
1692 WMSetLabelTextAlignment(panel->note2L, WALeft);
1693 WMSetLabelText(panel->note2L,
1694 _(" This fatal error occured probably due to a bug."
1695 " Please fill the included BUGFORM and "
1696 "report it to bugs@windowmaker.org."));
1699 panel->whatF = WMCreateFrame(panel->win);
1700 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1701 WMMoveWidget(panel->whatF, 10, 240);
1702 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1704 panel->whatP = WMCreatePopUpButton(panel->whatF);
1705 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1706 WMMoveWidget(panel->whatP, 35, 20);
1707 WMSetPopUpButtonPullsDown(panel->whatP, False);
1708 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1709 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1710 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1711 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1712 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1713 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1714 panel->action = WMRestart;
1716 WMMapSubwidgets(panel->whatF);
1718 panel->okB = WMCreateCommandButton(panel->win);
1719 WMResizeWidget(panel->okB, 80, 26);
1720 WMMoveWidget(panel->okB, 205, 309);
1721 WMSetButtonText(panel->okB, _("OK"));
1722 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1723 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1724 WMSetButtonImagePosition(panel->okB, WIPRight);
1725 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1727 panel->done = 0;
1729 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1730 handleKeyPress, panel);
1732 WMRealizeWidget(panel->win);
1733 WMMapSubwidgets(panel->win);
1735 WMMapWidget(panel->win);
1737 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1739 while (!panel->done) {
1740 XEvent event;
1742 WMNextEvent(dpy, &event);
1743 WMHandleEvent(&event);
1746 action = panel->action;
1748 WMUnmapWidget(panel->win);
1749 WMDestroyWidget(panel->win);
1750 wfree(panel);
1752 return action;
1758 /*****************************************************************************
1759 * About GNUstep Panel
1760 *****************************************************************************/
1763 static void
1764 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1765 unsigned long blackPixel, unsigned long whitePixel)
1767 GC gc;
1768 XGCValues gcv;
1769 XRectangle rects[3];
1771 gcv.foreground = blackPixel;
1772 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1774 XFillArc(dpy, d, gc, width/45, height/45,
1775 width - 2*width/45, height - 2*height/45, 0, 360*64);
1777 rects[0].x = 0;
1778 rects[0].y = 37*height/45;
1779 rects[0].width = width/3;
1780 rects[0].height = height - rects[0].y;
1782 rects[1].x = rects[0].width;
1783 rects[1].y = height/2;
1784 rects[1].width = width - 2*width/3;
1785 rects[1].height = height - rects[1].y;
1787 rects[2].x = 2*width/3;
1788 rects[2].y = height - 37*height/45;
1789 rects[2].width = width/3;
1790 rects[2].height = height - rects[2].y;
1792 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1793 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1795 XSetForeground(dpy, gc, whitePixel);
1796 XFillArc(dpy, d, gc, width/45, height/45,
1797 width - 2*width/45, height - 2*height/45, 0, 360*64);
1799 XFreeGC(dpy, gc);
1803 typedef struct {
1804 WScreen *scr;
1806 WWindow *wwin;
1808 WMWindow *win;
1810 WMLabel *gstepL;
1811 WMLabel *textL;
1812 } GNUstepPanel;
1815 static GNUstepPanel *gnustepPanel = NULL;
1817 static void
1818 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1820 WMUnmapWidget(gnustepPanel->win);
1822 WMDestroyWidget(gnustepPanel->win);
1824 wUnmanageWindow(gnustepPanel->wwin, False, False);
1826 wfree(gnustepPanel);
1828 gnustepPanel = NULL;
1832 void
1833 wShowGNUstepPanel(WScreen *scr)
1835 GNUstepPanel *panel;
1836 Window parent;
1837 WWindow *wwin;
1838 WMPixmap *pixmap;
1839 WMColor *color;
1841 if (gnustepPanel) {
1842 if (gnustepPanel->scr == scr) {
1843 wRaiseFrame(gnustepPanel->wwin->frame->core);
1844 wSetFocusTo(scr, gnustepPanel->wwin);
1846 return;
1849 panel = wmalloc(sizeof(GNUstepPanel));
1851 panel->scr = scr;
1853 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1854 WMResizeWidget(panel->win, 325, 200);
1856 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1857 WMScreenDepth(scr->wmscreen), True);
1859 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1861 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1862 WMColorPixel(color), scr->white_pixel);
1864 WMReleaseColor(color);
1866 XSetForeground(dpy, scr->mono_gc, 0);
1867 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1868 130, 130);
1869 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1871 panel->gstepL = WMCreateLabel(panel->win);
1872 WMResizeWidget(panel->gstepL, 285, 64);
1873 WMMoveWidget(panel->gstepL, 20, 0);
1874 WMSetLabelTextAlignment(panel->gstepL, WARight);
1875 WMSetLabelText(panel->gstepL, "GNUstep");
1877 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1879 WMSetLabelFont(panel->gstepL, font);
1880 WMReleaseFont(font);
1883 panel->textL = WMCreateLabel(panel->win);
1884 WMResizeWidget(panel->textL, 275, 130);
1885 WMMoveWidget(panel->textL, 30, 50);
1886 WMSetLabelTextAlignment(panel->textL, WARight);
1887 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1888 WMSetLabelText(panel->textL,
1889 _("Window Maker is part of the GNUstep project.\n"\
1890 "The GNUstep project aims to create a free\n"\
1891 "implementation of the OpenStep(tm) specification\n"\
1892 "which is a object-oriented framework for\n"\
1893 "creating advanced graphical, multi-platform\n"\
1894 "applications. Additionally, a development and\n"\
1895 "user desktop enviroment will be created on top\n"\
1896 "of the framework. For more information about\n"\
1897 "GNUstep, please visit: www.gnustep.org"));
1898 WMSetLabelImage(panel->textL, pixmap);
1900 WMReleasePixmap(pixmap);
1902 WMRealizeWidget(panel->win);
1903 WMMapSubwidgets(panel->win);
1905 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1907 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1909 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1910 (scr->scr_width - 325)/2,
1911 (scr->scr_height - 200)/2, 325, 200);
1913 WSETUFLAG(wwin, no_closable, 0);
1914 WSETUFLAG(wwin, no_close_button, 0);
1915 wWindowUpdateButtonImages(wwin);
1916 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1917 #ifdef XKB_BUTTON_HINT
1918 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1919 #endif
1920 wwin->frame->on_click_right = destroyGNUstepPanel;
1922 panel->wwin = wwin;
1924 WMMapWidget(panel->win);
1926 wWindowMap(wwin);
1928 gnustepPanel = panel;