Mercurial > hg > xemacs-beta
annotate src/balloon_help.c @ 5887:6eca500211f4
Prototype for X509_check_host() has changed, detect this in configure.ac
ChangeLog addition:
2015-04-09 Aidan Kehoe <kehoea@parhasard.net>
* configure.ac:
If X509_check_host() is available, check the number of arguments
it takes. Don't use it if it takes any number of arguments other
than five. Also don't use it if <openssl/x509v3.h> does not
declare it, since if that is so there is no portable way to tell
how many arguments it should take, and so we would end up smashing
the stack.
* configure: Regenerate.
src/ChangeLog addition:
2015-04-09 Aidan Kehoe <kehoea@parhasard.net>
* tls.c:
#include <openssl/x509v3.h> for its prototype for
X509_check_host().
* tls.c (tls_open):
Pass the new fifth argument to X509_check_host().
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Thu, 09 Apr 2015 14:27:02 +0100 |
parents | 308d34e9f07d |
children |
rev | line source |
---|---|
428 | 1 /* Balloon Help |
2 Copyright (c) 1997 Douglas Keller | |
3 | |
4 This file is part of XEmacs. | |
5 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
2286
diff
changeset
|
6 XEmacs is free software: you can redistribute it and/or modify it |
428 | 7 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
2286
diff
changeset
|
8 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
2286
diff
changeset
|
9 option) any later version. |
428 | 10 |
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
2286
diff
changeset
|
17 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 18 |
19 /* Synched up with: Not in FSF. */ | |
20 | |
771 | 21 /* !!#### Needs to be Mule-ized. */ |
22 | |
428 | 23 /* |
24 * Balloon Help | |
25 * | |
26 * Version: 1.337 (Sun Apr 13 04:52:10 1997) | |
27 * | |
28 * Written by Douglas Keller <dkeller@vnet.ibm.com> | |
29 * | |
30 * | |
31 */ | |
32 | |
33 #include <config.h> | |
34 #include <string.h> | |
35 #include <stdlib.h> | |
36 #include <stdio.h> | |
37 #include <assert.h> | |
38 | |
39 #include <X11/Xlib.h> | |
40 #include <X11/Xutil.h> | |
41 #include <X11/extensions/shape.h> | |
42 | |
2286 | 43 #include "compiler.h" |
428 | 44 #include "xintrinsic.h" |
45 | |
46 #include "balloon_help.h" | |
47 | |
442 | 48 #ifndef max |
428 | 49 #define max(x,y) (x>y?x:y) |
50 #endif | |
51 | |
52 #undef bool | |
53 #define bool int | |
54 | |
55 #define MARGIN_WIDTH 4 | |
56 #define POINTER_OFFSET 8 | |
57 #define BORDER_WIDTH 2 | |
58 #define BORDER_WIDTH_HALF 1 | |
59 | |
60 #define CONE_HEIGHT 20 | |
61 #define CONE_WIDTH 50 | |
62 | |
63 #define SHAPE_CONE_TOP (1<<0) | |
64 #define SHAPE_CONE_LEFT (1<<1) | |
65 #define SHAPE_CONE_TOP_LEFT (SHAPE_CONE_TOP | SHAPE_CONE_LEFT) | |
66 #define SHAPE_CONE_TOP_RIGHT (SHAPE_CONE_TOP) | |
67 #define SHAPE_CONE_BOTTOM_LEFT (SHAPE_CONE_LEFT) | |
68 #define SHAPE_CONE_BOTTOM_RIGHT (0) | |
69 #define SHAPE_CONE_FREE (-1) | |
70 | |
71 | |
72 static Display* b_dpy; | |
73 | |
74 static XFontStruct* b_fontStruct; | |
75 static GC b_gc; | |
76 | |
77 static GC b_shineGC; | |
78 static GC b_shadowGC; | |
79 | |
80 static Window b_win; | |
81 static bool b_winMapped; | |
82 | |
83 static Pixmap b_mask; | |
84 static int b_maskWidth, b_maskHeight; | |
85 static GC b_maskGC; | |
86 | |
442 | 87 static const char* b_text; |
428 | 88 static int b_width, b_height; |
89 | |
90 static XtIntervalId b_timer; | |
91 static unsigned long b_delay; | |
92 | |
93 static int b_screenWidth, b_screenHeight; | |
94 | |
95 static int b_lastShape; | |
96 | |
97 /*============================================================================ | |
98 | |
99 ============================================================================*/ | |
100 | |
101 static GC | |
102 create_gc (Display* dpy, Window win, unsigned long fg, unsigned long bg, | |
103 XFontStruct* fontStruct) | |
104 { | |
105 XGCValues gcv; | |
106 unsigned long mask; | |
107 | |
108 gcv.foreground = fg; | |
109 gcv.background = bg; | |
110 gcv.font = fontStruct->fid; | |
111 gcv.join_style = JoinMiter; | |
112 gcv.line_width = BORDER_WIDTH; | |
113 | |
114 mask = GCFont | GCBackground | GCForeground | GCJoinStyle | GCLineWidth; | |
115 | |
116 return XCreateGC (dpy, win, mask, &gcv); | |
117 } | |
118 | |
119 static void | |
120 destroy_gc (Display* dpy, GC gc) | |
121 { | |
122 if (gc) | |
123 { | |
124 XFreeGC (dpy, gc); | |
125 } | |
126 } | |
127 | |
128 /*============================================================================ | |
129 | |
130 ============================================================================*/ | |
131 | |
132 static Window | |
133 create_window (Display* dpy, unsigned long bg) | |
134 { | |
135 Window win; | |
136 XSetWindowAttributes attr; | |
137 unsigned long attr_mask; | |
138 | |
139 attr_mask = CWOverrideRedirect | CWBackPixel | CWSaveUnder; | |
140 attr.override_redirect = True; | |
141 attr.background_pixel = bg; | |
142 attr.save_under = True; | |
143 | |
144 win = | |
145 XCreateWindow (dpy, | |
146 DefaultRootWindow (dpy), | |
147 0, 0, 1, 1, | |
148 0, | |
149 CopyFromParent, InputOutput, CopyFromParent, | |
150 attr_mask, &attr); | |
151 | |
152 XSelectInput (dpy, win, | |
153 SubstructureRedirectMask | | |
154 SubstructureNotifyMask | | |
155 ExposureMask | | |
156 EnterWindowMask | | |
157 LeaveWindowMask); | |
158 return win; | |
159 } | |
160 | |
161 static void | |
162 destroy_window (Display* dpy, Window win) | |
163 { | |
164 if (win) | |
165 { | |
166 XDestroyWindow (dpy, win); | |
167 } | |
168 } | |
169 | |
170 /*============================================================================ | |
171 | |
172 ============================================================================*/ | |
173 | |
174 static void | |
175 get_pointer_xy (Display* dpy, int* x_return, int* y_return) | |
176 { | |
177 int dummy; | |
178 unsigned int mask; | |
179 Window dummy_win; | |
180 | |
181 XQueryPointer (dpy, RootWindow(dpy, DefaultScreen(dpy)), &dummy_win, &dummy_win, | |
182 x_return, y_return, &dummy, &dummy, &mask); | |
183 } | |
184 | |
185 /*============================================================================ | |
186 | |
187 ============================================================================*/ | |
188 | |
189 static void | |
190 create_pixmap_mask (int width, int height) | |
191 { | |
192 b_maskWidth = width; | |
193 b_maskHeight = height; | |
194 b_mask = XCreatePixmap (b_dpy, b_win, width, height, 1); | |
195 } | |
196 | |
197 static void | |
198 destroy_pixmap_mask(void) | |
199 { | |
200 XFreePixmap (b_dpy, b_mask); | |
201 } | |
202 | |
203 static void | |
204 grow_pixmap_mask (int width, int height) | |
205 { | |
206 if (width > b_maskWidth || height > b_maskHeight) | |
207 { | |
208 destroy_pixmap_mask (); | |
209 create_pixmap_mask (width, height); | |
210 } | |
211 } | |
212 | |
213 /*============================================================================ | |
214 | |
215 ============================================================================*/ | |
216 | |
217 static void | |
442 | 218 text_extent (XFontStruct* fontStruct, const char* text, int len, |
428 | 219 int* width, int* height) |
220 { | |
221 XCharStruct extent; | |
222 int dummy; | |
223 | |
224 XTextExtents (fontStruct, text, len, &dummy, &dummy, &dummy, &extent); | |
225 | |
226 *width = extent.width; | |
227 *height = fontStruct->ascent + fontStruct->descent; | |
228 } | |
229 | |
230 static void | |
2286 | 231 get_text_size (Display* UNUSED (dpy), XFontStruct* fontStruct, |
232 const char* text, int* max_width, int* max_height) | |
428 | 233 { |
234 int width; | |
235 int height; | |
442 | 236 const char* start; |
237 const char* end; | |
428 | 238 |
239 *max_width = *max_height = 0; | |
240 | |
241 start = text; | |
242 while ((end = strchr(start, '\n'))) | |
243 { | |
244 text_extent (fontStruct, start, end - start, &width, &height); | |
245 *max_width = max (width, *max_width); | |
246 *max_height += height; | |
247 | |
248 start = end + 1; | |
249 } | |
250 text_extent (fontStruct, start, strlen (start), &width, &height); | |
251 *max_width = max (width, *max_width); | |
252 *max_height += height; | |
253 | |
254 /* Min width */ | |
255 *max_width = max (*max_width, CONE_WIDTH / 2 * 3); | |
256 | |
257 } | |
258 | |
259 static void | |
260 draw_text (Display* dpy, Window win, GC gc, XFontStruct* fontStruct, | |
442 | 261 int x, int y, const char* text) |
428 | 262 { |
442 | 263 const char* start; |
264 const char* end; | |
428 | 265 int font_height; |
266 | |
267 y += fontStruct->ascent; | |
268 | |
269 font_height = fontStruct->ascent + fontStruct->descent; | |
270 | |
271 start = text; | |
272 while ((end = strchr(start, '\n'))) | |
273 { | |
274 XDrawString (dpy, win, gc, x, y, start, end - start); | |
275 | |
276 start = end + 1; | |
277 y += font_height; | |
278 } | |
279 XDrawString (dpy, win, gc, x, y, start, strlen (start)); | |
280 } | |
281 | |
282 /*============================================================================ | |
283 | |
284 ============================================================================*/ | |
285 | |
286 static int | |
287 get_shape (int last_shape, int x, int y, int width, int height, | |
288 int screen_width, int screen_height) | |
289 { | |
290 /* Can we use last_shape? */ | |
291 if (((last_shape == SHAPE_CONE_TOP_LEFT) && | |
292 (x + width < screen_width) && (y + height < screen_height)) || | |
293 ((last_shape == SHAPE_CONE_TOP_RIGHT) && | |
294 (x - width > 0) && (y + height < screen_height)) || | |
295 ((last_shape == SHAPE_CONE_BOTTOM_LEFT) && | |
296 (x + width < screen_width) && (y - height > 0)) || | |
297 ((last_shape == SHAPE_CONE_BOTTOM_RIGHT) && | |
298 (x - width > 0) && (y - height > 0))) | |
299 return last_shape; | |
300 | |
301 /* Try to pick a shape that will not get changed, | |
302 e.g. if top left quadrant, top_left */ | |
303 return (x < screen_width / 2) ? | |
304 (y < screen_height / 2 ? SHAPE_CONE_TOP_LEFT: SHAPE_CONE_BOTTOM_LEFT) : | |
305 (y < screen_height / 2 ? SHAPE_CONE_TOP_RIGHT: SHAPE_CONE_BOTTOM_RIGHT); | |
306 } | |
307 | |
308 static void | |
2286 | 309 make_mask (int shape, int UNUSED (x), int UNUSED (y), int width, int height) |
428 | 310 { |
311 XPoint cone[ 3 ]; | |
312 | |
313 grow_pixmap_mask (width, height); | |
314 | |
315 /* Clear mask */ | |
316 XSetForeground (b_dpy, b_maskGC, 0); | |
317 XFillRectangle (b_dpy, b_mask, b_maskGC, | |
318 0, 0, width, height); | |
319 | |
320 /* Enable text area */ | |
321 XSetForeground (b_dpy, b_maskGC, 1); | |
322 XFillRectangle (b_dpy, b_mask, b_maskGC, 0, | |
323 shape & SHAPE_CONE_TOP ? CONE_HEIGHT : 0, width, height - CONE_HEIGHT); | |
324 | |
325 /* Enable for cone area */ | |
326 cone[0].x = (shape & SHAPE_CONE_LEFT) ? CONE_WIDTH / 2 : width - (CONE_WIDTH / 2); | |
327 cone[0].y = (shape & SHAPE_CONE_TOP) ? CONE_HEIGHT : height - CONE_HEIGHT; | |
328 cone[1].x = (shape & SHAPE_CONE_LEFT) ? 0 : width; | |
329 cone[1].y = (shape & SHAPE_CONE_TOP) ? 0 : height; | |
330 cone[2].x = (shape & SHAPE_CONE_LEFT) ? CONE_WIDTH : width - CONE_WIDTH; | |
331 cone[2].y = (shape & SHAPE_CONE_TOP) ? CONE_HEIGHT : height - CONE_HEIGHT; | |
332 | |
333 XFillPolygon (b_dpy, b_mask, b_maskGC, cone, 3, Nonconvex, CoordModeOrigin); | |
334 | |
335 } | |
336 | |
337 static void | |
2286 | 338 show_help (XtPointer UNUSED (data), XtIntervalId* id) |
428 | 339 { |
340 int x, y; | |
341 int shape; | |
342 XPoint border[ 3 ]; | |
343 | |
344 if (id == NULL || ((id && b_timer) && b_text)) | |
345 { | |
346 b_timer = None; | |
347 | |
348 /* size */ | |
349 get_text_size (b_dpy, b_fontStruct, b_text, &b_width, &b_height); | |
350 b_width += 2 * MARGIN_WIDTH + 2 * BORDER_WIDTH; | |
351 b_height += 2 * MARGIN_WIDTH + 2 * BORDER_WIDTH + CONE_HEIGHT; | |
352 | |
353 /* origin */ | |
354 get_pointer_xy (b_dpy, &x, &y); | |
355 | |
356 /* guess at shape */ | |
357 shape = get_shape(b_lastShape, x, y, b_width, b_height, | |
358 b_screenWidth, b_screenHeight); | |
359 | |
360 x += (shape & SHAPE_CONE_LEFT) ? POINTER_OFFSET : -POINTER_OFFSET; | |
361 y += (shape & SHAPE_CONE_TOP) ? POINTER_OFFSET : -POINTER_OFFSET; | |
362 | |
363 /* make sure it is still ok with offset */ | |
364 shape = get_shape (shape, x, y, b_width, b_height, b_screenWidth, b_screenHeight); | |
365 | |
366 b_lastShape = shape; | |
367 | |
368 make_mask (shape, x, y, b_width, b_height); | |
369 | |
370 XShapeCombineMask (b_dpy, b_win, ShapeBounding, 0, 0, b_mask, ShapeSet); | |
371 | |
372 XMoveResizeWindow(b_dpy, b_win, | |
373 (shape & SHAPE_CONE_LEFT) ? x : x - b_width, | |
374 (shape & SHAPE_CONE_TOP) ? y : y - b_height, | |
375 b_width, b_height); | |
376 | |
377 XClearWindow (b_dpy, b_win); | |
378 | |
379 XMapRaised (b_dpy, b_win); | |
380 b_winMapped = True; | |
381 | |
382 draw_text (b_dpy, b_win, b_gc, b_fontStruct, | |
383 BORDER_WIDTH + MARGIN_WIDTH, | |
384 BORDER_WIDTH + MARGIN_WIDTH + ((shape & SHAPE_CONE_TOP) ? CONE_HEIGHT : 0), | |
385 b_text); | |
386 | |
387 /* 3d border */ | |
388 /* shine- top left */ | |
389 border[0].x = 0 + BORDER_WIDTH_HALF; | |
390 border[0].y = ((shape & SHAPE_CONE_TOP) ? b_height : b_height - CONE_HEIGHT) - BORDER_WIDTH_HALF; | |
391 border[1].x = 0 + BORDER_WIDTH_HALF; | |
392 border[1].y = ((shape & SHAPE_CONE_TOP) ? CONE_HEIGHT : 0) + BORDER_WIDTH_HALF; | |
393 border[2].x = b_width - BORDER_WIDTH_HALF; | |
394 border[2].y = border[1].y; | |
395 XDrawLines (b_dpy, b_win, b_shineGC, border, 3, CoordModeOrigin); | |
396 | |
397 /* shadow- bottom right */ | |
398 border[0].x = 0 + BORDER_WIDTH_HALF; | |
399 border[0].y = ((shape & SHAPE_CONE_TOP) ? b_height : b_height - CONE_HEIGHT) - BORDER_WIDTH_HALF; | |
400 border[1].x = b_width - BORDER_WIDTH_HALF; | |
401 border[1].y = border[0].y; | |
402 border[2].x = b_width - BORDER_WIDTH_HALF; | |
403 border[2].y = ((shape & SHAPE_CONE_TOP) ? CONE_HEIGHT : 0) + BORDER_WIDTH_HALF; | |
404 XDrawLines (b_dpy, b_win, b_shadowGC, border, 3, CoordModeOrigin); | |
405 | |
406 /* cone */ | |
407 if (SHAPE_CONE_TOP_LEFT == shape) | |
408 { | |
409 XClearArea (b_dpy, b_win, | |
410 CONE_WIDTH / 2 + BORDER_WIDTH, | |
411 CONE_HEIGHT, | |
412 CONE_WIDTH / 2 - BORDER_WIDTH, | |
413 BORDER_WIDTH, False); | |
414 XDrawLine (b_dpy, b_win, b_shadowGC, | |
415 0, | |
416 0, | |
417 CONE_WIDTH / 2 + BORDER_WIDTH_HALF, | |
418 CONE_HEIGHT); | |
419 XDrawLine (b_dpy, b_win, b_shineGC, | |
420 0, | |
421 0, | |
422 CONE_WIDTH - BORDER_WIDTH_HALF, | |
423 CONE_HEIGHT); | |
424 } | |
425 else if (SHAPE_CONE_TOP_RIGHT == shape) | |
426 { | |
427 XClearArea (b_dpy, b_win, | |
428 b_width - CONE_WIDTH + BORDER_WIDTH, | |
429 CONE_HEIGHT, | |
430 CONE_WIDTH / 2 - BORDER_WIDTH, | |
431 BORDER_WIDTH, False); | |
432 XDrawLine (b_dpy, b_win, b_shadowGC, | |
433 b_width, | |
434 0, | |
435 b_width - CONE_WIDTH / 2 - BORDER_WIDTH_HALF, | |
436 CONE_HEIGHT); | |
437 XDrawLine (b_dpy, b_win, b_shineGC, | |
438 b_width, | |
439 0, | |
440 b_width - CONE_WIDTH + BORDER_WIDTH_HALF, | |
441 CONE_HEIGHT); | |
442 } | |
443 else if (SHAPE_CONE_BOTTOM_LEFT == shape) | |
444 { | |
445 XClearArea (b_dpy, b_win, | |
446 CONE_WIDTH / 2 + BORDER_WIDTH, | |
447 b_height - CONE_HEIGHT - BORDER_WIDTH, | |
448 CONE_WIDTH / 2 - BORDER_WIDTH, | |
449 BORDER_WIDTH, False); | |
450 XDrawLine (b_dpy, b_win, b_shadowGC, | |
451 0, | |
452 b_height - 1, | |
453 CONE_WIDTH, | |
454 b_height - 1 - CONE_HEIGHT); | |
455 XDrawLine (b_dpy, b_win, b_shineGC, | |
456 0, | |
457 b_height - 1, | |
458 CONE_WIDTH / 2 + BORDER_WIDTH, | |
459 b_height - 1 - CONE_HEIGHT); | |
460 } | |
461 else if (SHAPE_CONE_BOTTOM_RIGHT == shape) | |
462 { | |
463 XClearArea (b_dpy, b_win, | |
464 b_width - 1 - CONE_WIDTH + BORDER_WIDTH, | |
465 b_height - CONE_HEIGHT - BORDER_WIDTH, | |
466 CONE_WIDTH / 2 - BORDER_WIDTH - 1, | |
467 BORDER_WIDTH, False); | |
468 XDrawLine (b_dpy, b_win, b_shadowGC, | |
469 b_width - 1, | |
470 b_height - 1, | |
471 b_width - 1 - CONE_WIDTH, | |
472 b_height - 1 - CONE_HEIGHT); | |
473 XDrawLine (b_dpy, b_win, b_shineGC, | |
474 b_width - 1, | |
475 b_height - 1, | |
476 b_width - 1 - CONE_WIDTH / 2 - BORDER_WIDTH, | |
477 b_height - 1 - CONE_HEIGHT); | |
478 } | |
479 } | |
480 | |
481 } | |
482 | |
483 /*============================================================================ | |
484 | |
485 ============================================================================*/ | |
486 | |
487 static void | |
488 balloon_help_destroy (void) | |
489 { | |
490 assert (b_dpy != NULL); | |
491 b_dpy = NULL; | |
492 | |
493 destroy_window (b_dpy, b_win); | |
494 destroy_gc (b_dpy, b_gc); | |
495 | |
496 destroy_gc (b_dpy, b_shineGC); | |
497 destroy_gc (b_dpy, b_shadowGC); | |
498 | |
499 destroy_pixmap_mask (); | |
500 destroy_gc (b_dpy, b_maskGC); | |
501 | |
502 if (b_timer) XtRemoveTimeOut (b_timer); | |
503 } | |
504 | |
505 void | |
506 balloon_help_create (Display* dpy, | |
507 Pixel fg, Pixel bg, Pixel shine, Pixel shadow, | |
508 XFontStruct* font) | |
509 { | |
510 if (b_dpy) balloon_help_destroy (); | |
511 | |
512 b_dpy = dpy; | |
513 | |
514 b_fontStruct = font; | |
515 | |
516 b_win = create_window (dpy, bg); | |
517 b_gc = create_gc (dpy, b_win, fg, bg, b_fontStruct); | |
518 | |
519 b_shineGC = create_gc (dpy, b_win, shine, bg, b_fontStruct); | |
520 b_shadowGC = create_gc (dpy, b_win, shadow, bg, b_fontStruct); | |
521 | |
522 create_pixmap_mask (1, 1); | |
523 b_maskGC = create_gc (dpy, b_mask, bg, fg, b_fontStruct); | |
524 | |
525 b_winMapped = False; | |
526 b_timer = None; | |
527 b_delay = 500; | |
528 | |
529 b_screenWidth = DisplayWidth (b_dpy, DefaultScreen(b_dpy)); | |
530 b_screenHeight = DisplayHeight (b_dpy, DefaultScreen(b_dpy)); | |
531 | |
532 b_lastShape = SHAPE_CONE_FREE; | |
533 } | |
534 | |
535 void | |
536 balloon_help_set_delay (unsigned long milliseconds) | |
537 { | |
538 b_delay = milliseconds; | |
539 } | |
540 | |
541 void | |
442 | 542 balloon_help_show (const char* text) |
428 | 543 { |
544 assert (b_dpy != NULL); | |
545 | |
546 /* We don't copy the text */ | |
547 b_text = text; | |
548 b_lastShape = SHAPE_CONE_FREE; | |
549 | |
550 if (b_winMapped) | |
551 { | |
552 /* If help is already being shown, don't delay just update */ | |
553 show_help (NULL, NULL); | |
554 } | |
555 else | |
556 { | |
557 b_timer = | |
558 XtAppAddTimeOut (XtDisplayToApplicationContext(b_dpy), | |
559 b_delay, show_help, NULL); | |
560 } | |
561 } | |
562 | |
563 void | |
564 balloon_help_hide (void) | |
565 { | |
566 assert (b_dpy != NULL); | |
567 | |
568 b_text = NULL; | |
569 XUnmapWindow (b_dpy, b_win); | |
570 b_winMapped = False; | |
571 if (b_timer) | |
572 { | |
573 XtRemoveTimeOut (b_timer); | |
574 b_timer = None; | |
575 } | |
576 } | |
577 | |
578 void | |
579 balloon_help_move_to_pointer (void) | |
580 { | |
581 assert (b_dpy != NULL); | |
582 | |
583 if (b_winMapped) | |
584 { | |
585 int x, y; | |
586 int shape = b_lastShape; | |
587 | |
588 get_pointer_xy (b_dpy, &x, &y); | |
589 | |
590 x += (shape & SHAPE_CONE_LEFT) ? POINTER_OFFSET : -POINTER_OFFSET; | |
591 y += (shape & SHAPE_CONE_TOP) ? POINTER_OFFSET : -POINTER_OFFSET; | |
592 | |
593 shape = get_shape (shape, x, y, b_width, b_height, b_screenWidth, b_screenHeight); | |
594 | |
595 if (shape == b_lastShape) | |
596 { | |
597 XMoveWindow (b_dpy, b_win, | |
598 shape & SHAPE_CONE_LEFT ? x : x - b_width, | |
599 shape & SHAPE_CONE_TOP ? y : y - b_height); | |
600 } | |
601 else | |
602 { | |
603 /* text would be off screen, rebuild with new shape */ | |
604 b_lastShape = SHAPE_CONE_FREE; | |
605 show_help (NULL, NULL); | |
606 } | |
607 } | |
608 } |