- fixes for AA fonts
[wmaker-crm.git] / src / dialog.c
blob4e7d9f60b0c03fa4c990c2779ecd8bd18a21093b
1 /* dialog.c - dialog windows for internal use
3 * Window Maker window manager
5 * Copyright (c) 1997-2002 Alfredo K. Kojima
6 * Copyright (c) 1998-2002 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"
63 #include "xinerama.h"
65 extern WPreferences wPreferences;
68 static WMPoint getCenter(WScreen *scr, int width, int height)
70 WMPoint pt;
72 #ifdef XINERAMA
73 WMRect rect;
75 rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr));
77 pt.x = rect.pos.x + (rect.size.width - width)/2;
78 pt.y = rect.pos.y + (rect.size.height - height)/2;
79 #else
80 pt.x = (scr->scr_width - width) / 2;
81 pt.y = (scr->scr_height - height) / 2;
82 #endif
84 return pt;
89 int
90 wMessageDialog(WScreen *scr, char *title, char *message,
91 char *defBtn, char *altBtn, char *othBtn)
93 WMAlertPanel *panel;
94 Window parent;
95 WWindow *wwin;
96 int result;
97 WMPoint center;
99 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
100 defBtn, altBtn, othBtn);
102 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
104 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
107 center = getCenter(scr, 400, 180);
108 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y,
109 400, 180);
110 wwin->client_leader = WMWidgetXID(panel->win);
112 WMMapWidget(panel->win);
114 wWindowMap(wwin);
116 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
118 result = panel->result;
120 WMUnmapWidget(panel->win);
122 wUnmanageWindow(wwin, False, False);
124 WMDestroyAlertPanel(panel);
126 XDestroyWindow(dpy, parent);
128 return result;
132 void
133 toggleSaveSession(WMWidget *w, void *data)
135 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
140 wExitDialog(WScreen *scr, char *title, char *message,
141 char *defBtn, char *altBtn, char *othBtn)
143 WMAlertPanel *panel;
144 WMButton *saveSessionBtn;
145 Window parent;
146 WWindow *wwin;
147 int result;
149 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
150 defBtn, altBtn, othBtn);
152 /* add save session button */
153 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
154 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
155 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn),
156 False, True, 200, 0, 0);
157 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
158 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
159 WMRealizeWidget(saveSessionBtn);
160 WMMapWidget(saveSessionBtn);
162 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
164 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
166 wwin = wManageInternalWindow(scr, parent, None, NULL,
167 (scr->scr_width - 400)/2,
168 (scr->scr_height - 180)/2, 400, 180);
169 wwin->client_leader = WMWidgetXID(panel->win);
171 WMMapWidget(panel->win);
173 wWindowMap(wwin);
175 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
177 result = panel->result;
179 WMUnmapWidget(panel->win);
181 wUnmanageWindow(wwin, False, False);
183 WMDestroyAlertPanel(panel);
185 XDestroyWindow(dpy, parent);
187 return result;
192 wInputDialog(WScreen *scr, char *title, char *message, char **text)
194 WWindow *wwin;
195 Window parent;
196 WMInputPanel *panel;
197 char *result;
198 WMPoint center;
200 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text,
201 _("OK"), _("Cancel"));
204 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
205 XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
207 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
209 center = getCenter(scr, 320, 160);
210 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y,
211 320, 160);
213 wwin->client_leader = WMWidgetXID(panel->win);
215 WMMapWidget(panel->win);
217 wWindowMap(wwin);
219 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
221 if (panel->result == WAPRDefault)
222 result = WMGetTextFieldText(panel->text);
223 else
224 result = NULL;
226 wUnmanageWindow(wwin, False, False);
228 WMDestroyInputPanel(panel);
230 XDestroyWindow(dpy, parent);
232 if (result==NULL)
233 return False;
234 else {
235 if (*text)
236 wfree(*text);
237 *text = result;
239 return True;
245 *****************************************************************
246 * Icon Selection Panel
247 *****************************************************************
250 typedef struct IconPanel {
252 WScreen *scr;
254 WMWindow *win;
256 WMLabel *dirLabel;
257 WMLabel *iconLabel;
259 WMList *dirList;
260 WMList *iconList;
261 WMFont *normalfont;
263 WMButton *previewButton;
265 WMLabel *iconView;
267 WMLabel *fileLabel;
268 WMTextField *fileField;
270 WMButton *okButton;
271 WMButton *cancelButton;
272 #if 0
273 WMButton *chooseButton;
274 #endif
275 short done;
276 short result;
277 short preview;
278 } IconPanel;
282 static void
283 listPixmaps(WScreen *scr, WMList *lPtr, char *path)
285 struct dirent *dentry;
286 DIR *dir;
287 char pbuf[PATH_MAX+16];
288 char *apath;
289 IconPanel *panel = WMGetHangedData(lPtr);
291 panel->preview = False;
293 apath = wexpandpath(path);
294 dir = opendir(apath);
296 if (!dir) {
297 char *msg;
298 char *tmp;
299 tmp = _("Could not open directory ");
300 msg = wmalloc(strlen(tmp)+strlen(path)+6);
301 strcpy(msg, tmp);
302 strcat(msg, path);
304 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
305 wfree(msg);
306 wfree(apath);
307 return;
310 /* list contents in the column */
311 while ((dentry = readdir(dir))) {
312 struct stat statb;
314 if (strcmp(dentry->d_name, ".")==0 ||
315 strcmp(dentry->d_name, "..")==0)
316 continue;
318 strcpy(pbuf, apath);
319 strcat(pbuf, "/");
320 strcat(pbuf, dentry->d_name);
322 if (stat(pbuf, &statb)<0)
323 continue;
325 if (statb.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)
326 && statb.st_mode & (S_IFREG|S_IFLNK)) {
327 WMAddListItem(lPtr, dentry->d_name);
330 WMSortListItems(lPtr);
332 closedir(dir);
333 wfree(apath);
334 panel->preview = True;
339 static void
340 setViewedImage(IconPanel *panel, char *file)
342 WMPixmap *pixmap;
343 RColor color;
345 color.red = 0xae;
346 color.green = 0xaa;
347 color.blue = 0xae;
348 color.alpha = 0;
349 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win),
350 file, &color);
351 if (!pixmap) {
352 WMSetButtonEnabled(panel->okButton, False);
354 WMSetLabelText(panel->iconView, _("Could not load image file "));
356 WMSetLabelImage(panel->iconView, NULL);
357 } else {
358 WMSetButtonEnabled(panel->okButton, True);
360 WMSetLabelText(panel->iconView, NULL);
361 WMSetLabelImage(panel->iconView, pixmap);
362 WMReleasePixmap(pixmap);
367 static void
368 listCallback(void *self, void *data)
370 WMList *lPtr = (WMList*)self;
371 IconPanel *panel = (IconPanel*)data;
372 char *path;
374 if (lPtr==panel->dirList) {
375 WMListItem *item = WMGetListSelectedItem(lPtr);
377 if (item == NULL)
378 return;
379 path = item->text;
381 WMSetTextFieldText(panel->fileField, path);
383 WMSetLabelImage(panel->iconView, NULL);
385 WMSetButtonEnabled(panel->okButton, False);
387 WMClearList(panel->iconList);
388 listPixmaps(panel->scr, panel->iconList, path);
389 } else {
390 char *tmp, *iconFile;
391 WMListItem *item = WMGetListSelectedItem(panel->dirList);
393 if (item == NULL)
394 return;
395 path = item->text;
396 tmp = wexpandpath(path);
398 item = WMGetListSelectedItem(panel->iconList);
399 if (item == NULL)
400 return;
401 iconFile = item->text;
403 path = wmalloc(strlen(tmp)+strlen(iconFile)+4);
404 strcpy(path, tmp);
405 strcat(path, "/");
406 strcat(path, iconFile);
407 wfree(tmp);
408 WMSetTextFieldText(panel->fileField, path);
409 setViewedImage(panel, path);
410 wfree(path);
415 static void
416 listIconPaths(WMList *lPtr)
418 char *paths;
419 char *path;
421 paths = wstrdup(wPreferences.icon_path);
423 path = strtok(paths, ":");
425 do {
426 char *tmp;
428 tmp = wexpandpath(path);
429 /* do not sort, because the order implies the order of
430 * directories searched */
431 if (access(tmp, X_OK)==0)
432 WMAddListItem(lPtr, path);
433 wfree(tmp);
434 } while ((path=strtok(NULL, ":"))!=NULL);
436 wfree(paths);
440 void
441 drawIconProc(WMList *lPtr, int index, Drawable d, char *text, int state,
442 WMRect *rect)
444 IconPanel *panel = WMGetHangedData(lPtr);
445 WScreen *scr = panel->scr;
446 GC gc = scr->draw_gc;
447 GC copygc = scr->copy_gc;
448 char *file, *dirfile;
449 WMPixmap *pixmap;
450 WMColor *back;
451 WMSize size;
452 WMScreen *wmscr = WMWidgetScreen(panel->win);
453 RColor color;
454 int x, y, width, height, len;
456 if(!panel->preview) return;
458 x = rect->pos.x;
459 y = rect->pos.y;
460 width = rect->size.width;
461 height = rect->size.height;
463 back = (state & WLDSSelected) ? scr->white : scr->gray;
465 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
466 len = strlen(dirfile)+strlen(text)+4;
467 file = wmalloc(len);
468 snprintf(file, len, "%s/%s", dirfile, text);
469 wfree(dirfile);
471 color.red = WMRedComponentOfColor(back) >> 8;
472 color.green = WMGreenComponentOfColor(back) >> 8;
473 color.blue = WMBlueComponentOfColor(back) >> 8;
474 color.alpha = WMGetColorAlpha(back) >> 8;
476 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
477 wfree(file);
479 if (!pixmap) {
480 /*WMRemoveListItem(lPtr, index);*/
481 return;
484 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
486 XSetClipMask(dpy, gc, None);
487 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54);*/
488 XDrawLine(dpy, d, WMColorGC(scr->white), x, y+height-1, x+width, y+height-1);
490 size = WMGetPixmapSize(pixmap);
492 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
493 XSetClipOrigin(dpy, copygc, x + (width-size.width)/2, y+2);
494 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
495 size.width>100?100:size.width, size.height>64?64:size.height,
496 x + (width-size.width)/2, y+2);
499 int i,j;
500 int fheight = WMFontHeight(panel->normalfont);
501 int tlen = strlen(text);
502 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
503 int ofx, ofy;
505 ofx = x + (width - twidth)/2;
506 ofy = y + 64 - fheight;
508 for(i=-1;i<2;i++)
509 for(j=-1;j<2;j++)
510 WMDrawString(wmscr, d, scr->white, panel->normalfont,
511 ofx+i, ofy+j, text, tlen);
513 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy,
514 text, tlen);
517 WMReleasePixmap(pixmap);
518 /* I hope it is better to do not use cache / on my box it is fast nuff */
519 XFlush(dpy);
523 static void
524 buttonCallback(void *self, void *clientData)
526 WMButton *bPtr = (WMButton*)self;
527 IconPanel *panel = (IconPanel*)clientData;
530 if (bPtr==panel->okButton) {
531 panel->done = True;
532 panel->result = True;
533 } else if (bPtr==panel->cancelButton) {
534 panel->done = True;
535 panel->result = False;
536 } else if (bPtr==panel->previewButton) {
537 /**** Previewer ****/
538 WMSetButtonEnabled(bPtr, False);
539 WMSetListUserDrawItemHeight(panel->iconList, 68);
540 WMSetListUserDrawProc(panel->iconList, drawIconProc);
541 WMRedisplayWidget(panel->iconList);
542 /* for draw proc to access screen/gc */
543 /*** end preview ***/
545 #if 0
546 else if (bPtr==panel->chooseButton) {
547 WMOpenPanel *op;
549 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
551 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
552 char *path;
553 path = WMGetFilePanelFile(op);
554 WMSetTextFieldText(panel->fileField, path);
555 setViewedImage(panel, path);
556 wfree(path);
558 WMDestroyFilePanel(op);
560 #endif
564 static void
565 keyPressHandler(XEvent *event, void *data)
567 IconPanel *panel = (IconPanel*)data;
568 char buffer[32];
569 int count;
570 KeySym ksym;
571 int iidx;
572 int didx;
573 int item;
574 WMList *list = NULL;
576 if (event->type == KeyRelease)
577 return;
579 buffer[0] = 0;
580 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
583 iidx = WMGetListSelectedItemRow(panel->iconList);
584 didx = WMGetListSelectedItemRow(panel->dirList);
586 switch (ksym) {
587 case XK_Up:
588 if (iidx > 0)
589 item = iidx-1;
590 else
591 item = iidx;
592 list = panel->iconList;
593 break;
594 case XK_Down:
595 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
596 item = iidx+1;
597 else
598 item = iidx;
599 list = panel->iconList;
600 break;
601 case XK_Home:
602 item = 0;
603 list = panel->iconList;
604 break;
605 case XK_End:
606 item = WMGetListNumberOfRows(panel->iconList) - 1;
607 list = panel->iconList;
608 break;
609 case XK_Next:
610 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
611 item = didx + 1;
612 else
613 item = didx;
614 list = panel->dirList;
615 break;
616 case XK_Prior:
617 if (didx > 0)
618 item = didx - 1;
619 else
620 item = 0;
621 list = panel->dirList;
622 break;
623 case XK_Return:
624 WMPerformButtonClick(panel->okButton);
625 break;
626 case XK_Escape:
627 WMPerformButtonClick(panel->cancelButton);
628 break;
631 if (list) {
632 WMSelectListItem(list, item);
633 WMSetListPosition(list, item - 5);
634 listCallback(list, panel);
640 Bool
641 wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
643 WWindow *wwin;
644 Window parent;
645 IconPanel *panel;
646 WMColor *color;
647 WMFont *boldFont;
649 panel = wmalloc(sizeof(IconPanel));
650 memset(panel, 0, sizeof(IconPanel));
652 panel->scr = scr;
654 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
655 WMResizeWidget(panel->win, 450, 280);
657 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask|KeyReleaseMask,
658 keyPressHandler, panel);
661 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
662 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
664 panel->dirLabel = WMCreateLabel(panel->win);
665 WMResizeWidget(panel->dirLabel, 200, 20);
666 WMMoveWidget(panel->dirLabel, 10, 7);
667 WMSetLabelText(panel->dirLabel, _("Directories"));
668 WMSetLabelFont(panel->dirLabel, boldFont);
669 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
671 WMSetLabelRelief(panel->dirLabel, WRSunken);
673 panel->iconLabel = WMCreateLabel(panel->win);
674 WMResizeWidget(panel->iconLabel, 140, 20);
675 WMMoveWidget(panel->iconLabel, 215, 7);
676 WMSetLabelText(panel->iconLabel, _("Icons"));
677 WMSetLabelFont(panel->iconLabel, boldFont);
678 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
680 WMReleaseFont(boldFont);
682 color = WMWhiteColor(scr->wmscreen);
683 WMSetLabelTextColor(panel->dirLabel, color);
684 WMSetLabelTextColor(panel->iconLabel, color);
685 WMReleaseColor(color);
687 color = WMDarkGrayColor(scr->wmscreen);
688 WMSetWidgetBackgroundColor(panel->iconLabel, color);
689 WMSetWidgetBackgroundColor(panel->dirLabel, color);
690 WMReleaseColor(color);
692 WMSetLabelRelief(panel->iconLabel, WRSunken);
694 panel->dirList = WMCreateList(panel->win);
695 WMResizeWidget(panel->dirList, 200, 170);
696 WMMoveWidget(panel->dirList, 10, 30);
697 WMSetListAction(panel->dirList, listCallback, panel);
699 panel->iconList = WMCreateList(panel->win);
700 WMResizeWidget(panel->iconList, 140, 170);
701 WMMoveWidget(panel->iconList, 215, 30);
702 WMSetListAction(panel->iconList, listCallback, panel);
704 WMHangData(panel->iconList,panel);
706 panel->previewButton = WMCreateCommandButton(panel->win);
707 WMResizeWidget(panel->previewButton, 75, 26);
708 WMMoveWidget(panel->previewButton, 365, 130);
709 WMSetButtonText(panel->previewButton, _("Preview"));
710 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
712 panel->iconView = WMCreateLabel(panel->win);
713 WMResizeWidget(panel->iconView, 75, 75);
714 WMMoveWidget(panel->iconView, 365, 40);
715 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
716 WMSetLabelRelief(panel->iconView, WRSunken);
717 WMSetLabelTextAlignment(panel->iconView, WACenter);
719 panel->fileLabel = WMCreateLabel(panel->win);
720 WMResizeWidget(panel->fileLabel, 80, 20);
721 WMMoveWidget(panel->fileLabel, 10, 210);
722 WMSetLabelText(panel->fileLabel, _("File Name:"));
724 panel->fileField = WMCreateTextField(panel->win);
725 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
726 WMResizeWidget(panel->fileField, 345, 20);
727 WMMoveWidget(panel->fileField, 95, 210);
728 WMSetTextFieldEditable(panel->fileField, False);
730 panel->okButton = WMCreateCommandButton(panel->win);
731 WMResizeWidget(panel->okButton, 80, 26);
732 WMMoveWidget(panel->okButton, 360, 240);
733 WMSetButtonText(panel->okButton, _("OK"));
734 WMSetButtonEnabled(panel->okButton, False);
735 WMSetButtonAction(panel->okButton, buttonCallback, panel);
737 panel->cancelButton = WMCreateCommandButton(panel->win);
738 WMResizeWidget(panel->cancelButton, 80, 26);
739 WMMoveWidget(panel->cancelButton, 270, 240);
740 WMSetButtonText(panel->cancelButton, _("Cancel"));
741 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
742 #if 0
743 panel->chooseButton = WMCreateCommandButton(panel->win);
744 WMResizeWidget(panel->chooseButton, 110, 26);
745 WMMoveWidget(panel->chooseButton, 150, 240);
746 WMSetButtonText(panel->chooseButton, _("Choose File"));
747 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
748 #endif
749 WMRealizeWidget(panel->win);
750 WMMapSubwidgets(panel->win);
752 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
754 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
757 char *tmp;
758 int len = (instance ? strlen(instance) : 0)
759 + (class ? strlen(class) : 0) + 32;
760 WMPoint center;
762 tmp = wmalloc(len);
764 if (tmp && (instance || class))
765 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
766 else
767 strcpy(tmp, _("Icon Chooser"));
769 center = getCenter(scr, 450, 280);
771 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x,center.y,
772 450, 280);
773 wfree(tmp);
776 /* put icon paths in the list */
777 listIconPaths(panel->dirList);
779 WMMapWidget(panel->win);
781 wWindowMap(wwin);
783 while (!panel->done) {
784 XEvent event;
786 WMNextEvent(dpy, &event);
787 WMHandleEvent(&event);
790 if (panel->result) {
791 char *defaultPath, *wantedPath;
793 /* check if the file the user selected is not the one that
794 * would be loaded by default with the current search path */
795 *file = WMGetListSelectedItem(panel->iconList)->text;
796 if ((*file)[0]==0) {
797 wfree(*file);
798 *file = NULL;
799 } else {
800 defaultPath = FindImage(wPreferences.icon_path, *file);
801 wantedPath = WMGetTextFieldText(panel->fileField);
802 /* if the file is not the default, use full path */
803 if (strcmp(wantedPath, defaultPath)!=0) {
804 *file = wantedPath;
805 } else {
806 *file = wstrdup(*file);
807 wfree(wantedPath);
809 wfree(defaultPath);
811 } else {
812 *file = NULL;
815 WMReleaseFont(panel->normalfont);
817 WMUnmapWidget(panel->win);
819 WMDestroyWidget(panel->win);
821 wUnmanageWindow(wwin, False, False);
823 wfree(panel);
825 XDestroyWindow(dpy, parent);
827 return panel->result;
832 ***********************************************************************
833 * Info Panel
834 ***********************************************************************
838 typedef struct {
839 WScreen *scr;
841 WWindow *wwin;
843 WMWindow *win;
845 WMLabel *logoL;
846 WMLabel *name1L;
847 WMLabel *name2L;
849 WMLabel *versionL;
851 WMLabel *infoL;
853 WMLabel *copyrL;
855 #ifdef SILLYNESS
856 WMHandlerID timer;
857 int cycle;
858 RImage *icon;
859 RImage *pic;
860 WMPixmap *oldPix;
861 WMFont *oldFont;
862 char *str;
863 int x;
864 #endif
865 } InfoPanel;
869 #define COPYRIGHT_TEXT \
870 "Copyright \xa9 1997-2002 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
871 "Copyright \xa9 1998-2002 Dan Pascu <dan@windowmaker.org>"
875 static InfoPanel *thePanel = NULL;
877 static void
878 destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
880 #ifdef SILLYNESS
881 if (thePanel->timer) {
882 WMDeleteTimerHandler(thePanel->timer);
884 if (thePanel->oldPix) {
885 WMReleasePixmap(thePanel->oldPix);
887 if (thePanel->oldFont) {
888 WMReleaseFont(thePanel->oldFont);
890 if (thePanel->icon) {
891 RReleaseImage(thePanel->icon);
893 if (thePanel->pic) {
894 RReleaseImage(thePanel->pic);
896 #endif /* SILLYNESS */
897 WMUnmapWidget(thePanel);
899 wUnmanageWindow(thePanel->wwin, False, False);
901 WMDestroyWidget(thePanel->win);
903 wfree(thePanel);
905 thePanel = NULL;
909 WMPixmap*
910 renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
912 WMPixmap *wpix = NULL;
913 Pixmap grad = None;
914 Pixmap mask = None;
915 RContext *rc = WMScreenRContext(scr);
916 XFontStruct *f = NULL;
917 int w, h;
918 GC gc = None;
920 f = XLoadQueryFont(dpy, font);
921 if (!f)
922 return NULL;
924 w = XTextWidth(f, text, strlen(text));
925 h = f->ascent+f->descent;
927 mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
928 gc = XCreateGC(dpy, mask, 0, NULL);
929 XSetForeground(dpy, gc, 0);
930 XSetFont(dpy, gc, f->fid);
931 XFillRectangle(dpy, mask, gc, 0, 0, w, h);
933 XSetForeground(dpy, gc, 1);
934 XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
935 XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
936 XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
938 grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
940 WMColor *color;
942 color = WMBlackColor(scr);
943 XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
944 WMReleaseColor(color);
947 wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
949 if (gc)
950 XFreeGC(dpy, gc);
951 XFreeFont(dpy, f);
953 return wpix;
956 #ifdef SILLYNESS
958 extern WMPixmap *DoXThing();
959 extern Bool InitXThing();
961 static void
962 logoPushCallback(void *data)
964 InfoPanel *panel = (InfoPanel*)data;
965 char buffer[512];
966 int i;
967 static int oldi = 0;
968 int len;
969 static int jingobeu[] = {
970 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
971 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
972 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
974 static int c = 0;
976 if (panel->x) {
977 XKeyboardControl kc;
978 XKeyboardState ksave;
979 unsigned long mask = KBBellPitch|KBBellDuration|KBBellPercent;
981 XGetKeyboardControl(dpy, &ksave);
983 if (panel->x > 0) {
984 if(jingobeu[panel->x-1]==0) {
985 panel->x=-1;
986 } else if (jingobeu[panel->x-1]<0) {
987 panel->x++;
988 c=jingobeu[panel->x-1]/50;
989 panel->x++;
990 } else if (c==0) {
991 kc.bell_percent=50;
992 kc.bell_pitch=jingobeu[panel->x-1];
993 panel->x++;
994 kc.bell_duration=jingobeu[panel->x-1];
995 c=jingobeu[panel->x-1]/50;
996 panel->x++;
997 XChangeKeyboardControl(dpy, mask, &kc);
998 XBell(dpy, 50);
999 XFlush(dpy);
1000 } else {
1001 c--;
1004 if (!(panel->cycle % 4)) {
1005 WMPixmap *p;
1007 p = DoXThing(panel->wwin);
1008 WMSetLabelImage(panel->logoL, p);
1010 kc.bell_pitch = ksave.bell_pitch;
1011 kc.bell_percent = ksave.bell_percent;
1012 kc.bell_duration = ksave.bell_duration;
1013 XChangeKeyboardControl(dpy, mask, &kc);
1014 } else if (panel->cycle < 30) {
1015 RImage *image;
1016 WMPixmap *pix;
1017 RColor gray;
1019 gray.red = 0xae; gray.green = 0xaa;
1020 gray.blue = 0xae; gray.alpha = 0;
1022 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
1023 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
1024 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
1025 RReleaseImage(image);
1026 WMSetLabelImage(panel->logoL, pix);
1027 WMReleasePixmap(pix);
1030 /* slow down text a little */
1031 i = (int)(panel->cycle * 50.0/85.0)%200;
1033 if (i != oldi) {
1034 len = strlen(panel->str);
1036 strncpy(buffer, panel->str, i<len ? i : len);
1037 if (i >= len)
1038 memset(&buffer[len], ' ', i-len);
1040 strncpy(buffer, panel->str, i<len ? i : len);
1041 if (i >= len)
1042 memset(&buffer[len], ' ', i-len);
1043 buffer[i]=0;
1045 WMSetLabelText(panel->versionL, buffer);
1047 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1049 oldi = i;
1052 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1053 panel->cycle++;
1057 static void
1058 handleLogoPush(XEvent *event, void *data)
1060 InfoPanel *panel = (InfoPanel*)data;
1061 static int broken = 0;
1062 static int clicks = 0;
1063 static char *pic_data[] = {
1064 "45 45 57 1",
1065 " c None",
1066 ". c #000000",
1067 "X c #383C00",
1068 "o c #515500",
1069 "O c #616100",
1070 "+ c #616900",
1071 "@ c #696D00",
1072 "# c #697100",
1073 "$ c #495100",
1074 "% c #202800",
1075 "& c #969600",
1076 "* c #CFCF00",
1077 "= c #D7DB00",
1078 "- c #D7D700",
1079 "; c #C7CB00",
1080 ": c #A6AA00",
1081 "> c #494900",
1082 ", c #8E8E00",
1083 "< c #DFE700",
1084 "1 c #F7FF00",
1085 "2 c #FFFF00",
1086 "3 c #E7EB00",
1087 "4 c #B6B600",
1088 "5 c #595900",
1089 "6 c #717500",
1090 "7 c #AEB200",
1091 "8 c #CFD300",
1092 "9 c #E7EF00",
1093 "0 c #EFF300",
1094 "q c #9EA200",
1095 "w c #F7FB00",
1096 "e c #F7F700",
1097 "r c #BEBE00",
1098 "t c #8E9200",
1099 "y c #EFF700",
1100 "u c #969A00",
1101 "i c #414500",
1102 "p c #595D00",
1103 "a c #E7E700",
1104 "s c #C7C700",
1105 "d c #797D00",
1106 "f c #BEC300",
1107 "g c #DFE300",
1108 "h c #868600",
1109 "j c #EFEF00",
1110 "k c #9E9E00",
1111 "l c #616500",
1112 "z c #DFDF00",
1113 "x c #868A00",
1114 "c c #969200",
1115 "v c #B6BA00",
1116 "b c #A6A600",
1117 "n c #8E8A00",
1118 "m c #717100",
1119 "M c #AEAE00",
1120 "N c #AEAA00",
1121 "B c #868200",
1122 " ............... ",
1123 " ....XoO+@##+O$%.... ",
1124 " ...%X&*========-;;:o... ",
1125 " ...>.>,<122222222222134@... ",
1126 " ..>5678912222222222222220q%.. ",
1127 " ..$.&-w2222222222222222222er>.. ",
1128 " ..O.t31222222222222222222222y4>.. ",
1129 " ...O5u3222222222222222222222222yri... ",
1130 " ..>p&a22222222222222222222222222wso.. ",
1131 " ..ids91222222222222222222222222222wfi.. ",
1132 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1133 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1134 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1135 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1136 "..io*222222222&...u22222222yt..%*22222220:%. ",
1137 "..>k02222222227...f222222222v..X=222222229t. ",
1138 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1139 ".%vw222222222221y2222222222219*y2222222222wd.",
1140 ".X;2222222222222222222222222222222222222222b.",
1141 ".i*2222222222222222222222222222222222222222v.",
1142 ".i*2222222222222222222222222222222222222222;.",
1143 ".i*22222222222222222222222222222222222222228.",
1144 ".>*2222222222222222222222222222222222222222=.",
1145 ".i*22222222222222222222222222222222222222228.",
1146 ".i*2222222222222222222222222222222222222222;.",
1147 ".X*222222222222222222222222222222we12222222r.",
1148 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1149 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1150 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1151 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1152 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1153 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1154 " ...:e2222218mdz22222222222222a&$vw222220@...",
1155 " ...O-122222y:.u02222222222229q$uj222221r... ",
1156 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1157 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1158 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1159 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1160 " ..Xb9122222109g-****;<y22221zn%... ",
1161 " ..X&801222222222222222222w-h.... ",
1162 " ...o:=022222222222222221=lX... ",
1163 " ..X@:;3w2222222222210fO... ",
1164 " ...XX&v8<30000003-N@... ",
1165 " .....XmnbN:q&Bo.... ",
1166 " ............ "
1168 static char *msgs[] = {
1169 "Have a nice day!",
1170 "Focus follow mouse users will burn in hell!!!",
1171 "Mooo Canada!!!!",
1172 "Hi! My name is bobby...",
1173 "AHH! The neurotic monkeys are after me!",
1174 "WE GET SIGNAL",
1175 "HOW ARE YOU GENTLEMEN?",
1176 "WHAT YOU SAY??",
1177 "SOMEBODY SET UP US THE BOMB",
1178 "ALL YOUR BASE ARE BELONG TO US!",
1179 "Oh My God!!! Larry is back!"
1183 clicks++;
1185 if (!panel->timer && !broken && clicks > 0) {
1186 WMFont *font;
1188 panel->x = 0;
1189 clicks = 0;
1190 if (!panel->icon) {
1191 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1192 if (!panel->icon) {
1193 broken = 1;
1194 return;
1195 } else {
1196 RColor color;
1198 color.red = 0xae; color.green = 0xaa;
1199 color.blue = 0xae; color.alpha = 0;
1201 panel->icon = RCloneImage(panel->icon);
1202 RCombineImageWithColor(panel->icon, &color);
1205 if (!panel->pic) {
1206 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1207 if (!panel->pic) {
1208 broken = 1;
1209 RReleaseImage(panel->icon);
1210 panel->icon = NULL;
1211 return;
1215 panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
1217 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1218 panel->cycle = 0;
1219 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1220 /* If we don't use a fixed font, scrolling will be jumpy */
1221 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1222 if ((panel->oldFont = WMGetLabelFont(panel->versionL))!=NULL)
1223 WMRetainFont(panel->oldFont);
1224 font = WMCreateFont(WMWidgetScreen(panel->versionL), "-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
1225 if (font) {
1226 WMSetLabelFont(panel->versionL, font);
1227 WMReleaseFont(font);
1229 WMSetLabelText(panel->versionL, "");
1230 } else if (panel->timer) {
1231 char version[20];
1233 panel->x = 0;
1234 clicks = 0;
1235 WMSetLabelImage(panel->logoL, panel->oldPix);
1236 WMReleasePixmap(panel->oldPix);
1237 panel->oldPix = NULL;
1239 WMDeleteTimerHandler(panel->timer);
1240 panel->timer = NULL;
1242 WMSetLabelFont(panel->versionL, panel->oldFont);
1243 if (panel->oldFont) {
1244 WMReleaseFont(panel->oldFont);
1245 panel->oldFont = NULL;
1247 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1248 WMSetLabelText(panel->versionL, version);
1249 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1253 XEvent ev;
1254 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
1255 ButtonPress, &ev));
1258 #endif /* SILLYNESS */
1261 void
1262 wShowInfoPanel(WScreen *scr)
1264 InfoPanel *panel;
1265 WMPixmap *logo;
1266 WMSize size;
1267 WMFont *font;
1268 char *strbuf = NULL;
1269 char buffer[256];
1270 Window parent;
1271 WWindow *wwin;
1272 RColor color1, color2;
1273 char **strl;
1274 int i;
1275 char *visuals[] = {
1276 "StaticGray",
1277 "GrayScale",
1278 "StaticColor",
1279 "PseudoColor",
1280 "TrueColor",
1281 "DirectColor"
1285 if (thePanel) {
1286 if (thePanel->scr == scr) {
1287 wRaiseFrame(thePanel->wwin->frame->core);
1288 wSetFocusTo(scr, thePanel->wwin);
1290 return;
1293 panel = wmalloc(sizeof(InfoPanel));
1294 memset(panel, 0, sizeof(InfoPanel));
1296 panel->scr = scr;
1298 panel->win = WMCreateWindow(scr->wmscreen, "info");
1299 WMResizeWidget(panel->win, 382, 230);
1301 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor*)NULL);
1302 if (!logo) {
1303 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1305 if (logo) {
1306 size = WMGetPixmapSize(logo);
1307 panel->logoL = WMCreateLabel(panel->win);
1308 WMResizeWidget(panel->logoL, 64, 64);
1309 WMMoveWidget(panel->logoL, 30, 20);
1310 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1311 WMSetLabelImage(panel->logoL, logo);
1312 #ifdef SILLYNESS
1313 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
1314 handleLogoPush, panel);
1315 #endif
1316 WMReleasePixmap(logo);
1319 panel->name1L = WMCreateLabel(panel->win);
1320 WMResizeWidget(panel->name1L, 240, 30);
1321 WMMoveWidget(panel->name1L, 100, 30);
1322 color1.red = 0;
1323 color1.green = 0;
1324 color1.blue = 0;
1325 color2.red = 0x50;
1326 color2.green = 0x50;
1327 color2.blue = 0x70;
1328 logo = renderText(scr->wmscreen, "Window Maker",
1329 "-*-utopia-*-r-*-*-25-*", &color1, &color2);
1330 if (logo) {
1331 WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
1332 WMSetLabelImage(panel->name1L, logo);
1333 WMReleasePixmap(logo);
1334 } else {
1335 font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
1336 if (font) {
1337 WMSetLabelFont(panel->name1L, font);
1338 WMReleaseFont(font);
1340 WMSetLabelTextAlignment(panel->name1L, WACenter);
1341 WMSetLabelText(panel->name1L, "Window Maker");
1344 panel->name2L = WMCreateLabel(panel->win);
1345 WMResizeWidget(panel->name2L, 240, 24);
1346 WMMoveWidget(panel->name2L, 100, 60);
1347 font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
1348 if (font) {
1349 WMSetLabelFont(panel->name2L, font);
1350 WMReleaseFont(font);
1351 font = NULL;
1353 WMSetLabelTextAlignment(panel->name2L, WACenter);
1354 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1357 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1358 panel->versionL = WMCreateLabel(panel->win);
1359 WMResizeWidget(panel->versionL, 310, 16);
1360 WMMoveWidget(panel->versionL, 30, 95);
1361 WMSetLabelTextAlignment(panel->versionL, WARight);
1362 WMSetLabelText(panel->versionL, buffer);
1363 WMSetLabelWraps(panel->versionL, False);
1365 panel->copyrL = WMCreateLabel(panel->win);
1366 WMResizeWidget(panel->copyrL, 340, 40);
1367 WMMoveWidget(panel->copyrL, 15, 185);
1368 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1369 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1370 /* we want the (c) character in the helvetica font */
1371 font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
1372 if (font) {
1373 WMSetLabelFont(panel->copyrL, font);
1374 WMReleaseFont(font);
1375 font = NULL;
1378 strbuf = NULL;
1379 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1380 (unsigned)scr->w_visual->visualid,
1381 visuals[scr->w_visual->class], scr->w_depth);
1383 strbuf = wstrappend(strbuf, buffer);
1385 switch (scr->w_depth) {
1386 case 15:
1387 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1388 break;
1389 case 16:
1390 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1391 break;
1392 case 24:
1393 case 32:
1394 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1395 break;
1396 default:
1397 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1<<scr->w_depth);
1398 strbuf = wstrappend(strbuf, buffer);
1399 break;
1403 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1405 struct mallinfo ma = mallinfo();
1406 snprintf(buffer, sizeof(buffer),
1407 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1408 (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024);
1410 strbuf = wstrappend(strbuf, buffer);
1412 #endif
1414 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1415 strl = RSupportedFileFormats();
1416 for (i=0; strl[i]!=NULL; i++) {
1417 strbuf = wstrappend(strbuf, strl[i]);
1418 strbuf = wstrappend(strbuf, " ");
1421 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1423 char *list[8];
1424 char buf[80];
1425 int j = 0;
1427 #ifdef MWM_HINTS
1428 list[j++] = "MWM";
1429 #endif
1430 #ifdef KWM_HINTS
1431 list[j++] = "KDE";
1432 #endif
1433 #ifdef GNOME_STUFF
1434 list[j++] = "GNOME";
1435 #endif
1436 #ifdef OLWM_HINTS
1437 list[j++] = "OLWM";
1438 #endif
1440 buf[0] = 0;
1441 for (i = 0; i < j; i++) {
1442 if (i > 0) {
1443 if (i == j - 1)
1444 strcat(buf, _(" and "));
1445 else
1446 strcat(buf, ", ");
1448 strcat(buf, list[i]);
1450 strbuf = wstrappend(strbuf, buf);
1453 if (wPreferences.no_sound) {
1454 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1455 } else {
1456 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1460 panel->infoL = WMCreateLabel(panel->win);
1461 WMResizeWidget(panel->infoL, 350, 75);
1462 WMMoveWidget(panel->infoL, 15, 115);
1463 WMSetLabelText(panel->infoL, strbuf);
1464 font = WMCreateFont(scr->wmscreen, HELVETICA10_FONT);
1465 if (font) {
1466 WMSetLabelFont(panel->infoL, font);
1467 WMReleaseFont(font);
1468 font = NULL;
1470 wfree(strbuf);
1473 WMRealizeWidget(panel->win);
1474 WMMapSubwidgets(panel->win);
1476 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1478 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1480 WMMapWidget(panel->win);
1483 WMPoint center = getCenter(scr, 382, 230);
1485 wwin = wManageInternalWindow(scr, parent, None, _("Info"),
1486 center.x, center.y,
1487 382, 230);
1490 WSETUFLAG(wwin, no_closable, 0);
1491 WSETUFLAG(wwin, no_close_button, 0);
1492 #ifdef XKB_BUTTON_HINT
1493 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1494 #endif
1495 wWindowUpdateButtonImages(wwin);
1496 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1497 wwin->frame->on_click_right = destroyInfoPanel;
1499 wWindowMap(wwin);
1501 panel->wwin = wwin;
1503 thePanel = panel;
1504 #ifdef SILLYNESS
1505 if (InitXThing(panel->scr)) {
1506 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1507 panel->cycle = 0;
1508 panel->x = 1;
1509 panel->str = _("Merry Christmas!");
1510 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1512 #endif
1517 ***********************************************************************
1518 * Legal Panel
1519 ***********************************************************************
1522 typedef struct {
1523 WScreen *scr;
1525 WWindow *wwin;
1527 WMWindow *win;
1529 WMLabel *licenseL;
1530 } LegalPanel;
1533 static LegalPanel *legalPanel = NULL;
1535 static void
1536 destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
1538 WMUnmapWidget(legalPanel->win);
1540 WMDestroyWidget(legalPanel->win);
1542 wUnmanageWindow(legalPanel->wwin, False, False);
1544 wfree(legalPanel);
1546 legalPanel = NULL;
1550 void
1551 wShowLegalPanel(WScreen *scr)
1553 LegalPanel *panel;
1554 Window parent;
1555 WWindow *wwin;
1557 if (legalPanel) {
1558 if (legalPanel->scr == scr) {
1559 wRaiseFrame(legalPanel->wwin->frame->core);
1560 wSetFocusTo(scr, legalPanel->wwin);
1562 return;
1565 panel = wmalloc(sizeof(LegalPanel));
1567 panel->scr = scr;
1569 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1570 WMResizeWidget(panel->win, 420, 250);
1573 panel->licenseL = WMCreateLabel(panel->win);
1574 WMSetLabelWraps(panel->licenseL, True);
1575 WMResizeWidget(panel->licenseL, 400, 230);
1576 WMMoveWidget(panel->licenseL, 10, 10);
1577 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1578 WMSetLabelText(panel->licenseL,
1579 _(" Window Maker is free software; you can redistribute it and/or\n"
1580 "modify it under the terms of the GNU General Public License as\n"
1581 "published by the Free Software Foundation; either version 2 of the\n"
1582 "License, or (at your option) any later version.\n\n"
1583 " Window Maker is distributed in the hope that it will be useful,\n"
1584 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1585 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1586 "See the GNU General Public License for more details.\n\n"
1587 " You should have received a copy of the GNU General Public\n"
1588 "License along with this program; if not, write to the Free Software\n"
1589 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n"
1590 "02111-1307, USA."));
1591 WMSetLabelRelief(panel->licenseL, WRGroove);
1593 WMRealizeWidget(panel->win);
1594 WMMapSubwidgets(panel->win);
1596 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1598 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1601 WMPoint center = getCenter(scr, 420, 250);
1603 wwin = wManageInternalWindow(scr, parent, None, _("Legal"),
1604 center.x, center.y,
1605 420, 250);
1608 WSETUFLAG(wwin, no_closable, 0);
1609 WSETUFLAG(wwin, no_close_button, 0);
1610 wWindowUpdateButtonImages(wwin);
1611 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1612 #ifdef XKB_BUTTON_HINT
1613 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1614 #endif
1615 wwin->frame->on_click_right = destroyLegalPanel;
1617 panel->wwin = wwin;
1619 WMMapWidget(panel->win);
1621 wWindowMap(wwin);
1623 legalPanel = panel;
1628 ***********************************************************************
1629 * Crashing Dialog Panel
1630 ***********************************************************************
1633 extern WDDomain *WDWindowAttributes;
1636 typedef struct _CrashPanel {
1637 WMWindow *win; /* main window */
1639 WMLabel *iconL; /* application icon */
1640 WMLabel *nameL; /* title of panel */
1642 WMFrame *sepF; /* separator frame */
1644 WMLabel *noteL; /* Title of note */
1645 WMLabel *note2L; /* body of note with what happened */
1647 WMFrame *whatF; /* "what to do next" frame */
1648 WMPopUpButton *whatP; /* action selection popup button */
1650 WMButton *okB; /* ok button */
1652 Bool done; /* if finished with this dialog */
1653 int action; /* what to do after */
1655 KeyCode retKey;
1657 } CrashPanel;
1660 static void
1661 handleKeyPress(XEvent *event, void *clientData)
1663 CrashPanel *panel = (CrashPanel*)clientData;
1665 if (event->xkey.keycode == panel->retKey) {
1666 WMPerformButtonClick(panel->okB);
1671 static void
1672 okButtonCallback(void *self, void *clientData)
1674 CrashPanel *panel = (CrashPanel*)clientData;
1676 panel->done = True;
1680 static void
1681 setCrashAction(void *self, void *clientData)
1683 WMPopUpButton *pop = (WMPopUpButton*)self;
1684 CrashPanel *panel = (CrashPanel*)clientData;
1686 panel->action = WMGetPopUpButtonSelectedItem(pop);
1690 static WMPixmap*
1691 getWindowMakerIconImage(WMScreen *scr)
1693 WMPropList *dict, *key, *option, *value=NULL;
1694 WMPixmap *pix=NULL;
1695 char *path;
1697 WMPLSetCaseSensitive(True);
1699 key = WMCreatePLString("Logo.WMPanel");
1700 option = WMCreatePLString("Icon");
1702 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1704 if (dict) {
1705 value = WMGetFromPLDictionary(dict, option);
1708 WMReleasePropList(key);
1709 WMReleasePropList(option);
1711 WMPLSetCaseSensitive(False);
1713 if (value && WMIsPLString(value)) {
1714 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1716 if (path) {
1717 RColor gray;
1719 gray.red = 0xae; gray.green = 0xaa;
1720 gray.blue = 0xae; gray.alpha = 0;
1722 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1723 wfree(path);
1727 return pix;
1731 #define PWIDTH 295
1732 #define PHEIGHT 345
1736 wShowCrashingDialogPanel(int whatSig)
1738 CrashPanel *panel;
1739 WMScreen *scr;
1740 WMFont *font;
1741 WMPixmap *logo;
1742 int screen_no, scr_width, scr_height;
1743 int action;
1744 char buf[256];
1746 panel = wmalloc(sizeof(CrashPanel));
1747 memset(panel, 0, sizeof(CrashPanel));
1749 screen_no = DefaultScreen(dpy);
1750 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1751 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1753 scr = WMCreateScreen(dpy, screen_no);
1754 if (!scr) {
1755 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1756 return WMAbort;
1759 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1761 panel->win = WMCreateWindow(scr, "crashingDialog");
1762 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1763 WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
1765 logo = getWindowMakerIconImage(scr);
1766 if (logo) {
1767 panel->iconL = WMCreateLabel(panel->win);
1768 WMResizeWidget(panel->iconL, 64, 64);
1769 WMMoveWidget(panel->iconL, 10, 10);
1770 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1771 WMSetLabelImage(panel->iconL, logo);
1774 panel->nameL = WMCreateLabel(panel->win);
1775 WMResizeWidget(panel->nameL, 190, 18);
1776 WMMoveWidget(panel->nameL, 80, 35);
1777 WMSetLabelTextAlignment(panel->nameL, WALeft);
1778 font = WMBoldSystemFontOfSize(scr, 18);
1779 WMSetLabelFont(panel->nameL, font);
1780 WMReleaseFont(font);
1781 WMSetLabelText(panel->nameL, _("Fatal error"));
1783 panel->sepF = WMCreateFrame(panel->win);
1784 WMResizeWidget(panel->sepF, PWIDTH+4, 2);
1785 WMMoveWidget(panel->sepF, -2, 80);
1787 panel->noteL = WMCreateLabel(panel->win);
1788 WMResizeWidget(panel->noteL, PWIDTH-20, 40);
1789 WMMoveWidget(panel->noteL, 10, 90);
1790 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1791 #ifdef SYS_SIGLIST_DECLARED
1792 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."),
1793 whatSig, sys_siglist[whatSig]);
1794 #else
1795 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1796 #endif
1797 WMSetLabelText(panel->noteL, buf);
1799 panel->note2L = WMCreateLabel(panel->win);
1800 WMResizeWidget(panel->note2L, PWIDTH-20, 100);
1801 WMMoveWidget(panel->note2L, 10, 130);
1802 WMSetLabelTextAlignment(panel->note2L, WALeft);
1803 WMSetLabelText(panel->note2L,
1804 _(" This fatal error occured probably due to a bug."
1805 " Please fill the included BUGFORM and "
1806 "report it to bugs@windowmaker.org."));
1807 WMSetLabelWraps(panel->note2L, True);
1810 panel->whatF = WMCreateFrame(panel->win);
1811 WMResizeWidget(panel->whatF, PWIDTH-20, 50);
1812 WMMoveWidget(panel->whatF, 10, 240);
1813 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1815 panel->whatP = WMCreatePopUpButton(panel->whatF);
1816 WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
1817 WMMoveWidget(panel->whatP, 35, 20);
1818 WMSetPopUpButtonPullsDown(panel->whatP, False);
1819 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1820 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1821 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1822 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1823 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1824 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1825 panel->action = WMRestart;
1827 WMMapSubwidgets(panel->whatF);
1829 panel->okB = WMCreateCommandButton(panel->win);
1830 WMResizeWidget(panel->okB, 80, 26);
1831 WMMoveWidget(panel->okB, 205, 309);
1832 WMSetButtonText(panel->okB, _("OK"));
1833 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1834 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1835 WMSetButtonImagePosition(panel->okB, WIPRight);
1836 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1838 panel->done = 0;
1840 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
1841 handleKeyPress, panel);
1843 WMRealizeWidget(panel->win);
1844 WMMapSubwidgets(panel->win);
1846 WMMapWidget(panel->win);
1848 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1850 while (!panel->done) {
1851 XEvent event;
1853 WMNextEvent(dpy, &event);
1854 WMHandleEvent(&event);
1857 action = panel->action;
1859 WMUnmapWidget(panel->win);
1860 WMDestroyWidget(panel->win);
1861 wfree(panel);
1863 return action;
1869 /*****************************************************************************
1870 * About GNUstep Panel
1871 *****************************************************************************/
1874 static void
1875 drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
1876 unsigned long blackPixel, unsigned long whitePixel)
1878 GC gc;
1879 XGCValues gcv;
1880 XRectangle rects[3];
1882 gcv.foreground = blackPixel;
1883 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1885 XFillArc(dpy, d, gc, width/45, height/45,
1886 width - 2*width/45, height - 2*height/45, 0, 360*64);
1888 rects[0].x = 0;
1889 rects[0].y = 37*height/45;
1890 rects[0].width = width/3;
1891 rects[0].height = height - rects[0].y;
1893 rects[1].x = rects[0].width;
1894 rects[1].y = height/2;
1895 rects[1].width = width - 2*width/3;
1896 rects[1].height = height - rects[1].y;
1898 rects[2].x = 2*width/3;
1899 rects[2].y = height - 37*height/45;
1900 rects[2].width = width/3;
1901 rects[2].height = height - rects[2].y;
1903 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1904 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1906 XSetForeground(dpy, gc, whitePixel);
1907 XFillArc(dpy, d, gc, width/45, height/45,
1908 width - 2*width/45, height - 2*height/45, 0, 360*64);
1910 XFreeGC(dpy, gc);
1914 typedef struct {
1915 WScreen *scr;
1917 WWindow *wwin;
1919 WMWindow *win;
1921 WMLabel *gstepL;
1922 WMLabel *textL;
1923 } GNUstepPanel;
1926 static GNUstepPanel *gnustepPanel = NULL;
1928 static void
1929 destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
1931 WMUnmapWidget(gnustepPanel->win);
1933 WMDestroyWidget(gnustepPanel->win);
1935 wUnmanageWindow(gnustepPanel->wwin, False, False);
1937 wfree(gnustepPanel);
1939 gnustepPanel = NULL;
1943 void
1944 wShowGNUstepPanel(WScreen *scr)
1946 GNUstepPanel *panel;
1947 Window parent;
1948 WWindow *wwin;
1949 WMPixmap *pixmap;
1950 WMColor *color;
1952 if (gnustepPanel) {
1953 if (gnustepPanel->scr == scr) {
1954 wRaiseFrame(gnustepPanel->wwin->frame->core);
1955 wSetFocusTo(scr, gnustepPanel->wwin);
1957 return;
1960 panel = wmalloc(sizeof(GNUstepPanel));
1962 panel->scr = scr;
1964 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1965 WMResizeWidget(panel->win, 325, 200);
1967 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130,
1968 WMScreenDepth(scr->wmscreen), True);
1970 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1972 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
1973 WMColorPixel(color), scr->white_pixel);
1975 WMReleaseColor(color);
1977 XSetForeground(dpy, scr->mono_gc, 0);
1978 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0,
1979 130, 130);
1980 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1982 panel->gstepL = WMCreateLabel(panel->win);
1983 WMResizeWidget(panel->gstepL, 285, 64);
1984 WMMoveWidget(panel->gstepL, 20, 0);
1985 WMSetLabelTextAlignment(panel->gstepL, WARight);
1986 WMSetLabelText(panel->gstepL, "GNUstep");
1988 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1990 WMSetLabelFont(panel->gstepL, font);
1991 WMReleaseFont(font);
1994 panel->textL = WMCreateLabel(panel->win);
1995 WMResizeWidget(panel->textL, 275, 130);
1996 WMMoveWidget(panel->textL, 30, 50);
1997 WMSetLabelTextAlignment(panel->textL, WARight);
1998 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1999 WMSetLabelText(panel->textL,
2000 _("Window Maker is part of the GNUstep project.\n"\
2001 "The GNUstep project aims to create a free\n"\
2002 "implementation of the OpenStep(tm) specification\n"\
2003 "which is a object-oriented framework for\n"\
2004 "creating advanced graphical, multi-platform\n"\
2005 "applications. Additionally, a development and\n"\
2006 "user desktop enviroment will be created on top\n"\
2007 "of the framework. For more information about\n"\
2008 "GNUstep, please visit: www.gnustep.org"));
2009 WMSetLabelImage(panel->textL, pixmap);
2011 WMReleasePixmap(pixmap);
2013 WMRealizeWidget(panel->win);
2014 WMMapSubwidgets(panel->win);
2016 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
2018 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
2021 WMPoint center = getCenter(scr, 325, 200);
2023 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"),
2024 center.x, center.y,
2025 325, 200);
2028 WSETUFLAG(wwin, no_closable, 0);
2029 WSETUFLAG(wwin, no_close_button, 0);
2030 wWindowUpdateButtonImages(wwin);
2031 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
2032 #ifdef XKB_BUTTON_HINT
2033 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
2034 #endif
2035 wwin->frame->on_click_right = destroyGNUstepPanel;
2037 panel->wwin = wwin;
2039 WMMapWidget(panel->win);
2041 wWindowMap(wwin);
2043 gnustepPanel = panel;