Fix enable-modelock warnings
[wmaker-crm.git] / src / framewin.c
blob5d3ec49cd0c2e73b74ff2da62ac036c73de53f45
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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * USA.
22 #include "wconfig.h"
24 #include <X11/Xlib.h>
25 #include <X11/Xutil.h>
26 #ifdef KEEP_XKB_LOCK_STATUS
27 #include <X11/XKBlib.h>
28 #endif /* KEEP_XKB_LOCK_STATUS */
30 #include <stdlib.h>
31 #include <string.h>
33 #include <wraster.h>
35 #include "WindowMaker.h"
36 #include "GNUstep.h"
37 #include "texture.h"
38 #include "screen.h"
39 #include "wcore.h"
40 #include "framewin.h"
41 #include "stacking.h"
42 #include "funcs.h"
44 #define DBLCLICK_TIME wPreferences.dblclick_time
46 extern WPreferences wPreferences;
48 static void handleExpose(WObjDescriptor * desc, XEvent * event);
49 static void handleButtonExpose(WObjDescriptor * desc, XEvent * event);
51 static void buttonMouseDown(WObjDescriptor * desc, XEvent * event);
52 static void titlebarMouseDown(WObjDescriptor * desc, XEvent * event);
53 static void resizebarMouseDown(WObjDescriptor * desc, XEvent * event);
55 static void checkTitleSize(WFrameWindow * fwin);
57 static void paintButton(WCoreWindow * button, WTexture * texture,
58 unsigned long color, WPixmap * image, int pushed);
60 static void updateTitlebar(WFrameWindow * fwin);
62 WFrameWindow *wFrameWindowCreate(WScreen * scr, int wlevel, int x, int y,
63 int width, int height, int *clearance, int flags,
64 WTexture ** title_texture, WTexture ** resize_texture,
65 WMColor ** color, WMFont ** font)
67 WFrameWindow *fwin;
69 fwin = wmalloc(sizeof(WFrameWindow));
70 memset(fwin, 0, sizeof(WFrameWindow));
72 fwin->screen_ptr = scr;
74 fwin->flags.single_texture = (flags & WFF_SINGLE_STATE) ? 1 : 0;
76 fwin->title_texture = title_texture;
77 fwin->resizebar_texture = resize_texture;
78 fwin->title_color = color;
79 fwin->title_clearance = clearance;
80 fwin->font = font;
81 #ifdef KEEP_XKB_LOCK_STATUS
82 fwin->languagemode = XkbGroup1Index;
83 fwin->last_languagemode = XkbGroup2Index;
84 #endif
86 fwin->core = wCoreCreateTopLevel(scr, x, y, width, height, (flags & WFF_BORDER)
87 ? FRAME_BORDER_WIDTH : 0);
88 if (wPreferences.use_saveunders) {
89 unsigned long vmask;
90 XSetWindowAttributes attribs;
92 vmask = CWSaveUnder;
93 attribs.save_under = True;
94 XChangeWindowAttributes(dpy, fwin->core->window, vmask, &attribs);
97 /* setup stacking information */
98 fwin->core->stacking = wmalloc(sizeof(WStacking));
99 fwin->core->stacking->above = NULL;
100 fwin->core->stacking->under = NULL;
101 fwin->core->stacking->child_of = NULL;
102 fwin->core->stacking->window_level = wlevel;
104 AddToStackList(fwin->core);
106 wFrameWindowUpdateBorders(fwin, flags);
108 return fwin;
111 void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags)
113 int theight;
114 int bsize;
115 int width, height;
116 int i;
117 WScreen *scr = fwin->screen_ptr;
119 width = fwin->core->width;
120 if (flags & WFF_IS_SHADED)
121 height = -1;
122 else
123 height = fwin->core->height - fwin->top_width - fwin->bottom_width;
125 if (flags & WFF_TITLEBAR)
126 theight = WMFontHeight(*fwin->font) + (*fwin->title_clearance + TITLEBAR_EXTEND_SPACE) * 2;
127 else
128 theight = 0;
130 if (wPreferences.new_style) {
131 bsize = theight;
132 } else {
133 bsize = theight - 7;
136 if (fwin->titlebar) {
137 /* if we had a titlebar and is requesting for one,
138 * check if the size has changed and resize it */
139 if (flags & WFF_TITLEBAR) {
140 fwin->top_width = theight;
142 fwin->flags.need_texture_remake = 1;
144 if (wPreferences.new_style) {
145 if (fwin->left_button) {
146 wCoreConfigure(fwin->left_button, 0, 0, bsize, bsize);
148 #ifdef XKB_BUTTON_HINT
149 if (fwin->language_button) {
150 if (fwin->flags.hide_left_button || !fwin->left_button
151 || fwin->flags.lbutton_dont_fit) {
152 wCoreConfigure(fwin->language_button, 0, 0, bsize, bsize);
153 } else {
154 wCoreConfigure(fwin->language_button, bsize, 0, bsize, bsize);
157 #endif
159 if (fwin->right_button) {
160 wCoreConfigure(fwin->right_button, width - bsize + 1, 0, bsize, bsize);
162 } else { /* !new_style */
163 if (fwin->left_button) {
164 wCoreConfigure(fwin->left_button, 3, (theight - bsize) / 2, bsize, bsize);
166 #ifdef XKB_BUTTON_HINT
167 if (fwin->language_button) {
168 wCoreConfigure(fwin->language_button, 6 + bsize, (theight - bsize) / 2,
169 bsize, bsize);
171 #endif
173 if (fwin->right_button) {
174 wCoreConfigure(fwin->right_button, width - bsize - 3,
175 (theight - bsize) / 2, bsize, bsize);
178 updateTitlebar(fwin);
179 } else {
180 /* we had a titlebar, but now we don't need it anymore */
181 for (i = 0; i < (fwin->flags.single_texture ? 1 : 3); i++) {
182 FREE_PIXMAP(fwin->title_back[i]);
183 if (wPreferences.new_style) {
184 FREE_PIXMAP(fwin->lbutton_back[i]);
185 FREE_PIXMAP(fwin->rbutton_back[i]);
186 #ifdef XKB_BUTTON_HINT
187 FREE_PIXMAP(fwin->languagebutton_back[i]);
188 #endif
191 if (fwin->left_button)
192 wCoreDestroy(fwin->left_button);
193 fwin->left_button = NULL;
195 #ifdef XKB_BUTTON_HINT
196 if (fwin->language_button)
197 wCoreDestroy(fwin->language_button);
198 fwin->language_button = NULL;
199 #endif
201 if (fwin->right_button)
202 wCoreDestroy(fwin->right_button);
203 fwin->right_button = NULL;
205 wCoreDestroy(fwin->titlebar);
206 fwin->titlebar = NULL;
208 fwin->top_width = 0;
210 } else {
211 /* if we didn't have a titlebar and are being requested for
212 * one, create it */
213 if (flags & WFF_TITLEBAR) {
214 fwin->top_width = theight;
216 fwin->flags.titlebar = 1;
217 fwin->titlebar = wCoreCreate(fwin->core, 0, 0, width + 1, theight);
219 if (flags & WFF_LEFT_BUTTON) {
220 fwin->flags.left_button = 1;
221 if (wPreferences.new_style) {
222 fwin->left_button = wCoreCreate(fwin->core, 0, 0, bsize, bsize);
223 if (width < theight * 4) {
224 fwin->flags.lbutton_dont_fit = 1;
225 } else {
226 XMapRaised(dpy, fwin->left_button->window);
228 } else {
229 fwin->left_button =
230 wCoreCreate(fwin->titlebar, 3, (theight - bsize) / 2, bsize, bsize);
232 XSetWindowBackground(dpy, fwin->left_button->window,
233 scr->widget_texture->normal.pixel);
235 if (width < theight * 3) {
236 fwin->flags.lbutton_dont_fit = 1;
237 } else {
238 XMapRaised(dpy, fwin->left_button->window);
242 #ifdef XKB_BUTTON_HINT
243 if (flags & WFF_LANGUAGE_BUTTON) {
244 fwin->flags.language_button = 1;
245 if (wPreferences.new_style) {
246 fwin->language_button = wCoreCreate(fwin->core, bsize, 0, bsize, bsize);
248 if (width < theight * 4) {
249 fwin->flags.languagebutton_dont_fit = 1;
250 } else {
251 XMapRaised(dpy, fwin->language_button->window);
253 } else {
254 fwin->language_button =
255 wCoreCreate(fwin->titlebar, bsize + 6, (theight - bsize) / 2,
256 bsize, bsize);
258 XSetWindowBackground(dpy, fwin->language_button->window,
259 scr->widget_texture->normal.pixel);
261 if (width < theight * 3) {
262 fwin->flags.languagebutton_dont_fit = 1;
263 } else {
264 XMapRaised(dpy, fwin->language_button->window);
268 #endif
270 if (flags & WFF_RIGHT_BUTTON) {
271 fwin->flags.right_button = 1;
272 if (wPreferences.new_style) {
273 fwin->right_button =
274 wCoreCreate(fwin->core, width - bsize + 1, 0, bsize, bsize);
275 } else {
276 fwin->right_button =
277 wCoreCreate(fwin->titlebar, width - bsize - 3,
278 (theight - bsize) / 2, bsize, bsize);
279 XSetWindowBackground(dpy, fwin->right_button->window,
280 scr->widget_texture->normal.pixel);
283 if (width < theight * 2) {
284 fwin->flags.rbutton_dont_fit = 1;
285 } else {
286 XMapRaised(dpy, fwin->right_button->window);
290 if (wPreferences.new_style)
291 updateTitlebar(fwin);
293 XMapRaised(dpy, fwin->titlebar->window);
295 fwin->flags.need_texture_remake = 1;
298 checkTitleSize(fwin);
300 if (flags & WFF_RESIZEBAR) {
301 fwin->bottom_width = RESIZEBAR_HEIGHT;
303 if (!fwin->resizebar) {
304 fwin->flags.resizebar = 1;
305 fwin->resizebar = wCoreCreate(fwin->core, 0,
306 height + fwin->top_width, width, RESIZEBAR_HEIGHT);
307 fwin->resizebar_corner_width = RESIZEBAR_CORNER_WIDTH;
308 if (width < RESIZEBAR_CORNER_WIDTH * 2 + RESIZEBAR_MIN_WIDTH) {
309 fwin->resizebar_corner_width = (width - RESIZEBAR_MIN_WIDTH) / 2;
310 if (fwin->resizebar_corner_width < 0)
311 fwin->resizebar_corner_width = 0;
314 XMapWindow(dpy, fwin->resizebar->window);
315 XLowerWindow(dpy, fwin->resizebar->window);
317 fwin->flags.need_texture_remake = 1;
318 } else {
319 if (height + fwin->top_width + fwin->bottom_width != fwin->core->height) {
320 wCoreConfigure(fwin->resizebar, 0, height + fwin->top_width,
321 width, RESIZEBAR_HEIGHT);
324 } else {
325 fwin->bottom_width = 0;
327 if (fwin->resizebar) {
328 fwin->bottom_width = 0;
329 wCoreDestroy(fwin->resizebar);
330 fwin->resizebar = NULL;
334 if (height + fwin->top_width + fwin->bottom_width != fwin->core->height && !(flags & WFF_IS_SHADED)) {
335 wFrameWindowResize(fwin, width, height + fwin->top_width + fwin->bottom_width);
338 if (flags & WFF_BORDER) {
339 XSetWindowBorderWidth(dpy, fwin->core->window, FRAME_BORDER_WIDTH);
340 } else {
341 XSetWindowBorderWidth(dpy, fwin->core->window, 0);
344 /* setup object descriptors */
346 if (fwin->titlebar) {
347 fwin->titlebar->descriptor.handle_expose = handleExpose;
348 fwin->titlebar->descriptor.parent = fwin;
349 fwin->titlebar->descriptor.parent_type = WCLASS_FRAME;
350 fwin->titlebar->descriptor.handle_mousedown = titlebarMouseDown;
353 if (fwin->resizebar) {
354 fwin->resizebar->descriptor.handle_expose = handleExpose;
355 fwin->resizebar->descriptor.parent = fwin;
356 fwin->resizebar->descriptor.parent_type = WCLASS_FRAME;
357 fwin->resizebar->descriptor.handle_mousedown = resizebarMouseDown;
360 if (fwin->left_button) {
361 fwin->left_button->descriptor.handle_expose = handleButtonExpose;
362 fwin->left_button->descriptor.parent = fwin;
363 fwin->left_button->descriptor.parent_type = WCLASS_FRAME;
364 fwin->left_button->descriptor.handle_mousedown = buttonMouseDown;
366 #ifdef XKB_BUTTON_HINT
367 if (fwin->language_button) {
368 fwin->language_button->descriptor.handle_expose = handleButtonExpose;
369 fwin->language_button->descriptor.parent = fwin;
370 fwin->language_button->descriptor.parent_type = WCLASS_FRAME;
371 fwin->language_button->descriptor.handle_mousedown = buttonMouseDown;
373 #endif
375 if (fwin->right_button) {
376 fwin->right_button->descriptor.parent = fwin;
377 fwin->right_button->descriptor.parent_type = WCLASS_FRAME;
378 fwin->right_button->descriptor.handle_expose = handleButtonExpose;
379 fwin->right_button->descriptor.handle_mousedown = buttonMouseDown;
382 checkTitleSize(fwin);
385 void wFrameWindowDestroy(WFrameWindow * fwin)
387 int i;
389 if (fwin->left_button)
390 wCoreDestroy(fwin->left_button);
392 #ifdef XKB_BUTTON_HINT
393 if (fwin->language_button)
394 wCoreDestroy(fwin->language_button);
395 #endif
397 if (fwin->right_button)
398 wCoreDestroy(fwin->right_button);
400 if (fwin->resizebar)
401 wCoreDestroy(fwin->resizebar);
403 if (fwin->titlebar)
404 wCoreDestroy(fwin->titlebar);
406 RemoveFromStackList(fwin->core);
408 wCoreDestroy(fwin->core);
410 if (fwin->title)
411 wfree(fwin->title);
413 for (i = 0; i < (fwin->flags.single_texture ? 1 : 3); i++) {
414 FREE_PIXMAP(fwin->title_back[i]);
415 if (wPreferences.new_style) {
416 FREE_PIXMAP(fwin->lbutton_back[i]);
417 #ifdef XKB_BUTTON_HINT
418 FREE_PIXMAP(fwin->languagebutton_back[i]);
419 #endif
420 FREE_PIXMAP(fwin->rbutton_back[i]);
424 wfree(fwin);
427 void wFrameWindowChangeState(WFrameWindow * fwin, int state)
429 if (fwin->flags.state == state)
430 return;
432 fwin->flags.state = state;
433 fwin->flags.need_texture_change = 1;
435 wFrameWindowPaint(fwin);
438 static void updateTitlebar(WFrameWindow * fwin)
440 int x, w;
441 int theight;
443 theight = WMFontHeight(*fwin->font) + (*fwin->title_clearance + TITLEBAR_EXTEND_SPACE) * 2;
445 x = 0;
446 w = fwin->core->width + 1;
448 if (wPreferences.new_style) {
449 if (fwin->flags.hide_left_button || !fwin->left_button || fwin->flags.lbutton_dont_fit) {
450 x = 0;
451 #ifdef XKB_BUTTON_HINT
452 if (fwin->language_button)
453 wCoreConfigure(fwin->language_button, 0, 0,
454 fwin->language_button->width, fwin->language_button->width);
455 #endif
456 } else {
457 #ifdef XKB_BUTTON_HINT
458 if (fwin->language_button)
459 wCoreConfigure(fwin->language_button, fwin->left_button->width, 0,
460 fwin->language_button->width, fwin->language_button->width);
461 #endif
462 x = fwin->left_button->width;
463 w -= fwin->left_button->width;
465 #ifdef XKB_BUTTON_HINT
466 if (fwin->flags.hide_language_button || !fwin->language_button
467 || fwin->flags.languagebutton_dont_fit) {
468 } else {
469 x += fwin->language_button->width;
470 w -= fwin->language_button->width;
472 #endif
474 #ifdef XKB_BUTTON_HINT
475 else {
476 int bsize = theight - 7;
477 if (fwin->flags.hide_left_button || !fwin->left_button || fwin->flags.lbutton_dont_fit) {
478 if (fwin->language_button)
479 wCoreConfigure(fwin->language_button, 3, (theight - bsize) / 2,
480 fwin->language_button->width, fwin->language_button->width);
481 } else {
482 if (fwin->language_button)
483 wCoreConfigure(fwin->language_button,
484 6 + fwin->left_button->width, (theight - bsize) / 2,
485 fwin->language_button->width, fwin->language_button->width);
488 #endif
490 if (wPreferences.new_style) {
491 if (!fwin->flags.hide_right_button && fwin->right_button && !fwin->flags.rbutton_dont_fit) {
492 w -= fwin->right_button->width;
496 if (wPreferences.new_style || fwin->titlebar->width != w)
497 fwin->flags.need_texture_remake = 1;
499 wCoreConfigure(fwin->titlebar, x, 0, w, theight);
502 void wFrameWindowHideButton(WFrameWindow * fwin, int flags)
504 if ((flags & WFF_RIGHT_BUTTON) && fwin->right_button) {
505 XUnmapWindow(dpy, fwin->right_button->window);
506 fwin->flags.hide_right_button = 1;
509 if ((flags & WFF_LEFT_BUTTON) && fwin->left_button) {
510 XUnmapWindow(dpy, fwin->left_button->window);
511 fwin->flags.hide_left_button = 1;
513 #ifdef XKB_BUTTON_HINT
514 if ((flags & WFF_LANGUAGE_BUTTON) && fwin->language_button) {
515 XUnmapWindow(dpy, fwin->language_button->window);
516 fwin->flags.hide_language_button = 1;
518 #endif
520 if (fwin->titlebar) {
521 if (wPreferences.new_style) {
522 updateTitlebar(fwin);
523 } else {
524 #ifdef XKB_BUTTON_HINT
525 updateTitlebar(fwin);
526 #else
527 XClearWindow(dpy, fwin->titlebar->window);
528 wFrameWindowPaint(fwin);
529 #endif
531 checkTitleSize(fwin);
535 void wFrameWindowShowButton(WFrameWindow * fwin, int flags)
537 if ((flags & WFF_RIGHT_BUTTON) && fwin->right_button && fwin->flags.hide_right_button) {
539 if (!fwin->flags.rbutton_dont_fit)
540 XMapWindow(dpy, fwin->right_button->window);
542 fwin->flags.hide_right_button = 0;
544 #ifdef XKB_BUTTON_HINT
545 if ((flags & WFF_LANGUAGE_BUTTON) && fwin->language_button && fwin->flags.hide_language_button) {
547 if (!fwin->flags.languagebutton_dont_fit)
548 XMapWindow(dpy, fwin->language_button->window);
550 fwin->flags.hide_language_button = 0;
552 #endif
554 if ((flags & WFF_LEFT_BUTTON) && fwin->left_button && fwin->flags.hide_left_button) {
556 if (!fwin->flags.lbutton_dont_fit)
557 XMapWindow(dpy, fwin->left_button->window);
559 fwin->flags.hide_left_button = 0;
562 if (fwin->titlebar) {
563 if (wPreferences.new_style) {
564 updateTitlebar(fwin);
565 } else {
566 XClearWindow(dpy, fwin->titlebar->window);
567 wFrameWindowPaint(fwin);
569 checkTitleSize(fwin);
573 static void
574 #ifdef XKB_BUTTON_HINT
575 renderTexture(WScreen * scr, WTexture * texture, int width, int height,
576 int bwidth, int bheight, int left, int language, int right,
577 Pixmap * title, Pixmap * lbutton, Pixmap * languagebutton, Pixmap * rbutton)
578 #else
579 renderTexture(WScreen * scr, WTexture * texture, int width, int height,
580 int bwidth, int bheight, int left, int right, Pixmap * title, Pixmap * lbutton, Pixmap * rbutton)
581 #endif
583 RImage *img;
584 RImage *limg, *rimg, *mimg;
585 #ifdef XKB_BUTTON_HINT
586 RImage *timg;
587 #endif
588 int x, w;
590 *title = None;
591 *lbutton = None;
592 *rbutton = None;
593 #ifdef XKB_BUTTON_HINT
594 *languagebutton = None;
595 #endif
597 img = wTextureRenderImage(texture, width, height, WREL_FLAT);
598 if (!img) {
599 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode));
600 return;
603 if (wPreferences.new_style) {
604 if (left) {
605 limg = RGetSubImage(img, 0, 0, bwidth, bheight);
606 } else
607 limg = NULL;
609 x = 0;
610 w = img->width;
612 #ifdef XKB_BUTTON_HINT
613 if (language) {
614 timg = RGetSubImage(img, bwidth * left, 0, bwidth, bheight);
615 } else
616 timg = NULL;
617 #endif
619 if (limg) {
620 RBevelImage(limg, RBEV_RAISED2);
621 if (!RConvertImage(scr->rcontext, limg, lbutton)) {
622 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
624 x += limg->width;
625 w -= limg->width;
626 RReleaseImage(limg);
628 #ifdef XKB_BUTTON_HINT
629 if (timg) {
630 RBevelImage(timg, RBEV_RAISED2);
631 if (!RConvertImage(scr->rcontext, timg, languagebutton)) {
632 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
634 x += timg->width;
635 w -= timg->width;
636 RReleaseImage(timg);
638 #endif
640 if (right) {
641 rimg = RGetSubImage(img, width - bwidth, 0, bwidth, bheight);
642 } else
643 rimg = NULL;
645 if (rimg) {
646 RBevelImage(rimg, RBEV_RAISED2);
647 if (!RConvertImage(scr->rcontext, rimg, rbutton)) {
648 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
650 w -= rimg->width;
651 RReleaseImage(rimg);
654 if (w != width) {
655 mimg = RGetSubImage(img, x, 0, w, img->height);
656 RBevelImage(mimg, RBEV_RAISED2);
658 if (!RConvertImage(scr->rcontext, mimg, title)) {
659 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
661 RReleaseImage(mimg);
662 } else {
663 RBevelImage(img, RBEV_RAISED2);
665 if (!RConvertImage(scr->rcontext, img, title)) {
666 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
669 } else {
670 RBevelImage(img, RBEV_RAISED2);
672 if (!RConvertImage(scr->rcontext, img, title)) {
673 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode));
677 RReleaseImage(img);
680 static void
681 renderResizebarTexture(WScreen * scr, WTexture * texture, int width, int height, int cwidth, Pixmap * pmap)
683 RImage *img;
684 RColor light;
685 RColor dark;
687 *pmap = None;
689 img = wTextureRenderImage(texture, width, height, WREL_FLAT);
690 if (!img) {
691 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode));
692 return;
695 light.alpha = 0;
696 light.red = light.green = light.blue = 80;
698 dark.alpha = 0;
699 dark.red = dark.green = dark.blue = 40;
701 ROperateLine(img, RSubtractOperation, 0, 0, width - 1, 0, &dark);
702 ROperateLine(img, RAddOperation, 0, 1, width - 1, 1, &light);
704 ROperateLine(img, RSubtractOperation, cwidth, 2, cwidth, height - 1, &dark);
705 ROperateLine(img, RAddOperation, cwidth + 1, 2, cwidth + 1, height - 1, &light);
707 if (width > 1)
708 ROperateLine(img, RSubtractOperation, width - cwidth - 2, 2,
709 width - cwidth - 2, height - 1, &dark);
710 ROperateLine(img, RAddOperation, width - cwidth - 1, 2, width - cwidth - 1, height - 1, &light);
712 #ifdef SHADOW_RESIZEBAR
713 ROperateLine(img, RAddOperation, 0, 1, 0, height - 1, &light);
714 ROperateLine(img, RSubtractOperation, width - 1, 1, width - 1, height - 1, &dark);
715 ROperateLine(img, RSubtractOperation, 0, height - 1, width - 1, height - 1, &dark);
716 #endif /* SHADOW_RESIZEBAR */
718 if (!RConvertImage(scr->rcontext, img, pmap)) {
719 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode));
722 RReleaseImage(img);
725 static void updateTexture(WFrameWindow * fwin)
727 int i;
728 unsigned long pixel;
730 i = fwin->flags.state;
731 if (fwin->titlebar) {
732 if (fwin->title_texture[i]->any.type != WTEX_SOLID) {
733 XSetWindowBackgroundPixmap(dpy, fwin->titlebar->window, fwin->title_back[i]);
734 if (wPreferences.new_style) {
735 if (fwin->left_button && fwin->lbutton_back[i])
736 XSetWindowBackgroundPixmap(dpy, fwin->left_button->window,
737 fwin->lbutton_back[i]);
739 #ifdef XKB_BUTTON_HINT
740 if (fwin->language_button && fwin->languagebutton_back[i]) {
741 XSetWindowBackgroundPixmap(dpy, fwin->language_button->window,
742 fwin->languagebutton_back[i]);
744 #endif
746 if (fwin->right_button && fwin->rbutton_back[i])
747 XSetWindowBackgroundPixmap(dpy, fwin->right_button->window,
748 fwin->rbutton_back[i]);
750 } else {
751 pixel = fwin->title_texture[i]->solid.normal.pixel;
752 XSetWindowBackground(dpy, fwin->titlebar->window, pixel);
753 if (wPreferences.new_style) {
754 if (fwin->left_button)
755 XSetWindowBackground(dpy, fwin->left_button->window, pixel);
756 #ifdef XKB_BUTTON_HINT
757 if (fwin->language_button)
758 XSetWindowBackground(dpy, fwin->language_button->window, pixel);
759 #endif
760 if (fwin->right_button)
761 XSetWindowBackground(dpy, fwin->right_button->window, pixel);
764 XClearWindow(dpy, fwin->titlebar->window);
766 if (fwin->left_button) {
767 XClearWindow(dpy, fwin->left_button->window);
768 handleButtonExpose(&fwin->left_button->descriptor, NULL);
770 #ifdef XKB_BUTTON_HINT
771 if (fwin->language_button) {
772 XClearWindow(dpy, fwin->language_button->window);
773 handleButtonExpose(&fwin->language_button->descriptor, NULL);
775 #endif
776 if (fwin->right_button) {
777 XClearWindow(dpy, fwin->right_button->window);
778 handleButtonExpose(&fwin->right_button->descriptor, NULL);
783 static void remakeTexture(WFrameWindow * fwin, int state)
785 Pixmap pmap, lpmap, rpmap;
786 #ifdef XKB_BUTTON_HINT
787 Pixmap tpmap;
788 #endif
790 if (fwin->title_texture[state] && fwin->titlebar) {
791 FREE_PIXMAP(fwin->title_back[state]);
792 if (wPreferences.new_style) {
793 FREE_PIXMAP(fwin->lbutton_back[state]);
794 FREE_PIXMAP(fwin->rbutton_back[state]);
795 #ifdef XKB_BUTTON_HINT
796 FREE_PIXMAP(fwin->languagebutton_back[state]);
797 #endif
800 if (fwin->title_texture[state]->any.type != WTEX_SOLID) {
801 int left, right;
802 int width;
803 #ifdef XKB_BUTTON_HINT
804 int language;
805 #endif
807 /* eventually surrounded by if new_style */
808 left = fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit;
809 #ifdef XKB_BUTTON_HINT
810 language = fwin->language_button && !fwin->flags.hide_language_button
811 && !fwin->flags.languagebutton_dont_fit;
812 #endif
813 right = fwin->right_button && !fwin->flags.hide_right_button
814 && !fwin->flags.rbutton_dont_fit;
816 width = fwin->core->width + 1;
818 #ifdef XKB_BUTTON_HINT
819 renderTexture(fwin->screen_ptr, fwin->title_texture[state],
820 width, fwin->titlebar->height,
821 fwin->titlebar->height, fwin->titlebar->height,
822 left, language, right, &pmap, &lpmap, &tpmap, &rpmap);
823 #else
824 renderTexture(fwin->screen_ptr, fwin->title_texture[state],
825 width, fwin->titlebar->height,
826 fwin->titlebar->height, fwin->titlebar->height,
827 left, right, &pmap, &lpmap, &rpmap);
828 #endif
830 fwin->title_back[state] = pmap;
831 if (wPreferences.new_style) {
832 fwin->lbutton_back[state] = lpmap;
833 fwin->rbutton_back[state] = rpmap;
834 #ifdef XKB_BUTTON_HINT
835 fwin->languagebutton_back[state] = tpmap;
836 #endif
840 if (fwin->resizebar_texture && fwin->resizebar_texture[0]
841 && fwin->resizebar && state == 0) {
843 FREE_PIXMAP(fwin->resizebar_back[0]);
845 if (fwin->resizebar_texture[0]->any.type != WTEX_SOLID) {
847 renderResizebarTexture(fwin->screen_ptr,
848 fwin->resizebar_texture[0],
849 fwin->resizebar->width,
850 fwin->resizebar->height, fwin->resizebar_corner_width, &pmap);
852 fwin->resizebar_back[0] = pmap;
855 /* this part should be in updateTexture() */
856 if (fwin->resizebar_texture[0]->any.type != WTEX_SOLID) {
857 XSetWindowBackgroundPixmap(dpy, fwin->resizebar->window, fwin->resizebar_back[0]);
858 } else {
859 XSetWindowBackground(dpy, fwin->resizebar->window,
860 fwin->resizebar_texture[0]->solid.normal.pixel);
862 XClearWindow(dpy, fwin->resizebar->window);
866 void wFrameWindowPaint(WFrameWindow * fwin)
868 WScreen *scr = fwin->screen_ptr;
869 int state;
871 state = fwin->flags.state;
873 if (fwin->flags.is_client_window_frame)
874 fwin->flags.justification = wPreferences.title_justification;
876 if (fwin->flags.need_texture_remake) {
877 int i;
879 fwin->flags.need_texture_remake = 0;
880 fwin->flags.need_texture_change = 0;
882 if (fwin->flags.single_texture) {
883 remakeTexture(fwin, 0);
884 updateTexture(fwin);
885 } else {
886 /* first render the texture for the current state... */
887 remakeTexture(fwin, state);
888 /* ... and paint it */
889 updateTexture(fwin);
891 for (i = 0; i < 3; i++) {
892 if (i != state) {
893 remakeTexture(fwin, i);
899 if (fwin->flags.need_texture_change) {
900 fwin->flags.need_texture_change = 0;
902 updateTexture(fwin);
905 if (fwin->titlebar && !fwin->flags.repaint_only_resizebar
906 && fwin->title_texture[state]->any.type == WTEX_SOLID) {
907 wDrawBevel(fwin->titlebar->window, fwin->titlebar->width,
908 fwin->titlebar->height, (WTexSolid *) fwin->title_texture[state], WREL_RAISED);
911 if (fwin->resizebar && !fwin->flags.repaint_only_titlebar
912 && fwin->resizebar_texture[0]->any.type == WTEX_SOLID) {
913 Window win;
914 int w, h;
915 int cw;
916 GC light_gc, dim_gc;
917 WTexSolid *texture = (WTexSolid *) fwin->resizebar_texture[0];
919 w = fwin->resizebar->width;
920 h = fwin->resizebar->height;
921 cw = fwin->resizebar_corner_width;
922 light_gc = texture->light_gc;
923 dim_gc = texture->dim_gc;
924 win = fwin->resizebar->window;
926 XDrawLine(dpy, win, dim_gc, 0, 0, w, 0);
927 XDrawLine(dpy, win, light_gc, 0, 1, w, 1);
929 XDrawLine(dpy, win, dim_gc, cw, 2, cw, h);
930 XDrawLine(dpy, win, light_gc, cw + 1, 2, cw + 1, h);
932 XDrawLine(dpy, win, dim_gc, w - cw - 2, 2, w - cw - 2, h);
933 XDrawLine(dpy, win, light_gc, w - cw - 1, 2, w - cw - 1, h);
935 #ifdef SHADOW_RESIZEBAR
936 XDrawLine(dpy, win, light_gc, 0, 1, 0, h - 1);
937 XDrawLine(dpy, win, dim_gc, w - 1, 2, w - 1, h - 1);
938 XDrawLine(dpy, win, dim_gc, 1, h - 1, cw, h - 1);
939 XDrawLine(dpy, win, dim_gc, cw + 2, h - 1, w - cw - 2, h - 1);
940 XDrawLine(dpy, win, dim_gc, w - cw, h - 1, w - 1, h - 1);
941 #endif /* SHADOW_RESIZEBAR */
944 if (fwin->titlebar && !fwin->flags.repaint_only_resizebar) {
945 int x, y, w, h;
946 int lofs = 6, rofs = 6;
947 int titlelen;
948 int allButtons = 1;
950 if (!wPreferences.new_style) {
951 if (fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit)
952 lofs += fwin->left_button->width + 3;
953 else
954 allButtons = 0;
956 #ifdef XKB_BUTTON_HINT
957 if (fwin->language_button && !fwin->flags.hide_language_button
958 && !fwin->flags.languagebutton_dont_fit)
959 lofs += fwin->language_button->width;
960 else
961 allButtons = 0;
962 #endif
964 if (fwin->right_button && !fwin->flags.hide_right_button && !fwin->flags.rbutton_dont_fit)
965 rofs += fwin->right_button->width + 3;
966 else
967 allButtons = 0;
969 #ifdef XKB_BUTTON_HINT
970 fwin->languagebutton_image = scr->b_pixmaps[WBUT_XKBGROUP1 + fwin->languagemode];
971 #endif
973 if (fwin->title) {
974 Drawable buf;
975 char *title;
977 title = ShrinkString(*fwin->font, fwin->title, fwin->titlebar->width - lofs - rofs);
978 titlelen = strlen(title);
979 w = WMWidthOfString(*fwin->font, title, titlelen);
981 switch (fwin->flags.justification) {
982 case WTJ_LEFT:
983 x = lofs;
984 break;
986 case WTJ_RIGHT:
987 x = fwin->titlebar->width - w - rofs;
988 break;
990 default:
991 if (!allButtons)
992 x = lofs + (fwin->titlebar->width - w - lofs - rofs) / 2;
993 else
994 x = (fwin->titlebar->width - w) / 2;
995 break;
998 y = *fwin->title_clearance + TITLEBAR_EXTEND_SPACE;
999 h = WMFontHeight(*fwin->font);
1001 /* We use a w+2 buffer to have an extra pixel on the left and
1002 * another one on the right. This is because for some odd reason,
1003 * sometimes when using AA fonts (when libfreetype2 is compiled
1004 * with bytecode interpreter turned off), some fonts are drawn
1005 * starting from x = -1 not from 0 as requested. Observed with
1006 * capital A letter on the bold 'trebuchet ms' font. -Dan
1008 buf = XCreatePixmap(dpy, fwin->titlebar->window, w + 2, h, scr->w_depth);
1010 XSetClipMask(dpy, scr->copy_gc, None);
1012 if (fwin->title_texture[state]->any.type != WTEX_SOLID) {
1013 XCopyArea(dpy, fwin->title_back[state], buf, scr->copy_gc,
1014 x - 1, y, w + 2, h, 0, 0);
1015 } else {
1016 XSetForeground(dpy, scr->copy_gc, fwin->title_texture[state]->solid.normal.pixel);
1017 XFillRectangle(dpy, buf, scr->copy_gc, 0, 0, w + 2, h);
1020 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1021 WMDrawString(scr->wmscreen, buf, fwin->title_color[state],
1022 *fwin->font, 1, 0, title, titlelen);
1024 XCopyArea(dpy, buf, fwin->titlebar->window, scr->copy_gc, 0, 0, w + 2, h, x - 1, y);
1026 XFreePixmap(dpy, buf);
1028 wfree(title);
1031 if (fwin->left_button)
1032 handleButtonExpose(&fwin->left_button->descriptor, NULL);
1033 if (fwin->right_button)
1034 handleButtonExpose(&fwin->right_button->descriptor, NULL);
1035 #ifdef XKB_BUTTON_HINT
1036 if (fwin->language_button)
1037 handleButtonExpose(&fwin->language_button->descriptor, NULL);
1038 #endif
1042 static void reconfigure(WFrameWindow * fwin, int x, int y, int width, int height, Bool dontMove)
1044 int k = (wPreferences.new_style ? 4 : 3);
1045 int resizedHorizontally = 0;
1047 if (dontMove)
1048 XResizeWindow(dpy, fwin->core->window, width, height);
1049 else
1050 XMoveResizeWindow(dpy, fwin->core->window, x, y, width, height);
1053 if (fwin->core->height != height && fwin->resizebar)
1054 XMoveWindow(dpy, fwin->resizebar->window, 0,
1055 height - fwin->resizebar->height);
1057 if (fwin->core->width != width) {
1058 fwin->flags.need_texture_remake = 1;
1059 resizedHorizontally = 1;
1062 fwin->core->width = width;
1063 fwin->core->height = height;
1065 if (fwin->titlebar && resizedHorizontally) {
1066 /* Check if the titlebar is wide enough to hold the buttons.
1067 * Temporarily remove them if can't
1069 if (fwin->left_button) {
1070 if (width < fwin->top_width * k && !fwin->flags.lbutton_dont_fit) {
1072 if (!fwin->flags.hide_left_button) {
1073 XUnmapWindow(dpy, fwin->left_button->window);
1075 fwin->flags.lbutton_dont_fit = 1;
1076 } else if (width >= fwin->top_width * k && fwin->flags.lbutton_dont_fit) {
1078 if (!fwin->flags.hide_left_button) {
1079 XMapWindow(dpy, fwin->left_button->window);
1081 fwin->flags.lbutton_dont_fit = 0;
1084 #ifdef XKB_BUTTON_HINT
1085 if (fwin->language_button) {
1086 if (width < fwin->top_width * k && !fwin->flags.languagebutton_dont_fit) {
1088 if (!fwin->flags.hide_language_button) {
1089 XUnmapWindow(dpy, fwin->language_button->window);
1091 fwin->flags.languagebutton_dont_fit = 1;
1092 } else if (width >= fwin->top_width * k && fwin->flags.languagebutton_dont_fit) {
1094 if (!fwin->flags.hide_language_button) {
1095 XMapWindow(dpy, fwin->language_button->window);
1097 fwin->flags.languagebutton_dont_fit = 0;
1100 #endif
1102 if (fwin->right_button) {
1103 if (width < fwin->top_width * 2 && !fwin->flags.rbutton_dont_fit) {
1105 if (!fwin->flags.hide_right_button) {
1106 XUnmapWindow(dpy, fwin->right_button->window);
1108 fwin->flags.rbutton_dont_fit = 1;
1109 } else if (width >= fwin->top_width * 2 && fwin->flags.rbutton_dont_fit) {
1111 if (!fwin->flags.hide_right_button) {
1112 XMapWindow(dpy, fwin->right_button->window);
1114 fwin->flags.rbutton_dont_fit = 0;
1118 if (wPreferences.new_style) {
1119 if (fwin->right_button)
1120 XMoveWindow(dpy, fwin->right_button->window,
1121 width - fwin->right_button->width + 1, 0);
1122 } else {
1123 if (fwin->right_button)
1124 XMoveWindow(dpy, fwin->right_button->window,
1125 width - fwin->right_button->width - 3,
1126 (fwin->titlebar->height - fwin->right_button->height) / 2);
1128 updateTitlebar(fwin);
1129 checkTitleSize(fwin);
1132 if (fwin->resizebar) {
1133 wCoreConfigure(fwin->resizebar, 0,
1134 fwin->core->height - fwin->resizebar->height,
1135 fwin->core->width, fwin->resizebar->height);
1137 fwin->resizebar_corner_width = RESIZEBAR_CORNER_WIDTH;
1138 if (fwin->core->width < RESIZEBAR_CORNER_WIDTH * 2 + RESIZEBAR_MIN_WIDTH) {
1139 fwin->resizebar_corner_width = fwin->core->width / 2;
1144 void wFrameWindowConfigure(WFrameWindow * fwin, int x, int y, int width, int height)
1146 reconfigure(fwin, x, y, width, height, False);
1149 void wFrameWindowResize(WFrameWindow * fwin, int width, int height)
1151 reconfigure(fwin, 0, 0, width, height, True);
1154 int wFrameWindowChangeTitle(WFrameWindow * fwin, char *new_title)
1156 /* check if the title is the same as before */
1157 if (fwin->title) {
1158 if (new_title && (strcmp(fwin->title, new_title) == 0)) {
1159 return 0;
1161 } else {
1162 if (!new_title)
1163 return 0;
1166 if (fwin->title)
1167 wfree(fwin->title);
1169 fwin->title = wstrdup(new_title);
1171 if (fwin->titlebar) {
1172 XClearWindow(dpy, fwin->titlebar->window);
1174 wFrameWindowPaint(fwin);
1176 checkTitleSize(fwin);
1178 return 1;
1181 #ifdef XKB_BUTTON_HINT
1182 void wFrameWindowUpdateLanguageButton(WFrameWindow * fwin)
1184 paintButton(fwin->language_button, fwin->title_texture[fwin->flags.state],
1185 WMColorPixel(fwin->title_color[fwin->flags.state]), fwin->languagebutton_image, True);
1187 #endif /* XKB_BUTTON_HINT */
1189 /*********************************************************************/
1191 static void handleExpose(WObjDescriptor * desc, XEvent * event)
1193 WFrameWindow *fwin = (WFrameWindow *) desc->parent;
1195 if (fwin->titlebar && fwin->titlebar->window == event->xexpose.window)
1196 fwin->flags.repaint_only_titlebar = 1;
1197 if (fwin->resizebar && fwin->resizebar->window == event->xexpose.window)
1198 fwin->flags.repaint_only_resizebar = 1;
1199 wFrameWindowPaint(fwin);
1200 fwin->flags.repaint_only_titlebar = 0;
1201 fwin->flags.repaint_only_resizebar = 0;
1204 static void checkTitleSize(WFrameWindow * fwin)
1206 int width;
1208 if (!fwin->title) {
1209 fwin->flags.incomplete_title = 0;
1210 return;
1213 if (!fwin->titlebar) {
1214 fwin->flags.incomplete_title = 1;
1215 return;
1216 } else {
1217 width = fwin->titlebar->width - 6 - 6;
1220 if (!wPreferences.new_style) {
1221 if (fwin->left_button && !fwin->flags.hide_left_button && !fwin->flags.lbutton_dont_fit)
1222 width -= fwin->left_button->width + 3;
1224 #ifdef XKB_BUTTON_HINT
1225 if (fwin->language_button && !fwin->flags.hide_language_button
1226 && !fwin->flags.languagebutton_dont_fit)
1227 width -= fwin->language_button->width + 3;
1228 #endif
1230 if (fwin->right_button && !fwin->flags.hide_right_button && !fwin->flags.rbutton_dont_fit)
1231 width -= fwin->right_button->width + 3;
1233 if (WMWidthOfString(*fwin->font, fwin->title, strlen(fwin->title)) > width) {
1234 fwin->flags.incomplete_title = 1;
1235 } else {
1236 fwin->flags.incomplete_title = 0;
1240 static void paintButton(WCoreWindow * button, WTexture * texture, unsigned long color, WPixmap * image, int pushed)
1242 WScreen *scr = button->screen_ptr;
1243 GC copy_gc = scr->copy_gc;
1244 int x = 0, y = 0, d = 0;
1245 int left = 0, width = 0;
1247 /* setup stuff according to the state */
1248 if (pushed) {
1249 if (image) {
1250 if (image->width >= image->height * 2) {
1251 /* the image contains 2 pictures: the second is for the
1252 * pushed state */
1253 width = image->width / 2;
1254 left = image->width / 2;
1255 } else {
1256 width = image->width;
1259 XSetClipMask(dpy, copy_gc, None);
1260 XSetForeground(dpy, copy_gc, scr->white_pixel);
1261 d = 1;
1262 if (wPreferences.new_style) {
1263 XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width - 1, button->height - 1);
1264 XSetForeground(dpy, copy_gc, scr->black_pixel);
1265 XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width - 1, button->height - 1);
1266 } else {
1267 XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height);
1268 XSetForeground(dpy, copy_gc, scr->black_pixel);
1269 XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height);
1271 } else {
1272 XClearWindow(dpy, button->window);
1274 if (image) {
1275 if (image->width >= image->height * 2)
1276 width = image->width / 2;
1277 else
1278 width = image->width;
1280 d = 0;
1282 if (wPreferences.new_style) {
1283 if (texture->any.type == WTEX_SOLID || pushed) {
1284 wDrawBevel(button->window, button->width, button->height,
1285 (WTexSolid *) texture, WREL_RAISED);
1287 } else {
1288 wDrawBevel(button->window, button->width, button->height,
1289 scr->widget_texture, WREL_RAISED);
1293 if (image) {
1294 /* display image */
1295 XSetClipMask(dpy, copy_gc, image->mask);
1296 x = (button->width - width) / 2 + d;
1297 y = (button->height - image->height) / 2 + d;
1298 XSetClipOrigin(dpy, copy_gc, x - left, y);
1299 if (!wPreferences.new_style) {
1300 XSetForeground(dpy, copy_gc, scr->black_pixel);
1301 if (!pushed) {
1302 if (image->depth == 1)
1303 XCopyPlane(dpy, image->image, button->window, copy_gc,
1304 left, 0, width, image->height, x, y, 1);
1305 else
1306 XCopyArea(dpy, image->image, button->window, copy_gc,
1307 left, 0, width, image->height, x, y);
1308 } else {
1309 XSetForeground(dpy, copy_gc, scr->dark_pixel);
1310 XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height);
1312 } else {
1313 if (pushed) {
1314 XSetForeground(dpy, copy_gc, scr->black_pixel);
1315 } else {
1316 XSetForeground(dpy, copy_gc, color);
1317 XSetBackground(dpy, copy_gc, texture->any.color.pixel);
1319 XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height);
1324 static void handleButtonExpose(WObjDescriptor * desc, XEvent * event)
1326 WFrameWindow *fwin = (WFrameWindow *) desc->parent;
1327 WCoreWindow *button = (WCoreWindow *) desc->self;
1329 #ifdef XKB_BUTTON_HINT
1330 if (button == fwin->language_button) {
1331 if (wPreferences.modelock) {
1332 paintButton(button, fwin->title_texture[fwin->flags.state],
1333 WMColorPixel(fwin->title_color[fwin->flags.state]),
1334 fwin->languagebutton_image, False);
1336 } else
1337 #endif
1338 if (button == fwin->left_button) {
1339 paintButton(button, fwin->title_texture[fwin->flags.state],
1340 WMColorPixel(fwin->title_color[fwin->flags.state]), fwin->lbutton_image, False);
1341 } else {
1342 paintButton(button, fwin->title_texture[fwin->flags.state],
1343 WMColorPixel(fwin->title_color[fwin->flags.state]), fwin->rbutton_image, False);
1347 static void titlebarMouseDown(WObjDescriptor * desc, XEvent * event)
1349 WFrameWindow *fwin = desc->parent;
1350 WCoreWindow *titlebar = desc->self;
1352 if (IsDoubleClick(fwin->core->screen_ptr, event)) {
1353 if (fwin->on_dblclick_titlebar) {
1354 (*fwin->on_dblclick_titlebar) (titlebar, fwin->child, event);
1356 } else {
1357 if (fwin->on_mousedown_titlebar) {
1358 (*fwin->on_mousedown_titlebar) (titlebar, fwin->child, event);
1363 static void resizebarMouseDown(WObjDescriptor * desc, XEvent * event)
1365 WFrameWindow *fwin = desc->parent;
1366 WCoreWindow *resizebar = desc->self;
1368 if (fwin->on_mousedown_resizebar)
1369 (*fwin->on_mousedown_resizebar) (resizebar, fwin->child, event);
1372 static void buttonMouseDown(WObjDescriptor * desc, XEvent * event)
1374 WFrameWindow *fwin = desc->parent;
1375 WCoreWindow *button = desc->self;
1376 WPixmap *image;
1377 XEvent ev;
1378 int done = 0, execute = 1;
1379 WTexture *texture;
1380 unsigned long pixel;
1381 int clickButton = event->xbutton.button;
1383 if (IsDoubleClick(fwin->core->screen_ptr, event)) {
1384 if (button == fwin->right_button && fwin->on_dblclick_right) {
1385 (*fwin->on_dblclick_right) (button, fwin->child, event);
1387 return;
1390 if (button == fwin->left_button) {
1391 image = fwin->lbutton_image;
1392 } else {
1393 image = fwin->rbutton_image;
1395 #ifdef XKB_BUTTON_HINT
1396 if (button == fwin->language_button) {
1397 if (!wPreferences.modelock)
1398 return;
1399 image = fwin->languagebutton_image;
1401 #endif
1403 pixel = WMColorPixel(fwin->title_color[fwin->flags.state]);
1404 texture = fwin->title_texture[fwin->flags.state];
1405 paintButton(button, texture, pixel, image, True);
1407 while (!done) {
1408 WMMaskEvent(dpy, LeaveWindowMask | EnterWindowMask | ButtonReleaseMask
1409 | ButtonPressMask | ExposureMask, &ev);
1410 switch (ev.type) {
1411 case LeaveNotify:
1412 execute = 0;
1413 paintButton(button, texture, pixel, image, False);
1414 break;
1416 case EnterNotify:
1417 execute = 1;
1418 paintButton(button, texture, pixel, image, True);
1419 break;
1421 case ButtonPress:
1422 break;
1424 case ButtonRelease:
1425 if (ev.xbutton.button == clickButton)
1426 done = 1;
1427 break;
1429 default:
1430 WMHandleEvent(&ev);
1433 paintButton(button, texture, pixel, image, False);
1435 if (execute) {
1436 if (button == fwin->left_button) {
1437 if (fwin->on_click_left)
1438 (*fwin->on_click_left) (button, fwin->child, &ev);
1439 } else if (button == fwin->right_button) {
1440 if (fwin->on_click_right)
1441 (*fwin->on_click_right) (button, fwin->child, &ev);
1443 #ifdef XKB_BUTTON_HINT
1444 else if (button == fwin->language_button) {
1445 if (fwin->on_click_language)
1446 (*fwin->on_click_language) (button, fwin->child, &ev);
1448 #endif