- Made scrolling of text in dialog panel smoother
[wmaker-crm.git] / src / dialog.c
blobd46d22b08115e8f4e384cf1c17875135fd5dd113
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->icon) {
812 RDestroyImage(thePanel->icon);
814 if (thePanel->pic) {
815 RDestroyImage(thePanel->pic);
817 #endif /* SILLYNESS */
818 WMUnmapWidget(thePanel);
820 wUnmanageWindow(thePanel->wwin, False, False);
822 WMDestroyWidget(thePanel->win);
824 wfree(thePanel);
826 thePanel = NULL;
830 WMPixmap*
831 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
833 WMPixmap *wpix = NULL;
834 Pixmap grad = None;
835 Pixmap mask = None;
836 RContext *rc = WMScreenRContext(scr);
837 XFontStruct *f = NULL;
838 int w, h;
839 GC gc = None;
841 f = XLoadQueryFont(dpy, font);
842 if (!f)
843 return NULL;
845 w = XTextWidth(f, text, strlen(text));
846 h = f->ascent+f->descent;
848 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
849 gc = XCreateGC(dpy, mask, 0, NULL);
850 XSetForeground(dpy, gc, 0);
851 XSetFont(dpy, gc, f->fid);
852 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
854 XSetForeground(dpy, gc, 1);
855 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
856 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
857 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
859 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
861 WMColor *color;
863 color = WMBlackColor(scr);
864 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
865 WMReleaseColor(color);
868 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
870 if (gc)
871 XFreeGC(dpy, gc);
872 XFreeFont(dpy, f);
874 return wpix;
877 #ifdef SILLYNESS
879 extern WMPixmap *DoXThing();
880 extern Bool InitXThing();
882 static void
883 logoPushCallback(void *data)
885 InfoPanel *panel = (InfoPanel*)data;
886 char buffer[512];
887 int i;
888 static int oldi = 0;
889 int len;
890 static int jingobeu[] = {
891 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
892 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
893 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
895 static int c = 0;
897 if (panel->x) {
898 XKeyboardControl kc;
900 if (panel->x > 0) {
901 if(jingobeu[panel->x-1]==0){panel->x=-1;}else if(jingobeu[panel->x
902 -1]<0){panel->x++;c=jingobeu[panel->x-1]/50;panel->x++;}else if(c==0){
903 kc.bell_pitch=jingobeu[panel->x-1];panel->x++;kc.bell_percent=50;c=
904 jingobeu[panel->x-1]/50;kc.bell_duration=jingobeu[panel->x-1];panel->x++;
905 XChangeKeyboardControl(dpy,KBBellPitch|KBBellDuration|KBBellPercent,&kc);
906 XBell(dpy,50);XFlush(dpy);}else{c--;}}
907 if (!(panel->cycle % 4)) {
908 WMPixmap *p;
910 p = DoXThing(panel->wwin);
911 WMSetLabelImage(panel->logoL, p);
913 } else if (panel->cycle < 30) {
914 RImage *image;
915 WMPixmap *pix;
917 image = RCloneImage(panel->icon);
918 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
919 pix = WMCreatePixmapFromRImage(panel->scr->wmscreen, image, 128);
920 RDestroyImage(image);
921 WMSetLabelImage(panel->logoL, pix);
922 WMReleasePixmap(pix);
925 /* slow down text a little */
926 i = (int)(panel->cycle * 50.0/85.0)%200;
928 if (i != oldi) {
929 len = strlen(panel->str);
931 strncpy(buffer, panel->str, i<len ? i : len);
932 if (i >= len)
933 memset(&buffer[len], ' ', i-len);
935 strncpy(buffer, panel->str, i<len ? i : len);
936 if (i >= len)
937 memset(&buffer[len], ' ', i-len);
938 buffer[i]=0;
940 WMSetLabelText(panel->versionL, buffer);
942 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
944 oldi = i;
947 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
948 panel->cycle++;
952 static void
953 handleLogoPush(XEvent *event, void *data)
955 InfoPanel *panel = (InfoPanel*)data;
956 static int broken = 0;
957 static int clicks = 0;
958 static char *pic_data[] = {
959 "45 45 57 1",
960 " c None",
961 ". c #000000",
962 "X c #383C00",
963 "o c #515500",
964 "O c #616100",
965 "+ c #616900",
966 "@ c #696D00",
967 "# c #697100",
968 "$ c #495100",
969 "% c #202800",
970 "& c #969600",
971 "* c #CFCF00",
972 "= c #D7DB00",
973 "- c #D7D700",
974 "; c #C7CB00",
975 ": c #A6AA00",
976 "> c #494900",
977 ", c #8E8E00",
978 "< c #DFE700",
979 "1 c #F7FF00",
980 "2 c #FFFF00",
981 "3 c #E7EB00",
982 "4 c #B6B600",
983 "5 c #595900",
984 "6 c #717500",
985 "7 c #AEB200",
986 "8 c #CFD300",
987 "9 c #E7EF00",
988 "0 c #EFF300",
989 "q c #9EA200",
990 "w c #F7FB00",
991 "e c #F7F700",
992 "r c #BEBE00",
993 "t c #8E9200",
994 "y c #EFF700",
995 "u c #969A00",
996 "i c #414500",
997 "p c #595D00",
998 "a c #E7E700",
999 "s c #C7C700",
1000 "d c #797D00",
1001 "f c #BEC300",
1002 "g c #DFE300",
1003 "h c #868600",
1004 "j c #EFEF00",
1005 "k c #9E9E00",
1006 "l c #616500",
1007 "z c #DFDF00",
1008 "x c #868A00",
1009 "c c #969200",
1010 "v c #B6BA00",
1011 "b c #A6A600",
1012 "n c #8E8A00",
1013 "m c #717100",
1014 "M c #AEAE00",
1015 "N c #AEAA00",
1016 "B c #868200",
1017 " ............... ",
1018 " ....XoO+@##+O$%.... ",
1019 " ...%X&*========-;;:o... ",
1020 " ...>.>,<122222222222134@... ",
1021 " ..>5678912222222222222220q%.. ",
1022 " ..$.&-w2222222222222222222er>.. ",
1023 " ..O.t31222222222222222222222y4>.. ",
1024 " ...O5u3222222222222222222222222yri... ",
1025 " ..>p&a22222222222222222222222222wso.. ",
1026 " ..ids91222222222222222222222222222wfi.. ",
1027 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1028 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1029 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1030 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1031 "..io*222222222&...u22222222yt..%*22222220:%. ",
1032 "..>k02222222227...f222222222v..X=222222229t. ",
1033 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1034 ".%vw222222222221y2222222222219*y2222222222wd.",
1035 ".X;2222222222222222222222222222222222222222b.",
1036 ".i*2222222222222222222222222222222222222222v.",
1037 ".i*2222222222222222222222222222222222222222;.",
1038 ".i*22222222222222222222222222222222222222228.",
1039 ".>*2222222222222222222222222222222222222222=.",
1040 ".i*22222222222222222222222222222222222222228.",
1041 ".i*2222222222222222222222222222222222222222;.",
1042 ".X*222222222222222222222222222222we12222222r.",
1043 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1044 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1045 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1046 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1047 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1048 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1049 " ...:e2222218mdz22222222222222a&$vw222220@...",
1050 " ...O-122222y:.u02222222222229q$uj222221r... ",
1051 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1052 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1053 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1054 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1055 " ..Xb9122222109g-****;<y22221zn%... ",
1056 " ..X&801222222222222222222w-h.... ",
1057 " ...o:=022222222222222221=lX... ",
1058 " ..X@:;3w2222222222210fO... ",
1059 " ...XX&v8<30000003-N@... ",
1060 " .....XmnbN:q&Bo.... ",
1061 " ............ "};
1062 static char *msgs[] = {
1063 "Have a nice day!",
1064 "Focus follow mouse users will burn in hell!!!",
1065 "F'ck Canada!!!!",
1066 "F'ck Bastard Imperialists!!!",
1067 "Hi! My name is bobby...",
1068 "AHH! The neurotic monkeys are after me!"
1072 clicks++;
1074 if (!panel->timer && !broken && clicks > 0) {
1075 WMFont *font;
1076 char *file;
1077 char *path;
1079 panel->x = 0;
1080 clicks = 0;
1081 if (!panel->icon) {
1082 file = wDefaultGetIconFile(panel->scr, "Logo", "WMPanel", False);
1083 if (!file) {
1084 broken = 1;
1085 return;
1088 path = FindImage(wPreferences.icon_path, file);
1089 if (!path) {
1090 broken = 1;
1091 return;
1094 panel->icon = RLoadImage(panel->scr->rcontext, path, 0);
1095 wfree(path);
1096 if (!panel->icon) {
1097 broken = 1;
1098 return;
1101 if (!panel->pic) {
1102 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1103 if (!panel->pic || panel->icon->width!=panel->pic->width
1104 || panel->icon->height!=panel->pic->height) {
1105 broken = 1;
1106 RDestroyImage(panel->icon);
1107 panel->icon = NULL;
1108 if (panel->pic) {
1109 RDestroyImage(panel->pic);
1110 panel->pic = NULL;
1112 return;
1116 RColor color;
1117 color.red = 0xae;
1118 color.green = 0xaa;
1119 color.blue = 0xae;
1120 color.alpha = 255;
1121 RCombineImageWithColor(panel->icon, &color);
1122 RCombineImageWithColor(panel->pic, &color);
1126 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1128 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1129 panel->cycle = 0;
1130 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1131 /* If we don't use a fixed font, scrolling will be jumpy */
1132 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1133 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1134 WMRetainFont(panel->oldFont);
1135 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1136 if (font) {
1137 WMSetLabelFont(panel->versionL, font);
1138 WMReleaseFont(font);
1140 WMSetLabelText(panel->versionL, "");
1141 } else if (panel->timer) {
1142 char version[20];
1144 panel->x = 0;
1145 clicks = 0;
1146 WMSetLabelImage(panel->logoL, panel->oldPix);
1147 WMReleasePixmap(panel->oldPix);
1148 panel->oldPix = NULL;
1150 WMDeleteTimerHandler(panel->timer);
1151 panel->timer = NULL;
1153 WMSetLabelFont(panel->versionL, panel->oldFont);
1154 if (panel->oldFont) {
1155 WMReleaseFont(panel->oldFont);
1156 panel->oldFont = NULL;
1158 sprintf(version, _("Version %s"), VERSION);
1159 WMSetLabelText(panel->versionL, version);
1160 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1164 XEvent ev;
1165 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1166 ButtonPress, &ev));
1169 #endif /* SILLYNESS */
1172 void
1173 wShowInfoPanel(WScreen *scr)
1175 InfoPanel *panel;
1176 WMPixmap *logo;
1177 WMSize size;
1178 WMFont *font;
1179 char version[32];
1180 char buffer[512];
1181 Window parent;
1182 WWindow *wwin;
1183 RColor color1, color2;
1184 char **strl;
1185 int i;
1186 char *visuals[] = {
1187 "StaticGray",
1188 "GrayScale",
1189 "StaticColor",
1190 "PseudoColor",
1191 "TrueColor",
1192 "DirectColor"
1196 if (thePanel) {
1197 if (thePanel->scr == scr) {
1198 wRaiseFrame(thePanel->wwin->frame->core);
1199 wSetFocusTo(scr, thePanel->wwin);
1201 return;
1204 panel = wmalloc(sizeof(InfoPanel));
1205 memset(panel, 0, sizeof(InfoPanel));
1207 panel->scr = scr;
1209 panel->win = WMCreateWindow(scr->wmscreen, "info");
1210 WMResizeWidget(panel->win, 382, 230);
1212 logo = WMGetApplicationIconImage(scr->wmscreen);
1213 if (logo) {
1214 size = WMGetPixmapSize(logo);
1215 panel->logoL = WMCreateLabel(panel->win);
1216 WMResizeWidget(panel->logoL, 64, 64);
1217 WMMoveWidget(panel->logoL, 30, 20);
1218 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1219 WMSetLabelImage(panel->logoL, logo);
1220 #ifdef SILLYNESS
1221 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1222 handleLogoPush, panel);
1223 #endif
1226 panel->name1L = WMCreateLabel(panel->win);
1227 WMResizeWidget(panel->name1L, 240, 30);
1228 WMMoveWidget(panel->name1L, 100, 30);
1229 color1.red = 0;
1230 color1.green = 0;
1231 color1.blue = 0;
1232 color2.red = 0x50;
1233 color2.green = 0x50;
1234 color2.blue = 0x70;
1235 logo = renderText(scr->wmscreen, "GNU Window Maker",
1236 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1237 if (logo) {
1238 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1239 WMSetLabelImage(panel->name1L, logo);
1240 WMReleasePixmap(logo);
1241 } else {
1242 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1243 if (font) {
1244 WMSetLabelFont(panel->name1L, font);
1245 WMReleaseFont(font);
1247 WMSetLabelTextAlignment(panel->name1L, WACenter);
1248 WMSetLabelText(panel->name1L, "GNU Window Maker");
1251 panel->name2L = WMCreateLabel(panel->win);
1252 WMResizeWidget(panel->name2L, 240, 24);
1253 WMMoveWidget(panel->name2L, 100, 60);
1254 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1255 if (font) {
1256 WMSetLabelFont(panel->name2L, font);
1257 WMReleaseFont(font);
1258 font = NULL;
1260 WMSetLabelTextAlignment(panel->name2L, WACenter);
1261 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1264 sprintf(version, _("Version %s"), VERSION);
1265 panel->versionL = WMCreateLabel(panel->win);
1266 WMResizeWidget(panel->versionL, 310, 16);
1267 WMMoveWidget(panel->versionL, 30, 95);
1268 WMSetLabelTextAlignment(panel->versionL, WARight);
1269 WMSetLabelText(panel->versionL, version);
1270 WMSetLabelWraps(panel->versionL, False);
1272 panel->copyrL = WMCreateLabel(panel->win);
1273 WMResizeWidget(panel->copyrL, 340, 40);
1274 WMMoveWidget(panel->copyrL, 15, 185);
1275 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1276 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1277 /* we want the (c) character in the helvetica font */
1278 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1279 if (font) {
1280 WMSetLabelFont(panel->copyrL, font);
1283 switch (scr->w_depth) {
1284 case 15:
1285 strcpy(version, _("32 thousand"));
1286 break;
1287 case 16:
1288 strcpy(version, _("64 thousand"));
1289 break;
1290 case 24:
1291 case 32:
1292 strcpy(version, _("16 million"));
1293 break;
1294 default:
1295 sprintf(version, "%d", 1<<scr->w_depth);
1296 break;
1299 sprintf(buffer, _("Using visual 0x%x: %s %ibpp (%s colors)\n"),
1300 (unsigned)scr->w_visual->visualid,
1301 visuals[scr->w_visual->class], scr->w_depth, version);
1303 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1305 struct mallinfo ma = mallinfo();
1306 sprintf(buffer+strlen(buffer),
1307 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1308 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1311 #endif
1313 strcat(buffer, _("Supported image formats: "));
1314 strl = RSupportedFileFormats();
1315 for (i=0; strl[i]!=NULL; i++) {
1316 strcat(buffer, strl[i]);
1317 strcat(buffer, " ");
1320 strcat(buffer, _("\nAdditional Support For: "));
1322 char *list[8];
1323 char buf[80];
1324 int j = 0;
1326 #ifdef MWM_HINTS
1327 list[j++] = "MWM";
1328 #endif
1329 #ifdef KWM_HINTS
1330 list[j++] = "KDE";
1331 #endif
1332 #ifdef GNOME_STUFF
1333 list[j++] = "GNOME";
1334 #endif
1335 #ifdef OLWM_HINTS
1336 list[j++] = "OLWM";
1337 #endif
1338 #ifdef WSOUND
1339 list[j++] = _("Sound");
1340 #endif
1342 buf[0] = 0;
1343 for (i = 0; i < j; i++) {
1344 if (i > 0) {
1345 if (i == j - 1)
1346 strcat(buf, _(" and "));
1347 else
1348 strcat(buf, ", ");
1350 strcat(buf, list[i]);
1352 strcat(buffer, buf);
1356 panel->infoL = WMCreateLabel(panel->win);
1357 WMResizeWidget(panel->infoL, 350, 75);
1358 WMMoveWidget(panel->infoL, 15, 115);
1359 WMSetLabelText(panel->infoL, buffer);
1360 if (font) {
1361 WMSetLabelFont(panel->infoL, font);
1362 WMReleaseFont(font);
1366 WMRealizeWidget(panel->win);
1367 WMMapSubwidgets(panel->win);
1369 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1371 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1373 WMMapWidget(panel->win);
1375 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1376 (scr->scr_width - 382)/2,
1377 (scr->scr_height - 230)/2, 382, 230);
1379 WSETUFLAG(wwin, no_closable, 0);
1380 WSETUFLAG(wwin, no_close_button, 0);
1381 #ifdef XKB_BUTTON_HINT
1382 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1383 #endif
1384 wWindowUpdateButtonImages(wwin);
1385 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1386 wwin->frame->on_click_right = destroyInfoPanel;
1388 wWindowMap(wwin);
1390 panel->wwin = wwin;
1392 thePanel = panel;
1393 #ifdef SILLYNESS
1394 if (InitXThing(panel->scr)) {
1395 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1396 panel->cycle = 0;
1397 panel->x = 1;
1398 panel->str = _("Merry X'mas!");
1399 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1401 #endif
1406 ***********************************************************************
1407 * Legal Panel
1408 ***********************************************************************
1411 typedef struct {
1412 WScreen *scr;
1414 WWindow *wwin;
1416 WMWindow *win;
1418 WMLabel *licenseL;
1419 } LegalPanel;
1422 static LegalPanel *legalPanel = NULL;
1424 static void
1425 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1427 WMUnmapWidget(legalPanel->win);
1429 WMDestroyWidget(legalPanel->win);
1431 wUnmanageWindow(legalPanel->wwin, False, False);
1433 wfree(legalPanel);
1435 legalPanel = NULL;
1439 void
1440 wShowLegalPanel(WScreen *scr)
1442 LegalPanel *panel;
1443 Window parent;
1444 WWindow *wwin;
1446 if (legalPanel) {
1447 if (legalPanel->scr == scr) {
1448 wRaiseFrame(legalPanel->wwin->frame->core);
1449 wSetFocusTo(scr, legalPanel->wwin);
1451 return;
1454 panel = wmalloc(sizeof(LegalPanel));
1456 panel->scr = scr;
1458 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1459 WMResizeWidget(panel->win, 420, 250);
1462 panel->licenseL = WMCreateLabel(panel->win);
1463 WMSetLabelWraps(panel->licenseL, True);
1464 WMResizeWidget(panel->licenseL, 400, 230);
1465 WMMoveWidget(panel->licenseL, 10, 10);
1466 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1467 WMSetLabelText(panel->licenseL,
1468 _(" Window Maker is free software; you can redistribute it and/or\n"
1469 "modify it under the terms of the GNU General Public License as\n"
1470 "published by the Free Software Foundation; either version 2 of the\n"
1471 "License, or (at your option) any later version.\n\n\n"
1472 " Window Maker is distributed in the hope that it will be useful,\n"
1473 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1474 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1475 "See the GNU General Public License for more details.\n\n\n"
1476 " You should have received a copy of the GNU General Public\n"
1477 "License along with this program; if not, write to the Free Software\n"
1478 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1479 "02111-1307, USA."));
1480 WMSetLabelRelief(panel->licenseL, WRGroove);
1482 WMRealizeWidget(panel->win);
1483 WMMapSubwidgets(panel->win);
1485 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1487 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1489 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1490 (scr->scr_width - 420)/2,
1491 (scr->scr_height - 250)/2, 420, 250);
1493 WSETUFLAG(wwin, no_closable, 0);
1494 WSETUFLAG(wwin, no_close_button, 0);
1495 wWindowUpdateButtonImages(wwin);
1496 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1497 #ifdef XKB_BUTTON_HINT
1498 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1499 #endif
1500 wwin->frame->on_click_right = destroyLegalPanel;
1502 panel->wwin = wwin;
1504 WMMapWidget(panel->win);
1506 wWindowMap(wwin);
1508 legalPanel = panel;
1513 ***********************************************************************
1514 * Crashing Dialog Panel
1515 ***********************************************************************
1518 extern WDDomain *WDWindowAttributes;
1521 typedef struct _CrashPanel {
1522 WMWindow *win; /* main window */
1524 WMLabel *iconL; /* application icon */
1525 WMLabel *nameL; /* title of panel */
1527 WMFrame *sepF; /* separator frame */
1529 WMLabel *noteL; /* Title of note */
1530 WMLabel *note2L; /* body of note with what happened */
1532 WMFrame *whatF; /* "what to do next" frame */
1533 WMPopUpButton *whatP; /* action selection popup button */
1535 WMButton *okB; /* ok button */
1537 Bool done; /* if finished with this dialog */
1538 int action; /* what to do after */
1540 KeyCode retKey;
1542 } CrashPanel;
1545 static void
1546 handleKeyPress(XEvent *event, void *clientData)
1548 CrashPanel *panel = (CrashPanel*)clientData;
1550 if (event->xkey.keycode == panel->retKey) {
1551 WMPerformButtonClick(panel->okB);
1556 static void
1557 okButtonCallback(void *self, void *clientData)
1559 CrashPanel *panel = (CrashPanel*)clientData;
1561 panel->done = True;
1565 static void
1566 setCrashAction(void *self, void *clientData)
1568 WMPopUpButton *pop = (WMPopUpButton*)self;
1569 CrashPanel *panel = (CrashPanel*)clientData;
1571 panel->action = WMGetPopUpButtonSelectedItem(pop);
1575 static WMPixmap*
1576 getWindowMakerIconImage(WMScreen *scr)
1578 proplist_t dict, key, option, value=NULL;
1579 WMPixmap *pix=NULL;
1580 char *path;
1582 PLSetStringCmpHook(NULL);
1584 key = PLMakeString("Logo.WMPanel");
1585 option = PLMakeString("Icon");
1587 dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
1589 if (dict) {
1590 value = PLGetDictionaryEntry(dict, option);
1593 PLRelease(key);
1594 PLRelease(option);
1596 PLSetStringCmpHook(StringCompareHook);
1598 if (value && PLIsString(value)) {
1599 path = FindImage(wPreferences.icon_path, PLGetString(value));
1601 if (path) {
1602 RImage *image;
1604 image = RLoadImage(WMScreenRContext(scr), path, 0);
1605 if (image) {
1606 pix = WMCreatePixmapFromRImage(scr, image, 0);
1607 RDestroyImage(image);
1609 wfree(path);
1613 return pix;
1617 #define PWIDTH 295
1618 #define PHEIGHT 345
1622 wShowCrashingDialogPanel(int whatSig)
1624 CrashPanel *panel;
1625 WMScreen *scr;
1626 WMFont *font;
1627 WMPixmap *logo;
1628 int screen_no, scr_width, scr_height;
1629 int action;
1630 char buf[256];
1632 panel = wmalloc(sizeof(CrashPanel));
1633 memset(panel, 0, sizeof(CrashPanel));
1635 screen_no = DefaultScreen(dpy);
1636 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1637 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1639 scr = WMCreateScreen(dpy, screen_no);
1640 if (!scr) {
1641 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1642 return WMAbort;
1645 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1647 panel->win = WMCreateWindow(scr, "crashingDialog");
1648 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1649 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1651 logo = getWindowMakerIconImage(scr);
1652 if (logo) {
1653 panel->iconL = WMCreateLabel(panel->win);
1654 WMResizeWidget(panel->iconL, 64, 64);
1655 WMMoveWidget(panel->iconL, 10, 10);
1656 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1657 WMSetLabelImage(panel->iconL, logo);
1660 panel->nameL = WMCreateLabel(panel->win);
1661 WMResizeWidget(panel->nameL, 190, 18);
1662 WMMoveWidget(panel->nameL, 80, 35);
1663 WMSetLabelTextAlignment(panel->nameL, WALeft);
1664 font = WMBoldSystemFontOfSize(scr, 18);
1665 WMSetLabelFont(panel->nameL, font);
1666 WMReleaseFont(font);
1667 WMSetLabelText(panel->nameL, _("Fatal error"));
1669 panel->sepF = WMCreateFrame(panel->win);
1670 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1671 WMMoveWidget(panel->sepF, -2, 80);
1673 panel->noteL = WMCreateLabel(panel->win);
1674 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1675 WMMoveWidget(panel->noteL, 10, 90);
1676 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1677 #ifdef SYS_SIGLIST_DECLARED
1678 sprintf(buf, _("Window Maker received signal %i\n(%s)."),
1679 whatSig, sys_siglist[whatSig]);
1680 #else
1681 sprintf(buf, _("Window Maker received signal %i."), whatSig);
1682 #endif
1683 WMSetLabelText(panel->noteL, buf);
1685 panel->note2L = WMCreateLabel(panel->win);
1686 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1687 WMMoveWidget(panel->note2L, 10, 130);
1688 WMSetLabelTextAlignment(panel->note2L, WALeft);
1689 WMSetLabelText(panel->note2L,
1690 _(" This fatal error occured probably due to a bug."
1691 " Please fill the included BUGFORM and "
1692 "report it to bugs@windowmaker.org."));
1695 panel->whatF = WMCreateFrame(panel->win);
1696 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1697 WMMoveWidget(panel->whatF, 10, 240);
1698 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1700 panel->whatP = WMCreatePopUpButton(panel->whatF);
1701 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1702 WMMoveWidget(panel->whatP, 35, 20);
1703 WMSetPopUpButtonPullsDown(panel->whatP, False);
1704 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1705 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1706 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1707 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1708 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1709 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1710 panel->action = WMRestart;
1712 WMMapSubwidgets(panel->whatF);
1714 panel->okB = WMCreateCommandButton(panel->win);
1715 WMResizeWidget(panel->okB, 80, 26);
1716 WMMoveWidget(panel->okB, 205, 309);
1717 WMSetButtonText(panel->okB, _("OK"));
1718 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1719 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1720 WMSetButtonImagePosition(panel->okB, WIPRight);
1721 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1723 panel->done = 0;
1725 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1726 handleKeyPress, panel);
1728 WMRealizeWidget(panel->win);
1729 WMMapSubwidgets(panel->win);
1731 WMMapWidget(panel->win);
1733 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1735 while (!panel->done) {
1736 XEvent event;
1738 WMNextEvent(dpy, &event);
1739 WMHandleEvent(&event);
1742 action = panel->action;
1744 WMUnmapWidget(panel->win);
1745 WMDestroyWidget(panel->win);
1746 wfree(panel);
1748 return action;
1754 /*****************************************************************************
1755 * About GNUstep Panel
1756 *****************************************************************************/
1759 static void
1760 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1761 unsigned long blackPixel, unsigned long whitePixel)
1763 GC gc;
1764 XGCValues gcv;
1765 XRectangle rects[3];
1767 gcv.foreground = blackPixel;
1768 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1770 XFillArc(dpy, d, gc, width/45, height/45,
1771 width - 2*width/45, height - 2*height/45, 0, 360*64);
1773 rects[0].x = 0;
1774 rects[0].y = 37*height/45;
1775 rects[0].width = width/3;
1776 rects[0].height = height - rects[0].y;
1778 rects[1].x = rects[0].width;
1779 rects[1].y = height/2;
1780 rects[1].width = width - 2*width/3;
1781 rects[1].height = height - rects[1].y;
1783 rects[2].x = 2*width/3;
1784 rects[2].y = height - 37*height/45;
1785 rects[2].width = width/3;
1786 rects[2].height = height - rects[2].y;
1788 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1789 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1791 XSetForeground(dpy, gc, whitePixel);
1792 XFillArc(dpy, d, gc, width/45, height/45,
1793 width - 2*width/45, height - 2*height/45, 0, 360*64);
1795 XFreeGC(dpy, gc);
1799 typedef struct {
1800 WScreen *scr;
1802 WWindow *wwin;
1804 WMWindow *win;
1806 WMLabel *gstepL;
1807 WMLabel *textL;
1808 } GNUstepPanel;
1811 static GNUstepPanel *gnustepPanel = NULL;
1813 static void
1814 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1816 WMUnmapWidget(gnustepPanel->win);
1818 WMDestroyWidget(gnustepPanel->win);
1820 wUnmanageWindow(gnustepPanel->wwin, False, False);
1822 wfree(gnustepPanel);
1824 gnustepPanel = NULL;
1828 void
1829 wShowGNUstepPanel(WScreen *scr)
1831 GNUstepPanel *panel;
1832 Window parent;
1833 WWindow *wwin;
1834 WMPixmap *pixmap;
1835 WMColor *color;
1837 if (gnustepPanel) {
1838 if (gnustepPanel->scr == scr) {
1839 wRaiseFrame(gnustepPanel->wwin->frame->core);
1840 wSetFocusTo(scr, gnustepPanel->wwin);
1842 return;
1845 panel = wmalloc(sizeof(GNUstepPanel));
1847 panel->scr = scr;
1849 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1850 WMResizeWidget(panel->win, 325, 200);
1852 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1853 WMScreenDepth(scr->wmscreen), True);
1855 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1857 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1858 WMColorPixel(color), scr->white_pixel);
1860 WMReleaseColor(color);
1862 XSetForeground(dpy, scr->mono_gc, 0);
1863 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1864 130, 130);
1865 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1867 panel->gstepL = WMCreateLabel(panel->win);
1868 WMResizeWidget(panel->gstepL, 285, 64);
1869 WMMoveWidget(panel->gstepL, 20, 0);
1870 WMSetLabelTextAlignment(panel->gstepL, WARight);
1871 WMSetLabelText(panel->gstepL, "GNUstep");
1873 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1875 WMSetLabelFont(panel->gstepL, font);
1876 WMReleaseFont(font);
1879 panel->textL = WMCreateLabel(panel->win);
1880 WMResizeWidget(panel->textL, 275, 130);
1881 WMMoveWidget(panel->textL, 30, 50);
1882 WMSetLabelTextAlignment(panel->textL, WARight);
1883 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1884 WMSetLabelText(panel->textL,
1885 _("Window Maker is part of the GNUstep project.\n"\
1886 "The GNUstep project aims to create a free\n"\
1887 "implementation of the OpenStep(tm) specification\n"\
1888 "which is a object-oriented framework for\n"\
1889 "creating advanced graphical, multi-platform\n"\
1890 "applications. Additionally, a development and\n"\
1891 "user desktop enviroment will be created on top\n"\
1892 "of the framework. For more information about\n"\
1893 "GNUstep, please visit: www.gnustep.org"));
1894 WMSetLabelImage(panel->textL, pixmap);
1896 WMReleasePixmap(pixmap);
1898 WMRealizeWidget(panel->win);
1899 WMMapSubwidgets(panel->win);
1901 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1903 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1905 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
1906 (scr->scr_width - 325)/2,
1907 (scr->scr_height - 200)/2, 325, 200);
1909 WSETUFLAG(wwin, no_closable, 0);
1910 WSETUFLAG(wwin, no_close_button, 0);
1911 wWindowUpdateButtonImages(wwin);
1912 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1913 #ifdef XKB_BUTTON_HINT
1914 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1915 #endif
1916 wwin->frame->on_click_right = destroyGNUstepPanel;
1918 panel->wwin = wwin;
1920 WMMapWidget(panel->win);
1922 wWindowMap(wwin);
1924 gnustepPanel = panel;