2 * Window Maker window manager
4 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <X11/Xutil.h>
25 #ifdef KEEP_XKB_LOCK_STATUS
26 #include <X11/XKBlib.h>
27 #endif /* KEEP_XKB_LOCK_STATUS */
34 #include "WindowMaker.h"
43 #define DBLCLICK_TIME wPreferences.dblclick_time
45 extern WPreferences wPreferences
;
47 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
);
48 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
);
50 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
51 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
52 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
54 static void checkTitleSize(WFrameWindow
* fwin
);
56 static void paintButton(WCoreWindow
* button
, WTexture
* texture
,
57 unsigned long color
, WPixmap
* image
, int pushed
);
59 static void updateTitlebar(WFrameWindow
* fwin
);
61 static void allocFrameBorderPixel(Colormap colormap
, char *color_name
, unsigned long **pixel
);
63 static void allocFrameBorderPixel(Colormap colormap
, char *color_name
, unsigned long **pixel
) {
68 if (!XParseColor(dpy
, colormap
, color_name
, &xcol
)) {
69 wwarning(_("could not parse color \"%s\""), color_name
);
72 if (!XAllocColor(dpy
, colormap
, &xcol
)) {
73 wwarning(_("could not allocate color \"%s\""), color_name
);
77 *pixel
= wmalloc(sizeof(unsigned long));
82 WFrameWindow
*wFrameWindowCreate(WScreen
* scr
, int wlevel
, int x
, int y
,
83 int width
, int height
, int *clearance
,
84 int *title_min
, int *title_max
, int flags
,
85 WTexture
** title_texture
, WTexture
** resize_texture
,
86 WMColor
** color
, WMFont
** font
,
87 int depth
, Visual
*visual
, Colormap colormap
)
91 fwin
= wmalloc(sizeof(WFrameWindow
));
93 fwin
->screen_ptr
= scr
;
95 fwin
->flags
.single_texture
= (flags
& WFF_SINGLE_STATE
) ? 1 : 0;
97 fwin
->title_texture
= title_texture
;
98 fwin
->resizebar_texture
= resize_texture
;
99 fwin
->title_color
= color
;
100 fwin
->title_clearance
= clearance
;
101 fwin
->title_min_height
= title_min
;
102 fwin
->title_max_height
= title_max
;
104 #ifdef KEEP_XKB_LOCK_STATUS
105 fwin
->languagemode
= XkbGroup1Index
;
106 fwin
->last_languagemode
= XkbGroup2Index
;
110 fwin
->visual
= visual
;
111 fwin
->colormap
= colormap
;
112 allocFrameBorderPixel(fwin
->colormap
, FRAME_BORDER_COLOR
, &fwin
->border_pixel
);
113 allocFrameBorderPixel(fwin
->colormap
, FRAME_SELECTED_BORDER_COLOR
, &fwin
->selected_border_pixel
);
115 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
116 ? FRAME_BORDER_WIDTH
: 0, fwin
->depth
, fwin
->visual
, fwin
->colormap
, scr
->frame_border_pixel
);
118 /* setup stacking information */
119 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
120 fwin
->core
->stacking
->above
= NULL
;
121 fwin
->core
->stacking
->under
= NULL
;
122 fwin
->core
->stacking
->child_of
= NULL
;
123 fwin
->core
->stacking
->window_level
= wlevel
;
125 AddToStackList(fwin
->core
);
127 wFrameWindowUpdateBorders(fwin
, flags
);
132 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
138 WScreen
*scr
= fwin
->screen_ptr
;
140 width
= fwin
->core
->width
;
141 if (flags
& WFF_IS_SHADED
)
144 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
146 if (flags
& WFF_TITLEBAR
) {
147 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
149 if (theight
> *fwin
->title_max_height
)
150 theight
= *fwin
->title_max_height
;
152 if (theight
< *fwin
->title_min_height
)
153 theight
= *fwin
->title_min_height
;
158 if (wPreferences
.new_style
== TS_NEW
) {
160 } else if (wPreferences
.new_style
== TS_OLD
) {
166 if (fwin
->titlebar
) {
167 /* if we had a titlebar and is requesting for one,
168 * check if the size has changed and resize it */
169 if (flags
& WFF_TITLEBAR
) {
170 fwin
->top_width
= theight
;
172 fwin
->flags
.need_texture_remake
= 1;
174 if (wPreferences
.new_style
== TS_NEW
) {
175 if (fwin
->left_button
)
176 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
177 #ifdef XKB_BUTTON_HINT
178 if (fwin
->language_button
) {
179 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
180 || fwin
->flags
.lbutton_dont_fit
)
181 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
183 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
187 if (fwin
->right_button
)
188 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
190 } else { /* !new_style */
191 if (fwin
->left_button
)
192 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
193 #ifdef XKB_BUTTON_HINT
194 if (fwin
->language_button
)
195 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
199 if (fwin
->right_button
)
200 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
201 (theight
- bsize
) / 2, bsize
, bsize
);
203 updateTitlebar(fwin
);
205 /* we had a titlebar, but now we don't need it anymore */
206 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
207 FREE_PIXMAP(fwin
->title_back
[i
]);
208 if (wPreferences
.new_style
== TS_NEW
) {
209 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
210 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
211 #ifdef XKB_BUTTON_HINT
212 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
216 if (fwin
->left_button
)
217 wCoreDestroy(fwin
->left_button
);
218 fwin
->left_button
= NULL
;
220 #ifdef XKB_BUTTON_HINT
221 if (fwin
->language_button
)
222 wCoreDestroy(fwin
->language_button
);
223 fwin
->language_button
= NULL
;
226 if (fwin
->right_button
)
227 wCoreDestroy(fwin
->right_button
);
228 fwin
->right_button
= NULL
;
230 wCoreDestroy(fwin
->titlebar
);
231 fwin
->titlebar
= NULL
;
236 /* if we didn't have a titlebar and are being requested for
238 if (flags
& WFF_TITLEBAR
) {
239 fwin
->top_width
= theight
;
241 fwin
->flags
.titlebar
= 1;
242 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
244 if (flags
& WFF_LEFT_BUTTON
) {
245 fwin
->flags
.left_button
= 1;
246 if (wPreferences
.new_style
== TS_NEW
) {
247 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
249 if (width
< theight
* 4)
250 fwin
->flags
.lbutton_dont_fit
= 1;
252 XMapRaised(dpy
, fwin
->left_button
->window
);
254 } else if (wPreferences
.new_style
== TS_OLD
) {
256 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
258 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
259 scr
->widget_texture
->normal
.pixel
);
261 if (width
< theight
* 3)
262 fwin
->flags
.lbutton_dont_fit
= 1;
264 XMapRaised(dpy
, fwin
->left_button
->window
);
268 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
271 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
272 scr
->widget_texture
->dark
.pixel
);
274 if (width
< theight
* 3)
275 fwin
->flags
.lbutton_dont_fit
= 1;
277 XMapRaised(dpy
, fwin
->left_button
->window
);
281 #ifdef XKB_BUTTON_HINT
282 if (flags
& WFF_LANGUAGE_BUTTON
) {
283 fwin
->flags
.language_button
= 1;
284 if (wPreferences
.new_style
== TS_NEW
) {
285 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
287 if (width
< theight
* 4)
288 fwin
->flags
.languagebutton_dont_fit
= 1;
290 XMapRaised(dpy
, fwin
->language_button
->window
);
292 fwin
->language_button
=
293 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
296 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
297 scr
->widget_texture
->normal
.pixel
);
299 if (width
< theight
* 3)
300 fwin
->flags
.languagebutton_dont_fit
= 1;
302 XMapRaised(dpy
, fwin
->language_button
->window
);
307 if (flags
& WFF_RIGHT_BUTTON
) {
308 fwin
->flags
.right_button
= 1;
309 if (wPreferences
.new_style
== TS_NEW
) {
311 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
312 } else if (wPreferences
.new_style
== TS_OLD
) {
314 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
315 (theight
- bsize
) / 2, bsize
, bsize
);
316 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
317 scr
->widget_texture
->normal
.pixel
);
320 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
321 (theight
-bsize
)/2, bsize
, bsize
);
322 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
323 scr
->widget_texture
->dark
.pixel
);
326 if (width
< theight
* 2)
327 fwin
->flags
.rbutton_dont_fit
= 1;
329 XMapRaised(dpy
, fwin
->right_button
->window
);
332 if (wPreferences
.new_style
== TS_NEW
)
333 updateTitlebar(fwin
);
335 XMapRaised(dpy
, fwin
->titlebar
->window
);
337 fwin
->flags
.need_texture_remake
= 1;
340 checkTitleSize(fwin
);
342 if (flags
& WFF_RESIZEBAR
) {
343 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
345 if (!fwin
->resizebar
) {
346 fwin
->flags
.resizebar
= 1;
347 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
348 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
349 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
350 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
351 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
352 if (fwin
->resizebar_corner_width
< 0)
353 fwin
->resizebar_corner_width
= 0;
356 XMapWindow(dpy
, fwin
->resizebar
->window
);
357 XLowerWindow(dpy
, fwin
->resizebar
->window
);
359 fwin
->flags
.need_texture_remake
= 1;
361 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
)
362 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
363 width
, RESIZEBAR_HEIGHT
);
366 fwin
->bottom_width
= 0;
368 if (fwin
->resizebar
) {
369 fwin
->bottom_width
= 0;
370 wCoreDestroy(fwin
->resizebar
);
371 fwin
->resizebar
= NULL
;
375 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
))
376 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
378 if (flags
& WFF_BORDER
)
379 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
381 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
383 /* setup object descriptors */
384 if (fwin
->titlebar
) {
385 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
386 fwin
->titlebar
->descriptor
.parent
= fwin
;
387 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
388 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
391 if (fwin
->resizebar
) {
392 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
393 fwin
->resizebar
->descriptor
.parent
= fwin
;
394 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
395 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
398 if (fwin
->left_button
) {
399 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
400 fwin
->left_button
->descriptor
.parent
= fwin
;
401 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
402 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
405 #ifdef XKB_BUTTON_HINT
406 if (fwin
->language_button
) {
407 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
408 fwin
->language_button
->descriptor
.parent
= fwin
;
409 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
410 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
414 if (fwin
->right_button
) {
415 fwin
->right_button
->descriptor
.parent
= fwin
;
416 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
417 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
418 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
421 checkTitleSize(fwin
);
423 if (fwin
->border_pixel
)
424 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->border_pixel
);
427 void wFrameWindowDestroy(WFrameWindow
* fwin
)
431 if (fwin
->left_button
)
432 wCoreDestroy(fwin
->left_button
);
434 #ifdef XKB_BUTTON_HINT
435 if (fwin
->language_button
)
436 wCoreDestroy(fwin
->language_button
);
439 if (fwin
->right_button
)
440 wCoreDestroy(fwin
->right_button
);
443 wCoreDestroy(fwin
->resizebar
);
446 wCoreDestroy(fwin
->titlebar
);
448 RemoveFromStackList(fwin
->core
);
450 wCoreDestroy(fwin
->core
);
455 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
456 FREE_PIXMAP(fwin
->title_back
[i
]);
457 if (wPreferences
.new_style
== TS_NEW
) {
458 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
459 #ifdef XKB_BUTTON_HINT
460 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
462 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
469 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
471 if (fwin
->flags
.state
== state
)
474 fwin
->flags
.state
= state
;
475 fwin
->flags
.need_texture_change
= 1;
477 wFrameWindowPaint(fwin
);
480 static void updateTitlebar(WFrameWindow
* fwin
)
485 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
487 if (theight
> *fwin
->title_max_height
)
488 theight
= *fwin
->title_max_height
;
490 if (theight
< *fwin
->title_min_height
)
491 theight
= *fwin
->title_min_height
;
494 w
= fwin
->core
->width
+ 1;
496 if (wPreferences
.new_style
== TS_NEW
) {
497 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
499 #ifdef XKB_BUTTON_HINT
500 if (fwin
->language_button
)
501 wCoreConfigure(fwin
->language_button
, 0, 0,
502 fwin
->language_button
->width
, fwin
->language_button
->width
);
505 #ifdef XKB_BUTTON_HINT
506 if (fwin
->language_button
)
507 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
508 fwin
->language_button
->width
, fwin
->language_button
->width
);
510 x
= fwin
->left_button
->width
;
511 w
-= fwin
->left_button
->width
;
513 #ifdef XKB_BUTTON_HINT
514 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
515 || fwin
->flags
.languagebutton_dont_fit
) {
517 x
+= fwin
->language_button
->width
;
518 w
-= fwin
->language_button
->width
;
522 #ifdef XKB_BUTTON_HINT
524 int bsize
= theight
- 7;
525 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
526 if (fwin
->language_button
)
527 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
528 fwin
->language_button
->width
, fwin
->language_button
->width
);
530 if (fwin
->language_button
)
531 wCoreConfigure(fwin
->language_button
,
532 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
533 fwin
->language_button
->width
, fwin
->language_button
->width
);
538 if (wPreferences
.new_style
== TS_NEW
) {
539 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
)
540 w
-= fwin
->right_button
->width
;
543 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
544 fwin
->flags
.need_texture_remake
= 1;
546 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
549 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
551 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
552 XUnmapWindow(dpy
, fwin
->right_button
->window
);
553 fwin
->flags
.hide_right_button
= 1;
556 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
557 XUnmapWindow(dpy
, fwin
->left_button
->window
);
558 fwin
->flags
.hide_left_button
= 1;
560 #ifdef XKB_BUTTON_HINT
561 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
562 XUnmapWindow(dpy
, fwin
->language_button
->window
);
563 fwin
->flags
.hide_language_button
= 1;
567 if (fwin
->titlebar
) {
568 if (wPreferences
.new_style
== TS_NEW
) {
569 updateTitlebar(fwin
);
571 #ifdef XKB_BUTTON_HINT
572 updateTitlebar(fwin
);
574 XClearWindow(dpy
, fwin
->titlebar
->window
);
575 wFrameWindowPaint(fwin
);
578 checkTitleSize(fwin
);
582 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
584 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
586 if (!fwin
->flags
.rbutton_dont_fit
)
587 XMapWindow(dpy
, fwin
->right_button
->window
);
589 fwin
->flags
.hide_right_button
= 0;
591 #ifdef XKB_BUTTON_HINT
592 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
594 if (!fwin
->flags
.languagebutton_dont_fit
)
595 XMapWindow(dpy
, fwin
->language_button
->window
);
597 fwin
->flags
.hide_language_button
= 0;
601 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
603 if (!fwin
->flags
.lbutton_dont_fit
)
604 XMapWindow(dpy
, fwin
->left_button
->window
);
606 fwin
->flags
.hide_left_button
= 0;
609 if (fwin
->titlebar
) {
610 if (wPreferences
.new_style
== TS_NEW
) {
611 updateTitlebar(fwin
);
613 XClearWindow(dpy
, fwin
->titlebar
->window
);
614 wFrameWindowPaint(fwin
);
616 checkTitleSize(fwin
);
621 #ifdef XKB_BUTTON_HINT
622 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
623 int bwidth
, int bheight
, int left
, int language
, int right
,
624 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
626 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
627 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
631 RImage
*limg
, *rimg
, *mimg
;
632 #ifdef XKB_BUTTON_HINT
640 #ifdef XKB_BUTTON_HINT
641 *languagebutton
= None
;
644 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
646 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
650 if (wPreferences
.new_style
== TS_NEW
) {
652 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
659 #ifdef XKB_BUTTON_HINT
661 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
667 RBevelImage(limg
, RBEV_RAISED2
);
668 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
))
669 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
675 #ifdef XKB_BUTTON_HINT
677 RBevelImage(timg
, RBEV_RAISED2
);
678 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
))
679 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
688 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
693 RBevelImage(rimg
, RBEV_RAISED2
);
694 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
))
695 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
702 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
703 RBevelImage(mimg
, RBEV_RAISED2
);
705 if (!RConvertImage(scr
->rcontext
, mimg
, title
))
706 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
710 RBevelImage(img
, RBEV_RAISED2
);
712 if (!RConvertImage(scr
->rcontext
, img
, title
))
713 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
716 RBevelImage(img
, RBEV_RAISED2
);
718 if (!RConvertImage(scr
->rcontext
, img
, title
))
719 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
726 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
734 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
736 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
741 light
.red
= light
.green
= light
.blue
= 80;
744 dark
.red
= dark
.green
= dark
.blue
= 40;
746 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
747 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
749 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
750 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
753 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
754 width
- cwidth
- 2, height
- 1, &dark
);
755 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
757 #ifdef SHADOW_RESIZEBAR
758 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
759 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
760 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
761 #endif /* SHADOW_RESIZEBAR */
763 if (!RConvertImage(scr
->rcontext
, img
, pmap
))
764 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
769 static void updateTexture(WFrameWindow
* fwin
)
774 i
= fwin
->flags
.state
;
775 if (fwin
->titlebar
) {
776 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
777 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
778 if (wPreferences
.new_style
== TS_NEW
) {
779 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
780 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
781 fwin
->lbutton_back
[i
]);
783 #ifdef XKB_BUTTON_HINT
784 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
])
785 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
786 fwin
->languagebutton_back
[i
]);
789 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
790 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
791 fwin
->rbutton_back
[i
]);
794 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
795 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
796 if (wPreferences
.new_style
== TS_NEW
) {
797 if (fwin
->left_button
)
798 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
799 #ifdef XKB_BUTTON_HINT
800 if (fwin
->language_button
)
801 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
803 if (fwin
->right_button
)
804 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
807 XClearWindow(dpy
, fwin
->titlebar
->window
);
809 if (fwin
->left_button
) {
810 XClearWindow(dpy
, fwin
->left_button
->window
);
811 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
813 #ifdef XKB_BUTTON_HINT
814 if (fwin
->language_button
) {
815 XClearWindow(dpy
, fwin
->language_button
->window
);
816 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
819 if (fwin
->right_button
) {
820 XClearWindow(dpy
, fwin
->right_button
->window
);
821 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
826 static void remakeTexture(WFrameWindow
* fwin
, int state
)
828 Pixmap pmap
, lpmap
, rpmap
;
829 #ifdef XKB_BUTTON_HINT
833 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
834 FREE_PIXMAP(fwin
->title_back
[state
]);
835 if (wPreferences
.new_style
== TS_NEW
) {
836 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
837 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
838 #ifdef XKB_BUTTON_HINT
839 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
843 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
846 #ifdef XKB_BUTTON_HINT
850 /* eventually surrounded by if new_style */
851 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
852 #ifdef XKB_BUTTON_HINT
853 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
854 && !fwin
->flags
.languagebutton_dont_fit
;
856 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
857 && !fwin
->flags
.rbutton_dont_fit
;
859 width
= fwin
->core
->width
+ 1;
861 #ifdef XKB_BUTTON_HINT
862 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
863 width
, fwin
->titlebar
->height
,
864 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
865 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
867 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
868 width
, fwin
->titlebar
->height
,
869 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
870 left
, right
, &pmap
, &lpmap
, &rpmap
);
873 fwin
->title_back
[state
] = pmap
;
874 if (wPreferences
.new_style
== TS_NEW
) {
875 fwin
->lbutton_back
[state
] = lpmap
;
876 fwin
->rbutton_back
[state
] = rpmap
;
877 #ifdef XKB_BUTTON_HINT
878 fwin
->languagebutton_back
[state
] = tpmap
;
883 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
884 && fwin
->resizebar
&& state
== 0) {
886 FREE_PIXMAP(fwin
->resizebar_back
[0]);
888 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
890 renderResizebarTexture(fwin
->screen_ptr
,
891 fwin
->resizebar_texture
[0],
892 fwin
->resizebar
->width
,
893 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
895 fwin
->resizebar_back
[0] = pmap
;
898 /* this part should be in updateTexture() */
899 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
)
900 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
902 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
903 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
905 XClearWindow(dpy
, fwin
->resizebar
->window
);
909 void wFrameWindowPaint(WFrameWindow
* fwin
)
911 WScreen
*scr
= fwin
->screen_ptr
;
914 state
= fwin
->flags
.state
;
916 if (fwin
->flags
.is_client_window_frame
)
917 fwin
->flags
.justification
= wPreferences
.title_justification
;
919 if (fwin
->flags
.need_texture_remake
) {
922 fwin
->flags
.need_texture_remake
= 0;
923 fwin
->flags
.need_texture_change
= 0;
925 if (fwin
->flags
.single_texture
) {
926 remakeTexture(fwin
, 0);
929 /* first render the texture for the current state... */
930 remakeTexture(fwin
, state
);
931 /* ... and paint it */
934 for (i
= 0; i
< 3; i
++) {
936 remakeTexture(fwin
, i
);
941 if (fwin
->flags
.need_texture_change
) {
942 fwin
->flags
.need_texture_change
= 0;
947 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
948 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
949 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
950 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
953 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
954 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
959 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
961 w
= fwin
->resizebar
->width
;
962 h
= fwin
->resizebar
->height
;
963 cw
= fwin
->resizebar_corner_width
;
964 light_gc
= texture
->light_gc
;
965 dim_gc
= texture
->dim_gc
;
966 win
= fwin
->resizebar
->window
;
968 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
969 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
971 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
972 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
974 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
975 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
977 #ifdef SHADOW_RESIZEBAR
978 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
979 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
980 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
981 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
982 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
983 #endif /* SHADOW_RESIZEBAR */
986 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
988 int lofs
= 6, rofs
= 6;
992 if (!wPreferences
.new_style
== TS_NEW
) {
993 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
994 lofs
+= fwin
->left_button
->width
+ 3;
998 #ifdef XKB_BUTTON_HINT
999 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1000 && !fwin
->flags
.languagebutton_dont_fit
)
1001 lofs
+= fwin
->language_button
->width
;
1006 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1007 rofs
+= fwin
->right_button
->width
+ 3;
1011 #ifdef XKB_BUTTON_HINT
1012 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1019 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
1020 titlelen
= strlen(title
);
1021 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1023 switch (fwin
->flags
.justification
) {
1029 x
= fwin
->titlebar
->width
- w
- rofs
;
1034 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1036 x
= (fwin
->titlebar
->width
- w
) / 2;
1040 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1041 h
= WMFontHeight(*fwin
->font
);
1043 if (y
*2 + h
> *fwin
->title_max_height
)
1044 y
= (*fwin
->title_max_height
- h
) / 2;
1046 if (y
*2 + h
< *fwin
->title_min_height
)
1047 y
= (*fwin
->title_min_height
- h
) / 2;
1049 /* We use a w+2 buffer to have an extra pixel on the left and
1050 * another one on the right. This is because for some odd reason,
1051 * sometimes when using AA fonts (when libfreetype2 is compiled
1052 * with bytecode interpreter turned off), some fonts are drawn
1053 * starting from x = -1 not from 0 as requested. Observed with
1054 * capital A letter on the bold 'trebuchet ms' font. -Dan
1056 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1058 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1060 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1061 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1062 x
- 1, y
, w
+ 2, h
, 0, 0);
1064 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1065 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1068 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1069 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1070 *fwin
->font
, 1, 0, title
, titlelen
);
1072 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1074 XFreePixmap(dpy
, buf
);
1079 if (fwin
->left_button
)
1080 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1081 if (fwin
->right_button
)
1082 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1083 #ifdef XKB_BUTTON_HINT
1084 if (fwin
->language_button
)
1085 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1090 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1092 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1093 int resizedHorizontally
= 0;
1096 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1098 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1100 if (fwin
->core
->width
!= width
) {
1101 fwin
->flags
.need_texture_remake
= 1;
1102 resizedHorizontally
= 1;
1105 fwin
->core
->width
= width
;
1106 fwin
->core
->height
= height
;
1108 if (fwin
->titlebar
&& resizedHorizontally
) {
1109 /* Check if the titlebar is wide enough to hold the buttons.
1110 * Temporarily remove them if can't
1112 if (fwin
->left_button
) {
1113 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1114 if (!fwin
->flags
.hide_left_button
)
1115 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1117 fwin
->flags
.lbutton_dont_fit
= 1;
1118 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1119 if (!fwin
->flags
.hide_left_button
)
1120 XMapWindow(dpy
, fwin
->left_button
->window
);
1122 fwin
->flags
.lbutton_dont_fit
= 0;
1125 #ifdef XKB_BUTTON_HINT
1126 if (fwin
->language_button
) {
1127 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1128 if (!fwin
->flags
.hide_language_button
)
1129 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1131 fwin
->flags
.languagebutton_dont_fit
= 1;
1132 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1133 if (!fwin
->flags
.hide_language_button
)
1134 XMapWindow(dpy
, fwin
->language_button
->window
);
1136 fwin
->flags
.languagebutton_dont_fit
= 0;
1141 if (fwin
->right_button
) {
1142 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1143 if (!fwin
->flags
.hide_right_button
)
1144 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1146 fwin
->flags
.rbutton_dont_fit
= 1;
1147 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1148 if (!fwin
->flags
.hide_right_button
)
1149 XMapWindow(dpy
, fwin
->right_button
->window
);
1151 fwin
->flags
.rbutton_dont_fit
= 0;
1155 if (wPreferences
.new_style
== TS_NEW
) {
1156 if (fwin
->right_button
)
1157 XMoveWindow(dpy
, fwin
->right_button
->window
,
1158 width
- fwin
->right_button
->width
+ 1, 0);
1160 if (fwin
->right_button
)
1161 XMoveWindow(dpy
, fwin
->right_button
->window
,
1162 width
- fwin
->right_button
->width
- 3,
1163 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1165 updateTitlebar(fwin
);
1166 checkTitleSize(fwin
);
1169 if (fwin
->resizebar
) {
1170 wCoreConfigure(fwin
->resizebar
, 0,
1171 fwin
->core
->height
- fwin
->resizebar
->height
,
1172 fwin
->core
->width
, fwin
->resizebar
->height
);
1174 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1175 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
)
1176 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1180 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1182 reconfigure(fwin
, x
, y
, width
, height
, False
);
1185 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1187 reconfigure(fwin
, 0, 0, width
, height
, True
);
1190 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1192 /* check if the title is the same as before */
1194 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0))
1204 fwin
->title
= wstrdup(new_title
);
1206 if (fwin
->titlebar
) {
1207 XClearWindow(dpy
, fwin
->titlebar
->window
);
1209 wFrameWindowPaint(fwin
);
1211 checkTitleSize(fwin
);
1216 #ifdef XKB_BUTTON_HINT
1217 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1219 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1220 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1222 #endif /* XKB_BUTTON_HINT */
1224 /*********************************************************************/
1226 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1228 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1230 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1231 fwin
->flags
.repaint_only_titlebar
= 1;
1232 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1233 fwin
->flags
.repaint_only_resizebar
= 1;
1234 wFrameWindowPaint(fwin
);
1235 fwin
->flags
.repaint_only_titlebar
= 0;
1236 fwin
->flags
.repaint_only_resizebar
= 0;
1239 static void checkTitleSize(WFrameWindow
* fwin
)
1244 fwin
->flags
.incomplete_title
= 0;
1248 if (!fwin
->titlebar
) {
1249 fwin
->flags
.incomplete_title
= 1;
1252 width
= fwin
->titlebar
->width
- 6 - 6;
1255 if (!wPreferences
.new_style
== TS_NEW
) {
1256 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1257 width
-= fwin
->left_button
->width
+ 3;
1259 #ifdef XKB_BUTTON_HINT
1260 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1261 && !fwin
->flags
.languagebutton_dont_fit
)
1262 width
-= fwin
->language_button
->width
+ 3;
1265 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1266 width
-= fwin
->right_button
->width
+ 3;
1269 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
)
1270 fwin
->flags
.incomplete_title
= 1;
1272 fwin
->flags
.incomplete_title
= 0;
1275 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1277 WScreen
*scr
= button
->screen_ptr
;
1278 GC copy_gc
= scr
->copy_gc
;
1279 int x
= 0, y
= 0, d
= 0;
1280 int left
= 0, width
= 0;
1282 /* setup stuff according to the state */
1285 if (image
->width
>= image
->height
* 2) {
1286 /* the image contains 2 pictures: the second is for the
1288 width
= image
->width
/ 2;
1289 left
= image
->width
/ 2;
1291 width
= image
->width
;
1294 XSetClipMask(dpy
, copy_gc
, None
);
1295 if (wPreferences
.new_style
== TS_NEXT
)
1296 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1298 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1301 if (wPreferences
.new_style
== TS_NEW
) {
1302 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1303 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1304 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1305 } else if (wPreferences
.new_style
== TS_OLD
) {
1306 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1307 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1308 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1310 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1311 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1312 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1315 XClearWindow(dpy
, button
->window
);
1318 if (image
->width
>= image
->height
* 2)
1319 width
= image
->width
/ 2;
1321 width
= image
->width
;
1325 if (wPreferences
.new_style
== TS_NEW
) {
1326 if (texture
->any
.type
== WTEX_SOLID
|| pushed
)
1327 wDrawBevel(button
->window
, button
->width
, button
->height
,
1328 (WTexSolid
*) texture
, WREL_RAISED
);
1330 wDrawBevel(button
->window
, button
->width
, button
->height
,
1331 scr
->widget_texture
, WREL_RAISED
);
1337 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1338 x
= (button
->width
- width
) / 2 + d
;
1339 y
= (button
->height
- image
->height
) / 2 + d
;
1340 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1341 if (!wPreferences
.new_style
== TS_NEW
) {
1342 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1344 if (image
->depth
== 1)
1345 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1346 left
, 0, width
, image
->height
, x
, y
, 1);
1348 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1349 left
, 0, width
, image
->height
, x
, y
);
1351 if (wPreferences
.new_style
== TS_OLD
) {
1352 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1353 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1354 button
->width
, button
->height
);
1356 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1357 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1358 left
, 0, width
, image
->height
, x
, y
);
1363 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1365 XSetForeground(dpy
, copy_gc
, color
);
1366 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1368 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1373 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1375 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1376 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1378 #ifdef XKB_BUTTON_HINT
1379 if (button
== fwin
->language_button
) {
1380 if (wPreferences
.modelock
)
1381 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1382 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1383 fwin
->languagebutton_image
, False
);
1386 if (button
== fwin
->left_button
)
1387 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1388 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1390 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1391 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1394 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1396 WFrameWindow
*fwin
= desc
->parent
;
1397 WCoreWindow
*titlebar
= desc
->self
;
1399 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1400 if (fwin
->on_dblclick_titlebar
)
1401 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1403 if (fwin
->on_mousedown_titlebar
)
1404 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1408 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1410 WFrameWindow
*fwin
= desc
->parent
;
1411 WCoreWindow
*resizebar
= desc
->self
;
1413 if (fwin
->on_mousedown_resizebar
)
1414 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1417 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1419 WFrameWindow
*fwin
= desc
->parent
;
1420 WCoreWindow
*button
= desc
->self
;
1423 int done
= 0, execute
= 1;
1425 unsigned long pixel
;
1426 int clickButton
= event
->xbutton
.button
;
1428 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1429 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
)
1430 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1435 if (button
== fwin
->left_button
)
1436 image
= fwin
->lbutton_image
;
1438 image
= fwin
->rbutton_image
;
1440 #ifdef XKB_BUTTON_HINT
1441 if (button
== fwin
->language_button
) {
1442 if (!wPreferences
.modelock
)
1444 image
= fwin
->languagebutton_image
;
1448 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1449 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1450 paintButton(button
, texture
, pixel
, image
, True
);
1453 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1454 | ButtonPressMask
| ExposureMask
, &ev
);
1458 paintButton(button
, texture
, pixel
, image
, False
);
1463 paintButton(button
, texture
, pixel
, image
, True
);
1470 if (ev
.xbutton
.button
== clickButton
)
1478 paintButton(button
, texture
, pixel
, image
, False
);
1481 if (button
== fwin
->left_button
) {
1482 if (fwin
->on_click_left
)
1483 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1484 } else if (button
== fwin
->right_button
) {
1485 if (fwin
->on_click_right
)
1486 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1488 #ifdef XKB_BUTTON_HINT
1489 else if (button
== fwin
->language_button
) {
1490 if (fwin
->on_click_language
)
1491 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);