For libwraster:
[wmaker-crm.git] / src / dialog.c
blob2bf425aed8d162339363298765ed2f1f5851fbef
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 *file, *dirfile;
368 WMPixmap *pixmap;
369 WMColor *blackcolor;
370 WMColor *whitecolor;
371 WMSize size;
372 WMScreen *wmscr = WMWidgetScreen(panel->win);
373 RColor gray;
374 int width;
376 if(!panel->preview) return;
378 width = rect->size.width;
380 blackcolor = WMBlackColor(wmscr);
381 whitecolor = WMWhiteColor(wmscr);
383 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
384 file = wmalloc(strlen(dirfile)+strlen(text)+4);
385 sprintf(file, "%s/%s", dirfile, text);
386 wfree(dirfile);
388 gray.red = 0xae; gray.green = 0xaa;
389 gray.blue = 0xae; gray.alpha = 0;
390 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &gray);
391 wfree(file);
393 if (!pixmap) {
394 WMRemoveListItem(lPtr, index);
395 return;
398 XClearArea(dpy, d, rect->pos.x, rect->pos.y, width, rect->size.height,
399 False);
400 XSetClipMask(dpy, gc, None);
402 XDrawRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x + 5,
403 rect->pos.y +5, width - 10, 54);
405 XDrawLine(dpy, d, WMColorGC(whitecolor), rect->pos.x,
406 rect->pos.y+rect->size.height-1, rect->pos.x+width,
407 rect->pos.y+rect->size.height-1);
410 if (state&WLDSSelected) {
411 XFillRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x,
412 rect->pos.y, width, rect->size.height);
415 size = WMGetPixmapSize(pixmap);
417 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
418 XSetClipOrigin(dpy, copygc, rect->pos.x + (width-size.width)/2,
419 rect->pos.y+2);
420 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
421 size.width>100?100:size.width, size.height>64?64:size.height,
422 rect->pos.x + (width-size.width)/2, rect->pos.y+2);
425 int i,j;
426 int fheight = WMFontHeight(panel->normalfont);
427 int tlen = strlen(text);
428 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
429 int ofx, ofy;
431 ofx = rect->pos.x + (width - twidth)/2;
432 ofy = rect->pos.y + 64 - fheight;
434 for(i=-1;i<2;i++)
435 for(j=-1;j<2;j++)
436 WMDrawString(wmscr, d, WMColorGC(whitecolor),
437 panel->normalfont, ofx+i, ofy+j,
438 text, tlen);
440 WMDrawString(wmscr, d, WMColorGC(blackcolor), panel->normalfont,
441 ofx, ofy, text, tlen);
444 WMReleasePixmap(pixmap);
445 /* I hope it is better to do not use cache / on my box it is fast nuff */
446 XFlush(dpy);
448 WMReleaseColor(blackcolor);
449 WMReleaseColor(whitecolor);
453 static void
454 buttonCallback(void *self, void *clientData)
456 WMButton *bPtr = (WMButton*)self;
457 IconPanel *panel = (IconPanel*)clientData;
460 if (bPtr==panel->okButton) {
461 panel->done = True;
462 panel->result = True;
463 } else if (bPtr==panel->cancelButton) {
464 panel->done = True;
465 panel->result = False;
466 } else if (bPtr==panel->previewButton) {
467 /**** Previewer ****/
468 WMSetButtonEnabled(bPtr, False);
469 WMSetListUserDrawItemHeight(panel->iconList, 68);
470 WMSetListUserDrawProc(panel->iconList, drawIconProc);
471 WMRedisplayWidget(panel->iconList);
472 /* for draw proc to access screen/gc */
473 /*** end preview ***/
475 #if 0
476 else if (bPtr==panel->chooseButton) {
477 WMOpenPanel *op;
479 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
481 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
482 char *path;
483 path = WMGetFilePanelFile(op);
484 WMSetTextFieldText(panel->fileField, path);
485 setViewedImage(panel, path);
486 wfree(path);
488 WMDestroyFilePanel(op);
490 #endif
494 static void
495 keyPressHandler(XEvent *event, void *data)
497 IconPanel *panel = (IconPanel*)data;
498 Display *dpy = event->xany.display;
499 char buffer[32];
500 int count;
501 KeySym ksym;
502 int iidx;
503 int didx;
504 int item;
505 WMList *list = NULL;
507 if (event->type == KeyRelease)
508 return;
510 buffer[0] = 0;
511 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
514 iidx = WMGetListSelectedItemRow(panel->iconList);
515 didx = WMGetListSelectedItemRow(panel->dirList);
517 switch (ksym) {
518 case XK_Up:
519 if (iidx > 0)
520 item = iidx-1;
521 else
522 item = iidx;
523 list = panel->iconList;
524 break;
525 case XK_Down:
526 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
527 item = iidx+1;
528 else
529 item = iidx;
530 list = panel->iconList;
531 break;
532 case XK_Home:
533 item = 0;
534 list = panel->iconList;
535 break;
536 case XK_End:
537 item = WMGetListNumberOfRows(panel->iconList) - 1;
538 list = panel->iconList;
539 break;
540 case XK_Next:
541 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
542 item = didx + 1;
543 else
544 item = didx;
545 list = panel->dirList;
546 break;
547 case XK_Prior:
548 if (didx > 0)
549 item = didx - 1;
550 else
551 item = 0;
552 list = panel->dirList;
553 break;
554 case XK_Return:
555 WMPerformButtonClick(panel->okButton);
556 break;
557 case XK_Escape:
558 WMPerformButtonClick(panel->cancelButton);
559 break;
562 if (list) {
563 WMSelectListItem(list, item);
564 WMSetListPosition(list, item - 5);
565 listCallback(list, panel);
571 Bool
572 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
574 WWindow *wwin;
575 Window parent;
576 IconPanel *panel;
577 WMColor *color;
578 WMFont *boldFont;
580 panel = wmalloc(sizeof(IconPanel));
581 memset(panel, 0, sizeof(IconPanel));
583 panel->scr = scr;
585 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
586 WMResizeWidget(panel->win, 450, 280);
588 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
589 keyPressHandler, panel);
592 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
593 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
595 panel->dirLabel = WMCreateLabel(panel->win);
596 WMResizeWidget(panel->dirLabel, 200, 20);
597 WMMoveWidget(panel->dirLabel, 10, 7);
598 WMSetLabelText(panel->dirLabel, _("Directories"));
599 WMSetLabelFont(panel->dirLabel, boldFont);
600 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
602 WMSetLabelRelief(panel->dirLabel, WRSunken);
604 panel->iconLabel = WMCreateLabel(panel->win);
605 WMResizeWidget(panel->iconLabel, 140, 20);
606 WMMoveWidget(panel->iconLabel, 215, 7);
607 WMSetLabelText(panel->iconLabel, _("Icons"));
608 WMSetLabelFont(panel->iconLabel, boldFont);
609 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
611 WMReleaseFont(boldFont);
613 color = WMWhiteColor(scr->wmscreen);
614 WMSetLabelTextColor(panel->dirLabel, color);
615 WMSetLabelTextColor(panel->iconLabel, color);
616 WMReleaseColor(color);
618 color = WMDarkGrayColor(scr->wmscreen);
619 WMSetWidgetBackgroundColor(panel->iconLabel, color);
620 WMSetWidgetBackgroundColor(panel->dirLabel, color);
621 WMReleaseColor(color);
623 WMSetLabelRelief(panel->iconLabel, WRSunken);
625 panel->dirList = WMCreateList(panel->win);
626 WMResizeWidget(panel->dirList, 200, 170);
627 WMMoveWidget(panel->dirList, 10, 30);
628 WMSetListAction(panel->dirList, listCallback, panel);
630 panel->iconList = WMCreateList(panel->win);
631 WMResizeWidget(panel->iconList, 140, 170);
632 WMMoveWidget(panel->iconList, 215, 30);
633 WMSetListAction(panel->iconList, listCallback, panel);
635 WMHangData(panel->iconList,panel);
637 panel->previewButton = WMCreateCommandButton(panel->win);
638 WMResizeWidget(panel->previewButton, 75, 26);
639 WMMoveWidget(panel->previewButton, 365, 130);
640 WMSetButtonText(panel->previewButton, _("Preview"));
641 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
643 panel->iconView = WMCreateLabel(panel->win);
644 WMResizeWidget(panel->iconView, 75, 75);
645 WMMoveWidget(panel->iconView, 365, 40);
646 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
647 WMSetLabelRelief(panel->iconView, WRSunken);
648 WMSetLabelTextAlignment(panel->iconView, WACenter);
650 panel->fileLabel = WMCreateLabel(panel->win);
651 WMResizeWidget(panel->fileLabel, 80, 20);
652 WMMoveWidget(panel->fileLabel, 10, 210);
653 WMSetLabelText(panel->fileLabel, _("File Name:"));
655 panel->fileField = WMCreateTextField(panel->win);
656 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
657 WMResizeWidget(panel->fileField, 345, 20);
658 WMMoveWidget(panel->fileField, 95, 210);
659 WMSetTextFieldEditable(panel->fileField, False);
661 panel->okButton = WMCreateCommandButton(panel->win);
662 WMResizeWidget(panel->okButton, 80, 26);
663 WMMoveWidget(panel->okButton, 360, 240);
664 WMSetButtonText(panel->okButton, _("OK"));
665 WMSetButtonEnabled(panel->okButton, False);
666 WMSetButtonAction(panel->okButton, buttonCallback, panel);
668 panel->cancelButton = WMCreateCommandButton(panel->win);
669 WMResizeWidget(panel->cancelButton, 80, 26);
670 WMMoveWidget(panel->cancelButton, 270, 240);
671 WMSetButtonText(panel->cancelButton, _("Cancel"));
672 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
673 #if 0
674 panel->chooseButton = WMCreateCommandButton(panel->win);
675 WMResizeWidget(panel->chooseButton, 110, 26);
676 WMMoveWidget(panel->chooseButton, 150, 240);
677 WMSetButtonText(panel->chooseButton, _("Choose File"));
678 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
679 #endif
680 WMRealizeWidget(panel->win);
681 WMMapSubwidgets(panel->win);
683 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
685 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
688 char *tmp;
690 tmp = wmalloc((instance ? strlen(instance) : 0)
691 + (class ? strlen(class) : 0) + 32);
693 if (tmp && (instance || class))
694 sprintf(tmp, "%s [%s.%s]", _("Icon Chooser"), instance, class);
695 else
696 strcpy(tmp, _("Icon Chooser"));
698 wwin = wManageInternalWindow(scr, parent, None, tmp,
699 (scr->scr_width - 450)/2,
700 (scr->scr_height - 280)/2, 450, 280);
701 wfree(tmp);
704 /* put icon paths in the list */
705 listIconPaths(panel->dirList);
707 WMMapWidget(panel->win);
709 wWindowMap(wwin);
711 while (!panel->done) {
712 XEvent event;
714 WMNextEvent(dpy, &event);
715 WMHandleEvent(&event);
718 if (panel->result) {
719 char *defaultPath, *wantedPath;
721 /* check if the file the user selected is not the one that
722 * would be loaded by default with the current search path */
723 *file = WMGetListSelectedItem(panel->iconList)->text;
724 if ((*file)[0]==0) {
725 wfree(*file);
726 *file = NULL;
727 } else {
728 defaultPath = FindImage(wPreferences.icon_path, *file);
729 wantedPath = WMGetTextFieldText(panel->fileField);
730 /* if the file is not the default, use full path */
731 if (strcmp(wantedPath, defaultPath)!=0) {
732 *file = wantedPath;
733 } else {
734 *file = wstrdup(*file);
735 wfree(wantedPath);
737 wfree(defaultPath);
739 } else {
740 *file = NULL;
743 WMReleaseFont(panel->normalfont);
745 WMUnmapWidget(panel->win);
747 WMDestroyWidget(panel->win);
749 wUnmanageWindow(wwin, False, False);
751 wfree(panel);
753 XDestroyWindow(dpy, parent);
755 return panel->result;
760 ***********************************************************************
761 * Info Panel
762 ***********************************************************************
766 typedef struct {
767 WScreen *scr;
769 WWindow *wwin;
771 WMWindow *win;
773 WMLabel *logoL;
774 WMLabel *name1L;
775 WMLabel *name2L;
777 WMLabel *versionL;
779 WMLabel *infoL;
781 WMLabel *copyrL;
783 #ifdef SILLYNESS
784 WMHandlerID timer;
785 int cycle;
786 RImage *icon;
787 RImage *pic;
788 WMPixmap *oldPix;
789 WMFont *oldFont;
790 char *str;
791 int x;
792 #endif
793 } InfoPanel;
797 #define COPYRIGHT_TEXT \
798 "Copyright \xa9 1997~2001 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
799 "Copyright \xa9 1998~2001 Dan Pascu <dan@windowmaker.org>"
803 static InfoPanel *thePanel = NULL;
805 static void
806 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
808 #ifdef SILLYNESS
809 if (thePanel->timer) {
810 WMDeleteTimerHandler(thePanel->timer);
812 if (thePanel->oldPix) {
813 WMReleasePixmap(thePanel->oldPix);
815 if (thePanel->oldFont) {
816 WMReleaseFont(thePanel->oldFont);
818 if (thePanel->icon) {
819 RReleaseImage(thePanel->icon);
821 if (thePanel->pic) {
822 RReleaseImage(thePanel->pic);
824 #endif /* SILLYNESS */
825 WMUnmapWidget(thePanel);
827 wUnmanageWindow(thePanel->wwin, False, False);
829 WMDestroyWidget(thePanel->win);
831 wfree(thePanel);
833 thePanel = NULL;
837 WMPixmap*
838 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
840 WMPixmap *wpix = NULL;
841 Pixmap grad = None;
842 Pixmap mask = None;
843 RContext *rc = WMScreenRContext(scr);
844 XFontStruct *f = NULL;
845 int w, h;
846 GC gc = None;
848 f = XLoadQueryFont(dpy, font);
849 if (!f)
850 return NULL;
852 w = XTextWidth(f, text, strlen(text));
853 h = f->ascent+f->descent;
855 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
856 gc = XCreateGC(dpy, mask, 0, NULL);
857 XSetForeground(dpy, gc, 0);
858 XSetFont(dpy, gc, f->fid);
859 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
861 XSetForeground(dpy, gc, 1);
862 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
863 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
864 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
866 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
868 WMColor *color;
870 color = WMBlackColor(scr);
871 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
872 WMReleaseColor(color);
875 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
877 if (gc)
878 XFreeGC(dpy, gc);
879 XFreeFont(dpy, f);
881 return wpix;
884 #ifdef SILLYNESS
886 extern WMPixmap *DoXThing();
887 extern Bool InitXThing();
889 static void
890 logoPushCallback(void *data)
892 InfoPanel *panel = (InfoPanel*)data;
893 char buffer[512];
894 int i;
895 static int oldi = 0;
896 int len;
897 static int jingobeu[] = {
898 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
899 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
900 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
902 static int c = 0;
904 if (panel->x) {
905 XKeyboardControl kc;
907 if (panel->x > 0) {
908 if(jingobeu[panel->x-1]==0){panel->x=-1;}else if(jingobeu[panel->x
909 -1]<0){panel->x++;c=jingobeu[panel->x-1]/50;panel->x++;}else if(c==0){
910 kc.bell_pitch=jingobeu[panel->x-1];panel->x++;kc.bell_percent=50;c=
911 jingobeu[panel->x-1]/50;kc.bell_duration=jingobeu[panel->x-1];panel->x++;
912 XChangeKeyboardControl(dpy,KBBellPitch|KBBellDuration|KBBellPercent,&kc);
913 XBell(dpy,50);XFlush(dpy);}else{c--;}}
914 if (!(panel->cycle % 4)) {
915 WMPixmap *p;
917 p = DoXThing(panel->wwin);
918 WMSetLabelImage(panel->logoL, p);
920 } else if (panel->cycle < 30) {
921 RImage *image;
922 WMPixmap *pix;
923 RColor gray;
925 gray.red = 0xae; gray.green = 0xaa;
926 gray.blue = 0xae; gray.alpha = 0;
928 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
929 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
930 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
931 RReleaseImage(image);
932 WMSetLabelImage(panel->logoL, pix);
933 WMReleasePixmap(pix);
936 /* slow down text a little */
937 i = (int)(panel->cycle * 50.0/85.0)%200;
939 if (i != oldi) {
940 len = strlen(panel->str);
942 strncpy(buffer, panel->str, i<len ? i : len);
943 if (i >= len)
944 memset(&buffer[len], ' ', i-len);
946 strncpy(buffer, panel->str, i<len ? i : len);
947 if (i >= len)
948 memset(&buffer[len], ' ', i-len);
949 buffer[i]=0;
951 WMSetLabelText(panel->versionL, buffer);
953 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
955 oldi = i;
958 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
959 panel->cycle++;
963 static void
964 handleLogoPush(XEvent *event, void *data)
966 InfoPanel *panel = (InfoPanel*)data;
967 static int broken = 0;
968 static int clicks = 0;
969 static char *pic_data[] = {
970 "45 45 57 1",
971 " c None",
972 ". c #000000",
973 "X c #383C00",
974 "o c #515500",
975 "O c #616100",
976 "+ c #616900",
977 "@ c #696D00",
978 "# c #697100",
979 "$ c #495100",
980 "% c #202800",
981 "& c #969600",
982 "* c #CFCF00",
983 "= c #D7DB00",
984 "- c #D7D700",
985 "; c #C7CB00",
986 ": c #A6AA00",
987 "> c #494900",
988 ", c #8E8E00",
989 "< c #DFE700",
990 "1 c #F7FF00",
991 "2 c #FFFF00",
992 "3 c #E7EB00",
993 "4 c #B6B600",
994 "5 c #595900",
995 "6 c #717500",
996 "7 c #AEB200",
997 "8 c #CFD300",
998 "9 c #E7EF00",
999 "0 c #EFF300",
1000 "q c #9EA200",
1001 "w c #F7FB00",
1002 "e c #F7F700",
1003 "r c #BEBE00",
1004 "t c #8E9200",
1005 "y c #EFF700",
1006 "u c #969A00",
1007 "i c #414500",
1008 "p c #595D00",
1009 "a c #E7E700",
1010 "s c #C7C700",
1011 "d c #797D00",
1012 "f c #BEC300",
1013 "g c #DFE300",
1014 "h c #868600",
1015 "j c #EFEF00",
1016 "k c #9E9E00",
1017 "l c #616500",
1018 "z c #DFDF00",
1019 "x c #868A00",
1020 "c c #969200",
1021 "v c #B6BA00",
1022 "b c #A6A600",
1023 "n c #8E8A00",
1024 "m c #717100",
1025 "M c #AEAE00",
1026 "N c #AEAA00",
1027 "B c #868200",
1028 " ............... ",
1029 " ....XoO+@##+O$%.... ",
1030 " ...%X&*========-;;:o... ",
1031 " ...>.>,<122222222222134@... ",
1032 " ..>5678912222222222222220q%.. ",
1033 " ..$.&-w2222222222222222222er>.. ",
1034 " ..O.t31222222222222222222222y4>.. ",
1035 " ...O5u3222222222222222222222222yri... ",
1036 " ..>p&a22222222222222222222222222wso.. ",
1037 " ..ids91222222222222222222222222222wfi.. ",
1038 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1039 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1040 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1041 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1042 "..io*222222222&...u22222222yt..%*22222220:%. ",
1043 "..>k02222222227...f222222222v..X=222222229t. ",
1044 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1045 ".%vw222222222221y2222222222219*y2222222222wd.",
1046 ".X;2222222222222222222222222222222222222222b.",
1047 ".i*2222222222222222222222222222222222222222v.",
1048 ".i*2222222222222222222222222222222222222222;.",
1049 ".i*22222222222222222222222222222222222222228.",
1050 ".>*2222222222222222222222222222222222222222=.",
1051 ".i*22222222222222222222222222222222222222228.",
1052 ".i*2222222222222222222222222222222222222222;.",
1053 ".X*222222222222222222222222222222we12222222r.",
1054 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1055 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1056 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1057 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1058 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1059 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1060 " ...:e2222218mdz22222222222222a&$vw222220@...",
1061 " ...O-122222y:.u02222222222229q$uj222221r... ",
1062 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1063 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1064 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1065 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1066 " ..Xb9122222109g-****;<y22221zn%... ",
1067 " ..X&801222222222222222222w-h.... ",
1068 " ...o:=022222222222222221=lX... ",
1069 " ..X@:;3w2222222222210fO... ",
1070 " ...XX&v8<30000003-N@... ",
1071 " .....XmnbN:q&Bo.... ",
1072 " ............ "};
1073 static char *msgs[] = {
1074 "Have a nice day!",
1075 "Focus follow mouse users will burn in hell!!!",
1076 "Mooo Canada!!!!",
1077 "Hi! My name is bobby...",
1078 "AHH! The neurotic monkeys are after me!",
1079 "WHAT YOU SAY??",
1080 "WE GET SIGNAL",
1081 "SOMEBODY SET UP US THE BOMB",
1082 "ALL YOUR BASE ARE BELONG TO US!",
1083 "Oh My God!!! Larry is back!"
1087 clicks++;
1089 if (!panel->timer && !broken && clicks > 0) {
1090 WMFont *font;
1092 panel->x = 0;
1093 clicks = 0;
1094 if (!panel->icon) {
1095 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1096 if (!panel->icon) {
1097 broken = 1;
1098 return;
1099 } else {
1100 RColor color;
1102 color.red = 0xae; color.green = 0xaa;
1103 color.blue = 0xae; color.alpha = 0;
1105 panel->icon = RCloneImage(panel->icon);
1106 RCombineImageWithColor(panel->icon, &color);
1109 if (!panel->pic) {
1110 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1111 if (!panel->pic) {
1112 broken = 1;
1113 RReleaseImage(panel->icon);
1114 panel->icon = NULL;
1115 return;
1119 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1121 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1122 panel->cycle = 0;
1123 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1124 /* If we don't use a fixed font, scrolling will be jumpy */
1125 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1126 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1127 WMRetainFont(panel->oldFont);
1128 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1129 if (font) {
1130 WMSetLabelFont(panel->versionL, font);
1131 WMReleaseFont(font);
1133 WMSetLabelText(panel->versionL, "");
1134 } else if (panel->timer) {
1135 char version[20];
1137 panel->x = 0;
1138 clicks = 0;
1139 WMSetLabelImage(panel->logoL, panel->oldPix);
1140 WMReleasePixmap(panel->oldPix);
1141 panel->oldPix = NULL;
1143 WMDeleteTimerHandler(panel->timer);
1144 panel->timer = NULL;
1146 WMSetLabelFont(panel->versionL, panel->oldFont);
1147 if (panel->oldFont) {
1148 WMReleaseFont(panel->oldFont);
1149 panel->oldFont = NULL;
1151 sprintf(version, _("Version %s"), VERSION);
1152 WMSetLabelText(panel->versionL, version);
1153 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1157 XEvent ev;
1158 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1159 ButtonPress, &ev));
1162 #endif /* SILLYNESS */
1165 void
1166 wShowInfoPanel(WScreen *scr)
1168 InfoPanel *panel;
1169 WMPixmap *logo;
1170 WMSize size;
1171 WMFont *font;
1172 char version[32];
1173 char buffer[512];
1174 Window parent;
1175 WWindow *wwin;
1176 RColor color1, color2;
1177 char **strl;
1178 int i;
1179 char *visuals[] = {
1180 "StaticGray",
1181 "GrayScale",
1182 "StaticColor",
1183 "PseudoColor",
1184 "TrueColor",
1185 "DirectColor"
1189 if (thePanel) {
1190 if (thePanel->scr == scr) {
1191 wRaiseFrame(thePanel->wwin->frame->core);
1192 wSetFocusTo(scr, thePanel->wwin);
1194 return;
1197 panel = wmalloc(sizeof(InfoPanel));
1198 memset(panel, 0, sizeof(InfoPanel));
1200 panel->scr = scr;
1202 panel->win = WMCreateWindow(scr->wmscreen, "info");
1203 WMResizeWidget(panel->win, 382, 230);
1205 logo = WMGetApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1206 if (!logo) {
1207 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1209 if (logo) {
1210 size = WMGetPixmapSize(logo);
1211 panel->logoL = WMCreateLabel(panel->win);
1212 WMResizeWidget(panel->logoL, 64, 64);
1213 WMMoveWidget(panel->logoL, 30, 20);
1214 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1215 WMSetLabelImage(panel->logoL, logo);
1216 #ifdef SILLYNESS
1217 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1218 handleLogoPush, panel);
1219 #endif
1220 WMReleasePixmap(logo);
1223 panel->name1L = WMCreateLabel(panel->win);
1224 WMResizeWidget(panel->name1L, 240, 30);
1225 WMMoveWidget(panel->name1L, 100, 30);
1226 color1.red = 0;
1227 color1.green = 0;
1228 color1.blue = 0;
1229 color2.red = 0x50;
1230 color2.green = 0x50;
1231 color2.blue = 0x70;
1232 logo = renderText(scr->wmscreen, "GNU Window Maker",
1233 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1234 if (logo) {
1235 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1236 WMSetLabelImage(panel->name1L, logo);
1237 WMReleasePixmap(logo);
1238 } else {
1239 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1240 if (font) {
1241 WMSetLabelFont(panel->name1L, font);
1242 WMReleaseFont(font);
1244 WMSetLabelTextAlignment(panel->name1L, WACenter);
1245 WMSetLabelText(panel->name1L, "GNU Window Maker");
1248 panel->name2L = WMCreateLabel(panel->win);
1249 WMResizeWidget(panel->name2L, 240, 24);
1250 WMMoveWidget(panel->name2L, 100, 60);
1251 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1252 if (font) {
1253 WMSetLabelFont(panel->name2L, font);
1254 WMReleaseFont(font);
1255 font = NULL;
1257 WMSetLabelTextAlignment(panel->name2L, WACenter);
1258 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1261 sprintf(version, _("Version %s"), VERSION);
1262 panel->versionL = WMCreateLabel(panel->win);
1263 WMResizeWidget(panel->versionL, 310, 16);
1264 WMMoveWidget(panel->versionL, 30, 95);
1265 WMSetLabelTextAlignment(panel->versionL, WARight);
1266 WMSetLabelText(panel->versionL, version);
1267 WMSetLabelWraps(panel->versionL, False);
1269 panel->copyrL = WMCreateLabel(panel->win);
1270 WMResizeWidget(panel->copyrL, 340, 40);
1271 WMMoveWidget(panel->copyrL, 15, 185);
1272 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1273 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1274 /* we want the (c) character in the helvetica font */
1275 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1276 if (font) {
1277 WMSetLabelFont(panel->copyrL, font);
1280 switch (scr->w_depth) {
1281 case 15:
1282 strcpy(version, _("32 thousand"));
1283 break;
1284 case 16:
1285 strcpy(version, _("64 thousand"));
1286 break;
1287 case 24:
1288 case 32:
1289 strcpy(version, _("16 million"));
1290 break;
1291 default:
1292 sprintf(version, "%d", 1<<scr->w_depth);
1293 break;
1296 sprintf(buffer, _("Using visual 0x%x: %s %ibpp (%s colors)\n"),
1297 (unsigned)scr->w_visual->visualid,
1298 visuals[scr->w_visual->class], scr->w_depth, version);
1300 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1302 struct mallinfo ma = mallinfo();
1303 sprintf(buffer+strlen(buffer),
1304 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1305 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1308 #endif
1310 strcat(buffer, _("Supported image formats: "));
1311 strl = RSupportedFileFormats();
1312 for (i=0; strl[i]!=NULL; i++) {
1313 strcat(buffer, strl[i]);
1314 strcat(buffer, " ");
1317 strcat(buffer, _("\nAdditional Support For: "));
1319 char *list[8];
1320 char buf[80];
1321 int j = 0;
1323 #ifdef MWM_HINTS
1324 list[j++] = "MWM";
1325 #endif
1326 #ifdef KWM_HINTS
1327 list[j++] = "KDE";
1328 #endif
1329 #ifdef GNOME_STUFF
1330 list[j++] = "GNOME";
1331 #endif
1332 #ifdef OLWM_HINTS
1333 list[j++] = "OLWM";
1334 #endif
1335 #ifdef WSOUND
1336 list[j++] = _("Sound");
1337 #endif
1339 buf[0] = 0;
1340 for (i = 0; i < j; i++) {
1341 if (i > 0) {
1342 if (i == j - 1)
1343 strcat(buf, _(" and "));
1344 else
1345 strcat(buf, ", ");
1347 strcat(buf, list[i]);
1349 strcat(buffer, buf);
1353 panel->infoL = WMCreateLabel(panel->win);
1354 WMResizeWidget(panel->infoL, 350, 75);
1355 WMMoveWidget(panel->infoL, 15, 115);
1356 WMSetLabelText(panel->infoL, buffer);
1357 if (font) {
1358 WMSetLabelFont(panel->infoL, font);
1359 WMReleaseFont(font);
1363 WMRealizeWidget(panel->win);
1364 WMMapSubwidgets(panel->win);
1366 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1368 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1370 WMMapWidget(panel->win);
1372 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1373 (scr->scr_width - 382)/2,
1374 (scr->scr_height - 230)/2, 382, 230);
1376 WSETUFLAG(wwin, no_closable, 0);
1377 WSETUFLAG(wwin, no_close_button, 0);
1378 #ifdef XKB_BUTTON_HINT
1379 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1380 #endif
1381 wWindowUpdateButtonImages(wwin);
1382 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1383 wwin->frame->on_click_right = destroyInfoPanel;
1385 wWindowMap(wwin);
1387 panel->wwin = wwin;
1389 thePanel = panel;
1390 #ifdef SILLYNESS
1391 if (InitXThing(panel->scr)) {
1392 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1393 panel->cycle = 0;
1394 panel->x = 1;
1395 panel->str = _("Merry X'mas!");
1396 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1398 #endif
1403 ***********************************************************************
1404 * Legal Panel
1405 ***********************************************************************
1408 typedef struct {
1409 WScreen *scr;
1411 WWindow *wwin;
1413 WMWindow *win;
1415 WMLabel *licenseL;
1416 } LegalPanel;
1419 static LegalPanel *legalPanel = NULL;
1421 static void
1422 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1424 WMUnmapWidget(legalPanel->win);
1426 WMDestroyWidget(legalPanel->win);
1428 wUnmanageWindow(legalPanel->wwin, False, False);
1430 wfree(legalPanel);
1432 legalPanel = NULL;
1436 void
1437 wShowLegalPanel(WScreen *scr)
1439 LegalPanel *panel;
1440 Window parent;
1441 WWindow *wwin;
1443 if (legalPanel) {
1444 if (legalPanel->scr == scr) {
1445 wRaiseFrame(legalPanel->wwin->frame->core);
1446 wSetFocusTo(scr, legalPanel->wwin);
1448 return;
1451 panel = wmalloc(sizeof(LegalPanel));
1453 panel->scr = scr;
1455 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1456 WMResizeWidget(panel->win, 420, 250);
1459 panel->licenseL = WMCreateLabel(panel->win);
1460 WMSetLabelWraps(panel->licenseL, True);
1461 WMResizeWidget(panel->licenseL, 400, 230);
1462 WMMoveWidget(panel->licenseL, 10, 10);
1463 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1464 WMSetLabelText(panel->licenseL,
1465 _(" Window Maker is free software; you can redistribute it and/or\n"
1466 "modify it under the terms of the GNU General Public License as\n"
1467 "published by the Free Software Foundation; either version 2 of the\n"
1468 "License, or (at your option) any later version.\n\n\n"
1469 " Window Maker is distributed in the hope that it will be useful,\n"
1470 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1471 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1472 "See the GNU General Public License for more details.\n\n\n"
1473 " You should have received a copy of the GNU General Public\n"
1474 "License along with this program; if not, write to the Free Software\n"
1475 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1476 "02111-1307, USA."));
1477 WMSetLabelRelief(panel->licenseL, WRGroove);
1479 WMRealizeWidget(panel->win);
1480 WMMapSubwidgets(panel->win);
1482 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1484 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1486 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1487 (scr->scr_width - 420)/2,
1488 (scr->scr_height - 250)/2, 420, 250);
1490 WSETUFLAG(wwin, no_closable, 0);
1491 WSETUFLAG(wwin, no_close_button, 0);
1492 wWindowUpdateButtonImages(wwin);
1493 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1494 #ifdef XKB_BUTTON_HINT
1495 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1496 #endif
1497 wwin->frame->on_click_right = destroyLegalPanel;
1499 panel->wwin = wwin;
1501 WMMapWidget(panel->win);
1503 wWindowMap(wwin);
1505 legalPanel = panel;
1510 ***********************************************************************
1511 * Crashing Dialog Panel
1512 ***********************************************************************
1515 extern WDDomain *WDWindowAttributes;
1518 typedef struct _CrashPanel {
1519 WMWindow *win; /* main window */
1521 WMLabel *iconL; /* application icon */
1522 WMLabel *nameL; /* title of panel */
1524 WMFrame *sepF; /* separator frame */
1526 WMLabel *noteL; /* Title of note */
1527 WMLabel *note2L; /* body of note with what happened */
1529 WMFrame *whatF; /* "what to do next" frame */
1530 WMPopUpButton *whatP; /* action selection popup button */
1532 WMButton *okB; /* ok button */
1534 Bool done; /* if finished with this dialog */
1535 int action; /* what to do after */
1537 KeyCode retKey;
1539 } CrashPanel;
1542 static void
1543 handleKeyPress(XEvent *event, void *clientData)
1545 CrashPanel *panel = (CrashPanel*)clientData;
1547 if (event->xkey.keycode == panel->retKey) {
1548 WMPerformButtonClick(panel->okB);
1553 static void
1554 okButtonCallback(void *self, void *clientData)
1556 CrashPanel *panel = (CrashPanel*)clientData;
1558 panel->done = True;
1562 static void
1563 setCrashAction(void *self, void *clientData)
1565 WMPopUpButton *pop = (WMPopUpButton*)self;
1566 CrashPanel *panel = (CrashPanel*)clientData;
1568 panel->action = WMGetPopUpButtonSelectedItem(pop);
1572 static WMPixmap*
1573 getWindowMakerIconImage(WMScreen *scr)
1575 proplist_t dict, key, option, value=NULL;
1576 WMPixmap *pix=NULL;
1577 char *path;
1579 PLSetStringCmpHook(NULL);
1581 key = PLMakeString("Logo.WMPanel");
1582 option = PLMakeString("Icon");
1584 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
1586 if (dict) {
1587 value = PLGetDictionaryEntry(dict, option);
1590 PLRelease(key);
1591 PLRelease(option);
1593 PLSetStringCmpHook(StringCompareHook);
1595 if (value && PLIsString(value)) {
1596 path = FindImage(wPreferences.icon_path, PLGetString(value));
1598 if (path) {
1599 RColor gray;
1601 gray.red = 0xae; gray.green = 0xaa;
1602 gray.blue = 0xae; gray.alpha = 0;
1604 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1605 wfree(path);
1609 return pix;
1613 #define PWIDTH 295
1614 #define PHEIGHT 345
1618 wShowCrashingDialogPanel(int whatSig)
1620 CrashPanel *panel;
1621 WMScreen *scr;
1622 WMFont *font;
1623 WMPixmap *logo;
1624 int screen_no, scr_width, scr_height;
1625 int action;
1626 char buf[256];
1628 panel = wmalloc(sizeof(CrashPanel));
1629 memset(panel, 0, sizeof(CrashPanel));
1631 screen_no = DefaultScreen(dpy);
1632 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1633 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1635 scr = WMCreateScreen(dpy, screen_no);
1636 if (!scr) {
1637 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1638 return WMAbort;
1641 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1643 panel->win = WMCreateWindow(scr, "crashingDialog");
1644 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1645 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1647 logo = getWindowMakerIconImage(scr);
1648 if (logo) {
1649 panel->iconL = WMCreateLabel(panel->win);
1650 WMResizeWidget(panel->iconL, 64, 64);
1651 WMMoveWidget(panel->iconL, 10, 10);
1652 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1653 WMSetLabelImage(panel->iconL, logo);
1656 panel->nameL = WMCreateLabel(panel->win);
1657 WMResizeWidget(panel->nameL, 190, 18);
1658 WMMoveWidget(panel->nameL, 80, 35);
1659 WMSetLabelTextAlignment(panel->nameL, WALeft);
1660 font = WMBoldSystemFontOfSize(scr, 18);
1661 WMSetLabelFont(panel->nameL, font);
1662 WMReleaseFont(font);
1663 WMSetLabelText(panel->nameL, _("Fatal error"));
1665 panel->sepF = WMCreateFrame(panel->win);
1666 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1667 WMMoveWidget(panel->sepF, -2, 80);
1669 panel->noteL = WMCreateLabel(panel->win);
1670 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1671 WMMoveWidget(panel->noteL, 10, 90);
1672 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1673 #ifdef SYS_SIGLIST_DECLARED
1674 sprintf(buf, _("Window Maker received signal %i\n(%s)."),
1675 whatSig, sys_siglist[whatSig]);
1676 #else
1677 sprintf(buf, _("Window Maker received signal %i."), whatSig);
1678 #endif
1679 WMSetLabelText(panel->noteL, buf);
1681 panel->note2L = WMCreateLabel(panel->win);
1682 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1683 WMMoveWidget(panel->note2L, 10, 130);
1684 WMSetLabelTextAlignment(panel->note2L, WALeft);
1685 WMSetLabelText(panel->note2L,
1686 _(" This fatal error occured probably due to a bug."
1687 " Please fill the included BUGFORM and "
1688 "report it to bugs@windowmaker.org."));
1689 WMSetLabelWraps(panel->note2L, True);
1692 panel->whatF = WMCreateFrame(panel->win);
1693 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1694 WMMoveWidget(panel->whatF, 10, 240);
1695 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1697 panel->whatP = WMCreatePopUpButton(panel->whatF);
1698 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1699 WMMoveWidget(panel->whatP, 35, 20);
1700 WMSetPopUpButtonPullsDown(panel->whatP, False);
1701 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1702 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1703 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1704 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1705 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1706 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1707 panel->action = WMRestart;
1709 WMMapSubwidgets(panel->whatF);
1711 panel->okB = WMCreateCommandButton(panel->win);
1712 WMResizeWidget(panel->okB, 80, 26);
1713 WMMoveWidget(panel->okB, 205, 309);
1714 WMSetButtonText(panel->okB, _("OK"));
1715 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1716 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1717 WMSetButtonImagePosition(panel->okB, WIPRight);
1718 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1720 panel->done = 0;
1722 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1723 handleKeyPress, panel);
1725 WMRealizeWidget(panel->win);
1726 WMMapSubwidgets(panel->win);
1728 WMMapWidget(panel->win);
1730 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1732 while (!panel->done) {
1733 XEvent event;
1735 WMNextEvent(dpy, &event);
1736 WMHandleEvent(&event);
1739 action = panel->action;
1741 WMUnmapWidget(panel->win);
1742 WMDestroyWidget(panel->win);
1743 wfree(panel);
1745 return action;
1751 /*****************************************************************************
1752 * About GNUstep Panel
1753 *****************************************************************************/
1756 static void
1757 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1758 unsigned long blackPixel, unsigned long whitePixel)
1760 GC gc;
1761 XGCValues gcv;
1762 XRectangle rects[3];
1764 gcv.foreground = blackPixel;
1765 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1767 XFillArc(dpy, d, gc, width/45, height/45,
1768 width - 2*width/45, height - 2*height/45, 0, 360*64);
1770 rects[0].x = 0;
1771 rects[0].y = 37*height/45;
1772 rects[0].width = width/3;
1773 rects[0].height = height - rects[0].y;
1775 rects[1].x = rects[0].width;
1776 rects[1].y = height/2;
1777 rects[1].width = width - 2*width/3;
1778 rects[1].height = height - rects[1].y;
1780 rects[2].x = 2*width/3;
1781 rects[2].y = height - 37*height/45;
1782 rects[2].width = width/3;
1783 rects[2].height = height - rects[2].y;
1785 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1786 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1788 XSetForeground(dpy, gc, whitePixel);
1789 XFillArc(dpy, d, gc, width/45, height/45,
1790 width - 2*width/45, height - 2*height/45, 0, 360*64);
1792 XFreeGC(dpy, gc);
1796 typedef struct {
1797 WScreen *scr;
1799 WWindow *wwin;
1801 WMWindow *win;
1803 WMLabel *gstepL;
1804 WMLabel *textL;
1805 } GNUstepPanel;
1808 static GNUstepPanel *gnustepPanel = NULL;
1810 static void
1811 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1813 WMUnmapWidget(gnustepPanel->win);
1815 WMDestroyWidget(gnustepPanel->win);
1817 wUnmanageWindow(gnustepPanel->wwin, False, False);
1819 wfree(gnustepPanel);
1821 gnustepPanel = NULL;
1825 void
1826 wShowGNUstepPanel(WScreen *scr)
1828 GNUstepPanel *panel;
1829 Window parent;
1830 WWindow *wwin;
1831 WMPixmap *pixmap;
1832 WMColor *color;
1834 if (gnustepPanel) {
1835 if (gnustepPanel->scr == scr) {
1836 wRaiseFrame(gnustepPanel->wwin->frame->core);
1837 wSetFocusTo(scr, gnustepPanel->wwin);
1839 return;
1842 panel = wmalloc(sizeof(GNUstepPanel));
1844 panel->scr = scr;
1846 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1847 WMResizeWidget(panel->win, 325, 200);
1849 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1850 WMScreenDepth(scr->wmscreen), True);
1852 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1854 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1855 WMColorPixel(color), scr->white_pixel);
1857 WMReleaseColor(color);
1859 XSetForeground(dpy, scr->mono_gc, 0);
1860 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1861 130, 130);
1862 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1864 panel->gstepL = WMCreateLabel(panel->win);
1865 WMResizeWidget(panel->gstepL, 285, 64);
1866 WMMoveWidget(panel->gstepL, 20, 0);
1867 WMSetLabelTextAlignment(panel->gstepL, WARight);
1868 WMSetLabelText(panel->gstepL, "GNUstep");
1870 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1872 WMSetLabelFont(panel->gstepL, font);
1873 WMReleaseFont(font);
1876 panel->textL = WMCreateLabel(panel->win);
1877 WMResizeWidget(panel->textL, 275, 130);
1878 WMMoveWidget(panel->textL, 30, 50);
1879 WMSetLabelTextAlignment(panel->textL, WARight);
1880 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1881 WMSetLabelText(panel->textL,
1882 _("Window Maker is part of the GNUstep project.\n"\
1883 "The GNUstep project aims to create a free\n"\
1884 "implementation of the OpenStep(tm) specification\n"\
1885 "which is a object-oriented framework for\n"\
1886 "creating advanced graphical, multi-platform\n"\
1887 "applications. Additionally, a development and\n"\
1888 "user desktop enviroment will be created on top\n"\
1889 "of the framework. For more information about\n"\
1890 "GNUstep, please visit: www.gnustep.org"));
1891 WMSetLabelImage(panel->textL, pixmap);
1893 WMReleasePixmap(pixmap);
1895 WMRealizeWidget(panel->win);
1896 WMMapSubwidgets(panel->win);
1898 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1900 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1902 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1903 (scr->scr_width - 325)/2,
1904 (scr->scr_height - 200)/2, 325, 200);
1906 WSETUFLAG(wwin, no_closable, 0);
1907 WSETUFLAG(wwin, no_close_button, 0);
1908 wWindowUpdateButtonImages(wwin);
1909 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1910 #ifdef XKB_BUTTON_HINT
1911 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1912 #endif
1913 wwin->frame->on_click_right = destroyGNUstepPanel;
1915 panel->wwin = wwin;
1917 WMMapWidget(panel->win);
1919 wWindowMap(wwin);
1921 gnustepPanel = panel;