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 WFrameWindow
*wFrameWindowCreate(WScreen
* scr
, int wlevel
, int x
, int y
,
62 int width
, int height
, int *clearance
, int flags
,
63 WTexture
** title_texture
, WTexture
** resize_texture
,
64 WMColor
** color
, WMFont
** font
)
68 fwin
= wmalloc(sizeof(WFrameWindow
));
69 memset(fwin
, 0, sizeof(WFrameWindow
));
71 fwin
->screen_ptr
= scr
;
73 fwin
->flags
.single_texture
= (flags
& WFF_SINGLE_STATE
) ? 1 : 0;
75 fwin
->title_texture
= title_texture
;
76 fwin
->resizebar_texture
= resize_texture
;
77 fwin
->title_color
= color
;
78 fwin
->title_clearance
= clearance
;
80 #ifdef KEEP_XKB_LOCK_STATUS
81 fwin
->languagemode
= XkbGroup1Index
;
82 fwin
->last_languagemode
= XkbGroup2Index
;
85 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
, (flags
& WFF_BORDER
)
86 ? FRAME_BORDER_WIDTH
: 0);
87 if (wPreferences
.use_saveunders
) {
89 XSetWindowAttributes attribs
;
92 attribs
.save_under
= True
;
93 XChangeWindowAttributes(dpy
, fwin
->core
->window
, vmask
, &attribs
);
96 /* setup stacking information */
97 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
98 fwin
->core
->stacking
->above
= NULL
;
99 fwin
->core
->stacking
->under
= NULL
;
100 fwin
->core
->stacking
->child_of
= NULL
;
101 fwin
->core
->stacking
->window_level
= wlevel
;
103 AddToStackList(fwin
->core
);
105 wFrameWindowUpdateBorders(fwin
, flags
);
110 void wFrameWindowUpdateBorders(WFrameWindow
* fwin
, int flags
)
116 WScreen
*scr
= fwin
->screen_ptr
;
118 width
= fwin
->core
->width
;
119 if (flags
& WFF_IS_SHADED
)
122 height
= fwin
->core
->height
- fwin
->top_width
- fwin
->bottom_width
;
124 if (flags
& WFF_TITLEBAR
)
125 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
129 if (wPreferences
.new_style
== TS_NEW
) {
131 } else if (wPreferences
.new_style
== TS_OLD
) {
137 if (fwin
->titlebar
) {
138 /* if we had a titlebar and is requesting for one,
139 * check if the size has changed and resize it */
140 if (flags
& WFF_TITLEBAR
) {
141 fwin
->top_width
= theight
;
143 fwin
->flags
.need_texture_remake
= 1;
145 if (wPreferences
.new_style
== TS_NEW
) {
146 if (fwin
->left_button
) {
147 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
149 #ifdef XKB_BUTTON_HINT
150 if (fwin
->language_button
) {
151 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
152 || fwin
->flags
.lbutton_dont_fit
) {
153 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
155 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
160 if (fwin
->right_button
) {
161 wCoreConfigure(fwin
->right_button
, width
- bsize
+ 1, 0, bsize
, bsize
);
163 } else { /* !new_style */
164 if (fwin
->left_button
) {
165 wCoreConfigure(fwin
->left_button
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
167 #ifdef XKB_BUTTON_HINT
168 if (fwin
->language_button
) {
169 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
- bsize
) / 2,
174 if (fwin
->right_button
) {
175 wCoreConfigure(fwin
->right_button
, width
- bsize
- 3,
176 (theight
- bsize
) / 2, bsize
, bsize
);
179 updateTitlebar(fwin
);
181 /* we had a titlebar, but now we don't need it anymore */
182 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
183 FREE_PIXMAP(fwin
->title_back
[i
]);
184 if (wPreferences
.new_style
== TS_NEW
) {
185 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
186 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
187 #ifdef XKB_BUTTON_HINT
188 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
192 if (fwin
->left_button
)
193 wCoreDestroy(fwin
->left_button
);
194 fwin
->left_button
= NULL
;
196 #ifdef XKB_BUTTON_HINT
197 if (fwin
->language_button
)
198 wCoreDestroy(fwin
->language_button
);
199 fwin
->language_button
= NULL
;
202 if (fwin
->right_button
)
203 wCoreDestroy(fwin
->right_button
);
204 fwin
->right_button
= NULL
;
206 wCoreDestroy(fwin
->titlebar
);
207 fwin
->titlebar
= NULL
;
212 /* if we didn't have a titlebar and are being requested for
214 if (flags
& WFF_TITLEBAR
) {
215 fwin
->top_width
= theight
;
217 fwin
->flags
.titlebar
= 1;
218 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+ 1, theight
);
220 if (flags
& WFF_LEFT_BUTTON
) {
221 fwin
->flags
.left_button
= 1;
222 if (wPreferences
.new_style
== TS_NEW
) {
223 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0, bsize
, bsize
);
224 if (width
< theight
* 4) {
225 fwin
->flags
.lbutton_dont_fit
= 1;
227 XMapRaised(dpy
, fwin
->left_button
->window
);
229 } else if (wPreferences
.new_style
== TS_OLD
) {
231 wCoreCreate(fwin
->titlebar
, 3, (theight
- bsize
) / 2, bsize
, bsize
);
233 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
234 scr
->widget_texture
->normal
.pixel
);
236 if (width
< theight
* 3) {
237 fwin
->flags
.lbutton_dont_fit
= 1;
239 XMapRaised(dpy
, fwin
->left_button
->window
);
243 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
246 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
247 scr
->widget_texture
->dark
.pixel
);
249 if (width
< theight
*3) {
250 fwin
->flags
.lbutton_dont_fit
= 1;
252 XMapRaised(dpy
, fwin
->left_button
->window
);
256 #ifdef XKB_BUTTON_HINT
257 if (flags
& WFF_LANGUAGE_BUTTON
) {
258 fwin
->flags
.language_button
= 1;
259 if (wPreferences
.new_style
== TS_NEW
) {
260 fwin
->language_button
= wCoreCreate(fwin
->core
, bsize
, 0, bsize
, bsize
);
262 if (width
< theight
* 4) {
263 fwin
->flags
.languagebutton_dont_fit
= 1;
265 XMapRaised(dpy
, fwin
->language_button
->window
);
268 fwin
->language_button
=
269 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
- bsize
) / 2,
272 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
273 scr
->widget_texture
->normal
.pixel
);
275 if (width
< theight
* 3) {
276 fwin
->flags
.languagebutton_dont_fit
= 1;
278 XMapRaised(dpy
, fwin
->language_button
->window
);
284 if (flags
& WFF_RIGHT_BUTTON
) {
285 fwin
->flags
.right_button
= 1;
286 if (wPreferences
.new_style
== TS_NEW
) {
288 wCoreCreate(fwin
->core
, width
- bsize
+ 1, 0, bsize
, bsize
);
289 } else if (wPreferences
.new_style
== TS_OLD
) {
291 wCoreCreate(fwin
->titlebar
, width
- bsize
- 3,
292 (theight
- bsize
) / 2, bsize
, bsize
);
293 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
294 scr
->widget_texture
->normal
.pixel
);
297 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
298 (theight
-bsize
)/2, bsize
, bsize
);
299 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
300 scr
->widget_texture
->dark
.pixel
);
303 if (width
< theight
* 2) {
304 fwin
->flags
.rbutton_dont_fit
= 1;
306 XMapRaised(dpy
, fwin
->right_button
->window
);
310 if (wPreferences
.new_style
== TS_NEW
)
311 updateTitlebar(fwin
);
313 XMapRaised(dpy
, fwin
->titlebar
->window
);
315 fwin
->flags
.need_texture_remake
= 1;
318 checkTitleSize(fwin
);
320 if (flags
& WFF_RESIZEBAR
) {
321 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
323 if (!fwin
->resizebar
) {
324 fwin
->flags
.resizebar
= 1;
325 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
326 height
+ fwin
->top_width
, width
, RESIZEBAR_HEIGHT
);
327 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
328 if (width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
329 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
) / 2;
330 if (fwin
->resizebar_corner_width
< 0)
331 fwin
->resizebar_corner_width
= 0;
334 XMapWindow(dpy
, fwin
->resizebar
->window
);
335 XLowerWindow(dpy
, fwin
->resizebar
->window
);
337 fwin
->flags
.need_texture_remake
= 1;
339 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
) {
340 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
341 width
, RESIZEBAR_HEIGHT
);
345 fwin
->bottom_width
= 0;
347 if (fwin
->resizebar
) {
348 fwin
->bottom_width
= 0;
349 wCoreDestroy(fwin
->resizebar
);
350 fwin
->resizebar
= NULL
;
354 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
&& !(flags
& WFF_IS_SHADED
)) {
355 wFrameWindowResize(fwin
, width
, height
+ fwin
->top_width
+ fwin
->bottom_width
);
358 if (flags
& WFF_BORDER
) {
359 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
361 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
364 /* setup object descriptors */
366 if (fwin
->titlebar
) {
367 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
368 fwin
->titlebar
->descriptor
.parent
= fwin
;
369 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
370 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
373 if (fwin
->resizebar
) {
374 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
375 fwin
->resizebar
->descriptor
.parent
= fwin
;
376 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
377 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
380 if (fwin
->left_button
) {
381 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
382 fwin
->left_button
->descriptor
.parent
= fwin
;
383 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
384 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
386 #ifdef XKB_BUTTON_HINT
387 if (fwin
->language_button
) {
388 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
389 fwin
->language_button
->descriptor
.parent
= fwin
;
390 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
391 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
395 if (fwin
->right_button
) {
396 fwin
->right_button
->descriptor
.parent
= fwin
;
397 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
398 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
399 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
402 checkTitleSize(fwin
);
405 void wFrameWindowDestroy(WFrameWindow
* fwin
)
409 if (fwin
->left_button
)
410 wCoreDestroy(fwin
->left_button
);
412 #ifdef XKB_BUTTON_HINT
413 if (fwin
->language_button
)
414 wCoreDestroy(fwin
->language_button
);
417 if (fwin
->right_button
)
418 wCoreDestroy(fwin
->right_button
);
421 wCoreDestroy(fwin
->resizebar
);
424 wCoreDestroy(fwin
->titlebar
);
426 RemoveFromStackList(fwin
->core
);
428 wCoreDestroy(fwin
->core
);
433 for (i
= 0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
434 FREE_PIXMAP(fwin
->title_back
[i
]);
435 if (wPreferences
.new_style
== TS_NEW
) {
436 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
437 #ifdef XKB_BUTTON_HINT
438 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
440 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
447 void wFrameWindowChangeState(WFrameWindow
* fwin
, int state
)
449 if (fwin
->flags
.state
== state
)
452 fwin
->flags
.state
= state
;
453 fwin
->flags
.need_texture_change
= 1;
455 wFrameWindowPaint(fwin
);
458 static void updateTitlebar(WFrameWindow
* fwin
)
463 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
466 w
= fwin
->core
->width
+ 1;
468 if (wPreferences
.new_style
== TS_NEW
) {
469 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
471 #ifdef XKB_BUTTON_HINT
472 if (fwin
->language_button
)
473 wCoreConfigure(fwin
->language_button
, 0, 0,
474 fwin
->language_button
->width
, fwin
->language_button
->width
);
477 #ifdef XKB_BUTTON_HINT
478 if (fwin
->language_button
)
479 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
480 fwin
->language_button
->width
, fwin
->language_button
->width
);
482 x
= fwin
->left_button
->width
;
483 w
-= fwin
->left_button
->width
;
485 #ifdef XKB_BUTTON_HINT
486 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
487 || fwin
->flags
.languagebutton_dont_fit
) {
489 x
+= fwin
->language_button
->width
;
490 w
-= fwin
->language_button
->width
;
494 #ifdef XKB_BUTTON_HINT
496 int bsize
= theight
- 7;
497 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
|| fwin
->flags
.lbutton_dont_fit
) {
498 if (fwin
->language_button
)
499 wCoreConfigure(fwin
->language_button
, 3, (theight
- bsize
) / 2,
500 fwin
->language_button
->width
, fwin
->language_button
->width
);
502 if (fwin
->language_button
)
503 wCoreConfigure(fwin
->language_button
,
504 6 + fwin
->left_button
->width
, (theight
- bsize
) / 2,
505 fwin
->language_button
->width
, fwin
->language_button
->width
);
510 if (wPreferences
.new_style
== TS_NEW
) {
511 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
&& !fwin
->flags
.rbutton_dont_fit
) {
512 w
-= fwin
->right_button
->width
;
516 if (wPreferences
.new_style
== TS_NEW
|| fwin
->titlebar
->width
!= w
)
517 fwin
->flags
.need_texture_remake
= 1;
519 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
522 void wFrameWindowHideButton(WFrameWindow
* fwin
, int flags
)
524 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
525 XUnmapWindow(dpy
, fwin
->right_button
->window
);
526 fwin
->flags
.hide_right_button
= 1;
529 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
530 XUnmapWindow(dpy
, fwin
->left_button
->window
);
531 fwin
->flags
.hide_left_button
= 1;
533 #ifdef XKB_BUTTON_HINT
534 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
535 XUnmapWindow(dpy
, fwin
->language_button
->window
);
536 fwin
->flags
.hide_language_button
= 1;
540 if (fwin
->titlebar
) {
541 if (wPreferences
.new_style
== TS_NEW
) {
542 updateTitlebar(fwin
);
544 #ifdef XKB_BUTTON_HINT
545 updateTitlebar(fwin
);
547 XClearWindow(dpy
, fwin
->titlebar
->window
);
548 wFrameWindowPaint(fwin
);
551 checkTitleSize(fwin
);
555 void wFrameWindowShowButton(WFrameWindow
* fwin
, int flags
)
557 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
&& fwin
->flags
.hide_right_button
) {
559 if (!fwin
->flags
.rbutton_dont_fit
)
560 XMapWindow(dpy
, fwin
->right_button
->window
);
562 fwin
->flags
.hide_right_button
= 0;
564 #ifdef XKB_BUTTON_HINT
565 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
&& fwin
->flags
.hide_language_button
) {
567 if (!fwin
->flags
.languagebutton_dont_fit
)
568 XMapWindow(dpy
, fwin
->language_button
->window
);
570 fwin
->flags
.hide_language_button
= 0;
574 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
&& fwin
->flags
.hide_left_button
) {
576 if (!fwin
->flags
.lbutton_dont_fit
)
577 XMapWindow(dpy
, fwin
->left_button
->window
);
579 fwin
->flags
.hide_left_button
= 0;
582 if (fwin
->titlebar
) {
583 if (wPreferences
.new_style
== TS_NEW
) {
584 updateTitlebar(fwin
);
586 XClearWindow(dpy
, fwin
->titlebar
->window
);
587 wFrameWindowPaint(fwin
);
589 checkTitleSize(fwin
);
594 #ifdef XKB_BUTTON_HINT
595 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
596 int bwidth
, int bheight
, int left
, int language
, int right
,
597 Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* languagebutton
, Pixmap
* rbutton
)
599 renderTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
,
600 int bwidth
, int bheight
, int left
, int right
, Pixmap
* title
, Pixmap
* lbutton
, Pixmap
* rbutton
)
604 RImage
*limg
, *rimg
, *mimg
;
605 #ifdef XKB_BUTTON_HINT
613 #ifdef XKB_BUTTON_HINT
614 *languagebutton
= None
;
617 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
619 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
623 if (wPreferences
.new_style
== TS_NEW
) {
625 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
632 #ifdef XKB_BUTTON_HINT
634 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
640 RBevelImage(limg
, RBEV_RAISED2
);
641 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
)) {
642 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
648 #ifdef XKB_BUTTON_HINT
650 RBevelImage(timg
, RBEV_RAISED2
);
651 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
)) {
652 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
661 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
666 RBevelImage(rimg
, RBEV_RAISED2
);
667 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
)) {
668 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
675 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
676 RBevelImage(mimg
, RBEV_RAISED2
);
678 if (!RConvertImage(scr
->rcontext
, mimg
, title
)) {
679 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
683 RBevelImage(img
, RBEV_RAISED2
);
685 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
686 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
690 RBevelImage(img
, RBEV_RAISED2
);
692 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
693 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
701 renderResizebarTexture(WScreen
* scr
, WTexture
* texture
, int width
, int height
, int cwidth
, Pixmap
* pmap
)
709 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
711 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
716 light
.red
= light
.green
= light
.blue
= 80;
719 dark
.red
= dark
.green
= dark
.blue
= 40;
721 ROperateLine(img
, RSubtractOperation
, 0, 0, width
- 1, 0, &dark
);
722 ROperateLine(img
, RAddOperation
, 0, 1, width
- 1, 1, &light
);
724 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
- 1, &dark
);
725 ROperateLine(img
, RAddOperation
, cwidth
+ 1, 2, cwidth
+ 1, height
- 1, &light
);
728 ROperateLine(img
, RSubtractOperation
, width
- cwidth
- 2, 2,
729 width
- cwidth
- 2, height
- 1, &dark
);
730 ROperateLine(img
, RAddOperation
, width
- cwidth
- 1, 2, width
- cwidth
- 1, height
- 1, &light
);
732 #ifdef SHADOW_RESIZEBAR
733 ROperateLine(img
, RAddOperation
, 0, 1, 0, height
- 1, &light
);
734 ROperateLine(img
, RSubtractOperation
, width
- 1, 1, width
- 1, height
- 1, &dark
);
735 ROperateLine(img
, RSubtractOperation
, 0, height
- 1, width
- 1, height
- 1, &dark
);
736 #endif /* SHADOW_RESIZEBAR */
738 if (!RConvertImage(scr
->rcontext
, img
, pmap
)) {
739 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
745 static void updateTexture(WFrameWindow
* fwin
)
750 i
= fwin
->flags
.state
;
751 if (fwin
->titlebar
) {
752 if (fwin
->title_texture
[i
]->any
.type
!= WTEX_SOLID
) {
753 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
, fwin
->title_back
[i
]);
754 if (wPreferences
.new_style
== TS_NEW
) {
755 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
756 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
757 fwin
->lbutton_back
[i
]);
759 #ifdef XKB_BUTTON_HINT
760 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
]) {
761 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
762 fwin
->languagebutton_back
[i
]);
766 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
767 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
768 fwin
->rbutton_back
[i
]);
771 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
772 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
773 if (wPreferences
.new_style
== TS_NEW
) {
774 if (fwin
->left_button
)
775 XSetWindowBackground(dpy
, fwin
->left_button
->window
, pixel
);
776 #ifdef XKB_BUTTON_HINT
777 if (fwin
->language_button
)
778 XSetWindowBackground(dpy
, fwin
->language_button
->window
, pixel
);
780 if (fwin
->right_button
)
781 XSetWindowBackground(dpy
, fwin
->right_button
->window
, pixel
);
784 XClearWindow(dpy
, fwin
->titlebar
->window
);
786 if (fwin
->left_button
) {
787 XClearWindow(dpy
, fwin
->left_button
->window
);
788 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
790 #ifdef XKB_BUTTON_HINT
791 if (fwin
->language_button
) {
792 XClearWindow(dpy
, fwin
->language_button
->window
);
793 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
796 if (fwin
->right_button
) {
797 XClearWindow(dpy
, fwin
->right_button
->window
);
798 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
803 static void remakeTexture(WFrameWindow
* fwin
, int state
)
805 Pixmap pmap
, lpmap
, rpmap
;
806 #ifdef XKB_BUTTON_HINT
810 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
811 FREE_PIXMAP(fwin
->title_back
[state
]);
812 if (wPreferences
.new_style
== TS_NEW
) {
813 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
814 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
815 #ifdef XKB_BUTTON_HINT
816 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
820 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
823 #ifdef XKB_BUTTON_HINT
827 /* eventually surrounded by if new_style */
828 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
;
829 #ifdef XKB_BUTTON_HINT
830 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
831 && !fwin
->flags
.languagebutton_dont_fit
;
833 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
834 && !fwin
->flags
.rbutton_dont_fit
;
836 width
= fwin
->core
->width
+ 1;
838 #ifdef XKB_BUTTON_HINT
839 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
840 width
, fwin
->titlebar
->height
,
841 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
842 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
844 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
845 width
, fwin
->titlebar
->height
,
846 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
847 left
, right
, &pmap
, &lpmap
, &rpmap
);
850 fwin
->title_back
[state
] = pmap
;
851 if (wPreferences
.new_style
== TS_NEW
) {
852 fwin
->lbutton_back
[state
] = lpmap
;
853 fwin
->rbutton_back
[state
] = rpmap
;
854 #ifdef XKB_BUTTON_HINT
855 fwin
->languagebutton_back
[state
] = tpmap
;
860 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
861 && fwin
->resizebar
&& state
== 0) {
863 FREE_PIXMAP(fwin
->resizebar_back
[0]);
865 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
867 renderResizebarTexture(fwin
->screen_ptr
,
868 fwin
->resizebar_texture
[0],
869 fwin
->resizebar
->width
,
870 fwin
->resizebar
->height
, fwin
->resizebar_corner_width
, &pmap
);
872 fwin
->resizebar_back
[0] = pmap
;
875 /* this part should be in updateTexture() */
876 if (fwin
->resizebar_texture
[0]->any
.type
!= WTEX_SOLID
) {
877 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
, fwin
->resizebar_back
[0]);
879 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
880 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
882 XClearWindow(dpy
, fwin
->resizebar
->window
);
886 void wFrameWindowPaint(WFrameWindow
* fwin
)
888 WScreen
*scr
= fwin
->screen_ptr
;
891 state
= fwin
->flags
.state
;
893 if (fwin
->flags
.is_client_window_frame
)
894 fwin
->flags
.justification
= wPreferences
.title_justification
;
896 if (fwin
->flags
.need_texture_remake
) {
899 fwin
->flags
.need_texture_remake
= 0;
900 fwin
->flags
.need_texture_change
= 0;
902 if (fwin
->flags
.single_texture
) {
903 remakeTexture(fwin
, 0);
906 /* first render the texture for the current state... */
907 remakeTexture(fwin
, state
);
908 /* ... and paint it */
911 for (i
= 0; i
< 3; i
++) {
913 remakeTexture(fwin
, i
);
919 if (fwin
->flags
.need_texture_change
) {
920 fwin
->flags
.need_texture_change
= 0;
925 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
926 && fwin
->title_texture
[state
]->any
.type
== WTEX_SOLID
) {
927 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
928 fwin
->titlebar
->height
, (WTexSolid
*) fwin
->title_texture
[state
], WREL_RAISED
);
931 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
932 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
937 WTexSolid
*texture
= (WTexSolid
*) fwin
->resizebar_texture
[0];
939 w
= fwin
->resizebar
->width
;
940 h
= fwin
->resizebar
->height
;
941 cw
= fwin
->resizebar_corner_width
;
942 light_gc
= texture
->light_gc
;
943 dim_gc
= texture
->dim_gc
;
944 win
= fwin
->resizebar
->window
;
946 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
947 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
949 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
950 XDrawLine(dpy
, win
, light_gc
, cw
+ 1, 2, cw
+ 1, h
);
952 XDrawLine(dpy
, win
, dim_gc
, w
- cw
- 2, 2, w
- cw
- 2, h
);
953 XDrawLine(dpy
, win
, light_gc
, w
- cw
- 1, 2, w
- cw
- 1, h
);
955 #ifdef SHADOW_RESIZEBAR
956 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
- 1);
957 XDrawLine(dpy
, win
, dim_gc
, w
- 1, 2, w
- 1, h
- 1);
958 XDrawLine(dpy
, win
, dim_gc
, 1, h
- 1, cw
, h
- 1);
959 XDrawLine(dpy
, win
, dim_gc
, cw
+ 2, h
- 1, w
- cw
- 2, h
- 1);
960 XDrawLine(dpy
, win
, dim_gc
, w
- cw
, h
- 1, w
- 1, h
- 1);
961 #endif /* SHADOW_RESIZEBAR */
964 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
966 int lofs
= 6, rofs
= 6;
970 if (!wPreferences
.new_style
== TS_NEW
) {
971 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
972 lofs
+= fwin
->left_button
->width
+ 3;
976 #ifdef XKB_BUTTON_HINT
977 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
978 && !fwin
->flags
.languagebutton_dont_fit
)
979 lofs
+= fwin
->language_button
->width
;
984 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
985 rofs
+= fwin
->right_button
->width
+ 3;
989 #ifdef XKB_BUTTON_HINT
990 fwin
->languagebutton_image
= scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
997 title
= ShrinkString(*fwin
->font
, fwin
->title
, fwin
->titlebar
->width
- lofs
- rofs
);
998 titlelen
= strlen(title
);
999 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1001 switch (fwin
->flags
.justification
) {
1007 x
= fwin
->titlebar
->width
- w
- rofs
;
1012 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1014 x
= (fwin
->titlebar
->width
- w
) / 2;
1018 y
= *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
;
1019 h
= WMFontHeight(*fwin
->font
);
1021 /* We use a w+2 buffer to have an extra pixel on the left and
1022 * another one on the right. This is because for some odd reason,
1023 * sometimes when using AA fonts (when libfreetype2 is compiled
1024 * with bytecode interpreter turned off), some fonts are drawn
1025 * starting from x = -1 not from 0 as requested. Observed with
1026 * capital A letter on the bold 'trebuchet ms' font. -Dan
1028 buf
= XCreatePixmap(dpy
, fwin
->titlebar
->window
, w
+ 2, h
, scr
->w_depth
);
1030 XSetClipMask(dpy
, scr
->copy_gc
, None
);
1032 if (fwin
->title_texture
[state
]->any
.type
!= WTEX_SOLID
) {
1033 XCopyArea(dpy
, fwin
->title_back
[state
], buf
, scr
->copy_gc
,
1034 x
- 1, y
, w
+ 2, h
, 0, 0);
1036 XSetForeground(dpy
, scr
->copy_gc
, fwin
->title_texture
[state
]->solid
.normal
.pixel
);
1037 XFillRectangle(dpy
, buf
, scr
->copy_gc
, 0, 0, w
+ 2, h
);
1040 /*XDrawRectangle(dpy, buf, WMColorGC(scr->white),1,0,w,h-1); */
1041 WMDrawString(scr
->wmscreen
, buf
, fwin
->title_color
[state
],
1042 *fwin
->font
, 1, 0, title
, titlelen
);
1044 XCopyArea(dpy
, buf
, fwin
->titlebar
->window
, scr
->copy_gc
, 0, 0, w
+ 2, h
, x
- 1, y
);
1046 XFreePixmap(dpy
, buf
);
1051 if (fwin
->left_button
)
1052 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1053 if (fwin
->right_button
)
1054 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1055 #ifdef XKB_BUTTON_HINT
1056 if (fwin
->language_button
)
1057 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1062 static void reconfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
, Bool dontMove
)
1064 int k
= (wPreferences
.new_style
== TS_NEW
? 4 : 3);
1065 int resizedHorizontally
= 0;
1068 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1070 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1073 if (fwin->core->height != height && fwin->resizebar)
1074 XMoveWindow(dpy, fwin->resizebar->window, 0,
1075 height - fwin->resizebar->height);
1077 if (fwin
->core
->width
!= width
) {
1078 fwin
->flags
.need_texture_remake
= 1;
1079 resizedHorizontally
= 1;
1082 fwin
->core
->width
= width
;
1083 fwin
->core
->height
= height
;
1085 if (fwin
->titlebar
&& resizedHorizontally
) {
1086 /* Check if the titlebar is wide enough to hold the buttons.
1087 * Temporarily remove them if can't
1089 if (fwin
->left_button
) {
1090 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.lbutton_dont_fit
) {
1092 if (!fwin
->flags
.hide_left_button
) {
1093 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1095 fwin
->flags
.lbutton_dont_fit
= 1;
1096 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.lbutton_dont_fit
) {
1098 if (!fwin
->flags
.hide_left_button
) {
1099 XMapWindow(dpy
, fwin
->left_button
->window
);
1101 fwin
->flags
.lbutton_dont_fit
= 0;
1104 #ifdef XKB_BUTTON_HINT
1105 if (fwin
->language_button
) {
1106 if (width
< fwin
->top_width
* k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1108 if (!fwin
->flags
.hide_language_button
) {
1109 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1111 fwin
->flags
.languagebutton_dont_fit
= 1;
1112 } else if (width
>= fwin
->top_width
* k
&& fwin
->flags
.languagebutton_dont_fit
) {
1114 if (!fwin
->flags
.hide_language_button
) {
1115 XMapWindow(dpy
, fwin
->language_button
->window
);
1117 fwin
->flags
.languagebutton_dont_fit
= 0;
1122 if (fwin
->right_button
) {
1123 if (width
< fwin
->top_width
* 2 && !fwin
->flags
.rbutton_dont_fit
) {
1125 if (!fwin
->flags
.hide_right_button
) {
1126 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1128 fwin
->flags
.rbutton_dont_fit
= 1;
1129 } else if (width
>= fwin
->top_width
* 2 && fwin
->flags
.rbutton_dont_fit
) {
1131 if (!fwin
->flags
.hide_right_button
) {
1132 XMapWindow(dpy
, fwin
->right_button
->window
);
1134 fwin
->flags
.rbutton_dont_fit
= 0;
1138 if (wPreferences
.new_style
== TS_NEW
) {
1139 if (fwin
->right_button
)
1140 XMoveWindow(dpy
, fwin
->right_button
->window
,
1141 width
- fwin
->right_button
->width
+ 1, 0);
1143 if (fwin
->right_button
)
1144 XMoveWindow(dpy
, fwin
->right_button
->window
,
1145 width
- fwin
->right_button
->width
- 3,
1146 (fwin
->titlebar
->height
- fwin
->right_button
->height
) / 2);
1148 updateTitlebar(fwin
);
1149 checkTitleSize(fwin
);
1152 if (fwin
->resizebar
) {
1153 wCoreConfigure(fwin
->resizebar
, 0,
1154 fwin
->core
->height
- fwin
->resizebar
->height
,
1155 fwin
->core
->width
, fwin
->resizebar
->height
);
1157 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1158 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
* 2 + RESIZEBAR_MIN_WIDTH
) {
1159 fwin
->resizebar_corner_width
= fwin
->core
->width
/ 2;
1164 void wFrameWindowConfigure(WFrameWindow
* fwin
, int x
, int y
, int width
, int height
)
1166 reconfigure(fwin
, x
, y
, width
, height
, False
);
1169 void wFrameWindowResize(WFrameWindow
* fwin
, int width
, int height
)
1171 reconfigure(fwin
, 0, 0, width
, height
, True
);
1174 int wFrameWindowChangeTitle(WFrameWindow
* fwin
, char *new_title
)
1176 /* check if the title is the same as before */
1178 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0)) {
1189 fwin
->title
= wstrdup(new_title
);
1191 if (fwin
->titlebar
) {
1192 XClearWindow(dpy
, fwin
->titlebar
->window
);
1194 wFrameWindowPaint(fwin
);
1196 checkTitleSize(fwin
);
1201 #ifdef XKB_BUTTON_HINT
1202 void wFrameWindowUpdateLanguageButton(WFrameWindow
* fwin
)
1204 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1205 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->languagebutton_image
, True
);
1207 #endif /* XKB_BUTTON_HINT */
1209 /*********************************************************************/
1211 static void handleExpose(WObjDescriptor
* desc
, XEvent
* event
)
1213 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1215 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1216 fwin
->flags
.repaint_only_titlebar
= 1;
1217 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1218 fwin
->flags
.repaint_only_resizebar
= 1;
1219 wFrameWindowPaint(fwin
);
1220 fwin
->flags
.repaint_only_titlebar
= 0;
1221 fwin
->flags
.repaint_only_resizebar
= 0;
1224 static void checkTitleSize(WFrameWindow
* fwin
)
1229 fwin
->flags
.incomplete_title
= 0;
1233 if (!fwin
->titlebar
) {
1234 fwin
->flags
.incomplete_title
= 1;
1237 width
= fwin
->titlebar
->width
- 6 - 6;
1240 if (!wPreferences
.new_style
== TS_NEW
) {
1241 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
&& !fwin
->flags
.lbutton_dont_fit
)
1242 width
-= fwin
->left_button
->width
+ 3;
1244 #ifdef XKB_BUTTON_HINT
1245 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1246 && !fwin
->flags
.languagebutton_dont_fit
)
1247 width
-= fwin
->language_button
->width
+ 3;
1250 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
&& !fwin
->flags
.rbutton_dont_fit
)
1251 width
-= fwin
->right_button
->width
+ 3;
1253 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
) {
1254 fwin
->flags
.incomplete_title
= 1;
1256 fwin
->flags
.incomplete_title
= 0;
1260 static void paintButton(WCoreWindow
* button
, WTexture
* texture
, unsigned long color
, WPixmap
* image
, int pushed
)
1262 WScreen
*scr
= button
->screen_ptr
;
1263 GC copy_gc
= scr
->copy_gc
;
1264 int x
= 0, y
= 0, d
= 0;
1265 int left
= 0, width
= 0;
1267 /* setup stuff according to the state */
1270 if (image
->width
>= image
->height
* 2) {
1271 /* the image contains 2 pictures: the second is for the
1273 width
= image
->width
/ 2;
1274 left
= image
->width
/ 2;
1276 width
= image
->width
;
1279 XSetClipMask(dpy
, copy_gc
, None
);
1280 if (wPreferences
.new_style
== TS_NEXT
) {
1281 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1283 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1286 if (wPreferences
.new_style
== TS_NEW
) {
1287 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1288 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1289 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
- 1, button
->height
- 1);
1290 } else if (wPreferences
.new_style
== TS_OLD
) {
1291 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1292 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1293 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1295 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1296 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1297 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
-3, button
->height
-3);
1300 XClearWindow(dpy
, button
->window
);
1303 if (image
->width
>= image
->height
* 2)
1304 width
= image
->width
/ 2;
1306 width
= image
->width
;
1310 if (wPreferences
.new_style
== TS_NEW
) {
1311 if (texture
->any
.type
== WTEX_SOLID
|| pushed
) {
1312 wDrawBevel(button
->window
, button
->width
, button
->height
,
1313 (WTexSolid
*) texture
, WREL_RAISED
);
1316 wDrawBevel(button
->window
, button
->width
, button
->height
,
1317 scr
->widget_texture
, WREL_RAISED
);
1323 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1324 x
= (button
->width
- width
) / 2 + d
;
1325 y
= (button
->height
- image
->height
) / 2 + d
;
1326 XSetClipOrigin(dpy
, copy_gc
, x
- left
, y
);
1327 if (!wPreferences
.new_style
== TS_NEW
) {
1328 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1330 if (image
->depth
== 1)
1331 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1332 left
, 0, width
, image
->height
, x
, y
, 1);
1334 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1335 left
, 0, width
, image
->height
, x
, y
);
1337 if (wPreferences
.new_style
== TS_OLD
) {
1338 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1339 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1340 button
->width
, button
->height
);
1342 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1343 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1344 left
, 0, width
, image
->height
, x
, y
);
1349 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1351 XSetForeground(dpy
, copy_gc
, color
);
1352 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1354 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0, button
->width
, button
->height
);
1359 static void handleButtonExpose(WObjDescriptor
* desc
, XEvent
* event
)
1361 WFrameWindow
*fwin
= (WFrameWindow
*) desc
->parent
;
1362 WCoreWindow
*button
= (WCoreWindow
*) desc
->self
;
1364 #ifdef XKB_BUTTON_HINT
1365 if (button
== fwin
->language_button
) {
1366 if (wPreferences
.modelock
) {
1367 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1368 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]),
1369 fwin
->languagebutton_image
, False
);
1373 if (button
== fwin
->left_button
) {
1374 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1375 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->lbutton_image
, False
);
1377 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1378 WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]), fwin
->rbutton_image
, False
);
1382 static void titlebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1384 WFrameWindow
*fwin
= desc
->parent
;
1385 WCoreWindow
*titlebar
= desc
->self
;
1387 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1388 if (fwin
->on_dblclick_titlebar
) {
1389 (*fwin
->on_dblclick_titlebar
) (titlebar
, fwin
->child
, event
);
1392 if (fwin
->on_mousedown_titlebar
) {
1393 (*fwin
->on_mousedown_titlebar
) (titlebar
, fwin
->child
, event
);
1398 static void resizebarMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1400 WFrameWindow
*fwin
= desc
->parent
;
1401 WCoreWindow
*resizebar
= desc
->self
;
1403 if (fwin
->on_mousedown_resizebar
)
1404 (*fwin
->on_mousedown_resizebar
) (resizebar
, fwin
->child
, event
);
1407 static void buttonMouseDown(WObjDescriptor
* desc
, XEvent
* event
)
1409 WFrameWindow
*fwin
= desc
->parent
;
1410 WCoreWindow
*button
= desc
->self
;
1413 int done
= 0, execute
= 1;
1415 unsigned long pixel
;
1416 int clickButton
= event
->xbutton
.button
;
1418 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1419 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
) {
1420 (*fwin
->on_dblclick_right
) (button
, fwin
->child
, event
);
1425 if (button
== fwin
->left_button
) {
1426 image
= fwin
->lbutton_image
;
1428 image
= fwin
->rbutton_image
;
1430 #ifdef XKB_BUTTON_HINT
1431 if (button
== fwin
->language_button
) {
1432 if (!wPreferences
.modelock
)
1434 image
= fwin
->languagebutton_image
;
1438 pixel
= WMColorPixel(fwin
->title_color
[fwin
->flags
.state
]);
1439 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1440 paintButton(button
, texture
, pixel
, image
, True
);
1443 WMMaskEvent(dpy
, LeaveWindowMask
| EnterWindowMask
| ButtonReleaseMask
1444 | ButtonPressMask
| ExposureMask
, &ev
);
1448 paintButton(button
, texture
, pixel
, image
, False
);
1453 paintButton(button
, texture
, pixel
, image
, True
);
1460 if (ev
.xbutton
.button
== clickButton
)
1468 paintButton(button
, texture
, pixel
, image
, False
);
1471 if (button
== fwin
->left_button
) {
1472 if (fwin
->on_click_left
)
1473 (*fwin
->on_click_left
) (button
, fwin
->child
, &ev
);
1474 } else if (button
== fwin
->right_button
) {
1475 if (fwin
->on_click_right
)
1476 (*fwin
->on_click_right
) (button
, fwin
->child
, &ev
);
1478 #ifdef XKB_BUTTON_HINT
1479 else if (button
== fwin
->language_button
) {
1480 if (fwin
->on_click_language
)
1481 (*fwin
->on_click_language
) (button
, fwin
->child
, &ev
);