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"
37 #include "resources.h"
44 #define DBLCLICK_TIME wPreferences.dblclick_time
46 extern WPreferences wPreferences
;
48 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
);
49 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
);
51 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
52 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
53 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
55 static void checkTitleSize(WFrameWindow
* fwin
);
57 static void paintButton(WCoreWindow
* button
, WTexture
* texture
,
58 unsigned long color
, WPixmap
* image
, int pushed
);
60 static void updateTitlebar(WFrameWindow
* fwin
);
62 static void allocFrameBorderPixel(Colormap colormap
, char *color_name
, unsigned long **pixel
);
64 static void allocFrameBorderPixel(Colormap colormap
, char *color_name
, unsigned long **pixel
) {
69 if (! wGetColorForColormap(colormap
, color_name
, &xcol
))
72 *pixel
= wmalloc(sizeof(unsigned long));
77 WFrameWindow
*wFrameWindowCreate(WScreen
* scr
, int wlevel
, int x
, int y
,
78 int width
, int height
, int *clearance
,
79 int *title_min
, int *title_max
, int flags
,
80 WTexture
** title_texture
, WTexture
** resize_texture
,
81 WMColor
** color
, WMFont
** font
,
82 int depth
, Visual
*visual
, Colormap colormap
)
86 fwin
= wmalloc(sizeof(WFrameWindow
));
88 fwin
->screen_ptr
= scr
;
90 fwin
->flags
.single_texture
= (flags
& WFF_SINGLE_STATE
) ? 1 : 0;
92 fwin
->title_texture
= title_texture
;
93 fwin
->resizebar_texture
= resize_texture
;
94 fwin
->title_color
= color
;
95 fwin
->title_clearance
= clearance
;
96 fwin
->title_min_height
= title_min
;
97 fwin
->title_max_height
= title_max
;
99 #ifdef KEEP_XKB_LOCK_STATUS
100 fwin
->languagemode
= XkbGroup1Index
;
101 fwin
->last_languagemode
= XkbGroup2Index
;
105 fwin
->visual
= visual
;
106 fwin
->colormap
= colormap
;
108 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
109 ? scr
->frame_border_width
: 0, fwin
->depth
, fwin
->visual
, fwin
->colormap
, scr
->frame_border_pixel
);
111 /* setup stacking information */
112 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
113 fwin
->core
->stacking
->above
= NULL
;
114 fwin
->core
->stacking
->under
= NULL
;
115 fwin
->core
->stacking
->child_of
= NULL
;
116 fwin
->core
->stacking
->window_level
= wlevel
;
118 AddToStackList(fwin
->core
);
120 wFrameWindowUpdateBorders(fwin
, flags
);
125 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
131 WScreen
*scr
= fwin
->screen_ptr
;
133 width
= fwin
->core
->width
;
134 if (flags
& WFF_IS_SHADED
)
137 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
139 if (flags
& WFF_TITLEBAR
) {
140 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
142 if (theight
> *fwin
->title_max_height
)
143 theight
= *fwin
->title_max_height
;
145 if (theight
< *fwin
->title_min_height
)
146 theight
= *fwin
->title_min_height
;
151 if (wPreferences
.new_style
== TS_NEW
) {
153 } else if (wPreferences
.new_style
== TS_OLD
) {
159 if (fwin
->titlebar
) {
160 /* if we had a titlebar and is requesting for one,
161 * check if the size has changed and resize it */
162 if (flags
& WFF_TITLEBAR
) {
163 fwin
->top_width
= theight
;
165 fwin
->flags
.need_texture_remake
= 1;
167 if (wPreferences
.new_style
== TS_NEW
) {
168 if (fwin
->left_button
)
169 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
170 #ifdef XKB_BUTTON_HINT
171 if (fwin
->language_button
) {
172 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
173 || fwin
->flags
.lbutton_dont_fit
)
174 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
176 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
180 if (fwin
->right_button
)
181 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
183 } else { /* !new_style */
184 if (fwin
->left_button
)
185 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
186 #ifdef XKB_BUTTON_HINT
187 if (fwin
->language_button
)
188 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
192 if (fwin
->right_button
)
193 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
194 (theight
- bsize
) / 2, bsize
, bsize
);
196 updateTitlebar(fwin
);
198 /* we had a titlebar, but now we don't need it anymore */
199 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
200 FREE_PIXMAP(fwin
->title_back
[i
]);
201 if (wPreferences
.new_style
== TS_NEW
) {
202 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
203 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
204 #ifdef XKB_BUTTON_HINT
205 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
209 if (fwin
->left_button
)
210 wCoreDestroy(fwin
->left_button
);
211 fwin
->left_button
= NULL
;
213 #ifdef XKB_BUTTON_HINT
214 if (fwin
->language_button
)
215 wCoreDestroy(fwin
->language_button
);
216 fwin
->language_button
= NULL
;
219 if (fwin
->right_button
)
220 wCoreDestroy(fwin
->right_button
);
221 fwin
->right_button
= NULL
;
223 wCoreDestroy(fwin
->titlebar
);
224 fwin
->titlebar
= NULL
;
229 /* if we didn't have a titlebar and are being requested for
231 if (flags
& WFF_TITLEBAR
) {
232 fwin
->top_width
= theight
;
234 fwin
->flags
.titlebar
= 1;
235 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
237 if (flags
& WFF_LEFT_BUTTON
) {
238 fwin
->flags
.left_button
= 1;
239 if (wPreferences
.new_style
== TS_NEW
) {
240 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
242 if (width
< theight
* 4)
243 fwin
->flags
.lbutton_dont_fit
= 1;
245 XMapRaised(dpy
, fwin
->left_button
->window
);
247 } else if (wPreferences
.new_style
== TS_OLD
) {
249 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
251 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
252 scr
->widget_texture
->normal
.pixel
);
254 if (width
< theight
* 3)
255 fwin
->flags
.lbutton_dont_fit
= 1;
257 XMapRaised(dpy
, fwin
->left_button
->window
);
261 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
264 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
265 scr
->widget_texture
->dark
.pixel
);
267 if (width
< theight
* 3)
268 fwin
->flags
.lbutton_dont_fit
= 1;
270 XMapRaised(dpy
, fwin
->left_button
->window
);
274 #ifdef XKB_BUTTON_HINT
275 if (flags
& WFF_LANGUAGE_BUTTON
) {
276 fwin
->flags
.language_button
= 1;
277 if (wPreferences
.new_style
== TS_NEW
) {
278 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
280 if (width
< theight
* 4)
281 fwin
->flags
.languagebutton_dont_fit
= 1;
283 XMapRaised(dpy
, fwin
->language_button
->window
);
285 fwin
->language_button
=
286 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
289 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
290 scr
->widget_texture
->normal
.pixel
);
292 if (width
< theight
* 3)
293 fwin
->flags
.languagebutton_dont_fit
= 1;
295 XMapRaised(dpy
, fwin
->language_button
->window
);
300 if (flags
& WFF_RIGHT_BUTTON
) {
301 fwin
->flags
.right_button
= 1;
302 if (wPreferences
.new_style
== TS_NEW
) {
304 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
305 } else if (wPreferences
.new_style
== TS_OLD
) {
307 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
308 (theight
- bsize
) / 2, bsize
, bsize
);
309 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
310 scr
->widget_texture
->normal
.pixel
);
313 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
314 (theight
-bsize
)/2, bsize
, bsize
);
315 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
316 scr
->widget_texture
->dark
.pixel
);
319 if (width
< theight
* 2)
320 fwin
->flags
.rbutton_dont_fit
= 1;
322 XMapRaised(dpy
, fwin
->right_button
->window
);
325 if (wPreferences
.new_style
== TS_NEW
)
326 updateTitlebar(fwin
);
328 XMapRaised(dpy
, fwin
->titlebar
->window
);
330 fwin
->flags
.need_texture_remake
= 1;
333 checkTitleSize(fwin
);
335 if (flags
& WFF_RESIZEBAR
) {
336 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
338 if (!fwin
->resizebar
) {
339 fwin
->flags
.resizebar
= 1;
340 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
341 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
342 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
343 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
344 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
345 if (fwin
->resizebar_corner_width
< 0)
346 fwin
->resizebar_corner_width
= 0;
349 XMapWindow(dpy
, fwin
->resizebar
->window
);
350 XLowerWindow(dpy
, fwin
->resizebar
->window
);
352 fwin
->flags
.need_texture_remake
= 1;
354 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
)
355 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
356 width
, RESIZEBAR_HEIGHT
);
359 fwin
->bottom_width
= 0;
361 if (fwin
->resizebar
) {
362 fwin
->bottom_width
= 0;
363 wCoreDestroy(fwin
->resizebar
);
364 fwin
->resizebar
= NULL
;
368 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
))
369 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
371 if (flags
& WFF_BORDER
)
372 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, scr
->frame_border_width
);
374 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
376 /* setup object descriptors */
377 if (fwin
->titlebar
) {
378 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
379 fwin
->titlebar
->descriptor
.parent
= fwin
;
380 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
381 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
384 if (fwin
->resizebar
) {
385 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
386 fwin
->resizebar
->descriptor
.parent
= fwin
;
387 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
388 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
391 if (fwin
->left_button
) {
392 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
393 fwin
->left_button
->descriptor
.parent
= fwin
;
394 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
395 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
398 #ifdef XKB_BUTTON_HINT
399 if (fwin
->language_button
) {
400 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
401 fwin
->language_button
->descriptor
.parent
= fwin
;
402 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
403 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
407 if (fwin
->right_button
) {
408 fwin
->right_button
->descriptor
.parent
= fwin
;
409 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
410 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
411 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
414 checkTitleSize(fwin
);
416 allocFrameBorderPixel(fwin
->colormap
, WMGetColorRGBDescription(scr
->frame_border_color
), &fwin
->border_pixel
);
417 allocFrameBorderPixel(fwin
->colormap
, WMGetColorRGBDescription(scr
->frame_selected_border_color
), &fwin
->selected_border_pixel
);
419 if (flags
& WFF_SELECTED
) {
420 if (fwin
->selected_border_pixel
)
421 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->selected_border_pixel
);
424 if (fwin
->border_pixel
)
425 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->border_pixel
);
429 void wFrameWindowDestroy(WFrameWindow
* fwin
)
433 if (fwin
->left_button
)
434 wCoreDestroy(fwin
->left_button
);
436 #ifdef XKB_BUTTON_HINT
437 if (fwin
->language_button
)
438 wCoreDestroy(fwin
->language_button
);
441 if (fwin
->right_button
)
442 wCoreDestroy(fwin
->right_button
);
445 wCoreDestroy(fwin
->resizebar
);
448 wCoreDestroy(fwin
->titlebar
);
450 RemoveFromStackList(fwin
->core
);
452 wCoreDestroy(fwin
->core
);
457 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
458 FREE_PIXMAP(fwin
->title_back
[i
]);
459 if (wPreferences
.new_style
== TS_NEW
) {
460 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
461 #ifdef XKB_BUTTON_HINT
462 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
464 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
471 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
473 if (fwin
->flags
.state
== state
)
476 fwin
->flags
.state
= state
;
477 fwin
->flags
.need_texture_change
= 1;
479 wFrameWindowPaint(fwin
);
482 static void updateTitlebar(WFrameWindow
* fwin
)
487 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
489 if (theight
> *fwin
->title_max_height
)
490 theight
= *fwin
->title_max_height
;
492 if (theight
< *fwin
->title_min_height
)
493 theight
= *fwin
->title_min_height
;
496 w
= fwin
->core
->width
+ 1;
498 if (wPreferences
.new_style
== TS_NEW
) {
499 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
501 #ifdef XKB_BUTTON_HINT
502 if (fwin
->language_button
)
503 wCoreConfigure(fwin
->language_button
, 0, 0,
504 fwin
->language_button
->width
, fwin
->language_button
->width
);
507 #ifdef XKB_BUTTON_HINT
508 if (fwin
->language_button
)
509 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
510 fwin
->language_button
->width
, fwin
->language_button
->width
);
512 x
= fwin
->left_button
->width
;
513 w
-= fwin
->left_button
->width
;
515 #ifdef XKB_BUTTON_HINT
516 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
517 || fwin
->flags
.languagebutton_dont_fit
) {
519 x
+= fwin
->language_button
->width
;
520 w
-= fwin
->language_button
->width
;
524 #ifdef XKB_BUTTON_HINT
526 int bsize
= theight
- 7;
527 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
528 if (fwin
->language_button
)
529 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
530 fwin
->language_button
->width
, fwin
->language_button
->width
);
532 if (fwin
->language_button
)
533 wCoreConfigure(fwin
->language_button
,
534 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
535 fwin
->language_button
->width
, fwin
->language_button
->width
);
540 if (wPreferences
.new_style
== TS_NEW
) {
541 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
)
542 w
-= fwin
->right_button
->width
;
545 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
546 fwin
->flags
.need_texture_remake
= 1;
548 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
551 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
553 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
554 XUnmapWindow(dpy
, fwin
->right_button
->window
);
555 fwin
->flags
.hide_right_button
= 1;
558 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
559 XUnmapWindow(dpy
, fwin
->left_button
->window
);
560 fwin
->flags
.hide_left_button
= 1;
562 #ifdef XKB_BUTTON_HINT
563 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
564 XUnmapWindow(dpy
, fwin
->language_button
->window
);
565 fwin
->flags
.hide_language_button
= 1;
569 if (fwin
->titlebar
) {
570 if (wPreferences
.new_style
== TS_NEW
) {
571 updateTitlebar(fwin
);
573 #ifdef XKB_BUTTON_HINT
574 updateTitlebar(fwin
);
576 XClearWindow(dpy
, fwin
->titlebar
->window
);
577 wFrameWindowPaint(fwin
);
580 checkTitleSize(fwin
);
584 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
586 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
588 if (!fwin
->flags
.rbutton_dont_fit
)
589 XMapWindow(dpy
, fwin
->right_button
->window
);
591 fwin
->flags
.hide_right_button
= 0;
593 #ifdef XKB_BUTTON_HINT
594 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
596 if (!fwin
->flags
.languagebutton_dont_fit
)
597 XMapWindow(dpy
, fwin
->language_button
->window
);
599 fwin
->flags
.hide_language_button
= 0;
603 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
605 if (!fwin
->flags
.lbutton_dont_fit
)
606 XMapWindow(dpy
, fwin
->left_button
->window
);
608 fwin
->flags
.hide_left_button
= 0;
611 if (fwin
->titlebar
) {
612 if (wPreferences
.new_style
== TS_NEW
) {
613 updateTitlebar(fwin
);
615 XClearWindow(dpy
, fwin
->titlebar
->window
);
616 wFrameWindowPaint(fwin
);
618 checkTitleSize(fwin
);
623 #ifdef XKB_BUTTON_HINT
624 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
625 int bwidth
, int bheight
, int left
, int language
, int right
,
626 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
628 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
629 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
633 RImage
*limg
, *rimg
, *mimg
;
634 #ifdef XKB_BUTTON_HINT
642 #ifdef XKB_BUTTON_HINT
643 *languagebutton
= None
;
646 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
648 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
652 if (wPreferences
.new_style
== TS_NEW
) {
654 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
661 #ifdef XKB_BUTTON_HINT
663 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
669 RBevelImage(limg
, RBEV_RAISED2
);
670 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
))
671 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
677 #ifdef XKB_BUTTON_HINT
679 RBevelImage(timg
, RBEV_RAISED2
);
680 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
))
681 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
690 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
695 RBevelImage(rimg
, RBEV_RAISED2
);
696 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
))
697 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
704 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
705 RBevelImage(mimg
, RBEV_RAISED2
);
707 if (!RConvertImage(scr
->rcontext
, mimg
, title
))
708 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
712 RBevelImage(img
, RBEV_RAISED2
);
714 if (!RConvertImage(scr
->rcontext
, img
, title
))
715 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
718 RBevelImage(img
, RBEV_RAISED2
);
720 if (!RConvertImage(scr
->rcontext
, img
, title
))
721 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
728 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
736 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
738 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
743 light
.red
= light
.green
= light
.blue
= 80;
746 dark
.red
= dark
.green
= dark
.blue
= 40;
748 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
749 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
751 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
752 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
755 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
756 width
- cwidth
- 2, height
- 1, &dark
);
757 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
759 #ifdef SHADOW_RESIZEBAR
760 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
761 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
762 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
763 #endif /* SHADOW_RESIZEBAR */
765 if (!RConvertImage(scr
->rcontext
, img
, pmap
))
766 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
771 static void updateTexture(WFrameWindow
* fwin
)
776 i
= fwin
->flags
.state
;
777 if (fwin
->titlebar
) {
778 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
779 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
780 if (wPreferences
.new_style
== TS_NEW
) {
781 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
782 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
783 fwin
->lbutton_back
[i
]);
785 #ifdef XKB_BUTTON_HINT
786 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
])
787 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
788 fwin
->languagebutton_back
[i
]);
791 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
792 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
793 fwin
->rbutton_back
[i
]);
796 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
797 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
798 if (wPreferences
.new_style
== TS_NEW
) {
799 if (fwin
->left_button
)
800 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
801 #ifdef XKB_BUTTON_HINT
802 if (fwin
->language_button
)
803 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
805 if (fwin
->right_button
)
806 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
809 XClearWindow(dpy
, fwin
->titlebar
->window
);
811 if (fwin
->left_button
) {
812 XClearWindow(dpy
, fwin
->left_button
->window
);
813 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
815 #ifdef XKB_BUTTON_HINT
816 if (fwin
->language_button
) {
817 XClearWindow(dpy
, fwin
->language_button
->window
);
818 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
821 if (fwin
->right_button
) {
822 XClearWindow(dpy
, fwin
->right_button
->window
);
823 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
828 static void remakeTexture(WFrameWindow
* fwin
, int state
)
830 Pixmap pmap
, lpmap
, rpmap
;
831 #ifdef XKB_BUTTON_HINT
835 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
836 FREE_PIXMAP(fwin
->title_back
[state
]);
837 if (wPreferences
.new_style
== TS_NEW
) {
838 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
839 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
840 #ifdef XKB_BUTTON_HINT
841 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
845 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
848 #ifdef XKB_BUTTON_HINT
852 /* eventually surrounded by if new_style */
853 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
854 #ifdef XKB_BUTTON_HINT
855 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
856 && !fwin
->flags
.languagebutton_dont_fit
;
858 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
859 && !fwin
->flags
.rbutton_dont_fit
;
861 width
= fwin
->core
->width
+ 1;
863 #ifdef XKB_BUTTON_HINT
864 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
865 width
, fwin
->titlebar
->height
,
866 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
867 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
869 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
870 width
, fwin
->titlebar
->height
,
871 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
872 left
, right
, &pmap
, &lpmap
, &rpmap
);
875 fwin
->title_back
[state
] = pmap
;
876 if (wPreferences
.new_style
== TS_NEW
) {
877 fwin
->lbutton_back
[state
] = lpmap
;
878 fwin
->rbutton_back
[state
] = rpmap
;
879 #ifdef XKB_BUTTON_HINT
880 fwin
->languagebutton_back
[state
] = tpmap
;
885 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
886 && fwin
->resizebar
&& state
== 0) {
888 FREE_PIXMAP(fwin
->resizebar_back
[0]);
890 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
892 renderResizebarTexture(fwin
->screen_ptr
,
893 fwin
->resizebar_texture
[0],
894 fwin
->resizebar
->width
,
895 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
897 fwin
->resizebar_back
[0] = pmap
;
900 /* this part should be in updateTexture() */
901 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
)
902 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
904 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
905 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
907 XClearWindow(dpy
, fwin
->resizebar
->window
);
911 void wFrameWindowPaint(WFrameWindow
* fwin
)
913 WScreen
*scr
= fwin
->screen_ptr
;
916 state
= fwin
->flags
.state
;
918 if (fwin
->flags
.is_client_window_frame
)
919 fwin
->flags
.justification
= wPreferences
.title_justification
;
921 if (fwin
->flags
.need_texture_remake
) {
924 fwin
->flags
.need_texture_remake
= 0;
925 fwin
->flags
.need_texture_change
= 0;
927 if (fwin
->flags
.single_texture
) {
928 remakeTexture(fwin
, 0);
931 /* first render the texture for the current state... */
932 remakeTexture(fwin
, state
);
933 /* ... and paint it */
936 for (i
= 0; i
< 3; i
++) {
938 remakeTexture(fwin
, i
);
943 if (fwin
->flags
.need_texture_change
) {
944 fwin
->flags
.need_texture_change
= 0;
949 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
950 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
951 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
952 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
955 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
956 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
961 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
963 w
= fwin
->resizebar
->width
;
964 h
= fwin
->resizebar
->height
;
965 cw
= fwin
->resizebar_corner_width
;
966 light_gc
= texture
->light_gc
;
967 dim_gc
= texture
->dim_gc
;
968 win
= fwin
->resizebar
->window
;
970 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
971 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
973 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
974 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
976 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
977 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
979 #ifdef SHADOW_RESIZEBAR
980 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
981 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
982 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
983 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
984 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
985 #endif /* SHADOW_RESIZEBAR */
988 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
990 int lofs
= 6, rofs
= 6;
994 if (!wPreferences
.new_style
== TS_NEW
) {
995 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
996 lofs
+= fwin
->left_button
->width
+ 3;
1000 #ifdef XKB_BUTTON_HINT
1001 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1002 && !fwin
->flags
.languagebutton_dont_fit
)
1003 lofs
+= fwin
->language_button
->width
;
1008 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1009 rofs
+= fwin
->right_button
->width
+ 3;
1013 #ifdef XKB_BUTTON_HINT
1014 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1021 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
1022 titlelen
= strlen(title
);
1023 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1025 switch (fwin
->flags
.justification
) {
1031 x
= fwin
->titlebar
->width
- w
- rofs
;
1036 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1038 x
= (fwin
->titlebar
->width
- w
) / 2;
1042 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1043 h
= WMFontHeight(*fwin
->font
);
1045 if (y
*2 + h
> *fwin
->title_max_height
)
1046 y
= (*fwin
->title_max_height
- h
) / 2;
1048 if (y
*2 + h
< *fwin
->title_min_height
)
1049 y
= (*fwin
->title_min_height
- h
) / 2;
1051 /* We use a w+2 buffer to have an extra pixel on the left and
1052 * another one on the right. This is because for some odd reason,
1053 * sometimes when using AA fonts (when libfreetype2 is compiled
1054 * with bytecode interpreter turned off), some fonts are drawn
1055 * starting from x = -1 not from 0 as requested. Observed with
1056 * capital A letter on the bold 'trebuchet ms' font. -Dan
1058 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1060 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1062 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1063 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1064 x
- 1, y
, w
+ 2, h
, 0, 0);
1066 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1067 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1070 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1071 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1072 *fwin
->font
, 1, 0, title
, titlelen
);
1074 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1076 XFreePixmap(dpy
, buf
);
1081 if (fwin
->left_button
)
1082 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1083 if (fwin
->right_button
)
1084 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1085 #ifdef XKB_BUTTON_HINT
1086 if (fwin
->language_button
)
1087 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1092 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1094 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1095 int resizedHorizontally
= 0;
1098 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1100 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, 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
) {
1116 if (!fwin
->flags
.hide_left_button
)
1117 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1119 fwin
->flags
.lbutton_dont_fit
= 1;
1120 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1121 if (!fwin
->flags
.hide_left_button
)
1122 XMapWindow(dpy
, fwin
->left_button
->window
);
1124 fwin
->flags
.lbutton_dont_fit
= 0;
1127 #ifdef XKB_BUTTON_HINT
1128 if (fwin
->language_button
) {
1129 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1130 if (!fwin
->flags
.hide_language_button
)
1131 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1133 fwin
->flags
.languagebutton_dont_fit
= 1;
1134 } 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
) {
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
) {
1150 if (!fwin
->flags
.hide_right_button
)
1151 XMapWindow(dpy
, fwin
->right_button
->window
);
1153 fwin
->flags
.rbutton_dont_fit
= 0;
1157 if (wPreferences
.new_style
== TS_NEW
) {
1158 if (fwin
->right_button
)
1159 XMoveWindow(dpy
, fwin
->right_button
->window
,
1160 width
- fwin
->right_button
->width
+ 1, 0);
1162 if (fwin
->right_button
)
1163 XMoveWindow(dpy
, fwin
->right_button
->window
,
1164 width
- fwin
->right_button
->width
- 3,
1165 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1167 updateTitlebar(fwin
);
1168 checkTitleSize(fwin
);
1171 if (fwin
->resizebar
) {
1172 wCoreConfigure(fwin
->resizebar
, 0,
1173 fwin
->core
->height
- fwin
->resizebar
->height
,
1174 fwin
->core
->width
, fwin
->resizebar
->height
);
1176 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1177 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
)
1178 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1182 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1184 reconfigure(fwin
, x
, y
, width
, height
, False
);
1187 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1189 reconfigure(fwin
, 0, 0, width
, height
, True
);
1192 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1194 /* check if the title is the same as before */
1196 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0))
1206 fwin
->title
= wstrdup(new_title
);
1208 if (fwin
->titlebar
) {
1209 XClearWindow(dpy
, fwin
->titlebar
->window
);
1211 wFrameWindowPaint(fwin
);
1213 checkTitleSize(fwin
);
1218 #ifdef XKB_BUTTON_HINT
1219 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1221 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1222 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1224 #endif /* XKB_BUTTON_HINT */
1226 /*********************************************************************/
1228 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1230 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1232 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1233 fwin
->flags
.repaint_only_titlebar
= 1;
1234 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1235 fwin
->flags
.repaint_only_resizebar
= 1;
1236 wFrameWindowPaint(fwin
);
1237 fwin
->flags
.repaint_only_titlebar
= 0;
1238 fwin
->flags
.repaint_only_resizebar
= 0;
1241 static void checkTitleSize(WFrameWindow
* fwin
)
1246 fwin
->flags
.incomplete_title
= 0;
1250 if (!fwin
->titlebar
) {
1251 fwin
->flags
.incomplete_title
= 1;
1254 width
= fwin
->titlebar
->width
- 6 - 6;
1257 if (!wPreferences
.new_style
== TS_NEW
) {
1258 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1259 width
-= fwin
->left_button
->width
+ 3;
1261 #ifdef XKB_BUTTON_HINT
1262 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1263 && !fwin
->flags
.languagebutton_dont_fit
)
1264 width
-= fwin
->language_button
->width
+ 3;
1267 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1268 width
-= fwin
->right_button
->width
+ 3;
1271 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
)
1272 fwin
->flags
.incomplete_title
= 1;
1274 fwin
->flags
.incomplete_title
= 0;
1277 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1279 WScreen
*scr
= button
->screen_ptr
;
1280 GC copy_gc
= scr
->copy_gc
;
1281 int x
= 0, y
= 0, d
= 0;
1282 int left
= 0, width
= 0;
1284 /* setup stuff according to the state */
1287 if (image
->width
>= image
->height
* 2) {
1288 /* the image contains 2 pictures: the second is for the
1290 width
= image
->width
/ 2;
1291 left
= image
->width
/ 2;
1293 width
= image
->width
;
1296 XSetClipMask(dpy
, copy_gc
, None
);
1297 if (wPreferences
.new_style
== TS_NEXT
)
1298 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1300 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1303 if (wPreferences
.new_style
== TS_NEW
) {
1304 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1305 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1306 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1307 } else if (wPreferences
.new_style
== TS_OLD
) {
1308 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1309 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1310 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1312 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1313 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1314 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1317 XClearWindow(dpy
, button
->window
);
1320 if (image
->width
>= image
->height
* 2)
1321 width
= image
->width
/ 2;
1323 width
= image
->width
;
1327 if (wPreferences
.new_style
== TS_NEW
) {
1328 if (texture
->any
.type
== WTEX_SOLID
|| pushed
)
1329 wDrawBevel(button
->window
, button
->width
, button
->height
,
1330 (WTexSolid
*) texture
, WREL_RAISED
);
1332 wDrawBevel(button
->window
, button
->width
, button
->height
,
1333 scr
->widget_texture
, WREL_RAISED
);
1339 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1340 x
= (button
->width
- width
) / 2 + d
;
1341 y
= (button
->height
- image
->height
) / 2 + d
;
1342 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1343 if (!wPreferences
.new_style
== TS_NEW
) {
1344 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1346 if (image
->depth
== 1)
1347 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1348 left
, 0, width
, image
->height
, x
, y
, 1);
1350 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1351 left
, 0, width
, image
->height
, x
, y
);
1353 if (wPreferences
.new_style
== TS_OLD
) {
1354 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1355 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1356 button
->width
, button
->height
);
1358 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1359 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1360 left
, 0, width
, image
->height
, x
, y
);
1365 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1367 XSetForeground(dpy
, copy_gc
, color
);
1368 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1370 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1375 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1377 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1378 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1380 #ifdef XKB_BUTTON_HINT
1381 if (button
== fwin
->language_button
) {
1382 if (wPreferences
.modelock
)
1383 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1384 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1385 fwin
->languagebutton_image
, False
);
1388 if (button
== fwin
->left_button
)
1389 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1390 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1392 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1393 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1396 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1398 WFrameWindow
*fwin
= desc
->parent
;
1399 WCoreWindow
*titlebar
= desc
->self
;
1401 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1402 if (fwin
->on_dblclick_titlebar
)
1403 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1405 if (fwin
->on_mousedown_titlebar
)
1406 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1410 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1412 WFrameWindow
*fwin
= desc
->parent
;
1413 WCoreWindow
*resizebar
= desc
->self
;
1415 if (fwin
->on_mousedown_resizebar
)
1416 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1419 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1421 WFrameWindow
*fwin
= desc
->parent
;
1422 WCoreWindow
*button
= desc
->self
;
1425 int done
= 0, execute
= 1;
1427 unsigned long pixel
;
1428 int clickButton
= event
->xbutton
.button
;
1430 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1431 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
)
1432 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1437 if (button
== fwin
->left_button
)
1438 image
= fwin
->lbutton_image
;
1440 image
= fwin
->rbutton_image
;
1442 #ifdef XKB_BUTTON_HINT
1443 if (button
== fwin
->language_button
) {
1444 if (!wPreferences
.modelock
)
1446 image
= fwin
->languagebutton_image
;
1450 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1451 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1452 paintButton(button
, texture
, pixel
, image
, True
);
1455 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1456 | ButtonPressMask
| ExposureMask
, &ev
);
1460 paintButton(button
, texture
, pixel
, image
, False
);
1465 paintButton(button
, texture
, pixel
, image
, True
);
1472 if (ev
.xbutton
.button
== clickButton
)
1480 paintButton(button
, texture
, pixel
, image
, False
);
1483 if (button
== fwin
->left_button
) {
1484 if (fwin
->on_click_left
)
1485 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1486 } else if (button
== fwin
->right_button
) {
1487 if (fwin
->on_click_right
)
1488 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1490 #ifdef XKB_BUTTON_HINT
1491 else if (button
== fwin
->language_button
) {
1492 if (fwin
->on_click_language
)
1493 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);