2 * Window Maker window manager
4 * Copyright (c) 1997, 1998 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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 #include <X11/Xutil.h>
26 #ifdef KEEP_XKB_LOCK_STATUS
27 #include <X11/XKBlib.h>
28 #endif /* KEEP_XKB_LOCK_STATUS */
35 #include "WindowMaker.h"
44 #define DBLCLICK_TIME wPreferences.dblclick_time
46 extern WPreferences wPreferences
;
48 static void handleExpose(WObjDescriptor
*desc
, XEvent
*event
);
49 static void handleButtonExpose(WObjDescriptor
*desc
, XEvent
*event
);
51 static void buttonMouseDown(WObjDescriptor
*desc
, XEvent
*event
);
52 static void titlebarMouseDown(WObjDescriptor
*desc
, XEvent
*event
);
53 static void resizebarMouseDown(WObjDescriptor
*desc
, XEvent
*event
);
55 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
);
65 wFrameWindowCreate(WScreen
*scr
, int wlevel
, int x
, int y
,
66 int width
, int height
, int *clearance
, int flags
,
67 WTexture
**title_texture
, WTexture
**resize_texture
,
69 #ifdef DRAWSTRING_PLUGIN
72 GC
*gc
, WMFont
**font
)
76 fwin
= wmalloc(sizeof(WFrameWindow
));
77 memset(fwin
, 0, sizeof(WFrameWindow
));
79 fwin
->screen_ptr
= scr
;
81 fwin
->flags
.single_texture
= (flags
& WFF_SINGLE_STATE
) ? 1 : 0;
83 fwin
->title_texture
= title_texture
;
84 fwin
->resizebar_texture
= resize_texture
;
85 fwin
->title_pixel
= color
;
86 fwin
->title_clearance
= clearance
;
87 #ifdef DRAWSTRING_PLUGIN
88 fwin
->drawstring_proc_offset
= function_offset
;
92 #ifdef KEEP_XKB_LOCK_STATUS
93 fwin
->languagemode
= XkbGroup1Index
;
94 fwin
->last_languagemode
= XkbGroup2Index
;
97 fwin
->core
= wCoreCreateTopLevel(scr
, x
, y
, width
, height
,
99 ? FRAME_BORDER_WIDTH
: 0);
100 if (wPreferences
.use_saveunders
) {
102 XSetWindowAttributes attribs
;
105 attribs
.save_under
= True
;
106 XChangeWindowAttributes(dpy
, fwin
->core
->window
, vmask
, &attribs
);
109 /* setup stacking information */
110 fwin
->core
->stacking
= wmalloc(sizeof(WStacking
));
111 fwin
->core
->stacking
->above
= NULL
;
112 fwin
->core
->stacking
->under
= NULL
;
113 fwin
->core
->stacking
->child_of
= NULL
;
114 fwin
->core
->stacking
->window_level
= wlevel
;
116 AddToStackList(fwin
->core
);
118 wFrameWindowUpdateBorders(fwin
, flags
);
126 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;
145 if (wPreferences
.new_style
) {
151 if (fwin
->titlebar
) {
152 /* if we had a titlebar and is requesting for one,
153 * check if the size has changed and resize it */
154 if (flags
& WFF_TITLEBAR
) {
155 fwin
->top_width
= theight
;
157 fwin
->flags
.need_texture_remake
= 1;
159 if (wPreferences
.new_style
) {
160 if (fwin
->left_button
) {
161 wCoreConfigure(fwin
->left_button
, 0, 0, bsize
, bsize
);
163 #ifdef XKB_BUTTON_HINT
164 if (fwin
->language_button
)
165 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
166 || fwin
->flags
.lbutton_dont_fit
) {
167 wCoreConfigure(fwin
->language_button
, 0, 0, bsize
, bsize
);
169 wCoreConfigure(fwin
->language_button
, bsize
, 0, bsize
, bsize
);
174 if (fwin
->right_button
) {
175 wCoreConfigure(fwin
->right_button
, width
-bsize
+1,
178 } else { /* !new_style */
179 if (fwin
->left_button
) {
180 wCoreConfigure(fwin
->left_button
, 3, (theight
-bsize
)/2,
184 #ifdef XKB_BUTTON_HINT
185 if (fwin
->language_button
) {
186 wCoreConfigure(fwin
->language_button
, 6 + bsize
, (theight
-bsize
)/2,
191 if (fwin
->right_button
) {
192 wCoreConfigure(fwin
->right_button
, width
-bsize
-3,
193 (theight
-bsize
)/2, bsize
, bsize
);
196 updateTitlebar(fwin
);
198 /* we had a titlebar, but now we don't need it anymore */
199 for (i
=0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
200 FREE_PIXMAP(fwin
->title_back
[i
]);
201 if (wPreferences
.new_style
) {
202 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
203 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
204 #ifdef XKB_BUTTON_HINT
205 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
209 if (fwin
->left_button
)
210 wCoreDestroy(fwin
->left_button
);
211 fwin
->left_button
= NULL
;
213 #ifdef XKB_BUTTON_HINT
214 if (fwin
->language_button
)
215 wCoreDestroy(fwin
->language_button
);
216 fwin
->language_button
= NULL
;
219 if (fwin
->right_button
)
220 wCoreDestroy(fwin
->right_button
);
221 fwin
->right_button
= NULL
;
223 wCoreDestroy(fwin
->titlebar
);
224 fwin
->titlebar
= NULL
;
229 /* if we didn't have a titlebar and are being requested for
231 if (flags
& WFF_TITLEBAR
) {
232 fwin
->top_width
= theight
;
234 fwin
->flags
.titlebar
= 1;
235 fwin
->titlebar
= wCoreCreate(fwin
->core
, 0, 0, width
+1, theight
);
237 if (flags
& WFF_LEFT_BUTTON
) {
238 fwin
->flags
.left_button
= 1;
239 if (wPreferences
.new_style
) {
240 fwin
->left_button
= wCoreCreate(fwin
->core
, 0, 0,
242 if (width
< theight
*4) {
243 fwin
->flags
.lbutton_dont_fit
= 1;
245 XMapRaised(dpy
, fwin
->left_button
->window
);
249 wCoreCreate(fwin
->titlebar
, 3, (theight
-bsize
)/2,
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
);
263 #ifdef XKB_BUTTON_HINT
264 if (flags
& WFF_LANGUAGE_BUTTON
) {
265 fwin
->flags
.language_button
= 1;
266 if (wPreferences
.new_style
) {
267 fwin
->language_button
= wCoreCreate(fwin
->core
,
268 bsize
, 0, bsize
, bsize
);
270 if (width
< theight
*4) {
271 fwin
->flags
.languagebutton_dont_fit
= 1;
273 XMapRaised(dpy
, fwin
->language_button
->window
);
276 fwin
->language_button
=
277 wCoreCreate(fwin
->titlebar
, bsize
+ 6, (theight
-bsize
)/2,
280 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
281 scr
->widget_texture
->normal
.pixel
);
283 if (width
< theight
*3) {
284 fwin
->flags
.languagebutton_dont_fit
= 1;
286 XMapRaised(dpy
, fwin
->language_button
->window
);
292 if (flags
& WFF_RIGHT_BUTTON
) {
293 fwin
->flags
.right_button
= 1;
294 if (wPreferences
.new_style
) {
296 wCoreCreate(fwin
->core
, width
-bsize
+1, 0,
300 wCoreCreate(fwin
->titlebar
, width
-bsize
-3,
301 (theight
-bsize
)/2, bsize
, bsize
);
302 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
303 scr
->widget_texture
->normal
.pixel
);
306 if (width
< theight
*2) {
307 fwin
->flags
.rbutton_dont_fit
= 1;
309 XMapRaised(dpy
, fwin
->right_button
->window
);
313 if (wPreferences
.new_style
)
314 updateTitlebar(fwin
);
316 XMapRaised(dpy
, fwin
->titlebar
->window
);
318 fwin
->flags
.need_texture_remake
= 1;
321 checkTitleSize(fwin
);
323 if (flags
& WFF_RESIZEBAR
) {
324 fwin
->bottom_width
= RESIZEBAR_HEIGHT
;
326 if (!fwin
->resizebar
) {
327 fwin
->flags
.resizebar
= 1;
328 fwin
->resizebar
= wCoreCreate(fwin
->core
, 0,
329 height
+ fwin
->top_width
,
330 width
, RESIZEBAR_HEIGHT
);
331 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
332 if (width
< RESIZEBAR_CORNER_WIDTH
*2 + RESIZEBAR_MIN_WIDTH
) {
333 fwin
->resizebar_corner_width
= (width
- RESIZEBAR_MIN_WIDTH
)/2;
334 if (fwin
->resizebar_corner_width
< 0)
335 fwin
->resizebar_corner_width
= 0;
338 XMapWindow(dpy
, fwin
->resizebar
->window
);
339 XLowerWindow(dpy
, fwin
->resizebar
->window
);
341 fwin
->flags
.need_texture_remake
= 1;
343 if (height
+fwin
->top_width
+fwin
->bottom_width
!= fwin
->core
->height
) {
344 wCoreConfigure(fwin
->resizebar
, 0, height
+ fwin
->top_width
,
345 width
, RESIZEBAR_HEIGHT
);
349 fwin
->bottom_width
= 0;
351 if (fwin
->resizebar
) {
352 fwin
->bottom_width
= 0;
353 wCoreDestroy(fwin
->resizebar
);
354 fwin
->resizebar
= NULL
;
358 if (height
+ fwin
->top_width
+ fwin
->bottom_width
!= fwin
->core
->height
359 && !(flags
& WFF_IS_SHADED
)) {
360 wFrameWindowResize(fwin
, width
,
361 height
+ fwin
->top_width
+ fwin
->bottom_width
);
365 if (flags
& WFF_BORDER
) {
366 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, FRAME_BORDER_WIDTH
);
368 XSetWindowBorderWidth(dpy
, fwin
->core
->window
, 0);
371 /* setup object descriptors */
373 if (fwin
->titlebar
) {
374 fwin
->titlebar
->descriptor
.handle_expose
= handleExpose
;
375 fwin
->titlebar
->descriptor
.parent
= fwin
;
376 fwin
->titlebar
->descriptor
.parent_type
= WCLASS_FRAME
;
377 fwin
->titlebar
->descriptor
.handle_mousedown
= titlebarMouseDown
;
380 if (fwin
->resizebar
) {
381 fwin
->resizebar
->descriptor
.handle_expose
= handleExpose
;
382 fwin
->resizebar
->descriptor
.parent
= fwin
;
383 fwin
->resizebar
->descriptor
.parent_type
= WCLASS_FRAME
;
384 fwin
->resizebar
->descriptor
.handle_mousedown
= resizebarMouseDown
;
387 if (fwin
->left_button
) {
388 fwin
->left_button
->descriptor
.handle_expose
= handleButtonExpose
;
389 fwin
->left_button
->descriptor
.parent
= fwin
;
390 fwin
->left_button
->descriptor
.parent_type
= WCLASS_FRAME
;
391 fwin
->left_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
394 #ifdef XKB_BUTTON_HINT
395 if (fwin
->language_button
) {
396 fwin
->language_button
->descriptor
.handle_expose
= handleButtonExpose
;
397 fwin
->language_button
->descriptor
.parent
= fwin
;
398 fwin
->language_button
->descriptor
.parent_type
= WCLASS_FRAME
;
399 fwin
->language_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
404 if (fwin
->right_button
) {
405 fwin
->right_button
->descriptor
.parent
= fwin
;
406 fwin
->right_button
->descriptor
.parent_type
= WCLASS_FRAME
;
407 fwin
->right_button
->descriptor
.handle_expose
= handleButtonExpose
;
408 fwin
->right_button
->descriptor
.handle_mousedown
= buttonMouseDown
;
411 checkTitleSize(fwin
);
417 wFrameWindowDestroy(WFrameWindow
*fwin
)
421 if (fwin
->left_button
)
422 wCoreDestroy(fwin
->left_button
);
424 #ifdef XKB_BUTTON_HINT
425 if (fwin
->language_button
)
426 wCoreDestroy(fwin
->language_button
);
429 if (fwin
->right_button
)
430 wCoreDestroy(fwin
->right_button
);
433 wCoreDestroy(fwin
->resizebar
);
436 wCoreDestroy(fwin
->titlebar
);
438 RemoveFromStackList(fwin
->core
);
440 wCoreDestroy(fwin
->core
);
445 for (i
=0; i
< (fwin
->flags
.single_texture
? 1 : 3); i
++) {
446 FREE_PIXMAP(fwin
->title_back
[i
]);
447 if (wPreferences
.new_style
) {
448 FREE_PIXMAP(fwin
->lbutton_back
[i
]);
449 #ifdef XKB_BUTTON_HINT
450 FREE_PIXMAP(fwin
->languagebutton_back
[i
]);
452 FREE_PIXMAP(fwin
->rbutton_back
[i
]);
461 wFrameWindowChangeState(WFrameWindow
*fwin
, int state
)
463 if (fwin
->flags
.state
==state
)
466 fwin
->flags
.state
= state
;
467 fwin
->flags
.need_texture_change
= 1;
469 wFrameWindowPaint(fwin
);
474 updateTitlebar(WFrameWindow
*fwin
)
479 theight
= WMFontHeight(*fwin
->font
) + (*fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
) * 2;
482 w
= fwin
->core
->width
+ 1;
484 if (wPreferences
.new_style
) {
485 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
486 || fwin
->flags
.lbutton_dont_fit
) {
488 #ifdef XKB_BUTTON_HINT
489 if(fwin
->language_button
)
490 wCoreConfigure(fwin
->language_button
, 0, 0,
491 fwin
->language_button
->width
,
492 fwin
->language_button
->width
);
495 #ifdef XKB_BUTTON_HINT
496 if(fwin
->language_button
)
497 wCoreConfigure(fwin
->language_button
, fwin
->left_button
->width
, 0,
498 fwin
->language_button
->width
,
499 fwin
->language_button
->width
);
501 x
= fwin
->left_button
->width
;
502 w
-= fwin
->left_button
->width
;
504 #ifdef XKB_BUTTON_HINT
505 if (fwin
->flags
.hide_language_button
|| !fwin
->language_button
506 || fwin
->flags
.languagebutton_dont_fit
) {
508 x
+= fwin
->language_button
->width
;
509 w
-= fwin
->language_button
->width
;
513 #ifdef XKB_BUTTON_HINT
515 int bsize
= theight
- 7;
516 if (fwin
->flags
.hide_left_button
|| !fwin
->left_button
517 || fwin
->flags
.lbutton_dont_fit
) {
518 if(fwin
->language_button
)
519 wCoreConfigure(fwin
->language_button
, 3, (theight
-bsize
)/2,
520 fwin
->language_button
->width
,
521 fwin
->language_button
->width
);
524 if(fwin
->language_button
)
525 wCoreConfigure(fwin
->language_button
,
526 6 + fwin
->left_button
->width
, (theight
-bsize
)/2,
527 fwin
->language_button
->width
,
528 fwin
->language_button
->width
);
533 if (wPreferences
.new_style
) {
534 if (!fwin
->flags
.hide_right_button
&& fwin
->right_button
535 && !fwin
->flags
.rbutton_dont_fit
) {
536 w
-= fwin
->right_button
->width
;
540 if (wPreferences
.new_style
|| fwin
->titlebar
->width
!=w
)
541 fwin
->flags
.need_texture_remake
= 1;
543 wCoreConfigure(fwin
->titlebar
, x
, 0, w
, theight
);
548 wFrameWindowHideButton(WFrameWindow
*fwin
, int flags
)
550 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
) {
551 XUnmapWindow(dpy
, fwin
->right_button
->window
);
552 fwin
->flags
.hide_right_button
= 1;
555 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
) {
556 XUnmapWindow(dpy
, fwin
->left_button
->window
);
557 fwin
->flags
.hide_left_button
= 1;
560 #ifdef XKB_BUTTON_HINT
561 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
) {
562 XUnmapWindow(dpy
, fwin
->language_button
->window
);
563 fwin
->flags
.hide_language_button
= 1;
567 if (fwin
->titlebar
) {
568 if (wPreferences
.new_style
) {
569 updateTitlebar(fwin
);
571 #ifdef XKB_BUTTON_HINT
572 updateTitlebar(fwin
);
574 XClearWindow(dpy
, fwin
->titlebar
->window
);
575 wFrameWindowPaint(fwin
);
578 checkTitleSize(fwin
);
584 wFrameWindowShowButton(WFrameWindow
*fwin
, int flags
)
586 if ((flags
& WFF_RIGHT_BUTTON
) && fwin
->right_button
587 && fwin
->flags
.hide_right_button
) {
589 if (!fwin
->flags
.rbutton_dont_fit
)
590 XMapWindow(dpy
, fwin
->right_button
->window
);
592 fwin
->flags
.hide_right_button
= 0;
595 #ifdef XKB_BUTTON_HINT
596 if ((flags
& WFF_LANGUAGE_BUTTON
) && fwin
->language_button
597 && fwin
->flags
.hide_language_button
) {
599 if (!fwin
->flags
.languagebutton_dont_fit
)
600 XMapWindow(dpy
, fwin
->language_button
->window
);
602 fwin
->flags
.hide_language_button
= 0;
606 if ((flags
& WFF_LEFT_BUTTON
) && fwin
->left_button
607 && fwin
->flags
.hide_left_button
) {
609 if (!fwin
->flags
.lbutton_dont_fit
)
610 XMapWindow(dpy
, fwin
->left_button
->window
);
612 fwin
->flags
.hide_left_button
= 0;
616 if (fwin
->titlebar
) {
617 if (wPreferences
.new_style
) {
618 updateTitlebar(fwin
);
620 XClearWindow(dpy
, fwin
->titlebar
->window
);
621 wFrameWindowPaint(fwin
);
623 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
,
636 Pixmap
*title
, Pixmap
*lbutton
, Pixmap
*rbutton
)
640 RImage
*limg
, *rimg
, *mimg
;
641 #ifdef XKB_BUTTON_HINT
649 #ifdef XKB_BUTTON_HINT
650 *languagebutton
= None
;
653 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
655 wwarning(_("could not render texture: %s"), RMessageForError(RErrorCode
));
659 if (wPreferences
.new_style
) {
661 limg
= RGetSubImage(img
, 0, 0, bwidth
, bheight
);
668 #ifdef XKB_BUTTON_HINT
670 timg
= RGetSubImage(img
, bwidth
* left
, 0, bwidth
, bheight
);
676 RBevelImage(limg
, RBEV_RAISED2
);
677 if (!RConvertImage(scr
->rcontext
, limg
, lbutton
)) {
678 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
685 #ifdef XKB_BUTTON_HINT
687 RBevelImage(timg
, RBEV_RAISED2
);
688 if (!RConvertImage(scr
->rcontext
, timg
, languagebutton
)) {
689 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
698 rimg
= RGetSubImage(img
, width
- bwidth
, 0, bwidth
, bheight
);
703 RBevelImage(rimg
, RBEV_RAISED2
);
704 if (!RConvertImage(scr
->rcontext
, rimg
, rbutton
)) {
705 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
712 mimg
= RGetSubImage(img
, x
, 0, w
, img
->height
);
713 RBevelImage(mimg
, RBEV_RAISED2
);
715 if (!RConvertImage(scr
->rcontext
, mimg
, title
)) {
716 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
720 RBevelImage(img
, RBEV_RAISED2
);
722 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
723 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
727 RBevelImage(img
, RBEV_RAISED2
);
729 if (!RConvertImage(scr
->rcontext
, img
, title
)) {
730 wwarning(_("error rendering image:%s"), RMessageForError(RErrorCode
));
739 renderResizebarTexture(WScreen
*scr
, WTexture
*texture
, int width
, int height
,
740 int cwidth
, Pixmap
*pmap
)
748 img
= wTextureRenderImage(texture
, width
, height
, WREL_FLAT
);
750 wwarning(_("could not render texture: %s"),
751 RMessageForError(RErrorCode
));
756 light
.red
= light
.green
= light
.blue
= 80;
759 dark
.red
= dark
.green
= dark
.blue
= 40;
761 ROperateLine(img
, RSubtractOperation
, 0, 0, width
-1, 0, &dark
);
762 ROperateLine(img
, RAddOperation
, 0, 1, width
-1, 1, &light
);
764 ROperateLine(img
, RSubtractOperation
, cwidth
, 2, cwidth
, height
-1, &dark
);
765 ROperateLine(img
, RAddOperation
, cwidth
+1, 2, cwidth
+1, height
-1, &light
);
768 ROperateLine(img
, RSubtractOperation
, width
-cwidth
-2, 2,
769 width
-cwidth
-2, height
-1, &dark
);
770 ROperateLine(img
, RAddOperation
, width
-cwidth
-1, 2, width
-cwidth
-1,
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,
777 ROperateLine(img
, RSubtractOperation
, 0, height
-1, width
-1, height
-1,
779 #endif /* SHADOW_RESIZEBAR */
782 if (!RConvertImage(scr
->rcontext
, img
, pmap
)) {
783 wwarning(_("error rendering image: %s"), RMessageForError(RErrorCode
));
792 updateTexture(WFrameWindow
*fwin
)
797 i
= fwin
->flags
.state
;
798 if (fwin
->titlebar
) {
799 if (fwin
->title_texture
[i
]->any
.type
!=WTEX_SOLID
) {
800 XSetWindowBackgroundPixmap(dpy
, fwin
->titlebar
->window
,
801 fwin
->title_back
[i
]);
802 if (wPreferences
.new_style
) {
803 if (fwin
->left_button
&& fwin
->lbutton_back
[i
])
804 XSetWindowBackgroundPixmap(dpy
, fwin
->left_button
->window
,
805 fwin
->lbutton_back
[i
]);
807 #ifdef XKB_BUTTON_HINT
808 if (fwin
->language_button
&& fwin
->languagebutton_back
[i
]) {
809 XSetWindowBackgroundPixmap(dpy
, fwin
->language_button
->window
,
810 fwin
->languagebutton_back
[i
]);
814 if (fwin
->right_button
&& fwin
->rbutton_back
[i
])
815 XSetWindowBackgroundPixmap(dpy
, fwin
->right_button
->window
,
816 fwin
->rbutton_back
[i
]);
819 pixel
= fwin
->title_texture
[i
]->solid
.normal
.pixel
;
820 XSetWindowBackground(dpy
, fwin
->titlebar
->window
, pixel
);
821 if (wPreferences
.new_style
) {
822 if (fwin
->left_button
)
823 XSetWindowBackground(dpy
, fwin
->left_button
->window
,
825 #ifdef XKB_BUTTON_HINT
826 if (fwin
->language_button
)
827 XSetWindowBackground(dpy
, fwin
->language_button
->window
,
830 if (fwin
->right_button
)
831 XSetWindowBackground(dpy
, fwin
->right_button
->window
,
835 XClearWindow(dpy
, fwin
->titlebar
->window
);
837 if (fwin
->left_button
) {
838 XClearWindow(dpy
, fwin
->left_button
->window
);
839 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
841 #ifdef XKB_BUTTON_HINT
842 if (fwin
->language_button
) {
843 XClearWindow(dpy
, fwin
->language_button
->window
);
844 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
847 if (fwin
->right_button
) {
848 XClearWindow(dpy
, fwin
->right_button
->window
);
849 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
857 remakeTexture(WFrameWindow
*fwin
, int state
)
859 Pixmap pmap
, lpmap
, rpmap
;
860 #ifdef XKB_BUTTON_HINT
864 if (fwin
->title_texture
[state
] && fwin
->titlebar
) {
865 FREE_PIXMAP(fwin
->title_back
[state
]);
866 if (wPreferences
.new_style
) {
867 FREE_PIXMAP(fwin
->lbutton_back
[state
]);
868 FREE_PIXMAP(fwin
->rbutton_back
[state
]);
869 #ifdef XKB_BUTTON_HINT
870 FREE_PIXMAP(fwin
->languagebutton_back
[state
]);
874 if (fwin
->title_texture
[state
]->any
.type
!=WTEX_SOLID
) {
876 #ifdef XKB_BUTTON_HINT
881 /* eventually surrounded by if new_style */
882 left
= fwin
->left_button
&& !fwin
->flags
.hide_left_button
883 && !fwin
->flags
.lbutton_dont_fit
;
884 #ifdef XKB_BUTTON_HINT
885 language
= fwin
->language_button
&& !fwin
->flags
.hide_language_button
886 && !fwin
->flags
.languagebutton_dont_fit
;
888 right
= fwin
->right_button
&& !fwin
->flags
.hide_right_button
889 && !fwin
->flags
.rbutton_dont_fit
;
891 width
= fwin
->core
->width
+1;
893 #ifdef XKB_BUTTON_HINT
894 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
895 width
, fwin
->titlebar
->height
,
896 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
897 left
, language
, right
, &pmap
, &lpmap
, &tpmap
, &rpmap
);
899 renderTexture(fwin
->screen_ptr
, fwin
->title_texture
[state
],
900 width
, fwin
->titlebar
->height
,
901 fwin
->titlebar
->height
, fwin
->titlebar
->height
,
902 left
, right
, &pmap
, &lpmap
, &rpmap
);
905 fwin
->title_back
[state
] = pmap
;
906 if (wPreferences
.new_style
) {
907 fwin
->lbutton_back
[state
] = lpmap
;
908 fwin
->rbutton_back
[state
] = rpmap
;
909 #ifdef XKB_BUTTON_HINT
910 fwin
->languagebutton_back
[state
] = tpmap
;
915 if (fwin
->resizebar_texture
&& fwin
->resizebar_texture
[0]
916 && fwin
->resizebar
&& state
== 0) {
918 FREE_PIXMAP(fwin
->resizebar_back
[0]);
920 if (fwin
->resizebar_texture
[0]->any
.type
!=WTEX_SOLID
) {
922 renderResizebarTexture(fwin
->screen_ptr
,
923 fwin
->resizebar_texture
[0],
924 fwin
->resizebar
->width
,
925 fwin
->resizebar
->height
,
926 fwin
->resizebar_corner_width
,
929 fwin
->resizebar_back
[0] = pmap
;
932 /* this part should be in updateTexture() */
933 if (fwin
->resizebar_texture
[0]->any
.type
!=WTEX_SOLID
) {
934 XSetWindowBackgroundPixmap(dpy
, fwin
->resizebar
->window
,
935 fwin
->resizebar_back
[0]);
937 XSetWindowBackground(dpy
, fwin
->resizebar
->window
,
938 fwin
->resizebar_texture
[0]->solid
.normal
.pixel
);
940 XClearWindow(dpy
, fwin
->resizebar
->window
);
946 wFrameWindowPaint(WFrameWindow
*fwin
)
948 WScreen
*scr
= fwin
->screen_ptr
;
949 #ifdef DRAWSTRING_PLUGIN
950 #define DRAWSTRING_CURRENT_STATE fwin->flags.state + fwin->drawstring_proc_offset
953 int tb
= fwin
->top_width
;
957 if (fwin
->flags
.is_client_window_frame
)
958 fwin
->flags
.justification
= wPreferences
.title_justification
;
960 if (fwin
->flags
.need_texture_remake
) {
963 fwin
->flags
.need_texture_remake
= 0;
964 fwin
->flags
.need_texture_change
= 0;
966 if (fwin
->flags
.single_texture
) {
967 remakeTexture(fwin
, 0);
970 /* first render the texture for the current state... */
971 remakeTexture(fwin
, fwin
->flags
.state
);
972 /* ... and paint it */
975 for (i
=0; i
< 3; i
++) {
976 if (i
!=fwin
->flags
.state
)
977 remakeTexture(fwin
, i
);
982 if (fwin
->flags
.need_texture_change
) {
983 fwin
->flags
.need_texture_change
= 0;
988 if (fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
989 && fwin
->title_texture
[fwin
->flags
.state
]->any
.type
==WTEX_SOLID
) {
990 #ifdef DRAWSTRING_PLUGIN
992 tmp_bg
= XCreatePixmap(dpy
, fwin
->titlebar
->window
,
993 fwin
->titlebar
->width
, tb
,
994 DefaultDepth(dpy
, DefaultScreen(dpy
)));
995 XFillRectangle(dpy
, tmp_bg
, (*fwin
->title_texture
)->solid
.normal_gc
,
996 0, 0, fwin
->titlebar
->width
, tb
);
997 wDrawBevel(tmp_bg
, fwin
->titlebar
->width
,
998 fwin
->titlebar
->height
,
999 (WTexSolid
*)fwin
->title_texture
[fwin
->flags
.state
],
1001 background
= &tmp_bg
;
1003 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
1004 fwin
->titlebar
->height
,
1005 (WTexSolid
*)fwin
->title_texture
[fwin
->flags
.state
],
1009 wDrawBevel(fwin
->titlebar
->window
, fwin
->titlebar
->width
,
1010 fwin
->titlebar
->height
,
1011 (WTexSolid
*)fwin
->title_texture
[fwin
->flags
.state
],
1015 #ifdef DRAWSTRING_PLUGIN
1016 else background
= &fwin
->title_back
[fwin
->flags
.state
];
1019 if (fwin
->resizebar
&& !fwin
->flags
.repaint_only_titlebar
1020 && fwin
->resizebar_texture
[0]->any
.type
== WTEX_SOLID
) {
1024 GC light_gc
, dim_gc
;
1025 WTexSolid
*texture
= (WTexSolid
*)fwin
->resizebar_texture
[0];
1027 w
= fwin
->resizebar
->width
;
1028 h
= fwin
->resizebar
->height
;
1029 cw
= fwin
->resizebar_corner_width
;
1030 light_gc
= texture
->light_gc
;
1031 dim_gc
= texture
->dim_gc
;
1032 win
= fwin
->resizebar
->window
;
1034 XDrawLine(dpy
, win
, dim_gc
, 0, 0, w
, 0);
1035 XDrawLine(dpy
, win
, light_gc
, 0, 1, w
, 1);
1037 XDrawLine(dpy
, win
, dim_gc
, cw
, 2, cw
, h
);
1038 XDrawLine(dpy
, win
, light_gc
, cw
+1, 2, cw
+1, h
);
1040 XDrawLine(dpy
, win
, dim_gc
, w
-cw
-2, 2, w
-cw
-2, h
);
1041 XDrawLine(dpy
, win
, light_gc
, w
-cw
-1, 2, w
-cw
-1, h
);
1043 #ifdef SHADOW_RESIZEBAR
1044 XDrawLine(dpy
, win
, light_gc
, 0, 1, 0, h
-1);
1045 XDrawLine(dpy
, win
, dim_gc
, w
-1, 2, w
-1, h
-1);
1046 XDrawLine(dpy
, win
, dim_gc
, 1, h
-1, cw
, h
-1);
1047 XDrawLine(dpy
, win
, dim_gc
, cw
+2, h
-1, w
-cw
-2, h
-1);
1048 XDrawLine(dpy
, win
, dim_gc
, w
-cw
, h
-1, w
-1, h
-1);
1049 #endif /* SHADOW_RESIZEBAR */
1053 if (fwin
->title
&& fwin
->titlebar
&& !fwin
->flags
.repaint_only_resizebar
) {
1055 int lofs
= 6, rofs
= 6;
1061 if (!wPreferences
.new_style
) {
1062 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
1063 && !fwin
->flags
.lbutton_dont_fit
)
1064 lofs
+= fwin
->left_button
->width
+ 3;
1068 #ifdef XKB_BUTTON_HINT
1069 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1070 && !fwin
->flags
.languagebutton_dont_fit
)
1071 lofs
+= fwin
->language_button
->width
;
1076 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
1077 && !fwin
->flags
.rbutton_dont_fit
)
1078 rofs
+= fwin
->right_button
->width
+ 3;
1083 #ifdef XKB_BUTTON_HINT
1084 fwin
->languagebutton_image
=
1085 scr
->b_pixmaps
[WBUT_XKBGROUP1
+ fwin
->languagemode
];
1088 #ifdef DRAWSTRING_PLUGIN
1089 if(scr
->drawstring_func
[DRAWSTRING_CURRENT_STATE
]) {
1090 title
= ShrinkString(*fwin
->font
, fwin
->title
,
1091 fwin
->titlebar
->width
- lofs
- rofs
,
1092 scr
->drawstring_func
[DRAWSTRING_CURRENT_STATE
]);
1093 titlelen
= strlen(title
);
1094 pd
= wPluginPackData(1, scr
->drawstring_func
[DRAWSTRING_CURRENT_STATE
]->data
);
1095 scr
->drawstring_func
[DRAWSTRING_CURRENT_STATE
]->proc
.widthOfString
[W_DSPROC_WIDTHOFSTRING
](
1096 title
, titlelen
, pd
, &w
, NULL
, NULL
);
1099 title
= ShrinkString(*fwin
->font
, fwin
->title
,
1100 fwin
->titlebar
->width
- lofs
- rofs
, NULL
);
1101 titlelen
= strlen(title
);
1102 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1105 title
= ShrinkString(*fwin
->font
, fwin
->title
,
1106 fwin
->titlebar
->width
- lofs
- rofs
);
1107 titlelen
= strlen(title
);
1108 w
= WMWidthOfString(*fwin
->font
, title
, titlelen
);
1110 switch (fwin
->flags
.justification
) {
1116 x
= fwin
->titlebar
->width
- w
- rofs
;
1121 x
= lofs
+ (fwin
->titlebar
->width
- w
- lofs
- rofs
) / 2;
1123 x
= (fwin
->titlebar
->width
- w
) / 2;
1127 XSetForeground(dpy
, *fwin
->title_gc
,
1128 fwin
->title_pixel
[fwin
->flags
.state
]);
1130 #ifdef DRAWSTRING_PLUGIN
1131 /* if the plugin want to do shrinking locally, they can trick
1132 * wmaker by returning a very short value (such as 0) to widthOfString -- I think */
1133 if (scr
->drawstring_func
[DRAWSTRING_CURRENT_STATE
]) {
1134 pd
= wPluginPackData(6, /* number of argument, will be passed */
1135 scr
->drawstring_func
[DRAWSTRING_CURRENT_STATE
]->data
,
1136 /* 0 plugin data, as it was initialized */
1137 background
, /* 1 current background Pixmap */
1138 fwin
->title_gc
, /* 2 gc */
1139 *fwin
->font
, /* 3 WMFont** */
1140 &fwin
->titlebar
->width
,
1141 /* 4 suggested width */
1142 &tb
/* 5 suggested height */
1144 scr
->drawstring_func
[DRAWSTRING_CURRENT_STATE
]->proc
.drawString
[W_DSPROC_DRAWSTRING
](
1145 scr
->drawstring_func
[DRAWSTRING_CURRENT_STATE
]->arg
,
1146 fwin
->titlebar
->window
,
1148 title
, strlen(fwin
->title
), pd
);
1151 WMDrawString(scr
->wmscreen
, fwin
->titlebar
->window
,
1152 *fwin
->title_gc
, *fwin
->font
,
1153 x
, ((signed)fwin
->top_width
- (signed)WMFontHeight(*fwin
->font
))/2,
1157 if (fwin
->title
&& fwin
->title_texture
[fwin
->flags
.state
]->any
.type
==WTEX_SOLID
) {
1158 XFreePixmap(dpy
, tmp_bg
);
1160 #undef DRAWSTRING_CURRENT_STATE
1162 WMDrawString(scr
->wmscreen
, fwin
->titlebar
->window
,
1163 *fwin
->title_gc
, *fwin
->font
, x
, *fwin
->title_clearance
+ TITLEBAR_EXTEND_SPACE
,
1165 #endif /* DRAWSTRING_PLUGIN */
1169 if (fwin
->left_button
)
1170 handleButtonExpose(&fwin
->left_button
->descriptor
, NULL
);
1171 if (fwin
->right_button
)
1172 handleButtonExpose(&fwin
->right_button
->descriptor
, NULL
);
1173 #ifdef XKB_BUTTON_HINT
1174 if (fwin
->language_button
)
1175 handleButtonExpose(&fwin
->language_button
->descriptor
, NULL
);
1182 reconfigure(WFrameWindow
*fwin
, int x
, int y
, int width
, int height
,
1185 int k
= (wPreferences
.new_style
? 4 : 3);
1186 int resizedHorizontally
= 0;
1189 XResizeWindow(dpy
, fwin
->core
->window
, width
, height
);
1191 XMoveResizeWindow(dpy
, fwin
->core
->window
, x
, y
, width
, height
);
1194 if (fwin->core->height != height && fwin->resizebar)
1195 XMoveWindow(dpy, fwin->resizebar->window, 0,
1196 height - fwin->resizebar->height);
1198 if (fwin
->core
->width
!= width
) {
1199 fwin
->flags
.need_texture_remake
= 1;
1200 resizedHorizontally
= 1;
1203 fwin
->core
->width
= width
;
1204 fwin
->core
->height
= height
;
1206 if (fwin
->titlebar
&& resizedHorizontally
) {
1207 /* Check if the titlebar is wide enough to hold the buttons.
1208 * Temporarily remove them if can't
1210 if (fwin
->left_button
) {
1211 if (width
< fwin
->top_width
*k
&& !fwin
->flags
.lbutton_dont_fit
) {
1213 if (!fwin
->flags
.hide_left_button
) {
1214 XUnmapWindow(dpy
, fwin
->left_button
->window
);
1216 fwin
->flags
.lbutton_dont_fit
= 1;
1217 } else if (width
>= fwin
->top_width
*k
&& fwin
->flags
.lbutton_dont_fit
) {
1219 if (!fwin
->flags
.hide_left_button
) {
1220 XMapWindow(dpy
, fwin
->left_button
->window
);
1222 fwin
->flags
.lbutton_dont_fit
= 0;
1226 #ifdef XKB_BUTTON_HINT
1227 if (fwin
->language_button
) {
1228 if (width
< fwin
->top_width
*k
&& !fwin
->flags
.languagebutton_dont_fit
) {
1230 if (!fwin
->flags
.hide_language_button
) {
1231 XUnmapWindow(dpy
, fwin
->language_button
->window
);
1233 fwin
->flags
.languagebutton_dont_fit
= 1;
1234 } else if (width
>= fwin
->top_width
*k
&& fwin
->flags
.languagebutton_dont_fit
) {
1236 if (!fwin
->flags
.hide_language_button
) {
1237 XMapWindow(dpy
, fwin
->language_button
->window
);
1239 fwin
->flags
.languagebutton_dont_fit
= 0;
1244 if (fwin
->right_button
) {
1245 if (width
< fwin
->top_width
*2 && !fwin
->flags
.rbutton_dont_fit
) {
1247 if (!fwin
->flags
.hide_right_button
) {
1248 XUnmapWindow(dpy
, fwin
->right_button
->window
);
1250 fwin
->flags
.rbutton_dont_fit
= 1;
1251 } else if (width
>= fwin
->top_width
*2 && fwin
->flags
.rbutton_dont_fit
) {
1253 if (!fwin
->flags
.hide_right_button
) {
1254 XMapWindow(dpy
, fwin
->right_button
->window
);
1256 fwin
->flags
.rbutton_dont_fit
= 0;
1260 if (wPreferences
.new_style
) {
1261 if (fwin
->right_button
)
1262 XMoveWindow(dpy
, fwin
->right_button
->window
,
1263 width
- fwin
->right_button
->width
+ 1, 0);
1265 if (fwin
->right_button
)
1266 XMoveWindow(dpy
, fwin
->right_button
->window
,
1267 width
- fwin
->right_button
->width
- 3,
1268 (fwin
->titlebar
->height
- fwin
->right_button
->height
)/2);
1270 updateTitlebar(fwin
);
1271 checkTitleSize(fwin
);
1274 if (fwin
->resizebar
) {
1275 wCoreConfigure(fwin
->resizebar
, 0,
1276 fwin
->core
->height
- fwin
->resizebar
->height
,
1277 fwin
->core
->width
, fwin
->resizebar
->height
);
1279 fwin
->resizebar_corner_width
= RESIZEBAR_CORNER_WIDTH
;
1280 if (fwin
->core
->width
< RESIZEBAR_CORNER_WIDTH
*2 + RESIZEBAR_MIN_WIDTH
) {
1281 fwin
->resizebar_corner_width
= fwin
->core
->width
/2;
1287 wFrameWindowConfigure(WFrameWindow
*fwin
, int x
, int y
, int width
, int height
)
1289 reconfigure(fwin
, x
, y
, width
, height
, False
);
1293 wFrameWindowResize(WFrameWindow
*fwin
, int width
, int height
)
1295 reconfigure(fwin
, 0, 0, width
, height
, True
);
1301 wFrameWindowChangeTitle(WFrameWindow
*fwin
, char *new_title
)
1303 /* check if the title is the same as before */
1305 if (new_title
&& (strcmp(fwin
->title
, new_title
) == 0)) {
1316 fwin
->title
= wstrdup(new_title
);
1318 if (fwin
->titlebar
) {
1319 XClearWindow(dpy
, fwin
->titlebar
->window
);
1321 wFrameWindowPaint(fwin
);
1323 checkTitleSize(fwin
);
1331 wFrameWindowUpdatePushButton(WFrameWindow
*fwin
, Bool pushed
)
1333 fwin
->flags
.right_button_pushed_in
= pushed
;
1335 paintButton(fwin
->right_button
, fwin
->title_texture
[fwin
->flags
.state
],
1336 fwin
->title_pixel
[fwin
->flags
.state
],
1337 fwin
->rbutton_image
, pushed
);
1339 #endif /* OLWM_HINTS */
1342 #ifdef XKB_BUTTON_HINT
1344 wFrameWindowUpdateLanguageButton(WFrameWindow
*fwin
)
1346 paintButton(fwin
->language_button
, fwin
->title_texture
[fwin
->flags
.state
],
1347 fwin
->title_pixel
[fwin
->flags
.state
],
1348 fwin
->languagebutton_image
, True
);
1350 #endif /* XKB_BUTTON_HINT */
1353 /*********************************************************************/
1356 handleExpose(WObjDescriptor
*desc
, XEvent
*event
)
1358 WFrameWindow
*fwin
= (WFrameWindow
*)desc
->parent
;
1361 if (fwin
->titlebar
&& fwin
->titlebar
->window
== event
->xexpose
.window
)
1362 fwin
->flags
.repaint_only_titlebar
= 1;
1363 if (fwin
->resizebar
&& fwin
->resizebar
->window
== event
->xexpose
.window
)
1364 fwin
->flags
.repaint_only_resizebar
= 1;
1365 wFrameWindowPaint(fwin
);
1366 fwin
->flags
.repaint_only_titlebar
= 0;
1367 fwin
->flags
.repaint_only_resizebar
= 0;
1372 checkTitleSize(WFrameWindow
*fwin
)
1377 fwin
->flags
.incomplete_title
= 0;
1381 if (!fwin
->titlebar
) {
1382 fwin
->flags
.incomplete_title
= 1;
1385 width
= fwin
->titlebar
->width
- 6 - 6;
1388 if (!wPreferences
.new_style
) {
1389 if (fwin
->left_button
&& !fwin
->flags
.hide_left_button
1390 && !fwin
->flags
.lbutton_dont_fit
)
1391 width
-= fwin
->left_button
->width
+ 3;
1393 #ifdef XKB_BUTTON_HINT
1394 if (fwin
->language_button
&& !fwin
->flags
.hide_language_button
1395 && !fwin
->flags
.languagebutton_dont_fit
)
1396 width
-= fwin
->language_button
->width
+ 3;
1399 if (fwin
->right_button
&& !fwin
->flags
.hide_right_button
1400 && !fwin
->flags
.rbutton_dont_fit
)
1401 width
-= fwin
->right_button
->width
+ 3;
1403 if (WMWidthOfString(*fwin
->font
, fwin
->title
, strlen(fwin
->title
)) > width
) {
1404 fwin
->flags
.incomplete_title
= 1;
1406 fwin
->flags
.incomplete_title
= 0;
1412 paintButton(WCoreWindow
*button
, WTexture
*texture
, unsigned long color
,
1413 WPixmap
*image
, int pushed
)
1415 WScreen
*scr
= button
->screen_ptr
;
1416 GC copy_gc
= scr
->copy_gc
;
1418 int left
=0, width
=0;
1420 /* setup stuff according to the state */
1423 if (image
->width
>=image
->height
*2) {
1424 /* the image contains 2 pictures: the second is for the
1426 width
= image
->width
/2;
1427 left
= image
->width
/2;
1429 width
= image
->width
;
1432 XSetClipMask(dpy
, copy_gc
, None
);
1433 XSetForeground(dpy
, copy_gc
, scr
->white_pixel
);
1435 if (wPreferences
.new_style
) {
1436 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1437 button
->width
-1, button
->height
-1);
1438 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1439 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1440 button
->width
-1, button
->height
-1);
1442 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1443 button
->width
, button
->height
);
1444 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1445 XDrawRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1446 button
->width
, button
->height
);
1449 XClearWindow(dpy
, button
->window
);
1452 if (image
->width
>=image
->height
*2)
1453 width
= image
->width
/2;
1455 width
= image
->width
;
1459 if (wPreferences
.new_style
) {
1460 if (texture
->any
.type
==WTEX_SOLID
|| pushed
) {
1461 wDrawBevel(button
->window
, button
->width
, button
->height
,
1462 (WTexSolid
*)texture
, WREL_RAISED
);
1465 wDrawBevel(button
->window
, button
->width
, button
->height
,
1466 scr
->widget_texture
, WREL_RAISED
);
1472 XSetClipMask(dpy
, copy_gc
, image
->mask
);
1473 x
= (button
->width
- width
)/2 + d
;
1474 y
= (button
->height
- image
->height
)/2 + d
;
1475 XSetClipOrigin(dpy
, copy_gc
, x
-left
, y
);
1476 if (!wPreferences
.new_style
) {
1477 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1479 if (image
->depth
==1)
1480 XCopyPlane(dpy
, image
->image
, button
->window
, copy_gc
,
1481 left
, 0, width
, image
->height
, x
, y
, 1);
1483 XCopyArea(dpy
, image
->image
, button
->window
, copy_gc
,
1484 left
, 0, width
, image
->height
, x
, y
);
1486 XSetForeground(dpy
, copy_gc
, scr
->dark_pixel
);
1487 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1488 button
->width
, button
->height
);
1492 XSetForeground(dpy
, copy_gc
, scr
->black_pixel
);
1494 XSetForeground(dpy
, copy_gc
, color
);
1495 XSetBackground(dpy
, copy_gc
, texture
->any
.color
.pixel
);
1497 XFillRectangle(dpy
, button
->window
, copy_gc
, 0, 0,
1498 button
->width
, button
->height
);
1505 handleButtonExpose(WObjDescriptor
*desc
, XEvent
*event
)
1507 WFrameWindow
*fwin
= (WFrameWindow
*)desc
->parent
;
1508 WCoreWindow
*button
= (WCoreWindow
*)desc
->self
;
1510 #ifdef XKB_BUTTON_HINT
1511 if (button
== fwin
->language_button
) {
1512 if (wPreferences
.modelock
){
1513 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1514 fwin
->title_pixel
[fwin
->flags
.state
],
1515 fwin
->languagebutton_image
, False
);
1519 if (button
== fwin
->left_button
) {
1520 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1521 fwin
->title_pixel
[fwin
->flags
.state
],
1522 fwin
->lbutton_image
, False
);
1524 Bool pushed
= False
;
1527 if (fwin
->flags
.right_button_pushed_in
)
1530 /* emulate the olwm pushpin in the "out" state */
1531 paintButton(button
, fwin
->title_texture
[fwin
->flags
.state
],
1532 fwin
->title_pixel
[fwin
->flags
.state
],
1533 fwin
->rbutton_image
, pushed
);
1539 titlebarMouseDown(WObjDescriptor
*desc
, XEvent
*event
)
1541 WFrameWindow
*fwin
= desc
->parent
;
1542 WCoreWindow
*titlebar
= desc
->self
;
1544 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1545 if (fwin
->on_dblclick_titlebar
)
1546 (*fwin
->on_dblclick_titlebar
)(titlebar
, fwin
->child
, event
);
1548 if (fwin
->on_mousedown_titlebar
)
1549 (*fwin
->on_mousedown_titlebar
)(titlebar
, fwin
->child
, event
);
1555 resizebarMouseDown(WObjDescriptor
*desc
, XEvent
*event
)
1557 WFrameWindow
*fwin
= desc
->parent
;
1558 WCoreWindow
*resizebar
= desc
->self
;
1560 if (fwin
->on_mousedown_resizebar
)
1561 (*fwin
->on_mousedown_resizebar
)(resizebar
, fwin
->child
, event
);
1566 buttonMouseDown(WObjDescriptor
*desc
, XEvent
*event
)
1568 WFrameWindow
*fwin
= desc
->parent
;
1569 WCoreWindow
*button
= desc
->self
;
1572 int done
=0, execute
=1;
1574 unsigned long pixel
;
1575 int clickButton
= event
->xbutton
.button
;
1577 if (IsDoubleClick(fwin
->core
->screen_ptr
, event
)) {
1578 if (button
== fwin
->right_button
&& fwin
->on_dblclick_right
) {
1579 (*fwin
->on_dblclick_right
)(button
, fwin
->child
, event
);
1584 if (button
== fwin
->left_button
) {
1585 image
= fwin
->lbutton_image
;
1587 image
= fwin
->rbutton_image
;
1589 #ifdef XKB_BUTTON_HINT
1590 if (button
== fwin
->language_button
) {
1591 if (!wPreferences
.modelock
) return;
1592 image
= fwin
->languagebutton_image
;
1596 pixel
= fwin
->title_pixel
[fwin
->flags
.state
];
1597 texture
= fwin
->title_texture
[fwin
->flags
.state
];
1598 paintButton(button
, texture
, pixel
, image
, True
);
1601 WMMaskEvent(dpy
, LeaveWindowMask
|EnterWindowMask
|ButtonReleaseMask
1602 |ButtonPressMask
|ExposureMask
, &ev
);
1606 paintButton(button
, texture
, pixel
, image
, False
);
1611 paintButton(button
, texture
, pixel
, image
, True
);
1618 if (ev
.xbutton
.button
== clickButton
)
1626 paintButton(button
, texture
, pixel
, image
, False
);
1629 if (button
== fwin
->left_button
) {
1630 if (fwin
->on_click_left
)
1631 (*fwin
->on_click_left
)(button
, fwin
->child
, &ev
);
1632 } else if (button
== fwin
->right_button
) {
1633 if (fwin
->on_click_right
)
1634 (*fwin
->on_click_right
)(button
, fwin
->child
, &ev
);
1636 #ifdef XKB_BUTTON_HINT
1637 else if (button
== fwin
->language_button
) {
1638 if (fwin
->on_click_language
)
1639 (*fwin
->on_click_language
)(button
, fwin
->child
, &ev
);