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"
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 static void allocFrameBorderPixel(Colormap colormap
, const char *color_name
, unsigned long **pixel
);
63 static void allocFrameBorderPixel(Colormap colormap
, const char *color_name
, unsigned long **pixel
) {
68 if (! wGetColorForColormap(colormap
, color_name
, &xcol
))
71 *pixel
= wmalloc(sizeof(unsigned long));
76 WFrameWindow
*wFrameWindowCreate(WScreen
* scr
, int wlevel
, int x
, int y
,
77 int width
, int height
, int *clearance
,
78 int *title_min
, int *title_max
, int flags
,
79 WTexture
** title_texture
, WTexture
** resize_texture
,
80 WMColor
** color
, WMFont
** font
,
81 int depth
, Visual
*visual
, Colormap colormap
)
85 fwin
= wmalloc(sizeof(WFrameWindow
));
87 fwin
->screen_ptr
= scr
;
89 fwin
->flags
.single_texture
= (flags
& WFF_SINGLE_STATE
) ? 1 : 0;
91 fwin
->title_texture
= title_texture
;
92 fwin
->resizebar_texture
= resize_texture
;
93 fwin
->title_color
= color
;
94 fwin
->title_clearance
= clearance
;
95 fwin
->title_min_height
= title_min
;
96 fwin
->title_max_height
= title_max
;
98 #ifdef KEEP_XKB_LOCK_STATUS
99 fwin
->languagemode
= XkbGroup1Index
;
100 fwin
->last_languagemode
= XkbGroup2Index
;
104 fwin
->visual
= visual
;
105 fwin
->colormap
= colormap
;
107 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
108 ? scr
->frame_border_width
: 0, fwin
->depth
, fwin
->visual
, fwin
->colormap
, scr
->frame_border_pixel
);
110 /* setup stacking information */
111 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
112 fwin
->core
->stacking
->above
= NULL
;
113 fwin
->core
->stacking
->under
= NULL
;
114 fwin
->core
->stacking
->child_of
= NULL
;
115 fwin
->core
->stacking
->window_level
= wlevel
;
117 AddToStackList(fwin
->core
);
119 wFrameWindowUpdateBorders(fwin
, flags
);
124 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
130 WScreen
*scr
= fwin
->screen_ptr
;
132 width
= fwin
->core
->width
;
133 if (flags
& WFF_IS_SHADED
)
136 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
138 if (flags
& WFF_TITLEBAR
) {
139 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
141 if (theight
> *fwin
->title_max_height
)
142 theight
= *fwin
->title_max_height
;
144 if (theight
< *fwin
->title_min_height
)
145 theight
= *fwin
->title_min_height
;
150 if (wPreferences
.new_style
== TS_NEW
) {
152 } else if (wPreferences
.new_style
== TS_OLD
) {
158 if (fwin
->titlebar
) {
159 /* if we had a titlebar and is requesting for one,
160 * check if the size has changed and resize it */
161 if (flags
& WFF_TITLEBAR
) {
162 fwin
->top_width
= theight
;
164 fwin
->flags
.need_texture_remake
= 1;
166 if (wPreferences
.new_style
== TS_NEW
) {
167 if (fwin
->left_button
)
168 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
169 #ifdef XKB_BUTTON_HINT
170 if (fwin
->language_button
) {
171 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
172 || fwin
->flags
.lbutton_dont_fit
)
173 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
175 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
179 if (fwin
->right_button
)
180 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
182 } else { /* !new_style */
183 if (fwin
->left_button
)
184 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
185 #ifdef XKB_BUTTON_HINT
186 if (fwin
->language_button
)
187 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
191 if (fwin
->right_button
)
192 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
193 (theight
- bsize
) / 2, bsize
, bsize
);
195 updateTitlebar(fwin
);
197 /* we had a titlebar, but now we don't need it anymore */
198 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
199 FREE_PIXMAP(fwin
->title_back
[i
]);
200 if (wPreferences
.new_style
== TS_NEW
) {
201 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
202 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
203 #ifdef XKB_BUTTON_HINT
204 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
208 if (fwin
->left_button
)
209 wCoreDestroy(fwin
->left_button
);
210 fwin
->left_button
= NULL
;
212 #ifdef XKB_BUTTON_HINT
213 if (fwin
->language_button
)
214 wCoreDestroy(fwin
->language_button
);
215 fwin
->language_button
= NULL
;
218 if (fwin
->right_button
)
219 wCoreDestroy(fwin
->right_button
);
220 fwin
->right_button
= NULL
;
222 wCoreDestroy(fwin
->titlebar
);
223 fwin
->titlebar
= NULL
;
228 /* if we didn't have a titlebar and are being requested for
230 if (flags
& WFF_TITLEBAR
) {
231 fwin
->top_width
= theight
;
233 fwin
->flags
.titlebar
= 1;
234 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
236 if (flags
& WFF_LEFT_BUTTON
) {
237 fwin
->flags
.left_button
= 1;
238 if (wPreferences
.new_style
== TS_NEW
) {
239 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
241 if (width
< theight
* 4)
242 fwin
->flags
.lbutton_dont_fit
= 1;
244 XMapRaised(dpy
, fwin
->left_button
->window
);
246 } else if (wPreferences
.new_style
== TS_OLD
) {
248 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
250 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
251 scr
->widget_texture
->normal
.pixel
);
253 if (width
< theight
* 3)
254 fwin
->flags
.lbutton_dont_fit
= 1;
256 XMapRaised(dpy
, fwin
->left_button
->window
);
260 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
263 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
264 scr
->widget_texture
->dark
.pixel
);
266 if (width
< theight
* 3)
267 fwin
->flags
.lbutton_dont_fit
= 1;
269 XMapRaised(dpy
, fwin
->left_button
->window
);
273 #ifdef XKB_BUTTON_HINT
274 if (flags
& WFF_LANGUAGE_BUTTON
) {
275 fwin
->flags
.language_button
= 1;
276 if (wPreferences
.new_style
== TS_NEW
) {
277 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
279 if (width
< theight
* 4)
280 fwin
->flags
.languagebutton_dont_fit
= 1;
282 XMapRaised(dpy
, fwin
->language_button
->window
);
284 fwin
->language_button
=
285 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
288 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
289 scr
->widget_texture
->normal
.pixel
);
291 if (width
< theight
* 3)
292 fwin
->flags
.languagebutton_dont_fit
= 1;
294 XMapRaised(dpy
, fwin
->language_button
->window
);
299 if (flags
& WFF_RIGHT_BUTTON
) {
300 fwin
->flags
.right_button
= 1;
301 if (wPreferences
.new_style
== TS_NEW
) {
303 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
304 } else if (wPreferences
.new_style
== TS_OLD
) {
306 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
307 (theight
- bsize
) / 2, bsize
, bsize
);
308 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
309 scr
->widget_texture
->normal
.pixel
);
312 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
313 (theight
-bsize
)/2, bsize
, bsize
);
314 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
315 scr
->widget_texture
->dark
.pixel
);
318 if (width
< theight
* 2)
319 fwin
->flags
.rbutton_dont_fit
= 1;
321 XMapRaised(dpy
, fwin
->right_button
->window
);
324 if (wPreferences
.new_style
== TS_NEW
)
325 updateTitlebar(fwin
);
327 XMapRaised(dpy
, fwin
->titlebar
->window
);
329 fwin
->flags
.need_texture_remake
= 1;
332 checkTitleSize(fwin
);
334 if (flags
& WFF_RESIZEBAR
) {
335 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
337 if (!fwin
->resizebar
) {
338 fwin
->flags
.resizebar
= 1;
339 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
340 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
341 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
342 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
343 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
344 if (fwin
->resizebar_corner_width
< 0)
345 fwin
->resizebar_corner_width
= 0;
348 XMapWindow(dpy
, fwin
->resizebar
->window
);
349 XLowerWindow(dpy
, fwin
->resizebar
->window
);
351 fwin
->flags
.need_texture_remake
= 1;
353 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
)
354 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
355 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
);
370 if (flags
& WFF_BORDER
)
371 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, scr
->frame_border_width
);
373 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
375 /* setup object descriptors */
376 if (fwin
->titlebar
) {
377 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
378 fwin
->titlebar
->descriptor
.parent
= fwin
;
379 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
380 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
383 if (fwin
->resizebar
) {
384 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
385 fwin
->resizebar
->descriptor
.parent
= fwin
;
386 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
387 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
390 if (fwin
->left_button
) {
391 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
392 fwin
->left_button
->descriptor
.parent
= fwin
;
393 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
394 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
397 #ifdef XKB_BUTTON_HINT
398 if (fwin
->language_button
) {
399 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
400 fwin
->language_button
->descriptor
.parent
= fwin
;
401 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
402 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
406 if (fwin
->right_button
) {
407 fwin
->right_button
->descriptor
.parent
= fwin
;
408 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
409 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
410 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
413 checkTitleSize(fwin
);
415 allocFrameBorderPixel(fwin
->colormap
, WMGetColorRGBDescription(scr
->frame_border_color
), &fwin
->border_pixel
);
416 allocFrameBorderPixel(fwin
->colormap
, WMGetColorRGBDescription(scr
->frame_focused_border_color
), &fwin
->focused_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
->flags
.state
== WS_FOCUSED
) {
425 if (fwin
->focused_border_pixel
)
426 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->focused_border_pixel
);
428 if (fwin
->border_pixel
)
429 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->border_pixel
);
434 void wFrameWindowDestroy(WFrameWindow
* fwin
)
438 if (fwin
->left_button
)
439 wCoreDestroy(fwin
->left_button
);
441 #ifdef XKB_BUTTON_HINT
442 if (fwin
->language_button
)
443 wCoreDestroy(fwin
->language_button
);
446 if (fwin
->right_button
)
447 wCoreDestroy(fwin
->right_button
);
450 wCoreDestroy(fwin
->resizebar
);
453 wCoreDestroy(fwin
->titlebar
);
455 RemoveFromStackList(fwin
->core
);
457 wCoreDestroy(fwin
->core
);
462 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
463 FREE_PIXMAP(fwin
->title_back
[i
]);
464 if (wPreferences
.new_style
== TS_NEW
) {
465 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
466 #ifdef XKB_BUTTON_HINT
467 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
469 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
476 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
478 if (fwin
->flags
.state
== state
)
481 fwin
->flags
.state
= state
;
482 fwin
->flags
.need_texture_change
= 1;
484 if (fwin
->flags
.state
== WS_FOCUSED
) {
485 if (fwin
->focused_border_pixel
)
486 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->focused_border_pixel
);
488 if (fwin
->border_pixel
)
489 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->border_pixel
);
491 wFrameWindowPaint(fwin
);
494 static void updateTitlebar(WFrameWindow
* fwin
)
499 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
501 if (theight
> *fwin
->title_max_height
)
502 theight
= *fwin
->title_max_height
;
504 if (theight
< *fwin
->title_min_height
)
505 theight
= *fwin
->title_min_height
;
508 w
= fwin
->core
->width
+ 1;
510 if (wPreferences
.new_style
== TS_NEW
) {
511 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
513 #ifdef XKB_BUTTON_HINT
514 if (fwin
->language_button
)
515 wCoreConfigure(fwin
->language_button
, 0, 0,
516 fwin
->language_button
->width
, fwin
->language_button
->width
);
519 #ifdef XKB_BUTTON_HINT
520 if (fwin
->language_button
)
521 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
522 fwin
->language_button
->width
, fwin
->language_button
->width
);
524 x
= fwin
->left_button
->width
;
525 w
-= fwin
->left_button
->width
;
527 #ifdef XKB_BUTTON_HINT
528 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
529 || fwin
->flags
.languagebutton_dont_fit
) {
531 x
+= fwin
->language_button
->width
;
532 w
-= fwin
->language_button
->width
;
536 #ifdef XKB_BUTTON_HINT
538 int bsize
= theight
- 7;
539 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
540 if (fwin
->language_button
)
541 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
542 fwin
->language_button
->width
, fwin
->language_button
->width
);
544 if (fwin
->language_button
)
545 wCoreConfigure(fwin
->language_button
,
546 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
547 fwin
->language_button
->width
, fwin
->language_button
->width
);
552 if (wPreferences
.new_style
== TS_NEW
) {
553 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
)
554 w
-= fwin
->right_button
->width
;
557 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
558 fwin
->flags
.need_texture_remake
= 1;
560 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
563 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
565 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
566 XUnmapWindow(dpy
, fwin
->right_button
->window
);
567 fwin
->flags
.hide_right_button
= 1;
570 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
571 XUnmapWindow(dpy
, fwin
->left_button
->window
);
572 fwin
->flags
.hide_left_button
= 1;
574 #ifdef XKB_BUTTON_HINT
575 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
576 XUnmapWindow(dpy
, fwin
->language_button
->window
);
577 fwin
->flags
.hide_language_button
= 1;
581 if (fwin
->titlebar
) {
582 if (wPreferences
.new_style
== TS_NEW
) {
583 updateTitlebar(fwin
);
585 #ifdef XKB_BUTTON_HINT
586 updateTitlebar(fwin
);
588 XClearWindow(dpy
, fwin
->titlebar
->window
);
589 wFrameWindowPaint(fwin
);
592 checkTitleSize(fwin
);
596 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
598 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
600 if (!fwin
->flags
.rbutton_dont_fit
)
601 XMapWindow(dpy
, fwin
->right_button
->window
);
603 fwin
->flags
.hide_right_button
= 0;
605 #ifdef XKB_BUTTON_HINT
606 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
608 if (!fwin
->flags
.languagebutton_dont_fit
)
609 XMapWindow(dpy
, fwin
->language_button
->window
);
611 fwin
->flags
.hide_language_button
= 0;
615 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
617 if (!fwin
->flags
.lbutton_dont_fit
)
618 XMapWindow(dpy
, fwin
->left_button
->window
);
620 fwin
->flags
.hide_left_button
= 0;
623 if (fwin
->titlebar
) {
624 if (wPreferences
.new_style
== TS_NEW
) {
625 updateTitlebar(fwin
);
627 XClearWindow(dpy
, fwin
->titlebar
->window
);
628 wFrameWindowPaint(fwin
);
630 checkTitleSize(fwin
);
635 #ifdef XKB_BUTTON_HINT
636 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
637 int bwidth
, int bheight
, int left
, int language
, int right
,
638 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
640 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
641 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
645 RImage
*limg
, *rimg
, *mimg
;
646 #ifdef XKB_BUTTON_HINT
654 #ifdef XKB_BUTTON_HINT
655 *languagebutton
= None
;
658 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
660 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
664 if (wPreferences
.new_style
== TS_NEW
) {
666 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
673 #ifdef XKB_BUTTON_HINT
675 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
681 RBevelImage(limg
, RBEV_RAISED2
);
682 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
))
683 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
689 #ifdef XKB_BUTTON_HINT
691 RBevelImage(timg
, RBEV_RAISED2
);
692 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
))
693 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
702 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
707 RBevelImage(rimg
, RBEV_RAISED2
);
708 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
))
709 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
716 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
717 RBevelImage(mimg
, RBEV_RAISED2
);
719 if (!RConvertImage(scr
->rcontext
, mimg
, title
))
720 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
724 RBevelImage(img
, RBEV_RAISED2
);
726 if (!RConvertImage(scr
->rcontext
, img
, title
))
727 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
730 RBevelImage(img
, RBEV_RAISED2
);
732 if (!RConvertImage(scr
->rcontext
, img
, title
))
733 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
740 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
748 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
750 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
755 light
.red
= light
.green
= light
.blue
= 80;
758 dark
.red
= dark
.green
= dark
.blue
= 40;
760 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
761 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
763 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
764 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
767 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
768 width
- cwidth
- 2, height
- 1, &dark
);
769 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
771 #ifdef SHADOW_RESIZEBAR
772 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
773 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
774 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
775 #endif /* SHADOW_RESIZEBAR */
777 if (!RConvertImage(scr
->rcontext
, img
, pmap
))
778 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
783 static void updateTexture(WFrameWindow
* fwin
)
788 i
= fwin
->flags
.state
;
789 if (fwin
->titlebar
) {
790 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
791 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
792 if (wPreferences
.new_style
== TS_NEW
) {
793 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
794 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
795 fwin
->lbutton_back
[i
]);
797 #ifdef XKB_BUTTON_HINT
798 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
])
799 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
800 fwin
->languagebutton_back
[i
]);
803 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
804 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
805 fwin
->rbutton_back
[i
]);
808 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
809 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
810 if (wPreferences
.new_style
== TS_NEW
) {
811 if (fwin
->left_button
)
812 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
813 #ifdef XKB_BUTTON_HINT
814 if (fwin
->language_button
)
815 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
817 if (fwin
->right_button
)
818 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
821 XClearWindow(dpy
, fwin
->titlebar
->window
);
823 if (fwin
->left_button
) {
824 XClearWindow(dpy
, fwin
->left_button
->window
);
825 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
827 #ifdef XKB_BUTTON_HINT
828 if (fwin
->language_button
) {
829 XClearWindow(dpy
, fwin
->language_button
->window
);
830 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
833 if (fwin
->right_button
) {
834 XClearWindow(dpy
, fwin
->right_button
->window
);
835 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
840 static void remakeTexture(WFrameWindow
* fwin
, int state
)
842 Pixmap pmap
, lpmap
, rpmap
;
843 #ifdef XKB_BUTTON_HINT
847 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
848 FREE_PIXMAP(fwin
->title_back
[state
]);
849 if (wPreferences
.new_style
== TS_NEW
) {
850 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
851 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
852 #ifdef XKB_BUTTON_HINT
853 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
857 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
860 #ifdef XKB_BUTTON_HINT
864 /* eventually surrounded by if new_style */
865 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
866 #ifdef XKB_BUTTON_HINT
867 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
868 && !fwin
->flags
.languagebutton_dont_fit
;
870 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
871 && !fwin
->flags
.rbutton_dont_fit
;
873 width
= fwin
->core
->width
+ 1;
875 #ifdef XKB_BUTTON_HINT
876 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
877 width
, fwin
->titlebar
->height
,
878 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
879 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
881 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
882 width
, fwin
->titlebar
->height
,
883 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
884 left
, right
, &pmap
, &lpmap
, &rpmap
);
887 fwin
->title_back
[state
] = pmap
;
888 if (wPreferences
.new_style
== TS_NEW
) {
889 fwin
->lbutton_back
[state
] = lpmap
;
890 fwin
->rbutton_back
[state
] = rpmap
;
891 #ifdef XKB_BUTTON_HINT
892 fwin
->languagebutton_back
[state
] = tpmap
;
897 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
898 && fwin
->resizebar
&& state
== 0) {
900 FREE_PIXMAP(fwin
->resizebar_back
[0]);
902 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
904 renderResizebarTexture(fwin
->screen_ptr
,
905 fwin
->resizebar_texture
[0],
906 fwin
->resizebar
->width
,
907 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
909 fwin
->resizebar_back
[0] = pmap
;
912 /* this part should be in updateTexture() */
913 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
)
914 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
916 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
917 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
919 XClearWindow(dpy
, fwin
->resizebar
->window
);
923 void wFrameWindowPaint(WFrameWindow
* fwin
)
925 WScreen
*scr
= fwin
->screen_ptr
;
928 state
= fwin
->flags
.state
;
930 if (fwin
->flags
.is_client_window_frame
)
931 fwin
->flags
.justification
= wPreferences
.title_justification
;
933 if (fwin
->flags
.need_texture_remake
) {
936 fwin
->flags
.need_texture_remake
= 0;
937 fwin
->flags
.need_texture_change
= 0;
939 if (fwin
->flags
.single_texture
) {
940 remakeTexture(fwin
, 0);
943 /* first render the texture for the current state... */
944 remakeTexture(fwin
, state
);
945 /* ... and paint it */
948 for (i
= 0; i
< 3; i
++) {
950 remakeTexture(fwin
, i
);
955 if (fwin
->flags
.need_texture_change
) {
956 fwin
->flags
.need_texture_change
= 0;
961 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
962 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
963 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
964 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
967 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
968 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
973 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
975 w
= fwin
->resizebar
->width
;
976 h
= fwin
->resizebar
->height
;
977 cw
= fwin
->resizebar_corner_width
;
978 light_gc
= texture
->light_gc
;
979 dim_gc
= texture
->dim_gc
;
980 win
= fwin
->resizebar
->window
;
982 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
983 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
985 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
986 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
988 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
989 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
991 #ifdef SHADOW_RESIZEBAR
992 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
993 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
994 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
995 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
996 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
997 #endif /* SHADOW_RESIZEBAR */
1000 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
1002 int lofs
= 6, rofs
= 6;
1006 if (!wPreferences
.new_style
== TS_NEW
) {
1007 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1008 lofs
+= fwin
->left_button
->width
+ 3;
1012 #ifdef XKB_BUTTON_HINT
1013 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1014 && !fwin
->flags
.languagebutton_dont_fit
)
1015 lofs
+= fwin
->language_button
->width
;
1020 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1021 rofs
+= fwin
->right_button
->width
+ 3;
1025 #ifdef XKB_BUTTON_HINT
1026 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1033 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
1034 titlelen
= strlen(title
);
1035 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1037 switch (fwin
->flags
.justification
) {
1043 x
= fwin
->titlebar
->width
- w
- rofs
;
1048 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1050 x
= (fwin
->titlebar
->width
- w
) / 2;
1054 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1055 h
= WMFontHeight(*fwin
->font
);
1057 if (y
*2 + h
> *fwin
->title_max_height
)
1058 y
= (*fwin
->title_max_height
- h
) / 2;
1060 if (y
*2 + h
< *fwin
->title_min_height
)
1061 y
= (*fwin
->title_min_height
- h
) / 2;
1063 /* We use a w+2 buffer to have an extra pixel on the left and
1064 * another one on the right. This is because for some odd reason,
1065 * sometimes when using AA fonts (when libfreetype2 is compiled
1066 * with bytecode interpreter turned off), some fonts are drawn
1067 * starting from x = -1 not from 0 as requested. Observed with
1068 * capital A letter on the bold 'trebuchet ms' font. -Dan
1070 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1072 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1074 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1075 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1076 x
- 1, y
, w
+ 2, h
, 0, 0);
1078 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1079 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1082 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1083 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1084 *fwin
->font
, 1, 0, title
, titlelen
);
1086 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1088 XFreePixmap(dpy
, buf
);
1093 if (fwin
->left_button
)
1094 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1095 if (fwin
->right_button
)
1096 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1097 #ifdef XKB_BUTTON_HINT
1098 if (fwin
->language_button
)
1099 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1104 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1106 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1107 int resizedHorizontally
= 0;
1110 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1112 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1114 if (fwin
->core
->width
!= width
) {
1115 fwin
->flags
.need_texture_remake
= 1;
1116 resizedHorizontally
= 1;
1119 fwin
->core
->width
= width
;
1120 fwin
->core
->height
= height
;
1122 if (fwin
->titlebar
&& resizedHorizontally
) {
1123 /* Check if the titlebar is wide enough to hold the buttons.
1124 * Temporarily remove them if can't
1126 if (fwin
->left_button
) {
1127 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1128 if (!fwin
->flags
.hide_left_button
)
1129 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1131 fwin
->flags
.lbutton_dont_fit
= 1;
1132 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1133 if (!fwin
->flags
.hide_left_button
)
1134 XMapWindow(dpy
, fwin
->left_button
->window
);
1136 fwin
->flags
.lbutton_dont_fit
= 0;
1139 #ifdef XKB_BUTTON_HINT
1140 if (fwin
->language_button
) {
1141 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1142 if (!fwin
->flags
.hide_language_button
)
1143 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1145 fwin
->flags
.languagebutton_dont_fit
= 1;
1146 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1147 if (!fwin
->flags
.hide_language_button
)
1148 XMapWindow(dpy
, fwin
->language_button
->window
);
1150 fwin
->flags
.languagebutton_dont_fit
= 0;
1155 if (fwin
->right_button
) {
1156 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1157 if (!fwin
->flags
.hide_right_button
)
1158 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1160 fwin
->flags
.rbutton_dont_fit
= 1;
1161 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1162 if (!fwin
->flags
.hide_right_button
)
1163 XMapWindow(dpy
, fwin
->right_button
->window
);
1165 fwin
->flags
.rbutton_dont_fit
= 0;
1169 if (wPreferences
.new_style
== TS_NEW
) {
1170 if (fwin
->right_button
)
1171 XMoveWindow(dpy
, fwin
->right_button
->window
,
1172 width
- fwin
->right_button
->width
+ 1, 0);
1174 if (fwin
->right_button
)
1175 XMoveWindow(dpy
, fwin
->right_button
->window
,
1176 width
- fwin
->right_button
->width
- 3,
1177 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1179 updateTitlebar(fwin
);
1180 checkTitleSize(fwin
);
1183 if (fwin
->resizebar
) {
1184 wCoreConfigure(fwin
->resizebar
, 0,
1185 fwin
->core
->height
- fwin
->resizebar
->height
,
1186 fwin
->core
->width
, fwin
->resizebar
->height
);
1188 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1189 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
)
1190 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1194 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1196 reconfigure(fwin
, x
, y
, width
, height
, False
);
1199 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1201 reconfigure(fwin
, 0, 0, width
, height
, True
);
1204 int wFrameWindowChangeTitle(WFrameWindow
*fwin
, const char *new_title
)
1206 if (new_title
== NULL
)
1209 /* check if the title is the same as before */
1211 if (strcmp(fwin
->title
, new_title
) == 0)
1218 fwin
->title
= wstrdup(new_title
);
1220 if (fwin
->titlebar
) {
1221 XClearWindow(dpy
, fwin
->titlebar
->window
);
1223 wFrameWindowPaint(fwin
);
1225 checkTitleSize(fwin
);
1230 #ifdef XKB_BUTTON_HINT
1231 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1233 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1234 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1236 #endif /* XKB_BUTTON_HINT */
1238 /*********************************************************************/
1240 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1242 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1244 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1245 fwin
->flags
.repaint_only_titlebar
= 1;
1246 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1247 fwin
->flags
.repaint_only_resizebar
= 1;
1248 wFrameWindowPaint(fwin
);
1249 fwin
->flags
.repaint_only_titlebar
= 0;
1250 fwin
->flags
.repaint_only_resizebar
= 0;
1253 static void checkTitleSize(WFrameWindow
* fwin
)
1258 fwin
->flags
.incomplete_title
= 0;
1262 if (!fwin
->titlebar
) {
1263 fwin
->flags
.incomplete_title
= 1;
1266 width
= fwin
->titlebar
->width
- 6 - 6;
1269 if (!wPreferences
.new_style
== TS_NEW
) {
1270 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1271 width
-= fwin
->left_button
->width
+ 3;
1273 #ifdef XKB_BUTTON_HINT
1274 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1275 && !fwin
->flags
.languagebutton_dont_fit
)
1276 width
-= fwin
->language_button
->width
+ 3;
1279 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1280 width
-= fwin
->right_button
->width
+ 3;
1283 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
)
1284 fwin
->flags
.incomplete_title
= 1;
1286 fwin
->flags
.incomplete_title
= 0;
1289 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1291 WScreen
*scr
= button
->screen_ptr
;
1292 GC copy_gc
= scr
->copy_gc
;
1293 int x
= 0, y
= 0, d
= 0;
1294 int left
= 0, width
= 0;
1296 /* setup stuff according to the state */
1299 if (image
->width
>= image
->height
* 2) {
1300 /* the image contains 2 pictures: the second is for the
1302 width
= image
->width
/ 2;
1303 left
= image
->width
/ 2;
1305 width
= image
->width
;
1308 XSetClipMask(dpy
, copy_gc
, None
);
1309 if (wPreferences
.new_style
== TS_NEXT
)
1310 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1312 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1315 if (wPreferences
.new_style
== TS_NEW
) {
1316 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1317 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1318 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1319 } else if (wPreferences
.new_style
== TS_OLD
) {
1320 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1321 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1322 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1324 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1325 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1326 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1329 XClearWindow(dpy
, button
->window
);
1332 if (image
->width
>= image
->height
* 2)
1333 width
= image
->width
/ 2;
1335 width
= image
->width
;
1339 if (wPreferences
.new_style
== TS_NEW
) {
1340 if (texture
->any
.type
== WTEX_SOLID
|| pushed
)
1341 wDrawBevel(button
->window
, button
->width
, button
->height
,
1342 (WTexSolid
*) texture
, WREL_RAISED
);
1344 wDrawBevel(button
->window
, button
->width
, button
->height
,
1345 scr
->widget_texture
, WREL_RAISED
);
1351 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1352 x
= (button
->width
- width
) / 2 + d
;
1353 y
= (button
->height
- image
->height
) / 2 + d
;
1354 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1355 if (!wPreferences
.new_style
== TS_NEW
) {
1356 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1358 if (image
->depth
== 1)
1359 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1360 left
, 0, width
, image
->height
, x
, y
, 1);
1362 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1363 left
, 0, width
, image
->height
, x
, y
);
1365 if (wPreferences
.new_style
== TS_OLD
) {
1366 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1367 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1368 button
->width
, button
->height
);
1370 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1371 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1372 left
, 0, width
, image
->height
, x
, y
);
1377 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1379 XSetForeground(dpy
, copy_gc
, color
);
1380 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1382 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1387 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1389 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1390 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1392 /* Parameter not used, but tell the compiler that it is ok */
1395 #ifdef XKB_BUTTON_HINT
1396 if (button
== fwin
->language_button
) {
1397 if (wPreferences
.modelock
)
1398 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1399 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1400 fwin
->languagebutton_image
, False
);
1403 if (button
== fwin
->left_button
)
1404 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1405 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1407 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1408 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1411 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1413 WFrameWindow
*fwin
= desc
->parent
;
1414 WCoreWindow
*titlebar
= desc
->self
;
1416 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1417 if (fwin
->on_dblclick_titlebar
)
1418 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1420 if (fwin
->on_mousedown_titlebar
)
1421 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1425 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1427 WFrameWindow
*fwin
= desc
->parent
;
1428 WCoreWindow
*resizebar
= desc
->self
;
1430 if (fwin
->on_mousedown_resizebar
)
1431 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1434 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1436 WFrameWindow
*fwin
= desc
->parent
;
1437 WCoreWindow
*button
= desc
->self
;
1440 int done
= 0, execute
= 1;
1442 unsigned long pixel
;
1443 int clickButton
= event
->xbutton
.button
;
1445 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1446 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
)
1447 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1452 if (button
== fwin
->left_button
)
1453 image
= fwin
->lbutton_image
;
1455 image
= fwin
->rbutton_image
;
1457 #ifdef XKB_BUTTON_HINT
1458 if (button
== fwin
->language_button
) {
1459 if (!wPreferences
.modelock
)
1461 image
= fwin
->languagebutton_image
;
1465 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1466 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1467 paintButton(button
, texture
, pixel
, image
, True
);
1470 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1471 | ButtonPressMask
| ExposureMask
, &ev
);
1475 paintButton(button
, texture
, pixel
, image
, False
);
1480 paintButton(button
, texture
, pixel
, image
, True
);
1487 if (ev
.xbutton
.button
== clickButton
)
1495 paintButton(button
, texture
, pixel
, image
, False
);
1498 if (button
== fwin
->left_button
) {
1499 if (fwin
->on_click_left
)
1500 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1501 } else if (button
== fwin
->right_button
) {
1502 if (fwin
->on_click_right
)
1503 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1505 #ifdef XKB_BUTTON_HINT
1506 else if (button
== fwin
->language_button
) {
1507 if (fwin
->on_click_language
)
1508 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);