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"
46 #define DBLCLICK_TIME wPreferences.dblclick_time
48 extern WPreferences wPreferences
;
50 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
);
51 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
);
53 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
54 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
55 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
57 static void checkTitleSize(WFrameWindow
* fwin
);
59 static void paintButton(WCoreWindow
* button
, WTexture
* texture
,
60 unsigned long color
, WPixmap
* image
, int pushed
);
62 static void updateTitlebar(WFrameWindow
* fwin
);
64 static void allocFrameBorderPixel(Colormap colormap
, char *color_name
, unsigned long **pixel
);
66 static void allocFrameBorderPixel(Colormap colormap
, char *color_name
, unsigned long **pixel
) {
71 if (! wGetColorForColormap(colormap
, color_name
, &xcol
))
74 *pixel
= wmalloc(sizeof(unsigned long));
79 WFrameWindow
*wFrameWindowCreate(WScreen
* scr
, int wlevel
, int x
, int y
,
80 int width
, int height
, int *clearance
,
81 int *title_min
, int *title_max
, int flags
,
82 WTexture
** title_texture
, WTexture
** resize_texture
,
83 WMColor
** color
, WMFont
** font
,
84 int depth
, Visual
*visual
, Colormap colormap
)
88 fwin
= wmalloc(sizeof(WFrameWindow
));
90 fwin
->screen_ptr
= scr
;
92 fwin
->flags
.single_texture
= (flags
& WFF_SINGLE_STATE
) ? 1 : 0;
94 fwin
->title_texture
= title_texture
;
95 fwin
->resizebar_texture
= resize_texture
;
96 fwin
->title_color
= color
;
97 fwin
->title_clearance
= clearance
;
98 fwin
->title_min_height
= title_min
;
99 fwin
->title_max_height
= title_max
;
101 #ifdef KEEP_XKB_LOCK_STATUS
102 fwin
->languagemode
= XkbGroup1Index
;
103 fwin
->last_languagemode
= XkbGroup2Index
;
107 fwin
->visual
= visual
;
108 fwin
->colormap
= colormap
;
110 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
111 ? scr
->frame_border_width
: 0, fwin
->depth
, fwin
->visual
, fwin
->colormap
, scr
->frame_border_pixel
);
113 /* setup stacking information */
114 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
115 fwin
->core
->stacking
->above
= NULL
;
116 fwin
->core
->stacking
->under
= NULL
;
117 fwin
->core
->stacking
->child_of
= NULL
;
118 fwin
->core
->stacking
->window_level
= wlevel
;
120 AddToStackList(fwin
->core
);
122 wFrameWindowUpdateBorders(fwin
, flags
);
127 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
133 WScreen
*scr
= fwin
->screen_ptr
;
135 width
= fwin
->core
->width
;
136 if (flags
& WFF_IS_SHADED
)
139 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
141 if (flags
& WFF_TITLEBAR
) {
142 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
144 if (theight
> *fwin
->title_max_height
)
145 theight
= *fwin
->title_max_height
;
147 if (theight
< *fwin
->title_min_height
)
148 theight
= *fwin
->title_min_height
;
153 if (wPreferences
.new_style
== TS_NEW
) {
155 } else if (wPreferences
.new_style
== TS_OLD
) {
161 if (fwin
->titlebar
) {
162 /* if we had a titlebar and is requesting for one,
163 * check if the size has changed and resize it */
164 if (flags
& WFF_TITLEBAR
) {
165 fwin
->top_width
= theight
;
167 fwin
->flags
.need_texture_remake
= 1;
169 if (wPreferences
.new_style
== TS_NEW
) {
170 if (fwin
->left_button
)
171 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
172 #ifdef XKB_BUTTON_HINT
173 if (fwin
->language_button
) {
174 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
175 || fwin
->flags
.lbutton_dont_fit
)
176 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
178 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
182 if (fwin
->right_button
)
183 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
185 } else { /* !new_style */
186 if (fwin
->left_button
)
187 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
188 #ifdef XKB_BUTTON_HINT
189 if (fwin
->language_button
)
190 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
194 if (fwin
->right_button
)
195 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
196 (theight
- bsize
) / 2, bsize
, bsize
);
198 updateTitlebar(fwin
);
200 /* we had a titlebar, but now we don't need it anymore */
201 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
202 FREE_PIXMAP(fwin
->title_back
[i
]);
203 if (wPreferences
.new_style
== TS_NEW
) {
204 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
205 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
206 #ifdef XKB_BUTTON_HINT
207 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
211 if (fwin
->left_button
)
212 wCoreDestroy(fwin
->left_button
);
213 fwin
->left_button
= NULL
;
215 #ifdef XKB_BUTTON_HINT
216 if (fwin
->language_button
)
217 wCoreDestroy(fwin
->language_button
);
218 fwin
->language_button
= NULL
;
221 if (fwin
->right_button
)
222 wCoreDestroy(fwin
->right_button
);
223 fwin
->right_button
= NULL
;
225 wCoreDestroy(fwin
->titlebar
);
226 fwin
->titlebar
= NULL
;
231 /* if we didn't have a titlebar and are being requested for
233 if (flags
& WFF_TITLEBAR
) {
234 fwin
->top_width
= theight
;
236 fwin
->flags
.titlebar
= 1;
237 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
239 if (flags
& WFF_LEFT_BUTTON
) {
240 fwin
->flags
.left_button
= 1;
241 if (wPreferences
.new_style
== TS_NEW
) {
242 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
244 if (width
< theight
* 4)
245 fwin
->flags
.lbutton_dont_fit
= 1;
247 XMapRaised(dpy
, fwin
->left_button
->window
);
249 } else if (wPreferences
.new_style
== TS_OLD
) {
251 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
253 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
254 scr
->widget_texture
->normal
.pixel
);
256 if (width
< theight
* 3)
257 fwin
->flags
.lbutton_dont_fit
= 1;
259 XMapRaised(dpy
, fwin
->left_button
->window
);
263 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
266 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
267 scr
->widget_texture
->dark
.pixel
);
269 if (width
< theight
* 3)
270 fwin
->flags
.lbutton_dont_fit
= 1;
272 XMapRaised(dpy
, fwin
->left_button
->window
);
276 #ifdef XKB_BUTTON_HINT
277 if (flags
& WFF_LANGUAGE_BUTTON
) {
278 fwin
->flags
.language_button
= 1;
279 if (wPreferences
.new_style
== TS_NEW
) {
280 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
282 if (width
< theight
* 4)
283 fwin
->flags
.languagebutton_dont_fit
= 1;
285 XMapRaised(dpy
, fwin
->language_button
->window
);
287 fwin
->language_button
=
288 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
291 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
292 scr
->widget_texture
->normal
.pixel
);
294 if (width
< theight
* 3)
295 fwin
->flags
.languagebutton_dont_fit
= 1;
297 XMapRaised(dpy
, fwin
->language_button
->window
);
302 if (flags
& WFF_RIGHT_BUTTON
) {
303 fwin
->flags
.right_button
= 1;
304 if (wPreferences
.new_style
== TS_NEW
) {
306 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
307 } else if (wPreferences
.new_style
== TS_OLD
) {
309 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
310 (theight
- bsize
) / 2, bsize
, bsize
);
311 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
312 scr
->widget_texture
->normal
.pixel
);
315 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
316 (theight
-bsize
)/2, bsize
, bsize
);
317 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
318 scr
->widget_texture
->dark
.pixel
);
321 if (width
< theight
* 2)
322 fwin
->flags
.rbutton_dont_fit
= 1;
324 XMapRaised(dpy
, fwin
->right_button
->window
);
327 if (wPreferences
.new_style
== TS_NEW
)
328 updateTitlebar(fwin
);
330 XMapRaised(dpy
, fwin
->titlebar
->window
);
332 fwin
->flags
.need_texture_remake
= 1;
335 checkTitleSize(fwin
);
337 if (flags
& WFF_RESIZEBAR
) {
338 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
340 if (!fwin
->resizebar
) {
341 fwin
->flags
.resizebar
= 1;
342 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
343 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
344 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
345 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
346 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
347 if (fwin
->resizebar_corner_width
< 0)
348 fwin
->resizebar_corner_width
= 0;
351 XMapWindow(dpy
, fwin
->resizebar
->window
);
352 XLowerWindow(dpy
, fwin
->resizebar
->window
);
354 fwin
->flags
.need_texture_remake
= 1;
356 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
)
357 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
358 width
, RESIZEBAR_HEIGHT
);
361 fwin
->bottom_width
= 0;
363 if (fwin
->resizebar
) {
364 fwin
->bottom_width
= 0;
365 wCoreDestroy(fwin
->resizebar
);
366 fwin
->resizebar
= NULL
;
370 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
))
371 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
373 if (flags
& WFF_BORDER
)
374 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, scr
->frame_border_width
);
376 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
378 /* setup object descriptors */
379 if (fwin
->titlebar
) {
380 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
381 fwin
->titlebar
->descriptor
.parent
= fwin
;
382 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
383 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
386 if (fwin
->resizebar
) {
387 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
388 fwin
->resizebar
->descriptor
.parent
= fwin
;
389 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
390 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
393 if (fwin
->left_button
) {
394 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
395 fwin
->left_button
->descriptor
.parent
= fwin
;
396 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
397 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
400 #ifdef XKB_BUTTON_HINT
401 if (fwin
->language_button
) {
402 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
403 fwin
->language_button
->descriptor
.parent
= fwin
;
404 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
405 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
409 if (fwin
->right_button
) {
410 fwin
->right_button
->descriptor
.parent
= fwin
;
411 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
412 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
413 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
416 checkTitleSize(fwin
);
418 allocFrameBorderPixel(fwin
->colormap
, WMGetColorRGBDescription(scr
->frame_border_color
), &fwin
->border_pixel
);
419 allocFrameBorderPixel(fwin
->colormap
, WMGetColorRGBDescription(scr
->frame_selected_border_color
), &fwin
->selected_border_pixel
);
421 if (flags
& WFF_SELECTED
) {
422 if (fwin
->selected_border_pixel
)
423 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->selected_border_pixel
);
426 if (fwin
->border_pixel
)
427 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->border_pixel
);
431 void wFrameWindowDestroy(WFrameWindow
* fwin
)
435 if (fwin
->left_button
)
436 wCoreDestroy(fwin
->left_button
);
438 #ifdef XKB_BUTTON_HINT
439 if (fwin
->language_button
)
440 wCoreDestroy(fwin
->language_button
);
443 if (fwin
->right_button
)
444 wCoreDestroy(fwin
->right_button
);
447 wCoreDestroy(fwin
->resizebar
);
450 wCoreDestroy(fwin
->titlebar
);
452 RemoveFromStackList(fwin
->core
);
454 wCoreDestroy(fwin
->core
);
459 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
460 FREE_PIXMAP(fwin
->title_back
[i
]);
461 if (wPreferences
.new_style
== TS_NEW
) {
462 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
463 #ifdef XKB_BUTTON_HINT
464 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
466 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
473 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
475 if (fwin
->flags
.state
== state
)
478 fwin
->flags
.state
= state
;
479 fwin
->flags
.need_texture_change
= 1;
481 wFrameWindowPaint(fwin
);
484 static void updateTitlebar(WFrameWindow
* fwin
)
489 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
491 if (theight
> *fwin
->title_max_height
)
492 theight
= *fwin
->title_max_height
;
494 if (theight
< *fwin
->title_min_height
)
495 theight
= *fwin
->title_min_height
;
498 w
= fwin
->core
->width
+ 1;
500 if (wPreferences
.new_style
== TS_NEW
) {
501 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
503 #ifdef XKB_BUTTON_HINT
504 if (fwin
->language_button
)
505 wCoreConfigure(fwin
->language_button
, 0, 0,
506 fwin
->language_button
->width
, fwin
->language_button
->width
);
509 #ifdef XKB_BUTTON_HINT
510 if (fwin
->language_button
)
511 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
512 fwin
->language_button
->width
, fwin
->language_button
->width
);
514 x
= fwin
->left_button
->width
;
515 w
-= fwin
->left_button
->width
;
517 #ifdef XKB_BUTTON_HINT
518 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
519 || fwin
->flags
.languagebutton_dont_fit
) {
521 x
+= fwin
->language_button
->width
;
522 w
-= fwin
->language_button
->width
;
526 #ifdef XKB_BUTTON_HINT
528 int bsize
= theight
- 7;
529 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
530 if (fwin
->language_button
)
531 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
532 fwin
->language_button
->width
, fwin
->language_button
->width
);
534 if (fwin
->language_button
)
535 wCoreConfigure(fwin
->language_button
,
536 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
537 fwin
->language_button
->width
, fwin
->language_button
->width
);
542 if (wPreferences
.new_style
== TS_NEW
) {
543 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
)
544 w
-= fwin
->right_button
->width
;
547 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
548 fwin
->flags
.need_texture_remake
= 1;
550 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
553 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
555 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
556 XUnmapWindow(dpy
, fwin
->right_button
->window
);
557 fwin
->flags
.hide_right_button
= 1;
560 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
561 XUnmapWindow(dpy
, fwin
->left_button
->window
);
562 fwin
->flags
.hide_left_button
= 1;
564 #ifdef XKB_BUTTON_HINT
565 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
566 XUnmapWindow(dpy
, fwin
->language_button
->window
);
567 fwin
->flags
.hide_language_button
= 1;
571 if (fwin
->titlebar
) {
572 if (wPreferences
.new_style
== TS_NEW
) {
573 updateTitlebar(fwin
);
575 #ifdef XKB_BUTTON_HINT
576 updateTitlebar(fwin
);
578 XClearWindow(dpy
, fwin
->titlebar
->window
);
579 wFrameWindowPaint(fwin
);
582 checkTitleSize(fwin
);
586 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
588 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
590 if (!fwin
->flags
.rbutton_dont_fit
)
591 XMapWindow(dpy
, fwin
->right_button
->window
);
593 fwin
->flags
.hide_right_button
= 0;
595 #ifdef XKB_BUTTON_HINT
596 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
598 if (!fwin
->flags
.languagebutton_dont_fit
)
599 XMapWindow(dpy
, fwin
->language_button
->window
);
601 fwin
->flags
.hide_language_button
= 0;
605 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
607 if (!fwin
->flags
.lbutton_dont_fit
)
608 XMapWindow(dpy
, fwin
->left_button
->window
);
610 fwin
->flags
.hide_left_button
= 0;
613 if (fwin
->titlebar
) {
614 if (wPreferences
.new_style
== TS_NEW
) {
615 updateTitlebar(fwin
);
617 XClearWindow(dpy
, fwin
->titlebar
->window
);
618 wFrameWindowPaint(fwin
);
620 checkTitleSize(fwin
);
625 #ifdef XKB_BUTTON_HINT
626 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
627 int bwidth
, int bheight
, int left
, int language
, int right
,
628 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
630 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
631 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
635 RImage
*limg
, *rimg
, *mimg
;
636 #ifdef XKB_BUTTON_HINT
644 #ifdef XKB_BUTTON_HINT
645 *languagebutton
= None
;
648 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
650 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
654 if (wPreferences
.new_style
== TS_NEW
) {
656 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
663 #ifdef XKB_BUTTON_HINT
665 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
671 RBevelImage(limg
, RBEV_RAISED2
);
672 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
))
673 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
679 #ifdef XKB_BUTTON_HINT
681 RBevelImage(timg
, RBEV_RAISED2
);
682 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
))
683 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
692 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
697 RBevelImage(rimg
, RBEV_RAISED2
);
698 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
))
699 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
706 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
707 RBevelImage(mimg
, RBEV_RAISED2
);
709 if (!RConvertImage(scr
->rcontext
, mimg
, title
))
710 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
714 RBevelImage(img
, RBEV_RAISED2
);
716 if (!RConvertImage(scr
->rcontext
, img
, title
))
717 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
720 RBevelImage(img
, RBEV_RAISED2
);
722 if (!RConvertImage(scr
->rcontext
, img
, title
))
723 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
730 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
738 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
740 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
745 light
.red
= light
.green
= light
.blue
= 80;
748 dark
.red
= dark
.green
= dark
.blue
= 40;
750 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
751 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
753 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
754 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
757 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
758 width
- cwidth
- 2, height
- 1, &dark
);
759 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
761 #ifdef SHADOW_RESIZEBAR
762 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
763 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
764 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
765 #endif /* SHADOW_RESIZEBAR */
767 if (!RConvertImage(scr
->rcontext
, img
, pmap
))
768 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
773 static void updateTexture(WFrameWindow
* fwin
)
778 i
= fwin
->flags
.state
;
779 if (fwin
->titlebar
) {
780 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
781 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
782 if (wPreferences
.new_style
== TS_NEW
) {
783 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
784 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
785 fwin
->lbutton_back
[i
]);
787 #ifdef XKB_BUTTON_HINT
788 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
])
789 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
790 fwin
->languagebutton_back
[i
]);
793 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
794 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
795 fwin
->rbutton_back
[i
]);
798 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
799 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
800 if (wPreferences
.new_style
== TS_NEW
) {
801 if (fwin
->left_button
)
802 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
803 #ifdef XKB_BUTTON_HINT
804 if (fwin
->language_button
)
805 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
807 if (fwin
->right_button
)
808 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
811 XClearWindow(dpy
, fwin
->titlebar
->window
);
813 if (fwin
->left_button
) {
814 XClearWindow(dpy
, fwin
->left_button
->window
);
815 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
817 #ifdef XKB_BUTTON_HINT
818 if (fwin
->language_button
) {
819 XClearWindow(dpy
, fwin
->language_button
->window
);
820 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
823 if (fwin
->right_button
) {
824 XClearWindow(dpy
, fwin
->right_button
->window
);
825 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
830 static void remakeTexture(WFrameWindow
* fwin
, int state
)
832 Pixmap pmap
, lpmap
, rpmap
;
833 #ifdef XKB_BUTTON_HINT
837 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
838 FREE_PIXMAP(fwin
->title_back
[state
]);
839 if (wPreferences
.new_style
== TS_NEW
) {
840 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
841 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
842 #ifdef XKB_BUTTON_HINT
843 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
847 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
850 #ifdef XKB_BUTTON_HINT
854 /* eventually surrounded by if new_style */
855 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
856 #ifdef XKB_BUTTON_HINT
857 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
858 && !fwin
->flags
.languagebutton_dont_fit
;
860 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
861 && !fwin
->flags
.rbutton_dont_fit
;
863 width
= fwin
->core
->width
+ 1;
865 #ifdef XKB_BUTTON_HINT
866 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
867 width
, fwin
->titlebar
->height
,
868 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
869 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
871 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
872 width
, fwin
->titlebar
->height
,
873 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
874 left
, right
, &pmap
, &lpmap
, &rpmap
);
877 fwin
->title_back
[state
] = pmap
;
878 if (wPreferences
.new_style
== TS_NEW
) {
879 fwin
->lbutton_back
[state
] = lpmap
;
880 fwin
->rbutton_back
[state
] = rpmap
;
881 #ifdef XKB_BUTTON_HINT
882 fwin
->languagebutton_back
[state
] = tpmap
;
887 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
888 && fwin
->resizebar
&& state
== 0) {
890 FREE_PIXMAP(fwin
->resizebar_back
[0]);
892 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
894 renderResizebarTexture(fwin
->screen_ptr
,
895 fwin
->resizebar_texture
[0],
896 fwin
->resizebar
->width
,
897 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
899 fwin
->resizebar_back
[0] = pmap
;
902 /* this part should be in updateTexture() */
903 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
)
904 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
906 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
907 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
909 XClearWindow(dpy
, fwin
->resizebar
->window
);
913 void wFrameWindowPaint(WFrameWindow
* fwin
)
915 WScreen
*scr
= fwin
->screen_ptr
;
918 state
= fwin
->flags
.state
;
920 if (fwin
->flags
.is_client_window_frame
)
921 fwin
->flags
.justification
= wPreferences
.title_justification
;
923 if (fwin
->flags
.need_texture_remake
) {
926 fwin
->flags
.need_texture_remake
= 0;
927 fwin
->flags
.need_texture_change
= 0;
929 if (fwin
->flags
.single_texture
) {
930 remakeTexture(fwin
, 0);
933 /* first render the texture for the current state... */
934 remakeTexture(fwin
, state
);
935 /* ... and paint it */
938 for (i
= 0; i
< 3; i
++) {
940 remakeTexture(fwin
, i
);
945 if (fwin
->flags
.need_texture_change
) {
946 fwin
->flags
.need_texture_change
= 0;
951 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
952 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
953 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
954 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
957 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
958 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
963 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
965 w
= fwin
->resizebar
->width
;
966 h
= fwin
->resizebar
->height
;
967 cw
= fwin
->resizebar_corner_width
;
968 light_gc
= texture
->light_gc
;
969 dim_gc
= texture
->dim_gc
;
970 win
= fwin
->resizebar
->window
;
972 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
973 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
975 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
976 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
978 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
979 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
981 #ifdef SHADOW_RESIZEBAR
982 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
983 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
984 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
985 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
986 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
987 #endif /* SHADOW_RESIZEBAR */
990 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
992 int lofs
= 6, rofs
= 6;
996 if (!wPreferences
.new_style
== TS_NEW
) {
997 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
998 lofs
+= fwin
->left_button
->width
+ 3;
1002 #ifdef XKB_BUTTON_HINT
1003 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1004 && !fwin
->flags
.languagebutton_dont_fit
)
1005 lofs
+= fwin
->language_button
->width
;
1010 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1011 rofs
+= fwin
->right_button
->width
+ 3;
1015 #ifdef XKB_BUTTON_HINT
1016 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1023 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
1024 titlelen
= strlen(title
);
1025 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1027 switch (fwin
->flags
.justification
) {
1033 x
= fwin
->titlebar
->width
- w
- rofs
;
1038 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1040 x
= (fwin
->titlebar
->width
- w
) / 2;
1044 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1045 h
= WMFontHeight(*fwin
->font
);
1047 if (y
*2 + h
> *fwin
->title_max_height
)
1048 y
= (*fwin
->title_max_height
- h
) / 2;
1050 if (y
*2 + h
< *fwin
->title_min_height
)
1051 y
= (*fwin
->title_min_height
- h
) / 2;
1053 /* We use a w+2 buffer to have an extra pixel on the left and
1054 * another one on the right. This is because for some odd reason,
1055 * sometimes when using AA fonts (when libfreetype2 is compiled
1056 * with bytecode interpreter turned off), some fonts are drawn
1057 * starting from x = -1 not from 0 as requested. Observed with
1058 * capital A letter on the bold 'trebuchet ms' font. -Dan
1060 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1062 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1064 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1065 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1066 x
- 1, y
, w
+ 2, h
, 0, 0);
1068 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1069 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1072 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1073 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1074 *fwin
->font
, 1, 0, title
, titlelen
);
1076 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1078 XFreePixmap(dpy
, buf
);
1083 if (fwin
->left_button
)
1084 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1085 if (fwin
->right_button
)
1086 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1087 #ifdef XKB_BUTTON_HINT
1088 if (fwin
->language_button
)
1089 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1094 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1096 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1097 int resizedHorizontally
= 0;
1100 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1102 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1104 if (fwin
->core
->width
!= width
) {
1105 fwin
->flags
.need_texture_remake
= 1;
1106 resizedHorizontally
= 1;
1109 fwin
->core
->width
= width
;
1110 fwin
->core
->height
= height
;
1112 if (fwin
->titlebar
&& resizedHorizontally
) {
1113 /* Check if the titlebar is wide enough to hold the buttons.
1114 * Temporarily remove them if can't
1116 if (fwin
->left_button
) {
1117 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1118 if (!fwin
->flags
.hide_left_button
)
1119 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1121 fwin
->flags
.lbutton_dont_fit
= 1;
1122 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1123 if (!fwin
->flags
.hide_left_button
)
1124 XMapWindow(dpy
, fwin
->left_button
->window
);
1126 fwin
->flags
.lbutton_dont_fit
= 0;
1129 #ifdef XKB_BUTTON_HINT
1130 if (fwin
->language_button
) {
1131 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1132 if (!fwin
->flags
.hide_language_button
)
1133 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1135 fwin
->flags
.languagebutton_dont_fit
= 1;
1136 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1137 if (!fwin
->flags
.hide_language_button
)
1138 XMapWindow(dpy
, fwin
->language_button
->window
);
1140 fwin
->flags
.languagebutton_dont_fit
= 0;
1145 if (fwin
->right_button
) {
1146 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1147 if (!fwin
->flags
.hide_right_button
)
1148 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1150 fwin
->flags
.rbutton_dont_fit
= 1;
1151 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1152 if (!fwin
->flags
.hide_right_button
)
1153 XMapWindow(dpy
, fwin
->right_button
->window
);
1155 fwin
->flags
.rbutton_dont_fit
= 0;
1159 if (wPreferences
.new_style
== TS_NEW
) {
1160 if (fwin
->right_button
)
1161 XMoveWindow(dpy
, fwin
->right_button
->window
,
1162 width
- fwin
->right_button
->width
+ 1, 0);
1164 if (fwin
->right_button
)
1165 XMoveWindow(dpy
, fwin
->right_button
->window
,
1166 width
- fwin
->right_button
->width
- 3,
1167 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1169 updateTitlebar(fwin
);
1170 checkTitleSize(fwin
);
1173 if (fwin
->resizebar
) {
1174 wCoreConfigure(fwin
->resizebar
, 0,
1175 fwin
->core
->height
- fwin
->resizebar
->height
,
1176 fwin
->core
->width
, fwin
->resizebar
->height
);
1178 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1179 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
)
1180 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
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
, const char *new_title
)
1196 /* check if the title is the same as before */
1198 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0))
1208 fwin
->title
= wstrdup(new_title
);
1210 if (fwin
->titlebar
) {
1211 XClearWindow(dpy
, fwin
->titlebar
->window
);
1213 wFrameWindowPaint(fwin
);
1215 checkTitleSize(fwin
);
1220 #ifdef XKB_BUTTON_HINT
1221 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1223 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1224 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1226 #endif /* XKB_BUTTON_HINT */
1228 /*********************************************************************/
1230 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1232 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1234 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1235 fwin
->flags
.repaint_only_titlebar
= 1;
1236 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1237 fwin
->flags
.repaint_only_resizebar
= 1;
1238 wFrameWindowPaint(fwin
);
1239 fwin
->flags
.repaint_only_titlebar
= 0;
1240 fwin
->flags
.repaint_only_resizebar
= 0;
1243 static void checkTitleSize(WFrameWindow
* fwin
)
1248 fwin
->flags
.incomplete_title
= 0;
1252 if (!fwin
->titlebar
) {
1253 fwin
->flags
.incomplete_title
= 1;
1256 width
= fwin
->titlebar
->width
- 6 - 6;
1259 if (!wPreferences
.new_style
== TS_NEW
) {
1260 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1261 width
-= fwin
->left_button
->width
+ 3;
1263 #ifdef XKB_BUTTON_HINT
1264 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1265 && !fwin
->flags
.languagebutton_dont_fit
)
1266 width
-= fwin
->language_button
->width
+ 3;
1269 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1270 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;
1279 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1281 WScreen
*scr
= button
->screen_ptr
;
1282 GC copy_gc
= scr
->copy_gc
;
1283 int x
= 0, y
= 0, d
= 0;
1284 int left
= 0, width
= 0;
1286 /* setup stuff according to the state */
1289 if (image
->width
>= image
->height
* 2) {
1290 /* the image contains 2 pictures: the second is for the
1292 width
= image
->width
/ 2;
1293 left
= image
->width
/ 2;
1295 width
= image
->width
;
1298 XSetClipMask(dpy
, copy_gc
, None
);
1299 if (wPreferences
.new_style
== TS_NEXT
)
1300 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1302 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1305 if (wPreferences
.new_style
== TS_NEW
) {
1306 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1307 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1308 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1309 } else if (wPreferences
.new_style
== TS_OLD
) {
1310 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1311 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1312 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1314 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1315 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1316 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1319 XClearWindow(dpy
, button
->window
);
1322 if (image
->width
>= image
->height
* 2)
1323 width
= image
->width
/ 2;
1325 width
= image
->width
;
1329 if (wPreferences
.new_style
== TS_NEW
) {
1330 if (texture
->any
.type
== WTEX_SOLID
|| pushed
)
1331 wDrawBevel(button
->window
, button
->width
, button
->height
,
1332 (WTexSolid
*) texture
, WREL_RAISED
);
1334 wDrawBevel(button
->window
, button
->width
, button
->height
,
1335 scr
->widget_texture
, WREL_RAISED
);
1341 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1342 x
= (button
->width
- width
) / 2 + d
;
1343 y
= (button
->height
- image
->height
) / 2 + d
;
1344 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1345 if (!wPreferences
.new_style
== TS_NEW
) {
1346 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1348 if (image
->depth
== 1)
1349 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1350 left
, 0, width
, image
->height
, x
, y
, 1);
1352 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1353 left
, 0, width
, image
->height
, x
, y
);
1355 if (wPreferences
.new_style
== TS_OLD
) {
1356 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1357 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1358 button
->width
, button
->height
);
1360 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1361 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1362 left
, 0, width
, image
->height
, x
, y
);
1367 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1369 XSetForeground(dpy
, copy_gc
, color
);
1370 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1372 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1377 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1379 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1380 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1382 #ifdef XKB_BUTTON_HINT
1383 if (button
== fwin
->language_button
) {
1384 if (wPreferences
.modelock
)
1385 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1386 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1387 fwin
->languagebutton_image
, False
);
1390 if (button
== fwin
->left_button
)
1391 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1392 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1394 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1395 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1398 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1400 WFrameWindow
*fwin
= desc
->parent
;
1401 WCoreWindow
*titlebar
= desc
->self
;
1403 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1404 if (fwin
->on_dblclick_titlebar
)
1405 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1407 if (fwin
->on_mousedown_titlebar
)
1408 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1412 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1414 WFrameWindow
*fwin
= desc
->parent
;
1415 WCoreWindow
*resizebar
= desc
->self
;
1417 if (fwin
->on_mousedown_resizebar
)
1418 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1421 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1423 WFrameWindow
*fwin
= desc
->parent
;
1424 WCoreWindow
*button
= desc
->self
;
1427 int done
= 0, execute
= 1;
1429 unsigned long pixel
;
1430 int clickButton
= event
->xbutton
.button
;
1432 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1433 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
)
1434 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1439 if (button
== fwin
->left_button
)
1440 image
= fwin
->lbutton_image
;
1442 image
= fwin
->rbutton_image
;
1444 #ifdef XKB_BUTTON_HINT
1445 if (button
== fwin
->language_button
) {
1446 if (!wPreferences
.modelock
)
1448 image
= fwin
->languagebutton_image
;
1452 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1453 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1454 paintButton(button
, texture
, pixel
, image
, True
);
1457 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1458 | ButtonPressMask
| ExposureMask
, &ev
);
1462 paintButton(button
, texture
, pixel
, image
, False
);
1467 paintButton(button
, texture
, pixel
, image
, True
);
1474 if (ev
.xbutton
.button
== clickButton
)
1482 paintButton(button
, texture
, pixel
, image
, False
);
1485 if (button
== fwin
->left_button
) {
1486 if (fwin
->on_click_left
)
1487 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1488 } else if (button
== fwin
->right_button
) {
1489 if (fwin
->on_click_right
)
1490 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1492 #ifdef XKB_BUTTON_HINT
1493 else if (button
== fwin
->language_button
) {
1494 if (fwin
->on_click_language
)
1495 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);