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
49 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
);
50 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
);
52 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
53 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
54 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
);
56 static void checkTitleSize(WFrameWindow
* fwin
);
58 static void paintButton(WCoreWindow
* button
, WTexture
* texture
,
59 unsigned long color
, WPixmap
* image
, int pushed
);
61 static void updateTitlebar(WFrameWindow
* fwin
);
63 static void allocFrameBorderPixel(Colormap colormap
, const char *color_name
, unsigned long **pixel
);
65 static void allocFrameBorderPixel(Colormap colormap
, const char *color_name
, unsigned long **pixel
) {
70 if (! wGetColorForColormap(colormap
, color_name
, &xcol
))
73 *pixel
= wmalloc(sizeof(unsigned long));
78 WFrameWindow
*wFrameWindowCreate(WScreen
* scr
, int wlevel
, int x
, int y
,
79 int width
, int height
, int *clearance
,
80 int *title_min
, int *title_max
, int flags
,
81 WTexture
** title_texture
, WTexture
** resize_texture
,
82 WMColor
** color
, WMFont
** font
,
83 int depth
, Visual
*visual
, Colormap colormap
)
87 fwin
= wmalloc(sizeof(WFrameWindow
));
89 fwin
->screen_ptr
= scr
;
91 fwin
->flags
.single_texture
= (flags
& WFF_SINGLE_STATE
) ? 1 : 0;
93 fwin
->title_texture
= title_texture
;
94 fwin
->resizebar_texture
= resize_texture
;
95 fwin
->title_color
= color
;
96 fwin
->title_clearance
= clearance
;
97 fwin
->title_min_height
= title_min
;
98 fwin
->title_max_height
= title_max
;
100 #ifdef KEEP_XKB_LOCK_STATUS
101 fwin
->languagemode
= XkbGroup1Index
;
102 fwin
->last_languagemode
= XkbGroup2Index
;
106 fwin
->visual
= visual
;
107 fwin
->colormap
= colormap
;
109 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
110 ? scr
->frame_border_width
: 0, fwin
->depth
, fwin
->visual
, fwin
->colormap
, scr
->frame_border_pixel
);
112 /* setup stacking information */
113 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
114 fwin
->core
->stacking
->above
= NULL
;
115 fwin
->core
->stacking
->under
= NULL
;
116 fwin
->core
->stacking
->child_of
= NULL
;
117 fwin
->core
->stacking
->window_level
= wlevel
;
119 AddToStackList(fwin
->core
);
121 wFrameWindowUpdateBorders(fwin
, flags
);
126 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
132 WScreen
*scr
= fwin
->screen_ptr
;
134 width
= fwin
->core
->width
;
135 if (flags
& WFF_IS_SHADED
)
138 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
140 if (flags
& WFF_TITLEBAR
) {
141 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
143 if (theight
> *fwin
->title_max_height
)
144 theight
= *fwin
->title_max_height
;
146 if (theight
< *fwin
->title_min_height
)
147 theight
= *fwin
->title_min_height
;
152 if (wPreferences
.new_style
== TS_NEW
) {
154 } else if (wPreferences
.new_style
== TS_OLD
) {
160 if (fwin
->titlebar
) {
161 /* if we had a titlebar and is requesting for one,
162 * check if the size has changed and resize it */
163 if (flags
& WFF_TITLEBAR
) {
164 fwin
->top_width
= theight
;
166 fwin
->flags
.need_texture_remake
= 1;
168 if (wPreferences
.new_style
== TS_NEW
) {
169 if (fwin
->left_button
)
170 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
171 #ifdef XKB_BUTTON_HINT
172 if (fwin
->language_button
) {
173 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
174 || fwin
->flags
.lbutton_dont_fit
)
175 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
177 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
181 if (fwin
->right_button
)
182 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
184 } else { /* !new_style */
185 if (fwin
->left_button
)
186 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
187 #ifdef XKB_BUTTON_HINT
188 if (fwin
->language_button
)
189 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
193 if (fwin
->right_button
)
194 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
195 (theight
- bsize
) / 2, bsize
, bsize
);
197 updateTitlebar(fwin
);
199 /* we had a titlebar, but now we don't need it anymore */
200 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
201 FREE_PIXMAP(fwin
->title_back
[i
]);
202 if (wPreferences
.new_style
== TS_NEW
) {
203 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
204 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
205 #ifdef XKB_BUTTON_HINT
206 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
210 if (fwin
->left_button
)
211 wCoreDestroy(fwin
->left_button
);
212 fwin
->left_button
= NULL
;
214 #ifdef XKB_BUTTON_HINT
215 if (fwin
->language_button
)
216 wCoreDestroy(fwin
->language_button
);
217 fwin
->language_button
= NULL
;
220 if (fwin
->right_button
)
221 wCoreDestroy(fwin
->right_button
);
222 fwin
->right_button
= NULL
;
224 wCoreDestroy(fwin
->titlebar
);
225 fwin
->titlebar
= NULL
;
230 /* if we didn't have a titlebar and are being requested for
232 if (flags
& WFF_TITLEBAR
) {
233 fwin
->top_width
= theight
;
235 fwin
->flags
.titlebar
= 1;
236 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
238 if (flags
& WFF_LEFT_BUTTON
) {
239 fwin
->flags
.left_button
= 1;
240 if (wPreferences
.new_style
== TS_NEW
) {
241 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
243 if (width
< theight
* 4)
244 fwin
->flags
.lbutton_dont_fit
= 1;
246 XMapRaised(dpy
, fwin
->left_button
->window
);
248 } else if (wPreferences
.new_style
== TS_OLD
) {
250 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
252 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
253 scr
->widget_texture
->normal
.pixel
);
255 if (width
< theight
* 3)
256 fwin
->flags
.lbutton_dont_fit
= 1;
258 XMapRaised(dpy
, fwin
->left_button
->window
);
262 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
265 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
266 scr
->widget_texture
->dark
.pixel
);
268 if (width
< theight
* 3)
269 fwin
->flags
.lbutton_dont_fit
= 1;
271 XMapRaised(dpy
, fwin
->left_button
->window
);
275 #ifdef XKB_BUTTON_HINT
276 if (flags
& WFF_LANGUAGE_BUTTON
) {
277 fwin
->flags
.language_button
= 1;
278 if (wPreferences
.new_style
== TS_NEW
) {
279 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
281 if (width
< theight
* 4)
282 fwin
->flags
.languagebutton_dont_fit
= 1;
284 XMapRaised(dpy
, fwin
->language_button
->window
);
286 fwin
->language_button
=
287 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
290 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
291 scr
->widget_texture
->normal
.pixel
);
293 if (width
< theight
* 3)
294 fwin
->flags
.languagebutton_dont_fit
= 1;
296 XMapRaised(dpy
, fwin
->language_button
->window
);
301 if (flags
& WFF_RIGHT_BUTTON
) {
302 fwin
->flags
.right_button
= 1;
303 if (wPreferences
.new_style
== TS_NEW
) {
305 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
306 } else if (wPreferences
.new_style
== TS_OLD
) {
308 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
309 (theight
- bsize
) / 2, bsize
, bsize
);
310 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
311 scr
->widget_texture
->normal
.pixel
);
314 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
315 (theight
-bsize
)/2, bsize
, bsize
);
316 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
317 scr
->widget_texture
->dark
.pixel
);
320 if (width
< theight
* 2)
321 fwin
->flags
.rbutton_dont_fit
= 1;
323 XMapRaised(dpy
, fwin
->right_button
->window
);
326 if (wPreferences
.new_style
== TS_NEW
)
327 updateTitlebar(fwin
);
329 XMapRaised(dpy
, fwin
->titlebar
->window
);
331 fwin
->flags
.need_texture_remake
= 1;
334 checkTitleSize(fwin
);
336 if (flags
& WFF_RESIZEBAR
) {
337 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
339 if (!fwin
->resizebar
) {
340 fwin
->flags
.resizebar
= 1;
341 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
342 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
343 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
344 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
345 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
346 if (fwin
->resizebar_corner_width
< 0)
347 fwin
->resizebar_corner_width
= 0;
350 XMapWindow(dpy
, fwin
->resizebar
->window
);
351 XLowerWindow(dpy
, fwin
->resizebar
->window
);
353 fwin
->flags
.need_texture_remake
= 1;
355 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
)
356 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
357 width
, RESIZEBAR_HEIGHT
);
360 fwin
->bottom_width
= 0;
362 if (fwin
->resizebar
) {
363 fwin
->bottom_width
= 0;
364 wCoreDestroy(fwin
->resizebar
);
365 fwin
->resizebar
= NULL
;
369 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
))
370 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
372 if (flags
& WFF_BORDER
)
373 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, scr
->frame_border_width
);
375 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
377 /* setup object descriptors */
378 if (fwin
->titlebar
) {
379 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
380 fwin
->titlebar
->descriptor
.parent
= fwin
;
381 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
382 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
385 if (fwin
->resizebar
) {
386 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
387 fwin
->resizebar
->descriptor
.parent
= fwin
;
388 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
389 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
392 if (fwin
->left_button
) {
393 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
394 fwin
->left_button
->descriptor
.parent
= fwin
;
395 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
396 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
399 #ifdef XKB_BUTTON_HINT
400 if (fwin
->language_button
) {
401 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
402 fwin
->language_button
->descriptor
.parent
= fwin
;
403 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
404 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
408 if (fwin
->right_button
) {
409 fwin
->right_button
->descriptor
.parent
= fwin
;
410 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
411 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
412 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
415 checkTitleSize(fwin
);
417 allocFrameBorderPixel(fwin
->colormap
, WMGetColorRGBDescription(scr
->frame_border_color
), &fwin
->border_pixel
);
418 allocFrameBorderPixel(fwin
->colormap
, WMGetColorRGBDescription(scr
->frame_focused_border_color
), &fwin
->focused_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
->flags
.state
== WS_FOCUSED
) {
427 if (fwin
->focused_border_pixel
)
428 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->focused_border_pixel
);
430 if (fwin
->border_pixel
)
431 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->border_pixel
);
436 void wFrameWindowDestroy(WFrameWindow
* fwin
)
440 if (fwin
->left_button
)
441 wCoreDestroy(fwin
->left_button
);
443 #ifdef XKB_BUTTON_HINT
444 if (fwin
->language_button
)
445 wCoreDestroy(fwin
->language_button
);
448 if (fwin
->right_button
)
449 wCoreDestroy(fwin
->right_button
);
452 wCoreDestroy(fwin
->resizebar
);
455 wCoreDestroy(fwin
->titlebar
);
457 RemoveFromStackList(fwin
->core
);
459 wCoreDestroy(fwin
->core
);
464 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
465 FREE_PIXMAP(fwin
->title_back
[i
]);
466 if (wPreferences
.new_style
== TS_NEW
) {
467 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
468 #ifdef XKB_BUTTON_HINT
469 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
471 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
478 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
480 if (fwin
->flags
.state
== state
)
483 fwin
->flags
.state
= state
;
484 fwin
->flags
.need_texture_change
= 1;
486 if (fwin
->flags
.state
== WS_FOCUSED
) {
487 if (fwin
->focused_border_pixel
)
488 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->focused_border_pixel
);
490 if (fwin
->border_pixel
)
491 XSetWindowBorder(dpy
, fwin
->core
->window
, *fwin
->border_pixel
);
493 wFrameWindowPaint(fwin
);
496 static void updateTitlebar(WFrameWindow
* fwin
)
501 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
503 if (theight
> *fwin
->title_max_height
)
504 theight
= *fwin
->title_max_height
;
506 if (theight
< *fwin
->title_min_height
)
507 theight
= *fwin
->title_min_height
;
510 w
= fwin
->core
->width
+ 1;
512 if (wPreferences
.new_style
== TS_NEW
) {
513 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
515 #ifdef XKB_BUTTON_HINT
516 if (fwin
->language_button
)
517 wCoreConfigure(fwin
->language_button
, 0, 0,
518 fwin
->language_button
->width
, fwin
->language_button
->width
);
521 #ifdef XKB_BUTTON_HINT
522 if (fwin
->language_button
)
523 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
524 fwin
->language_button
->width
, fwin
->language_button
->width
);
526 x
= fwin
->left_button
->width
;
527 w
-= fwin
->left_button
->width
;
529 #ifdef XKB_BUTTON_HINT
530 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
531 || fwin
->flags
.languagebutton_dont_fit
) {
533 x
+= fwin
->language_button
->width
;
534 w
-= fwin
->language_button
->width
;
538 #ifdef XKB_BUTTON_HINT
540 int bsize
= theight
- 7;
541 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
542 if (fwin
->language_button
)
543 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
544 fwin
->language_button
->width
, fwin
->language_button
->width
);
546 if (fwin
->language_button
)
547 wCoreConfigure(fwin
->language_button
,
548 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
549 fwin
->language_button
->width
, fwin
->language_button
->width
);
554 if (wPreferences
.new_style
== TS_NEW
) {
555 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
)
556 w
-= fwin
->right_button
->width
;
559 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
560 fwin
->flags
.need_texture_remake
= 1;
562 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
565 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
567 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
568 XUnmapWindow(dpy
, fwin
->right_button
->window
);
569 fwin
->flags
.hide_right_button
= 1;
572 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
573 XUnmapWindow(dpy
, fwin
->left_button
->window
);
574 fwin
->flags
.hide_left_button
= 1;
576 #ifdef XKB_BUTTON_HINT
577 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
578 XUnmapWindow(dpy
, fwin
->language_button
->window
);
579 fwin
->flags
.hide_language_button
= 1;
583 if (fwin
->titlebar
) {
584 if (wPreferences
.new_style
== TS_NEW
) {
585 updateTitlebar(fwin
);
587 #ifdef XKB_BUTTON_HINT
588 updateTitlebar(fwin
);
590 XClearWindow(dpy
, fwin
->titlebar
->window
);
591 wFrameWindowPaint(fwin
);
594 checkTitleSize(fwin
);
598 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
600 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
602 if (!fwin
->flags
.rbutton_dont_fit
)
603 XMapWindow(dpy
, fwin
->right_button
->window
);
605 fwin
->flags
.hide_right_button
= 0;
607 #ifdef XKB_BUTTON_HINT
608 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
610 if (!fwin
->flags
.languagebutton_dont_fit
)
611 XMapWindow(dpy
, fwin
->language_button
->window
);
613 fwin
->flags
.hide_language_button
= 0;
617 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
619 if (!fwin
->flags
.lbutton_dont_fit
)
620 XMapWindow(dpy
, fwin
->left_button
->window
);
622 fwin
->flags
.hide_left_button
= 0;
625 if (fwin
->titlebar
) {
626 if (wPreferences
.new_style
== TS_NEW
) {
627 updateTitlebar(fwin
);
629 XClearWindow(dpy
, fwin
->titlebar
->window
);
630 wFrameWindowPaint(fwin
);
632 checkTitleSize(fwin
);
637 #ifdef XKB_BUTTON_HINT
638 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
639 int bwidth
, int bheight
, int left
, int language
, int right
,
640 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
642 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
643 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
647 RImage
*limg
, *rimg
, *mimg
;
648 #ifdef XKB_BUTTON_HINT
656 #ifdef XKB_BUTTON_HINT
657 *languagebutton
= None
;
660 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
662 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
666 if (wPreferences
.new_style
== TS_NEW
) {
668 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
675 #ifdef XKB_BUTTON_HINT
677 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
683 RBevelImage(limg
, RBEV_RAISED2
);
684 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
))
685 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
691 #ifdef XKB_BUTTON_HINT
693 RBevelImage(timg
, RBEV_RAISED2
);
694 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
))
695 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
704 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
709 RBevelImage(rimg
, RBEV_RAISED2
);
710 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
))
711 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
718 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
719 RBevelImage(mimg
, RBEV_RAISED2
);
721 if (!RConvertImage(scr
->rcontext
, mimg
, title
))
722 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
726 RBevelImage(img
, RBEV_RAISED2
);
728 if (!RConvertImage(scr
->rcontext
, img
, title
))
729 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
732 RBevelImage(img
, RBEV_RAISED2
);
734 if (!RConvertImage(scr
->rcontext
, img
, title
))
735 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
742 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
750 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
752 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
757 light
.red
= light
.green
= light
.blue
= 80;
760 dark
.red
= dark
.green
= dark
.blue
= 40;
762 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
763 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
765 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
766 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
769 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
770 width
- cwidth
- 2, height
- 1, &dark
);
771 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
773 #ifdef SHADOW_RESIZEBAR
774 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
775 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
776 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
777 #endif /* SHADOW_RESIZEBAR */
779 if (!RConvertImage(scr
->rcontext
, img
, pmap
))
780 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
785 static void updateTexture(WFrameWindow
* fwin
)
790 i
= fwin
->flags
.state
;
791 if (fwin
->titlebar
) {
792 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
793 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
794 if (wPreferences
.new_style
== TS_NEW
) {
795 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
796 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
797 fwin
->lbutton_back
[i
]);
799 #ifdef XKB_BUTTON_HINT
800 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
])
801 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
802 fwin
->languagebutton_back
[i
]);
805 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
806 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
807 fwin
->rbutton_back
[i
]);
810 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
811 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
812 if (wPreferences
.new_style
== TS_NEW
) {
813 if (fwin
->left_button
)
814 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
815 #ifdef XKB_BUTTON_HINT
816 if (fwin
->language_button
)
817 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
819 if (fwin
->right_button
)
820 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
823 XClearWindow(dpy
, fwin
->titlebar
->window
);
825 if (fwin
->left_button
) {
826 XClearWindow(dpy
, fwin
->left_button
->window
);
827 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
829 #ifdef XKB_BUTTON_HINT
830 if (fwin
->language_button
) {
831 XClearWindow(dpy
, fwin
->language_button
->window
);
832 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
835 if (fwin
->right_button
) {
836 XClearWindow(dpy
, fwin
->right_button
->window
);
837 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
842 static void remakeTexture(WFrameWindow
* fwin
, int state
)
844 Pixmap pmap
, lpmap
, rpmap
;
845 #ifdef XKB_BUTTON_HINT
849 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
850 FREE_PIXMAP(fwin
->title_back
[state
]);
851 if (wPreferences
.new_style
== TS_NEW
) {
852 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
853 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
854 #ifdef XKB_BUTTON_HINT
855 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
859 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
862 #ifdef XKB_BUTTON_HINT
866 /* eventually surrounded by if new_style */
867 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
868 #ifdef XKB_BUTTON_HINT
869 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
870 && !fwin
->flags
.languagebutton_dont_fit
;
872 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
873 && !fwin
->flags
.rbutton_dont_fit
;
875 width
= fwin
->core
->width
+ 1;
877 #ifdef XKB_BUTTON_HINT
878 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
879 width
, fwin
->titlebar
->height
,
880 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
881 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
883 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
884 width
, fwin
->titlebar
->height
,
885 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
886 left
, right
, &pmap
, &lpmap
, &rpmap
);
889 fwin
->title_back
[state
] = pmap
;
890 if (wPreferences
.new_style
== TS_NEW
) {
891 fwin
->lbutton_back
[state
] = lpmap
;
892 fwin
->rbutton_back
[state
] = rpmap
;
893 #ifdef XKB_BUTTON_HINT
894 fwin
->languagebutton_back
[state
] = tpmap
;
899 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
900 && fwin
->resizebar
&& state
== 0) {
902 FREE_PIXMAP(fwin
->resizebar_back
[0]);
904 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
906 renderResizebarTexture(fwin
->screen_ptr
,
907 fwin
->resizebar_texture
[0],
908 fwin
->resizebar
->width
,
909 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
911 fwin
->resizebar_back
[0] = pmap
;
914 /* this part should be in updateTexture() */
915 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
)
916 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
918 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
919 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
921 XClearWindow(dpy
, fwin
->resizebar
->window
);
925 void wFrameWindowPaint(WFrameWindow
* fwin
)
927 WScreen
*scr
= fwin
->screen_ptr
;
930 state
= fwin
->flags
.state
;
932 if (fwin
->flags
.is_client_window_frame
)
933 fwin
->flags
.justification
= wPreferences
.title_justification
;
935 if (fwin
->flags
.need_texture_remake
) {
938 fwin
->flags
.need_texture_remake
= 0;
939 fwin
->flags
.need_texture_change
= 0;
941 if (fwin
->flags
.single_texture
) {
942 remakeTexture(fwin
, 0);
945 /* first render the texture for the current state... */
946 remakeTexture(fwin
, state
);
947 /* ... and paint it */
950 for (i
= 0; i
< 3; i
++) {
952 remakeTexture(fwin
, i
);
957 if (fwin
->flags
.need_texture_change
) {
958 fwin
->flags
.need_texture_change
= 0;
963 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
964 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
965 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
966 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
969 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
970 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
975 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
977 w
= fwin
->resizebar
->width
;
978 h
= fwin
->resizebar
->height
;
979 cw
= fwin
->resizebar_corner_width
;
980 light_gc
= texture
->light_gc
;
981 dim_gc
= texture
->dim_gc
;
982 win
= fwin
->resizebar
->window
;
984 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
985 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
987 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
988 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
990 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
991 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
993 #ifdef SHADOW_RESIZEBAR
994 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
995 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
996 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
997 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
998 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
999 #endif /* SHADOW_RESIZEBAR */
1002 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
1004 int lofs
= 6, rofs
= 6;
1008 if (!wPreferences
.new_style
== TS_NEW
) {
1009 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1010 lofs
+= fwin
->left_button
->width
+ 3;
1014 #ifdef XKB_BUTTON_HINT
1015 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1016 && !fwin
->flags
.languagebutton_dont_fit
)
1017 lofs
+= fwin
->language_button
->width
;
1022 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1023 rofs
+= fwin
->right_button
->width
+ 3;
1027 #ifdef XKB_BUTTON_HINT
1028 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1035 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
1036 titlelen
= strlen(title
);
1037 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1039 switch (fwin
->flags
.justification
) {
1045 x
= fwin
->titlebar
->width
- w
- rofs
;
1050 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1052 x
= (fwin
->titlebar
->width
- w
) / 2;
1056 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1057 h
= WMFontHeight(*fwin
->font
);
1059 if (y
*2 + h
> *fwin
->title_max_height
)
1060 y
= (*fwin
->title_max_height
- h
) / 2;
1062 if (y
*2 + h
< *fwin
->title_min_height
)
1063 y
= (*fwin
->title_min_height
- h
) / 2;
1065 /* We use a w+2 buffer to have an extra pixel on the left and
1066 * another one on the right. This is because for some odd reason,
1067 * sometimes when using AA fonts (when libfreetype2 is compiled
1068 * with bytecode interpreter turned off), some fonts are drawn
1069 * starting from x = -1 not from 0 as requested. Observed with
1070 * capital A letter on the bold 'trebuchet ms' font. -Dan
1072 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1074 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1076 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1077 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1078 x
- 1, y
, w
+ 2, h
, 0, 0);
1080 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1081 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1084 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1085 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1086 *fwin
->font
, 1, 0, title
, titlelen
);
1088 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1090 XFreePixmap(dpy
, buf
);
1095 if (fwin
->left_button
)
1096 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1097 if (fwin
->right_button
)
1098 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1099 #ifdef XKB_BUTTON_HINT
1100 if (fwin
->language_button
)
1101 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1106 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1108 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1109 int resizedHorizontally
= 0;
1112 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1114 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1116 if (fwin
->core
->width
!= width
) {
1117 fwin
->flags
.need_texture_remake
= 1;
1118 resizedHorizontally
= 1;
1121 fwin
->core
->width
= width
;
1122 fwin
->core
->height
= height
;
1124 if (fwin
->titlebar
&& resizedHorizontally
) {
1125 /* Check if the titlebar is wide enough to hold the buttons.
1126 * Temporarily remove them if can't
1128 if (fwin
->left_button
) {
1129 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1130 if (!fwin
->flags
.hide_left_button
)
1131 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1133 fwin
->flags
.lbutton_dont_fit
= 1;
1134 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1135 if (!fwin
->flags
.hide_left_button
)
1136 XMapWindow(dpy
, fwin
->left_button
->window
);
1138 fwin
->flags
.lbutton_dont_fit
= 0;
1141 #ifdef XKB_BUTTON_HINT
1142 if (fwin
->language_button
) {
1143 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1144 if (!fwin
->flags
.hide_language_button
)
1145 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1147 fwin
->flags
.languagebutton_dont_fit
= 1;
1148 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1149 if (!fwin
->flags
.hide_language_button
)
1150 XMapWindow(dpy
, fwin
->language_button
->window
);
1152 fwin
->flags
.languagebutton_dont_fit
= 0;
1157 if (fwin
->right_button
) {
1158 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1159 if (!fwin
->flags
.hide_right_button
)
1160 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1162 fwin
->flags
.rbutton_dont_fit
= 1;
1163 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1164 if (!fwin
->flags
.hide_right_button
)
1165 XMapWindow(dpy
, fwin
->right_button
->window
);
1167 fwin
->flags
.rbutton_dont_fit
= 0;
1171 if (wPreferences
.new_style
== TS_NEW
) {
1172 if (fwin
->right_button
)
1173 XMoveWindow(dpy
, fwin
->right_button
->window
,
1174 width
- fwin
->right_button
->width
+ 1, 0);
1176 if (fwin
->right_button
)
1177 XMoveWindow(dpy
, fwin
->right_button
->window
,
1178 width
- fwin
->right_button
->width
- 3,
1179 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1181 updateTitlebar(fwin
);
1182 checkTitleSize(fwin
);
1185 if (fwin
->resizebar
) {
1186 wCoreConfigure(fwin
->resizebar
, 0,
1187 fwin
->core
->height
- fwin
->resizebar
->height
,
1188 fwin
->core
->width
, fwin
->resizebar
->height
);
1190 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1191 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
)
1192 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1196 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1198 reconfigure(fwin
, x
, y
, width
, height
, False
);
1201 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1203 reconfigure(fwin
, 0, 0, width
, height
, True
);
1206 int wFrameWindowChangeTitle(WFrameWindow
*fwin
, const char *new_title
)
1208 /* check if the title is the same as before */
1210 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0))
1220 fwin
->title
= wstrdup(new_title
);
1222 if (fwin
->titlebar
) {
1223 XClearWindow(dpy
, fwin
->titlebar
->window
);
1225 wFrameWindowPaint(fwin
);
1227 checkTitleSize(fwin
);
1232 #ifdef XKB_BUTTON_HINT
1233 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1235 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1236 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1238 #endif /* XKB_BUTTON_HINT */
1240 /*********************************************************************/
1242 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1244 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1246 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1247 fwin
->flags
.repaint_only_titlebar
= 1;
1248 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1249 fwin
->flags
.repaint_only_resizebar
= 1;
1250 wFrameWindowPaint(fwin
);
1251 fwin
->flags
.repaint_only_titlebar
= 0;
1252 fwin
->flags
.repaint_only_resizebar
= 0;
1255 static void checkTitleSize(WFrameWindow
* fwin
)
1260 fwin
->flags
.incomplete_title
= 0;
1264 if (!fwin
->titlebar
) {
1265 fwin
->flags
.incomplete_title
= 1;
1268 width
= fwin
->titlebar
->width
- 6 - 6;
1271 if (!wPreferences
.new_style
== TS_NEW
) {
1272 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1273 width
-= fwin
->left_button
->width
+ 3;
1275 #ifdef XKB_BUTTON_HINT
1276 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1277 && !fwin
->flags
.languagebutton_dont_fit
)
1278 width
-= fwin
->language_button
->width
+ 3;
1281 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1282 width
-= fwin
->right_button
->width
+ 3;
1285 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
)
1286 fwin
->flags
.incomplete_title
= 1;
1288 fwin
->flags
.incomplete_title
= 0;
1291 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1293 WScreen
*scr
= button
->screen_ptr
;
1294 GC copy_gc
= scr
->copy_gc
;
1295 int x
= 0, y
= 0, d
= 0;
1296 int left
= 0, width
= 0;
1298 /* setup stuff according to the state */
1301 if (image
->width
>= image
->height
* 2) {
1302 /* the image contains 2 pictures: the second is for the
1304 width
= image
->width
/ 2;
1305 left
= image
->width
/ 2;
1307 width
= image
->width
;
1310 XSetClipMask(dpy
, copy_gc
, None
);
1311 if (wPreferences
.new_style
== TS_NEXT
)
1312 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1314 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1317 if (wPreferences
.new_style
== TS_NEW
) {
1318 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1319 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1320 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1321 } else if (wPreferences
.new_style
== TS_OLD
) {
1322 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1323 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1324 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1326 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1327 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1328 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1331 XClearWindow(dpy
, button
->window
);
1334 if (image
->width
>= image
->height
* 2)
1335 width
= image
->width
/ 2;
1337 width
= image
->width
;
1341 if (wPreferences
.new_style
== TS_NEW
) {
1342 if (texture
->any
.type
== WTEX_SOLID
|| pushed
)
1343 wDrawBevel(button
->window
, button
->width
, button
->height
,
1344 (WTexSolid
*) texture
, WREL_RAISED
);
1346 wDrawBevel(button
->window
, button
->width
, button
->height
,
1347 scr
->widget_texture
, WREL_RAISED
);
1353 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1354 x
= (button
->width
- width
) / 2 + d
;
1355 y
= (button
->height
- image
->height
) / 2 + d
;
1356 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1357 if (!wPreferences
.new_style
== TS_NEW
) {
1358 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1360 if (image
->depth
== 1)
1361 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1362 left
, 0, width
, image
->height
, x
, y
, 1);
1364 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1365 left
, 0, width
, image
->height
, x
, y
);
1367 if (wPreferences
.new_style
== TS_OLD
) {
1368 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1369 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1370 button
->width
, button
->height
);
1372 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1373 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1374 left
, 0, width
, image
->height
, x
, y
);
1379 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1381 XSetForeground(dpy
, copy_gc
, color
);
1382 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1384 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1389 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1391 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1392 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1394 /* Parameter not used, but tell the compiler that it is ok */
1397 #ifdef XKB_BUTTON_HINT
1398 if (button
== fwin
->language_button
) {
1399 if (wPreferences
.modelock
)
1400 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1401 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1402 fwin
->languagebutton_image
, False
);
1405 if (button
== fwin
->left_button
)
1406 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1407 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1409 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1410 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1413 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1415 WFrameWindow
*fwin
= desc
->parent
;
1416 WCoreWindow
*titlebar
= desc
->self
;
1418 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1419 if (fwin
->on_dblclick_titlebar
)
1420 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1422 if (fwin
->on_mousedown_titlebar
)
1423 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1427 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1429 WFrameWindow
*fwin
= desc
->parent
;
1430 WCoreWindow
*resizebar
= desc
->self
;
1432 if (fwin
->on_mousedown_resizebar
)
1433 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1436 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1438 WFrameWindow
*fwin
= desc
->parent
;
1439 WCoreWindow
*button
= desc
->self
;
1442 int done
= 0, execute
= 1;
1444 unsigned long pixel
;
1445 int clickButton
= event
->xbutton
.button
;
1447 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1448 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
)
1449 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1454 if (button
== fwin
->left_button
)
1455 image
= fwin
->lbutton_image
;
1457 image
= fwin
->rbutton_image
;
1459 #ifdef XKB_BUTTON_HINT
1460 if (button
== fwin
->language_button
) {
1461 if (!wPreferences
.modelock
)
1463 image
= fwin
->languagebutton_image
;
1467 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1468 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1469 paintButton(button
, texture
, pixel
, image
, True
);
1472 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1473 | ButtonPressMask
| ExposureMask
, &ev
);
1477 paintButton(button
, texture
, pixel
, image
, False
);
1482 paintButton(button
, texture
, pixel
, image
, True
);
1489 if (ev
.xbutton
.button
== clickButton
)
1497 paintButton(button
, texture
, pixel
, image
, False
);
1500 if (button
== fwin
->left_button
) {
1501 if (fwin
->on_click_left
)
1502 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1503 } else if (button
== fwin
->right_button
) {
1504 if (fwin
->on_click_right
)
1505 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1507 #ifdef XKB_BUTTON_HINT
1508 else if (button
== fwin
->language_button
) {
1509 if (fwin
->on_click_language
)
1510 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);