Fixed wrong re-generation of 'config-paths.h' file
[wmaker-crm.git] / src / framewin.c
blob2d3c0099e34f109f07ad248891c6cbcaace4118c
1 /*
2 * Window Maker window manager
4 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * This program 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.
11 * This program 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.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "wconfig.h"
23 #include <X11/Xlib.h>
24 #include <X11/Xutil.h>
25 #ifdef KEEP_XKB_LOCK_STATUS
26 #include <X11/XKBlib.h>
27 #endif /* KEEP_XKB_LOCK_STATUS */
29 #include <stdlib.h>
30 #include <string.h>
32 #include <wraster.h>
34 #include "WindowMaker.h"
35 #include "GNUstep.h"
36 #include "texture.h"
37 #include "screen.h"
38 #include "wcore.h"
39 #include "framewin.h"
40 #include "stacking.h"
41 #include "funcs.h"
43 #define DBLCLICK_TIME wPreferences.dblclick_time
45 extern WPreferences wPreferences;
47 static void handleExpose(WObjDescriptor * desc, XEvent * event);
48 static void handleButtonExpose(WObjDescriptor * desc, XEvent * event);
50 static void buttonMouseDown(WObjDescriptor * desc, XEvent * event);
51 static void titlebarMouseDown(WObjDescriptor * desc, XEvent * event);
52 static void resizebarMouseDown(WObjDescriptor * desc, XEvent * event);
54 static void checkTitleSize(WFrameWindow * fwin);
56 static void paintButton(WCoreWindow * button, WTexture * texture,
57 unsigned long color, WPixmap * image, int pushed);
59 static void updateTitlebar(WFrameWindow * fwin);
61 WFrameWindow *wFrameWindowCreate(WScreen * scr, int wlevel, int x, int y,
62 int width, int height, int *clearance,
63 int *title_min, int *title_max, int flags,
64 WTexture ** title_texture, WTexture ** resize_texture,
65 WMColor ** color, WMFont ** font)
67 WFrameWindow *fwin;
69 fwin = wmalloc(sizeof(WFrameWindow));
71 fwin->screen_ptr = scr;
73 fwin->flags.single_texture = (flags & WFF_SINGLE_STATE) ? 1 : 0;
75 fwin->title_texture = title_texture;
76 fwin->resizebar_texture = resize_texture;
77 fwin->title_color = color;
78 fwin->title_clearance = clearance;
79 fwin->title_min_height = title_min;
80 fwin->title_max_height = title_max;
81 fwin->font = font;
82 #ifdef KEEP_XKB_LOCK_STATUS
83 fwin->languagemode = XkbGroup1Index;
84 fwin->last_languagemode = XkbGroup2Index;
85 #endif
87 fwin->core = wCoreCreateTopLevel(scr, x, y, width, height, (flags & WFF_BORDER)
88 ? FRAME_BORDER_WIDTH : 0);
89 if (wPreferences.use_saveunders) {
90 unsigned long vmask;
91 XSetWindowAttributes attribs;
93 vmask = CWSaveUnder;
94 attribs.save_under = True;
95 XChangeWindowAttributes(dpy, fwin->core->window, vmask, &attribs);
98 /* setup stacking information */
99 fwin->core->stacking = wmalloc(sizeof(WStacking));
100 fwin->core->stacking->above = NULL;
101 fwin->core->stacking->under = NULL;
102 fwin->core->stacking->child_of = NULL;
103 fwin->core->stacking->window_level = wlevel;
105 AddToStackList(fwin->core);
107 wFrameWindowUpdateBorders(fwin, flags);
109 return fwin;
112 void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags)
114 int theight;
115 int bsize;
116 int width, height;
117 int i;
118 WScreen *scr = fwin->screen_ptr;
120 width = fwin->core->width;
121 if (flags & WFF_IS_SHADED)
122 height = -1;
123 else
124 height = fwin->core->height - fwin->top_width - fwin->bottom_width;
126 if (flags & WFF_TITLEBAR) {
127 theight = WMFontHeight(*fwin->font) + (*fwin->title_clearance + TITLEBAR_EXTEND_SPACE) * 2;
129 if (theight > *fwin->title_max_height)
130 theight = *fwin->title_max_height;
132 if (theight < *fwin->title_min_height)
133 theight = *fwin->title_min_height;
134 } else
135 theight = 0;
137 if (wPreferences.new_style == TS_NEW) {
138 bsize = theight;
139 } else if (wPreferences.new_style == TS_OLD) {
140 bsize = theight - 7;
141 } else {
142 bsize = theight - 8;
145 if (fwin->titlebar) {
146 /* if we had a titlebar and is requesting for one,
147 * check if the size has changed and resize it */
148 if (flags & WFF_TITLEBAR) {
149 fwin->top_width = theight;
151 fwin->flags.need_texture_remake = 1;
153 if (wPreferences.new_style == TS_NEW) {
154 if (fwin->left_button) {
155 wCoreConfigure(fwin->left_button, 0, 0, bsize, bsize);
157 #ifdef XKB_BUTTON_HINT
158 if (fwin->language_button) {
159 if (fwin->flags.hide_left_button || !fwin->left_button
160 || fwin->flags.lbutton_dont_fit) {
161 wCoreConfigure(fwin->language_button, 0, 0, bsize, bsize);
162 } else {
163 wCoreConfigure(fwin->language_button, bsize, 0, bsize, bsize);
166 #endif
168 if (fwin->right_button) {
169 wCoreConfigure(fwin->right_button, width - bsize + 1, 0, bsize, bsize);
171 } else { /* !new_style */
172 if (fwin->left_button) {
173 wCoreConfigure(fwin->left_button, 3, (theight - bsize) / 2, bsize, bsize);
175 #ifdef XKB_BUTTON_HINT
176 if (fwin->language_button) {
177 wCoreConfigure(fwin->language_button, 6 + bsize, (theight - bsize) / 2,
178 bsize, bsize);
180 #endif
182 if (fwin->right_button) {
183 wCoreConfigure(fwin->right_button, width - bsize - 3,
184 (theight - bsize) / 2, bsize, bsize);
187 updateTitlebar(fwin);
188 } else {
189 /* we had a titlebar, but now we don't need it anymore */
190 for (i = 0; i < (fwin->flags.single_texture ? 1 : 3); i++) {
191 FREE_PIXMAP(fwin->title_back[i]);
192 if (wPreferences.new_style == TS_NEW) {
193 FREE_PIXMAP(fwin->lbutton_back[i]);
194 FREE_PIXMAP(fwin->rbutton_back[i]);
195 #ifdef XKB_BUTTON_HINT
196 FREE_PIXMAP(fwin->languagebutton_back[i]);
197 #endif
200 if (fwin->left_button)
201 wCoreDestroy(fwin->left_button);
202 fwin->left_button = NULL;
204 #ifdef XKB_BUTTON_HINT
205 if (fwin->language_button)
206 wCoreDestroy(fwin->language_button);
207 fwin->language_button = NULL;
208 #endif
210 if (fwin->right_button)
211 wCoreDestroy(fwin->right_button);
212 fwin->right_button = NULL;
214 wCoreDestroy(fwin->titlebar);
215 fwin->titlebar = NULL;
217 fwin->top_width = 0;
219 } else {
220 /* if we didn't have a titlebar and are being requested for
221 * one, create it */
222 if (flags & WFF_TITLEBAR) {
223 fwin->top_width = theight;
225 fwin->flags.titlebar = 1;
226 fwin->titlebar = wCoreCreate(fwin->core, 0, 0, width + 1, theight);
228 if (flags & WFF_LEFT_BUTTON) {
229 fwin->flags.left_button = 1;
230 if (wPreferences.new_style == TS_NEW) {
231 fwin->left_button = wCoreCreate(fwin->core, 0, 0, bsize, bsize);
232 if (width < theight * 4) {
233 fwin->flags.lbutton_dont_fit = 1;
234 } else {
235 XMapRaised(dpy, fwin->left_button->window);
237 } else if (wPreferences.new_style == TS_OLD) {
238 fwin->left_button =
239 wCoreCreate(fwin->titlebar, 3, (theight - bsize) / 2, bsize, bsize);
241 XSetWindowBackground(dpy, fwin->left_button->window,
242 scr->widget_texture->normal.pixel);
244 if (width < theight * 3) {
245 fwin->flags.lbutton_dont_fit = 1;
246 } else {
247 XMapRaised(dpy, fwin->left_button->window);
249 } else {
250 fwin->left_button =
251 wCoreCreate(fwin->titlebar, 3, (theight-bsize)/2,
252 bsize, bsize);
254 XSetWindowBackground(dpy, fwin->left_button->window,
255 scr->widget_texture->dark.pixel);
257 if (width < theight*3) {
258 fwin->flags.lbutton_dont_fit = 1;
259 } else {
260 XMapRaised(dpy, fwin->left_button->window);
264 #ifdef XKB_BUTTON_HINT
265 if (flags & WFF_LANGUAGE_BUTTON) {
266 fwin->flags.language_button = 1;
267 if (wPreferences.new_style == TS_NEW) {
268 fwin->language_button = wCoreCreate(fwin->core, bsize, 0, bsize, bsize);
270 if (width < theight * 4) {
271 fwin->flags.languagebutton_dont_fit = 1;
272 } else {
273 XMapRaised(dpy, fwin->language_button->window);
275 } else {
276 fwin->language_button =
277 wCoreCreate(fwin->titlebar, bsize + 6, (theight - bsize) / 2,
278 bsize, bsize);
280 XSetWindowBackground(dpy, fwin->language_button->window,
281 scr->widget_texture->normal.pixel);
283 if (width < theight * 3) {
284 fwin->flags.languagebutton_dont_fit = 1;
285 } else {
286 XMapRaised(dpy, fwin->language_button->window);
290 #endif
292 if (flags & WFF_RIGHT_BUTTON) {
293 fwin->flags.right_button = 1;
294 if (wPreferences.new_style == TS_NEW) {
295 fwin->right_button =
296 wCoreCreate(fwin->core, width - bsize + 1, 0, bsize, bsize);
297 } else if (wPreferences.new_style == TS_OLD) {
298 fwin->right_button =
299 wCoreCreate(fwin->titlebar, width - bsize - 3,
300 (theight - bsize) / 2, bsize, bsize);
301 XSetWindowBackground(dpy, fwin->right_button->window,
302 scr->widget_texture->normal.pixel);
303 } else {
304 fwin->right_button =
305 wCoreCreate(fwin->titlebar, width-bsize-3,
306 (theight-bsize)/2, bsize, bsize);
307 XSetWindowBackground(dpy, fwin->right_button->window,
308 scr->widget_texture->dark.pixel);
311 if (width < theight * 2) {
312 fwin->flags.rbutton_dont_fit = 1;
313 } else {
314 XMapRaised(dpy, fwin->right_button->window);
318 if (wPreferences.new_style == TS_NEW)
319 updateTitlebar(fwin);
321 XMapRaised(dpy, fwin->titlebar->window);
323 fwin->flags.need_texture_remake = 1;
326 checkTitleSize(fwin);
328 if (flags & WFF_RESIZEBAR) {
329 fwin->bottom_width = RESIZEBAR_HEIGHT;
331 if (!fwin->resizebar) {
332 fwin->flags.resizebar = 1;
333 fwin->resizebar = wCoreCreate(fwin->core, 0,
334 height + fwin->top_width, width, RESIZEBAR_HEIGHT);
335 fwin->resizebar_corner_width = RESIZEBAR_CORNER_WIDTH;
336 if (width < RESIZEBAR_CORNER_WIDTH * 2 + RESIZEBAR_MIN_WIDTH) {
337 fwin->resizebar_corner_width = (width - RESIZEBAR_MIN_WIDTH) / 2;
338 if (fwin->resizebar_corner_width < 0)
339 fwin->resizebar_corner_width = 0;
342 XMapWindow(dpy, fwin->resizebar->window);
343 XLowerWindow(dpy, fwin->resizebar->window);
345 fwin->flags.need_texture_remake = 1;
346 } else {
347 if (height + fwin->top_width + fwin->bottom_width != fwin->core->height) {
348 wCoreConfigure(fwin->resizebar, 0, height + fwin->top_width,
349 width, RESIZEBAR_HEIGHT);
352 } else {
353 fwin->bottom_width = 0;
355 if (fwin->resizebar) {
356 fwin->bottom_width = 0;
357 wCoreDestroy(fwin->resizebar);
358 fwin->resizebar = NULL;
362 if (height + fwin->top_width + fwin->bottom_width != fwin->core->height && !(flags & WFF_IS_SHADED)) {
363 wFrameWindowResize(fwin, width, height + fwin->top_width + fwin->bottom_width);
366 if (flags & WFF_BORDER) {
367 XSetWindowBorderWidth(dpy, fwin->core->window, FRAME_BORDER_WIDTH);
368 } else {
369 XSetWindowBorderWidth(dpy, fwin->core->window, 0);
372 /* setup object descriptors */
374 if (fwin->titlebar) {
375 fwin->titlebar->descriptor.handle_expose = handleExpose;
376 fwin->titlebar->descriptor.parent = fwin;
377 fwin->titlebar->descriptor.parent_type = WCLASS_FRAME;
378 fwin->titlebar->descriptor.handle_mousedown = titlebarMouseDown;
381 if (fwin->resizebar) {
382 fwin->resizebar->descriptor.handle_expose = handleExpose;
383 fwin->resizebar->descriptor.parent = fwin;
384 fwin->resizebar->descriptor.parent_type = WCLASS_FRAME;
385 fwin->resizebar->descriptor.handle_mousedown = resizebarMouseDown;
388 if (fwin->left_button) {
389 fwin->left_button->descriptor.handle_expose = handleButtonExpose;
390 fwin->left_button->descriptor.parent = fwin;
391 fwin->left_button->descriptor.parent_type = WCLASS_FRAME;
392 fwin->left_button->descriptor.handle_mousedown = buttonMouseDown;
394 #ifdef XKB_BUTTON_HINT
395 if (fwin->language_button) {
396 fwin->language_button->descriptor.handle_expose = handleButtonExpose;
397 fwin->language_button->descriptor.parent = fwin;
398 fwin->language_button->descriptor.parent_type = WCLASS_FRAME;
399 fwin->language_button->descriptor.handle_mousedown = buttonMouseDown;
401 #endif
403 if (fwin->right_button) {
404 fwin->right_button->descriptor.parent = fwin;
405 fwin->right_button->descriptor.parent_type = WCLASS_FRAME;
406 fwin->right_button->descriptor.handle_expose = handleButtonExpose;
407 fwin->right_button->descriptor.handle_mousedown = buttonMouseDown;
410 checkTitleSize(fwin);
413 void wFrameWindowDestroy(WFrameWindow * fwin)
415 int i;
417 if (fwin->left_button)
418 wCoreDestroy(fwin->left_button);
420 #ifdef XKB_BUTTON_HINT
421 if (fwin->language_button)
422 wCoreDestroy(fwin->language_button);
423 #endif
425 if (fwin->right_button)
426 wCoreDestroy(fwin->right_button);
428 if (fwin->resizebar)
429 wCoreDestroy(fwin->resizebar);
431 if (fwin->titlebar)
432 wCoreDestroy(fwin->titlebar);
434 RemoveFromStackList(fwin->core);
436 wCoreDestroy(fwin->core);
438 if (fwin->title)
439 wfree(fwin->title);
441 for (i = 0; i < (fwin->flags.single_texture ? 1 : 3); i++) {
442 FREE_PIXMAP(fwin->title_back[i]);
443 if (wPreferences.new_style == TS_NEW) {
444 FREE_PIXMAP(fwin->lbutton_back[i]);
445 #ifdef XKB_BUTTON_HINT
446 FREE_PIXMAP(fwin->languagebutton_back[i]);
447 #endif
448 FREE_PIXMAP(fwin->rbutton_back[i]);
452 wfree(fwin);
455 void wFrameWindowChangeState(WFrameWindow * fwin, int state)
457 if (fwin->flags.state == state)
458 return;
460 fwin->flags.state = state;
461 fwin->flags.need_texture_change = 1;
463 wFrameWindowPaint(fwin);
466 static void updateTitlebar(WFrameWindow * fwin)
468 int x, w;
469 int theight;
471 theight = WMFontHeight(*fwin->font) + (*fwin->title_clearance + TITLEBAR_EXTEND_SPACE) * 2;
473 if (theight > *fwin->title_max_height)
474 theight = *fwin->title_max_height;
476 if (theight < *fwin->title_min_height)
477 theight = *fwin->title_min_height;
479 x = 0;
480 w = fwin->core->width + 1;
482 if (wPreferences.new_style == TS_NEW) {
483 if (fwin->flags.hide_left_button || !fwin->left_button || fwin->flags.lbutton_dont_fit) {
484 x = 0;
485 #ifdef XKB_BUTTON_HINT
486 if (fwin->language_button)
487 wCoreConfigure(fwin->language_button, 0, 0,
488 fwin->language_button->width, fwin->language_button->width);
489 #endif
490 } else {
491 #ifdef XKB_BUTTON_HINT
492 if (fwin->language_button)
493 wCoreConfigure(fwin->language_button, fwin->left_button->width, 0,
494 fwin->language_button->width, fwin->language_button->width);
495 #endif
496 x = fwin->left_button->width;
497 w -= fwin->left_button->width;
499 #ifdef XKB_BUTTON_HINT
500 if (fwin->flags.hide_language_button || !fwin->language_button
501 || fwin->flags.languagebutton_dont_fit) {
502 } else {
503 x += fwin->language_button->width;
504 w -= fwin->language_button->width;
506 #endif
508 #ifdef XKB_BUTTON_HINT
509 else {
510 int bsize = theight - 7;
511 if (fwin->flags.hide_left_button || !fwin->left_button || fwin->flags.lbutton_dont_fit) {
512 if (fwin->language_button)
513 wCoreConfigure(fwin->language_button, 3, (theight - bsize) / 2,
514 fwin->language_button->width, fwin->language_button->width);
515 } else {
516 if (fwin->language_button)
517 wCoreConfigure(fwin->language_button,
518 6 + fwin->left_button->width, (theight - bsize) / 2,
519 fwin->language_button->width, fwin->language_button->width);
522 #endif
524 if (wPreferences.new_style == TS_NEW) {
525 if (!fwin->flags.hide_right_button && fwin->right_button && !fwin->flags.rbutton_dont_fit) {
526 w -= fwin->right_button->width;
530 if (wPreferences.new_style == TS_NEW || fwin->titlebar->width != w)
531 fwin->flags.need_texture_remake = 1;
533 wCoreConfigure(fwin->titlebar, x, 0, w, theight);
536 void wFrameWindowHideButton(WFrameWindow * fwin, int flags)
538 if ((flags & WFF_RIGHT_BUTTON) && fwin->right_button) {
539 XUnmapWindow(dpy, fwin->right_button->window);
540 fwin->flags.hide_right_button = 1;
543 if ((flags & WFF_LEFT_BUTTON) && fwin->left_button) {
544 XUnmapWindow(dpy, fwin->left_button->window);
545 fwin->flags.hide_left_button = 1;
547 #ifdef XKB_BUTTON_HINT
548 if ((flags & WFF_LANGUAGE_BUTTON) && fwin->language_button) {
549 XUnmapWindow(dpy, fwin->language_button->window);
550 fwin->flags.hide_language_button = 1;
552 #endif
554 if (fwin->titlebar) {
555 if (wPreferences.new_style == TS_NEW) {
556 updateTitlebar(fwin);
557 } else {
558 #ifdef XKB_BUTTON_HINT
559 updateTitlebar(fwin);
560 #else
561 XClearWindow(dpy, fwin->titlebar->window);
562 wFrameWindowPaint(fwin);
563 #endif
565 checkTitleSize(fwin);
569 void wFrameWindowShowButton(WFrameWindow * fwin, int flags)
571 if ((flags & WFF_RIGHT_BUTTON) && fwin->right_button && fwin->flags.hide_right_button) {
573 if (!fwin->flags.rbutton_dont_fit)
574 XMapWindow(dpy, fwin->right_button->window);
576 fwin->flags.hide_right_button = 0;
578 #ifdef XKB_BUTTON_HINT
579 if ((flags & WFF_LANGUAGE_BUTTON) && fwin->language_button && fwin->flags.hide_language_button) {
581 if (!fwin->flags.languagebutton_dont_fit)
582 XMapWindow(dpy, fwin->language_button->window);
584 fwin->flags.hide_language_button = 0;
586 #endif
588 if ((flags & WFF_LEFT_BUTTON) && fwin->left_button && fwin->flags.hide_left_button) {
590 if (!fwin->flags.lbutton_dont_fit)
591 XMapWindow(dpy, fwin->left_button->window);
593 fwin->flags.hide_left_button = 0;
596 if (fwin->titlebar) {
597 if (wPreferences.new_style == TS_NEW) {
598 updateTitlebar(fwin);
599 } else {
600 XClearWindow(dpy, fwin->titlebar->window);
601 wFrameWindowPaint(fwin);
603 checkTitleSize(fwin);
607 static void
608 #ifdef XKB_BUTTON_HINT
609 renderTexture(WScreen * scr, WTexture * texture, int width, int height,
610 int bwidth, int bheight, int left, int language, int right,
611 Pixmap * title, Pixmap * lbutton, Pixmap * languagebutton, Pixmap * rbutton)
612 #else
613 renderTexture(WScreen * scr, WTexture * texture, int width, int height,
614 int bwidth, int bheight, int left, int right, Pixmap * title, Pixmap * lbutton, Pixmap * rbutton)
615 #endif
617 RImage *img;
618 RImage *limg, *rimg, *mimg;
619 #ifdef XKB_BUTTON_HINT
620 RImage *timg;
621 #endif
622 int x, w;
624 *title = None;
625 *lbutton = None;
626 *rbutton = None;
627 #ifdef XKB_BUTTON_HINT
628 *languagebutton = None;
629 #endif
631 img = wTextureRenderImage(texture, width, height, WREL_FLAT);
632 if (!img) {
633 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode));
634 return;
637 if (wPreferences.new_style == TS_NEW) {
638 if (left) {
639 limg = RGetSubImage(img, 0, 0, bwidth, bheight);
640 } else
641 limg = NULL;
643 x = 0;
644 w = img->width;
646 #ifdef XKB_BUTTON_HINT
647 if (language) {
648 timg = RGetSubImage(img, bwidth * left, 0, bwidth, bheight);
649 } else
650 timg = NULL;
651 #endif
653 if (limg) {
654 RBevelImage(limg, RBEV_RAISED2);
655 if (!RConvertImage(scr->rcontext, limg, lbutton)) {
656 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
658 x += limg->width;
659 w -= limg->width;
660 RReleaseImage(limg);
662 #ifdef XKB_BUTTON_HINT
663 if (timg) {
664 RBevelImage(timg, RBEV_RAISED2);
665 if (!RConvertImage(scr->rcontext, timg, languagebutton)) {
666 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
668 x += timg->width;
669 w -= timg->width;
670 RReleaseImage(timg);
672 #endif
674 if (right) {
675 rimg = RGetSubImage(img, width - bwidth, 0, bwidth, bheight);
676 } else
677 rimg = NULL;
679 if (rimg) {
680 RBevelImage(rimg, RBEV_RAISED2);
681 if (!RConvertImage(scr->rcontext, rimg, rbutton)) {
682 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
684 w -= rimg->width;
685 RReleaseImage(rimg);
688 if (w != width) {
689 mimg = RGetSubImage(img, x, 0, w, img->height);
690 RBevelImage(mimg, RBEV_RAISED2);
692 if (!RConvertImage(scr->rcontext, mimg, title)) {
693 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
695 RReleaseImage(mimg);
696 } else {
697 RBevelImage(img, RBEV_RAISED2);
699 if (!RConvertImage(scr->rcontext, img, title)) {
700 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
703 } else {
704 RBevelImage(img, RBEV_RAISED2);
706 if (!RConvertImage(scr->rcontext, img, title)) {
707 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
711 RReleaseImage(img);
714 static void
715 renderResizebarTexture(WScreen * scr, WTexture * texture, int width, int height, int cwidth, Pixmap * pmap)
717 RImage *img;
718 RColor light;
719 RColor dark;
721 *pmap = None;
723 img = wTextureRenderImage(texture, width, height, WREL_FLAT);
724 if (!img) {
725 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode));
726 return;
729 light.alpha = 0;
730 light.red = light.green = light.blue = 80;
732 dark.alpha = 0;
733 dark.red = dark.green = dark.blue = 40;
735 ROperateLine(img, RSubtractOperation, 0, 0, width - 1, 0, &dark);
736 ROperateLine(img, RAddOperation, 0, 1, width - 1, 1, &light);
738 ROperateLine(img, RSubtractOperation, cwidth, 2, cwidth, height - 1, &dark);
739 ROperateLine(img, RAddOperation, cwidth + 1, 2, cwidth + 1, height - 1, &light);
741 if (width > 1)
742 ROperateLine(img, RSubtractOperation, width - cwidth - 2, 2,
743 width - cwidth - 2, height - 1, &dark);
744 ROperateLine(img, RAddOperation, width - cwidth - 1, 2, width - cwidth - 1, height - 1, &light);
746 #ifdef SHADOW_RESIZEBAR
747 ROperateLine(img, RAddOperation, 0, 1, 0, height - 1, &light);
748 ROperateLine(img, RSubtractOperation, width - 1, 1, width - 1, height - 1, &dark);
749 ROperateLine(img, RSubtractOperation, 0, height - 1, width - 1, height - 1, &dark);
750 #endif /* SHADOW_RESIZEBAR */
752 if (!RConvertImage(scr->rcontext, img, pmap)) {
753 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode));
756 RReleaseImage(img);
759 static void updateTexture(WFrameWindow * fwin)
761 int i;
762 unsigned long pixel;
764 i = fwin->flags.state;
765 if (fwin->titlebar) {
766 if (fwin->title_texture[i]->any.type != WTEX_SOLID) {
767 XSetWindowBackgroundPixmap(dpy, fwin->titlebar->window, fwin->title_back[i]);
768 if (wPreferences.new_style == TS_NEW) {
769 if (fwin->left_button && fwin->lbutton_back[i])
770 XSetWindowBackgroundPixmap(dpy, fwin->left_button->window,
771 fwin->lbutton_back[i]);
773 #ifdef XKB_BUTTON_HINT
774 if (fwin->language_button && fwin->languagebutton_back[i]) {
775 XSetWindowBackgroundPixmap(dpy, fwin->language_button->window,
776 fwin->languagebutton_back[i]);
778 #endif
780 if (fwin->right_button && fwin->rbutton_back[i])
781 XSetWindowBackgroundPixmap(dpy, fwin->right_button->window,
782 fwin->rbutton_back[i]);
784 } else {
785 pixel = fwin->title_texture[i]->solid.normal.pixel;
786 XSetWindowBackground(dpy, fwin->titlebar->window, pixel);
787 if (wPreferences.new_style == TS_NEW) {
788 if (fwin->left_button)
789 XSetWindowBackground(dpy, fwin->left_button->window, pixel);
790 #ifdef XKB_BUTTON_HINT
791 if (fwin->language_button)
792 XSetWindowBackground(dpy, fwin->language_button->window, pixel);
793 #endif
794 if (fwin->right_button)
795 XSetWindowBackground(dpy, fwin->right_button->window, pixel);
798 XClearWindow(dpy, fwin->titlebar->window);
800 if (fwin->left_button) {
801 XClearWindow(dpy, fwin->left_button->window);
802 handleButtonExpose(&fwin->left_button->descriptor, NULL);
804 #ifdef XKB_BUTTON_HINT
805 if (fwin->language_button) {
806 XClearWindow(dpy, fwin->language_button->window);
807 handleButtonExpose(&fwin->language_button->descriptor, NULL);
809 #endif
810 if (fwin->right_button) {
811 XClearWindow(dpy, fwin->right_button->window);
812 handleButtonExpose(&fwin->right_button->descriptor, NULL);
817 static void remakeTexture(WFrameWindow * fwin, int state)
819 Pixmap pmap, lpmap, rpmap;
820 #ifdef XKB_BUTTON_HINT
821 Pixmap tpmap;
822 #endif
824 if (fwin->title_texture[state] && fwin->titlebar) {
825 FREE_PIXMAP(fwin->title_back[state]);
826 if (wPreferences.new_style == TS_NEW) {
827 FREE_PIXMAP(fwin->lbutton_back[state]);
828 FREE_PIXMAP(fwin->rbutton_back[state]);
829 #ifdef XKB_BUTTON_HINT
830 FREE_PIXMAP(fwin->languagebutton_back[state]);
831 #endif
834 if (fwin->title_texture[state]->any.type != WTEX_SOLID) {
835 int left, right;
836 int width;
837 #ifdef XKB_BUTTON_HINT
838 int language;
839 #endif
841 /* eventually surrounded by if new_style */
842 left = fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit;
843 #ifdef XKB_BUTTON_HINT
844 language = fwin->language_button && !fwin->flags.hide_language_button
845 && !fwin->flags.languagebutton_dont_fit;
846 #endif
847 right = fwin->right_button && !fwin->flags.hide_right_button
848 && !fwin->flags.rbutton_dont_fit;
850 width = fwin->core->width + 1;
852 #ifdef XKB_BUTTON_HINT
853 renderTexture(fwin->screen_ptr, fwin->title_texture[state],
854 width, fwin->titlebar->height,
855 fwin->titlebar->height, fwin->titlebar->height,
856 left, language, right, &pmap, &lpmap, &tpmap, &rpmap);
857 #else
858 renderTexture(fwin->screen_ptr, fwin->title_texture[state],
859 width, fwin->titlebar->height,
860 fwin->titlebar->height, fwin->titlebar->height,
861 left, right, &pmap, &lpmap, &rpmap);
862 #endif
864 fwin->title_back[state] = pmap;
865 if (wPreferences.new_style == TS_NEW) {
866 fwin->lbutton_back[state] = lpmap;
867 fwin->rbutton_back[state] = rpmap;
868 #ifdef XKB_BUTTON_HINT
869 fwin->languagebutton_back[state] = tpmap;
870 #endif
874 if (fwin->resizebar_texture && fwin->resizebar_texture[0]
875 && fwin->resizebar && state == 0) {
877 FREE_PIXMAP(fwin->resizebar_back[0]);
879 if (fwin->resizebar_texture[0]->any.type != WTEX_SOLID) {
881 renderResizebarTexture(fwin->screen_ptr,
882 fwin->resizebar_texture[0],
883 fwin->resizebar->width,
884 fwin->resizebar->height, fwin->resizebar_corner_width, &pmap);
886 fwin->resizebar_back[0] = pmap;
889 /* this part should be in updateTexture() */
890 if (fwin->resizebar_texture[0]->any.type != WTEX_SOLID) {
891 XSetWindowBackgroundPixmap(dpy, fwin->resizebar->window, fwin->resizebar_back[0]);
892 } else {
893 XSetWindowBackground(dpy, fwin->resizebar->window,
894 fwin->resizebar_texture[0]->solid.normal.pixel);
896 XClearWindow(dpy, fwin->resizebar->window);
900 void wFrameWindowPaint(WFrameWindow * fwin)
902 WScreen *scr = fwin->screen_ptr;
903 int state;
905 state = fwin->flags.state;
907 if (fwin->flags.is_client_window_frame)
908 fwin->flags.justification = wPreferences.title_justification;
910 if (fwin->flags.need_texture_remake) {
911 int i;
913 fwin->flags.need_texture_remake = 0;
914 fwin->flags.need_texture_change = 0;
916 if (fwin->flags.single_texture) {
917 remakeTexture(fwin, 0);
918 updateTexture(fwin);
919 } else {
920 /* first render the texture for the current state... */
921 remakeTexture(fwin, state);
922 /* ... and paint it */
923 updateTexture(fwin);
925 for (i = 0; i < 3; i++) {
926 if (i != state) {
927 remakeTexture(fwin, i);
933 if (fwin->flags.need_texture_change) {
934 fwin->flags.need_texture_change = 0;
936 updateTexture(fwin);
939 if (fwin->titlebar && !fwin->flags.repaint_only_resizebar
940 && fwin->title_texture[state]->any.type == WTEX_SOLID) {
941 wDrawBevel(fwin->titlebar->window, fwin->titlebar->width,
942 fwin->titlebar->height, (WTexSolid *) fwin->title_texture[state], WREL_RAISED);
945 if (fwin->resizebar && !fwin->flags.repaint_only_titlebar
946 && fwin->resizebar_texture[0]->any.type == WTEX_SOLID) {
947 Window win;
948 int w, h;
949 int cw;
950 GC light_gc, dim_gc;
951 WTexSolid *texture = (WTexSolid *) fwin->resizebar_texture[0];
953 w = fwin->resizebar->width;
954 h = fwin->resizebar->height;
955 cw = fwin->resizebar_corner_width;
956 light_gc = texture->light_gc;
957 dim_gc = texture->dim_gc;
958 win = fwin->resizebar->window;
960 XDrawLine(dpy, win, dim_gc, 0, 0, w, 0);
961 XDrawLine(dpy, win, light_gc, 0, 1, w, 1);
963 XDrawLine(dpy, win, dim_gc, cw, 2, cw, h);
964 XDrawLine(dpy, win, light_gc, cw + 1, 2, cw + 1, h);
966 XDrawLine(dpy, win, dim_gc, w - cw - 2, 2, w - cw - 2, h);
967 XDrawLine(dpy, win, light_gc, w - cw - 1, 2, w - cw - 1, h);
969 #ifdef SHADOW_RESIZEBAR
970 XDrawLine(dpy, win, light_gc, 0, 1, 0, h - 1);
971 XDrawLine(dpy, win, dim_gc, w - 1, 2, w - 1, h - 1);
972 XDrawLine(dpy, win, dim_gc, 1, h - 1, cw, h - 1);
973 XDrawLine(dpy, win, dim_gc, cw + 2, h - 1, w - cw - 2, h - 1);
974 XDrawLine(dpy, win, dim_gc, w - cw, h - 1, w - 1, h - 1);
975 #endif /* SHADOW_RESIZEBAR */
978 if (fwin->titlebar && !fwin->flags.repaint_only_resizebar) {
979 int x, y, w, h;
980 int lofs = 6, rofs = 6;
981 int titlelen;
982 int allButtons = 1;
984 if (!wPreferences.new_style == TS_NEW) {
985 if (fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit)
986 lofs += fwin->left_button->width + 3;
987 else
988 allButtons = 0;
990 #ifdef XKB_BUTTON_HINT
991 if (fwin->language_button && !fwin->flags.hide_language_button
992 && !fwin->flags.languagebutton_dont_fit)
993 lofs += fwin->language_button->width;
994 else
995 allButtons = 0;
996 #endif
998 if (fwin->right_button && !fwin->flags.hide_right_button && !fwin->flags.rbutton_dont_fit)
999 rofs += fwin->right_button->width + 3;
1000 else
1001 allButtons = 0;
1003 #ifdef XKB_BUTTON_HINT
1004 fwin->languagebutton_image = scr->b_pixmaps[WBUT_XKBGROUP1 + fwin->languagemode];
1005 #endif
1007 if (fwin->title) {
1008 Drawable buf;
1009 char *title;
1011 title = ShrinkString(*fwin->font, fwin->title, fwin->titlebar->width - lofs - rofs);
1012 titlelen = strlen(title);
1013 w = WMWidthOfString(*fwin->font, title, titlelen);
1015 switch (fwin->flags.justification) {
1016 case WTJ_LEFT:
1017 x = lofs;
1018 break;
1020 case WTJ_RIGHT:
1021 x = fwin->titlebar->width - w - rofs;
1022 break;
1024 default:
1025 if (!allButtons)
1026 x = lofs + (fwin->titlebar->width - w - lofs - rofs) / 2;
1027 else
1028 x = (fwin->titlebar->width - w) / 2;
1029 break;
1032 y = *fwin->title_clearance + TITLEBAR_EXTEND_SPACE;
1033 h = WMFontHeight(*fwin->font);
1035 if (y*2 + h > *fwin->title_max_height)
1036 y = (*fwin->title_max_height - h) / 2;
1038 if (y*2 + h < *fwin->title_min_height)
1039 y = (*fwin->title_min_height - h) / 2;
1041 /* We use a w+2 buffer to have an extra pixel on the left and
1042 * another one on the right. This is because for some odd reason,
1043 * sometimes when using AA fonts (when libfreetype2 is compiled
1044 * with bytecode interpreter turned off), some fonts are drawn
1045 * starting from x = -1 not from 0 as requested. Observed with
1046 * capital A letter on the bold 'trebuchet ms' font. -Dan
1048 buf = XCreatePixmap(dpy, fwin->titlebar->window, w + 2, h, scr->w_depth);
1050 XSetClipMask(dpy, scr->copy_gc, None);
1052 if (fwin->title_texture[state]->any.type != WTEX_SOLID) {
1053 XCopyArea(dpy, fwin->title_back[state], buf, scr->copy_gc,
1054 x - 1, y, w + 2, h, 0, 0);
1055 } else {
1056 XSetForeground(dpy, scr->copy_gc, fwin->title_texture[state]->solid.normal.pixel);
1057 XFillRectangle(dpy, buf, scr->copy_gc, 0, 0, w + 2, h);
1060 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1061 WMDrawString(scr->wmscreen, buf, fwin->title_color[state],
1062 *fwin->font, 1, 0, title, titlelen);
1064 XCopyArea(dpy, buf, fwin->titlebar->window, scr->copy_gc, 0, 0, w + 2, h, x - 1, y);
1066 XFreePixmap(dpy, buf);
1068 wfree(title);
1071 if (fwin->left_button)
1072 handleButtonExpose(&fwin->left_button->descriptor, NULL);
1073 if (fwin->right_button)
1074 handleButtonExpose(&fwin->right_button->descriptor, NULL);
1075 #ifdef XKB_BUTTON_HINT
1076 if (fwin->language_button)
1077 handleButtonExpose(&fwin->language_button->descriptor, NULL);
1078 #endif
1082 static void reconfigure(WFrameWindow * fwin, int x, int y, int width, int height, Bool dontMove)
1084 int k = (wPreferences.new_style == TS_NEW ? 4 : 3);
1085 int resizedHorizontally = 0;
1087 if (dontMove)
1088 XResizeWindow(dpy, fwin->core->window, width, height);
1089 else
1090 XMoveResizeWindow(dpy, fwin->core->window, x, y, width, height);
1093 if (fwin->core->height != height && fwin->resizebar)
1094 XMoveWindow(dpy, fwin->resizebar->window, 0,
1095 height - fwin->resizebar->height);
1097 if (fwin->core->width != width) {
1098 fwin->flags.need_texture_remake = 1;
1099 resizedHorizontally = 1;
1102 fwin->core->width = width;
1103 fwin->core->height = height;
1105 if (fwin->titlebar && resizedHorizontally) {
1106 /* Check if the titlebar is wide enough to hold the buttons.
1107 * Temporarily remove them if can't
1109 if (fwin->left_button) {
1110 if (width < fwin->top_width * k && !fwin->flags.lbutton_dont_fit) {
1112 if (!fwin->flags.hide_left_button) {
1113 XUnmapWindow(dpy, fwin->left_button->window);
1115 fwin->flags.lbutton_dont_fit = 1;
1116 } else if (width >= fwin->top_width * k && fwin->flags.lbutton_dont_fit) {
1118 if (!fwin->flags.hide_left_button) {
1119 XMapWindow(dpy, fwin->left_button->window);
1121 fwin->flags.lbutton_dont_fit = 0;
1124 #ifdef XKB_BUTTON_HINT
1125 if (fwin->language_button) {
1126 if (width < fwin->top_width * k && !fwin->flags.languagebutton_dont_fit) {
1128 if (!fwin->flags.hide_language_button) {
1129 XUnmapWindow(dpy, fwin->language_button->window);
1131 fwin->flags.languagebutton_dont_fit = 1;
1132 } else if (width >= fwin->top_width * k && fwin->flags.languagebutton_dont_fit) {
1134 if (!fwin->flags.hide_language_button) {
1135 XMapWindow(dpy, fwin->language_button->window);
1137 fwin->flags.languagebutton_dont_fit = 0;
1140 #endif
1142 if (fwin->right_button) {
1143 if (width < fwin->top_width * 2 && !fwin->flags.rbutton_dont_fit) {
1145 if (!fwin->flags.hide_right_button) {
1146 XUnmapWindow(dpy, fwin->right_button->window);
1148 fwin->flags.rbutton_dont_fit = 1;
1149 } else if (width >= fwin->top_width * 2 && fwin->flags.rbutton_dont_fit) {
1151 if (!fwin->flags.hide_right_button) {
1152 XMapWindow(dpy, fwin->right_button->window);
1154 fwin->flags.rbutton_dont_fit = 0;
1158 if (wPreferences.new_style == TS_NEW) {
1159 if (fwin->right_button)
1160 XMoveWindow(dpy, fwin->right_button->window,
1161 width - fwin->right_button->width + 1, 0);
1162 } else {
1163 if (fwin->right_button)
1164 XMoveWindow(dpy, fwin->right_button->window,
1165 width - fwin->right_button->width - 3,
1166 (fwin->titlebar->height - fwin->right_button->height) / 2);
1168 updateTitlebar(fwin);
1169 checkTitleSize(fwin);
1172 if (fwin->resizebar) {
1173 wCoreConfigure(fwin->resizebar, 0,
1174 fwin->core->height - fwin->resizebar->height,
1175 fwin->core->width, fwin->resizebar->height);
1177 fwin->resizebar_corner_width = RESIZEBAR_CORNER_WIDTH;
1178 if (fwin->core->width < RESIZEBAR_CORNER_WIDTH * 2 + RESIZEBAR_MIN_WIDTH) {
1179 fwin->resizebar_corner_width = fwin->core->width / 2;
1184 void wFrameWindowConfigure(WFrameWindow * fwin, int x, int y, int width, int height)
1186 reconfigure(fwin, x, y, width, height, False);
1189 void wFrameWindowResize(WFrameWindow * fwin, int width, int height)
1191 reconfigure(fwin, 0, 0, width, height, True);
1194 int wFrameWindowChangeTitle(WFrameWindow * fwin, char *new_title)
1196 /* check if the title is the same as before */
1197 if (fwin->title) {
1198 if (new_title && (strcmp(fwin->title, new_title) == 0)) {
1199 return 0;
1201 } else {
1202 if (!new_title)
1203 return 0;
1206 if (fwin->title)
1207 wfree(fwin->title);
1209 fwin->title = wstrdup(new_title);
1211 if (fwin->titlebar) {
1212 XClearWindow(dpy, fwin->titlebar->window);
1214 wFrameWindowPaint(fwin);
1216 checkTitleSize(fwin);
1218 return 1;
1221 #ifdef XKB_BUTTON_HINT
1222 void wFrameWindowUpdateLanguageButton(WFrameWindow * fwin)
1224 paintButton(fwin->language_button, fwin->title_texture[fwin->flags.state],
1225 WMColorPixel(fwin->title_color[fwin->flags.state]), fwin->languagebutton_image, True);
1227 #endif /* XKB_BUTTON_HINT */
1229 /*********************************************************************/
1231 static void handleExpose(WObjDescriptor * desc, XEvent * event)
1233 WFrameWindow *fwin = (WFrameWindow *) desc->parent;
1235 if (fwin->titlebar && fwin->titlebar->window == event->xexpose.window)
1236 fwin->flags.repaint_only_titlebar = 1;
1237 if (fwin->resizebar && fwin->resizebar->window == event->xexpose.window)
1238 fwin->flags.repaint_only_resizebar = 1;
1239 wFrameWindowPaint(fwin);
1240 fwin->flags.repaint_only_titlebar = 0;
1241 fwin->flags.repaint_only_resizebar = 0;
1244 static void checkTitleSize(WFrameWindow * fwin)
1246 int width;
1248 if (!fwin->title) {
1249 fwin->flags.incomplete_title = 0;
1250 return;
1253 if (!fwin->titlebar) {
1254 fwin->flags.incomplete_title = 1;
1255 return;
1256 } else {
1257 width = fwin->titlebar->width - 6 - 6;
1260 if (!wPreferences.new_style == TS_NEW) {
1261 if (fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit)
1262 width -= fwin->left_button->width + 3;
1264 #ifdef XKB_BUTTON_HINT
1265 if (fwin->language_button && !fwin->flags.hide_language_button
1266 && !fwin->flags.languagebutton_dont_fit)
1267 width -= fwin->language_button->width + 3;
1268 #endif
1270 if (fwin->right_button && !fwin->flags.hide_right_button && !fwin->flags.rbutton_dont_fit)
1271 width -= fwin->right_button->width + 3;
1273 if (WMWidthOfString(*fwin->font, fwin->title, strlen(fwin->title)) > width) {
1274 fwin->flags.incomplete_title = 1;
1275 } else {
1276 fwin->flags.incomplete_title = 0;
1280 static void paintButton(WCoreWindow * button, WTexture * texture, unsigned long color, WPixmap * image, int pushed)
1282 WScreen *scr = button->screen_ptr;
1283 GC copy_gc = scr->copy_gc;
1284 int x = 0, y = 0, d = 0;
1285 int left = 0, width = 0;
1287 /* setup stuff according to the state */
1288 if (pushed) {
1289 if (image) {
1290 if (image->width >= image->height * 2) {
1291 /* the image contains 2 pictures: the second is for the
1292 * pushed state */
1293 width = image->width / 2;
1294 left = image->width / 2;
1295 } else {
1296 width = image->width;
1299 XSetClipMask(dpy, copy_gc, None);
1300 if (wPreferences.new_style == TS_NEXT) {
1301 XSetForeground(dpy, copy_gc, scr->black_pixel);
1302 } else {
1303 XSetForeground(dpy, copy_gc, scr->white_pixel);
1305 d = 1;
1306 if (wPreferences.new_style == TS_NEW) {
1307 XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width - 1, button->height - 1);
1308 XSetForeground(dpy, copy_gc, scr->black_pixel);
1309 XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width - 1, button->height - 1);
1310 } else if (wPreferences.new_style == TS_OLD) {
1311 XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height);
1312 XSetForeground(dpy, copy_gc, scr->black_pixel);
1313 XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height);
1314 } else {
1315 XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width-3, button->height-3);
1316 XSetForeground(dpy, copy_gc, scr->black_pixel);
1317 XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width-3, button->height-3);
1319 } else {
1320 XClearWindow(dpy, button->window);
1322 if (image) {
1323 if (image->width >= image->height * 2)
1324 width = image->width / 2;
1325 else
1326 width = image->width;
1328 d = 0;
1330 if (wPreferences.new_style == TS_NEW) {
1331 if (texture->any.type == WTEX_SOLID || pushed) {
1332 wDrawBevel(button->window, button->width, button->height,
1333 (WTexSolid *) texture, WREL_RAISED);
1335 } else {
1336 wDrawBevel(button->window, button->width, button->height,
1337 scr->widget_texture, WREL_RAISED);
1341 if (image) {
1342 /* display image */
1343 XSetClipMask(dpy, copy_gc, image->mask);
1344 x = (button->width - width) / 2 + d;
1345 y = (button->height - image->height) / 2 + d;
1346 XSetClipOrigin(dpy, copy_gc, x - left, y);
1347 if (!wPreferences.new_style == TS_NEW) {
1348 XSetForeground(dpy, copy_gc, scr->black_pixel);
1349 if (!pushed) {
1350 if (image->depth == 1)
1351 XCopyPlane(dpy, image->image, button->window, copy_gc,
1352 left, 0, width, image->height, x, y, 1);
1353 else
1354 XCopyArea(dpy, image->image, button->window, copy_gc,
1355 left, 0, width, image->height, x, y);
1356 } else {
1357 if (wPreferences.new_style == TS_OLD) {
1358 XSetForeground(dpy, copy_gc, scr->dark_pixel);
1359 XFillRectangle(dpy, button->window, copy_gc, 0, 0,
1360 button->width, button->height);
1361 } else {
1362 XSetForeground(dpy, copy_gc, scr->black_pixel);
1363 XCopyArea(dpy, image->image, button->window, copy_gc,
1364 left, 0, width, image->height, x, y);
1367 } else {
1368 if (pushed) {
1369 XSetForeground(dpy, copy_gc, scr->black_pixel);
1370 } else {
1371 XSetForeground(dpy, copy_gc, color);
1372 XSetBackground(dpy, copy_gc, texture->any.color.pixel);
1374 XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height);
1379 static void handleButtonExpose(WObjDescriptor * desc, XEvent * event)
1381 WFrameWindow *fwin = (WFrameWindow *) desc->parent;
1382 WCoreWindow *button = (WCoreWindow *) desc->self;
1384 #ifdef XKB_BUTTON_HINT
1385 if (button == fwin->language_button) {
1386 if (wPreferences.modelock) {
1387 paintButton(button, fwin->title_texture[fwin->flags.state],
1388 WMColorPixel(fwin->title_color[fwin->flags.state]),
1389 fwin->languagebutton_image, False);
1391 } else
1392 #endif
1393 if (button == fwin->left_button) {
1394 paintButton(button, fwin->title_texture[fwin->flags.state],
1395 WMColorPixel(fwin->title_color[fwin->flags.state]), fwin->lbutton_image, False);
1396 } else {
1397 paintButton(button, fwin->title_texture[fwin->flags.state],
1398 WMColorPixel(fwin->title_color[fwin->flags.state]), fwin->rbutton_image, False);
1402 static void titlebarMouseDown(WObjDescriptor * desc, XEvent * event)
1404 WFrameWindow *fwin = desc->parent;
1405 WCoreWindow *titlebar = desc->self;
1407 if (IsDoubleClick(fwin->core->screen_ptr, event)) {
1408 if (fwin->on_dblclick_titlebar) {
1409 (*fwin->on_dblclick_titlebar) (titlebar, fwin->child, event);
1411 } else {
1412 if (fwin->on_mousedown_titlebar) {
1413 (*fwin->on_mousedown_titlebar) (titlebar, fwin->child, event);
1418 static void resizebarMouseDown(WObjDescriptor * desc, XEvent * event)
1420 WFrameWindow *fwin = desc->parent;
1421 WCoreWindow *resizebar = desc->self;
1423 if (fwin->on_mousedown_resizebar)
1424 (*fwin->on_mousedown_resizebar) (resizebar, fwin->child, event);
1427 static void buttonMouseDown(WObjDescriptor * desc, XEvent * event)
1429 WFrameWindow *fwin = desc->parent;
1430 WCoreWindow *button = desc->self;
1431 WPixmap *image;
1432 XEvent ev;
1433 int done = 0, execute = 1;
1434 WTexture *texture;
1435 unsigned long pixel;
1436 int clickButton = event->xbutton.button;
1438 if (IsDoubleClick(fwin->core->screen_ptr, event)) {
1439 if (button == fwin->right_button && fwin->on_dblclick_right) {
1440 (*fwin->on_dblclick_right) (button, fwin->child, event);
1442 return;
1445 if (button == fwin->left_button) {
1446 image = fwin->lbutton_image;
1447 } else {
1448 image = fwin->rbutton_image;
1450 #ifdef XKB_BUTTON_HINT
1451 if (button == fwin->language_button) {
1452 if (!wPreferences.modelock)
1453 return;
1454 image = fwin->languagebutton_image;
1456 #endif
1458 pixel = WMColorPixel(fwin->title_color[fwin->flags.state]);
1459 texture = fwin->title_texture[fwin->flags.state];
1460 paintButton(button, texture, pixel, image, True);
1462 while (!done) {
1463 WMMaskEvent(dpy, LeaveWindowMask | EnterWindowMask | ButtonReleaseMask
1464 | ButtonPressMask | ExposureMask, &ev);
1465 switch (ev.type) {
1466 case LeaveNotify:
1467 execute = 0;
1468 paintButton(button, texture, pixel, image, False);
1469 break;
1471 case EnterNotify:
1472 execute = 1;
1473 paintButton(button, texture, pixel, image, True);
1474 break;
1476 case ButtonPress:
1477 break;
1479 case ButtonRelease:
1480 if (ev.xbutton.button == clickButton)
1481 done = 1;
1482 break;
1484 default:
1485 WMHandleEvent(&ev);
1488 paintButton(button, texture, pixel, image, False);
1490 if (execute) {
1491 if (button == fwin->left_button) {
1492 if (fwin->on_click_left)
1493 (*fwin->on_click_left) (button, fwin->child, &ev);
1494 } else if (button == fwin->right_button) {
1495 if (fwin->on_click_right)
1496 (*fwin->on_click_right) (button, fwin->child, &ev);
1498 #ifdef XKB_BUTTON_HINT
1499 else if (button == fwin->language_button) {
1500 if (fwin->on_click_language)
1501 (*fwin->on_click_language) (button, fwin->child, &ev);
1503 #endif