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
));
71 fwin
->screen_ptr
= scr
;
73 fwin
->flags
.single_texture
= (flags
& WFF_SINGLE_STATE
) ? 1 : 0;
75 fwin
->title_texture
= title_texture
;
76 fwin
->resizebar_texture
= resize_texture
;
77 fwin
->title_color
= color
;
78 fwin
->title_clearance
= clearance
;
79 fwin
->title_min_height
= title_min
;
80 fwin
->title_max_height
= title_max
;
82 #ifdef KEEP_XKB_LOCK_STATUS
83 fwin
->languagemode
= XkbGroup1Index
;
84 fwin
->last_languagemode
= XkbGroup2Index
;
87 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
88 ? FRAME_BORDER_WIDTH
: 0);
89 if (wPreferences
.use_saveunders
) {
91 XSetWindowAttributes attribs
;
94 attribs
.save_under
= True
;
95 XChangeWindowAttributes(dpy
, fwin
->core
->window
, vmask
, &attribs
);
98 /* setup stacking information */
99 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
100 fwin
->core
->stacking
->above
= NULL
;
101 fwin
->core
->stacking
->under
= NULL
;
102 fwin
->core
->stacking
->child_of
= NULL
;
103 fwin
->core
->stacking
->window_level
= wlevel
;
105 AddToStackList(fwin
->core
);
107 wFrameWindowUpdateBorders(fwin
, flags
);
112 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
118 WScreen
*scr
= fwin
->screen_ptr
;
120 width
= fwin
->core
->width
;
121 if (flags
& WFF_IS_SHADED
)
124 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
126 if (flags
& WFF_TITLEBAR
) {
127 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
129 if (theight
> *fwin
->title_max_height
)
130 theight
= *fwin
->title_max_height
;
132 if (theight
< *fwin
->title_min_height
)
133 theight
= *fwin
->title_min_height
;
137 if (wPreferences
.new_style
== TS_NEW
) {
139 } else if (wPreferences
.new_style
== TS_OLD
) {
145 if (fwin
->titlebar
) {
146 /* if we had a titlebar and is requesting for one,
147 * check if the size has changed and resize it */
148 if (flags
& WFF_TITLEBAR
) {
149 fwin
->top_width
= theight
;
151 fwin
->flags
.need_texture_remake
= 1;
153 if (wPreferences
.new_style
== TS_NEW
) {
154 if (fwin
->left_button
) {
155 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
157 #ifdef XKB_BUTTON_HINT
158 if (fwin
->language_button
) {
159 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
160 || fwin
->flags
.lbutton_dont_fit
) {
161 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
163 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
168 if (fwin
->right_button
) {
169 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
171 } else { /* !new_style */
172 if (fwin
->left_button
) {
173 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
175 #ifdef XKB_BUTTON_HINT
176 if (fwin
->language_button
) {
177 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
182 if (fwin
->right_button
) {
183 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
184 (theight
- bsize
) / 2, bsize
, bsize
);
187 updateTitlebar(fwin
);
189 /* we had a titlebar, but now we don't need it anymore */
190 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
191 FREE_PIXMAP(fwin
->title_back
[i
]);
192 if (wPreferences
.new_style
== TS_NEW
) {
193 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
194 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
195 #ifdef XKB_BUTTON_HINT
196 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
200 if (fwin
->left_button
)
201 wCoreDestroy(fwin
->left_button
);
202 fwin
->left_button
= NULL
;
204 #ifdef XKB_BUTTON_HINT
205 if (fwin
->language_button
)
206 wCoreDestroy(fwin
->language_button
);
207 fwin
->language_button
= NULL
;
210 if (fwin
->right_button
)
211 wCoreDestroy(fwin
->right_button
);
212 fwin
->right_button
= NULL
;
214 wCoreDestroy(fwin
->titlebar
);
215 fwin
->titlebar
= NULL
;
220 /* if we didn't have a titlebar and are being requested for
222 if (flags
& WFF_TITLEBAR
) {
223 fwin
->top_width
= theight
;
225 fwin
->flags
.titlebar
= 1;
226 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
228 if (flags
& WFF_LEFT_BUTTON
) {
229 fwin
->flags
.left_button
= 1;
230 if (wPreferences
.new_style
== TS_NEW
) {
231 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
232 if (width
< theight
* 4) {
233 fwin
->flags
.lbutton_dont_fit
= 1;
235 XMapRaised(dpy
, fwin
->left_button
->window
);
237 } else if (wPreferences
.new_style
== TS_OLD
) {
239 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
241 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
242 scr
->widget_texture
->normal
.pixel
);
244 if (width
< theight
* 3) {
245 fwin
->flags
.lbutton_dont_fit
= 1;
247 XMapRaised(dpy
, fwin
->left_button
->window
);
251 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
254 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
255 scr
->widget_texture
->dark
.pixel
);
257 if (width
< theight
*3) {
258 fwin
->flags
.lbutton_dont_fit
= 1;
260 XMapRaised(dpy
, fwin
->left_button
->window
);
264 #ifdef XKB_BUTTON_HINT
265 if (flags
& WFF_LANGUAGE_BUTTON
) {
266 fwin
->flags
.language_button
= 1;
267 if (wPreferences
.new_style
== TS_NEW
) {
268 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
270 if (width
< theight
* 4) {
271 fwin
->flags
.languagebutton_dont_fit
= 1;
273 XMapRaised(dpy
, fwin
->language_button
->window
);
276 fwin
->language_button
=
277 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
280 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
281 scr
->widget_texture
->normal
.pixel
);
283 if (width
< theight
* 3) {
284 fwin
->flags
.languagebutton_dont_fit
= 1;
286 XMapRaised(dpy
, fwin
->language_button
->window
);
292 if (flags
& WFF_RIGHT_BUTTON
) {
293 fwin
->flags
.right_button
= 1;
294 if (wPreferences
.new_style
== TS_NEW
) {
296 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
297 } else if (wPreferences
.new_style
== TS_OLD
) {
299 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
300 (theight
- bsize
) / 2, bsize
, bsize
);
301 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
302 scr
->widget_texture
->normal
.pixel
);
305 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
306 (theight
-bsize
)/2, bsize
, bsize
);
307 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
308 scr
->widget_texture
->dark
.pixel
);
311 if (width
< theight
* 2) {
312 fwin
->flags
.rbutton_dont_fit
= 1;
314 XMapRaised(dpy
, fwin
->right_button
->window
);
318 if (wPreferences
.new_style
== TS_NEW
)
319 updateTitlebar(fwin
);
321 XMapRaised(dpy
, fwin
->titlebar
->window
);
323 fwin
->flags
.need_texture_remake
= 1;
326 checkTitleSize(fwin
);
328 if (flags
& WFF_RESIZEBAR
) {
329 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
331 if (!fwin
->resizebar
) {
332 fwin
->flags
.resizebar
= 1;
333 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
334 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
335 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
336 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
337 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
338 if (fwin
->resizebar_corner_width
< 0)
339 fwin
->resizebar_corner_width
= 0;
342 XMapWindow(dpy
, fwin
->resizebar
->window
);
343 XLowerWindow(dpy
, fwin
->resizebar
->window
);
345 fwin
->flags
.need_texture_remake
= 1;
347 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
) {
348 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
349 width
, RESIZEBAR_HEIGHT
);
353 fwin
->bottom_width
= 0;
355 if (fwin
->resizebar
) {
356 fwin
->bottom_width
= 0;
357 wCoreDestroy(fwin
->resizebar
);
358 fwin
->resizebar
= NULL
;
362 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
)) {
363 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
366 if (flags
& WFF_BORDER
) {
367 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
369 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
372 /* setup object descriptors */
374 if (fwin
->titlebar
) {
375 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
376 fwin
->titlebar
->descriptor
.parent
= fwin
;
377 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
378 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
381 if (fwin
->resizebar
) {
382 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
383 fwin
->resizebar
->descriptor
.parent
= fwin
;
384 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
385 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
388 if (fwin
->left_button
) {
389 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
390 fwin
->left_button
->descriptor
.parent
= fwin
;
391 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
392 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
394 #ifdef XKB_BUTTON_HINT
395 if (fwin
->language_button
) {
396 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
397 fwin
->language_button
->descriptor
.parent
= fwin
;
398 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
399 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
403 if (fwin
->right_button
) {
404 fwin
->right_button
->descriptor
.parent
= fwin
;
405 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
406 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
407 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
410 checkTitleSize(fwin
);
413 void wFrameWindowDestroy(WFrameWindow
* fwin
)
417 if (fwin
->left_button
)
418 wCoreDestroy(fwin
->left_button
);
420 #ifdef XKB_BUTTON_HINT
421 if (fwin
->language_button
)
422 wCoreDestroy(fwin
->language_button
);
425 if (fwin
->right_button
)
426 wCoreDestroy(fwin
->right_button
);
429 wCoreDestroy(fwin
->resizebar
);
432 wCoreDestroy(fwin
->titlebar
);
434 RemoveFromStackList(fwin
->core
);
436 wCoreDestroy(fwin
->core
);
441 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
442 FREE_PIXMAP(fwin
->title_back
[i
]);
443 if (wPreferences
.new_style
== TS_NEW
) {
444 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
445 #ifdef XKB_BUTTON_HINT
446 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
448 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
455 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
457 if (fwin
->flags
.state
== state
)
460 fwin
->flags
.state
= state
;
461 fwin
->flags
.need_texture_change
= 1;
463 wFrameWindowPaint(fwin
);
466 static void updateTitlebar(WFrameWindow
* fwin
)
471 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
473 if (theight
> *fwin
->title_max_height
)
474 theight
= *fwin
->title_max_height
;
476 if (theight
< *fwin
->title_min_height
)
477 theight
= *fwin
->title_min_height
;
480 w
= fwin
->core
->width
+ 1;
482 if (wPreferences
.new_style
== TS_NEW
) {
483 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
485 #ifdef XKB_BUTTON_HINT
486 if (fwin
->language_button
)
487 wCoreConfigure(fwin
->language_button
, 0, 0,
488 fwin
->language_button
->width
, fwin
->language_button
->width
);
491 #ifdef XKB_BUTTON_HINT
492 if (fwin
->language_button
)
493 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
494 fwin
->language_button
->width
, fwin
->language_button
->width
);
496 x
= fwin
->left_button
->width
;
497 w
-= fwin
->left_button
->width
;
499 #ifdef XKB_BUTTON_HINT
500 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
501 || fwin
->flags
.languagebutton_dont_fit
) {
503 x
+= fwin
->language_button
->width
;
504 w
-= fwin
->language_button
->width
;
508 #ifdef XKB_BUTTON_HINT
510 int bsize
= theight
- 7;
511 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
512 if (fwin
->language_button
)
513 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
514 fwin
->language_button
->width
, fwin
->language_button
->width
);
516 if (fwin
->language_button
)
517 wCoreConfigure(fwin
->language_button
,
518 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
519 fwin
->language_button
->width
, fwin
->language_button
->width
);
524 if (wPreferences
.new_style
== TS_NEW
) {
525 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
) {
526 w
-= fwin
->right_button
->width
;
530 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
531 fwin
->flags
.need_texture_remake
= 1;
533 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
536 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
538 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
539 XUnmapWindow(dpy
, fwin
->right_button
->window
);
540 fwin
->flags
.hide_right_button
= 1;
543 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
544 XUnmapWindow(dpy
, fwin
->left_button
->window
);
545 fwin
->flags
.hide_left_button
= 1;
547 #ifdef XKB_BUTTON_HINT
548 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
549 XUnmapWindow(dpy
, fwin
->language_button
->window
);
550 fwin
->flags
.hide_language_button
= 1;
554 if (fwin
->titlebar
) {
555 if (wPreferences
.new_style
== TS_NEW
) {
556 updateTitlebar(fwin
);
558 #ifdef XKB_BUTTON_HINT
559 updateTitlebar(fwin
);
561 XClearWindow(dpy
, fwin
->titlebar
->window
);
562 wFrameWindowPaint(fwin
);
565 checkTitleSize(fwin
);
569 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
571 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
573 if (!fwin
->flags
.rbutton_dont_fit
)
574 XMapWindow(dpy
, fwin
->right_button
->window
);
576 fwin
->flags
.hide_right_button
= 0;
578 #ifdef XKB_BUTTON_HINT
579 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
581 if (!fwin
->flags
.languagebutton_dont_fit
)
582 XMapWindow(dpy
, fwin
->language_button
->window
);
584 fwin
->flags
.hide_language_button
= 0;
588 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
590 if (!fwin
->flags
.lbutton_dont_fit
)
591 XMapWindow(dpy
, fwin
->left_button
->window
);
593 fwin
->flags
.hide_left_button
= 0;
596 if (fwin
->titlebar
) {
597 if (wPreferences
.new_style
== TS_NEW
) {
598 updateTitlebar(fwin
);
600 XClearWindow(dpy
, fwin
->titlebar
->window
);
601 wFrameWindowPaint(fwin
);
603 checkTitleSize(fwin
);
608 #ifdef XKB_BUTTON_HINT
609 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
610 int bwidth
, int bheight
, int left
, int language
, int right
,
611 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
613 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
614 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
618 RImage
*limg
, *rimg
, *mimg
;
619 #ifdef XKB_BUTTON_HINT
627 #ifdef XKB_BUTTON_HINT
628 *languagebutton
= None
;
631 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
633 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
637 if (wPreferences
.new_style
== TS_NEW
) {
639 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
646 #ifdef XKB_BUTTON_HINT
648 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
654 RBevelImage(limg
, RBEV_RAISED2
);
655 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
)) {
656 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
662 #ifdef XKB_BUTTON_HINT
664 RBevelImage(timg
, RBEV_RAISED2
);
665 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
)) {
666 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
675 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
680 RBevelImage(rimg
, RBEV_RAISED2
);
681 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
)) {
682 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
689 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
690 RBevelImage(mimg
, RBEV_RAISED2
);
692 if (!RConvertImage(scr
->rcontext
, mimg
, title
)) {
693 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
697 RBevelImage(img
, RBEV_RAISED2
);
699 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
700 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
704 RBevelImage(img
, RBEV_RAISED2
);
706 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
707 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
715 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
723 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
725 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
730 light
.red
= light
.green
= light
.blue
= 80;
733 dark
.red
= dark
.green
= dark
.blue
= 40;
735 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
736 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
738 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
739 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
742 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
743 width
- cwidth
- 2, height
- 1, &dark
);
744 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
746 #ifdef SHADOW_RESIZEBAR
747 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
748 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
749 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
750 #endif /* SHADOW_RESIZEBAR */
752 if (!RConvertImage(scr
->rcontext
, img
, pmap
)) {
753 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
759 static void updateTexture(WFrameWindow
* fwin
)
764 i
= fwin
->flags
.state
;
765 if (fwin
->titlebar
) {
766 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
767 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
768 if (wPreferences
.new_style
== TS_NEW
) {
769 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
770 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
771 fwin
->lbutton_back
[i
]);
773 #ifdef XKB_BUTTON_HINT
774 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
]) {
775 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
776 fwin
->languagebutton_back
[i
]);
780 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
781 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
782 fwin
->rbutton_back
[i
]);
785 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
786 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
787 if (wPreferences
.new_style
== TS_NEW
) {
788 if (fwin
->left_button
)
789 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
790 #ifdef XKB_BUTTON_HINT
791 if (fwin
->language_button
)
792 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
794 if (fwin
->right_button
)
795 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
798 XClearWindow(dpy
, fwin
->titlebar
->window
);
800 if (fwin
->left_button
) {
801 XClearWindow(dpy
, fwin
->left_button
->window
);
802 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
804 #ifdef XKB_BUTTON_HINT
805 if (fwin
->language_button
) {
806 XClearWindow(dpy
, fwin
->language_button
->window
);
807 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
810 if (fwin
->right_button
) {
811 XClearWindow(dpy
, fwin
->right_button
->window
);
812 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
817 static void remakeTexture(WFrameWindow
* fwin
, int state
)
819 Pixmap pmap
, lpmap
, rpmap
;
820 #ifdef XKB_BUTTON_HINT
824 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
825 FREE_PIXMAP(fwin
->title_back
[state
]);
826 if (wPreferences
.new_style
== TS_NEW
) {
827 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
828 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
829 #ifdef XKB_BUTTON_HINT
830 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
834 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
837 #ifdef XKB_BUTTON_HINT
841 /* eventually surrounded by if new_style */
842 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
843 #ifdef XKB_BUTTON_HINT
844 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
845 && !fwin
->flags
.languagebutton_dont_fit
;
847 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
848 && !fwin
->flags
.rbutton_dont_fit
;
850 width
= fwin
->core
->width
+ 1;
852 #ifdef XKB_BUTTON_HINT
853 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
854 width
, fwin
->titlebar
->height
,
855 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
856 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
858 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
859 width
, fwin
->titlebar
->height
,
860 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
861 left
, right
, &pmap
, &lpmap
, &rpmap
);
864 fwin
->title_back
[state
] = pmap
;
865 if (wPreferences
.new_style
== TS_NEW
) {
866 fwin
->lbutton_back
[state
] = lpmap
;
867 fwin
->rbutton_back
[state
] = rpmap
;
868 #ifdef XKB_BUTTON_HINT
869 fwin
->languagebutton_back
[state
] = tpmap
;
874 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
875 && fwin
->resizebar
&& state
== 0) {
877 FREE_PIXMAP(fwin
->resizebar_back
[0]);
879 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
881 renderResizebarTexture(fwin
->screen_ptr
,
882 fwin
->resizebar_texture
[0],
883 fwin
->resizebar
->width
,
884 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
886 fwin
->resizebar_back
[0] = pmap
;
889 /* this part should be in updateTexture() */
890 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
891 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
893 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
894 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
896 XClearWindow(dpy
, fwin
->resizebar
->window
);
900 void wFrameWindowPaint(WFrameWindow
* fwin
)
902 WScreen
*scr
= fwin
->screen_ptr
;
905 state
= fwin
->flags
.state
;
907 if (fwin
->flags
.is_client_window_frame
)
908 fwin
->flags
.justification
= wPreferences
.title_justification
;
910 if (fwin
->flags
.need_texture_remake
) {
913 fwin
->flags
.need_texture_remake
= 0;
914 fwin
->flags
.need_texture_change
= 0;
916 if (fwin
->flags
.single_texture
) {
917 remakeTexture(fwin
, 0);
920 /* first render the texture for the current state... */
921 remakeTexture(fwin
, state
);
922 /* ... and paint it */
925 for (i
= 0; i
< 3; i
++) {
927 remakeTexture(fwin
, i
);
933 if (fwin
->flags
.need_texture_change
) {
934 fwin
->flags
.need_texture_change
= 0;
939 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
940 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
941 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
942 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
945 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
946 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
951 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
953 w
= fwin
->resizebar
->width
;
954 h
= fwin
->resizebar
->height
;
955 cw
= fwin
->resizebar_corner_width
;
956 light_gc
= texture
->light_gc
;
957 dim_gc
= texture
->dim_gc
;
958 win
= fwin
->resizebar
->window
;
960 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
961 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
963 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
964 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
966 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
967 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
969 #ifdef SHADOW_RESIZEBAR
970 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
971 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
972 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
973 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
974 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
975 #endif /* SHADOW_RESIZEBAR */
978 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
980 int lofs
= 6, rofs
= 6;
984 if (!wPreferences
.new_style
== TS_NEW
) {
985 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
986 lofs
+= fwin
->left_button
->width
+ 3;
990 #ifdef XKB_BUTTON_HINT
991 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
992 && !fwin
->flags
.languagebutton_dont_fit
)
993 lofs
+= fwin
->language_button
->width
;
998 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
999 rofs
+= fwin
->right_button
->width
+ 3;
1003 #ifdef XKB_BUTTON_HINT
1004 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1011 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
1012 titlelen
= strlen(title
);
1013 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1015 switch (fwin
->flags
.justification
) {
1021 x
= fwin
->titlebar
->width
- w
- rofs
;
1026 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1028 x
= (fwin
->titlebar
->width
- w
) / 2;
1032 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1033 h
= WMFontHeight(*fwin
->font
);
1035 if (y
*2 + h
> *fwin
->title_max_height
)
1036 y
= (*fwin
->title_max_height
- h
) / 2;
1038 if (y
*2 + h
< *fwin
->title_min_height
)
1039 y
= (*fwin
->title_min_height
- h
) / 2;
1041 /* We use a w+2 buffer to have an extra pixel on the left and
1042 * another one on the right. This is because for some odd reason,
1043 * sometimes when using AA fonts (when libfreetype2 is compiled
1044 * with bytecode interpreter turned off), some fonts are drawn
1045 * starting from x = -1 not from 0 as requested. Observed with
1046 * capital A letter on the bold 'trebuchet ms' font. -Dan
1048 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1050 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1052 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1053 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1054 x
- 1, y
, w
+ 2, h
, 0, 0);
1056 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1057 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1060 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1061 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1062 *fwin
->font
, 1, 0, title
, titlelen
);
1064 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1066 XFreePixmap(dpy
, buf
);
1071 if (fwin
->left_button
)
1072 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1073 if (fwin
->right_button
)
1074 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1075 #ifdef XKB_BUTTON_HINT
1076 if (fwin
->language_button
)
1077 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1082 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1084 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1085 int resizedHorizontally
= 0;
1088 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1090 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1093 if (fwin->core->height != height && fwin->resizebar)
1094 XMoveWindow(dpy, fwin->resizebar->window, 0,
1095 height - fwin->resizebar->height);
1097 if (fwin
->core
->width
!= width
) {
1098 fwin
->flags
.need_texture_remake
= 1;
1099 resizedHorizontally
= 1;
1102 fwin
->core
->width
= width
;
1103 fwin
->core
->height
= height
;
1105 if (fwin
->titlebar
&& resizedHorizontally
) {
1106 /* Check if the titlebar is wide enough to hold the buttons.
1107 * Temporarily remove them if can't
1109 if (fwin
->left_button
) {
1110 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1112 if (!fwin
->flags
.hide_left_button
) {
1113 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1115 fwin
->flags
.lbutton_dont_fit
= 1;
1116 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1118 if (!fwin
->flags
.hide_left_button
) {
1119 XMapWindow(dpy
, fwin
->left_button
->window
);
1121 fwin
->flags
.lbutton_dont_fit
= 0;
1124 #ifdef XKB_BUTTON_HINT
1125 if (fwin
->language_button
) {
1126 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1128 if (!fwin
->flags
.hide_language_button
) {
1129 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1131 fwin
->flags
.languagebutton_dont_fit
= 1;
1132 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1134 if (!fwin
->flags
.hide_language_button
) {
1135 XMapWindow(dpy
, fwin
->language_button
->window
);
1137 fwin
->flags
.languagebutton_dont_fit
= 0;
1142 if (fwin
->right_button
) {
1143 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1145 if (!fwin
->flags
.hide_right_button
) {
1146 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1148 fwin
->flags
.rbutton_dont_fit
= 1;
1149 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1151 if (!fwin
->flags
.hide_right_button
) {
1152 XMapWindow(dpy
, fwin
->right_button
->window
);
1154 fwin
->flags
.rbutton_dont_fit
= 0;
1158 if (wPreferences
.new_style
== TS_NEW
) {
1159 if (fwin
->right_button
)
1160 XMoveWindow(dpy
, fwin
->right_button
->window
,
1161 width
- fwin
->right_button
->width
+ 1, 0);
1163 if (fwin
->right_button
)
1164 XMoveWindow(dpy
, fwin
->right_button
->window
,
1165 width
- fwin
->right_button
->width
- 3,
1166 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1168 updateTitlebar(fwin
);
1169 checkTitleSize(fwin
);
1172 if (fwin
->resizebar
) {
1173 wCoreConfigure(fwin
->resizebar
, 0,
1174 fwin
->core
->height
- fwin
->resizebar
->height
,
1175 fwin
->core
->width
, fwin
->resizebar
->height
);
1177 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1178 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
1179 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1184 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1186 reconfigure(fwin
, x
, y
, width
, height
, False
);
1189 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1191 reconfigure(fwin
, 0, 0, width
, height
, True
);
1194 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1196 /* check if the title is the same as before */
1198 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0)) {
1209 fwin
->title
= wstrdup(new_title
);
1211 if (fwin
->titlebar
) {
1212 XClearWindow(dpy
, fwin
->titlebar
->window
);
1214 wFrameWindowPaint(fwin
);
1216 checkTitleSize(fwin
);
1221 #ifdef XKB_BUTTON_HINT
1222 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1224 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1225 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1227 #endif /* XKB_BUTTON_HINT */
1229 /*********************************************************************/
1231 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1233 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1235 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1236 fwin
->flags
.repaint_only_titlebar
= 1;
1237 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1238 fwin
->flags
.repaint_only_resizebar
= 1;
1239 wFrameWindowPaint(fwin
);
1240 fwin
->flags
.repaint_only_titlebar
= 0;
1241 fwin
->flags
.repaint_only_resizebar
= 0;
1244 static void checkTitleSize(WFrameWindow
* fwin
)
1249 fwin
->flags
.incomplete_title
= 0;
1253 if (!fwin
->titlebar
) {
1254 fwin
->flags
.incomplete_title
= 1;
1257 width
= fwin
->titlebar
->width
- 6 - 6;
1260 if (!wPreferences
.new_style
== TS_NEW
) {
1261 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1262 width
-= fwin
->left_button
->width
+ 3;
1264 #ifdef XKB_BUTTON_HINT
1265 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1266 && !fwin
->flags
.languagebutton_dont_fit
)
1267 width
-= fwin
->language_button
->width
+ 3;
1270 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1271 width
-= fwin
->right_button
->width
+ 3;
1273 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
) {
1274 fwin
->flags
.incomplete_title
= 1;
1276 fwin
->flags
.incomplete_title
= 0;
1280 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1282 WScreen
*scr
= button
->screen_ptr
;
1283 GC copy_gc
= scr
->copy_gc
;
1284 int x
= 0, y
= 0, d
= 0;
1285 int left
= 0, width
= 0;
1287 /* setup stuff according to the state */
1290 if (image
->width
>= image
->height
* 2) {
1291 /* the image contains 2 pictures: the second is for the
1293 width
= image
->width
/ 2;
1294 left
= image
->width
/ 2;
1296 width
= image
->width
;
1299 XSetClipMask(dpy
, copy_gc
, None
);
1300 if (wPreferences
.new_style
== TS_NEXT
) {
1301 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1303 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1306 if (wPreferences
.new_style
== TS_NEW
) {
1307 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1308 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1309 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1310 } else if (wPreferences
.new_style
== TS_OLD
) {
1311 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1312 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1313 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1315 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1316 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1317 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1320 XClearWindow(dpy
, button
->window
);
1323 if (image
->width
>= image
->height
* 2)
1324 width
= image
->width
/ 2;
1326 width
= image
->width
;
1330 if (wPreferences
.new_style
== TS_NEW
) {
1331 if (texture
->any
.type
== WTEX_SOLID
|| pushed
) {
1332 wDrawBevel(button
->window
, button
->width
, button
->height
,
1333 (WTexSolid
*) texture
, WREL_RAISED
);
1336 wDrawBevel(button
->window
, button
->width
, button
->height
,
1337 scr
->widget_texture
, WREL_RAISED
);
1343 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1344 x
= (button
->width
- width
) / 2 + d
;
1345 y
= (button
->height
- image
->height
) / 2 + d
;
1346 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1347 if (!wPreferences
.new_style
== TS_NEW
) {
1348 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1350 if (image
->depth
== 1)
1351 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1352 left
, 0, width
, image
->height
, x
, y
, 1);
1354 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1355 left
, 0, width
, image
->height
, x
, y
);
1357 if (wPreferences
.new_style
== TS_OLD
) {
1358 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1359 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1360 button
->width
, button
->height
);
1362 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1363 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1364 left
, 0, width
, image
->height
, x
, y
);
1369 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1371 XSetForeground(dpy
, copy_gc
, color
);
1372 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1374 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1379 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1381 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1382 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1384 #ifdef XKB_BUTTON_HINT
1385 if (button
== fwin
->language_button
) {
1386 if (wPreferences
.modelock
) {
1387 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1388 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1389 fwin
->languagebutton_image
, False
);
1393 if (button
== fwin
->left_button
) {
1394 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1395 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1397 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1398 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1402 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1404 WFrameWindow
*fwin
= desc
->parent
;
1405 WCoreWindow
*titlebar
= desc
->self
;
1407 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1408 if (fwin
->on_dblclick_titlebar
) {
1409 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1412 if (fwin
->on_mousedown_titlebar
) {
1413 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1418 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1420 WFrameWindow
*fwin
= desc
->parent
;
1421 WCoreWindow
*resizebar
= desc
->self
;
1423 if (fwin
->on_mousedown_resizebar
)
1424 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1427 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1429 WFrameWindow
*fwin
= desc
->parent
;
1430 WCoreWindow
*button
= desc
->self
;
1433 int done
= 0, execute
= 1;
1435 unsigned long pixel
;
1436 int clickButton
= event
->xbutton
.button
;
1438 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1439 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
) {
1440 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1445 if (button
== fwin
->left_button
) {
1446 image
= fwin
->lbutton_image
;
1448 image
= fwin
->rbutton_image
;
1450 #ifdef XKB_BUTTON_HINT
1451 if (button
== fwin
->language_button
) {
1452 if (!wPreferences
.modelock
)
1454 image
= fwin
->languagebutton_image
;
1458 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1459 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1460 paintButton(button
, texture
, pixel
, image
, True
);
1463 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1464 | ButtonPressMask
| ExposureMask
, &ev
);
1468 paintButton(button
, texture
, pixel
, image
, False
);
1473 paintButton(button
, texture
, pixel
, image
, True
);
1480 if (ev
.xbutton
.button
== clickButton
)
1488 paintButton(button
, texture
, pixel
, image
, False
);
1491 if (button
== fwin
->left_button
) {
1492 if (fwin
->on_click_left
)
1493 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1494 } else if (button
== fwin
->right_button
) {
1495 if (fwin
->on_click_right
)
1496 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1498 #ifdef XKB_BUTTON_HINT
1499 else if (button
== fwin
->language_button
) {
1500 if (fwin
->on_click_language
)
1501 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);