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.
24 #include <X11/Xutil.h>
25 #ifdef KEEP_XKB_LOCK_STATUS
26 #include <X11/XKBlib.h>
27 #endif /* KEEP_XKB_LOCK_STATUS */
34 #include "WindowMaker.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
)
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
->title_min_height
= title_min
;
81 fwin
->title_max_height
= title_max
;
83 #ifdef KEEP_XKB_LOCK_STATUS
84 fwin
->languagemode
= XkbGroup1Index
;
85 fwin
->last_languagemode
= XkbGroup2Index
;
88 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
89 ? FRAME_BORDER_WIDTH
: 0);
90 if (wPreferences
.use_saveunders
) {
92 XSetWindowAttributes attribs
;
95 attribs
.save_under
= True
;
96 XChangeWindowAttributes(dpy
, fwin
->core
->window
, vmask
, &attribs
);
99 /* setup stacking information */
100 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
101 fwin
->core
->stacking
->above
= NULL
;
102 fwin
->core
->stacking
->under
= NULL
;
103 fwin
->core
->stacking
->child_of
= NULL
;
104 fwin
->core
->stacking
->window_level
= wlevel
;
106 AddToStackList(fwin
->core
);
108 wFrameWindowUpdateBorders(fwin
, flags
);
113 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
119 WScreen
*scr
= fwin
->screen_ptr
;
121 width
= fwin
->core
->width
;
122 if (flags
& WFF_IS_SHADED
)
125 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
127 if (flags
& WFF_TITLEBAR
) {
128 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
130 if (theight
> *fwin
->title_max_height
)
131 theight
= *fwin
->title_max_height
;
133 if (theight
< *fwin
->title_min_height
)
134 theight
= *fwin
->title_min_height
;
138 if (wPreferences
.new_style
== TS_NEW
) {
140 } else if (wPreferences
.new_style
== TS_OLD
) {
146 if (fwin
->titlebar
) {
147 /* if we had a titlebar and is requesting for one,
148 * check if the size has changed and resize it */
149 if (flags
& WFF_TITLEBAR
) {
150 fwin
->top_width
= theight
;
152 fwin
->flags
.need_texture_remake
= 1;
154 if (wPreferences
.new_style
== TS_NEW
) {
155 if (fwin
->left_button
) {
156 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
158 #ifdef XKB_BUTTON_HINT
159 if (fwin
->language_button
) {
160 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
161 || fwin
->flags
.lbutton_dont_fit
) {
162 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
164 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
169 if (fwin
->right_button
) {
170 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
172 } else { /* !new_style */
173 if (fwin
->left_button
) {
174 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
176 #ifdef XKB_BUTTON_HINT
177 if (fwin
->language_button
) {
178 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
183 if (fwin
->right_button
) {
184 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
185 (theight
- bsize
) / 2, bsize
, bsize
);
188 updateTitlebar(fwin
);
190 /* we had a titlebar, but now we don't need it anymore */
191 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
192 FREE_PIXMAP(fwin
->title_back
[i
]);
193 if (wPreferences
.new_style
== TS_NEW
) {
194 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
195 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
196 #ifdef XKB_BUTTON_HINT
197 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
201 if (fwin
->left_button
)
202 wCoreDestroy(fwin
->left_button
);
203 fwin
->left_button
= NULL
;
205 #ifdef XKB_BUTTON_HINT
206 if (fwin
->language_button
)
207 wCoreDestroy(fwin
->language_button
);
208 fwin
->language_button
= NULL
;
211 if (fwin
->right_button
)
212 wCoreDestroy(fwin
->right_button
);
213 fwin
->right_button
= NULL
;
215 wCoreDestroy(fwin
->titlebar
);
216 fwin
->titlebar
= NULL
;
221 /* if we didn't have a titlebar and are being requested for
223 if (flags
& WFF_TITLEBAR
) {
224 fwin
->top_width
= theight
;
226 fwin
->flags
.titlebar
= 1;
227 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
229 if (flags
& WFF_LEFT_BUTTON
) {
230 fwin
->flags
.left_button
= 1;
231 if (wPreferences
.new_style
== TS_NEW
) {
232 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
233 if (width
< theight
* 4) {
234 fwin
->flags
.lbutton_dont_fit
= 1;
236 XMapRaised(dpy
, fwin
->left_button
->window
);
238 } else if (wPreferences
.new_style
== TS_OLD
) {
240 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
242 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
243 scr
->widget_texture
->normal
.pixel
);
245 if (width
< theight
* 3) {
246 fwin
->flags
.lbutton_dont_fit
= 1;
248 XMapRaised(dpy
, fwin
->left_button
->window
);
252 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
255 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
256 scr
->widget_texture
->dark
.pixel
);
258 if (width
< theight
*3) {
259 fwin
->flags
.lbutton_dont_fit
= 1;
261 XMapRaised(dpy
, fwin
->left_button
->window
);
265 #ifdef XKB_BUTTON_HINT
266 if (flags
& WFF_LANGUAGE_BUTTON
) {
267 fwin
->flags
.language_button
= 1;
268 if (wPreferences
.new_style
== TS_NEW
) {
269 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
271 if (width
< theight
* 4) {
272 fwin
->flags
.languagebutton_dont_fit
= 1;
274 XMapRaised(dpy
, fwin
->language_button
->window
);
277 fwin
->language_button
=
278 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
281 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
282 scr
->widget_texture
->normal
.pixel
);
284 if (width
< theight
* 3) {
285 fwin
->flags
.languagebutton_dont_fit
= 1;
287 XMapRaised(dpy
, fwin
->language_button
->window
);
293 if (flags
& WFF_RIGHT_BUTTON
) {
294 fwin
->flags
.right_button
= 1;
295 if (wPreferences
.new_style
== TS_NEW
) {
297 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
298 } else if (wPreferences
.new_style
== TS_OLD
) {
300 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
301 (theight
- bsize
) / 2, bsize
, bsize
);
302 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
303 scr
->widget_texture
->normal
.pixel
);
306 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
307 (theight
-bsize
)/2, bsize
, bsize
);
308 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
309 scr
->widget_texture
->dark
.pixel
);
312 if (width
< theight
* 2) {
313 fwin
->flags
.rbutton_dont_fit
= 1;
315 XMapRaised(dpy
, fwin
->right_button
->window
);
319 if (wPreferences
.new_style
== TS_NEW
)
320 updateTitlebar(fwin
);
322 XMapRaised(dpy
, fwin
->titlebar
->window
);
324 fwin
->flags
.need_texture_remake
= 1;
327 checkTitleSize(fwin
);
329 if (flags
& WFF_RESIZEBAR
) {
330 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
332 if (!fwin
->resizebar
) {
333 fwin
->flags
.resizebar
= 1;
334 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
335 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
336 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
337 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
338 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
339 if (fwin
->resizebar_corner_width
< 0)
340 fwin
->resizebar_corner_width
= 0;
343 XMapWindow(dpy
, fwin
->resizebar
->window
);
344 XLowerWindow(dpy
, fwin
->resizebar
->window
);
346 fwin
->flags
.need_texture_remake
= 1;
348 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
) {
349 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
350 width
, RESIZEBAR_HEIGHT
);
354 fwin
->bottom_width
= 0;
356 if (fwin
->resizebar
) {
357 fwin
->bottom_width
= 0;
358 wCoreDestroy(fwin
->resizebar
);
359 fwin
->resizebar
= NULL
;
363 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
)) {
364 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
367 if (flags
& WFF_BORDER
) {
368 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
370 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
373 /* setup object descriptors */
375 if (fwin
->titlebar
) {
376 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
377 fwin
->titlebar
->descriptor
.parent
= fwin
;
378 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
379 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
382 if (fwin
->resizebar
) {
383 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
384 fwin
->resizebar
->descriptor
.parent
= fwin
;
385 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
386 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
389 if (fwin
->left_button
) {
390 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
391 fwin
->left_button
->descriptor
.parent
= fwin
;
392 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
393 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
395 #ifdef XKB_BUTTON_HINT
396 if (fwin
->language_button
) {
397 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
398 fwin
->language_button
->descriptor
.parent
= fwin
;
399 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
400 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
404 if (fwin
->right_button
) {
405 fwin
->right_button
->descriptor
.parent
= fwin
;
406 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
407 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
408 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
411 checkTitleSize(fwin
);
414 void wFrameWindowDestroy(WFrameWindow
* fwin
)
418 if (fwin
->left_button
)
419 wCoreDestroy(fwin
->left_button
);
421 #ifdef XKB_BUTTON_HINT
422 if (fwin
->language_button
)
423 wCoreDestroy(fwin
->language_button
);
426 if (fwin
->right_button
)
427 wCoreDestroy(fwin
->right_button
);
430 wCoreDestroy(fwin
->resizebar
);
433 wCoreDestroy(fwin
->titlebar
);
435 RemoveFromStackList(fwin
->core
);
437 wCoreDestroy(fwin
->core
);
442 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
443 FREE_PIXMAP(fwin
->title_back
[i
]);
444 if (wPreferences
.new_style
== TS_NEW
) {
445 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
446 #ifdef XKB_BUTTON_HINT
447 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
449 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
456 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
458 if (fwin
->flags
.state
== state
)
461 fwin
->flags
.state
= state
;
462 fwin
->flags
.need_texture_change
= 1;
464 wFrameWindowPaint(fwin
);
467 static void updateTitlebar(WFrameWindow
* fwin
)
472 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
474 if (theight
> *fwin
->title_max_height
)
475 theight
= *fwin
->title_max_height
;
477 if (theight
< *fwin
->title_min_height
)
478 theight
= *fwin
->title_min_height
;
481 w
= fwin
->core
->width
+ 1;
483 if (wPreferences
.new_style
== TS_NEW
) {
484 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
486 #ifdef XKB_BUTTON_HINT
487 if (fwin
->language_button
)
488 wCoreConfigure(fwin
->language_button
, 0, 0,
489 fwin
->language_button
->width
, fwin
->language_button
->width
);
492 #ifdef XKB_BUTTON_HINT
493 if (fwin
->language_button
)
494 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
495 fwin
->language_button
->width
, fwin
->language_button
->width
);
497 x
= fwin
->left_button
->width
;
498 w
-= fwin
->left_button
->width
;
500 #ifdef XKB_BUTTON_HINT
501 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
502 || fwin
->flags
.languagebutton_dont_fit
) {
504 x
+= fwin
->language_button
->width
;
505 w
-= fwin
->language_button
->width
;
509 #ifdef XKB_BUTTON_HINT
511 int bsize
= theight
- 7;
512 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
513 if (fwin
->language_button
)
514 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
515 fwin
->language_button
->width
, fwin
->language_button
->width
);
517 if (fwin
->language_button
)
518 wCoreConfigure(fwin
->language_button
,
519 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
520 fwin
->language_button
->width
, fwin
->language_button
->width
);
525 if (wPreferences
.new_style
== TS_NEW
) {
526 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
) {
527 w
-= fwin
->right_button
->width
;
531 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
532 fwin
->flags
.need_texture_remake
= 1;
534 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
537 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
539 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
540 XUnmapWindow(dpy
, fwin
->right_button
->window
);
541 fwin
->flags
.hide_right_button
= 1;
544 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
545 XUnmapWindow(dpy
, fwin
->left_button
->window
);
546 fwin
->flags
.hide_left_button
= 1;
548 #ifdef XKB_BUTTON_HINT
549 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
550 XUnmapWindow(dpy
, fwin
->language_button
->window
);
551 fwin
->flags
.hide_language_button
= 1;
555 if (fwin
->titlebar
) {
556 if (wPreferences
.new_style
== TS_NEW
) {
557 updateTitlebar(fwin
);
559 #ifdef XKB_BUTTON_HINT
560 updateTitlebar(fwin
);
562 XClearWindow(dpy
, fwin
->titlebar
->window
);
563 wFrameWindowPaint(fwin
);
566 checkTitleSize(fwin
);
570 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
572 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
574 if (!fwin
->flags
.rbutton_dont_fit
)
575 XMapWindow(dpy
, fwin
->right_button
->window
);
577 fwin
->flags
.hide_right_button
= 0;
579 #ifdef XKB_BUTTON_HINT
580 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
582 if (!fwin
->flags
.languagebutton_dont_fit
)
583 XMapWindow(dpy
, fwin
->language_button
->window
);
585 fwin
->flags
.hide_language_button
= 0;
589 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
591 if (!fwin
->flags
.lbutton_dont_fit
)
592 XMapWindow(dpy
, fwin
->left_button
->window
);
594 fwin
->flags
.hide_left_button
= 0;
597 if (fwin
->titlebar
) {
598 if (wPreferences
.new_style
== TS_NEW
) {
599 updateTitlebar(fwin
);
601 XClearWindow(dpy
, fwin
->titlebar
->window
);
602 wFrameWindowPaint(fwin
);
604 checkTitleSize(fwin
);
609 #ifdef XKB_BUTTON_HINT
610 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
611 int bwidth
, int bheight
, int left
, int language
, int right
,
612 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
614 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
615 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
619 RImage
*limg
, *rimg
, *mimg
;
620 #ifdef XKB_BUTTON_HINT
628 #ifdef XKB_BUTTON_HINT
629 *languagebutton
= None
;
632 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
634 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
638 if (wPreferences
.new_style
== TS_NEW
) {
640 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
647 #ifdef XKB_BUTTON_HINT
649 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
655 RBevelImage(limg
, RBEV_RAISED2
);
656 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
)) {
657 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
663 #ifdef XKB_BUTTON_HINT
665 RBevelImage(timg
, RBEV_RAISED2
);
666 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
)) {
667 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
676 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
681 RBevelImage(rimg
, RBEV_RAISED2
);
682 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
)) {
683 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
690 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
691 RBevelImage(mimg
, RBEV_RAISED2
);
693 if (!RConvertImage(scr
->rcontext
, mimg
, title
)) {
694 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
698 RBevelImage(img
, RBEV_RAISED2
);
700 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
701 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
705 RBevelImage(img
, RBEV_RAISED2
);
707 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
708 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
716 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
724 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
726 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
731 light
.red
= light
.green
= light
.blue
= 80;
734 dark
.red
= dark
.green
= dark
.blue
= 40;
736 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
737 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
739 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
740 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
743 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
744 width
- cwidth
- 2, height
- 1, &dark
);
745 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
747 #ifdef SHADOW_RESIZEBAR
748 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
749 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
750 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
751 #endif /* SHADOW_RESIZEBAR */
753 if (!RConvertImage(scr
->rcontext
, img
, pmap
)) {
754 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
760 static void updateTexture(WFrameWindow
* fwin
)
765 i
= fwin
->flags
.state
;
766 if (fwin
->titlebar
) {
767 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
768 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
769 if (wPreferences
.new_style
== TS_NEW
) {
770 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
771 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
772 fwin
->lbutton_back
[i
]);
774 #ifdef XKB_BUTTON_HINT
775 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
]) {
776 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
777 fwin
->languagebutton_back
[i
]);
781 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
782 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
783 fwin
->rbutton_back
[i
]);
786 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
787 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
788 if (wPreferences
.new_style
== TS_NEW
) {
789 if (fwin
->left_button
)
790 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
791 #ifdef XKB_BUTTON_HINT
792 if (fwin
->language_button
)
793 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
795 if (fwin
->right_button
)
796 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
799 XClearWindow(dpy
, fwin
->titlebar
->window
);
801 if (fwin
->left_button
) {
802 XClearWindow(dpy
, fwin
->left_button
->window
);
803 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
805 #ifdef XKB_BUTTON_HINT
806 if (fwin
->language_button
) {
807 XClearWindow(dpy
, fwin
->language_button
->window
);
808 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
811 if (fwin
->right_button
) {
812 XClearWindow(dpy
, fwin
->right_button
->window
);
813 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
818 static void remakeTexture(WFrameWindow
* fwin
, int state
)
820 Pixmap pmap
, lpmap
, rpmap
;
821 #ifdef XKB_BUTTON_HINT
825 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
826 FREE_PIXMAP(fwin
->title_back
[state
]);
827 if (wPreferences
.new_style
== TS_NEW
) {
828 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
829 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
830 #ifdef XKB_BUTTON_HINT
831 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
835 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
838 #ifdef XKB_BUTTON_HINT
842 /* eventually surrounded by if new_style */
843 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
844 #ifdef XKB_BUTTON_HINT
845 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
846 && !fwin
->flags
.languagebutton_dont_fit
;
848 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
849 && !fwin
->flags
.rbutton_dont_fit
;
851 width
= fwin
->core
->width
+ 1;
853 #ifdef XKB_BUTTON_HINT
854 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
855 width
, fwin
->titlebar
->height
,
856 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
857 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
859 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
860 width
, fwin
->titlebar
->height
,
861 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
862 left
, right
, &pmap
, &lpmap
, &rpmap
);
865 fwin
->title_back
[state
] = pmap
;
866 if (wPreferences
.new_style
== TS_NEW
) {
867 fwin
->lbutton_back
[state
] = lpmap
;
868 fwin
->rbutton_back
[state
] = rpmap
;
869 #ifdef XKB_BUTTON_HINT
870 fwin
->languagebutton_back
[state
] = tpmap
;
875 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
876 && fwin
->resizebar
&& state
== 0) {
878 FREE_PIXMAP(fwin
->resizebar_back
[0]);
880 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
882 renderResizebarTexture(fwin
->screen_ptr
,
883 fwin
->resizebar_texture
[0],
884 fwin
->resizebar
->width
,
885 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
887 fwin
->resizebar_back
[0] = pmap
;
890 /* this part should be in updateTexture() */
891 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
892 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
894 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
895 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
897 XClearWindow(dpy
, fwin
->resizebar
->window
);
901 void wFrameWindowPaint(WFrameWindow
* fwin
)
903 WScreen
*scr
= fwin
->screen_ptr
;
906 state
= fwin
->flags
.state
;
908 if (fwin
->flags
.is_client_window_frame
)
909 fwin
->flags
.justification
= wPreferences
.title_justification
;
911 if (fwin
->flags
.need_texture_remake
) {
914 fwin
->flags
.need_texture_remake
= 0;
915 fwin
->flags
.need_texture_change
= 0;
917 if (fwin
->flags
.single_texture
) {
918 remakeTexture(fwin
, 0);
921 /* first render the texture for the current state... */
922 remakeTexture(fwin
, state
);
923 /* ... and paint it */
926 for (i
= 0; i
< 3; i
++) {
928 remakeTexture(fwin
, i
);
934 if (fwin
->flags
.need_texture_change
) {
935 fwin
->flags
.need_texture_change
= 0;
940 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
941 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
942 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
943 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
946 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
947 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
952 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
954 w
= fwin
->resizebar
->width
;
955 h
= fwin
->resizebar
->height
;
956 cw
= fwin
->resizebar_corner_width
;
957 light_gc
= texture
->light_gc
;
958 dim_gc
= texture
->dim_gc
;
959 win
= fwin
->resizebar
->window
;
961 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
962 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
964 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
965 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
967 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
968 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
970 #ifdef SHADOW_RESIZEBAR
971 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
972 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
973 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
974 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
975 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
976 #endif /* SHADOW_RESIZEBAR */
979 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
981 int lofs
= 6, rofs
= 6;
985 if (!wPreferences
.new_style
== TS_NEW
) {
986 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
987 lofs
+= fwin
->left_button
->width
+ 3;
991 #ifdef XKB_BUTTON_HINT
992 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
993 && !fwin
->flags
.languagebutton_dont_fit
)
994 lofs
+= fwin
->language_button
->width
;
999 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1000 rofs
+= fwin
->right_button
->width
+ 3;
1004 #ifdef XKB_BUTTON_HINT
1005 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1012 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
1013 titlelen
= strlen(title
);
1014 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1016 switch (fwin
->flags
.justification
) {
1022 x
= fwin
->titlebar
->width
- w
- rofs
;
1027 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1029 x
= (fwin
->titlebar
->width
- w
) / 2;
1033 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1034 h
= WMFontHeight(*fwin
->font
);
1036 if (y
*2 + h
> *fwin
->title_max_height
)
1037 y
= (*fwin
->title_max_height
- h
) / 2;
1039 if (y
*2 + h
< *fwin
->title_min_height
)
1040 y
= (*fwin
->title_min_height
- h
) / 2;
1042 /* We use a w+2 buffer to have an extra pixel on the left and
1043 * another one on the right. This is because for some odd reason,
1044 * sometimes when using AA fonts (when libfreetype2 is compiled
1045 * with bytecode interpreter turned off), some fonts are drawn
1046 * starting from x = -1 not from 0 as requested. Observed with
1047 * capital A letter on the bold 'trebuchet ms' font. -Dan
1049 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1051 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1053 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1054 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1055 x
- 1, y
, w
+ 2, h
, 0, 0);
1057 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1058 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1061 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1062 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1063 *fwin
->font
, 1, 0, title
, titlelen
);
1065 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1067 XFreePixmap(dpy
, buf
);
1072 if (fwin
->left_button
)
1073 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1074 if (fwin
->right_button
)
1075 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1076 #ifdef XKB_BUTTON_HINT
1077 if (fwin
->language_button
)
1078 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1083 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1085 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1086 int resizedHorizontally
= 0;
1089 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1091 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1094 if (fwin->core->height != height && fwin->resizebar)
1095 XMoveWindow(dpy, fwin->resizebar->window, 0,
1096 height - fwin->resizebar->height);
1098 if (fwin
->core
->width
!= width
) {
1099 fwin
->flags
.need_texture_remake
= 1;
1100 resizedHorizontally
= 1;
1103 fwin
->core
->width
= width
;
1104 fwin
->core
->height
= height
;
1106 if (fwin
->titlebar
&& resizedHorizontally
) {
1107 /* Check if the titlebar is wide enough to hold the buttons.
1108 * Temporarily remove them if can't
1110 if (fwin
->left_button
) {
1111 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1113 if (!fwin
->flags
.hide_left_button
) {
1114 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1116 fwin
->flags
.lbutton_dont_fit
= 1;
1117 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1119 if (!fwin
->flags
.hide_left_button
) {
1120 XMapWindow(dpy
, fwin
->left_button
->window
);
1122 fwin
->flags
.lbutton_dont_fit
= 0;
1125 #ifdef XKB_BUTTON_HINT
1126 if (fwin
->language_button
) {
1127 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1129 if (!fwin
->flags
.hide_language_button
) {
1130 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1132 fwin
->flags
.languagebutton_dont_fit
= 1;
1133 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1135 if (!fwin
->flags
.hide_language_button
) {
1136 XMapWindow(dpy
, fwin
->language_button
->window
);
1138 fwin
->flags
.languagebutton_dont_fit
= 0;
1143 if (fwin
->right_button
) {
1144 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1146 if (!fwin
->flags
.hide_right_button
) {
1147 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1149 fwin
->flags
.rbutton_dont_fit
= 1;
1150 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1152 if (!fwin
->flags
.hide_right_button
) {
1153 XMapWindow(dpy
, fwin
->right_button
->window
);
1155 fwin
->flags
.rbutton_dont_fit
= 0;
1159 if (wPreferences
.new_style
== TS_NEW
) {
1160 if (fwin
->right_button
)
1161 XMoveWindow(dpy
, fwin
->right_button
->window
,
1162 width
- fwin
->right_button
->width
+ 1, 0);
1164 if (fwin
->right_button
)
1165 XMoveWindow(dpy
, fwin
->right_button
->window
,
1166 width
- fwin
->right_button
->width
- 3,
1167 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1169 updateTitlebar(fwin
);
1170 checkTitleSize(fwin
);
1173 if (fwin
->resizebar
) {
1174 wCoreConfigure(fwin
->resizebar
, 0,
1175 fwin
->core
->height
- fwin
->resizebar
->height
,
1176 fwin
->core
->width
, fwin
->resizebar
->height
);
1178 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1179 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
1180 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1185 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1187 reconfigure(fwin
, x
, y
, width
, height
, False
);
1190 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1192 reconfigure(fwin
, 0, 0, width
, height
, True
);
1195 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1197 /* check if the title is the same as before */
1199 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0)) {
1210 fwin
->title
= wstrdup(new_title
);
1212 if (fwin
->titlebar
) {
1213 XClearWindow(dpy
, fwin
->titlebar
->window
);
1215 wFrameWindowPaint(fwin
);
1217 checkTitleSize(fwin
);
1222 #ifdef XKB_BUTTON_HINT
1223 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1225 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1226 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1228 #endif /* XKB_BUTTON_HINT */
1230 /*********************************************************************/
1232 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1234 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1236 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1237 fwin
->flags
.repaint_only_titlebar
= 1;
1238 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1239 fwin
->flags
.repaint_only_resizebar
= 1;
1240 wFrameWindowPaint(fwin
);
1241 fwin
->flags
.repaint_only_titlebar
= 0;
1242 fwin
->flags
.repaint_only_resizebar
= 0;
1245 static void checkTitleSize(WFrameWindow
* fwin
)
1250 fwin
->flags
.incomplete_title
= 0;
1254 if (!fwin
->titlebar
) {
1255 fwin
->flags
.incomplete_title
= 1;
1258 width
= fwin
->titlebar
->width
- 6 - 6;
1261 if (!wPreferences
.new_style
== TS_NEW
) {
1262 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1263 width
-= fwin
->left_button
->width
+ 3;
1265 #ifdef XKB_BUTTON_HINT
1266 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1267 && !fwin
->flags
.languagebutton_dont_fit
)
1268 width
-= fwin
->language_button
->width
+ 3;
1271 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1272 width
-= fwin
->right_button
->width
+ 3;
1274 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
) {
1275 fwin
->flags
.incomplete_title
= 1;
1277 fwin
->flags
.incomplete_title
= 0;
1281 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1283 WScreen
*scr
= button
->screen_ptr
;
1284 GC copy_gc
= scr
->copy_gc
;
1285 int x
= 0, y
= 0, d
= 0;
1286 int left
= 0, width
= 0;
1288 /* setup stuff according to the state */
1291 if (image
->width
>= image
->height
* 2) {
1292 /* the image contains 2 pictures: the second is for the
1294 width
= image
->width
/ 2;
1295 left
= image
->width
/ 2;
1297 width
= image
->width
;
1300 XSetClipMask(dpy
, copy_gc
, None
);
1301 if (wPreferences
.new_style
== TS_NEXT
) {
1302 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1304 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1307 if (wPreferences
.new_style
== TS_NEW
) {
1308 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1309 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1310 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1311 } else if (wPreferences
.new_style
== TS_OLD
) {
1312 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1313 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1314 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1316 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1317 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1318 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1321 XClearWindow(dpy
, button
->window
);
1324 if (image
->width
>= image
->height
* 2)
1325 width
= image
->width
/ 2;
1327 width
= image
->width
;
1331 if (wPreferences
.new_style
== TS_NEW
) {
1332 if (texture
->any
.type
== WTEX_SOLID
|| pushed
) {
1333 wDrawBevel(button
->window
, button
->width
, button
->height
,
1334 (WTexSolid
*) texture
, WREL_RAISED
);
1337 wDrawBevel(button
->window
, button
->width
, button
->height
,
1338 scr
->widget_texture
, WREL_RAISED
);
1344 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1345 x
= (button
->width
- width
) / 2 + d
;
1346 y
= (button
->height
- image
->height
) / 2 + d
;
1347 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1348 if (!wPreferences
.new_style
== TS_NEW
) {
1349 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1351 if (image
->depth
== 1)
1352 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1353 left
, 0, width
, image
->height
, x
, y
, 1);
1355 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1356 left
, 0, width
, image
->height
, x
, y
);
1358 if (wPreferences
.new_style
== TS_OLD
) {
1359 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1360 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1361 button
->width
, button
->height
);
1363 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1364 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1365 left
, 0, width
, image
->height
, x
, y
);
1370 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1372 XSetForeground(dpy
, copy_gc
, color
);
1373 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1375 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1380 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1382 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1383 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1385 #ifdef XKB_BUTTON_HINT
1386 if (button
== fwin
->language_button
) {
1387 if (wPreferences
.modelock
) {
1388 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1389 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1390 fwin
->languagebutton_image
, False
);
1394 if (button
== fwin
->left_button
) {
1395 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1396 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1398 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1399 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1403 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1405 WFrameWindow
*fwin
= desc
->parent
;
1406 WCoreWindow
*titlebar
= desc
->self
;
1408 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1409 if (fwin
->on_dblclick_titlebar
) {
1410 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1413 if (fwin
->on_mousedown_titlebar
) {
1414 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1419 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1421 WFrameWindow
*fwin
= desc
->parent
;
1422 WCoreWindow
*resizebar
= desc
->self
;
1424 if (fwin
->on_mousedown_resizebar
)
1425 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1428 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1430 WFrameWindow
*fwin
= desc
->parent
;
1431 WCoreWindow
*button
= desc
->self
;
1434 int done
= 0, execute
= 1;
1436 unsigned long pixel
;
1437 int clickButton
= event
->xbutton
.button
;
1439 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1440 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
) {
1441 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1446 if (button
== fwin
->left_button
) {
1447 image
= fwin
->lbutton_image
;
1449 image
= fwin
->rbutton_image
;
1451 #ifdef XKB_BUTTON_HINT
1452 if (button
== fwin
->language_button
) {
1453 if (!wPreferences
.modelock
)
1455 image
= fwin
->languagebutton_image
;
1459 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1460 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1461 paintButton(button
, texture
, pixel
, image
, True
);
1464 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1465 | ButtonPressMask
| ExposureMask
, &ev
);
1469 paintButton(button
, texture
, pixel
, image
, False
);
1474 paintButton(button
, texture
, pixel
, image
, True
);
1481 if (ev
.xbutton
.button
== clickButton
)
1489 paintButton(button
, texture
, pixel
, image
, False
);
1492 if (button
== fwin
->left_button
) {
1493 if (fwin
->on_click_left
)
1494 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1495 } else if (button
== fwin
->right_button
) {
1496 if (fwin
->on_click_right
)
1497 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1499 #ifdef XKB_BUTTON_HINT
1500 else if (button
== fwin
->language_button
) {
1501 if (fwin
->on_click_language
)
1502 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);