- Now when Window Maker calls wmsetbg to set the background, it will pass the
[wmaker-crm.git] / src / dialog.c
blob8ff12d911a9469331679e0b24bba59a22a8acd1a
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 = RCloneImage(panel->icon);
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 || panel->icon->width!=panel->pic->width
1111 || panel->icon->height!=panel->pic->height) {
1112 broken = 1;
1113 RDestroyImage(panel->icon);
1114 panel->icon = NULL;
1115 if (panel->pic) {
1116 RDestroyImage(panel->pic);
1117 panel->pic = NULL;
1119 return;
1123 RColor color;
1124 color.red = 0xae;
1125 color.green = 0xaa;
1126 color.blue = 0xae;
1127 color.alpha = 255;
1128 RCombineImageWithColor(panel->icon, &color);
1129 RCombineImageWithColor(panel->pic, &color);
1133 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1135 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1136 panel->cycle = 0;
1137 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1138 /* If we don't use a fixed font, scrolling will be jumpy */
1139 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1140 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1141 WMRetainFont(panel->oldFont);
1142 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1143 if (font) {
1144 WMSetLabelFont(panel->versionL, font);
1145 WMReleaseFont(font);
1147 WMSetLabelText(panel->versionL, "");
1148 } else if (panel->timer) {
1149 char version[20];
1151 panel->x = 0;
1152 clicks = 0;
1153 WMSetLabelImage(panel->logoL, panel->oldPix);
1154 WMReleasePixmap(panel->oldPix);
1155 panel->oldPix = NULL;
1157 WMDeleteTimerHandler(panel->timer);
1158 panel->timer = NULL;
1160 WMSetLabelFont(panel->versionL, panel->oldFont);
1161 if (panel->oldFont) {
1162 WMReleaseFont(panel->oldFont);
1163 panel->oldFont = NULL;
1165 sprintf(version, _("Version %s"), VERSION);
1166 WMSetLabelText(panel->versionL, version);
1167 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1171 XEvent ev;
1172 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1173 ButtonPress, &ev));
1176 #endif /* SILLYNESS */
1179 void
1180 wShowInfoPanel(WScreen *scr)
1182 InfoPanel *panel;
1183 WMPixmap *logo;
1184 WMSize size;
1185 WMFont *font;
1186 char version[32];
1187 char buffer[512];
1188 Window parent;
1189 WWindow *wwin;
1190 RColor color1, color2;
1191 char **strl;
1192 int i;
1193 char *visuals[] = {
1194 "StaticGray",
1195 "GrayScale",
1196 "StaticColor",
1197 "PseudoColor",
1198 "TrueColor",
1199 "DirectColor"
1203 if (thePanel) {
1204 if (thePanel->scr == scr) {
1205 wRaiseFrame(thePanel->wwin->frame->core);
1206 wSetFocusTo(scr, thePanel->wwin);
1208 return;
1211 panel = wmalloc(sizeof(InfoPanel));
1212 memset(panel, 0, sizeof(InfoPanel));
1214 panel->scr = scr;
1216 panel->win = WMCreateWindow(scr->wmscreen, "info");
1217 WMResizeWidget(panel->win, 382, 230);
1219 logo = WMGetApplicationIconImage(scr->wmscreen);
1220 if (logo) {
1221 size = WMGetPixmapSize(logo);
1222 panel->logoL = WMCreateLabel(panel->win);
1223 WMResizeWidget(panel->logoL, 64, 64);
1224 WMMoveWidget(panel->logoL, 30, 20);
1225 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1226 WMSetLabelImage(panel->logoL, logo);
1227 #ifdef SILLYNESS
1228 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1229 handleLogoPush, panel);
1230 #endif
1233 panel->name1L = WMCreateLabel(panel->win);
1234 WMResizeWidget(panel->name1L, 240, 30);
1235 WMMoveWidget(panel->name1L, 100, 30);
1236 color1.red = 0;
1237 color1.green = 0;
1238 color1.blue = 0;
1239 color2.red = 0x50;
1240 color2.green = 0x50;
1241 color2.blue = 0x70;
1242 logo = renderText(scr->wmscreen, "GNU Window Maker",
1243 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1244 if (logo) {
1245 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1246 WMSetLabelImage(panel->name1L, logo);
1247 WMReleasePixmap(logo);
1248 } else {
1249 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1250 if (font) {
1251 WMSetLabelFont(panel->name1L, font);
1252 WMReleaseFont(font);
1254 WMSetLabelTextAlignment(panel->name1L, WACenter);
1255 WMSetLabelText(panel->name1L, "GNU Window Maker");
1258 panel->name2L = WMCreateLabel(panel->win);
1259 WMResizeWidget(panel->name2L, 240, 24);
1260 WMMoveWidget(panel->name2L, 100, 60);
1261 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1262 if (font) {
1263 WMSetLabelFont(panel->name2L, font);
1264 WMReleaseFont(font);
1265 font = NULL;
1267 WMSetLabelTextAlignment(panel->name2L, WACenter);
1268 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1271 sprintf(version, _("Version %s"), VERSION);
1272 panel->versionL = WMCreateLabel(panel->win);
1273 WMResizeWidget(panel->versionL, 310, 16);
1274 WMMoveWidget(panel->versionL, 30, 95);
1275 WMSetLabelTextAlignment(panel->versionL, WARight);
1276 WMSetLabelText(panel->versionL, version);
1277 WMSetLabelWraps(panel->versionL, False);
1279 panel->copyrL = WMCreateLabel(panel->win);
1280 WMResizeWidget(panel->copyrL, 340, 40);
1281 WMMoveWidget(panel->copyrL, 15, 185);
1282 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1283 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1284 /* we want the (c) character in the helvetica font */
1285 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1286 if (font) {
1287 WMSetLabelFont(panel->copyrL, font);
1290 switch (scr->w_depth) {
1291 case 15:
1292 strcpy(version, _("32 thousand"));
1293 break;
1294 case 16:
1295 strcpy(version, _("64 thousand"));
1296 break;
1297 case 24:
1298 case 32:
1299 strcpy(version, _("16 million"));
1300 break;
1301 default:
1302 sprintf(version, "%d", 1<<scr->w_depth);
1303 break;
1306 sprintf(buffer, _("Using visual 0x%x: %s %ibpp (%s colors)\n"),
1307 (unsigned)scr->w_visual->visualid,
1308 visuals[scr->w_visual->class], scr->w_depth, version);
1310 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1312 struct mallinfo ma = mallinfo();
1313 sprintf(buffer+strlen(buffer),
1314 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1315 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1318 #endif
1320 strcat(buffer, _("Supported image formats: "));
1321 strl = RSupportedFileFormats();
1322 for (i=0; strl[i]!=NULL; i++) {
1323 strcat(buffer, strl[i]);
1324 strcat(buffer, " ");
1327 strcat(buffer, _("\nAdditional Support For: "));
1329 char *list[8];
1330 char buf[80];
1331 int j = 0;
1333 #ifdef MWM_HINTS
1334 list[j++] = "MWM";
1335 #endif
1336 #ifdef KWM_HINTS
1337 list[j++] = "KDE";
1338 #endif
1339 #ifdef GNOME_STUFF
1340 list[j++] = "GNOME";
1341 #endif
1342 #ifdef OLWM_HINTS
1343 list[j++] = "OLWM";
1344 #endif
1345 #ifdef WSOUND
1346 list[j++] = _("Sound");
1347 #endif
1349 buf[0] = 0;
1350 for (i = 0; i < j; i++) {
1351 if (i > 0) {
1352 if (i == j - 1)
1353 strcat(buf, _(" and "));
1354 else
1355 strcat(buf, ", ");
1357 strcat(buf, list[i]);
1359 strcat(buffer, buf);
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 RImage *image;
1611 image = RLoadImage(WMScreenRContext(scr), path, 0);
1612 if (image) {
1613 pix = WMCreatePixmapFromRImage(scr, image, 0);
1614 RDestroyImage(image);
1616 wfree(path);
1620 return pix;
1624 #define PWIDTH 295
1625 #define PHEIGHT 345
1629 wShowCrashingDialogPanel(int whatSig)
1631 CrashPanel *panel;
1632 WMScreen *scr;
1633 WMFont *font;
1634 WMPixmap *logo;
1635 int screen_no, scr_width, scr_height;
1636 int action;
1637 char buf[256];
1639 panel = wmalloc(sizeof(CrashPanel));
1640 memset(panel, 0, sizeof(CrashPanel));
1642 screen_no = DefaultScreen(dpy);
1643 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1644 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1646 scr = WMCreateScreen(dpy, screen_no);
1647 if (!scr) {
1648 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1649 return WMAbort;
1652 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1654 panel->win = WMCreateWindow(scr, "crashingDialog");
1655 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1656 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1658 logo = getWindowMakerIconImage(scr);
1659 if (logo) {
1660 panel->iconL = WMCreateLabel(panel->win);
1661 WMResizeWidget(panel->iconL, 64, 64);
1662 WMMoveWidget(panel->iconL, 10, 10);
1663 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1664 WMSetLabelImage(panel->iconL, logo);
1667 panel->nameL = WMCreateLabel(panel->win);
1668 WMResizeWidget(panel->nameL, 190, 18);
1669 WMMoveWidget(panel->nameL, 80, 35);
1670 WMSetLabelTextAlignment(panel->nameL, WALeft);
1671 font = WMBoldSystemFontOfSize(scr, 18);
1672 WMSetLabelFont(panel->nameL, font);
1673 WMReleaseFont(font);
1674 WMSetLabelText(panel->nameL, _("Fatal error"));
1676 panel->sepF = WMCreateFrame(panel->win);
1677 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1678 WMMoveWidget(panel->sepF, -2, 80);
1680 panel->noteL = WMCreateLabel(panel->win);
1681 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1682 WMMoveWidget(panel->noteL, 10, 90);
1683 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1684 #ifdef SYS_SIGLIST_DECLARED
1685 sprintf(buf, _("Window Maker received signal %i\n(%s)."),
1686 whatSig, sys_siglist[whatSig]);
1687 #else
1688 sprintf(buf, _("Window Maker received signal %i."), whatSig);
1689 #endif
1690 WMSetLabelText(panel->noteL, buf);
1692 panel->note2L = WMCreateLabel(panel->win);
1693 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1694 WMMoveWidget(panel->note2L, 10, 130);
1695 WMSetLabelTextAlignment(panel->note2L, WALeft);
1696 WMSetLabelText(panel->note2L,
1697 _(" This fatal error occured probably due to a bug."
1698 " Please fill the included BUGFORM and "
1699 "report it to bugs@windowmaker.org."));
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;