- Fixed some non-portable shell constructs used in installed scripts
[wmaker-crm.git] / src / dialog.c
blob07e806b9d459756d97f2e725f6dcdf7bf9c10083
1 /* dialog.c - dialog windows for internal use
3 * Window Maker window manager
5 * Copyright (c) 1997, 1998 Alfredo K. Kojima
6 * Copyright (c) 1999 Dan Pascu
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 color;
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 if ((state & WLDSSelected) != 0) {
389 color.red = color.green = color.blue = 0xff;
390 color.alpha = 0;
391 } else {
392 color.red = color.blue = 0xae;
393 color.green = 0xaa; color.alpha = 0;
395 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
396 wfree(file);
398 if (!pixmap) {
399 WMRemoveListItem(lPtr, index);
400 return;
403 XClearArea(dpy, d, rect->pos.x, rect->pos.y, width, rect->size.height,
404 False);
405 XSetClipMask(dpy, gc, None);
407 XDrawRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x + 5,
408 rect->pos.y +5, width - 10, 54);
410 XDrawLine(dpy, d, WMColorGC(whitecolor), rect->pos.x,
411 rect->pos.y+rect->size.height-1, rect->pos.x+width,
412 rect->pos.y+rect->size.height-1);
415 if (state&WLDSSelected) {
416 XFillRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x,
417 rect->pos.y, width, rect->size.height);
420 size = WMGetPixmapSize(pixmap);
422 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
423 XSetClipOrigin(dpy, copygc, rect->pos.x + (width-size.width)/2,
424 rect->pos.y+2);
425 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
426 size.width>100?100:size.width, size.height>64?64:size.height,
427 rect->pos.x + (width-size.width)/2, rect->pos.y+2);
430 int i,j;
431 int fheight = WMFontHeight(panel->normalfont);
432 int tlen = strlen(text);
433 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
434 int ofx, ofy;
436 ofx = rect->pos.x + (width - twidth)/2;
437 ofy = rect->pos.y + 64 - fheight;
439 for(i=-1;i<2;i++)
440 for(j=-1;j<2;j++)
441 WMDrawString(wmscr, d, WMColorGC(whitecolor),
442 panel->normalfont, ofx+i, ofy+j,
443 text, tlen);
445 WMDrawString(wmscr, d, WMColorGC(blackcolor), panel->normalfont,
446 ofx, ofy, text, tlen);
449 WMReleasePixmap(pixmap);
450 /* I hope it is better to do not use cache / on my box it is fast nuff */
451 XFlush(dpy);
453 WMReleaseColor(blackcolor);
454 WMReleaseColor(whitecolor);
458 static void
459 buttonCallback(void *self, void *clientData)
461 WMButton *bPtr = (WMButton*)self;
462 IconPanel *panel = (IconPanel*)clientData;
465 if (bPtr==panel->okButton) {
466 panel->done = True;
467 panel->result = True;
468 } else if (bPtr==panel->cancelButton) {
469 panel->done = True;
470 panel->result = False;
471 } else if (bPtr==panel->previewButton) {
472 /**** Previewer ****/
473 WMSetButtonEnabled(bPtr, False);
474 WMSetListUserDrawItemHeight(panel->iconList, 68);
475 WMSetListUserDrawProc(panel->iconList, drawIconProc);
476 WMRedisplayWidget(panel->iconList);
477 /* for draw proc to access screen/gc */
478 /*** end preview ***/
480 #if 0
481 else if (bPtr==panel->chooseButton) {
482 WMOpenPanel *op;
484 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
486 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
487 char *path;
488 path = WMGetFilePanelFile(op);
489 WMSetTextFieldText(panel->fileField, path);
490 setViewedImage(panel, path);
491 wfree(path);
493 WMDestroyFilePanel(op);
495 #endif
499 static void
500 keyPressHandler(XEvent *event, void *data)
502 IconPanel *panel = (IconPanel*)data;
503 Display *dpy = event->xany.display;
504 char buffer[32];
505 int count;
506 KeySym ksym;
507 int iidx;
508 int didx;
509 int item;
510 WMList *list = NULL;
512 if (event->type == KeyRelease)
513 return;
515 buffer[0] = 0;
516 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
519 iidx = WMGetListSelectedItemRow(panel->iconList);
520 didx = WMGetListSelectedItemRow(panel->dirList);
522 switch (ksym) {
523 case XK_Up:
524 if (iidx > 0)
525 item = iidx-1;
526 else
527 item = iidx;
528 list = panel->iconList;
529 break;
530 case XK_Down:
531 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
532 item = iidx+1;
533 else
534 item = iidx;
535 list = panel->iconList;
536 break;
537 case XK_Home:
538 item = 0;
539 list = panel->iconList;
540 break;
541 case XK_End:
542 item = WMGetListNumberOfRows(panel->iconList) - 1;
543 list = panel->iconList;
544 break;
545 case XK_Next:
546 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
547 item = didx + 1;
548 else
549 item = didx;
550 list = panel->dirList;
551 break;
552 case XK_Prior:
553 if (didx > 0)
554 item = didx - 1;
555 else
556 item = 0;
557 list = panel->dirList;
558 break;
559 case XK_Return:
560 WMPerformButtonClick(panel->okButton);
561 break;
562 case XK_Escape:
563 WMPerformButtonClick(panel->cancelButton);
564 break;
567 if (list) {
568 WMSelectListItem(list, item);
569 WMSetListPosition(list, item - 5);
570 listCallback(list, panel);
576 Bool
577 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
579 WWindow *wwin;
580 Window parent;
581 IconPanel *panel;
582 WMColor *color;
583 WMFont *boldFont;
585 panel = wmalloc(sizeof(IconPanel));
586 memset(panel, 0, sizeof(IconPanel));
588 panel->scr = scr;
590 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
591 WMResizeWidget(panel->win, 450, 280);
593 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
594 keyPressHandler, panel);
597 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
598 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
600 panel->dirLabel = WMCreateLabel(panel->win);
601 WMResizeWidget(panel->dirLabel, 200, 20);
602 WMMoveWidget(panel->dirLabel, 10, 7);
603 WMSetLabelText(panel->dirLabel, _("Directories"));
604 WMSetLabelFont(panel->dirLabel, boldFont);
605 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
607 WMSetLabelRelief(panel->dirLabel, WRSunken);
609 panel->iconLabel = WMCreateLabel(panel->win);
610 WMResizeWidget(panel->iconLabel, 140, 20);
611 WMMoveWidget(panel->iconLabel, 215, 7);
612 WMSetLabelText(panel->iconLabel, _("Icons"));
613 WMSetLabelFont(panel->iconLabel, boldFont);
614 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
616 WMReleaseFont(boldFont);
618 color = WMWhiteColor(scr->wmscreen);
619 WMSetLabelTextColor(panel->dirLabel, color);
620 WMSetLabelTextColor(panel->iconLabel, color);
621 WMReleaseColor(color);
623 color = WMDarkGrayColor(scr->wmscreen);
624 WMSetWidgetBackgroundColor(panel->iconLabel, color);
625 WMSetWidgetBackgroundColor(panel->dirLabel, color);
626 WMReleaseColor(color);
628 WMSetLabelRelief(panel->iconLabel, WRSunken);
630 panel->dirList = WMCreateList(panel->win);
631 WMResizeWidget(panel->dirList, 200, 170);
632 WMMoveWidget(panel->dirList, 10, 30);
633 WMSetListAction(panel->dirList, listCallback, panel);
635 panel->iconList = WMCreateList(panel->win);
636 WMResizeWidget(panel->iconList, 140, 170);
637 WMMoveWidget(panel->iconList, 215, 30);
638 WMSetListAction(panel->iconList, listCallback, panel);
640 WMHangData(panel->iconList,panel);
642 panel->previewButton = WMCreateCommandButton(panel->win);
643 WMResizeWidget(panel->previewButton, 75, 26);
644 WMMoveWidget(panel->previewButton, 365, 130);
645 WMSetButtonText(panel->previewButton, _("Preview"));
646 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
648 panel->iconView = WMCreateLabel(panel->win);
649 WMResizeWidget(panel->iconView, 75, 75);
650 WMMoveWidget(panel->iconView, 365, 40);
651 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
652 WMSetLabelRelief(panel->iconView, WRSunken);
653 WMSetLabelTextAlignment(panel->iconView, WACenter);
655 panel->fileLabel = WMCreateLabel(panel->win);
656 WMResizeWidget(panel->fileLabel, 80, 20);
657 WMMoveWidget(panel->fileLabel, 10, 210);
658 WMSetLabelText(panel->fileLabel, _("File Name:"));
660 panel->fileField = WMCreateTextField(panel->win);
661 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
662 WMResizeWidget(panel->fileField, 345, 20);
663 WMMoveWidget(panel->fileField, 95, 210);
664 WMSetTextFieldEditable(panel->fileField, False);
666 panel->okButton = WMCreateCommandButton(panel->win);
667 WMResizeWidget(panel->okButton, 80, 26);
668 WMMoveWidget(panel->okButton, 360, 240);
669 WMSetButtonText(panel->okButton, _("OK"));
670 WMSetButtonEnabled(panel->okButton, False);
671 WMSetButtonAction(panel->okButton, buttonCallback, panel);
673 panel->cancelButton = WMCreateCommandButton(panel->win);
674 WMResizeWidget(panel->cancelButton, 80, 26);
675 WMMoveWidget(panel->cancelButton, 270, 240);
676 WMSetButtonText(panel->cancelButton, _("Cancel"));
677 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
678 #if 0
679 panel->chooseButton = WMCreateCommandButton(panel->win);
680 WMResizeWidget(panel->chooseButton, 110, 26);
681 WMMoveWidget(panel->chooseButton, 150, 240);
682 WMSetButtonText(panel->chooseButton, _("Choose File"));
683 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
684 #endif
685 WMRealizeWidget(panel->win);
686 WMMapSubwidgets(panel->win);
688 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
690 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
693 char *tmp;
695 tmp = wmalloc((instance ? strlen(instance) : 0)
696 + (class ? strlen(class) : 0) + 32);
698 if (tmp && (instance || class))
699 sprintf(tmp, "%s [%s.%s]", _("Icon Chooser"), instance, class);
700 else
701 strcpy(tmp, _("Icon Chooser"));
703 wwin = wManageInternalWindow(scr, parent, None, tmp,
704 (scr->scr_width - 450)/2,
705 (scr->scr_height - 280)/2, 450, 280);
706 wfree(tmp);
709 /* put icon paths in the list */
710 listIconPaths(panel->dirList);
712 WMMapWidget(panel->win);
714 wWindowMap(wwin);
716 while (!panel->done) {
717 XEvent event;
719 WMNextEvent(dpy, &event);
720 WMHandleEvent(&event);
723 if (panel->result) {
724 char *defaultPath, *wantedPath;
726 /* check if the file the user selected is not the one that
727 * would be loaded by default with the current search path */
728 *file = WMGetListSelectedItem(panel->iconList)->text;
729 if ((*file)[0]==0) {
730 wfree(*file);
731 *file = NULL;
732 } else {
733 defaultPath = FindImage(wPreferences.icon_path, *file);
734 wantedPath = WMGetTextFieldText(panel->fileField);
735 /* if the file is not the default, use full path */
736 if (strcmp(wantedPath, defaultPath)!=0) {
737 *file = wantedPath;
738 } else {
739 *file = wstrdup(*file);
740 wfree(wantedPath);
742 wfree(defaultPath);
744 } else {
745 *file = NULL;
748 WMReleaseFont(panel->normalfont);
750 WMUnmapWidget(panel->win);
752 WMDestroyWidget(panel->win);
754 wUnmanageWindow(wwin, False, False);
756 wfree(panel);
758 XDestroyWindow(dpy, parent);
760 return panel->result;
765 ***********************************************************************
766 * Info Panel
767 ***********************************************************************
771 typedef struct {
772 WScreen *scr;
774 WWindow *wwin;
776 WMWindow *win;
778 WMLabel *logoL;
779 WMLabel *name1L;
780 WMLabel *name2L;
782 WMLabel *versionL;
784 WMLabel *infoL;
786 WMLabel *copyrL;
788 #ifdef SILLYNESS
789 WMHandlerID timer;
790 int cycle;
791 RImage *icon;
792 RImage *pic;
793 WMPixmap *oldPix;
794 WMFont *oldFont;
795 char *str;
796 int x;
797 #endif
798 } InfoPanel;
802 #define COPYRIGHT_TEXT \
803 "Copyright \xa9 1997~2001 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
804 "Copyright \xa9 1998~2001 Dan Pascu <dan@windowmaker.org>"
808 static InfoPanel *thePanel = NULL;
810 static void
811 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
813 #ifdef SILLYNESS
814 if (thePanel->timer) {
815 WMDeleteTimerHandler(thePanel->timer);
817 if (thePanel->oldPix) {
818 WMReleasePixmap(thePanel->oldPix);
820 if (thePanel->oldFont) {
821 WMReleaseFont(thePanel->oldFont);
823 if (thePanel->icon) {
824 RReleaseImage(thePanel->icon);
826 if (thePanel->pic) {
827 RReleaseImage(thePanel->pic);
829 #endif /* SILLYNESS */
830 WMUnmapWidget(thePanel);
832 wUnmanageWindow(thePanel->wwin, False, False);
834 WMDestroyWidget(thePanel->win);
836 wfree(thePanel);
838 thePanel = NULL;
842 WMPixmap*
843 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
845 WMPixmap *wpix = NULL;
846 Pixmap grad = None;
847 Pixmap mask = None;
848 RContext *rc = WMScreenRContext(scr);
849 XFontStruct *f = NULL;
850 int w, h;
851 GC gc = None;
853 f = XLoadQueryFont(dpy, font);
854 if (!f)
855 return NULL;
857 w = XTextWidth(f, text, strlen(text));
858 h = f->ascent+f->descent;
860 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
861 gc = XCreateGC(dpy, mask, 0, NULL);
862 XSetForeground(dpy, gc, 0);
863 XSetFont(dpy, gc, f->fid);
864 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
866 XSetForeground(dpy, gc, 1);
867 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
868 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
869 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
871 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
873 WMColor *color;
875 color = WMBlackColor(scr);
876 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
877 WMReleaseColor(color);
880 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
882 if (gc)
883 XFreeGC(dpy, gc);
884 XFreeFont(dpy, f);
886 return wpix;
889 #ifdef SILLYNESS
891 extern WMPixmap *DoXThing();
892 extern Bool InitXThing();
894 static void
895 logoPushCallback(void *data)
897 InfoPanel *panel = (InfoPanel*)data;
898 char buffer[512];
899 int i;
900 static int oldi = 0;
901 int len;
902 static int jingobeu[] = {
903 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
904 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
905 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
907 static int c = 0;
909 if (panel->x) {
910 XKeyboardControl kc;
912 if (panel->x > 0) {
913 if(jingobeu[panel->x-1]==0){panel->x=-1;}else if(jingobeu[panel->x
914 -1]<0){panel->x++;c=jingobeu[panel->x-1]/50;panel->x++;}else if(c==0){
915 kc.bell_pitch=jingobeu[panel->x-1];panel->x++;kc.bell_percent=50;c=
916 jingobeu[panel->x-1]/50;kc.bell_duration=jingobeu[panel->x-1];panel->x++;
917 XChangeKeyboardControl(dpy,KBBellPitch|KBBellDuration|KBBellPercent,&kc);
918 XBell(dpy,50);XFlush(dpy);}else{c--;}}
919 if (!(panel->cycle % 4)) {
920 WMPixmap *p;
922 p = DoXThing(panel->wwin);
923 WMSetLabelImage(panel->logoL, p);
925 } else if (panel->cycle < 30) {
926 RImage *image;
927 WMPixmap *pix;
928 RColor gray;
930 gray.red = 0xae; gray.green = 0xaa;
931 gray.blue = 0xae; gray.alpha = 0;
933 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
934 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
935 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
936 RReleaseImage(image);
937 WMSetLabelImage(panel->logoL, pix);
938 WMReleasePixmap(pix);
941 /* slow down text a little */
942 i = (int)(panel->cycle * 50.0/85.0)%200;
944 if (i != oldi) {
945 len = strlen(panel->str);
947 strncpy(buffer, panel->str, i<len ? i : len);
948 if (i >= len)
949 memset(&buffer[len], ' ', i-len);
951 strncpy(buffer, panel->str, i<len ? i : len);
952 if (i >= len)
953 memset(&buffer[len], ' ', i-len);
954 buffer[i]=0;
956 WMSetLabelText(panel->versionL, buffer);
958 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
960 oldi = i;
963 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
964 panel->cycle++;
968 static void
969 handleLogoPush(XEvent *event, void *data)
971 InfoPanel *panel = (InfoPanel*)data;
972 static int broken = 0;
973 static int clicks = 0;
974 static char *pic_data[] = {
975 "45 45 57 1",
976 " c None",
977 ". c #000000",
978 "X c #383C00",
979 "o c #515500",
980 "O c #616100",
981 "+ c #616900",
982 "@ c #696D00",
983 "# c #697100",
984 "$ c #495100",
985 "% c #202800",
986 "& c #969600",
987 "* c #CFCF00",
988 "= c #D7DB00",
989 "- c #D7D700",
990 "; c #C7CB00",
991 ": c #A6AA00",
992 "> c #494900",
993 ", c #8E8E00",
994 "< c #DFE700",
995 "1 c #F7FF00",
996 "2 c #FFFF00",
997 "3 c #E7EB00",
998 "4 c #B6B600",
999 "5 c #595900",
1000 "6 c #717500",
1001 "7 c #AEB200",
1002 "8 c #CFD300",
1003 "9 c #E7EF00",
1004 "0 c #EFF300",
1005 "q c #9EA200",
1006 "w c #F7FB00",
1007 "e c #F7F700",
1008 "r c #BEBE00",
1009 "t c #8E9200",
1010 "y c #EFF700",
1011 "u c #969A00",
1012 "i c #414500",
1013 "p c #595D00",
1014 "a c #E7E700",
1015 "s c #C7C700",
1016 "d c #797D00",
1017 "f c #BEC300",
1018 "g c #DFE300",
1019 "h c #868600",
1020 "j c #EFEF00",
1021 "k c #9E9E00",
1022 "l c #616500",
1023 "z c #DFDF00",
1024 "x c #868A00",
1025 "c c #969200",
1026 "v c #B6BA00",
1027 "b c #A6A600",
1028 "n c #8E8A00",
1029 "m c #717100",
1030 "M c #AEAE00",
1031 "N c #AEAA00",
1032 "B c #868200",
1033 " ............... ",
1034 " ....XoO+@##+O$%.... ",
1035 " ...%X&*========-;;:o... ",
1036 " ...>.>,<122222222222134@... ",
1037 " ..>5678912222222222222220q%.. ",
1038 " ..$.&-w2222222222222222222er>.. ",
1039 " ..O.t31222222222222222222222y4>.. ",
1040 " ...O5u3222222222222222222222222yri... ",
1041 " ..>p&a22222222222222222222222222wso.. ",
1042 " ..ids91222222222222222222222222222wfi.. ",
1043 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1044 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1045 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1046 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1047 "..io*222222222&...u22222222yt..%*22222220:%. ",
1048 "..>k02222222227...f222222222v..X=222222229t. ",
1049 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1050 ".%vw222222222221y2222222222219*y2222222222wd.",
1051 ".X;2222222222222222222222222222222222222222b.",
1052 ".i*2222222222222222222222222222222222222222v.",
1053 ".i*2222222222222222222222222222222222222222;.",
1054 ".i*22222222222222222222222222222222222222228.",
1055 ".>*2222222222222222222222222222222222222222=.",
1056 ".i*22222222222222222222222222222222222222228.",
1057 ".i*2222222222222222222222222222222222222222;.",
1058 ".X*222222222222222222222222222222we12222222r.",
1059 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1060 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1061 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1062 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1063 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1064 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1065 " ...:e2222218mdz22222222222222a&$vw222220@...",
1066 " ...O-122222y:.u02222222222229q$uj222221r... ",
1067 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1068 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1069 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1070 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1071 " ..Xb9122222109g-****;<y22221zn%... ",
1072 " ..X&801222222222222222222w-h.... ",
1073 " ...o:=022222222222222221=lX... ",
1074 " ..X@:;3w2222222222210fO... ",
1075 " ...XX&v8<30000003-N@... ",
1076 " .....XmnbN:q&Bo.... ",
1077 " ............ "
1079 static char *msgs[] = {
1080 "Have a nice day!",
1081 "Focus follow mouse users will burn in hell!!!",
1082 "Mooo Canada!!!!",
1083 "Hi! My name is bobby...",
1084 "AHH! The neurotic monkeys are after me!",
1085 "WHAT YOU SAY??",
1086 "WE GET SIGNAL",
1087 "SOMEBODY SET UP US THE BOMB",
1088 "ALL YOUR BASE ARE BELONG TO US!",
1089 "Oh My God!!! Larry is back!",
1090 "Hey! What happened with these messages?!?"
1094 clicks++;
1096 if (!panel->timer && !broken && clicks > 0) {
1097 WMFont *font;
1099 panel->x = 0;
1100 clicks = 0;
1101 if (!panel->icon) {
1102 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1103 if (!panel->icon) {
1104 broken = 1;
1105 return;
1106 } else {
1107 RColor color;
1109 color.red = 0xae; color.green = 0xaa;
1110 color.blue = 0xae; color.alpha = 0;
1112 panel->icon = RCloneImage(panel->icon);
1113 RCombineImageWithColor(panel->icon, &color);
1116 if (!panel->pic) {
1117 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1118 if (!panel->pic) {
1119 broken = 1;
1120 RReleaseImage(panel->icon);
1121 panel->icon = NULL;
1122 return;
1126 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1128 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1129 panel->cycle = 0;
1130 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1131 /* If we don't use a fixed font, scrolling will be jumpy */
1132 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1133 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1134 WMRetainFont(panel->oldFont);
1135 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1136 if (font) {
1137 WMSetLabelFont(panel->versionL, font);
1138 WMReleaseFont(font);
1140 WMSetLabelText(panel->versionL, "");
1141 } else if (panel->timer) {
1142 char version[20];
1144 panel->x = 0;
1145 clicks = 0;
1146 WMSetLabelImage(panel->logoL, panel->oldPix);
1147 WMReleasePixmap(panel->oldPix);
1148 panel->oldPix = NULL;
1150 WMDeleteTimerHandler(panel->timer);
1151 panel->timer = NULL;
1153 WMSetLabelFont(panel->versionL, panel->oldFont);
1154 if (panel->oldFont) {
1155 WMReleaseFont(panel->oldFont);
1156 panel->oldFont = NULL;
1158 sprintf(version, _("Version %s"), VERSION);
1159 WMSetLabelText(panel->versionL, version);
1160 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1164 XEvent ev;
1165 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1166 ButtonPress, &ev));
1169 #endif /* SILLYNESS */
1172 void
1173 wShowInfoPanel(WScreen *scr)
1175 InfoPanel *panel;
1176 WMPixmap *logo;
1177 WMSize size;
1178 WMFont *font;
1179 char version[32];
1180 char buffer[512];
1181 Window parent;
1182 WWindow *wwin;
1183 RColor color1, color2;
1184 char **strl;
1185 int i;
1186 char *visuals[] = {
1187 "StaticGray",
1188 "GrayScale",
1189 "StaticColor",
1190 "PseudoColor",
1191 "TrueColor",
1192 "DirectColor"
1196 if (thePanel) {
1197 if (thePanel->scr == scr) {
1198 wRaiseFrame(thePanel->wwin->frame->core);
1199 wSetFocusTo(scr, thePanel->wwin);
1201 return;
1204 panel = wmalloc(sizeof(InfoPanel));
1205 memset(panel, 0, sizeof(InfoPanel));
1207 panel->scr = scr;
1209 panel->win = WMCreateWindow(scr->wmscreen, "info");
1210 WMResizeWidget(panel->win, 382, 230);
1212 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1213 if (!logo) {
1214 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1216 if (logo) {
1217 size = WMGetPixmapSize(logo);
1218 panel->logoL = WMCreateLabel(panel->win);
1219 WMResizeWidget(panel->logoL, 64, 64);
1220 WMMoveWidget(panel->logoL, 30, 20);
1221 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1222 WMSetLabelImage(panel->logoL, logo);
1223 #ifdef SILLYNESS
1224 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1225 handleLogoPush, panel);
1226 #endif
1227 WMReleasePixmap(logo);
1230 panel->name1L = WMCreateLabel(panel->win);
1231 WMResizeWidget(panel->name1L, 240, 30);
1232 WMMoveWidget(panel->name1L, 100, 30);
1233 color1.red = 0;
1234 color1.green = 0;
1235 color1.blue = 0;
1236 color2.red = 0x50;
1237 color2.green = 0x50;
1238 color2.blue = 0x70;
1239 logo = renderText(scr->wmscreen, "GNU Window Maker",
1240 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1241 if (logo) {
1242 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1243 WMSetLabelImage(panel->name1L, logo);
1244 WMReleasePixmap(logo);
1245 } else {
1246 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1247 if (font) {
1248 WMSetLabelFont(panel->name1L, font);
1249 WMReleaseFont(font);
1251 WMSetLabelTextAlignment(panel->name1L, WACenter);
1252 WMSetLabelText(panel->name1L, "GNU Window Maker");
1255 panel->name2L = WMCreateLabel(panel->win);
1256 WMResizeWidget(panel->name2L, 240, 24);
1257 WMMoveWidget(panel->name2L, 100, 60);
1258 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1259 if (font) {
1260 WMSetLabelFont(panel->name2L, font);
1261 WMReleaseFont(font);
1262 font = NULL;
1264 WMSetLabelTextAlignment(panel->name2L, WACenter);
1265 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1268 sprintf(version, _("Version %s"), VERSION);
1269 panel->versionL = WMCreateLabel(panel->win);
1270 WMResizeWidget(panel->versionL, 310, 16);
1271 WMMoveWidget(panel->versionL, 30, 95);
1272 WMSetLabelTextAlignment(panel->versionL, WARight);
1273 WMSetLabelText(panel->versionL, version);
1274 WMSetLabelWraps(panel->versionL, False);
1276 panel->copyrL = WMCreateLabel(panel->win);
1277 WMResizeWidget(panel->copyrL, 340, 40);
1278 WMMoveWidget(panel->copyrL, 15, 185);
1279 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1280 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1281 /* we want the (c) character in the helvetica font */
1282 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1283 if (font) {
1284 WMSetLabelFont(panel->copyrL, font);
1287 switch (scr->w_depth) {
1288 case 15:
1289 strcpy(version, _("32 thousand"));
1290 break;
1291 case 16:
1292 strcpy(version, _("64 thousand"));
1293 break;
1294 case 24:
1295 case 32:
1296 strcpy(version, _("16 million"));
1297 break;
1298 default:
1299 sprintf(version, "%d", 1<<scr->w_depth);
1300 break;
1303 sprintf(buffer, _("Using visual 0x%x: %s %ibpp (%s colors)\n"),
1304 (unsigned)scr->w_visual->visualid,
1305 visuals[scr->w_visual->class], scr->w_depth, version);
1307 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1309 struct mallinfo ma = mallinfo();
1310 sprintf(buffer+strlen(buffer),
1311 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1312 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1315 #endif
1317 strcat(buffer, _("Supported image formats: "));
1318 strl = RSupportedFileFormats();
1319 for (i=0; strl[i]!=NULL; i++) {
1320 strcat(buffer, strl[i]);
1321 strcat(buffer, " ");
1324 strcat(buffer, _("\nAdditional support for: "));
1326 char *list[8];
1327 char buf[80];
1328 int j = 0;
1330 #ifdef MWM_HINTS
1331 list[j++] = "MWM";
1332 #endif
1333 #ifdef KWM_HINTS
1334 list[j++] = "KDE";
1335 #endif
1336 #ifdef GNOME_STUFF
1337 list[j++] = "GNOME";
1338 #endif
1339 #ifdef OLWM_HINTS
1340 list[j++] = "OLWM";
1341 #endif
1343 buf[0] = 0;
1344 for (i = 0; i < j; i++) {
1345 if (i > 0) {
1346 if (i == j - 1)
1347 strcat(buf, _(" and "));
1348 else
1349 strcat(buf, ", ");
1351 strcat(buf, list[i]);
1353 strcat(buffer, buf);
1356 if (wPreferences.no_sound) {
1357 strcat(buffer, _("\nSound disabled"));
1358 } else {
1359 strcat(buffer, _("\nSound enabled"));
1363 panel->infoL = WMCreateLabel(panel->win);
1364 WMResizeWidget(panel->infoL, 350, 75);
1365 WMMoveWidget(panel->infoL, 15, 115);
1366 WMSetLabelText(panel->infoL, buffer);
1367 if (font) {
1368 WMSetLabelFont(panel->infoL, font);
1369 WMReleaseFont(font);
1373 WMRealizeWidget(panel->win);
1374 WMMapSubwidgets(panel->win);
1376 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1378 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1380 WMMapWidget(panel->win);
1382 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1383 (scr->scr_width - 382)/2,
1384 (scr->scr_height - 230)/2, 382, 230);
1386 WSETUFLAG(wwin, no_closable, 0);
1387 WSETUFLAG(wwin, no_close_button, 0);
1388 #ifdef XKB_BUTTON_HINT
1389 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1390 #endif
1391 wWindowUpdateButtonImages(wwin);
1392 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1393 wwin->frame->on_click_right = destroyInfoPanel;
1395 wWindowMap(wwin);
1397 panel->wwin = wwin;
1399 thePanel = panel;
1400 #ifdef SILLYNESS
1401 if (InitXThing(panel->scr)) {
1402 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1403 panel->cycle = 0;
1404 panel->x = 1;
1405 panel->str = _("Merry X'mas!");
1406 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1408 #endif
1413 ***********************************************************************
1414 * Legal Panel
1415 ***********************************************************************
1418 typedef struct {
1419 WScreen *scr;
1421 WWindow *wwin;
1423 WMWindow *win;
1425 WMLabel *licenseL;
1426 } LegalPanel;
1429 static LegalPanel *legalPanel = NULL;
1431 static void
1432 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1434 WMUnmapWidget(legalPanel->win);
1436 WMDestroyWidget(legalPanel->win);
1438 wUnmanageWindow(legalPanel->wwin, False, False);
1440 wfree(legalPanel);
1442 legalPanel = NULL;
1446 void
1447 wShowLegalPanel(WScreen *scr)
1449 LegalPanel *panel;
1450 Window parent;
1451 WWindow *wwin;
1453 if (legalPanel) {
1454 if (legalPanel->scr == scr) {
1455 wRaiseFrame(legalPanel->wwin->frame->core);
1456 wSetFocusTo(scr, legalPanel->wwin);
1458 return;
1461 panel = wmalloc(sizeof(LegalPanel));
1463 panel->scr = scr;
1465 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1466 WMResizeWidget(panel->win, 420, 250);
1469 panel->licenseL = WMCreateLabel(panel->win);
1470 WMSetLabelWraps(panel->licenseL, True);
1471 WMResizeWidget(panel->licenseL, 400, 230);
1472 WMMoveWidget(panel->licenseL, 10, 10);
1473 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1474 WMSetLabelText(panel->licenseL,
1475 _(" Window Maker is free software; you can redistribute it and/or\n"
1476 "modify it under the terms of the GNU General Public License as\n"
1477 "published by the Free Software Foundation; either version 2 of the\n"
1478 "License, or (at your option) any later version.\n\n\n"
1479 " Window Maker is distributed in the hope that it will be useful,\n"
1480 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1481 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1482 "See the GNU General Public License for more details.\n\n\n"
1483 " You should have received a copy of the GNU General Public\n"
1484 "License along with this program; if not, write to the Free Software\n"
1485 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1486 "02111-1307, USA."));
1487 WMSetLabelRelief(panel->licenseL, WRGroove);
1489 WMRealizeWidget(panel->win);
1490 WMMapSubwidgets(panel->win);
1492 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1494 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1496 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1497 (scr->scr_width - 420)/2,
1498 (scr->scr_height - 250)/2, 420, 250);
1500 WSETUFLAG(wwin, no_closable, 0);
1501 WSETUFLAG(wwin, no_close_button, 0);
1502 wWindowUpdateButtonImages(wwin);
1503 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1504 #ifdef XKB_BUTTON_HINT
1505 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1506 #endif
1507 wwin->frame->on_click_right = destroyLegalPanel;
1509 panel->wwin = wwin;
1511 WMMapWidget(panel->win);
1513 wWindowMap(wwin);
1515 legalPanel = panel;
1520 ***********************************************************************
1521 * Crashing Dialog Panel
1522 ***********************************************************************
1525 extern WDDomain *WDWindowAttributes;
1528 typedef struct _CrashPanel {
1529 WMWindow *win; /* main window */
1531 WMLabel *iconL; /* application icon */
1532 WMLabel *nameL; /* title of panel */
1534 WMFrame *sepF; /* separator frame */
1536 WMLabel *noteL; /* Title of note */
1537 WMLabel *note2L; /* body of note with what happened */
1539 WMFrame *whatF; /* "what to do next" frame */
1540 WMPopUpButton *whatP; /* action selection popup button */
1542 WMButton *okB; /* ok button */
1544 Bool done; /* if finished with this dialog */
1545 int action; /* what to do after */
1547 KeyCode retKey;
1549 } CrashPanel;
1552 static void
1553 handleKeyPress(XEvent *event, void *clientData)
1555 CrashPanel *panel = (CrashPanel*)clientData;
1557 if (event->xkey.keycode == panel->retKey) {
1558 WMPerformButtonClick(panel->okB);
1563 static void
1564 okButtonCallback(void *self, void *clientData)
1566 CrashPanel *panel = (CrashPanel*)clientData;
1568 panel->done = True;
1572 static void
1573 setCrashAction(void *self, void *clientData)
1575 WMPopUpButton *pop = (WMPopUpButton*)self;
1576 CrashPanel *panel = (CrashPanel*)clientData;
1578 panel->action = WMGetPopUpButtonSelectedItem(pop);
1582 static WMPixmap*
1583 getWindowMakerIconImage(WMScreen *scr)
1585 proplist_t dict, key, option, value=NULL;
1586 WMPixmap *pix=NULL;
1587 char *path;
1589 PLSetStringCmpHook(NULL);
1591 key = PLMakeString("Logo.WMPanel");
1592 option = PLMakeString("Icon");
1594 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
1596 if (dict) {
1597 value = PLGetDictionaryEntry(dict, option);
1600 PLRelease(key);
1601 PLRelease(option);
1603 PLSetStringCmpHook(StringCompareHook);
1605 if (value && PLIsString(value)) {
1606 path = FindImage(wPreferences.icon_path, PLGetString(value));
1608 if (path) {
1609 RColor gray;
1611 gray.red = 0xae; gray.green = 0xaa;
1612 gray.blue = 0xae; gray.alpha = 0;
1614 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
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."));
1699 WMSetLabelWraps(panel->note2L, True);
1702 panel->whatF = WMCreateFrame(panel->win);
1703 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1704 WMMoveWidget(panel->whatF, 10, 240);
1705 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1707 panel->whatP = WMCreatePopUpButton(panel->whatF);
1708 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1709 WMMoveWidget(panel->whatP, 35, 20);
1710 WMSetPopUpButtonPullsDown(panel->whatP, False);
1711 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1712 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1713 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1714 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1715 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1716 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1717 panel->action = WMRestart;
1719 WMMapSubwidgets(panel->whatF);
1721 panel->okB = WMCreateCommandButton(panel->win);
1722 WMResizeWidget(panel->okB, 80, 26);
1723 WMMoveWidget(panel->okB, 205, 309);
1724 WMSetButtonText(panel->okB, _("OK"));
1725 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1726 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1727 WMSetButtonImagePosition(panel->okB, WIPRight);
1728 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1730 panel->done = 0;
1732 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1733 handleKeyPress, panel);
1735 WMRealizeWidget(panel->win);
1736 WMMapSubwidgets(panel->win);
1738 WMMapWidget(panel->win);
1740 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1742 while (!panel->done) {
1743 XEvent event;
1745 WMNextEvent(dpy, &event);
1746 WMHandleEvent(&event);
1749 action = panel->action;
1751 WMUnmapWidget(panel->win);
1752 WMDestroyWidget(panel->win);
1753 wfree(panel);
1755 return action;
1761 /*****************************************************************************
1762 * About GNUstep Panel
1763 *****************************************************************************/
1766 static void
1767 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1768 unsigned long blackPixel, unsigned long whitePixel)
1770 GC gc;
1771 XGCValues gcv;
1772 XRectangle rects[3];
1774 gcv.foreground = blackPixel;
1775 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1777 XFillArc(dpy, d, gc, width/45, height/45,
1778 width - 2*width/45, height - 2*height/45, 0, 360*64);
1780 rects[0].x = 0;
1781 rects[0].y = 37*height/45;
1782 rects[0].width = width/3;
1783 rects[0].height = height - rects[0].y;
1785 rects[1].x = rects[0].width;
1786 rects[1].y = height/2;
1787 rects[1].width = width - 2*width/3;
1788 rects[1].height = height - rects[1].y;
1790 rects[2].x = 2*width/3;
1791 rects[2].y = height - 37*height/45;
1792 rects[2].width = width/3;
1793 rects[2].height = height - rects[2].y;
1795 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1796 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1798 XSetForeground(dpy, gc, whitePixel);
1799 XFillArc(dpy, d, gc, width/45, height/45,
1800 width - 2*width/45, height - 2*height/45, 0, 360*64);
1802 XFreeGC(dpy, gc);
1806 typedef struct {
1807 WScreen *scr;
1809 WWindow *wwin;
1811 WMWindow *win;
1813 WMLabel *gstepL;
1814 WMLabel *textL;
1815 } GNUstepPanel;
1818 static GNUstepPanel *gnustepPanel = NULL;
1820 static void
1821 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1823 WMUnmapWidget(gnustepPanel->win);
1825 WMDestroyWidget(gnustepPanel->win);
1827 wUnmanageWindow(gnustepPanel->wwin, False, False);
1829 wfree(gnustepPanel);
1831 gnustepPanel = NULL;
1835 void
1836 wShowGNUstepPanel(WScreen *scr)
1838 GNUstepPanel *panel;
1839 Window parent;
1840 WWindow *wwin;
1841 WMPixmap *pixmap;
1842 WMColor *color;
1844 if (gnustepPanel) {
1845 if (gnustepPanel->scr == scr) {
1846 wRaiseFrame(gnustepPanel->wwin->frame->core);
1847 wSetFocusTo(scr, gnustepPanel->wwin);
1849 return;
1852 panel = wmalloc(sizeof(GNUstepPanel));
1854 panel->scr = scr;
1856 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1857 WMResizeWidget(panel->win, 325, 200);
1859 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1860 WMScreenDepth(scr->wmscreen), True);
1862 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1864 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1865 WMColorPixel(color), scr->white_pixel);
1867 WMReleaseColor(color);
1869 XSetForeground(dpy, scr->mono_gc, 0);
1870 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1871 130, 130);
1872 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1874 panel->gstepL = WMCreateLabel(panel->win);
1875 WMResizeWidget(panel->gstepL, 285, 64);
1876 WMMoveWidget(panel->gstepL, 20, 0);
1877 WMSetLabelTextAlignment(panel->gstepL, WARight);
1878 WMSetLabelText(panel->gstepL, "GNUstep");
1880 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1882 WMSetLabelFont(panel->gstepL, font);
1883 WMReleaseFont(font);
1886 panel->textL = WMCreateLabel(panel->win);
1887 WMResizeWidget(panel->textL, 275, 130);
1888 WMMoveWidget(panel->textL, 30, 50);
1889 WMSetLabelTextAlignment(panel->textL, WARight);
1890 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1891 WMSetLabelText(panel->textL,
1892 _("Window Maker is part of the GNUstep project.\n"\
1893 "The GNUstep project aims to create a free\n"\
1894 "implementation of the OpenStep(tm) specification\n"\
1895 "which is a object-oriented framework for\n"\
1896 "creating advanced graphical, multi-platform\n"\
1897 "applications. Additionally, a development and\n"\
1898 "user desktop enviroment will be created on top\n"\
1899 "of the framework. For more information about\n"\
1900 "GNUstep, please visit: www.gnustep.org"));
1901 WMSetLabelImage(panel->textL, pixmap);
1903 WMReleasePixmap(pixmap);
1905 WMRealizeWidget(panel->win);
1906 WMMapSubwidgets(panel->win);
1908 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1910 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1912 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1913 (scr->scr_width - 325)/2,
1914 (scr->scr_height - 200)/2, 325, 200);
1916 WSETUFLAG(wwin, no_closable, 0);
1917 WSETUFLAG(wwin, no_close_button, 0);
1918 wWindowUpdateButtonImages(wwin);
1919 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1920 #ifdef XKB_BUTTON_HINT
1921 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1922 #endif
1923 wwin->frame->on_click_right = destroyGNUstepPanel;
1925 panel->wwin = wwin;
1927 WMMapWidget(panel->win);
1929 wWindowMap(wwin);
1931 gnustepPanel = panel;