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
,
66 int depth
, Visual
*visual
, Colormap colormap
)
70 fwin
= wmalloc(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
;
89 fwin
->visual
= visual
;
90 fwin
->colormap
= colormap
;
92 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
93 ? FRAME_BORDER_WIDTH
: 0, fwin
->depth
, fwin
->visual
, fwin
->colormap
);
94 if (wPreferences
.use_saveunders
) {
96 XSetWindowAttributes attribs
;
99 attribs
.save_under
= True
;
100 XChangeWindowAttributes(dpy
, fwin
->core
->window
, vmask
, &attribs
);
103 /* setup stacking information */
104 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
105 fwin
->core
->stacking
->above
= NULL
;
106 fwin
->core
->stacking
->under
= NULL
;
107 fwin
->core
->stacking
->child_of
= NULL
;
108 fwin
->core
->stacking
->window_level
= wlevel
;
110 AddToStackList(fwin
->core
);
112 wFrameWindowUpdateBorders(fwin
, flags
);
117 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
123 WScreen
*scr
= fwin
->screen_ptr
;
125 width
= fwin
->core
->width
;
126 if (flags
& WFF_IS_SHADED
)
129 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
131 if (flags
& WFF_TITLEBAR
) {
132 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
134 if (theight
> *fwin
->title_max_height
)
135 theight
= *fwin
->title_max_height
;
137 if (theight
< *fwin
->title_min_height
)
138 theight
= *fwin
->title_min_height
;
142 if (wPreferences
.new_style
== TS_NEW
) {
144 } else if (wPreferences
.new_style
== TS_OLD
) {
150 if (fwin
->titlebar
) {
151 /* if we had a titlebar and is requesting for one,
152 * check if the size has changed and resize it */
153 if (flags
& WFF_TITLEBAR
) {
154 fwin
->top_width
= theight
;
156 fwin
->flags
.need_texture_remake
= 1;
158 if (wPreferences
.new_style
== TS_NEW
) {
159 if (fwin
->left_button
) {
160 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
162 #ifdef XKB_BUTTON_HINT
163 if (fwin
->language_button
) {
164 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
165 || fwin
->flags
.lbutton_dont_fit
) {
166 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
168 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
173 if (fwin
->right_button
) {
174 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
176 } else { /* !new_style */
177 if (fwin
->left_button
) {
178 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
180 #ifdef XKB_BUTTON_HINT
181 if (fwin
->language_button
) {
182 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
187 if (fwin
->right_button
) {
188 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
189 (theight
- bsize
) / 2, bsize
, bsize
);
192 updateTitlebar(fwin
);
194 /* we had a titlebar, but now we don't need it anymore */
195 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
196 FREE_PIXMAP(fwin
->title_back
[i
]);
197 if (wPreferences
.new_style
== TS_NEW
) {
198 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
199 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
200 #ifdef XKB_BUTTON_HINT
201 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
205 if (fwin
->left_button
)
206 wCoreDestroy(fwin
->left_button
);
207 fwin
->left_button
= NULL
;
209 #ifdef XKB_BUTTON_HINT
210 if (fwin
->language_button
)
211 wCoreDestroy(fwin
->language_button
);
212 fwin
->language_button
= NULL
;
215 if (fwin
->right_button
)
216 wCoreDestroy(fwin
->right_button
);
217 fwin
->right_button
= NULL
;
219 wCoreDestroy(fwin
->titlebar
);
220 fwin
->titlebar
= NULL
;
225 /* if we didn't have a titlebar and are being requested for
227 if (flags
& WFF_TITLEBAR
) {
228 fwin
->top_width
= theight
;
230 fwin
->flags
.titlebar
= 1;
231 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
233 if (flags
& WFF_LEFT_BUTTON
) {
234 fwin
->flags
.left_button
= 1;
235 if (wPreferences
.new_style
== TS_NEW
) {
236 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
237 if (width
< theight
* 4) {
238 fwin
->flags
.lbutton_dont_fit
= 1;
240 XMapRaised(dpy
, fwin
->left_button
->window
);
242 } else if (wPreferences
.new_style
== TS_OLD
) {
244 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
246 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
247 scr
->widget_texture
->normal
.pixel
);
249 if (width
< theight
* 3) {
250 fwin
->flags
.lbutton_dont_fit
= 1;
252 XMapRaised(dpy
, fwin
->left_button
->window
);
256 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
259 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
260 scr
->widget_texture
->dark
.pixel
);
262 if (width
< theight
*3) {
263 fwin
->flags
.lbutton_dont_fit
= 1;
265 XMapRaised(dpy
, fwin
->left_button
->window
);
269 #ifdef XKB_BUTTON_HINT
270 if (flags
& WFF_LANGUAGE_BUTTON
) {
271 fwin
->flags
.language_button
= 1;
272 if (wPreferences
.new_style
== TS_NEW
) {
273 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
275 if (width
< theight
* 4) {
276 fwin
->flags
.languagebutton_dont_fit
= 1;
278 XMapRaised(dpy
, fwin
->language_button
->window
);
281 fwin
->language_button
=
282 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
285 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
286 scr
->widget_texture
->normal
.pixel
);
288 if (width
< theight
* 3) {
289 fwin
->flags
.languagebutton_dont_fit
= 1;
291 XMapRaised(dpy
, fwin
->language_button
->window
);
297 if (flags
& WFF_RIGHT_BUTTON
) {
298 fwin
->flags
.right_button
= 1;
299 if (wPreferences
.new_style
== TS_NEW
) {
301 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
302 } else if (wPreferences
.new_style
== TS_OLD
) {
304 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
305 (theight
- bsize
) / 2, bsize
, bsize
);
306 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
307 scr
->widget_texture
->normal
.pixel
);
310 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
311 (theight
-bsize
)/2, bsize
, bsize
);
312 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
313 scr
->widget_texture
->dark
.pixel
);
316 if (width
< theight
* 2) {
317 fwin
->flags
.rbutton_dont_fit
= 1;
319 XMapRaised(dpy
, fwin
->right_button
->window
);
323 if (wPreferences
.new_style
== TS_NEW
)
324 updateTitlebar(fwin
);
326 XMapRaised(dpy
, fwin
->titlebar
->window
);
328 fwin
->flags
.need_texture_remake
= 1;
331 checkTitleSize(fwin
);
333 if (flags
& WFF_RESIZEBAR
) {
334 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
336 if (!fwin
->resizebar
) {
337 fwin
->flags
.resizebar
= 1;
338 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
339 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
340 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
341 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
342 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
343 if (fwin
->resizebar_corner_width
< 0)
344 fwin
->resizebar_corner_width
= 0;
347 XMapWindow(dpy
, fwin
->resizebar
->window
);
348 XLowerWindow(dpy
, fwin
->resizebar
->window
);
350 fwin
->flags
.need_texture_remake
= 1;
352 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
) {
353 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
354 width
, RESIZEBAR_HEIGHT
);
358 fwin
->bottom_width
= 0;
360 if (fwin
->resizebar
) {
361 fwin
->bottom_width
= 0;
362 wCoreDestroy(fwin
->resizebar
);
363 fwin
->resizebar
= NULL
;
367 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
)) {
368 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
371 if (flags
& WFF_BORDER
) {
372 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
374 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
377 /* setup object descriptors */
379 if (fwin
->titlebar
) {
380 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
381 fwin
->titlebar
->descriptor
.parent
= fwin
;
382 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
383 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
386 if (fwin
->resizebar
) {
387 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
388 fwin
->resizebar
->descriptor
.parent
= fwin
;
389 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
390 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
393 if (fwin
->left_button
) {
394 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
395 fwin
->left_button
->descriptor
.parent
= fwin
;
396 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
397 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
399 #ifdef XKB_BUTTON_HINT
400 if (fwin
->language_button
) {
401 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
402 fwin
->language_button
->descriptor
.parent
= fwin
;
403 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
404 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
408 if (fwin
->right_button
) {
409 fwin
->right_button
->descriptor
.parent
= fwin
;
410 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
411 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
412 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
415 checkTitleSize(fwin
);
418 void wFrameWindowDestroy(WFrameWindow
* fwin
)
422 if (fwin
->left_button
)
423 wCoreDestroy(fwin
->left_button
);
425 #ifdef XKB_BUTTON_HINT
426 if (fwin
->language_button
)
427 wCoreDestroy(fwin
->language_button
);
430 if (fwin
->right_button
)
431 wCoreDestroy(fwin
->right_button
);
434 wCoreDestroy(fwin
->resizebar
);
437 wCoreDestroy(fwin
->titlebar
);
439 RemoveFromStackList(fwin
->core
);
441 wCoreDestroy(fwin
->core
);
446 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
447 FREE_PIXMAP(fwin
->title_back
[i
]);
448 if (wPreferences
.new_style
== TS_NEW
) {
449 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
450 #ifdef XKB_BUTTON_HINT
451 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
453 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
460 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
462 if (fwin
->flags
.state
== state
)
465 fwin
->flags
.state
= state
;
466 fwin
->flags
.need_texture_change
= 1;
468 wFrameWindowPaint(fwin
);
471 static void updateTitlebar(WFrameWindow
* fwin
)
476 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
478 if (theight
> *fwin
->title_max_height
)
479 theight
= *fwin
->title_max_height
;
481 if (theight
< *fwin
->title_min_height
)
482 theight
= *fwin
->title_min_height
;
485 w
= fwin
->core
->width
+ 1;
487 if (wPreferences
.new_style
== TS_NEW
) {
488 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
490 #ifdef XKB_BUTTON_HINT
491 if (fwin
->language_button
)
492 wCoreConfigure(fwin
->language_button
, 0, 0,
493 fwin
->language_button
->width
, fwin
->language_button
->width
);
496 #ifdef XKB_BUTTON_HINT
497 if (fwin
->language_button
)
498 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
499 fwin
->language_button
->width
, fwin
->language_button
->width
);
501 x
= fwin
->left_button
->width
;
502 w
-= fwin
->left_button
->width
;
504 #ifdef XKB_BUTTON_HINT
505 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
506 || fwin
->flags
.languagebutton_dont_fit
) {
508 x
+= fwin
->language_button
->width
;
509 w
-= fwin
->language_button
->width
;
513 #ifdef XKB_BUTTON_HINT
515 int bsize
= theight
- 7;
516 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
517 if (fwin
->language_button
)
518 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
519 fwin
->language_button
->width
, fwin
->language_button
->width
);
521 if (fwin
->language_button
)
522 wCoreConfigure(fwin
->language_button
,
523 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
524 fwin
->language_button
->width
, fwin
->language_button
->width
);
529 if (wPreferences
.new_style
== TS_NEW
) {
530 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
) {
531 w
-= fwin
->right_button
->width
;
535 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
536 fwin
->flags
.need_texture_remake
= 1;
538 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
541 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
543 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
544 XUnmapWindow(dpy
, fwin
->right_button
->window
);
545 fwin
->flags
.hide_right_button
= 1;
548 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
549 XUnmapWindow(dpy
, fwin
->left_button
->window
);
550 fwin
->flags
.hide_left_button
= 1;
552 #ifdef XKB_BUTTON_HINT
553 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
554 XUnmapWindow(dpy
, fwin
->language_button
->window
);
555 fwin
->flags
.hide_language_button
= 1;
559 if (fwin
->titlebar
) {
560 if (wPreferences
.new_style
== TS_NEW
) {
561 updateTitlebar(fwin
);
563 #ifdef XKB_BUTTON_HINT
564 updateTitlebar(fwin
);
566 XClearWindow(dpy
, fwin
->titlebar
->window
);
567 wFrameWindowPaint(fwin
);
570 checkTitleSize(fwin
);
574 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
576 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
578 if (!fwin
->flags
.rbutton_dont_fit
)
579 XMapWindow(dpy
, fwin
->right_button
->window
);
581 fwin
->flags
.hide_right_button
= 0;
583 #ifdef XKB_BUTTON_HINT
584 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
586 if (!fwin
->flags
.languagebutton_dont_fit
)
587 XMapWindow(dpy
, fwin
->language_button
->window
);
589 fwin
->flags
.hide_language_button
= 0;
593 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
595 if (!fwin
->flags
.lbutton_dont_fit
)
596 XMapWindow(dpy
, fwin
->left_button
->window
);
598 fwin
->flags
.hide_left_button
= 0;
601 if (fwin
->titlebar
) {
602 if (wPreferences
.new_style
== TS_NEW
) {
603 updateTitlebar(fwin
);
605 XClearWindow(dpy
, fwin
->titlebar
->window
);
606 wFrameWindowPaint(fwin
);
608 checkTitleSize(fwin
);
613 #ifdef XKB_BUTTON_HINT
614 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
615 int bwidth
, int bheight
, int left
, int language
, int right
,
616 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
618 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
619 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
623 RImage
*limg
, *rimg
, *mimg
;
624 #ifdef XKB_BUTTON_HINT
632 #ifdef XKB_BUTTON_HINT
633 *languagebutton
= None
;
636 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
638 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
642 if (wPreferences
.new_style
== TS_NEW
) {
644 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
651 #ifdef XKB_BUTTON_HINT
653 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
659 RBevelImage(limg
, RBEV_RAISED2
);
660 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
)) {
661 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
667 #ifdef XKB_BUTTON_HINT
669 RBevelImage(timg
, RBEV_RAISED2
);
670 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
)) {
671 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
680 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
685 RBevelImage(rimg
, RBEV_RAISED2
);
686 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
)) {
687 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
694 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
695 RBevelImage(mimg
, RBEV_RAISED2
);
697 if (!RConvertImage(scr
->rcontext
, mimg
, title
)) {
698 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
702 RBevelImage(img
, RBEV_RAISED2
);
704 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
705 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
709 RBevelImage(img
, RBEV_RAISED2
);
711 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
712 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
720 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
728 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
730 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
735 light
.red
= light
.green
= light
.blue
= 80;
738 dark
.red
= dark
.green
= dark
.blue
= 40;
740 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
741 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
743 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
744 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
747 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
748 width
- cwidth
- 2, height
- 1, &dark
);
749 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
751 #ifdef SHADOW_RESIZEBAR
752 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
753 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
754 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
755 #endif /* SHADOW_RESIZEBAR */
757 if (!RConvertImage(scr
->rcontext
, img
, pmap
)) {
758 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
764 static void updateTexture(WFrameWindow
* fwin
)
769 i
= fwin
->flags
.state
;
770 if (fwin
->titlebar
) {
771 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
772 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
773 if (wPreferences
.new_style
== TS_NEW
) {
774 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
775 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
776 fwin
->lbutton_back
[i
]);
778 #ifdef XKB_BUTTON_HINT
779 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
]) {
780 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
781 fwin
->languagebutton_back
[i
]);
785 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
786 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
787 fwin
->rbutton_back
[i
]);
790 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
791 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
792 if (wPreferences
.new_style
== TS_NEW
) {
793 if (fwin
->left_button
)
794 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
795 #ifdef XKB_BUTTON_HINT
796 if (fwin
->language_button
)
797 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
799 if (fwin
->right_button
)
800 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
803 XClearWindow(dpy
, fwin
->titlebar
->window
);
805 if (fwin
->left_button
) {
806 XClearWindow(dpy
, fwin
->left_button
->window
);
807 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
809 #ifdef XKB_BUTTON_HINT
810 if (fwin
->language_button
) {
811 XClearWindow(dpy
, fwin
->language_button
->window
);
812 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
815 if (fwin
->right_button
) {
816 XClearWindow(dpy
, fwin
->right_button
->window
);
817 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
822 static void remakeTexture(WFrameWindow
* fwin
, int state
)
824 Pixmap pmap
, lpmap
, rpmap
;
825 #ifdef XKB_BUTTON_HINT
829 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
830 FREE_PIXMAP(fwin
->title_back
[state
]);
831 if (wPreferences
.new_style
== TS_NEW
) {
832 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
833 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
834 #ifdef XKB_BUTTON_HINT
835 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
839 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
842 #ifdef XKB_BUTTON_HINT
846 /* eventually surrounded by if new_style */
847 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
848 #ifdef XKB_BUTTON_HINT
849 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
850 && !fwin
->flags
.languagebutton_dont_fit
;
852 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
853 && !fwin
->flags
.rbutton_dont_fit
;
855 width
= fwin
->core
->width
+ 1;
857 #ifdef XKB_BUTTON_HINT
858 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
859 width
, fwin
->titlebar
->height
,
860 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
861 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
863 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
864 width
, fwin
->titlebar
->height
,
865 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
866 left
, right
, &pmap
, &lpmap
, &rpmap
);
869 fwin
->title_back
[state
] = pmap
;
870 if (wPreferences
.new_style
== TS_NEW
) {
871 fwin
->lbutton_back
[state
] = lpmap
;
872 fwin
->rbutton_back
[state
] = rpmap
;
873 #ifdef XKB_BUTTON_HINT
874 fwin
->languagebutton_back
[state
] = tpmap
;
879 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
880 && fwin
->resizebar
&& state
== 0) {
882 FREE_PIXMAP(fwin
->resizebar_back
[0]);
884 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
886 renderResizebarTexture(fwin
->screen_ptr
,
887 fwin
->resizebar_texture
[0],
888 fwin
->resizebar
->width
,
889 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
891 fwin
->resizebar_back
[0] = pmap
;
894 /* this part should be in updateTexture() */
895 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
896 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
898 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
899 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
901 XClearWindow(dpy
, fwin
->resizebar
->window
);
905 void wFrameWindowPaint(WFrameWindow
* fwin
)
907 WScreen
*scr
= fwin
->screen_ptr
;
910 state
= fwin
->flags
.state
;
912 if (fwin
->flags
.is_client_window_frame
)
913 fwin
->flags
.justification
= wPreferences
.title_justification
;
915 if (fwin
->flags
.need_texture_remake
) {
918 fwin
->flags
.need_texture_remake
= 0;
919 fwin
->flags
.need_texture_change
= 0;
921 if (fwin
->flags
.single_texture
) {
922 remakeTexture(fwin
, 0);
925 /* first render the texture for the current state... */
926 remakeTexture(fwin
, state
);
927 /* ... and paint it */
930 for (i
= 0; i
< 3; i
++) {
932 remakeTexture(fwin
, i
);
938 if (fwin
->flags
.need_texture_change
) {
939 fwin
->flags
.need_texture_change
= 0;
944 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
945 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
946 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
947 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
950 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
951 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
956 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
958 w
= fwin
->resizebar
->width
;
959 h
= fwin
->resizebar
->height
;
960 cw
= fwin
->resizebar_corner_width
;
961 light_gc
= texture
->light_gc
;
962 dim_gc
= texture
->dim_gc
;
963 win
= fwin
->resizebar
->window
;
965 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
966 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
968 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
969 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
971 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
972 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
974 #ifdef SHADOW_RESIZEBAR
975 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
976 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
977 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
978 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
979 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
980 #endif /* SHADOW_RESIZEBAR */
983 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
985 int lofs
= 6, rofs
= 6;
989 if (!wPreferences
.new_style
== TS_NEW
) {
990 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
991 lofs
+= fwin
->left_button
->width
+ 3;
995 #ifdef XKB_BUTTON_HINT
996 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
997 && !fwin
->flags
.languagebutton_dont_fit
)
998 lofs
+= fwin
->language_button
->width
;
1003 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1004 rofs
+= fwin
->right_button
->width
+ 3;
1008 #ifdef XKB_BUTTON_HINT
1009 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1016 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
1017 titlelen
= strlen(title
);
1018 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1020 switch (fwin
->flags
.justification
) {
1026 x
= fwin
->titlebar
->width
- w
- rofs
;
1031 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1033 x
= (fwin
->titlebar
->width
- w
) / 2;
1037 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1038 h
= WMFontHeight(*fwin
->font
);
1040 if (y
*2 + h
> *fwin
->title_max_height
)
1041 y
= (*fwin
->title_max_height
- h
) / 2;
1043 if (y
*2 + h
< *fwin
->title_min_height
)
1044 y
= (*fwin
->title_min_height
- h
) / 2;
1046 /* We use a w+2 buffer to have an extra pixel on the left and
1047 * another one on the right. This is because for some odd reason,
1048 * sometimes when using AA fonts (when libfreetype2 is compiled
1049 * with bytecode interpreter turned off), some fonts are drawn
1050 * starting from x = -1 not from 0 as requested. Observed with
1051 * capital A letter on the bold 'trebuchet ms' font. -Dan
1053 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1055 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1057 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1058 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1059 x
- 1, y
, w
+ 2, h
, 0, 0);
1061 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1062 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1065 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1066 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1067 *fwin
->font
, 1, 0, title
, titlelen
);
1069 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1071 XFreePixmap(dpy
, buf
);
1076 if (fwin
->left_button
)
1077 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1078 if (fwin
->right_button
)
1079 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1080 #ifdef XKB_BUTTON_HINT
1081 if (fwin
->language_button
)
1082 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1087 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1089 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1090 int resizedHorizontally
= 0;
1093 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1095 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1098 if (fwin->core->height != height && fwin->resizebar)
1099 XMoveWindow(dpy, fwin->resizebar->window, 0,
1100 height - fwin->resizebar->height);
1102 if (fwin
->core
->width
!= width
) {
1103 fwin
->flags
.need_texture_remake
= 1;
1104 resizedHorizontally
= 1;
1107 fwin
->core
->width
= width
;
1108 fwin
->core
->height
= height
;
1110 if (fwin
->titlebar
&& resizedHorizontally
) {
1111 /* Check if the titlebar is wide enough to hold the buttons.
1112 * Temporarily remove them if can't
1114 if (fwin
->left_button
) {
1115 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1117 if (!fwin
->flags
.hide_left_button
) {
1118 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1120 fwin
->flags
.lbutton_dont_fit
= 1;
1121 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1123 if (!fwin
->flags
.hide_left_button
) {
1124 XMapWindow(dpy
, fwin
->left_button
->window
);
1126 fwin
->flags
.lbutton_dont_fit
= 0;
1129 #ifdef XKB_BUTTON_HINT
1130 if (fwin
->language_button
) {
1131 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1133 if (!fwin
->flags
.hide_language_button
) {
1134 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1136 fwin
->flags
.languagebutton_dont_fit
= 1;
1137 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1139 if (!fwin
->flags
.hide_language_button
) {
1140 XMapWindow(dpy
, fwin
->language_button
->window
);
1142 fwin
->flags
.languagebutton_dont_fit
= 0;
1147 if (fwin
->right_button
) {
1148 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1150 if (!fwin
->flags
.hide_right_button
) {
1151 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1153 fwin
->flags
.rbutton_dont_fit
= 1;
1154 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1156 if (!fwin
->flags
.hide_right_button
) {
1157 XMapWindow(dpy
, fwin
->right_button
->window
);
1159 fwin
->flags
.rbutton_dont_fit
= 0;
1163 if (wPreferences
.new_style
== TS_NEW
) {
1164 if (fwin
->right_button
)
1165 XMoveWindow(dpy
, fwin
->right_button
->window
,
1166 width
- fwin
->right_button
->width
+ 1, 0);
1168 if (fwin
->right_button
)
1169 XMoveWindow(dpy
, fwin
->right_button
->window
,
1170 width
- fwin
->right_button
->width
- 3,
1171 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1173 updateTitlebar(fwin
);
1174 checkTitleSize(fwin
);
1177 if (fwin
->resizebar
) {
1178 wCoreConfigure(fwin
->resizebar
, 0,
1179 fwin
->core
->height
- fwin
->resizebar
->height
,
1180 fwin
->core
->width
, fwin
->resizebar
->height
);
1182 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1183 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
1184 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1189 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1191 reconfigure(fwin
, x
, y
, width
, height
, False
);
1194 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1196 reconfigure(fwin
, 0, 0, width
, height
, True
);
1199 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1201 /* check if the title is the same as before */
1203 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0)) {
1214 fwin
->title
= wstrdup(new_title
);
1216 if (fwin
->titlebar
) {
1217 XClearWindow(dpy
, fwin
->titlebar
->window
);
1219 wFrameWindowPaint(fwin
);
1221 checkTitleSize(fwin
);
1226 #ifdef XKB_BUTTON_HINT
1227 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1229 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1230 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1232 #endif /* XKB_BUTTON_HINT */
1234 /*********************************************************************/
1236 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1238 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1240 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1241 fwin
->flags
.repaint_only_titlebar
= 1;
1242 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1243 fwin
->flags
.repaint_only_resizebar
= 1;
1244 wFrameWindowPaint(fwin
);
1245 fwin
->flags
.repaint_only_titlebar
= 0;
1246 fwin
->flags
.repaint_only_resizebar
= 0;
1249 static void checkTitleSize(WFrameWindow
* fwin
)
1254 fwin
->flags
.incomplete_title
= 0;
1258 if (!fwin
->titlebar
) {
1259 fwin
->flags
.incomplete_title
= 1;
1262 width
= fwin
->titlebar
->width
- 6 - 6;
1265 if (!wPreferences
.new_style
== TS_NEW
) {
1266 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1267 width
-= fwin
->left_button
->width
+ 3;
1269 #ifdef XKB_BUTTON_HINT
1270 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1271 && !fwin
->flags
.languagebutton_dont_fit
)
1272 width
-= fwin
->language_button
->width
+ 3;
1275 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1276 width
-= fwin
->right_button
->width
+ 3;
1278 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
) {
1279 fwin
->flags
.incomplete_title
= 1;
1281 fwin
->flags
.incomplete_title
= 0;
1285 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1287 WScreen
*scr
= button
->screen_ptr
;
1288 GC copy_gc
= scr
->copy_gc
;
1289 int x
= 0, y
= 0, d
= 0;
1290 int left
= 0, width
= 0;
1292 /* setup stuff according to the state */
1295 if (image
->width
>= image
->height
* 2) {
1296 /* the image contains 2 pictures: the second is for the
1298 width
= image
->width
/ 2;
1299 left
= image
->width
/ 2;
1301 width
= image
->width
;
1304 XSetClipMask(dpy
, copy_gc
, None
);
1305 if (wPreferences
.new_style
== TS_NEXT
) {
1306 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1308 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1311 if (wPreferences
.new_style
== TS_NEW
) {
1312 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1313 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1314 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1315 } else if (wPreferences
.new_style
== TS_OLD
) {
1316 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1317 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1318 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1320 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1321 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1322 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1325 XClearWindow(dpy
, button
->window
);
1328 if (image
->width
>= image
->height
* 2)
1329 width
= image
->width
/ 2;
1331 width
= image
->width
;
1335 if (wPreferences
.new_style
== TS_NEW
) {
1336 if (texture
->any
.type
== WTEX_SOLID
|| pushed
) {
1337 wDrawBevel(button
->window
, button
->width
, button
->height
,
1338 (WTexSolid
*) texture
, WREL_RAISED
);
1341 wDrawBevel(button
->window
, button
->width
, button
->height
,
1342 scr
->widget_texture
, WREL_RAISED
);
1348 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1349 x
= (button
->width
- width
) / 2 + d
;
1350 y
= (button
->height
- image
->height
) / 2 + d
;
1351 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1352 if (!wPreferences
.new_style
== TS_NEW
) {
1353 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1355 if (image
->depth
== 1)
1356 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1357 left
, 0, width
, image
->height
, x
, y
, 1);
1359 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1360 left
, 0, width
, image
->height
, x
, y
);
1362 if (wPreferences
.new_style
== TS_OLD
) {
1363 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1364 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1365 button
->width
, button
->height
);
1367 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1368 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1369 left
, 0, width
, image
->height
, x
, y
);
1374 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1376 XSetForeground(dpy
, copy_gc
, color
);
1377 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1379 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1384 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1386 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1387 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1389 #ifdef XKB_BUTTON_HINT
1390 if (button
== fwin
->language_button
) {
1391 if (wPreferences
.modelock
) {
1392 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1393 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1394 fwin
->languagebutton_image
, False
);
1398 if (button
== fwin
->left_button
) {
1399 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1400 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1402 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1403 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1407 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1409 WFrameWindow
*fwin
= desc
->parent
;
1410 WCoreWindow
*titlebar
= desc
->self
;
1412 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1413 if (fwin
->on_dblclick_titlebar
) {
1414 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1417 if (fwin
->on_mousedown_titlebar
) {
1418 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1423 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1425 WFrameWindow
*fwin
= desc
->parent
;
1426 WCoreWindow
*resizebar
= desc
->self
;
1428 if (fwin
->on_mousedown_resizebar
)
1429 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1432 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1434 WFrameWindow
*fwin
= desc
->parent
;
1435 WCoreWindow
*button
= desc
->self
;
1438 int done
= 0, execute
= 1;
1440 unsigned long pixel
;
1441 int clickButton
= event
->xbutton
.button
;
1443 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1444 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
) {
1445 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1450 if (button
== fwin
->left_button
) {
1451 image
= fwin
->lbutton_image
;
1453 image
= fwin
->rbutton_image
;
1455 #ifdef XKB_BUTTON_HINT
1456 if (button
== fwin
->language_button
) {
1457 if (!wPreferences
.modelock
)
1459 image
= fwin
->languagebutton_image
;
1463 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1464 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1465 paintButton(button
, texture
, pixel
, image
, True
);
1468 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1469 | ButtonPressMask
| ExposureMask
, &ev
);
1473 paintButton(button
, texture
, pixel
, image
, False
);
1478 paintButton(button
, texture
, pixel
, image
, True
);
1485 if (ev
.xbutton
.button
== clickButton
)
1493 paintButton(button
, texture
, pixel
, image
, False
);
1496 if (button
== fwin
->left_button
) {
1497 if (fwin
->on_click_left
)
1498 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1499 } else if (button
== fwin
->right_button
) {
1500 if (fwin
->on_click_right
)
1501 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1503 #ifdef XKB_BUTTON_HINT
1504 else if (button
== fwin
->language_button
) {
1505 if (fwin
->on_click_language
)
1506 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);