1 /*
2 * Copyright (C) 2000-2019 the xine project
3 *
4 * This file is part of xine, a unix video player.
5 *
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <X11/Xlib.h>
28 #include <X11/keysym.h>
29
30 #include "_xitk.h"
31 #include "xitk.h"
32
33 #define DIALOG_TYPE_UNKNOWN 0
34 #define DIALOG_TYPE_OK 1
35 #define DIALOG_TYPE_YESNO 2
36 #define DIALOG_TYPE_YESNOCANCEL 3
37 #define DIALOG_TYPE_BUTTONLESS 4
38
39 static void _xitk_window_destroy_window(xitk_widget_t *, void *);
40
41 #define TITLE_BAR_HEIGHT 20
42
_xitk_window_set_focus(Display * display,Window window)43 static void _xitk_window_set_focus(Display *display, Window window) {
44 int t = 0;
45
46 while((!xitk_is_window_visible(display, window)) && (++t < 3))
47 xitk_usec_sleep(5000);
48
49 if(xitk_is_window_visible(display, window)) {
50 xitk_x_lock_display (display);
51 XSetInputFocus(display, window, RevertToParent, CurrentTime);
52 xitk_x_unlock_display (display);
53 }
54 }
55
56 /*
57 *
58 */
xitk_is_window_iconified(Display * display,Window window)59 int xitk_is_window_iconified(Display *display, Window window) {
60 unsigned char *prop_return = NULL;
61 unsigned long nitems_return;
62 unsigned long bytes_after_return;
63 int format_return;
64 Atom type_return, atom;
65 int retval = 0;
66
67 xitk_x_lock_display (display);
68 atom = XInternAtom(display, "WM_STATE", False);
69 XGetWindowProperty (display, window, atom, 0, 0x7fffffff, False,
70 atom, &type_return, &format_return, &nitems_return, &bytes_after_return, &prop_return);
71
72 if(prop_return) {
73 if (prop_return[0] == IconicState)
74 retval = 1;
75 XFree(prop_return);
76 }
77 xitk_x_unlock_display (display);
78
79 return retval;
80 }
81
82 /*
83 * Is window is size match with given args
84 */
xitk_is_window_visible(Display * display,Window window)85 int xitk_is_window_visible(Display *display, Window window) {
86 XWindowAttributes wattr;
87 Status status;
88
89 if((display == NULL) || (window == None))
90 return -1;
91
92 xitk_x_lock_display (display);
93 status = XGetWindowAttributes(display, window, &wattr);
94 xitk_x_unlock_display (display);
95
96 if((status != BadDrawable) && (status != BadWindow) && (wattr.map_state == IsViewable))
97 return 1;
98
99 return 0;
100 }
101
102 /*
103 * Is window is size match with given args
104 */
xitk_is_window_size(Display * display,Window window,int width,int height)105 int xitk_is_window_size(Display *display, Window window, int width, int height) {
106 XWindowAttributes wattr;
107
108 if((display == NULL) || (window == None))
109 return -1;
110
111 xitk_x_lock_display (display);
112 if(!XGetWindowAttributes(display, window, &wattr)) {
113 XITK_WARNING("XGetWindowAttributes() failed.n");
114 xitk_x_unlock_display (display);
115 return -1;
116 }
117 xitk_x_unlock_display (display);
118
119 if((wattr.width == width) && (wattr.height == height))
120 return 1;
121
122 return 0;
123 }
124
125 /*
126 * Set/Change window title.
127 */
xitk_set_window_title(Display * display,Window window,const char * title)128 void xitk_set_window_title(Display *display, Window window, const char *title) {
129
130 if((display == NULL) || (window == None) || (title == NULL))
131 return;
132
133 xitk_x_lock_display (display);
134 XmbSetWMProperties(display, window, title, title, NULL, 0, NULL, NULL, NULL);
135 xitk_x_unlock_display (display);
136 }
137
138 /*
139 * Set/Change window title.
140 */
xitk_window_set_window_title(ImlibData * im,xitk_window_t * w,const char * title)141 void xitk_window_set_window_title(ImlibData *im, xitk_window_t *w, const char *title) {
142
143 if((im == NULL) || (w == NULL) || (title == NULL))
144 return;
145
146 xitk_set_window_title(im->x.disp, w->window, title);
147 }
148
149 /*
150 * Get (safely) window pos.
151 */
xitk_get_window_position(Display * display,Window window,int * x,int * y,int * width,int * height)152 void xitk_get_window_position(Display *display, Window window,
153 int *x, int *y, int *width, int *height) {
154 XWindowAttributes wattr;
155 Window wdummy;
156 int xx = 0, yy = 0;
157
158 if((display == NULL) || (window == None))
159 return;
160
161 xitk_x_lock_display (display);
162 if(!XGetWindowAttributes(display, window, &wattr)) {
163 XITK_WARNING("XGetWindowAttributes() failed.n");
164 wattr.width = wattr.height = 0;
165 goto __failure;
166 }
167
168 (void) XTranslateCoordinates (display, window, wattr.root,
169 -wattr.border_width, -wattr.border_width,
170 &xx, &yy, &wdummy);
171
172 __failure:
173
174 xitk_x_unlock_display (display);
175
176 if(x)
177 *x = xx;
178 if(y)
179 *y = yy;
180 if(width)
181 *width = wattr.width;
182 if(height)
183 *height = wattr.height;
184 }
185
186 /*
187 * Get (safely) window pos.
188 */
xitk_window_get_window_position(ImlibData * im,xitk_window_t * w,int * x,int * y,int * width,int * height)189 void xitk_window_get_window_position(ImlibData *im, xitk_window_t *w,
190 int *x, int *y, int *width, int *height) {
191
192 if((im == NULL) || (w == NULL))
193 return;
194
195 xitk_get_window_position(im->x.disp, w->window, x, y, width, height);
196 }
197
198 /*
199 * Center a window in root window.
200 */
xitk_window_move_window(ImlibData * im,xitk_window_t * w,int x,int y)201 void xitk_window_move_window(ImlibData *im, xitk_window_t *w, int x, int y) {
202
203 if((im == NULL) || (w == NULL))
204 return;
205
206 XLOCK (im->x.x_lock_display, im->x.disp);
207 XMoveResizeWindow (im->x.disp, w->window, x, y, w->width, w->height);
208 XUNLOCK (im->x.x_unlock_display, im->x.disp);
209
210 }
211
212 /*
213 * Center a window in root window.
214 */
xitk_window_center_window(ImlibData * im,xitk_window_t * w)215 void xitk_window_center_window(ImlibData *im, xitk_window_t *w) {
216 Window rootwin;
217 int xwin, ywin;
218 unsigned int wwin, hwin, bwin, dwin;
219 int xx = 0, yy = 0;
220
221 if((im == NULL) || (w == NULL))
222 return;
223
224 XLOCK (im->x.x_lock_display, im->x.disp);
225 if(XGetGeometry(im->x.disp, im->x.root, &rootwin,
226 &xwin, &ywin, &wwin, &hwin, &bwin, &dwin) != BadDrawable) {
227
228 xx = (wwin / 2) - (w->width / 2);
229 yy = (hwin / 2) - (w->height / 2);
230 }
231
232 XMoveResizeWindow (im->x.disp, w->window, xx, yy, w->width, w->height);
233 XUNLOCK (im->x.x_unlock_display, im->x.disp);
234 }
235
236 /*
237 * Create a simple (empty) window.
238 */
xitk_window_create_window(ImlibData * im,int x,int y,int width,int height)239 xitk_window_t *xitk_window_create_window(ImlibData *im, int x, int y, int width, int height) {
240 xitk_window_t *xwin;
241 const char title[] = {"xiTK Window"};
242 XSizeHints hint;
243 XWMHints *wm_hint;
244 XSetWindowAttributes attr;
245 Atom prop, XA_WIN_LAYER, XA_DELETE_WINDOW;
246 XColor black, dummy;
247 MWMHints mwmhints;
248 XClassHint *xclasshint;
249 long data[1];
250
251 if((im == NULL) || (width == 0 || height == 0))
252 return NULL;
253
254 xwin = (xitk_window_t *) xitk_xmalloc(sizeof(xitk_window_t));
255 xwin->win_parent = None;
256 xwin->background = NULL;
257 xwin->background_mask = NULL;
258 xwin->width = width;
259 xwin->height = height;
260 xwin->parent = NULL;
261
262 memset(&hint, 0, sizeof(hint));
263 hint.x = x;
264 hint.y = y;
265 hint.width = width;
266 hint.base_width = width;
267 hint.min_width = width;
268 hint.max_width = width;
269 hint.height = height;
270 hint.base_height = height;
271 hint.min_height = height;
272 hint.max_height = height;
273 hint.win_gravity = NorthWestGravity;
274 hint.flags = PWinGravity | PBaseSize | PMinSize | PMaxSize | USSize | USPosition;
275
276 XLOCK (im->x.x_lock_display, im->x.disp);
277 XAllocNamedColor(im->x.disp, Imlib_get_colormap(im), "black", &black, &dummy);
278 XUNLOCK (im->x.x_unlock_display, im->x.disp);
279
280 attr.override_redirect = False;
281 attr.background_pixel = black.pixel;
282 attr.border_pixel = black.pixel;
283 attr.colormap = Imlib_get_colormap(im);
284 attr.win_gravity = NorthWestGravity;
285
286 XLOCK (im->x.x_lock_display, im->x.disp);
287 xwin->window = XCreateWindow(im->x.disp, im->x.root, hint.x, hint.y, hint.width, hint.height,
288 0, im->x.depth, InputOutput, im->x.visual,
289 CWBackPixel | CWBorderPixel | CWColormap
290 | CWOverrideRedirect | CWWinGravity ,
291 &attr);
292
293 XmbSetWMProperties(im->x.disp, xwin->window, title, title, NULL, 0, &hint, NULL, NULL);
294
295 XSelectInput(im->x.disp, xwin->window, INPUT_MOTION | KeymapStateMask);
296
297 XA_WIN_LAYER = XInternAtom(im->x.disp, "_WIN_LAYER", False);
298
299 data[0] = 10;
300 XChangeProperty(im->x.disp, xwin->window, XA_WIN_LAYER,
301 XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data,
302 1);
303
304 memset(&mwmhints, 0, sizeof(mwmhints));
305 prop = XInternAtom(im->x.disp, "_MOTIF_WM_HINTS", False);
306 mwmhints.flags = MWM_HINTS_DECORATIONS;
307 mwmhints.decorations = 0;
308
309 XChangeProperty(im->x.disp, xwin->window, prop, prop, 32,
310 PropModeReplace, (unsigned char *) &mwmhints,
311 PROP_MWM_HINTS_ELEMENTS);
312
313 XA_DELETE_WINDOW = XInternAtom(im->x.disp, "WM_DELETE_WINDOW", False);
314 XSetWMProtocols(im->x.disp, xwin->window, &XA_DELETE_WINDOW, 1);
315
316 if((xclasshint = XAllocClassHint()) != NULL) {
317 xclasshint->res_name = (char *)"Xine Window";
318 xclasshint->res_class = (char *)"Xitk";
319 XSetClassHint(im->x.disp, xwin->window, xclasshint);
320 XFree(xclasshint);
321 }
322
323 wm_hint = XAllocWMHints();
324 if (wm_hint != NULL) {
325 wm_hint->input = True;
326 wm_hint->initial_state = NormalState;
327 wm_hint->flags = InputHint | StateHint;
328 XSetWMHints(im->x.disp, xwin->window, wm_hint);
329 XFree(wm_hint);
330 }
331
332 XUNLOCK (im->x.x_unlock_display, im->x.disp);
333
334 return xwin;
335 }
336
337 /*
338 * Create a simple painted window.
339 */
xitk_window_create_simple_window(ImlibData * im,int x,int y,int width,int height)340 xitk_window_t *xitk_window_create_simple_window(ImlibData *im, int x, int y, int width, int height) {
341 xitk_window_t *xwin;
342
343 if((im == NULL) || (width == 0 || height == 0))
344 return NULL;
345
346 xwin = xitk_window_create_window(im, x, y, width, height);
347 xwin->width = width;
348 xwin->height = height;
349
350 xwin->background = xitk_image_create_xitk_pixmap(im, width, height);
351 draw_outter(im, xwin->background, width, height);
352 xitk_window_apply_background(im, xwin);
353
354 xitk_window_move_window(im, xwin, x, y);
355
356 return xwin;
357 }
358
359 /*
360 * Create a simple, with title bar, window.
361 */
xitk_window_create_dialog_window(ImlibData * im,const char * title,int x,int y,int width,int height)362 xitk_window_t *xitk_window_create_dialog_window(ImlibData *im, const char *title,
363 int x, int y, int width, int height) {
364 xitk_window_t *xwin;
365 xitk_pixmap_t *bar, *pix_bg;
366 unsigned int colorblack, colorwhite, colorgray, colordgray;
367 xitk_font_t *fs = NULL;
368 int lbear, rbear, wid, asc, des;
369 int bar_style = xitk_get_barstyle_feature();
370
371 if((im == NULL) || (title == NULL) || (width == 0 || height == 0))
372 return NULL;
373
374 xwin = xitk_window_create_simple_window(im, x, y, width, height);
375
376 xitk_window_set_window_title(im, xwin, title);
377
378 bar = xitk_image_create_xitk_pixmap(im, width, TITLE_BAR_HEIGHT);
379 pix_bg = xitk_image_create_xitk_pixmap(im, width, height);
380
381 fs = xitk_font_load_font(im->x.disp, DEFAULT_BOLD_FONT_12);
382 xitk_font_set_font(fs, bar->gc);
383 xitk_font_string_extent(fs, (title && strlen(title)) ? title : "Window", &lbear, &rbear, &wid, &asc, &des);
384
385 XLOCK (im->x.x_lock_display, im->x.disp);
386 XCopyArea(im->x.disp, xwin->background->pixmap, pix_bg->pixmap, xwin->background->gc,
387 0, 0, width, height, 0, 0);
388 XUNLOCK (im->x.x_unlock_display, im->x.disp);
389
390 colorblack = xitk_get_pixel_color_black(im);
391 colorwhite = xitk_get_pixel_color_white(im);
392 colorgray = xitk_get_pixel_color_gray(im);
393 colordgray = xitk_get_pixel_color_darkgray(im);
394
395 /* Draw window title bar background */
396 if(bar_style) {
397 int s, bl = 255;
398 unsigned int colorblue;
399
400 colorblue = xitk_get_pixel_color_from_rgb(im, 0, 0, bl);
401 XLOCK (im->x.x_lock_display, im->x.disp);
402 for(s = 0; s <= TITLE_BAR_HEIGHT; s++, bl -= 8) {
403 XSetForeground(im->x.disp, bar->gc, colorblue);
404 XDrawLine(im->x.disp, bar->pixmap, bar->gc, 0, s, width, s);
405 colorblue = xitk_get_pixel_color_from_rgb(im, 0, 0, bl);
406 }
407 XUNLOCK (im->x.x_unlock_display, im->x.disp);
408 }
409 else {
410 int s;
411 unsigned int c, cd;
412
413 cd = xitk_get_pixel_color_from_rgb(im, 115, 12, 206);
414 c = xitk_get_pixel_color_from_rgb(im, 135, 97, 168);
415
416 draw_flat_with_color(im, bar, width, TITLE_BAR_HEIGHT, colorgray);
417 draw_rectangular_inner_box(im, bar, 2, 2, width - 6, (TITLE_BAR_HEIGHT - 1 - 4));
418
419 XLOCK (im->x.x_lock_display, im->x.disp);
420 for(s = 6; s <= (TITLE_BAR_HEIGHT - 6); s += 3) {
421 XSetForeground(im->x.disp, bar->gc, c);
422 XDrawLine(im->x.disp, bar->pixmap, bar->gc, 5, s, (width - 8), s);
423 XSetForeground(im->x.disp, bar->gc, cd);
424 XDrawLine(im->x.disp, bar->pixmap, bar->gc, 5, s+1, (width - 8), s+1);
425 }
426
427 XSetForeground(im->x.disp, bar->gc, colorgray);
428 XFillRectangle(im->x.disp, bar->pixmap, bar->gc,
429 ((width - wid) - TITLE_BAR_HEIGHT) - 10, 6,
430 wid + 20, TITLE_BAR_HEIGHT - 1 - 8);
431 XUNLOCK (im->x.x_unlock_display, im->x.disp);
432 }
433
434 XLOCK (im->x.x_lock_display, im->x.disp);
435 XSetForeground(im->x.disp, bar->gc, colorwhite);
436 XDrawLine(im->x.disp, bar->pixmap, bar->gc, 0, 0, width, 0);
437 XDrawLine(im->x.disp, bar->pixmap, bar->gc, 0, 0, 0, TITLE_BAR_HEIGHT - 1);
438 XUNLOCK (im->x.x_unlock_display, im->x.disp);
439
440 XLOCK (im->x.x_lock_display, im->x.disp);
441 XSetForeground(im->x.disp, bar->gc, colorblack);
442 XDrawLine(im->x.disp, bar->pixmap, bar->gc, width - 1, 0, width - 1, TITLE_BAR_HEIGHT - 1);
443
444 XDrawLine(im->x.disp, bar->pixmap, bar->gc, 2, TITLE_BAR_HEIGHT - 1, width - 2, TITLE_BAR_HEIGHT - 1);
445 XUNLOCK (im->x.x_unlock_display, im->x.disp);
446
447 XLOCK (im->x.x_lock_display, im->x.disp);
448 XSetForeground(im->x.disp, bar->gc, colordgray);
449 XDrawLine(im->x.disp, bar->pixmap, bar->gc, width - 2, 2, width - 2, TITLE_BAR_HEIGHT - 1);
450 XUNLOCK (im->x.x_unlock_display, im->x.disp);
451
452 XLOCK (im->x.x_lock_display, im->x.disp);
453 XSetForeground(im->x.disp, bar->gc, colorblack);
454 XDrawLine(im->x.disp, pix_bg->pixmap, bar->gc, width - 1, 0, width - 1, height - 1);
455 XDrawLine(im->x.disp, pix_bg->pixmap, bar->gc, 0, height - 1, width - 1, height - 1);
456 XUNLOCK (im->x.x_unlock_display, im->x.disp);
457
458 XLOCK (im->x.x_lock_display, im->x.disp);
459 XSetForeground(im->x.disp, bar->gc, colordgray);
460 XDrawLine(im->x.disp, pix_bg->pixmap, bar->gc, width - 2, 0, width - 2, height - 2);
461 XDrawLine(im->x.disp, pix_bg->pixmap, bar->gc, 2, height - 2, width - 2, height - 2);
462 XUNLOCK (im->x.x_unlock_display, im->x.disp);
463
464 XLOCK (im->x.x_lock_display, im->x.disp);
465 if(bar_style)
466 XSetForeground(im->x.disp, bar->gc, colorwhite);
467 else
468 XSetForeground(im->x.disp, bar->gc, (xitk_get_pixel_color_from_rgb(im, 85, 12, 135)));
469 XUNLOCK (im->x.x_unlock_display, im->x.disp);
470
471 xitk_font_draw_string(fs, bar->pixmap, bar->gc,
472 (width - wid) - TITLE_BAR_HEIGHT, ((TITLE_BAR_HEIGHT+asc+des) >> 1) - des, title, strlen(title));
473
474 xitk_font_unload_font(fs);
475
476 XLOCK (im->x.x_lock_display, im->x.disp);
477 XCopyArea(im->x.disp, bar->pixmap, pix_bg->pixmap, bar->gc, 0, 0, width, TITLE_BAR_HEIGHT, 0, 0);
478 XUNLOCK (im->x.x_unlock_display, im->x.disp);
479
480 xitk_window_change_background(im, xwin, pix_bg->pixmap, width, height);
481
482 xitk_image_destroy_xitk_pixmap(bar);
483 xitk_image_destroy_xitk_pixmap(pix_bg);
484
485 return xwin;
486 }
487
488 /*
489 * Get window sizes.
490 */
xitk_window_get_window_size(xitk_window_t * w,int * width,int * height)491 void xitk_window_get_window_size(xitk_window_t *w, int *width, int *height) {
492
493 if (w == NULL) {
494 *width = 0;
495 *height = 0;
496 return;
497 }
498
499 *width = w->width;
500 *height = w->height;
501 }
502
503 /*
504 * Get window (X) id.
505 */
xitk_window_get_window(xitk_window_t * w)506 Window xitk_window_get_window(xitk_window_t *w) {
507
508 if(w == NULL)
509 return None;
510
511 return w->window;
512 }
513
514 /*
515 * Return window background pixmap.
516 */
xitk_window_get_background(xitk_window_t * w)517 Pixmap xitk_window_get_background(xitk_window_t *w) {
518
519 if(w == NULL)
520 return None;
521
522 return w->background->pixmap;
523 }
524
525 /*
526 * Return window background pixmap.
527 */
xitk_window_get_background_mask(xitk_window_t * w)528 Pixmap xitk_window_get_background_mask(xitk_window_t *w) {
529
530 if(w == NULL)
531 return None;
532
533 if(w->background_mask == NULL)
534 return None;
535
536 return w->background->pixmap;
537 }
538
539 /*
540 * Apply (draw) window background.
541 */
xitk_window_apply_background(ImlibData * im,xitk_window_t * w)542 void xitk_window_apply_background(ImlibData *im, xitk_window_t *w) {
543
544 if((im == NULL) || (w == NULL))
545 return;
546
547 XLOCK (im->x.x_lock_display, im->x.disp);
548
549 XSetWindowBackgroundPixmap(im->x.disp, w->window, w->background->pixmap);
550
551 if(w->background_mask)
552 XShapeCombineMask(im->x.disp, w->window, ShapeBounding, 0, 0, w->background_mask->pixmap, ShapeSet);
553 else
554 XShapeCombineMask(im->x.disp, w->window, ShapeBounding, 0, 0, 0, ShapeSet);
555
556 XClearWindow(im->x.disp, w->window);
557 XUNLOCK (im->x.x_unlock_display, im->x.disp);
558 }
559
560 /*
561 * Change window background with 'bg', then draw it.
562 */
xitk_window_change_background(ImlibData * im,xitk_window_t * w,Pixmap bg,int width,int height)563 int xitk_window_change_background(ImlibData *im,
564 xitk_window_t *w, Pixmap bg, int width, int height) {
565 Window rootwin;
566 int xwin, ywin;
567 unsigned int wwin, hwin, bwin, dwin;
568
569 if((im == NULL) || (w == NULL) || (bg == None) || (width == 0 || height == 0))
570 return 0;
571
572 xitk_image_destroy_xitk_pixmap(w->background);
573 if(w->background_mask)
574 xitk_image_destroy_xitk_pixmap(w->background_mask);
575
576 w->background = xitk_image_create_xitk_pixmap(im, width, height);
577 w->background_mask = NULL;
578
579 XLOCK (im->x.x_lock_display, im->x.disp);
580 if(XGetGeometry(im->x.disp, w->window, &rootwin,
581 &xwin, &ywin, &wwin, &hwin, &bwin, &dwin) != BadDrawable) {
582
583 XResizeWindow (im->x.disp, w->window, wwin, hwin);
584 }
585 else {
586 XUNLOCK (im->x.x_unlock_display, im->x.disp);
587 return 0;
588 }
589
590 XCopyArea(im->x.disp, bg, w->background->pixmap, w->background->gc, 0, 0, width, height, 0, 0);
591 XUNLOCK (im->x.x_unlock_display, im->x.disp);
592
593 xitk_window_apply_background(im, w);
594
595 return 1;
596 }
597
598 /*
599 * Change window background with img, then draw it.
600 */
xitk_window_change_background_with_image(ImlibData * im,xitk_window_t * w,xitk_image_t * img,int width,int height)601 int xitk_window_change_background_with_image(ImlibData *im, xitk_window_t *w, xitk_image_t *img, int width, int height) {
602 Window rootwin;
603 int xwin, ywin;
604 unsigned int wwin, hwin, bwin, dwin;
605
606 if((im == NULL) || (w == NULL) || (img == NULL) || (width == 0 || height == 0))
607 return 0;
608
609 xitk_image_destroy_xitk_pixmap(w->background);
610 if(w->background_mask)
611 xitk_image_destroy_xitk_pixmap(w->background_mask);
612
613 w->background = xitk_image_create_xitk_pixmap(im, width, height);
614 w->background_mask = NULL;
615
616 if(img->mask)
617 w->background_mask = xitk_image_create_xitk_mask_pixmap(im, width, height);
618
619 XLOCK (im->x.x_lock_display, im->x.disp);
620 if(XGetGeometry(im->x.disp, w->window, &rootwin,
621 &xwin, &ywin, &wwin, &hwin, &bwin, &dwin) != BadDrawable) {
622
623 XResizeWindow (im->x.disp, w->window, wwin, hwin);
624 }
625 else {
626 XUNLOCK (im->x.x_unlock_display, im->x.disp);
627 return 0;
628 }
629
630 XCopyArea(im->x.disp, img->image->pixmap, w->background->pixmap, w->background->gc, 0, 0, width, height, 0, 0);
631 if(w->background_mask)
632 XCopyArea(im->x.disp, img->mask->pixmap, w->background_mask->pixmap, w->background_mask->gc, 0, 0, width, height, 0, 0);
633
634 XUNLOCK (im->x.x_unlock_display, im->x.disp);
635 xitk_window_apply_background(im, w);
636
637 return 1;
638 }
639
640 /*
641 * Local XEvent handling.
642 */
_window_handle_event(XEvent * event,void * data)643 static void _window_handle_event(XEvent *event, void *data) {
644 xitk_dialog_t *wd = (xitk_dialog_t *)data;
645
646 switch(event->type) {
647
648 case Expose:
649 if(wd->widget_list) {
650 wd->widget_list->widget_focused = wd->default_button;
651 if ((wd->widget_list->widget_focused->type & WIDGET_FOCUSABLE) &&
652 wd->widget_list->widget_focused->enable == WIDGET_ENABLE) {
653 xitk_widget_t *w = wd->widget_list->widget_focused;
654 widget_event_t event;
655
656 event.type = WIDGET_EVENT_FOCUS;
657 event.focus = FOCUS_RECEIVED;
658
659 (void) w->event(w, &event, NULL);
660 w->have_focus = FOCUS_RECEIVED;
661
662 event.type = WIDGET_EVENT_PAINT;
663 (void) w->event(w, &event, NULL);
664 }
665 }
666 break;
667
668 case MappingNotify:
669 XLOCK (wd->imlibdata->x.x_lock_display, wd->imlibdata->x.disp);
670 XRefreshKeyboardMapping((XMappingEvent *) event);
671 XUNLOCK (wd->imlibdata->x.x_unlock_display, wd->imlibdata->x.disp);
672 break;
673
674 case KeyPress: {
675 XKeyEvent mykeyevent;
676 KeySym mykey;
677 char kbuf[256];
678
679 mykeyevent = event->xkey;
680
681 XLOCK (wd->imlibdata->x.x_lock_display, wd->imlibdata->x.disp);
682 XLookupString(&mykeyevent, kbuf, sizeof(kbuf), &mykey, NULL);
683 XUNLOCK (wd->imlibdata->x.x_unlock_display, wd->imlibdata->x.disp);
684
685 switch (mykey) {
686
687 case XK_Return:
688 if(wd->default_button)
689 _xitk_window_destroy_window(wd->default_button, (void *)wd);
690 break;
691
692 case XK_Escape:
693 if((wd->type == DIALOG_TYPE_YESNO) || (wd->type == DIALOG_TYPE_YESNOCANCEL)) {
694 if(wd->default_button)
695 _xitk_window_destroy_window(wd->default_button, (void *)wd);
696 }
697 else {
698 if(wd->type != DIALOG_TYPE_BUTTONLESS)
699 _xitk_window_destroy_window(NULL, (void *)wd);
700 }
701 break;
702
703 }
704
705 }
706 break;
707 }
708 }
709
xitk_window_set_modal(xitk_window_t * w)710 void xitk_window_set_modal(xitk_window_t *w) {
711 xitk_modal_window(w->window);
712 }
xitk_window_dialog_set_modal(xitk_window_t * w)713 void xitk_window_dialog_set_modal(xitk_window_t *w) {
714 xitk_dialog_t *wd = w->parent;
715 xitk_window_set_modal(wd->xwin);
716 }
xitk_window_destroy_window(ImlibData * im,xitk_window_t * w)717 void xitk_window_destroy_window(ImlibData *im, xitk_window_t *w) {
718
719 XLOCK (im->x.x_lock_display, im->x.disp);
720 XUnmapWindow(im->x.disp, w->window);
721 XUNLOCK (im->x.x_unlock_display, im->x.disp);
722
723 if(w->background)
724 xitk_image_destroy_xitk_pixmap(w->background);
725
726 w->width = -1;
727 w->height = -1;
728
729 xitk_unmodal_window(w->window);
730
731 XLOCK (im->x.x_lock_display, im->x.disp);
732 XDestroyWindow(im->x.disp, w->window);
733
734 if((w->win_parent != None) && xitk_is_window_visible(im->x.disp, w->win_parent))
735 XSetInputFocus(im->x.disp, w->win_parent, RevertToParent, CurrentTime);
736
737 XUNLOCK (im->x.x_unlock_display, im->x.disp);
738
739 XITK_FREE(w);
740 }
741
742 /**
743 *
744 * @TODO Should be split on a different unit, as it's only used with TAR support
745 * enabled.
746 */
xitk_window_dialog_destroy(xitk_window_t * w)747 void xitk_window_dialog_destroy(xitk_window_t *w) {
748 xitk_dialog_t *wd = w->parent;
749
750 if(wd) {
751 xitk_window_destroy_window(wd->imlibdata, wd->xwin);
752 xitk_unregister_event_handler(&wd->key);
753
754 if(wd->widget_list) {
755 xitk_destroy_widgets(wd->widget_list);
756 XLOCK (wd->imlibdata->x.x_lock_display, wd->imlibdata->x.disp);
757 XFreeGC(wd->imlibdata->x.disp, wd->widget_list->gc);
758 XUNLOCK (wd->imlibdata->x.x_unlock_display, wd->imlibdata->x.disp);
759
760 /* xitk_dlist_init (&wd->widget_list->list); */
761
762 XITK_WIDGET_LIST_FREE(wd->widget_list);
763 }
764 XITK_FREE(wd);
765 }
766 }
767
768 /*
769 * Unmap and free window components.
770 */
_xitk_window_destroy_window(xitk_widget_t * w,void * data)771 static void _xitk_window_destroy_window(xitk_widget_t *w, void *data) {
772 xitk_dialog_t *wd = (xitk_dialog_t *)data;
773
774 xitk_window_destroy_window(wd->imlibdata, wd->xwin);
775
776 switch(wd->type) {
777
778 case DIALOG_TYPE_OK:
779 if(wd->yescallback)
780 wd->yescallback(NULL, wd->userdata, XITK_WINDOW_ANSWER_OK);
781 break;
782
783 case DIALOG_TYPE_YESNO:
784 case DIALOG_TYPE_YESNOCANCEL:
785 if(w == wd->wyes) {
786 if(wd->yescallback)
787 wd->yescallback(NULL, wd->userdata, XITK_WINDOW_ANSWER_YES);
788 }
789 else if(w == wd->wno) {
790 if(wd->nocallback)
791 wd->nocallback(NULL, wd->userdata, XITK_WINDOW_ANSWER_NO);
792 }
793 else if(w == wd->wcancel) {
794 if(wd->cancelcallback)
795 wd->cancelcallback(NULL, wd->userdata, XITK_WINDOW_ANSWER_CANCEL);
796 }
797 break;
798
799 case DIALOG_TYPE_BUTTONLESS:
800 /* NOOP */
801 break;
802
803 default:
804 XITK_WARNING("window dialog type unknown: %d\n", wd->type);
805 break;
806
807 }
808
809 xitk_unregister_event_handler(&wd->key);
810
811 if(wd->widget_list) {
812 xitk_destroy_widgets(wd->widget_list);
813
814 XLOCK (wd->imlibdata->x.x_lock_display, wd->imlibdata->x.disp);
815 XFreeGC(wd->imlibdata->x.disp, wd->widget_list->gc);
816 XUNLOCK (wd->imlibdata->x.x_unlock_display, wd->imlibdata->x.disp);
817
818 /* xitk_dlist_init (&wd->widget_list->list); */
819
820 XITK_WIDGET_LIST_FREE(wd->widget_list);
821 }
822
823 XITK_FREE(wd);
824
825 }
826
827 /**
828 *
829 * @TODO Should be split on a different unit, as it's only used with TAR support
830 * enabled.
831 */
xitk_window_dialog_button_free_with_width(ImlibData * im,const char * title,int window_width,int align,const char * message,...)832 xitk_window_t *xitk_window_dialog_button_free_with_width(ImlibData *im, const char *title,
833 int window_width, int align, const char *message, ...) {
834 xitk_dialog_t *wd;
835 int windoww = window_width, windowh;
836 xitk_image_t *image;
837
838 if((im == NULL) || (window_width == 0) || (message == NULL))
839 return NULL;
840
841 {
842 va_list args;
843 char *buf;
844
845 va_start(args, message);
846 buf = xitk_vasprintf(message, args);
847 va_end(args);
848
849 if (!buf)
850 return NULL;
851
852 image = xitk_image_create_image_from_string(im, DEFAULT_FONT_12, windoww - 40, align, buf);
853 XITK_FREE(buf);
854 }
855
856 if (!image) {
857 return NULL;
858 }
859
860 windowh = (image->height) + (TITLE_BAR_HEIGHT + 40);
861
862 wd = (xitk_dialog_t *) xitk_xmalloc(sizeof(xitk_dialog_t));
863
864 wd->imlibdata = im;
865 wd->type = DIALOG_TYPE_BUTTONLESS;
866 wd->wyes = wd->wno = wd->wcancel = wd->default_button = NULL;
867 wd->widget_list = NULL;
868 wd->xwin = xitk_window_create_dialog_window(im, ((title != NULL) ? title : "Notice"),
869 0, 0, windoww, windowh);
870 wd->xwin->parent = wd;
871
872 xitk_window_center_window(im, wd->xwin);
873
874 wd->widget_list = NULL;
875
876 /* Draw text area */
877 {
878 xitk_pixmap_t *bg;
879 int width, height;
880 GC gc;
881
882 xitk_window_get_window_size(wd->xwin, &width, &height);
883 bg = xitk_image_create_xitk_pixmap(im, width, height);
884
885 XLOCK (im->x.x_lock_display, im->x.disp);
886 gc = XCreateGC(im->x.disp, (xitk_window_get_background(wd->xwin)), None, None);
887 XCopyArea(im->x.disp, (xitk_window_get_background(wd->xwin)), bg->pixmap,
888 gc, 0, 0, width, height, 0, 0);
889 XCopyArea(im->x.disp, image->image->pixmap, bg->pixmap,
890 image->image->gc, 0, 0, image->width, image->height, 20, (TITLE_BAR_HEIGHT + 20));
891 XUNLOCK (im->x.x_unlock_display, im->x.disp);
892
893 xitk_window_change_background(im, wd->xwin, bg->pixmap, width, height);
894
895 xitk_image_destroy_xitk_pixmap(bg);
896
897 XLOCK (im->x.x_lock_display, im->x.disp);
898 XFreeGC(im->x.disp, gc);
899 XUNLOCK (im->x.x_unlock_display, im->x.disp);
900
901 xitk_image_free_image(im, &image);
902
903 }
904
905 XLOCK (im->x.x_lock_display, im->x.disp);
906 XMapRaised(im->x.disp, (xitk_window_get_window(wd->xwin)));
907 XUNLOCK (im->x.x_unlock_display, im->x.disp);
908
909 wd->key = xitk_register_event_handler("xitk_nobtn",
910 (xitk_window_get_window(wd->xwin)),
911 _window_handle_event,
912 NULL,
913 NULL,
914 NULL,
915 (void *)wd);
916
917 _xitk_window_set_focus(im->x.disp, (xitk_window_get_window(wd->xwin)));
918
919 return wd->xwin;
920 }
921 /*
922 * Create a window error, containing an error message.
923 */
xitk_window_dialog_one_button_with_width(ImlibData * im,const char * title,const char * button_label,xitk_state_callback_t cb,void * userdata,int window_width,int align,const char * message,...)924 xitk_window_t *xitk_window_dialog_one_button_with_width(ImlibData *im, const char *title,
925 const char *button_label,
926 xitk_state_callback_t cb, void *userdata,
927 int window_width, int align,
928 const char *message, ...) {
929 xitk_dialog_t *wd;
930 xitk_labelbutton_widget_t lb;
931 int windoww = window_width, windowh;
932 xitk_image_t *image;
933 int bwidth = 100, bx, by;
934
935 if((im == NULL) || (window_width == 0) || (message == NULL))
936 return NULL;
937
938 {
939 va_list args;
940 char *buf;
941
942 va_start(args, message);
943 buf = xitk_vasprintf(message, args);
944 va_end(args);
945
946 if (!buf)
947 return NULL;
948
949 image = xitk_image_create_image_from_string(im, DEFAULT_FONT_12, windoww - 40, align, buf);
950 XITK_FREE(buf);
951 }
952
953 windowh = (image->height + 50) + (TITLE_BAR_HEIGHT + 40);
954
955 wd = (xitk_dialog_t *) xitk_xmalloc(sizeof(xitk_dialog_t));
956
957 wd->imlibdata = im;
958 wd->type = DIALOG_TYPE_OK;
959 wd->yescallback = cb;
960 wd->userdata = userdata;
961 wd->xwin = xitk_window_create_dialog_window(im, ((title != NULL) ? title : "Notice"),
962 0, 0, windoww, windowh);
963 wd->xwin->parent = wd;
964
965 xitk_window_center_window(im, wd->xwin);
966
967 wd->widget_list = xitk_widget_list_new();
968 xitk_dlist_init (&wd->widget_list->list);
969 wd->widget_list->win = (xitk_window_get_window(wd->xwin));
970
971 XLOCK (wd->imlibdata->x.x_lock_display, wd->imlibdata->x.disp);
972 wd->widget_list->gc = (XCreateGC(im->x.disp, (xitk_window_get_window(wd->xwin)),
973 None, None));
974 XUNLOCK (wd->imlibdata->x.x_unlock_display, wd->imlibdata->x.disp);
975
976 /* OK button */
977 if(bwidth > windoww)
978 bwidth = (windoww - 4);
979
980 bx = ((windoww - bwidth) / 2);
981 by = windowh - 50;
982
983 XITK_WIDGET_INIT(&lb, im);
984 lb.button_type = CLICK_BUTTON;
985 lb.label = button_label;
986 lb.align = ALIGN_CENTER;
987 lb.callback = _xitk_window_destroy_window;
988 lb.state_callback = NULL;
989 lb.userdata = (void*)wd;
990 lb.skin_element_name = NULL;
991 wd->wyes = xitk_noskin_labelbutton_create (wd->widget_list, &lb,
992 bx, by, bwidth, 30, "Black", "Black", "White", DEFAULT_BOLD_FONT_12);
993 xitk_dlist_add_tail (&wd->widget_list->list, &wd->wyes->node);
994 wd->default_button = wd->wyes;
995
996 /* Draw text area */
997 {
998 xitk_pixmap_t *bg;
999 int width, height;
1000 GC gc;
1001
1002 xitk_window_get_window_size(wd->xwin, &width, &height);
1003 bg = xitk_image_create_xitk_pixmap(im, width, height);
1004
1005 XLOCK (im->x.x_lock_display, im->x.disp);
1006 gc = XCreateGC(im->x.disp, (xitk_window_get_background(wd->xwin)), None, None);
1007 XCopyArea(im->x.disp, (xitk_window_get_background(wd->xwin)), bg->pixmap,
1008 gc, 0, 0, width, height, 0, 0);
1009 XCopyArea(im->x.disp, image->image->pixmap, bg->pixmap,
1010 image->image->gc, 0, 0, image->width, image->height, 20, (TITLE_BAR_HEIGHT + 20));
1011 XUNLOCK (im->x.x_unlock_display, im->x.disp);
1012
1013 xitk_window_change_background(im, wd->xwin, bg->pixmap, width, height);
1014
1015 xitk_image_destroy_xitk_pixmap(bg);
1016
1017 XLOCK (im->x.x_lock_display, im->x.disp);
1018 XFreeGC(im->x.disp, gc);
1019 XUNLOCK (im->x.x_unlock_display, im->x.disp);
1020
1021 xitk_image_free_image(im, &image);
1022
1023 }
1024
1025 XLOCK (im->x.x_lock_display, im->x.disp);
1026 XMapRaised(im->x.disp, (xitk_window_get_window(wd->xwin)));
1027 XUNLOCK (im->x.x_unlock_display, im->x.disp);
1028
1029 wd->key = xitk_register_event_handler("xitk_1btn",
1030 (xitk_window_get_window(wd->xwin)),
1031 _window_handle_event,
1032 NULL,
1033 NULL,
1034 wd->widget_list,
1035 (void *)wd);
1036
1037 xitk_enable_and_show_widget(wd->wyes);
1038
1039 _xitk_window_set_focus(im->x.disp, (xitk_window_get_window(wd->xwin)));
1040
1041 return wd->xwin;
1042 }
1043
xitk_window_dialog_ok_with_width(ImlibData * im,const char * title,xitk_state_callback_t cb,void * userdata,int window_width,int align,const char * message,...)1044 xitk_window_t *xitk_window_dialog_ok_with_width(ImlibData *im, const char *title,
1045 xitk_state_callback_t cb, void *userdata,
1046 int window_width, int align,
1047 const char *message, ...) {
1048
1049 va_list args;
1050 char *buf;
1051 xitk_window_t *xw = NULL;
1052
1053 va_start(args, message);
1054 buf = xitk_vasprintf(message, args);
1055 va_end(args);
1056
1057 if (!buf)
1058 return NULL;
1059
1060 xw = xitk_window_dialog_one_button_with_width(im, title, _("OK"), cb, userdata, window_width,
1061 align, "%s", buf);
1062 XITK_FREE(buf);
1063 return xw;
1064 }
1065
_checkbox_label_click(xitk_widget_t * w,void * data)1066 static void _checkbox_label_click(xitk_widget_t *w, void *data) {
1067 xitk_dialog_t *wd = (xitk_dialog_t *) data;
1068
1069 xitk_checkbox_set_state(wd->checkbox,
1070 (!xitk_checkbox_get_state(wd->checkbox)));
1071 xitk_checkbox_callback_exec(wd->checkbox);
1072 }
1073
1074 /*
1075 * Create an interactive window, containing 'yes', 'no', 'cancel' buttons.
1076 */
xitk_window_dialog_checkbox_two_buttons_with_width(ImlibData * im,const char * title,const char * button1_label,const char * button2_label,xitk_state_callback_t cb1,xitk_state_callback_t cb2,const char * checkbox_label,int checkbox_state,xitk_state_callback_t cb3,void * userdata,int window_width,int align,const char * message,...)1077 xitk_window_t *xitk_window_dialog_checkbox_two_buttons_with_width(ImlibData *im, const char *title,
1078 const char *button1_label,
1079 const char *button2_label,
1080 xitk_state_callback_t cb1,
1081 xitk_state_callback_t cb2,
1082 const char *checkbox_label,
1083 int checkbox_state,
1084 xitk_state_callback_t cb3,
1085 void *userdata,
1086 int window_width, int align,
1087 const char *message, ...) {
1088 xitk_dialog_t *wd;
1089 xitk_labelbutton_widget_t lb;
1090 int windoww = window_width, windowh;
1091 xitk_image_t *image;
1092 int bwidth = 150, bx1, bx2, by;
1093 int checkbox_height = 0;
1094
1095 if((im == NULL) || (window_width == 0) || (message == NULL))
1096 return NULL;
1097
1098 {
1099 va_list args;
1100 char *buf;
1101
1102 va_start(args, message);
1103 buf = xitk_vasprintf(message, args);
1104 va_end(args);
1105
1106 if (!buf)
1107 return NULL;
1108
1109 image = xitk_image_create_image_from_string(im, DEFAULT_FONT_12, windoww - 40, align, buf);
1110 free(buf);
1111 }
1112
1113 if( checkbox_label )
1114 checkbox_height = 50;
1115
1116 windowh = (image->height + 50 + checkbox_height) + (TITLE_BAR_HEIGHT + 40);
1117
1118 wd = (xitk_dialog_t *) xitk_xmalloc(sizeof(xitk_dialog_t));
1119
1120 wd->imlibdata = im;
1121 wd->type = DIALOG_TYPE_YESNO;
1122 wd->yescallback = cb1;
1123 wd->nocallback = cb2;
1124 wd->userdata = userdata;
1125 wd->xwin = xitk_window_create_dialog_window(im, ((title != NULL) ? title : _("Question?")),
1126 0, 0, windoww, windowh);
1127 wd->xwin->parent = wd;
1128 xitk_window_center_window(im, wd->xwin);
1129
1130 wd->widget_list = xitk_widget_list_new();
1131 xitk_dlist_init (&wd->widget_list->list);
1132 wd->widget_list->win = (xitk_window_get_window(wd->xwin));
1133 XLOCK (wd->imlibdata->x.x_lock_display, wd->imlibdata->x.disp);
1134 wd->widget_list->gc = (XCreateGC(im->x.disp, (xitk_window_get_window(wd->xwin)),
1135 None, None));
1136 XUNLOCK (wd->imlibdata->x.x_unlock_display, wd->imlibdata->x.disp);
1137
1138 /* Checkbox */
1139 if( checkbox_label ) {
1140 int x = 25, y = windowh - 50 - checkbox_height;
1141 xitk_checkbox_widget_t cb;
1142 xitk_label_widget_t lbl;
1143
1144 XITK_WIDGET_INIT(&cb, im);
1145 XITK_WIDGET_INIT(&lbl, im);
1146
1147 cb.skin_element_name = NULL;
1148 cb.callback = cb3;
1149 cb.userdata = userdata;
1150 wd->checkbox = xitk_noskin_checkbox_create (wd->widget_list, &cb, x, y+5, 10, 10);
1151 xitk_dlist_add_tail (&wd->widget_list->list, &wd->checkbox->node);
1152 xitk_checkbox_set_state(wd->checkbox, checkbox_state);
1153
1154 lbl.window = xitk_window_get_window(wd->xwin);
1155 lbl.gc = (XITK_WIDGET_LIST_GC(wd->widget_list));
1156 lbl.skin_element_name = NULL;
1157 lbl.label = checkbox_label;
1158 lbl.callback = _checkbox_label_click;
1159 lbl.userdata = wd;
1160 wd->checkbox_label = xitk_noskin_label_create (wd->widget_list, &lbl, x + 15, y, windoww - x - 40, 20, DEFAULT_FONT_12);
1161 xitk_dlist_add_tail (&wd->widget_list->list, &wd->checkbox_label->node);
1162 }
1163
1164 /* Buttons */
1165 if((bwidth * 2) > windoww)
1166 bwidth = (windoww / 2) - 8;
1167
1168 bx1 = ((windoww - (bwidth * 2)) / 3);
1169 bx2 = (bx1 + bwidth) + bx1;
1170 by = windowh - 50;
1171
1172 XITK_WIDGET_INIT(&lb, im);
1173 lb.button_type = CLICK_BUTTON;
1174 lb.label = button1_label;
1175 lb.align = ALIGN_CENTER;
1176 lb.callback = _xitk_window_destroy_window;
1177 lb.state_callback = NULL;
1178 lb.userdata = (void*)wd;
1179 lb.skin_element_name = NULL;
1180 wd->wyes = xitk_noskin_labelbutton_create (wd->widget_list, &lb,
1181 bx1, by, bwidth, 30, "Black", "Black", "White", DEFAULT_BOLD_FONT_12);
1182 xitk_dlist_add_tail (&wd->widget_list->list, &wd->wyes->node);
1183
1184 lb.button_type = CLICK_BUTTON;
1185 lb.label = button2_label;
1186 lb.align = ALIGN_CENTER;
1187 lb.callback = _xitk_window_destroy_window;
1188 lb.state_callback = NULL;
1189 lb.userdata = (void*)wd;
1190 lb.skin_element_name = NULL;
1191 wd->wno = xitk_noskin_labelbutton_create (wd->widget_list, &lb,
1192 bx2, by, bwidth, 30, "Black", "Black", "White", DEFAULT_BOLD_FONT_12);
1193 xitk_dlist_add_tail (&wd->widget_list->list, &wd->wno->node);
1194
1195 wd->default_button = wd->wno;
1196
1197 /* Draw text area */
1198 {
1199 xitk_pixmap_t *bg;
1200 int width, height;
1201 GC gc;
1202
1203 xitk_window_get_window_size(wd->xwin, &width, &height);
1204 bg = xitk_image_create_xitk_pixmap(im, width, height);
1205
1206 XLOCK (im->x.x_lock_display, im->x.disp);
1207 gc = XCreateGC(im->x.disp, (xitk_window_get_background(wd->xwin)), None, None);
1208 XCopyArea(im->x.disp, (xitk_window_get_background(wd->xwin)), bg->pixmap,
1209 gc, 0, 0, width, height, 0, 0);
1210 XCopyArea(im->x.disp, image->image->pixmap, bg->pixmap,
1211 image->image->gc, 0, 0, image->width, image->height, 20, (TITLE_BAR_HEIGHT + 20));
1212 XUNLOCK (im->x.x_unlock_display, im->x.disp);
1213
1214 xitk_window_change_background(im, wd->xwin, bg->pixmap, width, height);
1215
1216 xitk_image_destroy_xitk_pixmap(bg);
1217
1218 XLOCK (im->x.x_lock_display, im->x.disp);
1219 XFreeGC(im->x.disp, gc);
1220 XUNLOCK (im->x.x_unlock_display, im->x.disp);
1221
1222 xitk_image_free_image(im, &image);
1223
1224 }
1225
1226 XLOCK (im->x.x_lock_display, im->x.disp);
1227 XMapRaised(im->x.disp, (xitk_window_get_window(wd->xwin)));
1228 XUNLOCK (im->x.x_unlock_display, im->x.disp);
1229
1230 wd->key = xitk_register_event_handler("xitk_2btns",
1231 (xitk_window_get_window(wd->xwin)),
1232 _window_handle_event,
1233 NULL,
1234 NULL,
1235 wd->widget_list,
1236 (void *)wd);
1237 xitk_enable_and_show_widget(wd->wyes);
1238 xitk_enable_and_show_widget(wd->wno);
1239 if( checkbox_label ) {
1240 xitk_enable_and_show_widget(wd->checkbox);
1241 xitk_enable_and_show_widget(wd->checkbox_label);
1242 }
1243
1244 _xitk_window_set_focus(im->x.disp, (xitk_window_get_window(wd->xwin)));
1245
1246 return wd->xwin;
1247 }
1248
1249 /*
1250 *
1251 */
xitk_window_dialog_yesno_with_width(ImlibData * im,const char * title,xitk_state_callback_t ycb,xitk_state_callback_t ncb,void * userdata,int window_width,int align,const char * message,...)1252 xitk_window_t *xitk_window_dialog_yesno_with_width(ImlibData *im, const char *title,
1253 xitk_state_callback_t ycb,
1254 xitk_state_callback_t ncb,
1255 void *userdata,
1256 int window_width, int align,
1257 const char *message, ...) {
1258 va_list args;
1259 char *buf;
1260 xitk_window_t *xw = NULL;
1261
1262 va_start(args, message);
1263 buf = xitk_vasprintf(message, args);
1264 va_end(args);
1265
1266 if (!buf)
1267 return NULL;
1268
1269 xw = xitk_window_dialog_two_buttons_with_width(im, title, _("Yes"), _("No"),
1270 ycb, ncb, userdata, window_width, align, "%s", buf);
1271 free(buf);
1272 return xw;
1273 }
1274
1275 /*
1276 * Create an interactive window, containing 'yes', 'no', 'cancel' buttons.
1277 */
xitk_window_dialog_three_buttons_with_width(ImlibData * im,const char * title,const char * button1_label,const char * button2_label,const char * button3_label,xitk_state_callback_t cb1,xitk_state_callback_t cb2,xitk_state_callback_t cb3,void * userdata,int window_width,int align,const char * message,...)1278 xitk_window_t *xitk_window_dialog_three_buttons_with_width(ImlibData *im, const char *title,
1279 const char *button1_label,
1280 const char *button2_label,
1281 const char *button3_label,
1282 xitk_state_callback_t cb1,
1283 xitk_state_callback_t cb2,
1284 xitk_state_callback_t cb3,
1285 void *userdata,
1286 int window_width, int align,
1287 const char *message, ...) {
1288 xitk_dialog_t *wd;
1289 xitk_labelbutton_widget_t lb;
1290 int windoww = window_width, windowh;
1291 xitk_image_t *image;
1292 int bwidth = 100, bx1, bx2, bx3, by;
1293
1294 if((im == NULL) || (window_width == 0) || (message == NULL))
1295 return NULL;
1296
1297 {
1298 va_list args;
1299 char *buf;
1300
1301 va_start(args, message);
1302 buf = xitk_vasprintf(message, args);
1303 va_end(args);
1304
1305 if (!buf)
1306 return NULL;
1307
1308 image = xitk_image_create_image_from_string(im, DEFAULT_FONT_12, windoww - 40, align, buf);
1309 XITK_FREE(buf);
1310 }
1311
1312 windowh = (image->height + 50) + (TITLE_BAR_HEIGHT + 40);
1313
1314 wd = (xitk_dialog_t *) xitk_xmalloc(sizeof(xitk_dialog_t));
1315
1316 wd->imlibdata = im;
1317 wd->type = DIALOG_TYPE_YESNOCANCEL;
1318 wd->yescallback = cb1;
1319 wd->nocallback = cb2;
1320 wd->cancelcallback = cb3;
1321 wd->userdata = userdata;
1322 wd->xwin = xitk_window_create_dialog_window(im, ((title != NULL)
1323 ? title : _("Question?")),
1324 0, 0, windoww, windowh);
1325 wd->xwin->parent = wd;
1326
1327 xitk_window_center_window(im, wd->xwin);
1328
1329 wd->widget_list = xitk_widget_list_new();
1330 xitk_dlist_init (&wd->widget_list->list);
1331 wd->widget_list->win = (xitk_window_get_window(wd->xwin));
1332 XLOCK (wd->imlibdata->x.x_lock_display, wd->imlibdata->x.disp);
1333 wd->widget_list->gc = (XCreateGC(im->x.disp, (xitk_window_get_window(wd->xwin)),
1334 None, None));
1335 XUNLOCK (wd->imlibdata->x.x_unlock_display, wd->imlibdata->x.disp);
1336
1337 /* Buttons */
1338 if((bwidth * 3) > windoww)
1339 bwidth = (windoww / 3) - 12;
1340
1341 bx1 = ((windoww - (bwidth * 3)) / 4);
1342 bx2 = (bx1 + bwidth) + bx1;
1343 bx3 = (bx2 + bwidth) + bx1;
1344 by = windowh - 50;
1345
1346 XITK_WIDGET_INIT(&lb, im);
1347 lb.button_type = CLICK_BUTTON;
1348 lb.label = button1_label;
1349 lb.align = ALIGN_CENTER;
1350 lb.callback = _xitk_window_destroy_window;
1351 lb.state_callback = NULL;
1352 lb.userdata = (void*)wd;
1353 lb.skin_element_name = NULL;
1354 wd->wyes = xitk_noskin_labelbutton_create (wd->widget_list, &lb,
1355 bx1, by, bwidth, 30, "Black", "Black", "White", DEFAULT_BOLD_FONT_12);
1356 xitk_dlist_add_tail (&wd->widget_list->list, &wd->wyes->node);
1357
1358 lb.button_type = CLICK_BUTTON;
1359 lb.label = button2_label;
1360 lb.align = ALIGN_CENTER;
1361 lb.callback = _xitk_window_destroy_window;
1362 lb.state_callback = NULL;
1363 lb.userdata = (void*)wd;
1364 lb.skin_element_name = NULL;
1365 wd->wno = xitk_noskin_labelbutton_create (wd->widget_list, &lb,
1366 bx2, by, bwidth, 30, "Black", "Black", "White", DEFAULT_BOLD_FONT_12);
1367 xitk_dlist_add_tail (&wd->widget_list->list, &wd->wno->node);
1368
1369 lb.button_type = CLICK_BUTTON;
1370 lb.label = button3_label;
1371 lb.align = ALIGN_CENTER;
1372 lb.callback = _xitk_window_destroy_window;
1373 lb.state_callback = NULL;
1374 lb.userdata = (void*)wd;
1375 lb.skin_element_name = NULL;
1376 wd->wcancel = xitk_noskin_labelbutton_create (wd->widget_list, &lb,
1377 bx3, by, bwidth, 30, "Black", "Black", "White", DEFAULT_BOLD_FONT_12);
1378 xitk_dlist_add_tail (&wd->widget_list->list, &wd->wcancel->node);
1379
1380 wd->default_button = wd->wcancel;
1381
1382 /* Draw text area */
1383 {
1384 xitk_pixmap_t *bg;
1385 int width, height;
1386 GC gc;
1387
1388 xitk_window_get_window_size(wd->xwin, &width, &height);
1389 bg = xitk_image_create_xitk_pixmap(im, width, height);
1390
1391 XLOCK (im->x.x_lock_display, im->x.disp);
1392 gc = XCreateGC(im->x.disp, (xitk_window_get_background(wd->xwin)), None, None);
1393 XCopyArea(im->x.disp, (xitk_window_get_background(wd->xwin)), bg->pixmap,
1394 gc, 0, 0, width, height, 0, 0);
1395 XCopyArea(im->x.disp, image->image->pixmap, bg->pixmap,
1396 image->image->gc, 0, 0, image->width, image->height, 20, (TITLE_BAR_HEIGHT + 20));
1397 XUNLOCK (im->x.x_unlock_display, im->x.disp);
1398
1399 xitk_window_change_background(im, wd->xwin, bg->pixmap, width, height);
1400
1401 xitk_image_destroy_xitk_pixmap(bg);
1402 XLOCK (im->x.x_lock_display, im->x.disp);
1403 XFreeGC(im->x.disp, gc);
1404 XUNLOCK (im->x.x_unlock_display, im->x.disp);
1405
1406 xitk_image_free_image(im, &image);
1407
1408 }
1409
1410 XLOCK (im->x.x_lock_display, im->x.disp);
1411 XMapRaised(im->x.disp, (xitk_window_get_window(wd->xwin)));
1412 XUNLOCK (im->x.x_unlock_display, im->x.disp);
1413
1414 wd->key = xitk_register_event_handler("xitk_3btns",
1415 (xitk_window_get_window(wd->xwin)),
1416 _window_handle_event,
1417 NULL,
1418 NULL,
1419 wd->widget_list,
1420 (void *)wd);
1421 xitk_enable_and_show_widget(wd->wyes);
1422 xitk_enable_and_show_widget(wd->wno);
1423 xitk_enable_and_show_widget(wd->wcancel);
1424
1425 _xitk_window_set_focus(im->x.disp, (xitk_window_get_window(wd->xwin)));
1426
1427 return wd->xwin;
1428 }
1429
xitk_window_dialog_yesnocancel_with_width(ImlibData * im,const char * title,xitk_state_callback_t ycb,xitk_state_callback_t ncb,xitk_state_callback_t ccb,void * userdata,int window_width,int align,const char * message,...)1430 xitk_window_t *xitk_window_dialog_yesnocancel_with_width(ImlibData *im, const char *title,
1431 xitk_state_callback_t ycb,
1432 xitk_state_callback_t ncb,
1433 xitk_state_callback_t ccb,
1434 void *userdata,
1435 int window_width, int align,
1436 const char *message, ...) {
1437 va_list args;
1438 char *buf;
1439 xitk_window_t *xw = NULL;
1440
1441 va_start(args, message);
1442 buf = xitk_vasprintf(message, args);
1443 va_end(args);
1444
1445 if (!buf)
1446 return NULL;
1447
1448 xw = xitk_window_dialog_three_buttons_with_width(im, title, _("Yes"), _("No"), _("Cancel"),
1449 ycb, ncb, ccb, userdata, window_width, align, "%s", buf);
1450 free(buf);
1451 return xw;
1452 }
1453
xitk_window_set_parent_window(xitk_window_t * xwin,Window parent)1454 void xitk_window_set_parent_window(xitk_window_t *xwin, Window parent) {
1455 if(xwin)
1456 xwin->win_parent = parent;
1457 }
1458