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
);
117 if (wPreferences
.use_saveunders
) {
119 XSetWindowAttributes attribs
;
122 attribs
.save_under
= True
;
123 XChangeWindowAttributes(dpy
, fwin
->core
->window
, vmask
, &attribs
);
126 /* setup stacking information */
127 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
128 fwin
->core
->stacking
->above
= NULL
;
129 fwin
->core
->stacking
->under
= NULL
;
130 fwin
->core
->stacking
->child_of
= NULL
;
131 fwin
->core
->stacking
->window_level
= wlevel
;
133 AddToStackList(fwin
->core
);
135 wFrameWindowUpdateBorders(fwin
, flags
);
140 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
146 WScreen
*scr
= fwin
->screen_ptr
;
148 width
= fwin
->core
->width
;
149 if (flags
& WFF_IS_SHADED
)
152 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
154 if (flags
& WFF_TITLEBAR
) {
155 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
157 if (theight
> *fwin
->title_max_height
)
158 theight
= *fwin
->title_max_height
;
160 if (theight
< *fwin
->title_min_height
)
161 theight
= *fwin
->title_min_height
;
166 if (wPreferences
.new_style
== TS_NEW
) {
168 } else if (wPreferences
.new_style
== TS_OLD
) {
174 if (fwin
->titlebar
) {
175 /* if we had a titlebar and is requesting for one,
176 * check if the size has changed and resize it */
177 if (flags
& WFF_TITLEBAR
) {
178 fwin
->top_width
= theight
;
180 fwin
->flags
.need_texture_remake
= 1;
182 if (wPreferences
.new_style
== TS_NEW
) {
183 if (fwin
->left_button
)
184 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
185 #ifdef XKB_BUTTON_HINT
186 if (fwin
->language_button
) {
187 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
188 || fwin
->flags
.lbutton_dont_fit
)
189 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
191 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
195 if (fwin
->right_button
)
196 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
198 } else { /* !new_style */
199 if (fwin
->left_button
)
200 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
201 #ifdef XKB_BUTTON_HINT
202 if (fwin
->language_button
)
203 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
207 if (fwin
->right_button
)
208 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
209 (theight
- bsize
) / 2, bsize
, bsize
);
211 updateTitlebar(fwin
);
213 /* we had a titlebar, but now we don't need it anymore */
214 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
215 FREE_PIXMAP(fwin
->title_back
[i
]);
216 if (wPreferences
.new_style
== TS_NEW
) {
217 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
218 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
219 #ifdef XKB_BUTTON_HINT
220 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
224 if (fwin
->left_button
)
225 wCoreDestroy(fwin
->left_button
);
226 fwin
->left_button
= NULL
;
228 #ifdef XKB_BUTTON_HINT
229 if (fwin
->language_button
)
230 wCoreDestroy(fwin
->language_button
);
231 fwin
->language_button
= NULL
;
234 if (fwin
->right_button
)
235 wCoreDestroy(fwin
->right_button
);
236 fwin
->right_button
= NULL
;
238 wCoreDestroy(fwin
->titlebar
);
239 fwin
->titlebar
= NULL
;
244 /* if we didn't have a titlebar and are being requested for
246 if (flags
& WFF_TITLEBAR
) {
247 fwin
->top_width
= theight
;
249 fwin
->flags
.titlebar
= 1;
250 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
252 if (flags
& WFF_LEFT_BUTTON
) {
253 fwin
->flags
.left_button
= 1;
254 if (wPreferences
.new_style
== TS_NEW
) {
255 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
257 if (width
< theight
* 4)
258 fwin
->flags
.lbutton_dont_fit
= 1;
260 XMapRaised(dpy
, fwin
->left_button
->window
);
262 } else if (wPreferences
.new_style
== TS_OLD
) {
264 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
266 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
267 scr
->widget_texture
->normal
.pixel
);
269 if (width
< theight
* 3)
270 fwin
->flags
.lbutton_dont_fit
= 1;
272 XMapRaised(dpy
, fwin
->left_button
->window
);
276 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
279 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
280 scr
->widget_texture
->dark
.pixel
);
282 if (width
< theight
* 3)
283 fwin
->flags
.lbutton_dont_fit
= 1;
285 XMapRaised(dpy
, fwin
->left_button
->window
);
289 #ifdef XKB_BUTTON_HINT
290 if (flags
& WFF_LANGUAGE_BUTTON
) {
291 fwin
->flags
.language_button
= 1;
292 if (wPreferences
.new_style
== TS_NEW
) {
293 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
295 if (width
< theight
* 4)
296 fwin
->flags
.languagebutton_dont_fit
= 1;
298 XMapRaised(dpy
, fwin
->language_button
->window
);
300 fwin
->language_button
=
301 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
304 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
305 scr
->widget_texture
->normal
.pixel
);
307 if (width
< theight
* 3)
308 fwin
->flags
.languagebutton_dont_fit
= 1;
310 XMapRaised(dpy
, fwin
->language_button
->window
);
315 if (flags
& WFF_RIGHT_BUTTON
) {
316 fwin
->flags
.right_button
= 1;
317 if (wPreferences
.new_style
== TS_NEW
) {
319 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
320 } else if (wPreferences
.new_style
== TS_OLD
) {
322 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
323 (theight
- bsize
) / 2, bsize
, bsize
);
324 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
325 scr
->widget_texture
->normal
.pixel
);
328 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
329 (theight
-bsize
)/2, bsize
, bsize
);
330 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
331 scr
->widget_texture
->dark
.pixel
);
334 if (width
< theight
* 2)
335 fwin
->flags
.rbutton_dont_fit
= 1;
337 XMapRaised(dpy
, fwin
->right_button
->window
);
340 if (wPreferences
.new_style
== TS_NEW
)
341 updateTitlebar(fwin
);
343 XMapRaised(dpy
, fwin
->titlebar
->window
);
345 fwin
->flags
.need_texture_remake
= 1;
348 checkTitleSize(fwin
);
350 if (flags
& WFF_RESIZEBAR
) {
351 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
353 if (!fwin
->resizebar
) {
354 fwin
->flags
.resizebar
= 1;
355 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
356 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
357 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
358 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
359 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
360 if (fwin
->resizebar_corner_width
< 0)
361 fwin
->resizebar_corner_width
= 0;
364 XMapWindow(dpy
, fwin
->resizebar
->window
);
365 XLowerWindow(dpy
, fwin
->resizebar
->window
);
367 fwin
->flags
.need_texture_remake
= 1;
369 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
)
370 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
371 width
, RESIZEBAR_HEIGHT
);
374 fwin
->bottom_width
= 0;
376 if (fwin
->resizebar
) {
377 fwin
->bottom_width
= 0;
378 wCoreDestroy(fwin
->resizebar
);
379 fwin
->resizebar
= NULL
;
383 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
))
384 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
386 if (flags
& WFF_BORDER
)
387 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
389 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
391 /* setup object descriptors */
392 if (fwin
->titlebar
) {
393 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
394 fwin
->titlebar
->descriptor
.parent
= fwin
;
395 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
396 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
399 if (fwin
->resizebar
) {
400 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
401 fwin
->resizebar
->descriptor
.parent
= fwin
;
402 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
403 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
406 if (fwin
->left_button
) {
407 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
408 fwin
->left_button
->descriptor
.parent
= fwin
;
409 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
410 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
413 #ifdef XKB_BUTTON_HINT
414 if (fwin
->language_button
) {
415 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
416 fwin
->language_button
->descriptor
.parent
= fwin
;
417 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
418 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
422 if (fwin
->right_button
) {
423 fwin
->right_button
->descriptor
.parent
= fwin
;
424 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
425 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
426 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
429 checkTitleSize(fwin
);
431 if (fwin
->border_pixel
)
432 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->border_pixel
);
435 void wFrameWindowDestroy(WFrameWindow
* fwin
)
439 if (fwin
->left_button
)
440 wCoreDestroy(fwin
->left_button
);
442 #ifdef XKB_BUTTON_HINT
443 if (fwin
->language_button
)
444 wCoreDestroy(fwin
->language_button
);
447 if (fwin
->right_button
)
448 wCoreDestroy(fwin
->right_button
);
451 wCoreDestroy(fwin
->resizebar
);
454 wCoreDestroy(fwin
->titlebar
);
456 RemoveFromStackList(fwin
->core
);
458 wCoreDestroy(fwin
->core
);
463 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
464 FREE_PIXMAP(fwin
->title_back
[i
]);
465 if (wPreferences
.new_style
== TS_NEW
) {
466 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
467 #ifdef XKB_BUTTON_HINT
468 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
470 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
477 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
479 if (fwin
->flags
.state
== state
)
482 fwin
->flags
.state
= state
;
483 fwin
->flags
.need_texture_change
= 1;
485 wFrameWindowPaint(fwin
);
488 static void updateTitlebar(WFrameWindow
* fwin
)
493 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
495 if (theight
> *fwin
->title_max_height
)
496 theight
= *fwin
->title_max_height
;
498 if (theight
< *fwin
->title_min_height
)
499 theight
= *fwin
->title_min_height
;
502 w
= fwin
->core
->width
+ 1;
504 if (wPreferences
.new_style
== TS_NEW
) {
505 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
507 #ifdef XKB_BUTTON_HINT
508 if (fwin
->language_button
)
509 wCoreConfigure(fwin
->language_button
, 0, 0,
510 fwin
->language_button
->width
, fwin
->language_button
->width
);
513 #ifdef XKB_BUTTON_HINT
514 if (fwin
->language_button
)
515 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
516 fwin
->language_button
->width
, fwin
->language_button
->width
);
518 x
= fwin
->left_button
->width
;
519 w
-= fwin
->left_button
->width
;
521 #ifdef XKB_BUTTON_HINT
522 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
523 || fwin
->flags
.languagebutton_dont_fit
) {
525 x
+= fwin
->language_button
->width
;
526 w
-= fwin
->language_button
->width
;
530 #ifdef XKB_BUTTON_HINT
532 int bsize
= theight
- 7;
533 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
534 if (fwin
->language_button
)
535 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
536 fwin
->language_button
->width
, fwin
->language_button
->width
);
538 if (fwin
->language_button
)
539 wCoreConfigure(fwin
->language_button
,
540 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
541 fwin
->language_button
->width
, fwin
->language_button
->width
);
546 if (wPreferences
.new_style
== TS_NEW
) {
547 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
)
548 w
-= fwin
->right_button
->width
;
551 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
552 fwin
->flags
.need_texture_remake
= 1;
554 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
557 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
559 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
560 XUnmapWindow(dpy
, fwin
->right_button
->window
);
561 fwin
->flags
.hide_right_button
= 1;
564 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
565 XUnmapWindow(dpy
, fwin
->left_button
->window
);
566 fwin
->flags
.hide_left_button
= 1;
568 #ifdef XKB_BUTTON_HINT
569 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
570 XUnmapWindow(dpy
, fwin
->language_button
->window
);
571 fwin
->flags
.hide_language_button
= 1;
575 if (fwin
->titlebar
) {
576 if (wPreferences
.new_style
== TS_NEW
) {
577 updateTitlebar(fwin
);
579 #ifdef XKB_BUTTON_HINT
580 updateTitlebar(fwin
);
582 XClearWindow(dpy
, fwin
->titlebar
->window
);
583 wFrameWindowPaint(fwin
);
586 checkTitleSize(fwin
);
590 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
592 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
594 if (!fwin
->flags
.rbutton_dont_fit
)
595 XMapWindow(dpy
, fwin
->right_button
->window
);
597 fwin
->flags
.hide_right_button
= 0;
599 #ifdef XKB_BUTTON_HINT
600 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
602 if (!fwin
->flags
.languagebutton_dont_fit
)
603 XMapWindow(dpy
, fwin
->language_button
->window
);
605 fwin
->flags
.hide_language_button
= 0;
609 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
611 if (!fwin
->flags
.lbutton_dont_fit
)
612 XMapWindow(dpy
, fwin
->left_button
->window
);
614 fwin
->flags
.hide_left_button
= 0;
617 if (fwin
->titlebar
) {
618 if (wPreferences
.new_style
== TS_NEW
) {
619 updateTitlebar(fwin
);
621 XClearWindow(dpy
, fwin
->titlebar
->window
);
622 wFrameWindowPaint(fwin
);
624 checkTitleSize(fwin
);
629 #ifdef XKB_BUTTON_HINT
630 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
631 int bwidth
, int bheight
, int left
, int language
, int right
,
632 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
634 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
635 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
639 RImage
*limg
, *rimg
, *mimg
;
640 #ifdef XKB_BUTTON_HINT
648 #ifdef XKB_BUTTON_HINT
649 *languagebutton
= None
;
652 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
654 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
658 if (wPreferences
.new_style
== TS_NEW
) {
660 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
667 #ifdef XKB_BUTTON_HINT
669 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
675 RBevelImage(limg
, RBEV_RAISED2
);
676 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
))
677 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
683 #ifdef XKB_BUTTON_HINT
685 RBevelImage(timg
, RBEV_RAISED2
);
686 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
))
687 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
696 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
701 RBevelImage(rimg
, RBEV_RAISED2
);
702 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
))
703 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
710 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
711 RBevelImage(mimg
, RBEV_RAISED2
);
713 if (!RConvertImage(scr
->rcontext
, mimg
, title
))
714 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
718 RBevelImage(img
, RBEV_RAISED2
);
720 if (!RConvertImage(scr
->rcontext
, img
, title
))
721 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
724 RBevelImage(img
, RBEV_RAISED2
);
726 if (!RConvertImage(scr
->rcontext
, img
, title
))
727 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
734 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
742 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
744 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
749 light
.red
= light
.green
= light
.blue
= 80;
752 dark
.red
= dark
.green
= dark
.blue
= 40;
754 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
755 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
757 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
758 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
761 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
762 width
- cwidth
- 2, height
- 1, &dark
);
763 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
765 #ifdef SHADOW_RESIZEBAR
766 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
767 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
768 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
769 #endif /* SHADOW_RESIZEBAR */
771 if (!RConvertImage(scr
->rcontext
, img
, pmap
))
772 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
777 static void updateTexture(WFrameWindow
* fwin
)
782 i
= fwin
->flags
.state
;
783 if (fwin
->titlebar
) {
784 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
785 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
786 if (wPreferences
.new_style
== TS_NEW
) {
787 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
788 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
789 fwin
->lbutton_back
[i
]);
791 #ifdef XKB_BUTTON_HINT
792 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
])
793 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
794 fwin
->languagebutton_back
[i
]);
797 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
798 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
799 fwin
->rbutton_back
[i
]);
802 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
803 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
804 if (wPreferences
.new_style
== TS_NEW
) {
805 if (fwin
->left_button
)
806 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
807 #ifdef XKB_BUTTON_HINT
808 if (fwin
->language_button
)
809 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
811 if (fwin
->right_button
)
812 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
815 XClearWindow(dpy
, fwin
->titlebar
->window
);
817 if (fwin
->left_button
) {
818 XClearWindow(dpy
, fwin
->left_button
->window
);
819 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
821 #ifdef XKB_BUTTON_HINT
822 if (fwin
->language_button
) {
823 XClearWindow(dpy
, fwin
->language_button
->window
);
824 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
827 if (fwin
->right_button
) {
828 XClearWindow(dpy
, fwin
->right_button
->window
);
829 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
834 static void remakeTexture(WFrameWindow
* fwin
, int state
)
836 Pixmap pmap
, lpmap
, rpmap
;
837 #ifdef XKB_BUTTON_HINT
841 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
842 FREE_PIXMAP(fwin
->title_back
[state
]);
843 if (wPreferences
.new_style
== TS_NEW
) {
844 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
845 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
846 #ifdef XKB_BUTTON_HINT
847 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
851 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
854 #ifdef XKB_BUTTON_HINT
858 /* eventually surrounded by if new_style */
859 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
860 #ifdef XKB_BUTTON_HINT
861 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
862 && !fwin
->flags
.languagebutton_dont_fit
;
864 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
865 && !fwin
->flags
.rbutton_dont_fit
;
867 width
= fwin
->core
->width
+ 1;
869 #ifdef XKB_BUTTON_HINT
870 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
871 width
, fwin
->titlebar
->height
,
872 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
873 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
875 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
876 width
, fwin
->titlebar
->height
,
877 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
878 left
, right
, &pmap
, &lpmap
, &rpmap
);
881 fwin
->title_back
[state
] = pmap
;
882 if (wPreferences
.new_style
== TS_NEW
) {
883 fwin
->lbutton_back
[state
] = lpmap
;
884 fwin
->rbutton_back
[state
] = rpmap
;
885 #ifdef XKB_BUTTON_HINT
886 fwin
->languagebutton_back
[state
] = tpmap
;
891 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
892 && fwin
->resizebar
&& state
== 0) {
894 FREE_PIXMAP(fwin
->resizebar_back
[0]);
896 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
898 renderResizebarTexture(fwin
->screen_ptr
,
899 fwin
->resizebar_texture
[0],
900 fwin
->resizebar
->width
,
901 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
903 fwin
->resizebar_back
[0] = pmap
;
906 /* this part should be in updateTexture() */
907 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
)
908 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
910 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
911 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
913 XClearWindow(dpy
, fwin
->resizebar
->window
);
917 void wFrameWindowPaint(WFrameWindow
* fwin
)
919 WScreen
*scr
= fwin
->screen_ptr
;
922 state
= fwin
->flags
.state
;
924 if (fwin
->flags
.is_client_window_frame
)
925 fwin
->flags
.justification
= wPreferences
.title_justification
;
927 if (fwin
->flags
.need_texture_remake
) {
930 fwin
->flags
.need_texture_remake
= 0;
931 fwin
->flags
.need_texture_change
= 0;
933 if (fwin
->flags
.single_texture
) {
934 remakeTexture(fwin
, 0);
937 /* first render the texture for the current state... */
938 remakeTexture(fwin
, state
);
939 /* ... and paint it */
942 for (i
= 0; i
< 3; i
++) {
944 remakeTexture(fwin
, i
);
949 if (fwin
->flags
.need_texture_change
) {
950 fwin
->flags
.need_texture_change
= 0;
955 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
956 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
957 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
958 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
961 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
962 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
967 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
969 w
= fwin
->resizebar
->width
;
970 h
= fwin
->resizebar
->height
;
971 cw
= fwin
->resizebar_corner_width
;
972 light_gc
= texture
->light_gc
;
973 dim_gc
= texture
->dim_gc
;
974 win
= fwin
->resizebar
->window
;
976 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
977 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
979 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
980 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
982 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
983 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
985 #ifdef SHADOW_RESIZEBAR
986 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
987 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
988 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
989 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
990 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
991 #endif /* SHADOW_RESIZEBAR */
994 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
996 int lofs
= 6, rofs
= 6;
1000 if (!wPreferences
.new_style
== TS_NEW
) {
1001 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1002 lofs
+= fwin
->left_button
->width
+ 3;
1006 #ifdef XKB_BUTTON_HINT
1007 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1008 && !fwin
->flags
.languagebutton_dont_fit
)
1009 lofs
+= fwin
->language_button
->width
;
1014 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1015 rofs
+= fwin
->right_button
->width
+ 3;
1019 #ifdef XKB_BUTTON_HINT
1020 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1027 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
1028 titlelen
= strlen(title
);
1029 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1031 switch (fwin
->flags
.justification
) {
1037 x
= fwin
->titlebar
->width
- w
- rofs
;
1042 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1044 x
= (fwin
->titlebar
->width
- w
) / 2;
1048 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1049 h
= WMFontHeight(*fwin
->font
);
1051 if (y
*2 + h
> *fwin
->title_max_height
)
1052 y
= (*fwin
->title_max_height
- h
) / 2;
1054 if (y
*2 + h
< *fwin
->title_min_height
)
1055 y
= (*fwin
->title_min_height
- h
) / 2;
1057 /* We use a w+2 buffer to have an extra pixel on the left and
1058 * another one on the right. This is because for some odd reason,
1059 * sometimes when using AA fonts (when libfreetype2 is compiled
1060 * with bytecode interpreter turned off), some fonts are drawn
1061 * starting from x = -1 not from 0 as requested. Observed with
1062 * capital A letter on the bold 'trebuchet ms' font. -Dan
1064 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1066 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1068 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1069 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1070 x
- 1, y
, w
+ 2, h
, 0, 0);
1072 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1073 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1076 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1077 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1078 *fwin
->font
, 1, 0, title
, titlelen
);
1080 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1082 XFreePixmap(dpy
, buf
);
1087 if (fwin
->left_button
)
1088 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1089 if (fwin
->right_button
)
1090 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1091 #ifdef XKB_BUTTON_HINT
1092 if (fwin
->language_button
)
1093 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1098 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1100 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1101 int resizedHorizontally
= 0;
1104 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1106 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1108 if (fwin
->core
->width
!= width
) {
1109 fwin
->flags
.need_texture_remake
= 1;
1110 resizedHorizontally
= 1;
1113 fwin
->core
->width
= width
;
1114 fwin
->core
->height
= height
;
1116 if (fwin
->titlebar
&& resizedHorizontally
) {
1117 /* Check if the titlebar is wide enough to hold the buttons.
1118 * Temporarily remove them if can't
1120 if (fwin
->left_button
) {
1121 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1122 if (!fwin
->flags
.hide_left_button
)
1123 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1125 fwin
->flags
.lbutton_dont_fit
= 1;
1126 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1127 if (!fwin
->flags
.hide_left_button
)
1128 XMapWindow(dpy
, fwin
->left_button
->window
);
1130 fwin
->flags
.lbutton_dont_fit
= 0;
1133 #ifdef XKB_BUTTON_HINT
1134 if (fwin
->language_button
) {
1135 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1136 if (!fwin
->flags
.hide_language_button
)
1137 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1139 fwin
->flags
.languagebutton_dont_fit
= 1;
1140 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1141 if (!fwin
->flags
.hide_language_button
)
1142 XMapWindow(dpy
, fwin
->language_button
->window
);
1144 fwin
->flags
.languagebutton_dont_fit
= 0;
1149 if (fwin
->right_button
) {
1150 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1151 if (!fwin
->flags
.hide_right_button
)
1152 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1154 fwin
->flags
.rbutton_dont_fit
= 1;
1155 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1156 if (!fwin
->flags
.hide_right_button
)
1157 XMapWindow(dpy
, fwin
->right_button
->window
);
1159 fwin
->flags
.rbutton_dont_fit
= 0;
1163 if (wPreferences
.new_style
== TS_NEW
) {
1164 if (fwin
->right_button
)
1165 XMoveWindow(dpy
, fwin
->right_button
->window
,
1166 width
- fwin
->right_button
->width
+ 1, 0);
1168 if (fwin
->right_button
)
1169 XMoveWindow(dpy
, fwin
->right_button
->window
,
1170 width
- fwin
->right_button
->width
- 3,
1171 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1173 updateTitlebar(fwin
);
1174 checkTitleSize(fwin
);
1177 if (fwin
->resizebar
) {
1178 wCoreConfigure(fwin
->resizebar
, 0,
1179 fwin
->core
->height
- fwin
->resizebar
->height
,
1180 fwin
->core
->width
, fwin
->resizebar
->height
);
1182 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1183 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
)
1184 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1188 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1190 reconfigure(fwin
, x
, y
, width
, height
, False
);
1193 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1195 reconfigure(fwin
, 0, 0, width
, height
, True
);
1198 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1200 /* check if the title is the same as before */
1202 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0))
1212 fwin
->title
= wstrdup(new_title
);
1214 if (fwin
->titlebar
) {
1215 XClearWindow(dpy
, fwin
->titlebar
->window
);
1217 wFrameWindowPaint(fwin
);
1219 checkTitleSize(fwin
);
1224 #ifdef XKB_BUTTON_HINT
1225 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1227 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1228 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1230 #endif /* XKB_BUTTON_HINT */
1232 /*********************************************************************/
1234 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1236 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1238 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1239 fwin
->flags
.repaint_only_titlebar
= 1;
1240 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1241 fwin
->flags
.repaint_only_resizebar
= 1;
1242 wFrameWindowPaint(fwin
);
1243 fwin
->flags
.repaint_only_titlebar
= 0;
1244 fwin
->flags
.repaint_only_resizebar
= 0;
1247 static void checkTitleSize(WFrameWindow
* fwin
)
1252 fwin
->flags
.incomplete_title
= 0;
1256 if (!fwin
->titlebar
) {
1257 fwin
->flags
.incomplete_title
= 1;
1260 width
= fwin
->titlebar
->width
- 6 - 6;
1263 if (!wPreferences
.new_style
== TS_NEW
) {
1264 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1265 width
-= fwin
->left_button
->width
+ 3;
1267 #ifdef XKB_BUTTON_HINT
1268 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1269 && !fwin
->flags
.languagebutton_dont_fit
)
1270 width
-= fwin
->language_button
->width
+ 3;
1273 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1274 width
-= fwin
->right_button
->width
+ 3;
1277 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
)
1278 fwin
->flags
.incomplete_title
= 1;
1280 fwin
->flags
.incomplete_title
= 0;
1283 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1285 WScreen
*scr
= button
->screen_ptr
;
1286 GC copy_gc
= scr
->copy_gc
;
1287 int x
= 0, y
= 0, d
= 0;
1288 int left
= 0, width
= 0;
1290 /* setup stuff according to the state */
1293 if (image
->width
>= image
->height
* 2) {
1294 /* the image contains 2 pictures: the second is for the
1296 width
= image
->width
/ 2;
1297 left
= image
->width
/ 2;
1299 width
= image
->width
;
1302 XSetClipMask(dpy
, copy_gc
, None
);
1303 if (wPreferences
.new_style
== TS_NEXT
)
1304 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1306 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1309 if (wPreferences
.new_style
== TS_NEW
) {
1310 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1311 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1312 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1313 } else if (wPreferences
.new_style
== TS_OLD
) {
1314 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1315 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1316 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1318 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1319 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1320 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1323 XClearWindow(dpy
, button
->window
);
1326 if (image
->width
>= image
->height
* 2)
1327 width
= image
->width
/ 2;
1329 width
= image
->width
;
1333 if (wPreferences
.new_style
== TS_NEW
) {
1334 if (texture
->any
.type
== WTEX_SOLID
|| pushed
)
1335 wDrawBevel(button
->window
, button
->width
, button
->height
,
1336 (WTexSolid
*) texture
, WREL_RAISED
);
1338 wDrawBevel(button
->window
, button
->width
, button
->height
,
1339 scr
->widget_texture
, WREL_RAISED
);
1345 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1346 x
= (button
->width
- width
) / 2 + d
;
1347 y
= (button
->height
- image
->height
) / 2 + d
;
1348 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1349 if (!wPreferences
.new_style
== TS_NEW
) {
1350 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1352 if (image
->depth
== 1)
1353 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1354 left
, 0, width
, image
->height
, x
, y
, 1);
1356 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1357 left
, 0, width
, image
->height
, x
, y
);
1359 if (wPreferences
.new_style
== TS_OLD
) {
1360 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1361 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1362 button
->width
, button
->height
);
1364 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1365 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1366 left
, 0, width
, image
->height
, x
, y
);
1371 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1373 XSetForeground(dpy
, copy_gc
, color
);
1374 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1376 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1381 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1383 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1384 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1386 #ifdef XKB_BUTTON_HINT
1387 if (button
== fwin
->language_button
) {
1388 if (wPreferences
.modelock
)
1389 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1390 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1391 fwin
->languagebutton_image
, False
);
1394 if (button
== fwin
->left_button
)
1395 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1396 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1398 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1399 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1402 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1404 WFrameWindow
*fwin
= desc
->parent
;
1405 WCoreWindow
*titlebar
= desc
->self
;
1407 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1408 if (fwin
->on_dblclick_titlebar
)
1409 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1411 if (fwin
->on_mousedown_titlebar
)
1412 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1416 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1418 WFrameWindow
*fwin
= desc
->parent
;
1419 WCoreWindow
*resizebar
= desc
->self
;
1421 if (fwin
->on_mousedown_resizebar
)
1422 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1425 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1427 WFrameWindow
*fwin
= desc
->parent
;
1428 WCoreWindow
*button
= desc
->self
;
1431 int done
= 0, execute
= 1;
1433 unsigned long pixel
;
1434 int clickButton
= event
->xbutton
.button
;
1436 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1437 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
)
1438 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1443 if (button
== fwin
->left_button
)
1444 image
= fwin
->lbutton_image
;
1446 image
= fwin
->rbutton_image
;
1448 #ifdef XKB_BUTTON_HINT
1449 if (button
== fwin
->language_button
) {
1450 if (!wPreferences
.modelock
)
1452 image
= fwin
->languagebutton_image
;
1456 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1457 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1458 paintButton(button
, texture
, pixel
, image
, True
);
1461 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1462 | ButtonPressMask
| ExposureMask
, &ev
);
1466 paintButton(button
, texture
, pixel
, image
, False
);
1471 paintButton(button
, texture
, pixel
, image
, True
);
1478 if (ev
.xbutton
.button
== clickButton
)
1486 paintButton(button
, texture
, pixel
, image
, False
);
1489 if (button
== fwin
->left_button
) {
1490 if (fwin
->on_click_left
)
1491 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1492 } else if (button
== fwin
->right_button
) {
1493 if (fwin
->on_click_right
)
1494 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1496 #ifdef XKB_BUTTON_HINT
1497 else if (button
== fwin
->language_button
) {
1498 if (fwin
->on_click_language
)
1499 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);