Fixed the info panel to work well with icons different in size than the
[wmaker-crm.git] / src / dialog.c
blob2b0de6177c2461318b94e30f5eec42c5afa40b57
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->oldFont) {
812 WMReleaseFont(thePanel->oldFont);
814 if (thePanel->icon) {
815 RDestroyImage(thePanel->icon);
817 if (thePanel->pic) {
818 RDestroyImage(thePanel->pic);
820 #endif /* SILLYNESS */
821 WMUnmapWidget(thePanel);
823 wUnmanageWindow(thePanel->wwin, False, False);
825 WMDestroyWidget(thePanel->win);
827 wfree(thePanel);
829 thePanel = NULL;
833 WMPixmap*
834 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
836 WMPixmap *wpix = NULL;
837 Pixmap grad = None;
838 Pixmap mask = None;
839 RContext *rc = WMScreenRContext(scr);
840 XFontStruct *f = NULL;
841 int w, h;
842 GC gc = None;
844 f = XLoadQueryFont(dpy, font);
845 if (!f)
846 return NULL;
848 w = XTextWidth(f, text, strlen(text));
849 h = f->ascent+f->descent;
851 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
852 gc = XCreateGC(dpy, mask, 0, NULL);
853 XSetForeground(dpy, gc, 0);
854 XSetFont(dpy, gc, f->fid);
855 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
857 XSetForeground(dpy, gc, 1);
858 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
859 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
860 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
862 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
864 WMColor *color;
866 color = WMBlackColor(scr);
867 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
868 WMReleaseColor(color);
871 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
873 if (gc)
874 XFreeGC(dpy, gc);
875 XFreeFont(dpy, f);
877 return wpix;
880 #ifdef SILLYNESS
882 extern WMPixmap *DoXThing();
883 extern Bool InitXThing();
885 static void
886 logoPushCallback(void *data)
888 InfoPanel *panel = (InfoPanel*)data;
889 char buffer[512];
890 int i;
891 static int oldi = 0;
892 int len;
893 static int jingobeu[] = {
894 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
895 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
896 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
898 static int c = 0;
900 if (panel->x) {
901 XKeyboardControl kc;
903 if (panel->x > 0) {
904 if(jingobeu[panel->x-1]==0){panel->x=-1;}else if(jingobeu[panel->x
905 -1]<0){panel->x++;c=jingobeu[panel->x-1]/50;panel->x++;}else if(c==0){
906 kc.bell_pitch=jingobeu[panel->x-1];panel->x++;kc.bell_percent=50;c=
907 jingobeu[panel->x-1]/50;kc.bell_duration=jingobeu[panel->x-1];panel->x++;
908 XChangeKeyboardControl(dpy,KBBellPitch|KBBellDuration|KBBellPercent,&kc);
909 XBell(dpy,50);XFlush(dpy);}else{c--;}}
910 if (!(panel->cycle % 4)) {
911 WMPixmap *p;
913 p = DoXThing(panel->wwin);
914 WMSetLabelImage(panel->logoL, p);
916 } else if (panel->cycle < 30) {
917 RImage *image;
918 WMPixmap *pix;
920 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
921 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
922 pix = WMCreatePixmapFromRImage(panel->scr->wmscreen, image, 128);
923 RDestroyImage(image);
924 WMSetLabelImage(panel->logoL, pix);
925 WMReleasePixmap(pix);
928 /* slow down text a little */
929 i = (int)(panel->cycle * 50.0/85.0)%200;
931 if (i != oldi) {
932 len = strlen(panel->str);
934 strncpy(buffer, panel->str, i<len ? i : len);
935 if (i >= len)
936 memset(&buffer[len], ' ', i-len);
938 strncpy(buffer, panel->str, i<len ? i : len);
939 if (i >= len)
940 memset(&buffer[len], ' ', i-len);
941 buffer[i]=0;
943 WMSetLabelText(panel->versionL, buffer);
945 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
947 oldi = i;
950 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
951 panel->cycle++;
955 static void
956 handleLogoPush(XEvent *event, void *data)
958 InfoPanel *panel = (InfoPanel*)data;
959 static int broken = 0;
960 static int clicks = 0;
961 static char *pic_data[] = {
962 "45 45 57 1",
963 " c None",
964 ". c #000000",
965 "X c #383C00",
966 "o c #515500",
967 "O c #616100",
968 "+ c #616900",
969 "@ c #696D00",
970 "# c #697100",
971 "$ c #495100",
972 "% c #202800",
973 "& c #969600",
974 "* c #CFCF00",
975 "= c #D7DB00",
976 "- c #D7D700",
977 "; c #C7CB00",
978 ": c #A6AA00",
979 "> c #494900",
980 ", c #8E8E00",
981 "< c #DFE700",
982 "1 c #F7FF00",
983 "2 c #FFFF00",
984 "3 c #E7EB00",
985 "4 c #B6B600",
986 "5 c #595900",
987 "6 c #717500",
988 "7 c #AEB200",
989 "8 c #CFD300",
990 "9 c #E7EF00",
991 "0 c #EFF300",
992 "q c #9EA200",
993 "w c #F7FB00",
994 "e c #F7F700",
995 "r c #BEBE00",
996 "t c #8E9200",
997 "y c #EFF700",
998 "u c #969A00",
999 "i c #414500",
1000 "p c #595D00",
1001 "a c #E7E700",
1002 "s c #C7C700",
1003 "d c #797D00",
1004 "f c #BEC300",
1005 "g c #DFE300",
1006 "h c #868600",
1007 "j c #EFEF00",
1008 "k c #9E9E00",
1009 "l c #616500",
1010 "z c #DFDF00",
1011 "x c #868A00",
1012 "c c #969200",
1013 "v c #B6BA00",
1014 "b c #A6A600",
1015 "n c #8E8A00",
1016 "m c #717100",
1017 "M c #AEAE00",
1018 "N c #AEAA00",
1019 "B c #868200",
1020 " ............... ",
1021 " ....XoO+@##+O$%.... ",
1022 " ...%X&*========-;;:o... ",
1023 " ...>.>,<122222222222134@... ",
1024 " ..>5678912222222222222220q%.. ",
1025 " ..$.&-w2222222222222222222er>.. ",
1026 " ..O.t31222222222222222222222y4>.. ",
1027 " ...O5u3222222222222222222222222yri... ",
1028 " ..>p&a22222222222222222222222222wso.. ",
1029 " ..ids91222222222222222222222222222wfi.. ",
1030 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1031 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1032 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1033 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1034 "..io*222222222&...u22222222yt..%*22222220:%. ",
1035 "..>k02222222227...f222222222v..X=222222229t. ",
1036 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1037 ".%vw222222222221y2222222222219*y2222222222wd.",
1038 ".X;2222222222222222222222222222222222222222b.",
1039 ".i*2222222222222222222222222222222222222222v.",
1040 ".i*2222222222222222222222222222222222222222;.",
1041 ".i*22222222222222222222222222222222222222228.",
1042 ".>*2222222222222222222222222222222222222222=.",
1043 ".i*22222222222222222222222222222222222222228.",
1044 ".i*2222222222222222222222222222222222222222;.",
1045 ".X*222222222222222222222222222222we12222222r.",
1046 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1047 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1048 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1049 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1050 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1051 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1052 " ...:e2222218mdz22222222222222a&$vw222220@...",
1053 " ...O-122222y:.u02222222222229q$uj222221r... ",
1054 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1055 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1056 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1057 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1058 " ..Xb9122222109g-****;<y22221zn%... ",
1059 " ..X&801222222222222222222w-h.... ",
1060 " ...o:=022222222222222221=lX... ",
1061 " ..X@:;3w2222222222210fO... ",
1062 " ...XX&v8<30000003-N@... ",
1063 " .....XmnbN:q&Bo.... ",
1064 " ............ "};
1065 static char *msgs[] = {
1066 "Have a nice day!",
1067 "Focus follow mouse users will burn in hell!!!",
1068 "Mooo Canada!!!!",
1069 "Hi! My name is bobby...",
1070 "AHH! The neurotic monkeys are after me!",
1071 "WHAT YOU SAY??",
1072 "WE GET SIGNAL",
1073 "SOMEBODY SET UP US THE BOMB",
1074 "ALL YOUR BASE ARE BELONG TO US!",
1075 "Oh My God!!! Larry is back!"
1079 clicks++;
1081 if (!panel->timer && !broken && clicks > 0) {
1082 WMFont *font;
1083 char *file;
1084 char *path;
1086 panel->x = 0;
1087 clicks = 0;
1088 if (!panel->icon) {
1089 file = wDefaultGetIconFile(panel->scr, "Logo", "WMPanel", False);
1090 if (!file) {
1091 broken = 1;
1092 return;
1095 path = FindImage(wPreferences.icon_path, file);
1096 if (!path) {
1097 broken = 1;
1098 return;
1101 panel->icon = RLoadImage(panel->scr->rcontext, path, 0);
1102 wfree(path);
1103 if (!panel->icon) {
1104 broken = 1;
1105 return;
1108 if (!panel->pic) {
1109 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1110 if (!panel->pic) {
1111 broken = 1;
1112 RDestroyImage(panel->icon);
1113 panel->icon = NULL;
1114 if (panel->pic) {
1115 RDestroyImage(panel->pic);
1116 panel->pic = NULL;
1118 return;
1122 RColor color;
1123 color.red = 0xae;
1124 color.green = 0xaa;
1125 color.blue = 0xae;
1126 color.alpha = 255;
1127 RCombineImageWithColor(panel->icon, &color);
1128 RCombineImageWithColor(panel->pic, &color);
1132 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1134 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1135 panel->cycle = 0;
1136 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1137 /* If we don't use a fixed font, scrolling will be jumpy */
1138 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1139 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1140 WMRetainFont(panel->oldFont);
1141 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1142 if (font) {
1143 WMSetLabelFont(panel->versionL, font);
1144 WMReleaseFont(font);
1146 WMSetLabelText(panel->versionL, "");
1147 } else if (panel->timer) {
1148 char version[20];
1150 panel->x = 0;
1151 clicks = 0;
1152 WMSetLabelImage(panel->logoL, panel->oldPix);
1153 WMReleasePixmap(panel->oldPix);
1154 panel->oldPix = NULL;
1156 WMDeleteTimerHandler(panel->timer);
1157 panel->timer = NULL;
1159 WMSetLabelFont(panel->versionL, panel->oldFont);
1160 if (panel->oldFont) {
1161 WMReleaseFont(panel->oldFont);
1162 panel->oldFont = NULL;
1164 sprintf(version, _("Version %s"), VERSION);
1165 WMSetLabelText(panel->versionL, version);
1166 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1170 XEvent ev;
1171 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1172 ButtonPress, &ev));
1175 #endif /* SILLYNESS */
1178 void
1179 wShowInfoPanel(WScreen *scr)
1181 InfoPanel *panel;
1182 WMPixmap *logo;
1183 WMSize size;
1184 WMFont *font;
1185 char version[32];
1186 char buffer[512];
1187 Window parent;
1188 WWindow *wwin;
1189 RColor color1, color2;
1190 char **strl;
1191 int i;
1192 char *visuals[] = {
1193 "StaticGray",
1194 "GrayScale",
1195 "StaticColor",
1196 "PseudoColor",
1197 "TrueColor",
1198 "DirectColor"
1202 if (thePanel) {
1203 if (thePanel->scr == scr) {
1204 wRaiseFrame(thePanel->wwin->frame->core);
1205 wSetFocusTo(scr, thePanel->wwin);
1207 return;
1210 panel = wmalloc(sizeof(InfoPanel));
1211 memset(panel, 0, sizeof(InfoPanel));
1213 panel->scr = scr;
1215 panel->win = WMCreateWindow(scr->wmscreen, "info");
1216 WMResizeWidget(panel->win, 382, 230);
1218 logo = WMGetApplicationIconImage(scr->wmscreen);
1219 if (logo) {
1220 size = WMGetPixmapSize(logo);
1221 panel->logoL = WMCreateLabel(panel->win);
1222 WMResizeWidget(panel->logoL, 64, 64);
1223 WMMoveWidget(panel->logoL, 30, 20);
1224 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1225 WMSetLabelImage(panel->logoL, logo);
1226 #ifdef SILLYNESS
1227 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1228 handleLogoPush, panel);
1229 #endif
1232 panel->name1L = WMCreateLabel(panel->win);
1233 WMResizeWidget(panel->name1L, 240, 30);
1234 WMMoveWidget(panel->name1L, 100, 30);
1235 color1.red = 0;
1236 color1.green = 0;
1237 color1.blue = 0;
1238 color2.red = 0x50;
1239 color2.green = 0x50;
1240 color2.blue = 0x70;
1241 logo = renderText(scr->wmscreen, "GNU Window Maker",
1242 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1243 if (logo) {
1244 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1245 WMSetLabelImage(panel->name1L, logo);
1246 WMReleasePixmap(logo);
1247 } else {
1248 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1249 if (font) {
1250 WMSetLabelFont(panel->name1L, font);
1251 WMReleaseFont(font);
1253 WMSetLabelTextAlignment(panel->name1L, WACenter);
1254 WMSetLabelText(panel->name1L, "GNU Window Maker");
1257 panel->name2L = WMCreateLabel(panel->win);
1258 WMResizeWidget(panel->name2L, 240, 24);
1259 WMMoveWidget(panel->name2L, 100, 60);
1260 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1261 if (font) {
1262 WMSetLabelFont(panel->name2L, font);
1263 WMReleaseFont(font);
1264 font = NULL;
1266 WMSetLabelTextAlignment(panel->name2L, WACenter);
1267 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1270 sprintf(version, _("Version %s"), VERSION);
1271 panel->versionL = WMCreateLabel(panel->win);
1272 WMResizeWidget(panel->versionL, 310, 16);
1273 WMMoveWidget(panel->versionL, 30, 95);
1274 WMSetLabelTextAlignment(panel->versionL, WARight);
1275 WMSetLabelText(panel->versionL, version);
1276 WMSetLabelWraps(panel->versionL, False);
1278 panel->copyrL = WMCreateLabel(panel->win);
1279 WMResizeWidget(panel->copyrL, 340, 40);
1280 WMMoveWidget(panel->copyrL, 15, 185);
1281 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1282 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1283 /* we want the (c) character in the helvetica font */
1284 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1285 if (font) {
1286 WMSetLabelFont(panel->copyrL, font);
1289 switch (scr->w_depth) {
1290 case 15:
1291 strcpy(version, _("32 thousand"));
1292 break;
1293 case 16:
1294 strcpy(version, _("64 thousand"));
1295 break;
1296 case 24:
1297 case 32:
1298 strcpy(version, _("16 million"));
1299 break;
1300 default:
1301 sprintf(version, "%d", 1<<scr->w_depth);
1302 break;
1305 sprintf(buffer, _("Using visual 0x%x: %s %ibpp (%s colors)\n"),
1306 (unsigned)scr->w_visual->visualid,
1307 visuals[scr->w_visual->class], scr->w_depth, version);
1309 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1311 struct mallinfo ma = mallinfo();
1312 sprintf(buffer+strlen(buffer),
1313 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1314 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1317 #endif
1319 strcat(buffer, _("Supported image formats: "));
1320 strl = RSupportedFileFormats();
1321 for (i=0; strl[i]!=NULL; i++) {
1322 strcat(buffer, strl[i]);
1323 strcat(buffer, " ");
1326 strcat(buffer, _("\nAdditional Support For: "));
1328 char *list[8];
1329 char buf[80];
1330 int j = 0;
1332 #ifdef MWM_HINTS
1333 list[j++] = "MWM";
1334 #endif
1335 #ifdef KWM_HINTS
1336 list[j++] = "KDE";
1337 #endif
1338 #ifdef GNOME_STUFF
1339 list[j++] = "GNOME";
1340 #endif
1341 #ifdef OLWM_HINTS
1342 list[j++] = "OLWM";
1343 #endif
1344 #ifdef WSOUND
1345 list[j++] = _("Sound");
1346 #endif
1348 buf[0] = 0;
1349 for (i = 0; i < j; i++) {
1350 if (i > 0) {
1351 if (i == j - 1)
1352 strcat(buf, _(" and "));
1353 else
1354 strcat(buf, ", ");
1356 strcat(buf, list[i]);
1358 strcat(buffer, buf);
1362 panel->infoL = WMCreateLabel(panel->win);
1363 WMResizeWidget(panel->infoL, 350, 75);
1364 WMMoveWidget(panel->infoL, 15, 115);
1365 WMSetLabelText(panel->infoL, buffer);
1366 if (font) {
1367 WMSetLabelFont(panel->infoL, font);
1368 WMReleaseFont(font);
1372 WMRealizeWidget(panel->win);
1373 WMMapSubwidgets(panel->win);
1375 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1377 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1379 WMMapWidget(panel->win);
1381 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1382 (scr->scr_width - 382)/2,
1383 (scr->scr_height - 230)/2, 382, 230);
1385 WSETUFLAG(wwin, no_closable, 0);
1386 WSETUFLAG(wwin, no_close_button, 0);
1387 #ifdef XKB_BUTTON_HINT
1388 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1389 #endif
1390 wWindowUpdateButtonImages(wwin);
1391 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1392 wwin->frame->on_click_right = destroyInfoPanel;
1394 wWindowMap(wwin);
1396 panel->wwin = wwin;
1398 thePanel = panel;
1399 #ifdef SILLYNESS
1400 if (InitXThing(panel->scr)) {
1401 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1402 panel->cycle = 0;
1403 panel->x = 1;
1404 panel->str = _("Merry X'mas!");
1405 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1407 #endif
1412 ***********************************************************************
1413 * Legal Panel
1414 ***********************************************************************
1417 typedef struct {
1418 WScreen *scr;
1420 WWindow *wwin;
1422 WMWindow *win;
1424 WMLabel *licenseL;
1425 } LegalPanel;
1428 static LegalPanel *legalPanel = NULL;
1430 static void
1431 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1433 WMUnmapWidget(legalPanel->win);
1435 WMDestroyWidget(legalPanel->win);
1437 wUnmanageWindow(legalPanel->wwin, False, False);
1439 wfree(legalPanel);
1441 legalPanel = NULL;
1445 void
1446 wShowLegalPanel(WScreen *scr)
1448 LegalPanel *panel;
1449 Window parent;
1450 WWindow *wwin;
1452 if (legalPanel) {
1453 if (legalPanel->scr == scr) {
1454 wRaiseFrame(legalPanel->wwin->frame->core);
1455 wSetFocusTo(scr, legalPanel->wwin);
1457 return;
1460 panel = wmalloc(sizeof(LegalPanel));
1462 panel->scr = scr;
1464 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1465 WMResizeWidget(panel->win, 420, 250);
1468 panel->licenseL = WMCreateLabel(panel->win);
1469 WMSetLabelWraps(panel->licenseL, True);
1470 WMResizeWidget(panel->licenseL, 400, 230);
1471 WMMoveWidget(panel->licenseL, 10, 10);
1472 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1473 WMSetLabelText(panel->licenseL,
1474 _(" Window Maker is free software; you can redistribute it and/or\n"
1475 "modify it under the terms of the GNU General Public License as\n"
1476 "published by the Free Software Foundation; either version 2 of the\n"
1477 "License, or (at your option) any later version.\n\n\n"
1478 " Window Maker is distributed in the hope that it will be useful,\n"
1479 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1480 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1481 "See the GNU General Public License for more details.\n\n\n"
1482 " You should have received a copy of the GNU General Public\n"
1483 "License along with this program; if not, write to the Free Software\n"
1484 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1485 "02111-1307, USA."));
1486 WMSetLabelRelief(panel->licenseL, WRGroove);
1488 WMRealizeWidget(panel->win);
1489 WMMapSubwidgets(panel->win);
1491 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1493 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1495 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1496 (scr->scr_width - 420)/2,
1497 (scr->scr_height - 250)/2, 420, 250);
1499 WSETUFLAG(wwin, no_closable, 0);
1500 WSETUFLAG(wwin, no_close_button, 0);
1501 wWindowUpdateButtonImages(wwin);
1502 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1503 #ifdef XKB_BUTTON_HINT
1504 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1505 #endif
1506 wwin->frame->on_click_right = destroyLegalPanel;
1508 panel->wwin = wwin;
1510 WMMapWidget(panel->win);
1512 wWindowMap(wwin);
1514 legalPanel = panel;
1519 ***********************************************************************
1520 * Crashing Dialog Panel
1521 ***********************************************************************
1524 extern WDDomain *WDWindowAttributes;
1527 typedef struct _CrashPanel {
1528 WMWindow *win; /* main window */
1530 WMLabel *iconL; /* application icon */
1531 WMLabel *nameL; /* title of panel */
1533 WMFrame *sepF; /* separator frame */
1535 WMLabel *noteL; /* Title of note */
1536 WMLabel *note2L; /* body of note with what happened */
1538 WMFrame *whatF; /* "what to do next" frame */
1539 WMPopUpButton *whatP; /* action selection popup button */
1541 WMButton *okB; /* ok button */
1543 Bool done; /* if finished with this dialog */
1544 int action; /* what to do after */
1546 KeyCode retKey;
1548 } CrashPanel;
1551 static void
1552 handleKeyPress(XEvent *event, void *clientData)
1554 CrashPanel *panel = (CrashPanel*)clientData;
1556 if (event->xkey.keycode == panel->retKey) {
1557 WMPerformButtonClick(panel->okB);
1562 static void
1563 okButtonCallback(void *self, void *clientData)
1565 CrashPanel *panel = (CrashPanel*)clientData;
1567 panel->done = True;
1571 static void
1572 setCrashAction(void *self, void *clientData)
1574 WMPopUpButton *pop = (WMPopUpButton*)self;
1575 CrashPanel *panel = (CrashPanel*)clientData;
1577 panel->action = WMGetPopUpButtonSelectedItem(pop);
1581 static WMPixmap*
1582 getWindowMakerIconImage(WMScreen *scr)
1584 proplist_t dict, key, option, value=NULL;
1585 WMPixmap *pix=NULL;
1586 char *path;
1588 PLSetStringCmpHook(NULL);
1590 key = PLMakeString("Logo.WMPanel");
1591 option = PLMakeString("Icon");
1593 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
1595 if (dict) {
1596 value = PLGetDictionaryEntry(dict, option);
1599 PLRelease(key);
1600 PLRelease(option);
1602 PLSetStringCmpHook(StringCompareHook);
1604 if (value && PLIsString(value)) {
1605 path = FindImage(wPreferences.icon_path, PLGetString(value));
1607 if (path) {
1608 RImage *image;
1610 image = RLoadImage(WMScreenRContext(scr), path, 0);
1611 if (image) {
1612 pix = WMCreatePixmapFromRImage(scr, image, 0);
1613 RDestroyImage(image);
1615 wfree(path);
1619 return pix;
1623 #define PWIDTH 295
1624 #define PHEIGHT 345
1628 wShowCrashingDialogPanel(int whatSig)
1630 CrashPanel *panel;
1631 WMScreen *scr;
1632 WMFont *font;
1633 WMPixmap *logo;
1634 int screen_no, scr_width, scr_height;
1635 int action;
1636 char buf[256];
1638 panel = wmalloc(sizeof(CrashPanel));
1639 memset(panel, 0, sizeof(CrashPanel));
1641 screen_no = DefaultScreen(dpy);
1642 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1643 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1645 scr = WMCreateScreen(dpy, screen_no);
1646 if (!scr) {
1647 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1648 return WMAbort;
1651 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1653 panel->win = WMCreateWindow(scr, "crashingDialog");
1654 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1655 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1657 logo = getWindowMakerIconImage(scr);
1658 if (logo) {
1659 panel->iconL = WMCreateLabel(panel->win);
1660 WMResizeWidget(panel->iconL, 64, 64);
1661 WMMoveWidget(panel->iconL, 10, 10);
1662 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1663 WMSetLabelImage(panel->iconL, logo);
1666 panel->nameL = WMCreateLabel(panel->win);
1667 WMResizeWidget(panel->nameL, 190, 18);
1668 WMMoveWidget(panel->nameL, 80, 35);
1669 WMSetLabelTextAlignment(panel->nameL, WALeft);
1670 font = WMBoldSystemFontOfSize(scr, 18);
1671 WMSetLabelFont(panel->nameL, font);
1672 WMReleaseFont(font);
1673 WMSetLabelText(panel->nameL, _("Fatal error"));
1675 panel->sepF = WMCreateFrame(panel->win);
1676 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1677 WMMoveWidget(panel->sepF, -2, 80);
1679 panel->noteL = WMCreateLabel(panel->win);
1680 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1681 WMMoveWidget(panel->noteL, 10, 90);
1682 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1683 #ifdef SYS_SIGLIST_DECLARED
1684 sprintf(buf, _("Window Maker received signal %i\n(%s)."),
1685 whatSig, sys_siglist[whatSig]);
1686 #else
1687 sprintf(buf, _("Window Maker received signal %i."), whatSig);
1688 #endif
1689 WMSetLabelText(panel->noteL, buf);
1691 panel->note2L = WMCreateLabel(panel->win);
1692 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1693 WMMoveWidget(panel->note2L, 10, 130);
1694 WMSetLabelTextAlignment(panel->note2L, WALeft);
1695 WMSetLabelText(panel->note2L,
1696 _(" This fatal error occured probably due to a bug."
1697 " Please fill the included BUGFORM and "
1698 "report it to bugs@windowmaker.org."));
1701 panel->whatF = WMCreateFrame(panel->win);
1702 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1703 WMMoveWidget(panel->whatF, 10, 240);
1704 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1706 panel->whatP = WMCreatePopUpButton(panel->whatF);
1707 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1708 WMMoveWidget(panel->whatP, 35, 20);
1709 WMSetPopUpButtonPullsDown(panel->whatP, False);
1710 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1711 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1712 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1713 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1714 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1715 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1716 panel->action = WMRestart;
1718 WMMapSubwidgets(panel->whatF);
1720 panel->okB = WMCreateCommandButton(panel->win);
1721 WMResizeWidget(panel->okB, 80, 26);
1722 WMMoveWidget(panel->okB, 205, 309);
1723 WMSetButtonText(panel->okB, _("OK"));
1724 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1725 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1726 WMSetButtonImagePosition(panel->okB, WIPRight);
1727 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1729 panel->done = 0;
1731 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1732 handleKeyPress, panel);
1734 WMRealizeWidget(panel->win);
1735 WMMapSubwidgets(panel->win);
1737 WMMapWidget(panel->win);
1739 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1741 while (!panel->done) {
1742 XEvent event;
1744 WMNextEvent(dpy, &event);
1745 WMHandleEvent(&event);
1748 action = panel->action;
1750 WMUnmapWidget(panel->win);
1751 WMDestroyWidget(panel->win);
1752 wfree(panel);
1754 return action;
1760 /*****************************************************************************
1761 * About GNUstep Panel
1762 *****************************************************************************/
1765 static void
1766 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1767 unsigned long blackPixel, unsigned long whitePixel)
1769 GC gc;
1770 XGCValues gcv;
1771 XRectangle rects[3];
1773 gcv.foreground = blackPixel;
1774 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1776 XFillArc(dpy, d, gc, width/45, height/45,
1777 width - 2*width/45, height - 2*height/45, 0, 360*64);
1779 rects[0].x = 0;
1780 rects[0].y = 37*height/45;
1781 rects[0].width = width/3;
1782 rects[0].height = height - rects[0].y;
1784 rects[1].x = rects[0].width;
1785 rects[1].y = height/2;
1786 rects[1].width = width - 2*width/3;
1787 rects[1].height = height - rects[1].y;
1789 rects[2].x = 2*width/3;
1790 rects[2].y = height - 37*height/45;
1791 rects[2].width = width/3;
1792 rects[2].height = height - rects[2].y;
1794 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1795 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1797 XSetForeground(dpy, gc, whitePixel);
1798 XFillArc(dpy, d, gc, width/45, height/45,
1799 width - 2*width/45, height - 2*height/45, 0, 360*64);
1801 XFreeGC(dpy, gc);
1805 typedef struct {
1806 WScreen *scr;
1808 WWindow *wwin;
1810 WMWindow *win;
1812 WMLabel *gstepL;
1813 WMLabel *textL;
1814 } GNUstepPanel;
1817 static GNUstepPanel *gnustepPanel = NULL;
1819 static void
1820 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1822 WMUnmapWidget(gnustepPanel->win);
1824 WMDestroyWidget(gnustepPanel->win);
1826 wUnmanageWindow(gnustepPanel->wwin, False, False);
1828 wfree(gnustepPanel);
1830 gnustepPanel = NULL;
1834 void
1835 wShowGNUstepPanel(WScreen *scr)
1837 GNUstepPanel *panel;
1838 Window parent;
1839 WWindow *wwin;
1840 WMPixmap *pixmap;
1841 WMColor *color;
1843 if (gnustepPanel) {
1844 if (gnustepPanel->scr == scr) {
1845 wRaiseFrame(gnustepPanel->wwin->frame->core);
1846 wSetFocusTo(scr, gnustepPanel->wwin);
1848 return;
1851 panel = wmalloc(sizeof(GNUstepPanel));
1853 panel->scr = scr;
1855 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1856 WMResizeWidget(panel->win, 325, 200);
1858 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1859 WMScreenDepth(scr->wmscreen), True);
1861 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1863 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1864 WMColorPixel(color), scr->white_pixel);
1866 WMReleaseColor(color);
1868 XSetForeground(dpy, scr->mono_gc, 0);
1869 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1870 130, 130);
1871 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1873 panel->gstepL = WMCreateLabel(panel->win);
1874 WMResizeWidget(panel->gstepL, 285, 64);
1875 WMMoveWidget(panel->gstepL, 20, 0);
1876 WMSetLabelTextAlignment(panel->gstepL, WARight);
1877 WMSetLabelText(panel->gstepL, "GNUstep");
1879 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1881 WMSetLabelFont(panel->gstepL, font);
1882 WMReleaseFont(font);
1885 panel->textL = WMCreateLabel(panel->win);
1886 WMResizeWidget(panel->textL, 275, 130);
1887 WMMoveWidget(panel->textL, 30, 50);
1888 WMSetLabelTextAlignment(panel->textL, WARight);
1889 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1890 WMSetLabelText(panel->textL,
1891 _("Window Maker is part of the GNUstep project.\n"\
1892 "The GNUstep project aims to create a free\n"\
1893 "implementation of the OpenStep(tm) specification\n"\
1894 "which is a object-oriented framework for\n"\
1895 "creating advanced graphical, multi-platform\n"\
1896 "applications. Additionally, a development and\n"\
1897 "user desktop enviroment will be created on top\n"\
1898 "of the framework. For more information about\n"\
1899 "GNUstep, please visit: www.gnustep.org"));
1900 WMSetLabelImage(panel->textL, pixmap);
1902 WMReleasePixmap(pixmap);
1904 WMRealizeWidget(panel->win);
1905 WMMapSubwidgets(panel->win);
1907 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1909 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1911 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1912 (scr->scr_width - 325)/2,
1913 (scr->scr_height - 200)/2, 325, 200);
1915 WSETUFLAG(wwin, no_closable, 0);
1916 WSETUFLAG(wwin, no_close_button, 0);
1917 wWindowUpdateButtonImages(wwin);
1918 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1919 #ifdef XKB_BUTTON_HINT
1920 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1921 #endif
1922 wwin->frame->on_click_right = destroyGNUstepPanel;
1924 panel->wwin = wwin;
1926 WMMapWidget(panel->win);
1928 wWindowMap(wwin);
1930 gnustepPanel = panel;