4 #include "../src/config.h"
8 #include <X11/extensions/shape.h>
12 typedef struct W_Balloon
{
15 WMHashTable
*table
; /* Table from view ptr to text */
21 WMHandlerID timer
; /* timer for showing balloon */
23 WMHandlerID noDelayTimer
;
27 Window forWindow
; /* window for which the balloon
28 * is being show in the moment */
31 WMAlignment alignment
:2;
40 #define DEFAULT_WIDTH 60
41 #define DEFAULT_HEIGHT 14
42 #define DEFAULT_ALIGNMENT WALeft
43 #define DEFAULT_DELAY 500
45 #define NO_DELAY_DELAY 150
48 static void destroyBalloon(Balloon
*bPtr
);
51 static void handleEvents(XEvent
*event
, void *data
);
53 static void showText(Balloon
*bPtr
, int x
, int y
, int w
, int h
, char *text
);
57 W_CreateBalloon(WMScreen
*scr
)
61 bPtr
= wmalloc(sizeof(Balloon
));
62 memset(bPtr
, 0, sizeof(Balloon
));
64 bPtr
->view
= W_CreateTopView(scr
);
69 bPtr
->view
->self
= bPtr
;
71 bPtr
->view
->attribFlags
|= CWOverrideRedirect
;
72 bPtr
->view
->attribs
.override_redirect
= True
;
74 bPtr
->textColor
= WMRetainColor(bPtr
->view
->screen
->black
);
76 WMCreateEventHandler(bPtr
->view
, StructureNotifyMask
, handleEvents
, bPtr
);
78 W_ResizeView(bPtr
->view
, DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
79 bPtr
->flags
.alignment
= DEFAULT_ALIGNMENT
;
81 bPtr
->table
= WMCreateHashTable(WMIntHashCallbacks
);
83 bPtr
->delay
= DEFAULT_DELAY
;
85 bPtr
->flags
.enabled
= 1;
93 WMSetBalloonTextAlignment(WMScreen
*scr
, WMAlignment alignment
)
95 scr
->balloon
->flags
.alignment
= alignment
;
101 WMSetBalloonTextForView(char *text
, WMView
*view
)
103 char *oldText
= NULL
;
104 WMScreen
*scr
= view
->screen
;
107 oldText
= WMHashInsert(scr
->balloon
->table
, view
, wstrdup(text
));
109 oldText
= WMHashGet(scr
->balloon
->table
, view
);
111 WMHashRemove(scr
->balloon
->table
, view
);
121 WMSetBalloonFont(WMScreen
*scr
, WMFont
*font
)
123 Balloon
*bPtr
= scr
->balloon
;
125 if (bPtr
->font
!=NULL
)
126 WMReleaseFont(bPtr
->font
);
129 bPtr
->font
= WMRetainFont(font
);
136 WMSetBalloonTextColor(WMScreen
*scr
, WMColor
*color
)
138 Balloon
*bPtr
= scr
->balloon
;
141 WMReleaseColor(bPtr
->textColor
);
143 bPtr
->textColor
= WMRetainColor(color
);
148 WMSetBalloonDelay(WMScreen
*scr
, int delay
)
150 scr
->balloon
->delay
= delay
;
155 WMSetBalloonEnabled(WMScreen
*scr
, Bool flag
)
157 scr
->balloon
->flags
.enabled
= flag
;
159 W_UnmapView(scr
->balloon
->view
);
164 clearNoDelay(void *data
)
166 Balloon
*bPtr
= (Balloon
*)data
;
168 bPtr
->flags
.noDelay
= 0;
169 bPtr
->noDelayTimer
= NULL
;
174 W_BalloonHandleLeaveView(WMView
*view
)
176 Balloon
*bPtr
= view
->screen
->balloon
;
178 if (bPtr
->forWindow
== view
->window
) {
179 if (bPtr
->view
->flags
.mapped
) {
180 W_UnmapView(bPtr
->view
);
181 bPtr
->noDelayTimer
= WMAddTimerHandler(NO_DELAY_DELAY
,
185 WMDeleteTimerHandler(bPtr
->timer
);
189 bPtr
->forWindow
= None
;
195 * botar balao perto do cursor
196 * so mapear balao se o mouse ficar parado pelo delay
201 showBalloon(void *data
)
204 WMView
*view
= (WMView
*)data
;
205 Balloon
*bPtr
= view
->screen
->balloon
;
211 text
= WMHashGet(bPtr
->table
, view
);
215 XTranslateCoordinates(view
->screen
->display
, view
->window
,
216 view
->screen
->rootWin
, 0, 0, &x
, &y
, &foo
);
218 if (!bPtr
->view
->flags
.realized
)
219 W_RealizeView(bPtr
->view
);
221 showText(bPtr
, x
, y
, view
->size
.width
, view
->size
.height
, text
);
223 bPtr
->flags
.noDelay
= 1;
229 W_BalloonHandleEnterView(WMView
*view
)
231 Balloon
*bPtr
= view
->screen
->balloon
;
234 if (!bPtr
->flags
.enabled
)
237 text
= WMHashGet(bPtr
->table
, view
);
239 if (bPtr
->view
->flags
.realized
)
240 W_UnmapView(bPtr
->view
);
246 WMDeleteTimerHandler(bPtr
->timer
);
249 if (bPtr
->noDelayTimer
)
250 WMDeleteTimerHandler(bPtr
->noDelayTimer
);
251 bPtr
->noDelayTimer
= NULL
;
253 bPtr
->forWindow
= view
->window
;
255 if (bPtr
->flags
.noDelay
) {
260 bPtr
->timer
= WMAddTimerHandler(bPtr
->delay
, showBalloon
, view
);
270 #define TLEFT (TOP|LEFT)
271 #define TRIGHT (TOP|RIGHT)
272 #define BLEFT (BOTTOM|LEFT)
273 #define BRIGHT (BOTTOM|RIGHT)
281 drawBalloon(Display
*dpy
, Pixmap pix
, GC gc
, int x
, int y
, int w
, int h
,
287 XFillArc(dpy
, pix
, gc
, x
, y
, rad
, rad
, 90*64, 90*64);
288 XFillArc(dpy
, pix
, gc
, x
, y
+h
-1-rad
, rad
, rad
, 180*64, 90*64);
290 XFillArc(dpy
, pix
, gc
, x
+w
-1-rad
, y
, rad
, rad
, 0*64, 90*64);
291 XFillArc(dpy
, pix
, gc
, x
+w
-1-rad
, y
+h
-1-rad
, rad
, rad
, 270*64, 90*64);
293 XFillRectangle(dpy
, pix
, gc
, x
, y
+rad
/2, w
, h
-rad
);
294 XFillRectangle(dpy
, pix
, gc
, x
+rad
/2, y
, w
-rad
, h
);
298 pt
[1].y
= y
+h
-1+SPACE
;
306 pt
[0].x
= x
+w
-h
+2*h
/16;
307 pt
[1].x
= x
+w
-h
+11*h
/16;
308 pt
[2].x
= x
+w
-h
+7*h
/16;
310 pt
[0].x
= x
+h
-2*h
/16;
311 pt
[1].x
= x
+h
-11*h
/16;
312 pt
[2].x
= x
+h
-7*h
/16;
314 XFillPolygon(dpy
, pix
, gc
, pt
, 3, Convex
, CoordModeOrigin
);
319 makePixmap(WMScreen
*scr
, int width
, int height
, int side
, Pixmap
*mask
)
321 Display
*dpy
= WMScreenDisplay(scr
);
325 WMColor
*black
= WMBlackColor(scr
);
326 WMColor
*white
= WMWhiteColor(scr
);
328 bitmap
= XCreatePixmap(dpy
, scr
->rootWin
, width
+SPACE
, height
+SPACE
, 1);
330 XSetForeground(dpy
, scr
->monoGC
, 0);
331 XFillRectangle(dpy
, bitmap
, scr
->monoGC
, 0, 0, width
+SPACE
, height
+SPACE
);
333 pixmap
= XCreatePixmap(dpy
, scr
->rootWin
, width
+SPACE
, height
+SPACE
,
336 XFillRectangle(dpy
, pixmap
, WMColorGC(black
), 0, 0,
337 width
+SPACE
, height
+SPACE
);
346 XSetForeground(dpy
, scr
->monoGC
, 1);
347 drawBalloon(dpy
, bitmap
, scr
->monoGC
, x
, y
, width
, height
, side
);
348 drawBalloon(dpy
, pixmap
, WMColorGC(white
), x
+1, y
+1, width
-2, height
-2,
353 WMReleaseColor(black
);
354 WMReleaseColor(white
);
361 showText(Balloon
*bPtr
, int x
, int y
, int h
, int w
, char *text
)
363 WMScreen
*scr
= bPtr
->view
->screen
;
364 Display
*dpy
= WMScreenDisplay(scr
);
369 WMFont
*font
= bPtr
->font
? bPtr
->font
: scr
->normalFont
;
381 while (ptr
&& ptr2
) {
382 ptr2
= strchr(ptr
, '\n');
384 w
= WMWidthOfString(font
, ptr
, ptr2
- ptr
);
386 w
= WMWidthOfString(font
, ptr
, strlen(ptr
));
396 textHeight
= W_GetTextHeight(font
, text
, width
, False
);
398 height
= textHeight
+ 4;
405 if (x
+ width
> scr
->rootView
->size
.width
) {
407 bx
= x
- width
+ w
/2;
414 if (bx
+ width
> scr
->rootView
->size
.width
)
415 bx
= scr
->rootView
->size
.width
- width
;
417 if (y
- (height
+ SPACE
) < 0) {
423 by
= y
- (height
+ SPACE
);
426 pixmap
= makePixmap(scr
, width
, height
, side
, &mask
);
428 W_PaintText(bPtr
->view
, pixmap
, font
, 8, ty
+ (height
- textHeight
)/2,
429 width
, bPtr
->flags
.alignment
,
430 WMColorGC(bPtr
->textColor
? bPtr
->textColor
: scr
->black
),
431 False
, text
, strlen(text
));
433 XSetWindowBackgroundPixmap(dpy
, bPtr
->view
->window
, pixmap
);
435 W_ResizeView(bPtr
->view
, width
, height
+SPACE
);
437 XFreePixmap(dpy
, pixmap
);
440 XShapeCombineMask(dpy
, bPtr
->view
->window
, ShapeBounding
, 0, 0, mask
,
443 XFreePixmap(dpy
, mask
);
445 W_MoveView(bPtr
->view
, bx
, by
);
447 W_MapView(bPtr
->view
);
452 handleEvents(XEvent
*event
, void *data
)
454 Balloon
*bPtr
= (Balloon
*)data
;
456 switch (event
->type
) {
458 destroyBalloon(bPtr
);
465 destroyBalloon(Balloon
*bPtr
)
470 e
= WMEnumerateHashTable(bPtr
->table
);
472 while ((str
= WMNextHashEnumeratorItem(&e
))) {
475 WMFreeHashTable(bPtr
->table
);
478 WMReleaseColor(bPtr
->textColor
);
481 WMReleaseFont(bPtr
->font
);