- s/sprintf/snprintf
[wmaker-crm.git] / src / dialog.c
blob15fb715ea2df414b207501f6b6604a4f4a6d3969
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);
385 int len = strlen(dirfile)+strlen(text)+4;
386 file = wmalloc(len);
387 snprintf(file, len, "%s/%s", dirfile, text);
389 wfree(dirfile);
391 if ((state & WLDSSelected) != 0) {
392 color.red = color.green = color.blue = 0xff;
393 color.alpha = 0;
394 } else {
395 color.red = color.blue = 0xae;
396 color.green = 0xaa; color.alpha = 0;
398 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
399 wfree(file);
401 if (!pixmap) {
402 WMRemoveListItem(lPtr, index);
403 return;
406 XClearArea(dpy, d, rect->pos.x, rect->pos.y, width, rect->size.height,
407 False);
408 XSetClipMask(dpy, gc, None);
410 XDrawRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x + 5,
411 rect->pos.y +5, width - 10, 54);
413 XDrawLine(dpy, d, WMColorGC(whitecolor), rect->pos.x,
414 rect->pos.y+rect->size.height-1, rect->pos.x+width,
415 rect->pos.y+rect->size.height-1);
418 if (state&WLDSSelected) {
419 XFillRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x,
420 rect->pos.y, width, rect->size.height);
423 size = WMGetPixmapSize(pixmap);
425 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
426 XSetClipOrigin(dpy, copygc, rect->pos.x + (width-size.width)/2,
427 rect->pos.y+2);
428 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
429 size.width>100?100:size.width, size.height>64?64:size.height,
430 rect->pos.x + (width-size.width)/2, rect->pos.y+2);
433 int i,j;
434 int fheight = WMFontHeight(panel->normalfont);
435 int tlen = strlen(text);
436 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
437 int ofx, ofy;
439 ofx = rect->pos.x + (width - twidth)/2;
440 ofy = rect->pos.y + 64 - fheight;
442 for(i=-1;i<2;i++)
443 for(j=-1;j<2;j++)
444 WMDrawString(wmscr, d, WMColorGC(whitecolor),
445 panel->normalfont, ofx+i, ofy+j,
446 text, tlen);
448 WMDrawString(wmscr, d, WMColorGC(blackcolor), panel->normalfont,
449 ofx, ofy, text, tlen);
452 WMReleasePixmap(pixmap);
453 /* I hope it is better to do not use cache / on my box it is fast nuff */
454 XFlush(dpy);
456 WMReleaseColor(blackcolor);
457 WMReleaseColor(whitecolor);
461 static void
462 buttonCallback(void *self, void *clientData)
464 WMButton *bPtr = (WMButton*)self;
465 IconPanel *panel = (IconPanel*)clientData;
468 if (bPtr==panel->okButton) {
469 panel->done = True;
470 panel->result = True;
471 } else if (bPtr==panel->cancelButton) {
472 panel->done = True;
473 panel->result = False;
474 } else if (bPtr==panel->previewButton) {
475 /**** Previewer ****/
476 WMSetButtonEnabled(bPtr, False);
477 WMSetListUserDrawItemHeight(panel->iconList, 68);
478 WMSetListUserDrawProc(panel->iconList, drawIconProc);
479 WMRedisplayWidget(panel->iconList);
480 /* for draw proc to access screen/gc */
481 /*** end preview ***/
483 #if 0
484 else if (bPtr==panel->chooseButton) {
485 WMOpenPanel *op;
487 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
489 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
490 char *path;
491 path = WMGetFilePanelFile(op);
492 WMSetTextFieldText(panel->fileField, path);
493 setViewedImage(panel, path);
494 wfree(path);
496 WMDestroyFilePanel(op);
498 #endif
502 static void
503 keyPressHandler(XEvent *event, void *data)
505 IconPanel *panel = (IconPanel*)data;
506 Display *dpy = event->xany.display;
507 char buffer[32];
508 int count;
509 KeySym ksym;
510 int iidx;
511 int didx;
512 int item;
513 WMList *list = NULL;
515 if (event->type == KeyRelease)
516 return;
518 buffer[0] = 0;
519 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
522 iidx = WMGetListSelectedItemRow(panel->iconList);
523 didx = WMGetListSelectedItemRow(panel->dirList);
525 switch (ksym) {
526 case XK_Up:
527 if (iidx > 0)
528 item = iidx-1;
529 else
530 item = iidx;
531 list = panel->iconList;
532 break;
533 case XK_Down:
534 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
535 item = iidx+1;
536 else
537 item = iidx;
538 list = panel->iconList;
539 break;
540 case XK_Home:
541 item = 0;
542 list = panel->iconList;
543 break;
544 case XK_End:
545 item = WMGetListNumberOfRows(panel->iconList) - 1;
546 list = panel->iconList;
547 break;
548 case XK_Next:
549 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
550 item = didx + 1;
551 else
552 item = didx;
553 list = panel->dirList;
554 break;
555 case XK_Prior:
556 if (didx > 0)
557 item = didx - 1;
558 else
559 item = 0;
560 list = panel->dirList;
561 break;
562 case XK_Return:
563 WMPerformButtonClick(panel->okButton);
564 break;
565 case XK_Escape:
566 WMPerformButtonClick(panel->cancelButton);
567 break;
570 if (list) {
571 WMSelectListItem(list, item);
572 WMSetListPosition(list, item - 5);
573 listCallback(list, panel);
579 Bool
580 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
582 WWindow *wwin;
583 Window parent;
584 IconPanel *panel;
585 WMColor *color;
586 WMFont *boldFont;
588 panel = wmalloc(sizeof(IconPanel));
589 memset(panel, 0, sizeof(IconPanel));
591 panel->scr = scr;
593 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
594 WMResizeWidget(panel->win, 450, 280);
596 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
597 keyPressHandler, panel);
600 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
601 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
603 panel->dirLabel = WMCreateLabel(panel->win);
604 WMResizeWidget(panel->dirLabel, 200, 20);
605 WMMoveWidget(panel->dirLabel, 10, 7);
606 WMSetLabelText(panel->dirLabel, _("Directories"));
607 WMSetLabelFont(panel->dirLabel, boldFont);
608 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
610 WMSetLabelRelief(panel->dirLabel, WRSunken);
612 panel->iconLabel = WMCreateLabel(panel->win);
613 WMResizeWidget(panel->iconLabel, 140, 20);
614 WMMoveWidget(panel->iconLabel, 215, 7);
615 WMSetLabelText(panel->iconLabel, _("Icons"));
616 WMSetLabelFont(panel->iconLabel, boldFont);
617 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
619 WMReleaseFont(boldFont);
621 color = WMWhiteColor(scr->wmscreen);
622 WMSetLabelTextColor(panel->dirLabel, color);
623 WMSetLabelTextColor(panel->iconLabel, color);
624 WMReleaseColor(color);
626 color = WMDarkGrayColor(scr->wmscreen);
627 WMSetWidgetBackgroundColor(panel->iconLabel, color);
628 WMSetWidgetBackgroundColor(panel->dirLabel, color);
629 WMReleaseColor(color);
631 WMSetLabelRelief(panel->iconLabel, WRSunken);
633 panel->dirList = WMCreateList(panel->win);
634 WMResizeWidget(panel->dirList, 200, 170);
635 WMMoveWidget(panel->dirList, 10, 30);
636 WMSetListAction(panel->dirList, listCallback, panel);
638 panel->iconList = WMCreateList(panel->win);
639 WMResizeWidget(panel->iconList, 140, 170);
640 WMMoveWidget(panel->iconList, 215, 30);
641 WMSetListAction(panel->iconList, listCallback, panel);
643 WMHangData(panel->iconList,panel);
645 panel->previewButton = WMCreateCommandButton(panel->win);
646 WMResizeWidget(panel->previewButton, 75, 26);
647 WMMoveWidget(panel->previewButton, 365, 130);
648 WMSetButtonText(panel->previewButton, _("Preview"));
649 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
651 panel->iconView = WMCreateLabel(panel->win);
652 WMResizeWidget(panel->iconView, 75, 75);
653 WMMoveWidget(panel->iconView, 365, 40);
654 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
655 WMSetLabelRelief(panel->iconView, WRSunken);
656 WMSetLabelTextAlignment(panel->iconView, WACenter);
658 panel->fileLabel = WMCreateLabel(panel->win);
659 WMResizeWidget(panel->fileLabel, 80, 20);
660 WMMoveWidget(panel->fileLabel, 10, 210);
661 WMSetLabelText(panel->fileLabel, _("File Name:"));
663 panel->fileField = WMCreateTextField(panel->win);
664 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
665 WMResizeWidget(panel->fileField, 345, 20);
666 WMMoveWidget(panel->fileField, 95, 210);
667 WMSetTextFieldEditable(panel->fileField, False);
669 panel->okButton = WMCreateCommandButton(panel->win);
670 WMResizeWidget(panel->okButton, 80, 26);
671 WMMoveWidget(panel->okButton, 360, 240);
672 WMSetButtonText(panel->okButton, _("OK"));
673 WMSetButtonEnabled(panel->okButton, False);
674 WMSetButtonAction(panel->okButton, buttonCallback, panel);
676 panel->cancelButton = WMCreateCommandButton(panel->win);
677 WMResizeWidget(panel->cancelButton, 80, 26);
678 WMMoveWidget(panel->cancelButton, 270, 240);
679 WMSetButtonText(panel->cancelButton, _("Cancel"));
680 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
681 #if 0
682 panel->chooseButton = WMCreateCommandButton(panel->win);
683 WMResizeWidget(panel->chooseButton, 110, 26);
684 WMMoveWidget(panel->chooseButton, 150, 240);
685 WMSetButtonText(panel->chooseButton, _("Choose File"));
686 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
687 #endif
688 WMRealizeWidget(panel->win);
689 WMMapSubwidgets(panel->win);
691 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
693 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
696 char *tmp;
697 int len = (instance ? strlen(instance) : 0)
698 + (class ? strlen(class) : 0) + 32;
700 tmp = wmalloc(len);
702 if (tmp && (instance || class))
703 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
704 else
705 strcpy(tmp, _("Icon Chooser"));
707 wwin = wManageInternalWindow(scr, parent, None, tmp,
708 (scr->scr_width - 450)/2,
709 (scr->scr_height - 280)/2, 450, 280);
710 wfree(tmp);
713 /* put icon paths in the list */
714 listIconPaths(panel->dirList);
716 WMMapWidget(panel->win);
718 wWindowMap(wwin);
720 while (!panel->done) {
721 XEvent event;
723 WMNextEvent(dpy, &event);
724 WMHandleEvent(&event);
727 if (panel->result) {
728 char *defaultPath, *wantedPath;
730 /* check if the file the user selected is not the one that
731 * would be loaded by default with the current search path */
732 *file = WMGetListSelectedItem(panel->iconList)->text;
733 if ((*file)[0]==0) {
734 wfree(*file);
735 *file = NULL;
736 } else {
737 defaultPath = FindImage(wPreferences.icon_path, *file);
738 wantedPath = WMGetTextFieldText(panel->fileField);
739 /* if the file is not the default, use full path */
740 if (strcmp(wantedPath, defaultPath)!=0) {
741 *file = wantedPath;
742 } else {
743 *file = wstrdup(*file);
744 wfree(wantedPath);
746 wfree(defaultPath);
748 } else {
749 *file = NULL;
752 WMReleaseFont(panel->normalfont);
754 WMUnmapWidget(panel->win);
756 WMDestroyWidget(panel->win);
758 wUnmanageWindow(wwin, False, False);
760 wfree(panel);
762 XDestroyWindow(dpy, parent);
764 return panel->result;
769 ***********************************************************************
770 * Info Panel
771 ***********************************************************************
775 typedef struct {
776 WScreen *scr;
778 WWindow *wwin;
780 WMWindow *win;
782 WMLabel *logoL;
783 WMLabel *name1L;
784 WMLabel *name2L;
786 WMLabel *versionL;
788 WMLabel *infoL;
790 WMLabel *copyrL;
792 #ifdef SILLYNESS
793 WMHandlerID timer;
794 int cycle;
795 RImage *icon;
796 RImage *pic;
797 WMPixmap *oldPix;
798 WMFont *oldFont;
799 char *str;
800 int x;
801 #endif
802 } InfoPanel;
806 #define COPYRIGHT_TEXT \
807 "Copyright \xa9 1997~2001 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
808 "Copyright \xa9 1998~2001 Dan Pascu <dan@windowmaker.org>"
812 static InfoPanel *thePanel = NULL;
814 static void
815 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
817 #ifdef SILLYNESS
818 if (thePanel->timer) {
819 WMDeleteTimerHandler(thePanel->timer);
821 if (thePanel->oldPix) {
822 WMReleasePixmap(thePanel->oldPix);
824 if (thePanel->oldFont) {
825 WMReleaseFont(thePanel->oldFont);
827 if (thePanel->icon) {
828 RReleaseImage(thePanel->icon);
830 if (thePanel->pic) {
831 RReleaseImage(thePanel->pic);
833 #endif /* SILLYNESS */
834 WMUnmapWidget(thePanel);
836 wUnmanageWindow(thePanel->wwin, False, False);
838 WMDestroyWidget(thePanel->win);
840 wfree(thePanel);
842 thePanel = NULL;
846 WMPixmap*
847 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
849 WMPixmap *wpix = NULL;
850 Pixmap grad = None;
851 Pixmap mask = None;
852 RContext *rc = WMScreenRContext(scr);
853 XFontStruct *f = NULL;
854 int w, h;
855 GC gc = None;
857 f = XLoadQueryFont(dpy, font);
858 if (!f)
859 return NULL;
861 w = XTextWidth(f, text, strlen(text));
862 h = f->ascent+f->descent;
864 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
865 gc = XCreateGC(dpy, mask, 0, NULL);
866 XSetForeground(dpy, gc, 0);
867 XSetFont(dpy, gc, f->fid);
868 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
870 XSetForeground(dpy, gc, 1);
871 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
872 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
873 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
875 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
877 WMColor *color;
879 color = WMBlackColor(scr);
880 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
881 WMReleaseColor(color);
884 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
886 if (gc)
887 XFreeGC(dpy, gc);
888 XFreeFont(dpy, f);
890 return wpix;
893 #ifdef SILLYNESS
895 extern WMPixmap *DoXThing();
896 extern Bool InitXThing();
898 static void
899 logoPushCallback(void *data)
901 InfoPanel *panel = (InfoPanel*)data;
902 char buffer[512];
903 int i;
904 static int oldi = 0;
905 int len;
906 static int jingobeu[] = {
907 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
908 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
909 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
911 static int c = 0;
913 if (panel->x) {
914 XKeyboardControl kc;
916 if (panel->x > 0) {
917 if(jingobeu[panel->x-1]==0){panel->x=-1;}else if(jingobeu[panel->x
918 -1]<0){panel->x++;c=jingobeu[panel->x-1]/50;panel->x++;}else if(c==0){
919 kc.bell_pitch=jingobeu[panel->x-1];panel->x++;kc.bell_percent=50;c=
920 jingobeu[panel->x-1]/50;kc.bell_duration=jingobeu[panel->x-1];panel->x++;
921 XChangeKeyboardControl(dpy,KBBellPitch|KBBellDuration|KBBellPercent,&kc);
922 XBell(dpy,50);XFlush(dpy);}else{c--;}}
923 if (!(panel->cycle % 4)) {
924 WMPixmap *p;
926 p = DoXThing(panel->wwin);
927 WMSetLabelImage(panel->logoL, p);
929 } else if (panel->cycle < 30) {
930 RImage *image;
931 WMPixmap *pix;
932 RColor gray;
934 gray.red = 0xae; gray.green = 0xaa;
935 gray.blue = 0xae; gray.alpha = 0;
937 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
938 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
939 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
940 RReleaseImage(image);
941 WMSetLabelImage(panel->logoL, pix);
942 WMReleasePixmap(pix);
945 /* slow down text a little */
946 i = (int)(panel->cycle * 50.0/85.0)%200;
948 if (i != oldi) {
949 len = strlen(panel->str);
951 strncpy(buffer, panel->str, i<len ? i : len);
952 if (i >= len)
953 memset(&buffer[len], ' ', i-len);
955 strncpy(buffer, panel->str, i<len ? i : len);
956 if (i >= len)
957 memset(&buffer[len], ' ', i-len);
958 buffer[i]=0;
960 WMSetLabelText(panel->versionL, buffer);
962 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
964 oldi = i;
967 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
968 panel->cycle++;
972 static void
973 handleLogoPush(XEvent *event, void *data)
975 InfoPanel *panel = (InfoPanel*)data;
976 static int broken = 0;
977 static int clicks = 0;
978 static char *pic_data[] = {
979 "45 45 57 1",
980 " c None",
981 ". c #000000",
982 "X c #383C00",
983 "o c #515500",
984 "O c #616100",
985 "+ c #616900",
986 "@ c #696D00",
987 "# c #697100",
988 "$ c #495100",
989 "% c #202800",
990 "& c #969600",
991 "* c #CFCF00",
992 "= c #D7DB00",
993 "- c #D7D700",
994 "; c #C7CB00",
995 ": c #A6AA00",
996 "> c #494900",
997 ", c #8E8E00",
998 "< c #DFE700",
999 "1 c #F7FF00",
1000 "2 c #FFFF00",
1001 "3 c #E7EB00",
1002 "4 c #B6B600",
1003 "5 c #595900",
1004 "6 c #717500",
1005 "7 c #AEB200",
1006 "8 c #CFD300",
1007 "9 c #E7EF00",
1008 "0 c #EFF300",
1009 "q c #9EA200",
1010 "w c #F7FB00",
1011 "e c #F7F700",
1012 "r c #BEBE00",
1013 "t c #8E9200",
1014 "y c #EFF700",
1015 "u c #969A00",
1016 "i c #414500",
1017 "p c #595D00",
1018 "a c #E7E700",
1019 "s c #C7C700",
1020 "d c #797D00",
1021 "f c #BEC300",
1022 "g c #DFE300",
1023 "h c #868600",
1024 "j c #EFEF00",
1025 "k c #9E9E00",
1026 "l c #616500",
1027 "z c #DFDF00",
1028 "x c #868A00",
1029 "c c #969200",
1030 "v c #B6BA00",
1031 "b c #A6A600",
1032 "n c #8E8A00",
1033 "m c #717100",
1034 "M c #AEAE00",
1035 "N c #AEAA00",
1036 "B c #868200",
1037 " ............... ",
1038 " ....XoO+@##+O$%.... ",
1039 " ...%X&*========-;;:o... ",
1040 " ...>.>,<122222222222134@... ",
1041 " ..>5678912222222222222220q%.. ",
1042 " ..$.&-w2222222222222222222er>.. ",
1043 " ..O.t31222222222222222222222y4>.. ",
1044 " ...O5u3222222222222222222222222yri... ",
1045 " ..>p&a22222222222222222222222222wso.. ",
1046 " ..ids91222222222222222222222222222wfi.. ",
1047 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1048 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1049 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1050 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1051 "..io*222222222&...u22222222yt..%*22222220:%. ",
1052 "..>k02222222227...f222222222v..X=222222229t. ",
1053 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1054 ".%vw222222222221y2222222222219*y2222222222wd.",
1055 ".X;2222222222222222222222222222222222222222b.",
1056 ".i*2222222222222222222222222222222222222222v.",
1057 ".i*2222222222222222222222222222222222222222;.",
1058 ".i*22222222222222222222222222222222222222228.",
1059 ".>*2222222222222222222222222222222222222222=.",
1060 ".i*22222222222222222222222222222222222222228.",
1061 ".i*2222222222222222222222222222222222222222;.",
1062 ".X*222222222222222222222222222222we12222222r.",
1063 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1064 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1065 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1066 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1067 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1068 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1069 " ...:e2222218mdz22222222222222a&$vw222220@...",
1070 " ...O-122222y:.u02222222222229q$uj222221r... ",
1071 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1072 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1073 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1074 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1075 " ..Xb9122222109g-****;<y22221zn%... ",
1076 " ..X&801222222222222222222w-h.... ",
1077 " ...o:=022222222222222221=lX... ",
1078 " ..X@:;3w2222222222210fO... ",
1079 " ...XX&v8<30000003-N@... ",
1080 " .....XmnbN:q&Bo.... ",
1081 " ............ "
1083 static char *msgs[] = {
1084 "Have a nice day!",
1085 "Focus follow mouse users will burn in hell!!!",
1086 "Mooo Canada!!!!",
1087 "Hi! My name is bobby...",
1088 "AHH! The neurotic monkeys are after me!",
1089 "WHAT YOU SAY??",
1090 "WE GET SIGNAL",
1091 "SOMEBODY SET UP US THE BOMB",
1092 "ALL YOUR BASE ARE BELONG TO US!",
1093 "Oh My God!!! Larry is back!",
1094 "Hey! What happened with these messages?!?"
1098 clicks++;
1100 if (!panel->timer && !broken && clicks > 0) {
1101 WMFont *font;
1103 panel->x = 0;
1104 clicks = 0;
1105 if (!panel->icon) {
1106 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1107 if (!panel->icon) {
1108 broken = 1;
1109 return;
1110 } else {
1111 RColor color;
1113 color.red = 0xae; color.green = 0xaa;
1114 color.blue = 0xae; color.alpha = 0;
1116 panel->icon = RCloneImage(panel->icon);
1117 RCombineImageWithColor(panel->icon, &color);
1120 if (!panel->pic) {
1121 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1122 if (!panel->pic) {
1123 broken = 1;
1124 RReleaseImage(panel->icon);
1125 panel->icon = NULL;
1126 return;
1130 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1132 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1133 panel->cycle = 0;
1134 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1135 /* If we don't use a fixed font, scrolling will be jumpy */
1136 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1137 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1138 WMRetainFont(panel->oldFont);
1139 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1140 if (font) {
1141 WMSetLabelFont(panel->versionL, font);
1142 WMReleaseFont(font);
1144 WMSetLabelText(panel->versionL, "");
1145 } else if (panel->timer) {
1146 char version[20];
1148 panel->x = 0;
1149 clicks = 0;
1150 WMSetLabelImage(panel->logoL, panel->oldPix);
1151 WMReleasePixmap(panel->oldPix);
1152 panel->oldPix = NULL;
1154 WMDeleteTimerHandler(panel->timer);
1155 panel->timer = NULL;
1157 WMSetLabelFont(panel->versionL, panel->oldFont);
1158 if (panel->oldFont) {
1159 WMReleaseFont(panel->oldFont);
1160 panel->oldFont = NULL;
1162 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1163 WMSetLabelText(panel->versionL, version);
1164 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1168 XEvent ev;
1169 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1170 ButtonPress, &ev));
1173 #endif /* SILLYNESS */
1176 void
1177 wShowInfoPanel(WScreen *scr)
1179 InfoPanel *panel;
1180 WMPixmap *logo;
1181 WMSize size;
1182 WMFont *font;
1183 char *strbuf = NULL;
1184 char buffer[256];
1185 Window parent;
1186 WWindow *wwin;
1187 RColor color1, color2;
1188 char **strl;
1189 int i;
1190 char *visuals[] = {
1191 "StaticGray",
1192 "GrayScale",
1193 "StaticColor",
1194 "PseudoColor",
1195 "TrueColor",
1196 "DirectColor"
1200 if (thePanel) {
1201 if (thePanel->scr == scr) {
1202 wRaiseFrame(thePanel->wwin->frame->core);
1203 wSetFocusTo(scr, thePanel->wwin);
1205 return;
1208 panel = wmalloc(sizeof(InfoPanel));
1209 memset(panel, 0, sizeof(InfoPanel));
1211 panel->scr = scr;
1213 panel->win = WMCreateWindow(scr->wmscreen, "info");
1214 WMResizeWidget(panel->win, 382, 230);
1216 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1217 if (!logo) {
1218 logo = WMRetainPixmap(WMGetApplicationIconPixmap(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
1231 WMReleasePixmap(logo);
1234 panel->name1L = WMCreateLabel(panel->win);
1235 WMResizeWidget(panel->name1L, 240, 30);
1236 WMMoveWidget(panel->name1L, 100, 30);
1237 color1.red = 0;
1238 color1.green = 0;
1239 color1.blue = 0;
1240 color2.red = 0x50;
1241 color2.green = 0x50;
1242 color2.blue = 0x70;
1243 logo = renderText(scr->wmscreen, "GNU Window Maker",
1244 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1245 if (logo) {
1246 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1247 WMSetLabelImage(panel->name1L, logo);
1248 WMReleasePixmap(logo);
1249 } else {
1250 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1251 if (font) {
1252 WMSetLabelFont(panel->name1L, font);
1253 WMReleaseFont(font);
1255 WMSetLabelTextAlignment(panel->name1L, WACenter);
1256 WMSetLabelText(panel->name1L, "GNU Window Maker");
1259 panel->name2L = WMCreateLabel(panel->win);
1260 WMResizeWidget(panel->name2L, 240, 24);
1261 WMMoveWidget(panel->name2L, 100, 60);
1262 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1263 if (font) {
1264 WMSetLabelFont(panel->name2L, font);
1265 WMReleaseFont(font);
1266 font = NULL;
1268 WMSetLabelTextAlignment(panel->name2L, WACenter);
1269 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1272 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1273 panel->versionL = WMCreateLabel(panel->win);
1274 WMResizeWidget(panel->versionL, 310, 16);
1275 WMMoveWidget(panel->versionL, 30, 95);
1276 WMSetLabelTextAlignment(panel->versionL, WARight);
1277 WMSetLabelText(panel->versionL, buffer);
1278 WMSetLabelWraps(panel->versionL, False);
1280 panel->copyrL = WMCreateLabel(panel->win);
1281 WMResizeWidget(panel->copyrL, 340, 40);
1282 WMMoveWidget(panel->copyrL, 15, 185);
1283 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1284 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1285 /* we want the (c) character in the helvetica font */
1286 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1287 if (font) {
1288 WMSetLabelFont(panel->copyrL, font);
1291 strbuf = NULL;
1292 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1293 (unsigned)scr->w_visual->visualid,
1294 visuals[scr->w_visual->class], scr->w_depth);
1296 strbuf = wstrappend(strbuf, buffer);
1298 switch (scr->w_depth) {
1299 case 15:
1300 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1301 break;
1302 case 16:
1303 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1304 break;
1305 case 24:
1306 case 32:
1307 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1308 break;
1309 default:
1310 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1<<scr->w_depth);
1311 strbuf = wstrappend(strbuf, buffer);
1312 break;
1316 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1318 struct mallinfo ma = mallinfo();
1319 snprintf(buffer, sizeof(buffer),
1320 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1321 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1323 strbuf = wstrappend(strbuf, buffer);
1325 #endif
1327 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1328 strl = RSupportedFileFormats();
1329 for (i=0; strl[i]!=NULL; i++) {
1330 strbuf = wstrappend(strbuf, strl[i]);
1331 strbuf = wstrappend(strbuf, " ");
1334 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1336 char *list[8];
1337 char buf[80];
1338 int j = 0;
1340 #ifdef MWM_HINTS
1341 list[j++] = "MWM";
1342 #endif
1343 #ifdef KWM_HINTS
1344 list[j++] = "KDE";
1345 #endif
1346 #ifdef GNOME_STUFF
1347 list[j++] = "GNOME";
1348 #endif
1349 #ifdef OLWM_HINTS
1350 list[j++] = "OLWM";
1351 #endif
1353 buf[0] = 0;
1354 for (i = 0; i < j; i++) {
1355 if (i > 0) {
1356 if (i == j - 1)
1357 strcat(buf, _(" and "));
1358 else
1359 strcat(buf, ", ");
1361 strcat(buf, list[i]);
1363 strbuf = wstrappend(strbuf, buf);
1366 if (wPreferences.no_sound) {
1367 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1368 } else {
1369 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1373 panel->infoL = WMCreateLabel(panel->win);
1374 WMResizeWidget(panel->infoL, 350, 75);
1375 WMMoveWidget(panel->infoL, 15, 115);
1376 WMSetLabelText(panel->infoL, strbuf);
1377 if (font) {
1378 WMSetLabelFont(panel->infoL, font);
1379 WMReleaseFont(font);
1381 wfree(strbuf);
1384 WMRealizeWidget(panel->win);
1385 WMMapSubwidgets(panel->win);
1387 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1389 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1391 WMMapWidget(panel->win);
1393 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1394 (scr->scr_width - 382)/2,
1395 (scr->scr_height - 230)/2, 382, 230);
1397 WSETUFLAG(wwin, no_closable, 0);
1398 WSETUFLAG(wwin, no_close_button, 0);
1399 #ifdef XKB_BUTTON_HINT
1400 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1401 #endif
1402 wWindowUpdateButtonImages(wwin);
1403 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1404 wwin->frame->on_click_right = destroyInfoPanel;
1406 wWindowMap(wwin);
1408 panel->wwin = wwin;
1410 thePanel = panel;
1411 #ifdef SILLYNESS
1412 if (InitXThing(panel->scr)) {
1413 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1414 panel->cycle = 0;
1415 panel->x = 1;
1416 panel->str = _("Merry X'mas!");
1417 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1419 #endif
1424 ***********************************************************************
1425 * Legal Panel
1426 ***********************************************************************
1429 typedef struct {
1430 WScreen *scr;
1432 WWindow *wwin;
1434 WMWindow *win;
1436 WMLabel *licenseL;
1437 } LegalPanel;
1440 static LegalPanel *legalPanel = NULL;
1442 static void
1443 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1445 WMUnmapWidget(legalPanel->win);
1447 WMDestroyWidget(legalPanel->win);
1449 wUnmanageWindow(legalPanel->wwin, False, False);
1451 wfree(legalPanel);
1453 legalPanel = NULL;
1457 void
1458 wShowLegalPanel(WScreen *scr)
1460 LegalPanel *panel;
1461 Window parent;
1462 WWindow *wwin;
1464 if (legalPanel) {
1465 if (legalPanel->scr == scr) {
1466 wRaiseFrame(legalPanel->wwin->frame->core);
1467 wSetFocusTo(scr, legalPanel->wwin);
1469 return;
1472 panel = wmalloc(sizeof(LegalPanel));
1474 panel->scr = scr;
1476 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1477 WMResizeWidget(panel->win, 420, 250);
1480 panel->licenseL = WMCreateLabel(panel->win);
1481 WMSetLabelWraps(panel->licenseL, True);
1482 WMResizeWidget(panel->licenseL, 400, 230);
1483 WMMoveWidget(panel->licenseL, 10, 10);
1484 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1485 WMSetLabelText(panel->licenseL,
1486 _(" Window Maker is free software; you can redistribute it and/or\n"
1487 "modify it under the terms of the GNU General Public License as\n"
1488 "published by the Free Software Foundation; either version 2 of the\n"
1489 "License, or (at your option) any later version.\n\n\n"
1490 " Window Maker is distributed in the hope that it will be useful,\n"
1491 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1492 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1493 "See the GNU General Public License for more details.\n\n\n"
1494 " You should have received a copy of the GNU General Public\n"
1495 "License along with this program; if not, write to the Free Software\n"
1496 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1497 "02111-1307, USA."));
1498 WMSetLabelRelief(panel->licenseL, WRGroove);
1500 WMRealizeWidget(panel->win);
1501 WMMapSubwidgets(panel->win);
1503 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1505 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1507 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1508 (scr->scr_width - 420)/2,
1509 (scr->scr_height - 250)/2, 420, 250);
1511 WSETUFLAG(wwin, no_closable, 0);
1512 WSETUFLAG(wwin, no_close_button, 0);
1513 wWindowUpdateButtonImages(wwin);
1514 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1515 #ifdef XKB_BUTTON_HINT
1516 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1517 #endif
1518 wwin->frame->on_click_right = destroyLegalPanel;
1520 panel->wwin = wwin;
1522 WMMapWidget(panel->win);
1524 wWindowMap(wwin);
1526 legalPanel = panel;
1531 ***********************************************************************
1532 * Crashing Dialog Panel
1533 ***********************************************************************
1536 extern WDDomain *WDWindowAttributes;
1539 typedef struct _CrashPanel {
1540 WMWindow *win; /* main window */
1542 WMLabel *iconL; /* application icon */
1543 WMLabel *nameL; /* title of panel */
1545 WMFrame *sepF; /* separator frame */
1547 WMLabel *noteL; /* Title of note */
1548 WMLabel *note2L; /* body of note with what happened */
1550 WMFrame *whatF; /* "what to do next" frame */
1551 WMPopUpButton *whatP; /* action selection popup button */
1553 WMButton *okB; /* ok button */
1555 Bool done; /* if finished with this dialog */
1556 int action; /* what to do after */
1558 KeyCode retKey;
1560 } CrashPanel;
1563 static void
1564 handleKeyPress(XEvent *event, void *clientData)
1566 CrashPanel *panel = (CrashPanel*)clientData;
1568 if (event->xkey.keycode == panel->retKey) {
1569 WMPerformButtonClick(panel->okB);
1574 static void
1575 okButtonCallback(void *self, void *clientData)
1577 CrashPanel *panel = (CrashPanel*)clientData;
1579 panel->done = True;
1583 static void
1584 setCrashAction(void *self, void *clientData)
1586 WMPopUpButton *pop = (WMPopUpButton*)self;
1587 CrashPanel *panel = (CrashPanel*)clientData;
1589 panel->action = WMGetPopUpButtonSelectedItem(pop);
1593 static WMPixmap*
1594 getWindowMakerIconImage(WMScreen *scr)
1596 proplist_t dict, key, option, value=NULL;
1597 WMPixmap *pix=NULL;
1598 char *path;
1600 PLSetStringCmpHook(NULL);
1602 key = PLMakeString("Logo.WMPanel");
1603 option = PLMakeString("Icon");
1605 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
1607 if (dict) {
1608 value = PLGetDictionaryEntry(dict, option);
1611 PLRelease(key);
1612 PLRelease(option);
1614 PLSetStringCmpHook(StringCompareHook);
1616 if (value && PLIsString(value)) {
1617 path = FindImage(wPreferences.icon_path, PLGetString(value));
1619 if (path) {
1620 RColor gray;
1622 gray.red = 0xae; gray.green = 0xaa;
1623 gray.blue = 0xae; gray.alpha = 0;
1625 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1626 wfree(path);
1630 return pix;
1634 #define PWIDTH 295
1635 #define PHEIGHT 345
1639 wShowCrashingDialogPanel(int whatSig)
1641 CrashPanel *panel;
1642 WMScreen *scr;
1643 WMFont *font;
1644 WMPixmap *logo;
1645 int screen_no, scr_width, scr_height;
1646 int action;
1647 char buf[256];
1649 panel = wmalloc(sizeof(CrashPanel));
1650 memset(panel, 0, sizeof(CrashPanel));
1652 screen_no = DefaultScreen(dpy);
1653 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1654 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1656 scr = WMCreateScreen(dpy, screen_no);
1657 if (!scr) {
1658 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1659 return WMAbort;
1662 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1664 panel->win = WMCreateWindow(scr, "crashingDialog");
1665 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1666 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1668 logo = getWindowMakerIconImage(scr);
1669 if (logo) {
1670 panel->iconL = WMCreateLabel(panel->win);
1671 WMResizeWidget(panel->iconL, 64, 64);
1672 WMMoveWidget(panel->iconL, 10, 10);
1673 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1674 WMSetLabelImage(panel->iconL, logo);
1677 panel->nameL = WMCreateLabel(panel->win);
1678 WMResizeWidget(panel->nameL, 190, 18);
1679 WMMoveWidget(panel->nameL, 80, 35);
1680 WMSetLabelTextAlignment(panel->nameL, WALeft);
1681 font = WMBoldSystemFontOfSize(scr, 18);
1682 WMSetLabelFont(panel->nameL, font);
1683 WMReleaseFont(font);
1684 WMSetLabelText(panel->nameL, _("Fatal error"));
1686 panel->sepF = WMCreateFrame(panel->win);
1687 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1688 WMMoveWidget(panel->sepF, -2, 80);
1690 panel->noteL = WMCreateLabel(panel->win);
1691 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1692 WMMoveWidget(panel->noteL, 10, 90);
1693 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1694 #ifdef SYS_SIGLIST_DECLARED
1695 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."),
1696 whatSig, sys_siglist[whatSig]);
1697 #else
1698 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1699 #endif
1700 WMSetLabelText(panel->noteL, buf);
1702 panel->note2L = WMCreateLabel(panel->win);
1703 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1704 WMMoveWidget(panel->note2L, 10, 130);
1705 WMSetLabelTextAlignment(panel->note2L, WALeft);
1706 WMSetLabelText(panel->note2L,
1707 _(" This fatal error occured probably due to a bug."
1708 " Please fill the included BUGFORM and "
1709 "report it to bugs@windowmaker.org."));
1710 WMSetLabelWraps(panel->note2L, True);
1713 panel->whatF = WMCreateFrame(panel->win);
1714 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1715 WMMoveWidget(panel->whatF, 10, 240);
1716 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1718 panel->whatP = WMCreatePopUpButton(panel->whatF);
1719 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1720 WMMoveWidget(panel->whatP, 35, 20);
1721 WMSetPopUpButtonPullsDown(panel->whatP, False);
1722 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1723 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1724 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1725 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1726 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1727 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1728 panel->action = WMRestart;
1730 WMMapSubwidgets(panel->whatF);
1732 panel->okB = WMCreateCommandButton(panel->win);
1733 WMResizeWidget(panel->okB, 80, 26);
1734 WMMoveWidget(panel->okB, 205, 309);
1735 WMSetButtonText(panel->okB, _("OK"));
1736 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1737 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1738 WMSetButtonImagePosition(panel->okB, WIPRight);
1739 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1741 panel->done = 0;
1743 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1744 handleKeyPress, panel);
1746 WMRealizeWidget(panel->win);
1747 WMMapSubwidgets(panel->win);
1749 WMMapWidget(panel->win);
1751 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1753 while (!panel->done) {
1754 XEvent event;
1756 WMNextEvent(dpy, &event);
1757 WMHandleEvent(&event);
1760 action = panel->action;
1762 WMUnmapWidget(panel->win);
1763 WMDestroyWidget(panel->win);
1764 wfree(panel);
1766 return action;
1772 /*****************************************************************************
1773 * About GNUstep Panel
1774 *****************************************************************************/
1777 static void
1778 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1779 unsigned long blackPixel, unsigned long whitePixel)
1781 GC gc;
1782 XGCValues gcv;
1783 XRectangle rects[3];
1785 gcv.foreground = blackPixel;
1786 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1788 XFillArc(dpy, d, gc, width/45, height/45,
1789 width - 2*width/45, height - 2*height/45, 0, 360*64);
1791 rects[0].x = 0;
1792 rects[0].y = 37*height/45;
1793 rects[0].width = width/3;
1794 rects[0].height = height - rects[0].y;
1796 rects[1].x = rects[0].width;
1797 rects[1].y = height/2;
1798 rects[1].width = width - 2*width/3;
1799 rects[1].height = height - rects[1].y;
1801 rects[2].x = 2*width/3;
1802 rects[2].y = height - 37*height/45;
1803 rects[2].width = width/3;
1804 rects[2].height = height - rects[2].y;
1806 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1807 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1809 XSetForeground(dpy, gc, whitePixel);
1810 XFillArc(dpy, d, gc, width/45, height/45,
1811 width - 2*width/45, height - 2*height/45, 0, 360*64);
1813 XFreeGC(dpy, gc);
1817 typedef struct {
1818 WScreen *scr;
1820 WWindow *wwin;
1822 WMWindow *win;
1824 WMLabel *gstepL;
1825 WMLabel *textL;
1826 } GNUstepPanel;
1829 static GNUstepPanel *gnustepPanel = NULL;
1831 static void
1832 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1834 WMUnmapWidget(gnustepPanel->win);
1836 WMDestroyWidget(gnustepPanel->win);
1838 wUnmanageWindow(gnustepPanel->wwin, False, False);
1840 wfree(gnustepPanel);
1842 gnustepPanel = NULL;
1846 void
1847 wShowGNUstepPanel(WScreen *scr)
1849 GNUstepPanel *panel;
1850 Window parent;
1851 WWindow *wwin;
1852 WMPixmap *pixmap;
1853 WMColor *color;
1855 if (gnustepPanel) {
1856 if (gnustepPanel->scr == scr) {
1857 wRaiseFrame(gnustepPanel->wwin->frame->core);
1858 wSetFocusTo(scr, gnustepPanel->wwin);
1860 return;
1863 panel = wmalloc(sizeof(GNUstepPanel));
1865 panel->scr = scr;
1867 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1868 WMResizeWidget(panel->win, 325, 200);
1870 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1871 WMScreenDepth(scr->wmscreen), True);
1873 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1875 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1876 WMColorPixel(color), scr->white_pixel);
1878 WMReleaseColor(color);
1880 XSetForeground(dpy, scr->mono_gc, 0);
1881 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1882 130, 130);
1883 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1885 panel->gstepL = WMCreateLabel(panel->win);
1886 WMResizeWidget(panel->gstepL, 285, 64);
1887 WMMoveWidget(panel->gstepL, 20, 0);
1888 WMSetLabelTextAlignment(panel->gstepL, WARight);
1889 WMSetLabelText(panel->gstepL, "GNUstep");
1891 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1893 WMSetLabelFont(panel->gstepL, font);
1894 WMReleaseFont(font);
1897 panel->textL = WMCreateLabel(panel->win);
1898 WMResizeWidget(panel->textL, 275, 130);
1899 WMMoveWidget(panel->textL, 30, 50);
1900 WMSetLabelTextAlignment(panel->textL, WARight);
1901 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1902 WMSetLabelText(panel->textL,
1903 _("Window Maker is part of the GNUstep project.\n"\
1904 "The GNUstep project aims to create a free\n"\
1905 "implementation of the OpenStep(tm) specification\n"\
1906 "which is a object-oriented framework for\n"\
1907 "creating advanced graphical, multi-platform\n"\
1908 "applications. Additionally, a development and\n"\
1909 "user desktop enviroment will be created on top\n"\
1910 "of the framework. For more information about\n"\
1911 "GNUstep, please visit: www.gnustep.org"));
1912 WMSetLabelImage(panel->textL, pixmap);
1914 WMReleasePixmap(pixmap);
1916 WMRealizeWidget(panel->win);
1917 WMMapSubwidgets(panel->win);
1919 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1921 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1923 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1924 (scr->scr_width - 325)/2,
1925 (scr->scr_height - 200)/2, 325, 200);
1927 WSETUFLAG(wwin, no_closable, 0);
1928 WSETUFLAG(wwin, no_close_button, 0);
1929 wWindowUpdateButtonImages(wwin);
1930 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1931 #ifdef XKB_BUTTON_HINT
1932 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1933 #endif
1934 wwin->frame->on_click_right = destroyGNUstepPanel;
1936 panel->wwin = wwin;
1938 WMMapWidget(panel->win);
1940 wWindowMap(wwin);
1942 gnustepPanel = panel;