62846ec0cdafe1f71ef39a08ce83bbf44f76cab3
[framework/uifw/e17.git] / src / bin / e_alert.c
1 #include "e.h"
2 #include "e_alert.h"
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <signal.h>
10 #include <X11/Xlib.h>
11 #include <X11/X.h>
12 #include <X11/extensions/shape.h>
13 #include <Ecore.h>
14
15 /* local subsystem functions */
16
17 /* local subsystem globals */
18 static Display     *dd = NULL;
19 static char        *title = NULL, *str1 = NULL, *str2 = NULL;
20 static Font         font = 0;
21 static XFontStruct *fs = NULL;
22 static GC           gc = 0;
23 static Window       win = 0, b1 = 0, b2 = 0;
24 static int          ww = 320, hh = 240, wx = 20, wy = 20;
25
26 EAPI unsigned long       e_alert_composite_win = 0;
27
28 /* externally accessible functions */
29 EINTERN int
30 e_alert_init(const char *disp)
31 {
32    XGCValues            gcv;
33    int                  wid, hih, mask;
34    XSetWindowAttributes att;
35    
36    dd = XOpenDisplay(disp);
37    if (!dd) return 0;
38    font = XLoadFont(dd, "fixed");
39    fs = XQueryFont(dd, font);
40    
41    /* dont i18n this - i dont want gettext doing anything as this is called 
42       from a segv */
43    title = "Enlightenment Error";
44    str1 = "(F1) Recover";
45    str2 = "(F2) Exit";
46    
47    wid = DisplayWidth(dd, DefaultScreen(dd));
48    hih = DisplayHeight(dd, DefaultScreen(dd));
49    att.background_pixel  = WhitePixel(dd, DefaultScreen(dd));
50    att.border_pixel      = BlackPixel(dd, DefaultScreen(dd));
51    att.override_redirect = True;
52    mask = CWBackPixel | CWBorderPixel | CWOverrideRedirect;
53    
54    wx = (wid - ww) / 2;
55    wy = (hih - hh) / 2;
56
57    win = XCreateWindow(dd, DefaultRootWindow(dd), 
58                        wx, wy, ww, hh, 0,
59                        CopyFromParent, InputOutput,
60                        CopyFromParent, mask, &att);
61
62    b1 = XCreateWindow(dd, win, -100, -100, 1, 1, 0, CopyFromParent,
63                       InputOutput, CopyFromParent, mask, &att);
64    b2 = XCreateWindow(dd, win, -100, -100, 1, 1, 0, CopyFromParent,
65                       InputOutput, CopyFromParent, mask, &att);
66    XMapWindow(dd, b1);
67    XMapWindow(dd, b2);
68
69    gc = XCreateGC(dd, win, 0, &gcv);
70    XSetForeground(dd, gc, att.border_pixel);
71    XSelectInput(dd, win, KeyPressMask | KeyReleaseMask | ExposureMask);
72
73    return 1;
74 }
75
76 EINTERN int
77 e_alert_shutdown(void)
78 {
79    if (!x_fatal)
80      {
81         XDestroyWindow(dd, win);
82         XFreeGC(dd, gc);
83         XFreeFont(dd, fs);
84         XCloseDisplay(dd);
85      }
86    title = NULL;
87    str1 = NULL;
88    str2 = NULL;
89    dd = NULL;
90    font = 0;
91    fs = NULL;
92    gc = 0;
93    return 1;
94 }
95
96 EAPI void
97 e_alert_show(const char *text)
98 {
99    int                  w, i, j, k;
100    char                 line[1024];
101    XEvent               ev;
102    int                  fw, fh, mh;
103    KeyCode              key;
104    int                  button;
105
106    if (!text) return;
107
108    if ((!dd) || (!fs))
109      {
110         fputs(text, stderr);
111         fflush(stderr);
112         exit(1);
113      }
114    
115    fh = fs->ascent + fs->descent;
116    mh = ((ww - 20) / 2) - 20;
117
118    /* fixed size... */
119    w = 20;
120    XMoveResizeWindow(dd, b1, w, hh - 15 - fh, mh + 10, fh + 10);
121    XSelectInput(dd, b1, ButtonPressMask | ButtonReleaseMask | ExposureMask);
122    w = ww - 20 - mh;
123    XMoveResizeWindow(dd, b2, w, hh - 15 - fh, mh + 10, fh + 10);
124    XSelectInput(dd, b2, ButtonPressMask | ButtonReleaseMask | ExposureMask);
125
126    if (e_alert_composite_win)
127      {
128 #ifdef ShapeInput        
129         XRectangle rect;
130         
131         rect.x = wx;
132         rect.y = wy;
133         rect.width = ww;
134         rect.height = hh;
135         XShapeCombineRectangles(dd, e_alert_composite_win, ShapeInput, 
136                                 0, 0, &rect, 1, ShapeSet, Unsorted);
137 #endif        
138         XReparentWindow(dd, win, e_alert_composite_win, wx, wy);
139      }
140    XMapRaised(dd, win);
141    XGrabPointer(dd, win, True, ButtonPressMask | ButtonReleaseMask,
142                 GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
143    XGrabKeyboard(dd, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
144    XSetInputFocus(dd, win, RevertToPointerRoot, CurrentTime);
145    XSync(dd, False);
146    
147    button = 0;
148    while (button == 0)
149      {
150         XNextEvent(dd, &ev);
151         switch (ev.type)
152           {
153            case KeyPress:
154              key = XKeysymToKeycode(dd, XStringToKeysym("F1"));
155              if (key == ev.xkey.keycode)
156                {
157                   button = 1;
158                   break;
159                }
160              key = XKeysymToKeycode(dd, XStringToKeysym("F2"));
161              if (key == ev.xkey.keycode)
162                {
163                   button = 2;
164                   break;
165                }
166              break;
167            case ButtonPress:
168              if (ev.xbutton.window == b1)
169                button = 1;
170              else if (ev.xbutton.window == b2)
171                button = 2;
172              break;
173            case Expose:
174              while (XCheckTypedWindowEvent(dd, ev.xexpose.window, Expose, &ev));
175              
176              /* outline */
177              XDrawRectangle(dd, win, gc, 0, 0, ww - 1, hh - 1);
178              
179              XDrawRectangle(dd, win, gc, 2, 2, ww - 4 - 1, fh + 4 - 1);
180              
181              fw = XTextWidth(fs, title, strlen(title));
182              XDrawString(dd, win, gc, 2 + 2 + ((ww - 4 - 4 - fw) / 2) , 2 + 2 + fs->ascent, title, strlen(title));
183              
184              i = 0;
185              j = 0;
186              k = 2 + fh + 4 + 2;
187              while (text[i])
188                {
189                   line[j++] = text[i++];
190                   if (line[j - 1] == '\n')
191                     {
192                        line[j - 1] = 0;
193                        j = 0;
194                        XDrawString(dd, win, gc, 4, k + fs->ascent, line, strlen(line));
195                        k += fh + 2;
196                     }
197                }
198              fw = XTextWidth(fs, str1, strlen(str1));
199              XDrawRectangle(dd, b1, gc, 0, 0, mh - 1, fh + 10 - 1);
200              XDrawString(dd, b1, gc, 5 + ((mh - fw) / 2), 5 + fs->ascent, str1, strlen(str1));
201
202              fw = XTextWidth(fs, str2, strlen(str2));
203              XDrawRectangle(dd, b2, gc, 0, 0, mh - 1, fh + 10 - 1);
204              XDrawString(dd, b2, gc, 5 + ((mh - fw) / 2), 5 + fs->ascent, str2, strlen(str2));
205              
206              XSync(dd, False);
207              break;
208
209           default:
210              break;
211           }
212      }
213    XDestroyWindow(dd, win);
214    XSync(dd, False);
215    
216    switch (button)
217      {
218       case 1:
219         ecore_app_restart();
220         break;
221       case 2:
222         exit(-11);
223         break;
224       default:
225         break;
226      }
227 }
228
229 /* local subsystem functions */