Change to the linux kernel coding style
[wmaker-crm.git] / src / dialog.c
1 /* dialog.c - dialog windows for internal use
2 *
3 * Window Maker window manager
4 *
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 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.
12 *
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.
17 *
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.
22 */
23
24 #include "wconfig.h"
25
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include <X11/keysym.h>
29
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>
38
39 #ifdef HAVE_MALLOC_H
40 #include <malloc.h>
41 #endif
42
43 #include <signal.h>
44 #ifdef __FreeBSD__
45 #include <sys/signal.h>
46 #endif
47
48 #ifndef PATH_MAX
49 #define PATH_MAX DEFAULT_PATH_MAX
50 #endif
51
52 #include "WindowMaker.h"
53 #include "GNUstep.h"
54 #include "screen.h"
55 #include "dialog.h"
56 #include "funcs.h"
57 #include "stacking.h"
58 #include "framewin.h"
59 #include "window.h"
60 #include "actions.h"
61 #include "defaults.h"
62 #include "xinerama.h"
63
64 extern WPreferences wPreferences;
65
66 static WMPoint getCenter(WScreen * scr, int width, int height)
67 {
68 return wGetPointToCenterRectInHead(scr, wGetHeadForPointerLocation(scr), width, height);
69 }
70
71 int wMessageDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
72 {
73 WMAlertPanel *panel;
74 Window parent;
75 WWindow *wwin;
76 int result;
77 WMPoint center;
78
79 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
80
81 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
82
83 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
84
85 center = getCenter(scr, 400, 180);
86 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
87 wwin->client_leader = WMWidgetXID(panel->win);
88
89 WMMapWidget(panel->win);
90
91 wWindowMap(wwin);
92
93 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
94
95 result = panel->result;
96
97 WMUnmapWidget(panel->win);
98
99 wUnmanageWindow(wwin, False, False);
100
101 WMDestroyAlertPanel(panel);
102
103 XDestroyWindow(dpy, parent);
104
105 return result;
106 }
107
108 void toggleSaveSession(WMWidget * w, void *data)
109 {
110 wPreferences.save_session_on_exit = WMGetButtonSelected((WMButton *) w);
111 }
112
113 int wExitDialog(WScreen * scr, char *title, char *message, char *defBtn, char *altBtn, char *othBtn)
114 {
115 WMAlertPanel *panel;
116 WMButton *saveSessionBtn;
117 Window parent;
118 WWindow *wwin;
119 WMPoint center;
120 int result;
121
122 panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, defBtn, altBtn, othBtn);
123
124 /* add save session button */
125 saveSessionBtn = WMCreateSwitchButton(panel->hbox);
126 WMSetButtonAction(saveSessionBtn, toggleSaveSession, NULL);
127 WMAddBoxSubview(panel->hbox, WMWidgetView(saveSessionBtn), False, True, 200, 0, 0);
128 WMSetButtonText(saveSessionBtn, _("Save workspace state"));
129 WMSetButtonSelected(saveSessionBtn, wPreferences.save_session_on_exit);
130 WMRealizeWidget(saveSessionBtn);
131 WMMapWidget(saveSessionBtn);
132
133 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
134
135 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
136
137 center = getCenter(scr, 400, 180);
138 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 400, 180);
139
140 wwin->client_leader = WMWidgetXID(panel->win);
141
142 WMMapWidget(panel->win);
143
144 wWindowMap(wwin);
145
146 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
147
148 result = panel->result;
149
150 WMUnmapWidget(panel->win);
151
152 wUnmanageWindow(wwin, False, False);
153
154 WMDestroyAlertPanel(panel);
155
156 XDestroyWindow(dpy, parent);
157
158 return result;
159 }
160
161 int wInputDialog(WScreen * scr, char *title, char *message, char **text)
162 {
163 WWindow *wwin;
164 Window parent;
165 WMInputPanel *panel;
166 char *result;
167 WMPoint center;
168
169 panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text, _("OK"), _("Cancel"));
170
171 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
172 XSelectInput(dpy, parent, KeyPressMask | KeyReleaseMask);
173
174 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
175
176 center = getCenter(scr, 320, 160);
177 wwin = wManageInternalWindow(scr, parent, None, NULL, center.x, center.y, 320, 160);
178
179 wwin->client_leader = WMWidgetXID(panel->win);
180
181 WMMapWidget(panel->win);
182
183 wWindowMap(wwin);
184
185 WMRunModalLoop(WMWidgetScreen(panel->win), WMWidgetView(panel->win));
186
187 if (panel->result == WAPRDefault)
188 result = WMGetTextFieldText(panel->text);
189 else
190 result = NULL;
191
192 wUnmanageWindow(wwin, False, False);
193
194 WMDestroyInputPanel(panel);
195
196 XDestroyWindow(dpy, parent);
197
198 if (result == NULL)
199 return False;
200 else {
201 if (*text)
202 wfree(*text);
203 *text = result;
204
205 return True;
206 }
207 }
208
209 /*
210 *****************************************************************
211 * Icon Selection Panel
212 *****************************************************************
213 */
214
215 typedef struct IconPanel {
216
217 WScreen *scr;
218
219 WMWindow *win;
220
221 WMLabel *dirLabel;
222 WMLabel *iconLabel;
223
224 WMList *dirList;
225 WMList *iconList;
226 WMFont *normalfont;
227
228 WMButton *previewButton;
229
230 WMLabel *iconView;
231
232 WMLabel *fileLabel;
233 WMTextField *fileField;
234
235 WMButton *okButton;
236 WMButton *cancelButton;
237 #if 0
238 WMButton *chooseButton;
239 #endif
240 short done;
241 short result;
242 short preview;
243 } IconPanel;
244
245 static void listPixmaps(WScreen * scr, WMList * lPtr, char *path)
246 {
247 struct dirent *dentry;
248 DIR *dir;
249 char pbuf[PATH_MAX + 16];
250 char *apath;
251 IconPanel *panel = WMGetHangedData(lPtr);
252
253 panel->preview = False;
254
255 apath = wexpandpath(path);
256 dir = opendir(apath);
257
258 if (!dir) {
259 char *msg;
260 char *tmp;
261 tmp = _("Could not open directory ");
262 msg = wmalloc(strlen(tmp) + strlen(path) + 6);
263 strcpy(msg, tmp);
264 strcat(msg, path);
265
266 wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
267 wfree(msg);
268 wfree(apath);
269 return;
270 }
271
272 /* list contents in the column */
273 while ((dentry = readdir(dir))) {
274 struct stat statb;
275
276 if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
277 continue;
278
279 strcpy(pbuf, apath);
280 strcat(pbuf, "/");
281 strcat(pbuf, dentry->d_name);
282
283 if (stat(pbuf, &statb) < 0)
284 continue;
285
286 if (statb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
287 && statb.st_mode & (S_IFREG | S_IFLNK)) {
288 WMAddListItem(lPtr, dentry->d_name);
289 }
290 }
291 WMSortListItems(lPtr);
292
293 closedir(dir);
294 wfree(apath);
295 panel->preview = True;
296 }
297
298 static void setViewedImage(IconPanel * panel, char *file)
299 {
300 WMPixmap *pixmap;
301 RColor color;
302
303 color.red = 0xae;
304 color.green = 0xaa;
305 color.blue = 0xae;
306 color.alpha = 0;
307 pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color);
308 if (!pixmap) {
309 WMSetButtonEnabled(panel->okButton, False);
310
311 WMSetLabelText(panel->iconView, _("Could not load image file "));
312
313 WMSetLabelImage(panel->iconView, NULL);
314 } else {
315 WMSetButtonEnabled(panel->okButton, True);
316
317 WMSetLabelText(panel->iconView, NULL);
318 WMSetLabelImage(panel->iconView, pixmap);
319 WMReleasePixmap(pixmap);
320 }
321 }
322
323 static void listCallback(void *self, void *data)
324 {
325 WMList *lPtr = (WMList *) self;
326 IconPanel *panel = (IconPanel *) data;
327 char *path;
328
329 if (lPtr == panel->dirList) {
330 WMListItem *item = WMGetListSelectedItem(lPtr);
331
332 if (item == NULL)
333 return;
334 path = item->text;
335
336 WMSetTextFieldText(panel->fileField, path);
337
338 WMSetLabelImage(panel->iconView, NULL);
339
340 WMSetButtonEnabled(panel->okButton, False);
341
342 WMClearList(panel->iconList);
343 listPixmaps(panel->scr, panel->iconList, path);
344 } else {
345 char *tmp, *iconFile;
346 WMListItem *item = WMGetListSelectedItem(panel->dirList);
347
348 if (item == NULL)
349 return;
350 path = item->text;
351 tmp = wexpandpath(path);
352
353 item = WMGetListSelectedItem(panel->iconList);
354 if (item == NULL)
355 return;
356 iconFile = item->text;
357
358 path = wmalloc(strlen(tmp) + strlen(iconFile) + 4);
359 strcpy(path, tmp);
360 strcat(path, "/");
361 strcat(path, iconFile);
362 wfree(tmp);
363 WMSetTextFieldText(panel->fileField, path);
364 setViewedImage(panel, path);
365 wfree(path);
366 }
367 }
368
369 static void listIconPaths(WMList * lPtr)
370 {
371 char *paths;
372 char *path;
373
374 paths = wstrdup(wPreferences.icon_path);
375
376 path = strtok(paths, ":");
377
378 do {
379 char *tmp;
380
381 tmp = wexpandpath(path);
382 /* do not sort, because the order implies the order of
383 * directories searched */
384 if (access(tmp, X_OK) == 0)
385 WMAddListItem(lPtr, path);
386 wfree(tmp);
387 } while ((path = strtok(NULL, ":")) != NULL);
388
389 wfree(paths);
390 }
391
392 static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
393 {
394 IconPanel *panel = WMGetHangedData(lPtr);
395 WScreen *scr = panel->scr;
396 GC gc = scr->draw_gc;
397 GC copygc = scr->copy_gc;
398 char *file, *dirfile;
399 WMPixmap *pixmap;
400 WMColor *back;
401 WMSize size;
402 WMScreen *wmscr = WMWidgetScreen(panel->win);
403 RColor color;
404 int x, y, width, height, len;
405
406 if (!panel->preview)
407 return;
408
409 x = rect->pos.x;
410 y = rect->pos.y;
411 width = rect->size.width;
412 height = rect->size.height;
413
414 back = (state & WLDSSelected) ? scr->white : scr->gray;
415
416 dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
417 len = strlen(dirfile) + strlen(text) + 4;
418 file = wmalloc(len);
419 snprintf(file, len, "%s/%s", dirfile, text);
420 wfree(dirfile);
421
422 color.red = WMRedComponentOfColor(back) >> 8;
423 color.green = WMGreenComponentOfColor(back) >> 8;
424 color.blue = WMBlueComponentOfColor(back) >> 8;
425 color.alpha = WMGetColorAlpha(back) >> 8;
426
427 pixmap = WMCreateBlendedPixmapFromFile(wmscr, file, &color);
428 wfree(file);
429
430 if (!pixmap) {
431 /*WMRemoveListItem(lPtr, index); */
432 return;
433 }
434
435 XFillRectangle(dpy, d, WMColorGC(back), x, y, width, height);
436
437 XSetClipMask(dpy, gc, None);
438 /*XDrawRectangle(dpy, d, WMColorGC(white), x+5, y+5, width-10, 54); */
439 XDrawLine(dpy, d, WMColorGC(scr->white), x, y + height - 1, x + width, y + height - 1);
440
441 size = WMGetPixmapSize(pixmap);
442
443 XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
444 XSetClipOrigin(dpy, copygc, x + (width - size.width) / 2, y + 2);
445 XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
446 size.width > 100 ? 100 : size.width, size.height > 64 ? 64 : size.height,
447 x + (width - size.width) / 2, y + 2);
448
449 {
450 int i, j;
451 int fheight = WMFontHeight(panel->normalfont);
452 int tlen = strlen(text);
453 int twidth = WMWidthOfString(panel->normalfont, text, tlen);
454 int ofx, ofy;
455
456 ofx = x + (width - twidth) / 2;
457 ofy = y + 64 - fheight;
458
459 for (i = -1; i < 2; i++)
460 for (j = -1; j < 2; j++)
461 WMDrawString(wmscr, d, scr->white, panel->normalfont,
462 ofx + i, ofy + j, text, tlen);
463
464 WMDrawString(wmscr, d, scr->black, panel->normalfont, ofx, ofy, text, tlen);
465 }
466
467 WMReleasePixmap(pixmap);
468 /* I hope it is better to do not use cache / on my box it is fast nuff */
469 XFlush(dpy);
470 }
471
472 static void buttonCallback(void *self, void *clientData)
473 {
474 WMButton *bPtr = (WMButton *) self;
475 IconPanel *panel = (IconPanel *) clientData;
476
477 if (bPtr == panel->okButton) {
478 panel->done = True;
479 panel->result = True;
480 } else if (bPtr == panel->cancelButton) {
481 panel->done = True;
482 panel->result = False;
483 } else if (bPtr == panel->previewButton) {
484 /**** Previewer ****/
485 WMSetButtonEnabled(bPtr, False);
486 WMSetListUserDrawItemHeight(panel->iconList, 68);
487 WMSetListUserDrawProc(panel->iconList, drawIconProc);
488 WMRedisplayWidget(panel->iconList);
489 /* for draw proc to access screen/gc */
490 /*** end preview ***/
491 }
492 #if 0
493 else if (bPtr == panel->chooseButton) {
494 WMOpenPanel *op;
495
496 op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
497
498 if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
499 char *path;
500 path = WMGetFilePanelFile(op);
501 WMSetTextFieldText(panel->fileField, path);
502 setViewedImage(panel, path);
503 wfree(path);
504 }
505 WMDestroyFilePanel(op);
506 }
507 #endif
508 }
509
510 static void keyPressHandler(XEvent * event, void *data)
511 {
512 IconPanel *panel = (IconPanel *) data;
513 char buffer[32];
514 int count;
515 KeySym ksym;
516 int iidx;
517 int didx;
518 int item = 0;
519 WMList *list = NULL;
520
521 if (event->type == KeyRelease)
522 return;
523
524 buffer[0] = 0;
525 count = XLookupString(&event->xkey, buffer, sizeof(buffer), &ksym, NULL);
526
527 iidx = WMGetListSelectedItemRow(panel->iconList);
528 didx = WMGetListSelectedItemRow(panel->dirList);
529
530 switch (ksym) {
531 case XK_Up:
532 if (iidx > 0)
533 item = iidx - 1;
534 else
535 item = iidx;
536 list = panel->iconList;
537 break;
538 case XK_Down:
539 if (iidx < WMGetListNumberOfRows(panel->iconList) - 1)
540 item = iidx + 1;
541 else
542 item = iidx;
543 list = panel->iconList;
544 break;
545 case XK_Home:
546 item = 0;
547 list = panel->iconList;
548 break;
549 case XK_End:
550 item = WMGetListNumberOfRows(panel->iconList) - 1;
551 list = panel->iconList;
552 break;
553 case XK_Next:
554 if (didx < WMGetListNumberOfRows(panel->dirList) - 1)
555 item = didx + 1;
556 else
557 item = didx;
558 list = panel->dirList;
559 break;
560 case XK_Prior:
561 if (didx > 0)
562 item = didx - 1;
563 else
564 item = 0;
565 list = panel->dirList;
566 break;
567 case XK_Return:
568 WMPerformButtonClick(panel->okButton);
569 break;
570 case XK_Escape:
571 WMPerformButtonClick(panel->cancelButton);
572 break;
573 }
574
575 if (list) {
576 WMSelectListItem(list, item);
577 WMSetListPosition(list, item - 5);
578 listCallback(list, panel);
579 }
580 }
581
582 Bool wIconChooserDialog(WScreen * scr, char **file, char *instance, char *class)
583 {
584 WWindow *wwin;
585 Window parent;
586 IconPanel *panel;
587 WMColor *color;
588 WMFont *boldFont;
589 Bool result;
590
591 panel = wmalloc(sizeof(IconPanel));
592 memset(panel, 0, sizeof(IconPanel));
593
594 panel->scr = scr;
595
596 panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
597 WMResizeWidget(panel->win, 450, 280);
598
599 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask | KeyReleaseMask, keyPressHandler, panel);
600
601 boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
602 panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
603
604 panel->dirLabel = WMCreateLabel(panel->win);
605 WMResizeWidget(panel->dirLabel, 200, 20);
606 WMMoveWidget(panel->dirLabel, 10, 7);
607 WMSetLabelText(panel->dirLabel, _("Directories"));
608 WMSetLabelFont(panel->dirLabel, boldFont);
609 WMSetLabelTextAlignment(panel->dirLabel, WACenter);
610
611 WMSetLabelRelief(panel->dirLabel, WRSunken);
612
613 panel->iconLabel = WMCreateLabel(panel->win);
614 WMResizeWidget(panel->iconLabel, 140, 20);
615 WMMoveWidget(panel->iconLabel, 215, 7);
616 WMSetLabelText(panel->iconLabel, _("Icons"));
617 WMSetLabelFont(panel->iconLabel, boldFont);
618 WMSetLabelTextAlignment(panel->iconLabel, WACenter);
619
620 WMReleaseFont(boldFont);
621
622 color = WMWhiteColor(scr->wmscreen);
623 WMSetLabelTextColor(panel->dirLabel, color);
624 WMSetLabelTextColor(panel->iconLabel, color);
625 WMReleaseColor(color);
626
627 color = WMDarkGrayColor(scr->wmscreen);
628 WMSetWidgetBackgroundColor(panel->iconLabel, color);
629 WMSetWidgetBackgroundColor(panel->dirLabel, color);
630 WMReleaseColor(color);
631
632 WMSetLabelRelief(panel->iconLabel, WRSunken);
633
634 panel->dirList = WMCreateList(panel->win);
635 WMResizeWidget(panel->dirList, 200, 170);
636 WMMoveWidget(panel->dirList, 10, 30);
637 WMSetListAction(panel->dirList, listCallback, panel);
638
639 panel->iconList = WMCreateList(panel->win);
640 WMResizeWidget(panel->iconList, 140, 170);
641 WMMoveWidget(panel->iconList, 215, 30);
642 WMSetListAction(panel->iconList, listCallback, panel);
643
644 WMHangData(panel->iconList, panel);
645
646 panel->previewButton = WMCreateCommandButton(panel->win);
647 WMResizeWidget(panel->previewButton, 75, 26);
648 WMMoveWidget(panel->previewButton, 365, 130);
649 WMSetButtonText(panel->previewButton, _("Preview"));
650 WMSetButtonAction(panel->previewButton, buttonCallback, panel);
651
652 panel->iconView = WMCreateLabel(panel->win);
653 WMResizeWidget(panel->iconView, 75, 75);
654 WMMoveWidget(panel->iconView, 365, 40);
655 WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
656 WMSetLabelRelief(panel->iconView, WRSunken);
657 WMSetLabelTextAlignment(panel->iconView, WACenter);
658
659 panel->fileLabel = WMCreateLabel(panel->win);
660 WMResizeWidget(panel->fileLabel, 80, 20);
661 WMMoveWidget(panel->fileLabel, 10, 210);
662 WMSetLabelText(panel->fileLabel, _("File Name:"));
663
664 panel->fileField = WMCreateTextField(panel->win);
665 WMSetViewNextResponder(WMWidgetView(panel->fileField), WMWidgetView(panel->win));
666 WMResizeWidget(panel->fileField, 345, 20);
667 WMMoveWidget(panel->fileField, 95, 210);
668 WMSetTextFieldEditable(panel->fileField, False);
669
670 panel->okButton = WMCreateCommandButton(panel->win);
671 WMResizeWidget(panel->okButton, 80, 26);
672 WMMoveWidget(panel->okButton, 360, 240);
673 WMSetButtonText(panel->okButton, _("OK"));
674 WMSetButtonEnabled(panel->okButton, False);
675 WMSetButtonAction(panel->okButton, buttonCallback, panel);
676
677 panel->cancelButton = WMCreateCommandButton(panel->win);
678 WMResizeWidget(panel->cancelButton, 80, 26);
679 WMMoveWidget(panel->cancelButton, 270, 240);
680 WMSetButtonText(panel->cancelButton, _("Cancel"));
681 WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
682 #if 0
683 panel->chooseButton = WMCreateCommandButton(panel->win);
684 WMResizeWidget(panel->chooseButton, 110, 26);
685 WMMoveWidget(panel->chooseButton, 150, 240);
686 WMSetButtonText(panel->chooseButton, _("Choose File"));
687 WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
688 #endif
689 WMRealizeWidget(panel->win);
690 WMMapSubwidgets(panel->win);
691
692 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
693
694 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
695
696 {
697 char *tmp;
698 int len = (instance ? strlen(instance) : 0)
699 + (class ? strlen(class) : 0) + 32;
700 WMPoint center;
701
702 tmp = wmalloc(len);
703
704 if (tmp && (instance || class))
705 snprintf(tmp, len, "%s [%s.%s]", _("Icon Chooser"), instance, class);
706 else
707 strcpy(tmp, _("Icon Chooser"));
708
709 center = getCenter(scr, 450, 280);
710
711 wwin = wManageInternalWindow(scr, parent, None, tmp, center.x, center.y, 450, 280);
712 wfree(tmp);
713 }
714
715 /* put icon paths in the list */
716 listIconPaths(panel->dirList);
717
718 WMMapWidget(panel->win);
719
720 wWindowMap(wwin);
721
722 while (!panel->done) {
723 XEvent event;
724
725 WMNextEvent(dpy, &event);
726 WMHandleEvent(&event);
727 }
728
729 if (panel->result) {
730 char *defaultPath, *wantedPath;
731
732 /* check if the file the user selected is not the one that
733 * would be loaded by default with the current search path */
734 *file = WMGetListSelectedItem(panel->iconList)->text;
735 if (**file == 0) {
736 wfree(*file);
737 *file = NULL;
738 } else {
739 defaultPath = FindImage(wPreferences.icon_path, *file);
740 wantedPath = WMGetTextFieldText(panel->fileField);
741 /* if the file is not the default, use full path */
742 if (strcmp(wantedPath, defaultPath) != 0) {
743 *file = wantedPath;
744 } else {
745 *file = wstrdup(*file);
746 wfree(wantedPath);
747 }
748 wfree(defaultPath);
749 }
750 } else {
751 *file = NULL;
752 }
753
754 result = panel->result;
755
756 WMReleaseFont(panel->normalfont);
757
758 WMUnmapWidget(panel->win);
759
760 WMDestroyWidget(panel->win);
761
762 wUnmanageWindow(wwin, False, False);
763
764 wfree(panel);
765
766 XDestroyWindow(dpy, parent);
767
768 return result;
769 }
770
771 /*
772 ***********************************************************************
773 * Info Panel
774 ***********************************************************************
775 */
776
777 typedef struct {
778 WScreen *scr;
779
780 WWindow *wwin;
781
782 WMWindow *win;
783
784 WMLabel *logoL;
785 WMLabel *name1L;
786 WMFrame *lineF;
787 WMLabel *name2L;
788
789 WMLabel *versionL;
790
791 WMLabel *infoL;
792
793 WMLabel *copyrL;
794
795 #ifdef SILLYNESS
796 WMHandlerID timer;
797 int cycle;
798 RImage *icon;
799 RImage *pic;
800 WMPixmap *oldPix;
801 WMFont *oldFont;
802 char *str;
803 int x;
804 #endif
805 } InfoPanel;
806
807 #define COPYRIGHT_TEXT \
808 "Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
809 "Copyright \xc2\xa9 1998-2006 Dan Pascu"
810
811 static InfoPanel *thePanel = NULL;
812
813 static void destroyInfoPanel(WCoreWindow * foo, void *data, XEvent * event)
814 {
815 #ifdef SILLYNESS
816 if (thePanel->timer) {
817 WMDeleteTimerHandler(thePanel->timer);
818 }
819 if (thePanel->oldPix) {
820 WMReleasePixmap(thePanel->oldPix);
821 }
822 if (thePanel->oldFont) {
823 WMReleaseFont(thePanel->oldFont);
824 }
825 if (thePanel->icon) {
826 RReleaseImage(thePanel->icon);
827 }
828 if (thePanel->pic) {
829 RReleaseImage(thePanel->pic);
830 }
831 #endif /* SILLYNESS */
832 WMUnmapWidget(thePanel);
833
834 wUnmanageWindow(thePanel->wwin, False, False);
835
836 WMDestroyWidget(thePanel->win);
837
838 wfree(thePanel);
839
840 thePanel = NULL;
841 }
842
843 #ifdef SILLYNESS
844
845 extern WMPixmap *DoXThing();
846 extern Bool InitXThing();
847
848 static void logoPushCallback(void *data)
849 {
850 InfoPanel *panel = (InfoPanel *) data;
851 char buffer[512];
852 int i;
853 static int oldi = 0;
854 int len;
855 static int jingobeu[] = {
856 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
857 329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
858 329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
859 };
860 static int c = 0;
861
862 if (panel->x) {
863 XKeyboardControl kc;
864 XKeyboardState ksave;
865 unsigned long mask = KBBellPitch | KBBellDuration | KBBellPercent;
866
867 XGetKeyboardControl(dpy, &ksave);
868
869 if (panel->x > 0) {
870 if (jingobeu[panel->x - 1] == 0) {
871 panel->x = -1;
872 } else if (jingobeu[panel->x - 1] < 0) {
873 panel->x++;
874 c = jingobeu[panel->x - 1] / 50;
875 panel->x++;
876 } else if (c == 0) {
877 kc.bell_percent = 50;
878 kc.bell_pitch = jingobeu[panel->x - 1];
879 panel->x++;
880 kc.bell_duration = jingobeu[panel->x - 1];
881 c = jingobeu[panel->x - 1] / 50;
882 panel->x++;
883 XChangeKeyboardControl(dpy, mask, &kc);
884 XBell(dpy, 50);
885 XFlush(dpy);
886 } else {
887 c--;
888 }
889 }
890 if (!(panel->cycle % 4)) {
891 WMPixmap *p;
892
893 p = DoXThing(panel->wwin);
894 WMSetLabelImage(panel->logoL, p);
895 }
896 kc.bell_pitch = ksave.bell_pitch;
897 kc.bell_percent = ksave.bell_percent;
898 kc.bell_duration = ksave.bell_duration;
899 XChangeKeyboardControl(dpy, mask, &kc);
900 } else if (panel->cycle < 30) {
901 RImage *image;
902 WMPixmap *pix;
903 RColor gray;
904
905 gray.red = 0xae;
906 gray.green = 0xaa;
907 gray.blue = 0xae;
908 gray.alpha = 0;
909
910 image = RScaleImage(panel->icon, panel->pic->width, panel->pic->height);
911 RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle * 255 / 30);
912 pix = WMCreateBlendedPixmapFromRImage(panel->scr->wmscreen, image, &gray);
913 RReleaseImage(image);
914 WMSetLabelImage(panel->logoL, pix);
915 WMReleasePixmap(pix);
916 }
917
918 /* slow down text a little */
919 i = (int)(panel->cycle * 50.0 / 85.0) % 200;
920
921 if (i != oldi) {
922 len = strlen(panel->str);
923
924 strncpy(buffer, panel->str, i < len ? i : len);
925 if (i >= len)
926 memset(&buffer[len], ' ', i - len);
927
928 strncpy(buffer, panel->str, i < len ? i : len);
929 if (i >= len)
930 memset(&buffer[len], ' ', i - len);
931 buffer[i] = 0;
932
933 WMSetLabelText(panel->versionL, buffer);
934
935 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
936
937 oldi = i;
938 }
939
940 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
941 panel->cycle++;
942 }
943
944 static void handleLogoPush(XEvent * event, void *data)
945 {
946 InfoPanel *panel = (InfoPanel *) data;
947 static int broken = 0;
948 static int clicks = 0;
949 static char *pic_data[] = {
950 "45 45 57 1",
951 " c None",
952 ". c #000000",
953 "X c #383C00",
954 "o c #515500",
955 "O c #616100",
956 "+ c #616900",
957 "@ c #696D00",
958 "# c #697100",
959 "$ c #495100",
960 "% c #202800",
961 "& c #969600",
962 "* c #CFCF00",
963 "= c #D7DB00",
964 "- c #D7D700",
965 "; c #C7CB00",
966 ": c #A6AA00",
967 "> c #494900",
968 ", c #8E8E00",
969 "< c #DFE700",
970 "1 c #F7FF00",
971 "2 c #FFFF00",
972 "3 c #E7EB00",
973 "4 c #B6B600",
974 "5 c #595900",
975 "6 c #717500",
976 "7 c #AEB200",
977 "8 c #CFD300",
978 "9 c #E7EF00",
979 "0 c #EFF300",
980 "q c #9EA200",
981 "w c #F7FB00",
982 "e c #F7F700",
983 "r c #BEBE00",
984 "t c #8E9200",
985 "y c #EFF700",
986 "u c #969A00",
987 "i c #414500",
988 "p c #595D00",
989 "a c #E7E700",
990 "s c #C7C700",
991 "d c #797D00",
992 "f c #BEC300",
993 "g c #DFE300",
994 "h c #868600",
995 "j c #EFEF00",
996 "k c #9E9E00",
997 "l c #616500",
998 "z c #DFDF00",
999 "x c #868A00",
1000 "c c #969200",
1001 "v c #B6BA00",
1002 "b c #A6A600",
1003 "n c #8E8A00",
1004 "m c #717100",
1005 "M c #AEAE00",
1006 "N c #AEAA00",
1007 "B c #868200",
1008 " ............... ",
1009 " ....XoO+@##+O$%.... ",
1010 " ...%X&*========-;;:o... ",
1011 " ...>.>,<122222222222134@... ",
1012 " ..>5678912222222222222220q%.. ",
1013 " ..$.&-w2222222222222222222er>.. ",
1014 " ..O.t31222222222222222222222y4>.. ",
1015 " ...O5u3222222222222222222222222yri... ",
1016 " ..>p&a22222222222222222222222222wso.. ",
1017 " ..ids91222222222222222222222222222wfi.. ",
1018 " ..X.7w222222wgs-w2222222213=g0222222<hi.. ",
1019 " ..Xuj2222222<@X5=222222229k@l:022222y4i.. ",
1020 " .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
1021 " ..o7y22222222v...r222222223hX.i82222221si.. ",
1022 "..io*222222222&...u22222222yt..%*22222220:%. ",
1023 "..>k02222222227...f222222222v..X=222222229t. ",
1024 "..dz12222222220ui:y2222222223d%qw222222221g. ",
1025 ".%vw222222222221y2222222222219*y2222222222wd.",
1026 ".X;2222222222222222222222222222222222222222b.",
1027 ".i*2222222222222222222222222222222222222222v.",
1028 ".i*2222222222222222222222222222222222222222;.",
1029 ".i*22222222222222222222222222222222222222228.",
1030 ".>*2222222222222222222222222222222222222222=.",
1031 ".i*22222222222222222222222222222222222222228.",
1032 ".i*2222222222222222222222222222222222222222;.",
1033 ".X*222222222222222222222222222222we12222222r.",
1034 ".Xs12222222w3aw22222222222222222y8s0222222wk.",
1035 ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
1036 "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
1037 "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
1038 " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
1039 " ..58222wagsh6ry222222222222221;>Of0w222y:...",
1040 " ...:e2222218mdz22222222222222a&$vw222220@...",
1041 " ...O-122222y:.u02222222222229q$uj222221r... ",
1042 " ..%&a1222223&573w2222222219NOxz122221z>... ",
1043 " ...t3222221-l$nr8ay1222yzbo,=12222w-5... ",
1044 " ..X:022222w-k+>o,7s**s7xOn=12221<f5... ",
1045 " ..o:9222221j8:&Bl>>>>ihv<12221=dX... ",
1046 " ..Xb9122222109g-****;<y22221zn%... ",
1047 " ..X&801222222222222222222w-h.... ",
1048 " ...o:=022222222222222221=lX... ",
1049 " ..X@:;3w2222222222210fO... ",
1050 " ...XX&v8<30000003-N@... ",
1051 " .....XmnbN:q&Bo.... ",
1052 " ............ "
1053 };
1054 static char *msgs[] = {
1055 "Have a nice day!",
1056 "Focus follow mouse users will burn in hell!!!",
1057 "Mooo Canada!!!!",
1058 "Hi! My name is bobby...",
1059 "AHH! The neurotic monkeys are after me!",
1060 "WE GET SIGNAL",
1061 "HOW ARE YOU GENTLEMEN?",
1062 "WHAT YOU SAY??",
1063 "SOMEBODY SET UP US THE BOMB",
1064 "ALL YOUR BASE ARE BELONG TO US!",
1065 "Oh My God!!! Larry is back!",
1066 "Alex Perez is aliveeeeeeee!!!"
1067 };
1068
1069 clicks++;
1070
1071 if (!panel->timer && !broken && clicks > 0) {
1072 WMFont *font;
1073
1074 panel->x = 0;
1075 clicks = 0;
1076 if (!panel->icon) {
1077 panel->icon = WMGetApplicationIconImage(panel->scr->wmscreen);
1078 if (!panel->icon) {
1079 broken = 1;
1080 return;
1081 } else {
1082 RColor color;
1083
1084 color.red = 0xae;
1085 color.green = 0xaa;
1086 color.blue = 0xae;
1087 color.alpha = 0;
1088
1089 panel->icon = RCloneImage(panel->icon);
1090 RCombineImageWithColor(panel->icon, &color);
1091 }
1092 }
1093 if (!panel->pic) {
1094 panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
1095 if (!panel->pic) {
1096 broken = 1;
1097 RReleaseImage(panel->icon);
1098 panel->icon = NULL;
1099 return;
1100 }
1101 }
1102
1103 panel->str = msgs[rand() % (sizeof(msgs) / sizeof(char *))];
1104
1105 panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
1106 panel->cycle = 0;
1107 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1108 /* If we don't use a fixed font, scrolling will be jumpy */
1109 /* Alternatively we can draw text in a pixmap and scroll it smoothly */
1110 if ((panel->oldFont = WMGetLabelFont(panel->versionL)) != NULL)
1111 WMRetainFont(panel->oldFont);
1112 font = WMCreateFont(WMWidgetScreen(panel->versionL),
1113 "Lucida Console,Courier New,monospace:pixelsize=12");
1114 if (font) {
1115 WMSetLabelFont(panel->versionL, font);
1116 WMReleaseFont(font);
1117 }
1118 WMSetLabelText(panel->versionL, "");
1119 } else if (panel->timer) {
1120 char version[20];
1121
1122 panel->x = 0;
1123 clicks = 0;
1124 WMSetLabelImage(panel->logoL, panel->oldPix);
1125 WMReleasePixmap(panel->oldPix);
1126 panel->oldPix = NULL;
1127
1128 WMDeleteTimerHandler(panel->timer);
1129 panel->timer = NULL;
1130
1131 WMSetLabelFont(panel->versionL, panel->oldFont);
1132 if (panel->oldFont) {
1133 WMReleaseFont(panel->oldFont);
1134 panel->oldFont = NULL;
1135 }
1136 snprintf(version, sizeof(version), _("Version %s"), VERSION);
1137 WMSetLabelText(panel->versionL, version);
1138 XFlush(WMScreenDisplay(WMWidgetScreen(panel->versionL)));
1139 }
1140
1141 {
1142 XEvent ev;
1143 while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL), ButtonPress, &ev)) ;
1144 }
1145 }
1146 #endif /* SILLYNESS */
1147
1148 void wShowInfoPanel(WScreen * scr)
1149 {
1150 InfoPanel *panel;
1151 WMPixmap *logo;
1152 WMSize size;
1153 WMFont *font;
1154 char *strbuf = NULL;
1155 char buffer[256];
1156 char *name;
1157 Window parent;
1158 WWindow *wwin;
1159 char **strl;
1160 int i, width = 50, sepHeight;
1161 char *visuals[] = {
1162 "StaticGray",
1163 "GrayScale",
1164 "StaticColor",
1165 "PseudoColor",
1166 "TrueColor",
1167 "DirectColor"
1168 };
1169
1170 if (thePanel) {
1171 if (thePanel->scr == scr) {
1172 wRaiseFrame(thePanel->wwin->frame->core);
1173 wSetFocusTo(scr, thePanel->wwin);
1174 }
1175 return;
1176 }
1177
1178 panel = wmalloc(sizeof(InfoPanel));
1179 memset(panel, 0, sizeof(InfoPanel));
1180
1181 panel->scr = scr;
1182
1183 panel->win = WMCreateWindow(scr->wmscreen, "info");
1184 WMResizeWidget(panel->win, 390, 230);
1185
1186 logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
1187 if (!logo) {
1188 logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen));
1189 }
1190 if (logo) {
1191 size = WMGetPixmapSize(logo);
1192 panel->logoL = WMCreateLabel(panel->win);
1193 WMResizeWidget(panel->logoL, 64, 64);
1194 WMMoveWidget(panel->logoL, 30, 20);
1195 WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
1196 WMSetLabelImage(panel->logoL, logo);
1197 #ifdef SILLYNESS
1198 WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask, handleLogoPush, panel);
1199 #endif
1200 WMReleasePixmap(logo);
1201 }
1202
1203 sepHeight = 3;
1204 panel->name1L = WMCreateLabel(panel->win);
1205 WMResizeWidget(panel->name1L, 240, 30 + 2);
1206 WMMoveWidget(panel->name1L, 100, 30 - 2 - sepHeight);
1207
1208 name = "Lucida Sans,Comic Sans MS,URW Gothic L,Trebuchet MS" ":italic:pixelsize=28:antialias=true";
1209 font = WMCreateFont(scr->wmscreen, name);
1210 strbuf = "Window Maker";
1211 if (font) {
1212 width = WMWidthOfString(font, strbuf, strlen(strbuf));
1213 WMSetLabelFont(panel->name1L, font);
1214 WMReleaseFont(font);
1215 }
1216 WMSetLabelTextAlignment(panel->name1L, WACenter);
1217 WMSetLabelText(panel->name1L, strbuf);
1218
1219 panel->lineF = WMCreateFrame(panel->win);
1220 WMResizeWidget(panel->lineF, width, sepHeight);
1221 WMMoveWidget(panel->lineF, 100 + (240 - width) / 2, 60 - sepHeight);
1222 WMSetFrameRelief(panel->lineF, WRSimple);
1223 WMSetWidgetBackgroundColor(panel->lineF, scr->black);
1224
1225 panel->name2L = WMCreateLabel(panel->win);
1226 WMResizeWidget(panel->name2L, 240, 24);
1227 WMMoveWidget(panel->name2L, 100, 60);
1228 name = "URW Gothic L,Nimbus Sans L:pixelsize=16:antialias=true";
1229 font = WMCreateFont(scr->wmscreen, name);
1230 if (font) {
1231 WMSetLabelFont(panel->name2L, font);
1232 WMReleaseFont(font);
1233 font = NULL;
1234 }
1235 WMSetLabelTextAlignment(panel->name2L, WACenter);
1236 WMSetLabelText(panel->name2L, _("Window Manager for X"));
1237
1238 snprintf(buffer, sizeof(buffer), _("Version %s"), VERSION);
1239 panel->versionL = WMCreateLabel(panel->win);
1240 WMResizeWidget(panel->versionL, 310, 16);
1241 WMMoveWidget(panel->versionL, 30, 95);
1242 WMSetLabelTextAlignment(panel->versionL, WARight);
1243 WMSetLabelText(panel->versionL, buffer);
1244 WMSetLabelWraps(panel->versionL, False);
1245
1246 panel->copyrL = WMCreateLabel(panel->win);
1247 WMResizeWidget(panel->copyrL, 360, 40);
1248 WMMoveWidget(panel->copyrL, 15, 185);
1249 WMSetLabelTextAlignment(panel->copyrL, WALeft);
1250 WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
1251 font = WMSystemFontOfSize(scr->wmscreen, 11);
1252 if (font) {
1253 WMSetLabelFont(panel->copyrL, font);
1254 WMReleaseFont(font);
1255 font = NULL;
1256 }
1257
1258 strbuf = NULL;
1259 snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
1260 (unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
1261
1262 strbuf = wstrappend(strbuf, buffer);
1263
1264 switch (scr->w_depth) {
1265 case 15:
1266 strbuf = wstrappend(strbuf, _("(32 thousand colors)\n"));
1267 break;
1268 case 16:
1269 strbuf = wstrappend(strbuf, _("(64 thousand colors)\n"));
1270 break;
1271 case 24:
1272 case 32:
1273 strbuf = wstrappend(strbuf, _("(16 million colors)\n"));
1274 break;
1275 default:
1276 snprintf(buffer, sizeof(buffer), _("(%d colors)\n"), 1 << scr->w_depth);
1277 strbuf = wstrappend(strbuf, buffer);
1278 break;
1279 }
1280
1281 #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
1282 {
1283 struct mallinfo ma = mallinfo();
1284 snprintf(buffer, sizeof(buffer),
1285 _("Total allocated memory: %i kB. Total memory in use: %i kB.\n"),
1286 (ma.arena + ma.hblkhd) / 1024, (ma.uordblks + ma.hblkhd) / 1024);
1287
1288 strbuf = wstrappend(strbuf, buffer);
1289 }
1290 #endif
1291
1292 strbuf = wstrappend(strbuf, _("Supported image formats: "));
1293 strl = RSupportedFileFormats();
1294 for (i = 0; strl[i] != NULL; i++) {
1295 strbuf = wstrappend(strbuf, strl[i]);
1296 strbuf = wstrappend(strbuf, " ");
1297 }
1298
1299 strbuf = wstrappend(strbuf, _("\nAdditional support for: "));
1300 {
1301 char *list[9];
1302 char buf[80];
1303 int j = 0;
1304
1305 #ifdef NETWM_HINTS
1306 list[j++] = "WMSPEC";
1307 #endif
1308 #ifdef MWM_HINTS
1309 list[j++] = "MWM";
1310 #endif
1311
1312 buf[0] = 0;
1313 for (i = 0; i < j; i++) {
1314 if (i > 0) {
1315 if (i == j - 1)
1316 strcat(buf, _(" and "));
1317 else
1318 strcat(buf, ", ");
1319 }
1320 strcat(buf, list[i]);
1321 }
1322 strbuf = wstrappend(strbuf, buf);
1323 }
1324
1325 if (wPreferences.no_sound) {
1326 strbuf = wstrappend(strbuf, _("\nSound disabled"));
1327 } else {
1328 strbuf = wstrappend(strbuf, _("\nSound enabled"));
1329 }
1330
1331 #ifdef VIRTUAL_DESKTOP
1332 if (wPreferences.vdesk_enable)
1333 strbuf = wstrappend(strbuf, _(", VirtualDesktop enabled"));
1334 else
1335 strbuf = wstrappend(strbuf, _(", VirtualDesktop disabled"));
1336 #endif
1337
1338 #ifdef XINERAMA
1339 strbuf = wstrappend(strbuf, _("\n"));
1340 #ifdef SOLARIS_XINERAMA
1341 strbuf = wstrappend(strbuf, _("Solaris "));
1342 #endif
1343 strbuf = wstrappend(strbuf, _("Xinerama: "));
1344 {
1345 char tmp[128];
1346 snprintf(tmp, sizeof(tmp) - 1, "%d heads found.", scr->xine_info.count);
1347 strbuf = wstrappend(strbuf, tmp);
1348 }
1349 #endif
1350
1351 panel->infoL = WMCreateLabel(panel->win);
1352 WMResizeWidget(panel->infoL, 350, 75);
1353 WMMoveWidget(panel->infoL, 15, 115);
1354 WMSetLabelText(panel->infoL, strbuf);
1355 font = WMSystemFontOfSize(scr->wmscreen, 11);
1356 if (font) {
1357 WMSetLabelFont(panel->infoL, font);
1358 WMReleaseFont(font);
1359 font = NULL;
1360 }
1361 wfree(strbuf);
1362
1363 WMRealizeWidget(panel->win);
1364 WMMapSubwidgets(panel->win);
1365
1366 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
1367
1368 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1369
1370 WMMapWidget(panel->win);
1371
1372 {
1373 WMPoint center = getCenter(scr, 382, 230);
1374
1375 wwin = wManageInternalWindow(scr, parent, None, _("Info"), center.x, center.y, 382, 230);
1376 }
1377
1378 WSETUFLAG(wwin, no_closable, 0);
1379 WSETUFLAG(wwin, no_close_button, 0);
1380 #ifdef XKB_BUTTON_HINT
1381 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1382 #endif
1383 wWindowUpdateButtonImages(wwin);
1384 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1385 wwin->frame->on_click_right = destroyInfoPanel;
1386
1387 wWindowMap(wwin);
1388
1389 panel->wwin = wwin;
1390
1391 thePanel = panel;
1392 #ifdef SILLYNESS
1393 if (InitXThing(panel->scr)) {
1394 panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
1395 panel->cycle = 0;
1396 panel->x = 1;
1397 panel->str = _("Merry Christmas!");
1398 panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
1399 }
1400 #endif
1401 }
1402
1403 /*
1404 ***********************************************************************
1405 * Legal Panel
1406 ***********************************************************************
1407 */
1408
1409 typedef struct {
1410 WScreen *scr;
1411
1412 WWindow *wwin;
1413
1414 WMWindow *win;
1415
1416 WMLabel *licenseL;
1417 } LegalPanel;
1418
1419 static LegalPanel *legalPanel = NULL;
1420
1421 static void destroyLegalPanel(WCoreWindow * foo, void *data, XEvent * event)
1422 {
1423 WMUnmapWidget(legalPanel->win);
1424
1425 WMDestroyWidget(legalPanel->win);
1426
1427 wUnmanageWindow(legalPanel->wwin, False, False);
1428
1429 wfree(legalPanel);
1430
1431 legalPanel = NULL;
1432 }
1433
1434 void wShowLegalPanel(WScreen * scr)
1435 {
1436 LegalPanel *panel;
1437 Window parent;
1438 WWindow *wwin;
1439
1440 if (legalPanel) {
1441 if (legalPanel->scr == scr) {
1442 wRaiseFrame(legalPanel->wwin->frame->core);
1443 wSetFocusTo(scr, legalPanel->wwin);
1444 }
1445 return;
1446 }
1447
1448 panel = wmalloc(sizeof(LegalPanel));
1449
1450 panel->scr = scr;
1451
1452 panel->win = WMCreateWindow(scr->wmscreen, "legal");
1453 WMResizeWidget(panel->win, 420, 250);
1454
1455 panel->licenseL = WMCreateLabel(panel->win);
1456 WMSetLabelWraps(panel->licenseL, True);
1457 WMResizeWidget(panel->licenseL, 400, 230);
1458 WMMoveWidget(panel->licenseL, 10, 10);
1459 WMSetLabelTextAlignment(panel->licenseL, WALeft);
1460 WMSetLabelText(panel->licenseL,
1461 _(" Window Maker is free software; you can redistribute it and/or\n"
1462 "modify it under the terms of the GNU General Public License as\n"
1463 "published by the Free Software Foundation; either version 2 of the\n"
1464 "License, or (at your option) any later version.\n\n"
1465 " Window Maker is distributed in the hope that it will be useful,\n"
1466 "but WITHOUT ANY WARRANTY; without even the implied warranty\n"
1467 "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
1468 "See the GNU General Public License for more details.\n\n"
1469 " You should have received a copy of the GNU General Public\n"
1470 "License along with this program; if not, write to the Free Software\n"
1471 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n" "02111-1307, USA."));
1472 WMSetLabelRelief(panel->licenseL, WRGroove);
1473
1474 WMRealizeWidget(panel->win);
1475 WMMapSubwidgets(panel->win);
1476
1477 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
1478
1479 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1480
1481 {
1482 WMPoint center = getCenter(scr, 420, 250);
1483
1484 wwin = wManageInternalWindow(scr, parent, None, _("Legal"), center.x, center.y, 420, 250);
1485 }
1486
1487 WSETUFLAG(wwin, no_closable, 0);
1488 WSETUFLAG(wwin, no_close_button, 0);
1489 wWindowUpdateButtonImages(wwin);
1490 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1491 #ifdef XKB_BUTTON_HINT
1492 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1493 #endif
1494 wwin->frame->on_click_right = destroyLegalPanel;
1495
1496 panel->wwin = wwin;
1497
1498 WMMapWidget(panel->win);
1499
1500 wWindowMap(wwin);
1501
1502 legalPanel = panel;
1503 }
1504
1505 /*
1506 ***********************************************************************
1507 * Crashing Dialog Panel
1508 ***********************************************************************
1509 */
1510
1511 extern WDDomain *WDWindowAttributes;
1512
1513 typedef struct _CrashPanel {
1514 WMWindow *win; /* main window */
1515
1516 WMLabel *iconL; /* application icon */
1517 WMLabel *nameL; /* title of panel */
1518
1519 WMFrame *sepF; /* separator frame */
1520
1521 WMLabel *noteL; /* Title of note */
1522 WMLabel *note2L; /* body of note with what happened */
1523
1524 WMFrame *whatF; /* "what to do next" frame */
1525 WMPopUpButton *whatP; /* action selection popup button */
1526
1527 WMButton *okB; /* ok button */
1528
1529 Bool done; /* if finished with this dialog */
1530 int action; /* what to do after */
1531
1532 KeyCode retKey;
1533
1534 } CrashPanel;
1535
1536 static void handleKeyPress(XEvent * event, void *clientData)
1537 {
1538 CrashPanel *panel = (CrashPanel *) clientData;
1539
1540 if (event->xkey.keycode == panel->retKey) {
1541 WMPerformButtonClick(panel->okB);
1542 }
1543 }
1544
1545 static void okButtonCallback(void *self, void *clientData)
1546 {
1547 CrashPanel *panel = (CrashPanel *) clientData;
1548
1549 panel->done = True;
1550 }
1551
1552 static void setCrashAction(void *self, void *clientData)
1553 {
1554 WMPopUpButton *pop = (WMPopUpButton *) self;
1555 CrashPanel *panel = (CrashPanel *) clientData;
1556
1557 panel->action = WMGetPopUpButtonSelectedItem(pop);
1558 }
1559
1560 /* Make this read the logo from a compiled in pixmap -Dan */
1561 static WMPixmap *getWindowMakerIconImage(WMScreen * scr)
1562 {
1563 WMPropList *dict, *key, *option, *value = NULL;
1564 WMPixmap *pix = NULL;
1565 char *path;
1566
1567 if (!WDWindowAttributes || !WDWindowAttributes->dictionary)
1568 return NULL;
1569
1570 WMPLSetCaseSensitive(True);
1571
1572 key = WMCreatePLString("Logo.WMPanel");
1573 option = WMCreatePLString("Icon");
1574
1575 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
1576
1577 if (dict) {
1578 value = WMGetFromPLDictionary(dict, option);
1579 }
1580
1581 WMReleasePropList(key);
1582 WMReleasePropList(option);
1583
1584 WMPLSetCaseSensitive(False);
1585
1586 if (value && WMIsPLString(value)) {
1587 path = FindImage(wPreferences.icon_path, WMGetFromPLString(value));
1588
1589 if (path) {
1590 RColor gray;
1591
1592 gray.red = 0xae;
1593 gray.green = 0xaa;
1594 gray.blue = 0xae;
1595 gray.alpha = 0;
1596
1597 pix = WMCreateBlendedPixmapFromFile(scr, path, &gray);
1598 wfree(path);
1599 }
1600 }
1601
1602 return pix;
1603 }
1604
1605 #define PWIDTH 295
1606 #define PHEIGHT 345
1607
1608 int wShowCrashingDialogPanel(int whatSig)
1609 {
1610 CrashPanel *panel;
1611 WMScreen *scr;
1612 WMFont *font;
1613 WMPixmap *logo;
1614 int screen_no, scr_width, scr_height;
1615 int action;
1616 char buf[256];
1617
1618 panel = wmalloc(sizeof(CrashPanel));
1619 memset(panel, 0, sizeof(CrashPanel));
1620
1621 screen_no = DefaultScreen(dpy);
1622 scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
1623 scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
1624
1625 scr = WMCreateScreen(dpy, screen_no);
1626 if (!scr) {
1627 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
1628 return WMAbort;
1629 }
1630
1631 panel->retKey = XKeysymToKeycode(dpy, XK_Return);
1632
1633 panel->win = WMCreateWindow(scr, "crashingDialog");
1634 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
1635 WMMoveWidget(panel->win, (scr_width - PWIDTH) / 2, (scr_height - PHEIGHT) / 2);
1636
1637 logo = getWindowMakerIconImage(scr);
1638 if (logo) {
1639 panel->iconL = WMCreateLabel(panel->win);
1640 WMResizeWidget(panel->iconL, 64, 64);
1641 WMMoveWidget(panel->iconL, 10, 10);
1642 WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
1643 WMSetLabelImage(panel->iconL, logo);
1644 }
1645
1646 panel->nameL = WMCreateLabel(panel->win);
1647 WMResizeWidget(panel->nameL, 200, 30);
1648 WMMoveWidget(panel->nameL, 80, 25);
1649 WMSetLabelTextAlignment(panel->nameL, WALeft);
1650 font = WMBoldSystemFontOfSize(scr, 24);
1651 WMSetLabelFont(panel->nameL, font);
1652 WMReleaseFont(font);
1653 WMSetLabelText(panel->nameL, _("Fatal error"));
1654
1655 panel->sepF = WMCreateFrame(panel->win);
1656 WMResizeWidget(panel->sepF, PWIDTH + 4, 2);
1657 WMMoveWidget(panel->sepF, -2, 80);
1658
1659 panel->noteL = WMCreateLabel(panel->win);
1660 WMResizeWidget(panel->noteL, PWIDTH - 20, 40);
1661 WMMoveWidget(panel->noteL, 10, 90);
1662 WMSetLabelTextAlignment(panel->noteL, WAJustified);
1663 #ifdef SYS_SIGLIST_DECLARED
1664 snprintf(buf, sizeof(buf), _("Window Maker received signal %i\n(%s)."), whatSig, sys_siglist[whatSig]);
1665 #else
1666 snprintf(buf, sizeof(buf), _("Window Maker received signal %i."), whatSig);
1667 #endif
1668 WMSetLabelText(panel->noteL, buf);
1669
1670 panel->note2L = WMCreateLabel(panel->win);
1671 WMResizeWidget(panel->note2L, PWIDTH - 20, 100);
1672 WMMoveWidget(panel->note2L, 10, 130);
1673 WMSetLabelTextAlignment(panel->note2L, WALeft);
1674 WMSetLabelText(panel->note2L,
1675 _(" This fatal error occured probably due to a bug."
1676 " Please fill the included BUGFORM and " "report it to bugs@windowmaker.info."));
1677 WMSetLabelWraps(panel->note2L, True);
1678
1679 panel->whatF = WMCreateFrame(panel->win);
1680 WMResizeWidget(panel->whatF, PWIDTH - 20, 50);
1681 WMMoveWidget(panel->whatF, 10, 240);
1682 WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
1683
1684 panel->whatP = WMCreatePopUpButton(panel->whatF);
1685 WMResizeWidget(panel->whatP, PWIDTH - 20 - 70, 20);
1686 WMMoveWidget(panel->whatP, 35, 20);
1687 WMSetPopUpButtonPullsDown(panel->whatP, False);
1688 WMSetPopUpButtonText(panel->whatP, _("Select action"));
1689 WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
1690 WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
1691 WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
1692 WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
1693 WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
1694 panel->action = WMRestart;
1695
1696 WMMapSubwidgets(panel->whatF);
1697
1698 panel->okB = WMCreateCommandButton(panel->win);
1699 WMResizeWidget(panel->okB, 80, 26);
1700 WMMoveWidget(panel->okB, 205, 309);
1701 WMSetButtonText(panel->okB, _("OK"));
1702 WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
1703 WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
1704 WMSetButtonImagePosition(panel->okB, WIPRight);
1705 WMSetButtonAction(panel->okB, okButtonCallback, panel);
1706
1707 panel->done = 0;
1708
1709 WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask, handleKeyPress, panel);
1710
1711 WMRealizeWidget(panel->win);
1712 WMMapSubwidgets(panel->win);
1713
1714 WMMapWidget(panel->win);
1715
1716 XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
1717
1718 while (!panel->done) {
1719 XEvent event;
1720
1721 WMNextEvent(dpy, &event);
1722 WMHandleEvent(&event);
1723 }
1724
1725 action = panel->action;
1726
1727 WMUnmapWidget(panel->win);
1728 WMDestroyWidget(panel->win);
1729 wfree(panel);
1730
1731 return action;
1732 }
1733
1734 /*****************************************************************************
1735 * About GNUstep Panel
1736 *****************************************************************************/
1737
1738 static void
1739 drawGNUstepLogo(Display * dpy, Drawable d, int width, int height,
1740 unsigned long blackPixel, unsigned long whitePixel)
1741 {
1742 GC gc;
1743 XGCValues gcv;
1744 XRectangle rects[3];
1745
1746 gcv.foreground = blackPixel;
1747 gc = XCreateGC(dpy, d, GCForeground, &gcv);
1748
1749 XFillArc(dpy, d, gc, width / 45, height / 45,
1750 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1751
1752 rects[0].x = 0;
1753 rects[0].y = 37 * height / 45;
1754 rects[0].width = width / 3;
1755 rects[0].height = height - rects[0].y;
1756
1757 rects[1].x = rects[0].width;
1758 rects[1].y = height / 2;
1759 rects[1].width = width - 2 * width / 3;
1760 rects[1].height = height - rects[1].y;
1761
1762 rects[2].x = 2 * width / 3;
1763 rects[2].y = height - 37 * height / 45;
1764 rects[2].width = width / 3;
1765 rects[2].height = height - rects[2].y;
1766
1767 XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
1768 XFillRectangle(dpy, d, gc, 0, 0, width, height);
1769
1770 XSetForeground(dpy, gc, whitePixel);
1771 XFillArc(dpy, d, gc, width / 45, height / 45,
1772 width - 2 * width / 45, height - 2 * height / 45, 0, 360 * 64);
1773
1774 XFreeGC(dpy, gc);
1775 }
1776
1777 typedef struct {
1778 WScreen *scr;
1779
1780 WWindow *wwin;
1781
1782 WMWindow *win;
1783
1784 WMLabel *gstepL;
1785 WMLabel *textL;
1786 } GNUstepPanel;
1787
1788 static GNUstepPanel *gnustepPanel = NULL;
1789
1790 static void destroyGNUstepPanel(WCoreWindow * foo, void *data, XEvent * event)
1791 {
1792 WMUnmapWidget(gnustepPanel->win);
1793
1794 WMDestroyWidget(gnustepPanel->win);
1795
1796 wUnmanageWindow(gnustepPanel->wwin, False, False);
1797
1798 wfree(gnustepPanel);
1799
1800 gnustepPanel = NULL;
1801 }
1802
1803 void wShowGNUstepPanel(WScreen * scr)
1804 {
1805 GNUstepPanel *panel;
1806 Window parent;
1807 WWindow *wwin;
1808 WMPixmap *pixmap;
1809 WMColor *color;
1810
1811 if (gnustepPanel) {
1812 if (gnustepPanel->scr == scr) {
1813 wRaiseFrame(gnustepPanel->wwin->frame->core);
1814 wSetFocusTo(scr, gnustepPanel->wwin);
1815 }
1816 return;
1817 }
1818
1819 panel = wmalloc(sizeof(GNUstepPanel));
1820
1821 panel->scr = scr;
1822
1823 panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
1824 WMResizeWidget(panel->win, 325, 205);
1825
1826 pixmap = WMCreatePixmap(scr->wmscreen, 130, 130, WMScreenDepth(scr->wmscreen), True);
1827
1828 color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
1829
1830 drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130, WMColorPixel(color), scr->white_pixel);
1831
1832 WMReleaseColor(color);
1833
1834 XSetForeground(dpy, scr->mono_gc, 0);
1835 XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0, 130, 130);
1836 drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
1837
1838 panel->gstepL = WMCreateLabel(panel->win);
1839 WMResizeWidget(panel->gstepL, 285, 64);
1840 WMMoveWidget(panel->gstepL, 20, 0);
1841 WMSetLabelTextAlignment(panel->gstepL, WARight);
1842 WMSetLabelText(panel->gstepL, "GNUstep");
1843 {
1844 WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
1845
1846 WMSetLabelFont(panel->gstepL, font);
1847 WMReleaseFont(font);
1848 }
1849
1850 panel->textL = WMCreateLabel(panel->win);
1851 WMResizeWidget(panel->textL, 305, 140);
1852 WMMoveWidget(panel->textL, 10, 50);
1853 WMSetLabelTextAlignment(panel->textL, WARight);
1854 WMSetLabelImagePosition(panel->textL, WIPOverlaps);
1855 WMSetLabelText(panel->textL,
1856 _("Window Maker is part of the GNUstep project.\n"
1857 "The GNUstep project aims to create a free\n"
1858 "implementation of the OpenStep(tm) specification\n"
1859 "which is a object-oriented framework for\n"
1860 "creating advanced graphical, multi-platform\n"
1861 "applications. Additionally, a development and\n"
1862 "user desktop enviroment will be created on top\n"
1863 "of the framework. For more information about\n"
1864 "GNUstep, please visit: www.gnustep.org"));
1865 WMSetLabelImage(panel->textL, pixmap);
1866
1867 WMReleasePixmap(pixmap);
1868
1869 WMRealizeWidget(panel->win);
1870 WMMapSubwidgets(panel->win);
1871
1872 parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
1873
1874 XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
1875
1876 {
1877 WMPoint center = getCenter(scr, 325, 200);
1878
1879 wwin = wManageInternalWindow(scr, parent, None, _("About GNUstep"), center.x, center.y, 325, 200);
1880 }
1881
1882 WSETUFLAG(wwin, no_closable, 0);
1883 WSETUFLAG(wwin, no_close_button, 0);
1884 wWindowUpdateButtonImages(wwin);
1885 wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
1886 #ifdef XKB_BUTTON_HINT
1887 wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
1888 #endif
1889 wwin->frame->on_click_right = destroyGNUstepPanel;
1890
1891 panel->wwin = wwin;
1892
1893 WMMapWidget(panel->win);
1894
1895 wWindowMap(wwin);
1896
1897 gnustepPanel = panel;
1898 }