Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wballoon.c
Commit [+]AuthorDateLineData
7f018497 kojima1999-04-24 20:08:20 +00001
558615a8 dan2004-10-30 05:46:37 +00002#include "wconfig.h"
7f018497 kojima1999-04-24 20:08:20 +00003#include "WINGsP.h"
4
95e71d50 id1999-12-29 11:59:30 +00005#ifdef SHAPE
7f018497 kojima1999-04-24 20:08:20 +00006#include <X11/extensions/shape.h>
95e71d50 id1999-12-29 11:59:30 +00007#endif
7f018497 kojima1999-04-24 20:08:20 +00008
7f018497 kojima1999-04-24 20:08:20 +00009typedef struct W_Balloon {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020010 W_View *view;
7f018497 kojima1999-04-24 20:08:20 +000011
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020012 WMHashTable *table; /* Table from view ptr to text */
7f018497 kojima1999-04-24 20:08:20 +000013
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020014 WMColor *backColor;
15 WMColor *textColor;
16 WMFont *font;
7f018497 kojima1999-04-24 20:08:20 +000017
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020018 WMHandlerID timer; /* timer for showing balloon */
6830b057 dan2004-10-12 21:28:27 +000019
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020020 WMHandlerID noDelayTimer;
7f018497 kojima1999-04-24 20:08:20 +000021
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020022 int delay;
7f018497 kojima1999-04-24 20:08:20 +000023
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020024 Window forWindow; /* window for which the balloon
25 * is being show in the moment */
7f018497 kojima1999-04-24 20:08:20 +000026
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020027 struct {
28 WMAlignment alignment:2;
29 unsigned enabled:1;
daeb6d67 kojima1999-04-30 23:31:00 +000030
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020031 unsigned noDelay:1;
32 } flags;
7f018497 kojima1999-04-24 20:08:20 +000033} Balloon;
34
7f018497 kojima1999-04-24 20:08:20 +000035#define DEFAULT_WIDTH 60
36#define DEFAULT_HEIGHT 14
37#define DEFAULT_ALIGNMENT WALeft
38#define DEFAULT_DELAY 500
39
40#define NO_DELAY_DELAY 150
41
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020042static void destroyBalloon(Balloon * bPtr);
7f018497 kojima1999-04-24 20:08:20 +000043
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020044static void handleEvents(XEvent * event, void *data);
7f018497 kojima1999-04-24 20:08:20 +000045
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020046static void showText(Balloon * bPtr, int x, int y, int w, int h, char *text);
7f018497 kojima1999-04-24 20:08:20 +000047
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020048struct W_Balloon *W_CreateBalloon(WMScreen * scr)
7f018497 kojima1999-04-24 20:08:20 +000049{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020050 Balloon *bPtr;
7f018497 kojima1999-04-24 20:08:20 +000051
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020052 bPtr = wmalloc(sizeof(Balloon));
53 memset(bPtr, 0, sizeof(Balloon));
7f018497 kojima1999-04-24 20:08:20 +000054
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020055 bPtr->view = W_CreateUnmanagedTopView(scr);
56 if (!bPtr->view) {
57 wfree(bPtr);
58 return NULL;
59 }
60 bPtr->view->self = bPtr;
7f018497 kojima1999-04-24 20:08:20 +000061
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020062 bPtr->textColor = WMRetainColor(bPtr->view->screen->black);
7f018497 kojima1999-04-24 20:08:20 +000063
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020064 WMCreateEventHandler(bPtr->view, StructureNotifyMask, handleEvents, bPtr);
7f018497 kojima1999-04-24 20:08:20 +000065
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020066 W_ResizeView(bPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
67 bPtr->flags.alignment = DEFAULT_ALIGNMENT;
7f018497 kojima1999-04-24 20:08:20 +000068
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020069 bPtr->table = WMCreateHashTable(WMIntHashCallbacks);
7f018497 kojima1999-04-24 20:08:20 +000070
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020071 bPtr->delay = DEFAULT_DELAY;
7f018497 kojima1999-04-24 20:08:20 +000072
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020073 bPtr->flags.enabled = 1;
7f018497 kojima1999-04-24 20:08:20 +000074
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020075 return bPtr;
7f018497 kojima1999-04-24 20:08:20 +000076}
77
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020078void WMSetBalloonTextAlignment(WMScreen * scr, WMAlignment alignment)
7f018497 kojima1999-04-24 20:08:20 +000079{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020080 scr->balloon->flags.alignment = alignment;
7f018497 kojima1999-04-24 20:08:20 +000081
82}
83
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020084void WMSetBalloonTextForView(char *text, WMView * view)
7f018497 kojima1999-04-24 20:08:20 +000085{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020086 char *oldText = NULL;
87 WMScreen *scr = view->screen;
7f018497 kojima1999-04-24 20:08:20 +000088
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020089 if (text) {
90 oldText = WMHashInsert(scr->balloon->table, view, wstrdup(text));
91 } else {
92 oldText = WMHashGet(scr->balloon->table, view);
7f018497 kojima1999-04-24 20:08:20 +000093
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020094 WMHashRemove(scr->balloon->table, view);
95 }
7f018497 kojima1999-04-24 20:08:20 +000096
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020097 if (oldText) {
98 wfree(oldText);
99 }
7f018497 kojima1999-04-24 20:08:20 +0000100}
101
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200102void WMSetBalloonFont(WMScreen * scr, WMFont * font)
7f018497 kojima1999-04-24 20:08:20 +0000103{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200104 Balloon *bPtr = scr->balloon;
6830b057 dan2004-10-12 21:28:27 +0000105
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200106 if (bPtr->font != NULL)
107 WMReleaseFont(bPtr->font);
7f018497 kojima1999-04-24 20:08:20 +0000108
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200109 if (font)
110 bPtr->font = WMRetainFont(font);
111 else
112 bPtr->font = NULL;
7f018497 kojima1999-04-24 20:08:20 +0000113}
114
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200115void WMSetBalloonTextColor(WMScreen * scr, WMColor * color)
7f018497 kojima1999-04-24 20:08:20 +0000116{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200117 Balloon *bPtr = scr->balloon;
7f018497 kojima1999-04-24 20:08:20 +0000118
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200119 if (bPtr->textColor)
120 WMReleaseColor(bPtr->textColor);
7f018497 kojima1999-04-24 20:08:20 +0000121
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200122 bPtr->textColor = WMRetainColor(color);
7f018497 kojima1999-04-24 20:08:20 +0000123}
124
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200125void WMSetBalloonDelay(WMScreen * scr, int delay)
7f018497 kojima1999-04-24 20:08:20 +0000126{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200127 scr->balloon->delay = delay;
7f018497 kojima1999-04-24 20:08:20 +0000128}
129
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200130void WMSetBalloonEnabled(WMScreen * scr, Bool flag)
7f018497 kojima1999-04-24 20:08:20 +0000131{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200132 scr->balloon->flags.enabled = ((flag == 0) ? 0 : 1);
7f018497 kojima1999-04-24 20:08:20 +0000133
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200134 W_UnmapView(scr->balloon->view);
7f018497 kojima1999-04-24 20:08:20 +0000135}
136
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200137static void clearNoDelay(void *data)
7f018497 kojima1999-04-24 20:08:20 +0000138{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200139 Balloon *bPtr = (Balloon *) data;
7f018497 kojima1999-04-24 20:08:20 +0000140
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200141 bPtr->flags.noDelay = 0;
142 bPtr->noDelayTimer = NULL;
7f018497 kojima1999-04-24 20:08:20 +0000143}
144
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200145void W_BalloonHandleLeaveView(WMView * view)
7f018497 kojima1999-04-24 20:08:20 +0000146{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200147 Balloon *bPtr = view->screen->balloon;
7f018497 kojima1999-04-24 20:08:20 +0000148
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200149 if (bPtr->forWindow == view->window) {
150 if (bPtr->view->flags.mapped) {
151 W_UnmapView(bPtr->view);
152 bPtr->noDelayTimer = WMAddTimerHandler(NO_DELAY_DELAY, clearNoDelay, bPtr);
153 }
154 if (bPtr->timer)
155 WMDeleteTimerHandler(bPtr->timer);
7f018497 kojima1999-04-24 20:08:20 +0000156
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200157 bPtr->timer = NULL;
7f018497 kojima1999-04-24 20:08:20 +0000158
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200159 bPtr->forWindow = None;
160 }
7f018497 kojima1999-04-24 20:08:20 +0000161}
162
8f68cfd8 kojima1999-04-29 23:05:16 +0000163/*
164 * botar balao perto do cursor
165 * so mapear balao se o mouse ficar parado pelo delay
6830b057 dan2004-10-12 21:28:27 +0000166 *
8f68cfd8 kojima1999-04-29 23:05:16 +0000167 */
168
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200169static void showBalloon(void *data)
7f018497 kojima1999-04-24 20:08:20 +0000170{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200171 char *text;
172 WMView *view = (WMView *) data;
173 Balloon *bPtr = view->screen->balloon;
174 int x, y;
175 Window foo;
7f018497 kojima1999-04-24 20:08:20 +0000176
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200177 bPtr->timer = NULL;
7f018497 kojima1999-04-24 20:08:20 +0000178
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200179 text = WMHashGet(bPtr->table, view);
180 if (!text)
181 return;
7f018497 kojima1999-04-24 20:08:20 +0000182
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200183 XTranslateCoordinates(view->screen->display, view->window, view->screen->rootWin, 0, 0, &x, &y, &foo);
7f018497 kojima1999-04-24 20:08:20 +0000184
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200185 if (!bPtr->view->flags.realized)
186 W_RealizeView(bPtr->view);
7f018497 kojima1999-04-24 20:08:20 +0000187
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200188 showText(bPtr, x, y, view->size.width, view->size.height, text);
7f018497 kojima1999-04-24 20:08:20 +0000189
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200190 bPtr->flags.noDelay = 1;
7f018497 kojima1999-04-24 20:08:20 +0000191}
192
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200193void W_BalloonHandleEnterView(WMView * view)
7f018497 kojima1999-04-24 20:08:20 +0000194{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200195 Balloon *bPtr = view->screen->balloon;
196 char *text;
7f018497 kojima1999-04-24 20:08:20 +0000197
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200198 if (!bPtr->flags.enabled)
199 return;
7f018497 kojima1999-04-24 20:08:20 +0000200
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200201 text = WMHashGet(bPtr->table, view);
202 if (!text) {
203 if (bPtr->view->flags.realized)
204 W_UnmapView(bPtr->view);
7f018497 kojima1999-04-24 20:08:20 +0000205
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200206 return;
207 }
7f018497 kojima1999-04-24 20:08:20 +0000208
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200209 if (bPtr->timer)
210 WMDeleteTimerHandler(bPtr->timer);
211 bPtr->timer = NULL;
7f018497 kojima1999-04-24 20:08:20 +0000212
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200213 if (bPtr->noDelayTimer)
214 WMDeleteTimerHandler(bPtr->noDelayTimer);
215 bPtr->noDelayTimer = NULL;
7f018497 kojima1999-04-24 20:08:20 +0000216
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200217 bPtr->forWindow = view->window;
a205d1f5 kojima1999-04-27 01:38:09 +0000218
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200219 if (bPtr->flags.noDelay) {
220 bPtr->timer = NULL;
7f018497 kojima1999-04-24 20:08:20 +0000221
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200222 showBalloon(view);
223 } else {
224 bPtr->timer = WMAddTimerHandler(bPtr->delay, showBalloon, view);
225 }
7f018497 kojima1999-04-24 20:08:20 +0000226}
227
7f018497 kojima1999-04-24 20:08:20 +0000228#define TOP 0
229#define BOTTOM 1
230#define LEFT 0
231#define RIGHT 2
232
233#define TLEFT (TOP|LEFT)
234#define TRIGHT (TOP|RIGHT)
235#define BLEFT (BOTTOM|LEFT)
236#define BRIGHT (BOTTOM|RIGHT)
237
7f018497 kojima1999-04-24 20:08:20 +0000238#define SPACE 12
239
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200240static void drawBalloon(WMScreen * scr, Pixmap bitmap, Pixmap pix, int x, int y, int w, int h, int side)
7f018497 kojima1999-04-24 20:08:20 +0000241{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200242 Display *dpy = scr->display;
243 WMColor *white = WMWhiteColor(scr);
244 WMColor *black = WMBlackColor(scr);
245 GC bgc = scr->monoGC;
246 GC gc = WMColorGC(white);
247 int rad = h * 3 / 10;
248 XPoint pt[3], ipt[3];
249 int w1;
250
251 /* outline */
252 XSetForeground(dpy, bgc, 1);
253
254 XFillArc(dpy, bitmap, bgc, x, y, rad, rad, 90 * 64, 90 * 64);
255 XFillArc(dpy, bitmap, bgc, x, y + h - 1 - rad, rad, rad, 180 * 64, 90 * 64);
256
257 XFillArc(dpy, bitmap, bgc, x + w - 1 - rad, y, rad, rad, 0 * 64, 90 * 64);
258 XFillArc(dpy, bitmap, bgc, x + w - 1 - rad, y + h - 1 - rad, rad, rad, 270 * 64, 90 * 64);
259
260 XFillRectangle(dpy, bitmap, bgc, x, y + rad / 2, w, h - rad);
261 XFillRectangle(dpy, bitmap, bgc, x + rad / 2, y, w - rad, h);
262
263 /* interior */
264 XFillArc(dpy, pix, gc, x + 1, y + 1, rad, rad, 90 * 64, 90 * 64);
265 XFillArc(dpy, pix, gc, x + 1, y + h - 2 - rad, rad, rad, 180 * 64, 90 * 64);
266
267 XFillArc(dpy, pix, gc, x + w - 2 - rad, y + 1, rad, rad, 0 * 64, 90 * 64);
268 XFillArc(dpy, pix, gc, x + w - 2 - rad, y + h - 2 - rad, rad, rad, 270 * 64, 90 * 64);
269
270 XFillRectangle(dpy, pix, gc, x + 1, y + 1 + rad / 2, w - 2, h - 2 - rad);
271 XFillRectangle(dpy, pix, gc, x + 1 + rad / 2, y + 1, w - 2 - rad, h - 2);
272
273 if (side & BOTTOM) {
274 pt[0].y = y + h - 1;
275 pt[1].y = y + h - 1 + SPACE;
276 pt[2].y = y + h - 1;
277 ipt[0].y = pt[0].y - 1;
278 ipt[1].y = pt[1].y - 1;
279 ipt[2].y = pt[2].y - 1;
280 } else {
281 pt[0].y = y;
282 pt[1].y = y - SPACE;
283 pt[2].y = y;
284 ipt[0].y = pt[0].y + 1;
285 ipt[1].y = pt[1].y + 1;
286 ipt[2].y = pt[2].y + 1;
287 }
288
289 /*w1 = WMAX(h, 24); */
290 w1 = WMAX(h, 21);
291
292 if (side & RIGHT) {
293 pt[0].x = x + w - w1 + 2 * w1 / 16;
294 pt[1].x = x + w - w1 + 11 * w1 / 16;
295 pt[2].x = x + w - w1 + 7 * w1 / 16;
296 ipt[0].x = x + 1 + w - w1 + 2 * (w1 - 1) / 16;
297 ipt[1].x = x + 1 + w - w1 + 11 * (w1 - 1) / 16;
298 ipt[2].x = x + 1 + w - w1 + 7 * (w1 - 1) / 16;
299 /*ipt[0].x = pt[0].x+1;
300 ipt[1].x = pt[1].x;
301 ipt[2].x = pt[2].x; */
302 } else {
303 pt[0].x = x + w1 - 2 * w1 / 16;
304 pt[1].x = x + w1 - 11 * w1 / 16;
305 pt[2].x = x + w1 - 7 * w1 / 16;
306 ipt[0].x = x - 1 + w1 - 2 * (w1 - 1) / 16;
307 ipt[1].x = x - 1 + w1 - 11 * (w1 - 1) / 16;
308 ipt[2].x = x - 1 + w1 - 7 * (w1 - 1) / 16;
309 /*ipt[0].x = pt[0].x-1;
310 ipt[1].x = pt[1].x;
311 ipt[2].x = pt[2].x; */
312 }
313
314 XFillPolygon(dpy, bitmap, bgc, pt, 3, Convex, CoordModeOrigin);
315 XFillPolygon(dpy, pix, gc, ipt, 3, Convex, CoordModeOrigin);
316
317 /* fix outline */
318 XDrawLines(dpy, pix, WMColorGC(black), pt, 3, CoordModeOrigin);
319 if (side & RIGHT) {
320 pt[0].x++;
321 pt[2].x--;
322 } else {
323 pt[0].x--;
324 pt[2].x++;
325 }
326 XDrawLines(dpy, pix, WMColorGC(black), pt, 3, CoordModeOrigin);
327
328 WMReleaseColor(white);
329 WMReleaseColor(black);
7f018497 kojima1999-04-24 20:08:20 +0000330}
331
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200332static Pixmap makePixmap(WMScreen * scr, int width, int height, int side, Pixmap * mask)
7f018497 kojima1999-04-24 20:08:20 +0000333{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200334 Display *dpy = WMScreenDisplay(scr);
335 Pixmap bitmap;
336 Pixmap pixmap;
337 int x, y;
338 WMColor *black = WMBlackColor(scr);
7f018497 kojima1999-04-24 20:08:20 +0000339
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200340 bitmap = XCreatePixmap(dpy, scr->rootWin, width + SPACE, height + SPACE, 1);
7f018497 kojima1999-04-24 20:08:20 +0000341
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200342 XSetForeground(dpy, scr->monoGC, 0);
343 XFillRectangle(dpy, bitmap, scr->monoGC, 0, 0, width + SPACE, height + SPACE);
7f018497 kojima1999-04-24 20:08:20 +0000344
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200345 pixmap = XCreatePixmap(dpy, scr->rootWin, width + SPACE, height + SPACE, scr->depth);
7f018497 kojima1999-04-24 20:08:20 +0000346
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200347 XFillRectangle(dpy, pixmap, WMColorGC(black), 0, 0, width + SPACE, height + SPACE);
7f018497 kojima1999-04-24 20:08:20 +0000348
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200349 if (side & BOTTOM) {
350 y = 0;
351 } else {
352 y = SPACE;
353 }
354 x = 0;
7f018497 kojima1999-04-24 20:08:20 +0000355
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200356 drawBalloon(scr, bitmap, pixmap, x, y, width, height, side);
7f018497 kojima1999-04-24 20:08:20 +0000357
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200358 *mask = bitmap;
7f018497 kojima1999-04-24 20:08:20 +0000359
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200360 WMReleaseColor(black);
7f018497 kojima1999-04-24 20:08:20 +0000361
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200362 return pixmap;
7f018497 kojima1999-04-24 20:08:20 +0000363}
364
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200365static void showText(Balloon * bPtr, int x, int y, int w, int h, char *text)
7f018497 kojima1999-04-24 20:08:20 +0000366{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200367 WMScreen *scr = bPtr->view->screen;
368 Display *dpy = WMScreenDisplay(scr);
369 int width;
370 int height;
371 Pixmap pixmap;
372 Pixmap mask;
373 WMFont *font = bPtr->font ? bPtr->font : scr->normalFont;
374 int textHeight;
375 int side = 0;
376 int ty;
377 int bx, by;
378
379 {
380 int w;
381 char *ptr, *ptr2;
382
383 ptr2 = ptr = text;
384 width = 0;
385 while (ptr && ptr2) {
386 ptr2 = strchr(ptr, '\n');
387 if (ptr2) {
388 w = WMWidthOfString(font, ptr, ptr2 - ptr);
389 } else {
390 w = WMWidthOfString(font, ptr, strlen(ptr));
391 }
392 if (w > width)
393 width = w;
394 ptr = ptr2 + 1;
395 }
396 }
397
398 width += 16;
399
400 textHeight = W_GetTextHeight(font, text, width, False);
401
402 height = textHeight + 4;
403
404 if (height < 16)
405 height = 16;
406 if (width < height)
407 width = height;
408
409 if (x + width > scr->rootView->size.width) {
410 side = RIGHT;
411 bx = x - width + w / 2;
412 if (bx < 0)
413 bx = 0;
414 } else {
415 side = LEFT;
416 bx = x + w / 2;
417 }
418 if (bx + width > scr->rootView->size.width)
419 bx = scr->rootView->size.width - width;
420
421 if (y - (height + SPACE) < 0) {
422 side |= TOP;
423 by = y + h - 1;
424 ty = SPACE;
425 } else {
426 side |= BOTTOM;
427 by = y - (height + SPACE);
428 ty = 0;
429 }
430 pixmap = makePixmap(scr, width, height, side, &mask);
431
432 W_PaintText(bPtr->view, pixmap, font, 8, ty + (height - textHeight) / 2,
433 width, bPtr->flags.alignment,
434 bPtr->textColor ? bPtr->textColor : scr->black, False, text, strlen(text));
435
436 XSetWindowBackgroundPixmap(dpy, bPtr->view->window, pixmap);
437
438 W_ResizeView(bPtr->view, width, height + SPACE);
439
440 XFreePixmap(dpy, pixmap);
7f018497 kojima1999-04-24 20:08:20 +0000441
95e71d50 id1999-12-29 11:59:30 +0000442#ifdef SHAPE
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200443 XShapeCombineMask(dpy, bPtr->view->window, ShapeBounding, 0, 0, mask, ShapeSet);
95e71d50 id1999-12-29 11:59:30 +0000444#endif
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200445 XFreePixmap(dpy, mask);
7f018497 kojima1999-04-24 20:08:20 +0000446
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200447 W_MoveView(bPtr->view, bx, by);
7f018497 kojima1999-04-24 20:08:20 +0000448
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200449 W_MapView(bPtr->view);
7f018497 kojima1999-04-24 20:08:20 +0000450}
451
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200452static void handleEvents(XEvent * event, void *data)
7f018497 kojima1999-04-24 20:08:20 +0000453{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200454 Balloon *bPtr = (Balloon *) data;
7f018497 kojima1999-04-24 20:08:20 +0000455
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200456 switch (event->type) {
457 case DestroyNotify:
458 destroyBalloon(bPtr);
459 break;
460 }
7f018497 kojima1999-04-24 20:08:20 +0000461}
462
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200463static void destroyBalloon(Balloon * bPtr)
7f018497 kojima1999-04-24 20:08:20 +0000464{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200465 WMHashEnumerator e;
466 char *str;
7f018497 kojima1999-04-24 20:08:20 +0000467
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200468 e = WMEnumerateHashTable(bPtr->table);
7f018497 kojima1999-04-24 20:08:20 +0000469
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200470 while ((str = WMNextHashEnumeratorItem(&e))) {
471 wfree(str);
472 }
473 WMFreeHashTable(bPtr->table);
7f018497 kojima1999-04-24 20:08:20 +0000474
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200475 if (bPtr->textColor)
476 WMReleaseColor(bPtr->textColor);
7f018497 kojima1999-04-24 20:08:20 +0000477
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200478 if (bPtr->font)
479 WMReleaseFont(bPtr->font);
7f018497 kojima1999-04-24 20:08:20 +0000480
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200481 wfree(bPtr);
7f018497 kojima1999-04-24 20:08:20 +0000482}