Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #include "gdrawP.h"
28 : #include <gkeysym.h>
29 : #include <ustring.h>
30 : #include <gio.h>
31 : #include "gdraw.h"
32 : #if __Mac
33 : # include <sys/select.h>
34 : #endif
35 :
36 :
37 :
38 : /* Functions for font metrics:
39 : rectangle of text (left side bearing of first char, right of last char)
40 : */
41 :
42 : GDisplay *screen_display = NULL;
43 : GDisplay *printer_display = NULL;
44 : void (*_GDraw_BuildCharHook)(GDisplay *) = NULL;
45 : void (*_GDraw_InsCharHook)(GDisplay *,unichar_t) = NULL;
46 :
47 0 : void GDrawTerm(GDisplay *disp) {
48 0 : (disp->funcs->term)(disp);
49 0 : }
50 :
51 0 : int GDrawGetRes(GWindow gw) {
52 0 : if ( gw==NULL ) {
53 0 : if ( screen_display==NULL )
54 0 : return( 100 );
55 0 : gw = screen_display->groot;
56 : }
57 0 : return( gw->display->res );
58 : }
59 :
60 0 : int GDrawPointsToPixels(GWindow gw,int points) {
61 0 : if ( gw==NULL ) {
62 0 : if ( screen_display==NULL )
63 0 : return( PointToPixel(points,100));
64 0 : gw = screen_display->groot;
65 : }
66 0 : return( PointToPixel(points,gw->display->res));
67 : }
68 :
69 0 : int GDrawPixelsToPoints(GWindow gw,int pixels) {
70 0 : if ( gw==NULL ) {
71 0 : if ( screen_display==NULL )
72 0 : return( PixelToPoint(pixels,100));
73 0 : gw = screen_display->groot;
74 : }
75 0 : return( PixelToPoint(pixels,gw->display->res));
76 : }
77 :
78 0 : void GDrawSetDefaultIcon(GWindow icon) {
79 0 : (icon->display->funcs->setDefaultIcon)(icon);
80 0 : }
81 :
82 0 : GWindow GDrawCreateTopWindow(GDisplay *gdisp, GRect *pos,
83 : int (*eh)(GWindow,GEvent *), void *user_data, GWindowAttrs *wattrs) {
84 0 : if ( gdisp==NULL ) gdisp = screen_display;
85 0 : return( (gdisp->funcs->createTopWindow)(gdisp,pos,eh,user_data,wattrs) );
86 : }
87 :
88 0 : GWindow GDrawCreateSubWindow(GWindow w, GRect *pos,
89 : int (*eh)(GWindow,GEvent *), void *user_data, GWindowAttrs *wattrs) {
90 0 : return( (w->display->funcs->createSubWindow)(w,pos,eh,user_data,wattrs) );
91 : }
92 :
93 0 : GWindow GDrawCreatePixmap(GDisplay *gdisp, uint16 width, uint16 height) {
94 0 : if ( gdisp==NULL ) gdisp = screen_display;
95 0 : return( (gdisp->funcs->createPixmap)(gdisp,width,height));
96 : }
97 :
98 0 : GWindow GDrawCreateBitmap(GDisplay *gdisp, uint16 width, uint16 height, uint8 *data) {
99 0 : if ( gdisp==NULL ) gdisp = screen_display;
100 0 : return( (gdisp->funcs->createBitmap)(gdisp,width,height,data));
101 : }
102 :
103 0 : GCursor GDrawCreateCursor(GWindow src,GWindow mask,Color fg,Color bg,
104 : int16 x, int16 y ) {
105 0 : return( (src->display->funcs->createCursor)(src,mask,fg,bg,x,y));
106 : }
107 :
108 0 : void GDrawDestroyWindow(GWindow w) {
109 0 : (w->display->funcs->destroyWindow)(w);
110 0 : }
111 :
112 0 : void GDrawSetZoom(GWindow w,GRect *zoom, enum gzoom_flags flags) {
113 0 : (w->display->funcs->setZoom)(w,zoom,flags);
114 0 : }
115 :
116 0 : void GDrawDestroyCursor(GDisplay *gdisp, GCursor ct) {
117 0 : if ( gdisp==NULL ) gdisp = screen_display;
118 0 : (gdisp->funcs->destroyCursor)(gdisp,ct);
119 0 : }
120 :
121 0 : int GDrawNativeWindowExists(GDisplay *gdisp, void *native) {
122 0 : if ( gdisp==NULL ) gdisp = screen_display;
123 0 : return( (gdisp->funcs->nativeWindowExists)(gdisp,native) );
124 : }
125 :
126 0 : void GDrawSetWindowBackground(GWindow w,Color col) {
127 0 : (w->display->funcs->setWindowBackground)(w,col);
128 0 : }
129 :
130 0 : void GDrawSetWindowBorder(GWindow w,int width,Color col) {
131 0 : (w->display->funcs->setWindowBorder)(w,width,col);
132 0 : }
133 :
134 0 : int GDrawSetDither(GDisplay *gdisp, int dither) {
135 0 : if ( gdisp==NULL ) gdisp = screen_display;
136 0 : return( (gdisp->funcs->setDither)(gdisp,dither) );
137 : }
138 :
139 0 : void GDrawReparentWindow(GWindow child, GWindow parent, int x, int y) {
140 0 : (child->display->funcs->reparentWindow)(child,parent,x,y);
141 0 : }
142 :
143 0 : void GDrawSetVisible(GWindow w, int visible) {
144 0 : (w->display->funcs->setVisible)(w,visible);
145 0 : }
146 :
147 25 : int GDrawIsVisible(GWindow w) {
148 25 : if ( w==NULL )
149 25 : return( false );
150 0 : while ( w!=NULL && ( w->is_visible || w->is_pixmap ))
151 0 : w = w->parent;
152 0 : return( w==NULL );
153 : }
154 :
155 0 : void GDrawMove(GWindow w, int32 x, int32 y) {
156 0 : (w->display->funcs->move)(w,x,y);
157 0 : }
158 :
159 0 : void GDrawTrueMove(GWindow w, int32 x, int32 y) {
160 0 : (w->display->funcs->trueMove)(w,x,y);
161 0 : }
162 :
163 0 : void GDrawResize(GWindow w, int32 width, int32 height) {
164 0 : (w->display->funcs->resize)(w,width,height);
165 0 : }
166 :
167 0 : void GDrawMoveResize(GWindow w, int32 x, int32 y, int32 width, int32 height) {
168 0 : (w->display->funcs->moveResize)(w,x,y,width,height);
169 0 : }
170 :
171 0 : GWindow GDrawGetRoot(GDisplay *gdisp) {
172 0 : if ( gdisp==NULL ) gdisp = screen_display;
173 0 : return(gdisp->groot);
174 : }
175 :
176 0 : Color GDrawGetDefaultBackground(GDisplay *gdisp) {
177 0 : if ( gdisp==NULL ) gdisp = screen_display;
178 0 : return(gdisp->def_background);
179 : }
180 :
181 0 : Color GDrawGetDefaultForeground(GDisplay *gdisp) {
182 0 : if ( gdisp==NULL ) gdisp = screen_display;
183 0 : return(gdisp->def_foreground);
184 : }
185 :
186 0 : GRect *GDrawGetSize(GWindow w, GRect *ret) {
187 0 : *ret = w->pos;
188 0 : return(ret);
189 : }
190 :
191 0 : GDrawEH GDrawGetEH(GWindow w) {
192 0 : return( w->eh );
193 : }
194 :
195 0 : void GDrawSetEH(GWindow w,GDrawEH eh) {
196 0 : w->eh = eh;
197 0 : }
198 :
199 0 : void GDrawGetPointerPosition(GWindow w, GEvent *ret) {
200 0 : (w->display->funcs->getPointerPos)(w,ret);
201 0 : }
202 :
203 0 : GWindow GDrawGetPointerWindow(GWindow w) {
204 0 : return( (w->display->funcs->getPointerWindow)(w));
205 : }
206 :
207 0 : void GDrawRaise(GWindow w) {
208 0 : (w->display->funcs->raise)(w);
209 0 : }
210 :
211 0 : void GDrawRaiseAbove(GWindow w,GWindow below) {
212 0 : (w->display->funcs->raiseAbove)(w,below);
213 0 : }
214 :
215 0 : int GDrawIsAbove(GWindow w,GWindow other) {
216 0 : return( (w->display->funcs->isAbove)(w,other) );
217 : }
218 :
219 0 : void GDrawLower(GWindow w) {
220 0 : (w->display->funcs->lower)(w);
221 0 : }
222 :
223 0 : void GDrawSetWindowTitles(GWindow w, const unichar_t *title, const unichar_t *icontit) {
224 0 : (w->display->funcs->setWindowTitles)(w,title,icontit);
225 0 : }
226 :
227 0 : unichar_t *GDrawGetWindowTitle(GWindow w) {
228 0 : return( (w->display->funcs->getWindowTitle)(w) );
229 : }
230 :
231 0 : void GDrawSetWindowTitles8(GWindow w, const char *title, const char *icontit) {
232 0 : (w->display->funcs->setWindowTitles8)(w,title,icontit);
233 0 : }
234 :
235 0 : char *GDrawGetWindowTitle8(GWindow w) {
236 0 : return( (w->display->funcs->getWindowTitle8)(w) );
237 : }
238 :
239 0 : void GDrawSetTransientFor(GWindow transient, GWindow owner) {
240 0 : (transient->display->funcs->setTransientFor)(transient,owner);
241 0 : }
242 :
243 0 : void GDrawSetCursor(GWindow w, GCursor ct) {
244 0 : (w->display->funcs->setCursor)(w,ct);
245 0 : }
246 :
247 0 : GCursor GDrawGetCursor(GWindow w) {
248 0 : return( (w->display->funcs->getCursor)(w) );
249 : }
250 :
251 0 : GWindow GDrawGetRedirectWindow(GDisplay *gd) {
252 0 : if ( gd==NULL ) gd = screen_display;
253 0 : return( (gd->funcs->getRedirectWindow)(gd) );
254 : }
255 :
256 0 : void GDrawTranslateCoordinates(GWindow from,GWindow to, GPoint *pt) {
257 : GDisplay *gd;
258 0 : if ( from!=NULL )
259 0 : gd = from->display;
260 0 : else if ( to!=NULL )
261 0 : gd = to->display;
262 : else
263 0 : return;
264 0 : (gd->funcs->translateCoordinates)(from,to,pt);
265 : }
266 :
267 0 : int32 GDrawEventInWindow(GWindow inme,GEvent *event) {
268 : GPoint pt;
269 0 : if ( event->type<et_char || event->type>et_crossing )
270 0 : return( false );
271 0 : pt.x = event->u.mouse.x; pt.y = event->u.mouse.y;
272 0 : (inme->display->funcs->translateCoordinates)(event->w,inme,&pt);
273 0 : if ( pt.x<0 || pt.y<0 || pt.x >= inme->pos.width || pt.y >= inme->pos.height )
274 0 : return( false );
275 :
276 0 : return( true );
277 : }
278 :
279 0 : GWindow GDrawGetParentWindow(GWindow gw) {
280 0 : return( gw->parent );
281 : }
282 :
283 0 : int GDrawWindowIsAncestor(GWindow ancester, GWindow descendent) {
284 0 : while ( descendent!=NULL && descendent!=ancester )
285 0 : descendent = descendent->parent;
286 0 : return( descendent==ancester );
287 : }
288 :
289 0 : void GDrawSetUserData(GWindow gw, void *ud) {
290 0 : gw->user_data = ud;
291 0 : }
292 :
293 0 : void *GDrawGetUserData(GWindow gw) {
294 0 : if( !gw )
295 0 : return 0;
296 0 : return( gw->user_data );
297 : }
298 :
299 0 : void GDrawSetWindowTypeName(GWindow gw, char* name)
300 : {
301 0 : gw->window_type_name = name;
302 0 : }
303 :
304 0 : char* GDrawGetWindowTypeName(GWindow gw)
305 : {
306 0 : if(!gw)
307 0 : return 0;
308 :
309 0 : return(gw->window_type_name);
310 : }
311 :
312 :
313 0 : GDisplay *GDrawGetDisplayOfWindow(GWindow gw) {
314 0 : if ( gw==NULL )
315 0 : return( screen_display );
316 :
317 0 : return( gw->display );
318 : }
319 :
320 0 : void GDrawBeep(GDisplay *gdisp) {
321 0 : if ( gdisp==NULL ) gdisp = screen_display;
322 0 : (gdisp->funcs->beep)(gdisp);
323 0 : }
324 :
325 0 : void GDrawFlush(GDisplay *gdisp) {
326 0 : if ( gdisp==NULL ) gdisp = screen_display;
327 0 : (gdisp->funcs->flush)(gdisp);
328 0 : }
329 :
330 0 : void GDrawGetClip(GWindow w, GRect *ret) {
331 0 : *ret = w->ggc->clip;
332 0 : }
333 :
334 0 : void GDrawSetClip(GWindow w, GRect *rct) {
335 0 : if ( rct==NULL ) {
336 0 : w->ggc->clip.x = w->ggc->clip.y = 0;
337 0 : w->ggc->clip.width = w->ggc->clip.height = 0x7fff;
338 : } else
339 0 : w->ggc->clip = *rct;
340 0 : }
341 :
342 0 : void GDrawPushClip(GWindow w, GRect *rct, GRect *old) {
343 0 : (w->display->funcs->pushClip)(w,rct,old);
344 0 : }
345 :
346 0 : void GDrawPushClipOnly(GWindow w)
347 : {
348 0 : if( w->display->funcs->PushClipOnly )
349 0 : (w->display->funcs->PushClipOnly)( w );
350 0 : }
351 :
352 0 : void GDrawClipPreserve(GWindow w)
353 : {
354 0 : if( w->display->funcs->ClipPreserve )
355 0 : (w->display->funcs->ClipPreserve)( w );
356 0 : }
357 :
358 :
359 0 : void GDrawPopClip(GWindow w, GRect *old) {
360 0 : (w->display->funcs->popClip)(w,old);
361 0 : }
362 :
363 :
364 0 : GGC *GDrawGetWindowGGC(GWindow w) {
365 0 : return( w->ggc );
366 : }
367 :
368 0 : void GDrawSetXORBase(GWindow w,Color col) {
369 0 : w->ggc->xor_base = col;
370 0 : }
371 :
372 0 : void GDrawSetXORMode(GWindow w) {
373 0 : w->ggc->func = df_xor;
374 0 : }
375 :
376 0 : void GDrawSetCopyMode(GWindow w) {
377 0 : w->ggc->func = df_copy;
378 0 : }
379 :
380 0 : void GDrawSetCopyThroughSubWindows(GWindow w,int16 through) {
381 0 : w->ggc->copy_through_sub_windows = through;
382 0 : }
383 :
384 0 : void GDrawSetDashedLine(GWindow w,int16 dash_len, int16 skip_len, int16 off) {
385 0 : w->ggc->dash_offset = off;
386 0 : w->ggc->dash_len = dash_len;
387 0 : w->ggc->skip_len = skip_len;
388 0 : }
389 :
390 0 : void GDrawSetStippled(GWindow w,int16 ts, int32 yoff,int32 xoff) {
391 0 : w->ggc->ts = ts;
392 0 : w->ggc->ts_xoff = xoff; w->ggc->ts_yoff = yoff;
393 0 : }
394 :
395 0 : void GDrawSetLineWidth(GWindow w,int16 width) {
396 0 : w->ggc->line_width = width;
397 0 : }
398 :
399 0 : int16 GDrawGetLineWidth( GWindow w )
400 : {
401 0 : return w->ggc->line_width;
402 : }
403 :
404 :
405 0 : void GDrawSetForeground(GWindow w,Color col) {
406 0 : w->ggc->fg = col;
407 0 : }
408 :
409 0 : void GDrawSetBackground(GWindow w,Color col) {
410 0 : w->ggc->bg = col;
411 0 : }
412 :
413 0 : void GDrawClear(GWindow w, GRect *rect) {
414 0 : (w->display->funcs->clear)(w,rect);
415 0 : }
416 :
417 0 : void GDrawDrawLine(GWindow w, int32 x,int32 y, int32 xend,int32 yend, Color col) {
418 0 : if ( col!=COLOR_UNKNOWN )
419 0 : (w->display->funcs->drawLine)(w,x,y,xend,yend,col);
420 0 : }
421 :
422 0 : void GDrawDrawArrow(GWindow w, int32 x,int32 y, int32 xend,int32 yend, int arrows, Color col) {
423 0 : if ( col!=COLOR_UNKNOWN )
424 0 : (w->display->funcs->drawArrow)(w,x,y,xend,yend,arrows,col);
425 0 : }
426 :
427 0 : void GDrawDrawRect(GWindow w, GRect *rect, Color col) {
428 0 : if ( col!=COLOR_UNKNOWN )
429 0 : (w->display->funcs->drawRect)(w,rect,col);
430 0 : }
431 :
432 0 : void GDrawFillRect(GWindow w, GRect *rect, Color col) {
433 : GRect temp;
434 0 : if ( rect==NULL ) {
435 0 : temp.x = temp.y = 0; temp.width = w->pos.width; temp.height = w->pos.height;
436 0 : rect = &temp;
437 : }
438 0 : if ( col!=COLOR_UNKNOWN )
439 0 : (w->display->funcs->fillRect)(w,rect,col);
440 0 : }
441 :
442 0 : void GDrawFillRoundRect(GWindow w, GRect *rect, int radius, Color col) {
443 : GRect temp;
444 0 : if ( rect==NULL ) {
445 0 : temp.x = temp.y = 0; temp.width = w->pos.width; temp.height = w->pos.height;
446 0 : rect = &temp;
447 : }
448 0 : if ( col!=COLOR_UNKNOWN )
449 0 : (w->display->funcs->fillRoundRect)(w,rect,radius,col);
450 0 : }
451 :
452 0 : void GDrawDrawElipse(GWindow w, GRect *rect, Color col) {
453 0 : if ( col!=COLOR_UNKNOWN )
454 0 : (w->display->funcs->drawElipse)(w,rect,col);
455 0 : }
456 :
457 0 : void GDrawFillElipse(GWindow w, GRect *rect, Color col) {
458 0 : if ( col!=COLOR_UNKNOWN )
459 0 : (w->display->funcs->fillElipse)(w,rect,col);
460 0 : }
461 :
462 : /* angles expressed as in X, in 64's of a degree with 0 angle at 3 o'clock */
463 : /* and positive measured counter-clockwise (or the same way as in polar coords)*/
464 : /* tangle is NOT the end angle, it's the angle offset from the first to the end*/
465 0 : void GDrawDrawArc(GWindow w, GRect *rect, int32 sangle, int32 tangle, Color col) {
466 0 : if ( col!=COLOR_UNKNOWN )
467 0 : (w->display->funcs->drawArc)(w,rect,sangle,tangle,col);
468 0 : }
469 :
470 0 : void GDrawDrawPoly(GWindow w, GPoint *pts, int16 cnt, Color col) {
471 0 : if ( col!=COLOR_UNKNOWN )
472 0 : (w->display->funcs->drawPoly)(w,pts,cnt,col);
473 0 : }
474 :
475 0 : void GDrawFillPoly(GWindow w, GPoint *pts, int16 cnt, Color col) {
476 0 : if ( col!=COLOR_UNKNOWN )
477 0 : (w->display->funcs->fillPoly)(w,pts,cnt,col);
478 0 : }
479 :
480 0 : void GDrawScroll(GWindow w, GRect *rect, int32 hor, int32 vert) {
481 0 : (w->display->funcs->scroll)(w,rect,hor,vert);
482 0 : }
483 :
484 : /* draws the subset of the image specified by src starting at loc (x,y) */
485 0 : void GDrawDrawImage(GWindow w, GImage *img, GRect *src, int32 x, int32 y) {
486 : GRect r;
487 0 : if ( src==NULL ) {
488 0 : struct _GImage *base = img->list_len==0?img->u.image:img->u.images[0];
489 0 : r.x = r.y = 0;
490 0 : r.width = base->width; r.height = base->height;
491 0 : src = &r;
492 : }
493 0 : (w->display->funcs->drawImage)(w,img,src,x,y);
494 0 : }
495 :
496 : /* Draw the entire image so that it is approximately the same size on other */
497 : /* displays as on the screen */
498 0 : void GDrawDrawScaledImage(GWindow w, GImage *img, int32 x, int32 y) {
499 : GRect r;
500 :
501 0 : r.x = r.y = 0;
502 0 : r.width = GImageGetScaledWidth(w,img);
503 0 : r.height = GImageGetScaledHeight(w,img);
504 0 : (w->display->funcs->drawImage)(w,img,&r,x,y);
505 0 : }
506 :
507 : /* Similar to DrawImage, but can in some cases make improvements -- if the */
508 : /* is an indexed image, then treat as the alpha channel rather than a color */
509 : /* in its own right */
510 0 : void GDrawDrawGlyph(GWindow w, GImage *img, GRect *src, int32 x, int32 y) {
511 : GRect r;
512 0 : if ( src==NULL ) {
513 0 : struct _GImage *base = img->list_len==0?img->u.image:img->u.images[0];
514 0 : r.x = r.y = 0;
515 0 : r.width = base->width; r.height = base->height;
516 0 : src = &r;
517 : }
518 0 : (w->display->funcs->drawGlyph)(w,img,src,x,y);
519 0 : }
520 :
521 : /* We got an expose event for the src rectangle. The image is supposed to be */
522 : /* tiled across the window starting at (x,y) and continuing at least to the */
523 : /* limit of the expose event. Figure out how to draw what bits of the image */
524 : /* where and how many times */
525 0 : void GDrawTileImage(GWindow w, GImage *img, GRect *src, int32 x, int32 y) {
526 0 : (w->display->funcs->tileImage)(w,img,src,x,y);
527 0 : }
528 :
529 : /* same as drawImage except with pixmaps */
530 0 : void GDrawDrawPixmap(GWindow w, GWindow pixmap, GRect *src, int32 x, int32 y) {
531 0 : (w->display->funcs->drawPixmap)(w,pixmap,src,x,y);
532 0 : }
533 :
534 : /* same as tileImage except with pixmaps */
535 0 : void GDrawTilePixmap(GWindow w, GWindow pixmap, GRect *src, int32 x, int32 y) {
536 0 : (w->display->funcs->tilePixmap)(w,pixmap,src,x,y);
537 0 : }
538 :
539 : /* We assume the full image is drawn starting at (x,y) and scaled to (width,height) */
540 : /* this routine updates the rectangle on the screen */
541 : /* (x+src->x,y+src->y,x+src->width,y+src->height) */
542 : /* Ie. if you get an expose event in the middle of the image subtract off the */
543 : /* image base (x,y) and pass in the exposed rectangle */
544 0 : void GDrawDrawImageMagnified(GWindow w, GImage *img, GRect *dest, int32 x, int32 y,
545 : int32 width, int32 height) {
546 : GRect temp;
547 0 : struct _GImage *base = img->list_len==0?img->u.image:img->u.images[0];
548 :
549 0 : if ( base->width==width && base->height==height ) {
550 : /* Not magnified after all */
551 0 : if ( dest==NULL )
552 0 : GDrawDrawImage(w,img,NULL,x,y);
553 : else {
554 : int old;
555 0 : temp = *dest; temp.x += x; temp.y += y;
556 0 : if ( temp.x<x ) {
557 0 : temp.x = 0;
558 0 : temp.width-=x;
559 : } else {
560 0 : old = x;
561 0 : x = temp.x;
562 0 : temp.x -= old;
563 0 : temp.width -= old;
564 : }
565 0 : if ( temp.y<y ) {
566 0 : temp.y = 0;
567 0 : temp.height-=y;
568 : } else {
569 0 : old = y;
570 0 : y = temp.y;
571 0 : temp.y -= old;
572 0 : temp.height -= old;
573 : }
574 0 : if ( temp.x>=base->width || temp.y>=base->height || temp.width<=0 || temp.height<=0 )
575 0 : return;
576 0 : if ( temp.x+temp.width>=base->width )
577 0 : temp.width = base->width-temp.x;
578 0 : if ( temp.y+temp.height>=base->height )
579 0 : temp.height = base->height-temp.y;
580 0 : GDrawDrawImage(w,img,&temp,x,y);
581 : }
582 0 : return;
583 : }
584 0 : if ( dest==NULL ) {
585 0 : temp.x = temp.y = 0;
586 0 : temp.width = width; temp.height = height;
587 0 : dest = &temp;
588 0 : } else if ( dest->x<0 || dest->y<0 ||
589 0 : dest->x+dest->width > width || dest->y+dest->height > height ) {
590 0 : temp = *dest;
591 0 : if ( temp.x<0 ) { temp.width += temp.x; temp.x = 0; }
592 0 : if ( temp.y<0 ) { temp.height += temp.y; temp.y = 0; }
593 0 : if ( temp.x+temp.width>width ) temp.width = width-temp.x;
594 0 : if ( temp.y+temp.height>height ) temp.height = height-temp.y;
595 0 : dest = &temp;
596 : }
597 0 : (w->display->funcs->drawImageMag)(w,img,dest,x,y, width, height);
598 : }
599 :
600 0 : GImage *GDrawCopyScreenToImage(GWindow w, GRect *rect) {
601 : GRect temp;
602 0 : if ( rect==NULL ) {
603 0 : temp.x = 0; temp.y = 0; temp.width = w->pos.width; temp.height = w->pos.height;
604 0 : rect = &temp;
605 : }
606 0 : return( (w->display->funcs->copyScreenToImage)(w,rect) );
607 : }
608 :
609 0 : void GDrawWindowFontMetrics(GWindow w,FontInstance *fi,int *as, int *ds, int *ld) {
610 0 : (w->display->funcs->getFontMetrics)(w,fi,as,ds,ld);
611 0 : }
612 :
613 :
614 0 : enum gcairo_flags GDrawHasCairo(GWindow w) {
615 0 : return( (w->display->funcs->hasCairo)(w));
616 : }
617 :
618 0 : void GDrawPathStartNew(GWindow w) {
619 0 : (w->display->funcs->startNewPath)(w);
620 0 : }
621 :
622 0 : void GDrawPathStartSubNew(GWindow w) {
623 0 : (w->display->funcs->startNewSubPath)(w);
624 0 : }
625 :
626 0 : int GDrawFillRuleSetWinding(GWindow w) {
627 0 : return (w->display->funcs->fillRuleSetWinding)(w);
628 : }
629 :
630 0 : void GDrawPathClose(GWindow w) {
631 0 : (w->display->funcs->closePath)(w);
632 0 : }
633 :
634 0 : void GDrawPathMoveTo(GWindow w,double x, double y) {
635 0 : (w->display->funcs->moveto)(w,x,y);
636 0 : }
637 :
638 0 : void GDrawPathLineTo(GWindow w,double x, double y) {
639 0 : (w->display->funcs->lineto)(w,x,y);
640 0 : }
641 :
642 0 : void GDrawPathCurveTo(GWindow w,
643 : double cx1, double cy1,
644 : double cx2, double cy2,
645 : double x, double y) {
646 0 : (w->display->funcs->curveto)(w,cx1,cy1,cx2,cy2,x,y);
647 0 : }
648 :
649 0 : void GDrawPathStroke(GWindow w,Color col) {
650 0 : (w->display->funcs->stroke)(w,col);
651 0 : }
652 :
653 0 : void GDrawPathFill(GWindow w,Color col) {
654 0 : (w->display->funcs->fill)(w,col);
655 0 : }
656 :
657 0 : void GDrawPathFillAndStroke(GWindow w,Color fillcol, Color strokecol) {
658 0 : (w->display->funcs->fillAndStroke)(w,fillcol,strokecol);
659 0 : }
660 :
661 0 : void GDrawLayoutInit(GWindow w, char *text, int cnt, GFont *fi) {
662 0 : (w->display->funcs->layoutInit)(w,text,cnt,fi);
663 0 : }
664 :
665 0 : void GDrawLayoutDraw(GWindow w, int32 x, int32 y, Color fg) {
666 0 : (w->display->funcs->layoutDraw)(w,x,y,fg);
667 0 : }
668 :
669 0 : void GDrawLayoutIndexToPos(GWindow w, int index, GRect *pos) {
670 0 : (w->display->funcs->layoutIndexToPos)(w,index,pos);
671 0 : }
672 :
673 0 : int GDrawLayoutXYToIndex(GWindow w, int x, int y) {
674 0 : return( (w->display->funcs->layoutXYToIndex)(w,x,y) );
675 : }
676 :
677 0 : void GDrawLayoutExtents(GWindow w, GRect *size) {
678 0 : (w->display->funcs->layoutExtents)(w,size);
679 0 : }
680 :
681 0 : void GDrawLayoutSetWidth(GWindow w, int width) {
682 0 : (w->display->funcs->layoutSetWidth)(w,width);
683 0 : }
684 :
685 0 : int GDrawLayoutLineCount(GWindow w) {
686 0 : return( (w->display->funcs->layoutLineCount)(w) );
687 : }
688 :
689 0 : int GDrawLayoutLineStart(GWindow w,int line) {
690 0 : return( (w->display->funcs->layoutLineStart)(w,line) );
691 : }
692 :
693 :
694 0 : GIC *GDrawCreateInputContext(GWindow w,enum gic_style def_style) {
695 0 : return(w->display->funcs->createInputContext)(w,def_style);
696 : }
697 :
698 0 : void GDrawSetGIC(GWindow w, GIC *gic, int x, int y) {
699 0 : (w->display->funcs->setGIC)(w,gic,x,y);
700 0 : }
701 :
702 0 : void GDrawGrabSelection(GWindow w,enum selnames sel) {
703 0 : (w->display->funcs->grabSelection)(w,sel);
704 0 : }
705 :
706 0 : void GDrawAddSelectionType(GWindow w,enum selnames sel,char *type,
707 : void *data,int32 cnt,int32 unitsize,void *(*gendata)(void *,int32 *len),
708 : void (*freedata)(void *)) {
709 0 : (w->display->funcs->addSelectionType)(w,sel,type,data,cnt,unitsize,gendata,freedata);
710 0 : }
711 :
712 0 : void *GDrawRequestSelection(GWindow w,enum selnames sn, char *typename, int32 *len) {
713 0 : return( (w->display->funcs->requestSelection)(w,sn,typename,len));
714 : }
715 :
716 0 : int GDrawSelectionHasType(GWindow w,enum selnames sn, char *typename) {
717 0 : return( (w->display->funcs->selectionHasType)(w,sn,typename));
718 : }
719 :
720 0 : void GDrawBindSelection(GDisplay *disp,enum selnames sel, char *atomname) {
721 0 : if ( disp==NULL )
722 0 : disp = screen_display;
723 0 : if (disp != NULL)
724 0 : (disp->funcs->bindSelection)(disp,sel,atomname);
725 0 : }
726 :
727 0 : int GDrawSelectionOwned(GDisplay *disp,enum selnames sel) {
728 0 : if ( disp==NULL )
729 0 : disp = screen_display;
730 0 : if (disp != NULL)
731 0 : return( (disp->funcs->selectionHasOwner)(disp,sel));
732 : else
733 0 : return -1;
734 : }
735 :
736 0 : int GDrawEnableExposeRequests(GWindow w,int enabled) {
737 0 : int old = w->disable_expose_requests;
738 0 : w->disable_expose_requests = enabled;
739 0 : return( old );
740 : }
741 :
742 25 : void GDrawRequestExpose(GWindow w, GRect *rect, int doclear) {
743 25 : if ( !GDrawIsVisible(w) || w->disable_expose_requests )
744 50 : return;
745 0 : (w->display->funcs->requestExpose)(w,rect,doclear);
746 : }
747 :
748 0 : void GDrawForceUpdate(GWindow w) {
749 0 : (w->display->funcs->forceUpdate)(w);
750 0 : }
751 :
752 0 : void GDrawSync(GDisplay *gdisp) {
753 0 : if ( gdisp==NULL ) gdisp=screen_display;
754 0 : if (gdisp != NULL)
755 0 : (gdisp->funcs->sync)(gdisp);
756 0 : }
757 :
758 0 : void GDrawPointerUngrab(GDisplay *gdisp) {
759 0 : if ( gdisp==NULL ) gdisp=screen_display;
760 0 : if (gdisp != NULL)
761 0 : (gdisp->funcs->pointerUngrab)(gdisp);
762 0 : }
763 :
764 0 : void GDrawPointerGrab(GWindow w) {
765 0 : (w->display->funcs->pointerGrab)(w);
766 0 : }
767 :
768 0 : void GDrawProcessOneEvent(GDisplay *gdisp) {
769 0 : if ( gdisp==NULL ) gdisp=screen_display;
770 0 : if (gdisp != NULL)
771 0 : (gdisp->funcs->processOneEvent)(gdisp);
772 0 : }
773 :
774 0 : void GDrawSkipMouseMoveEvents(GWindow w,GEvent *last) {
775 0 : (w->display->funcs->skipMouseMoveEvents)(w,last);
776 0 : }
777 :
778 0 : void GDrawProcessPendingEvents(GDisplay *gdisp) {
779 0 : if ( gdisp==NULL ) gdisp=screen_display;
780 0 : if (gdisp != NULL)
781 0 : (gdisp->funcs->processPendingEvents)(gdisp);
782 0 : }
783 :
784 0 : void GDrawProcessWindowEvents(GWindow w) {
785 0 : (w->display->funcs->processWindowEvents)(w);
786 0 : }
787 :
788 0 : void GDrawEventLoop(GDisplay *gdisp) {
789 0 : if ( gdisp==NULL ) gdisp=screen_display;
790 0 : if (gdisp != NULL)
791 0 : (gdisp->funcs->eventLoop)(gdisp);
792 0 : }
793 :
794 0 : void GDrawPostEvent(GEvent *e) {
795 0 : GDisplay *gdisp = e->w->display;
796 0 : if ( gdisp==NULL ) gdisp=screen_display;
797 0 : if (gdisp != NULL)
798 0 : (gdisp->funcs->postEvent)(e);
799 0 : }
800 :
801 0 : void GDrawPostDragEvent(GWindow w,GEvent *mouse,enum event_type et) {
802 0 : GDisplay *gdisp = w->display;
803 0 : (gdisp->funcs->postDragEvent)(w,mouse,et);
804 0 : }
805 :
806 0 : GTimer *GDrawRequestTimer(GWindow w,int32 time_from_now,int32 frequency,
807 : void *userdata) {
808 0 : return( (w->display->funcs->requestTimer)(w,time_from_now,frequency,userdata));
809 : }
810 :
811 0 : void GDrawCancelTimer(GTimer *timer) {
812 : GDisplay *gdisp;
813 0 : if ( timer==NULL )
814 0 : return;
815 0 : gdisp=timer->owner->display;
816 0 : (gdisp->funcs->cancelTimer)(timer);
817 : }
818 :
819 0 : void GDrawSyncThread(GDisplay *gdisp, void (*func)(void *), void *data) {
820 0 : if ( gdisp==NULL )
821 0 : gdisp = screen_display;
822 0 : if (gdisp != NULL)
823 0 : (gdisp->funcs->syncThread)(gdisp,func,data);
824 0 : }
825 :
826 0 : GWindow GPrinterStartJob(GDisplay *gdisp,void *user_data,GPrinterAttrs *attrs) {
827 0 : if ( gdisp==NULL )
828 0 : gdisp = printer_display;
829 0 : if (gdisp != NULL)
830 0 : return( (gdisp->funcs->startJob)(gdisp,user_data,attrs) );
831 : else
832 0 : return NULL;
833 : }
834 :
835 0 : void GPrinterNextPage(GWindow w) {
836 0 : if ( w==NULL )
837 0 : w = printer_display->groot;
838 0 : (w->display->funcs->nextPage)(w);
839 0 : }
840 :
841 0 : int GPrinterEndJob(GWindow w,int cancel) {
842 0 : if ( w==NULL )
843 0 : w = printer_display->groot;
844 0 : return( (w->display->funcs->endJob)(w,cancel) );
845 : }
846 :
847 0 : int GDrawRequestDeviceEvents(GWindow w,int devcnt,struct gdeveventmask *de) {
848 0 : return( (w->display->funcs->requestDeviceEvents)(w,devcnt,de) );
849 : }
850 :
851 0 : void GDrawSetBuildCharHooks(void (*hook)(GDisplay *),void (*inshook)(GDisplay *,unichar_t)) {
852 0 : _GDraw_BuildCharHook = hook;
853 0 : _GDraw_InsCharHook = inshook;
854 0 : }
855 :
856 : /* We are in compose characters mode. The gdisp->mykey_state argument tells us*/
857 : /* how many accent keys have been pressed. When we finally get a non-accent */
858 : /* we try to look through our rules for composing letters given this set of */
859 : /* accents and this base character. If we find something, great, install it */
860 : /* and return. If there's nothing then see if we get anywhere by removing */
861 : /* one of the accents (if so use it, but continue with the remain accent in */
862 : /* the state). Finally we use the base character followed by all the accents */
863 : /* left unaccounted for in the mask */
864 0 : void _GDraw_ComposeChars(GDisplay *gdisp,GEvent *gevent) {
865 0 : unichar_t ch = gevent->u.chr.keysym;
866 0 : struct gchr_transform *strt = NULL, *trans, *end=NULL;
867 : extern struct gchr_lookup _gdraw_chrlookup[];
868 : extern struct gchr_accents _gdraw_accents[];
869 : extern uint32 _gdraw_chrs_ctlmask, _gdraw_chrs_metamask, _gdraw_chrs_any;
870 : int i,mask;
871 : unichar_t hold[_GD_EVT_CHRLEN], *pt, *ept, *hpt;
872 0 : uint32 mykey_state = gdisp->mykey_state;
873 :
874 0 : if ( gevent->u.chr.chars[0]=='\0' ) /* ignore things like the shift key */
875 0 : return;
876 0 : if ( gevent->u.chr.keysym==GK_Escape ) {
877 0 : gevent->u.chr.chars[0] = '\0';
878 0 : gevent->u.chr.keysym = '\0';
879 0 : gdisp->mykeybuild = false;
880 0 : return;
881 : }
882 0 : if ( gevent->u.chr.state&ksm_control )
883 0 : mykey_state |= _gdraw_chrs_ctlmask;
884 0 : if ( gevent->u.chr.state&ksm_meta )
885 0 : mykey_state |= _gdraw_chrs_metamask;
886 0 : if ( ch>' ' && ch<0x7f ) {
887 0 : for ( trans = strt = _gdraw_chrlookup[ch-' '].transtab, end=trans+_gdraw_chrlookup[ch-' '].cnt;
888 0 : trans<end; ++trans ) {
889 0 : if ( trans->oldstate==mykey_state ) {
890 0 : gdisp->mykey_state = trans->newstate;
891 0 : if ( trans->resch=='\0' )
892 0 : u_strcpy(gevent->u.chr.chars,gevent->u.chr.chars+1);
893 : else {
894 0 : gevent->u.chr.chars[0] = trans->resch;
895 0 : gdisp->mykeybuild = false;
896 : }
897 0 : return;
898 0 : } else if ( trans->oldstate==_gdraw_chrs_any ) {
899 0 : gdisp->mykey_state |= trans->newstate;
900 0 : u_strcpy(gevent->u.chr.chars,gevent->u.chr.chars+1);
901 0 : return;
902 : }
903 : }
904 : }
905 :
906 0 : GDrawBeep(gdisp);
907 0 : if ( mykey_state==0 || mykey_state==0x8000000 )
908 0 : return;
909 0 : u_strcpy(hold,gevent->u.chr.chars+1);
910 0 : if ( strt!=NULL ) for ( mask=0x1; mask<0x8000000; mask<<=1 ) {
911 0 : if ( (mykey_state&~mask)== 0 )
912 0 : break; /* otherwise dotabove a gives us ae */
913 0 : for ( trans=strt; trans<end; ++trans ) {
914 0 : if ( trans->oldstate==(mykey_state&~mask) && trans->resch!='\0' ) {
915 0 : mykey_state = mask;
916 0 : gevent->u.chr.chars[0] = trans->resch;
917 0 : goto break_2_loops;
918 : }
919 : }
920 : }
921 : break_2_loops:;
922 0 : pt = gevent->u.chr.chars+1; ept = gevent->u.chr.chars+_GD_EVT_CHRLEN-1;
923 0 : for ( i=0; _gdraw_accents[i].accent!=0 && pt<ept; ++i ) {
924 0 : if ( (_gdraw_accents[i].mask&mykey_state)==_gdraw_accents[i].mask ) {
925 0 : *pt++ = _gdraw_accents[i].accent;
926 0 : mykey_state &= ~_gdraw_accents[i].mask;
927 : }
928 : }
929 0 : for ( hpt = hold; pt<ept && *hpt!='\0'; )
930 0 : *pt++ = *hpt++;
931 0 : *pt = '\0';
932 0 : gdisp->mykeybuild = false;
933 : }
934 :
935 0 : void GDrawDestroyDisplays() {
936 0 : if (screen_display != NULL) {
937 0 : _GXDraw_DestroyDisplay(screen_display);
938 0 : screen_display = NULL;
939 : }
940 0 : if (printer_display != NULL) {
941 0 : _GPSDraw_DestroyDisplay(printer_display);
942 0 : printer_display = NULL;
943 : }
944 0 : }
945 :
946 0 : void GDrawCreateDisplays(char *displayname,char *programname) {
947 0 : GIO_SetThreadCallback((void (*)(void *,void *,void *)) GDrawSyncThread);
948 0 : screen_display = _GXDraw_CreateDisplay(displayname,programname);
949 0 : printer_display = _GPSDraw_CreateDisplay();
950 0 : if ( screen_display==NULL ) {
951 0 : fprintf( stderr, "Could not open screen.\n" );
952 : #if __Mac
953 : fprintf( stderr, "You must start X11 before you can start %s\n", programname);
954 : fprintf( stderr, " X11 is optional software found on your install DVD.\n" );
955 : #elif __CygWin
956 : fprintf( stderr, "You must start X11 before you can start %s\n", programname);
957 : fprintf( stderr, " X11 may be obtained from the cygwin site in a separate package.\n" );
958 : #endif
959 0 : exit(1);
960 : }
961 0 : }
962 :
963 0 : void *GDrawNativeDisplay(GDisplay *gdisp) {
964 0 : if ( gdisp==NULL )
965 0 : gdisp=screen_display;
966 0 : if ( gdisp==NULL )
967 0 : return( NULL );
968 :
969 0 : return( (gdisp->funcs->nativeDisplay)(gdisp) );
970 : }
971 :
972 :
973 : void
974 0 : GDrawAddReadFD( GDisplay *gdisp,
975 : int fd, void* udata,
976 : void (*callback)(int fd, void* udata ))
977 : {
978 0 : if ( !gdisp )
979 : {
980 0 : gdisp=screen_display;
981 : }
982 :
983 0 : if( !gdisp )
984 : {
985 : // collab code being called from python scripted fontforge.
986 0 : GDrawCreateDisplays( 0, "fontforge");
987 0 : gdisp=screen_display;
988 : }
989 :
990 0 : if( gdisp->fd_callbacks_last >= gdisplay_fd_callbacks_size )
991 : {
992 0 : fprintf(stderr,"Error: FontForge has attempted to add more read FDs than it is equipt to handle\n");
993 0 : fprintf(stderr," Please report this error!\n");
994 0 : return;
995 : }
996 :
997 0 : fd_callback_t* cb = &gdisp->fd_callbacks[ gdisp->fd_callbacks_last ];
998 0 : gdisp->fd_callbacks_last++;
999 :
1000 0 : cb->fd = fd;
1001 0 : cb->udata = udata;
1002 0 : cb->callback = callback;
1003 : }
1004 :
1005 : static void
1006 0 : fd_callback_clear( fd_callback_t* cb )
1007 : {
1008 0 : cb->fd = 0;
1009 0 : cb->callback = 0;
1010 0 : cb->udata = 0;
1011 0 : }
1012 :
1013 :
1014 : void
1015 0 : GDrawRemoveReadFD( GDisplay *gdisp,
1016 : int fd, void* udata )
1017 : {
1018 0 : if ( gdisp==NULL )
1019 0 : gdisp=screen_display;
1020 0 : if( !fd )
1021 0 : return;
1022 :
1023 0 : int idx = 0;
1024 0 : for( idx = 0; idx < gdisplay_fd_callbacks_size; ++idx )
1025 : {
1026 0 : fd_callback_t* cb = &gdisp->fd_callbacks[ idx ];
1027 0 : if( cb->fd == fd )
1028 : {
1029 0 : if( idx+1 >= gdisp->fd_callbacks_last )
1030 : {
1031 0 : gdisp->fd_callbacks_last--;
1032 0 : fd_callback_clear( cb );
1033 0 : return;
1034 : }
1035 0 : gdisp->fd_callbacks_last--;
1036 0 : fd_callback_t* last = &gdisp->fd_callbacks[ gdisp->fd_callbacks_last ];
1037 0 : memcpy( cb, last, sizeof(fd_callback_t) );
1038 0 : fd_callback_clear( last );
1039 0 : return;
1040 : }
1041 : }
1042 : }
1043 :
1044 :
1045 :
1046 : #ifndef MAX
1047 : #define MAX(x,y) (((x) > (y)) ? (x) : (y))
1048 : #endif
1049 :
1050 : /* void MacServiceZeroMQFDs() */
1051 : /* { */
1052 : /* int ret = 0; */
1053 :
1054 : /* GDisplay *gdisp = GDrawGetDisplayOfWindow(0); */
1055 : /* int fd = 0; */
1056 : /* fd_set read, write, except; */
1057 : /* FD_ZERO(&read); FD_ZERO(&write); FD_ZERO(&except); */
1058 : /* struct timeval timeout; */
1059 : /* timeout.tv_sec = 0; */
1060 : /* timeout.tv_usec = 1; */
1061 :
1062 : /* if( gdisp->zeromq_fd > 0 ) */
1063 : /* { */
1064 : /* FD_SET(gdisp->zeromq_fd,&read); */
1065 : /* fd = MAX( fd, gdisp->zeromq_fd ); */
1066 : /* } */
1067 : /* if( fd > 0 ) */
1068 : /* ret = select(fd+1,&read,&write,&except,&timeout); */
1069 :
1070 : /* if( FD_ISSET(gdisp->zeromq_fd,&read)) */
1071 : /* { */
1072 : /* gdisp->zeromq_fd_callback( gdisp->zeromq_fd, gdisp->zeromq_datas ); */
1073 : /* } */
1074 : /* } */
1075 :
1076 :
1077 0 : void MacServiceReadFDs()
1078 : {
1079 : #if (!defined(__MINGW32__))&&(!defined(__CYGWIN__))
1080 0 : int ret = 0;
1081 :
1082 0 : GDisplay *gdisp = GDrawGetDisplayOfWindow(0);
1083 0 : int fd = 0;
1084 : fd_set read, write, except;
1085 0 : FD_ZERO(&read); FD_ZERO(&write); FD_ZERO(&except);
1086 : struct timeval timeout;
1087 0 : timeout.tv_sec = 0;
1088 0 : timeout.tv_usec = 1;
1089 :
1090 0 : int idx = 0;
1091 0 : for( idx = 0; idx < gdisp->fd_callbacks_last; ++idx )
1092 : {
1093 0 : fd_callback_t* cb = &gdisp->fd_callbacks[ idx ];
1094 0 : FD_SET(cb->fd,&read);
1095 0 : fd = MAX( fd, cb->fd );
1096 : }
1097 :
1098 0 : if( fd > 0 )
1099 0 : ret = select(fd+1,&read,&write,&except,&timeout);
1100 :
1101 0 : for( idx = 0; idx < gdisp->fd_callbacks_last; ++idx )
1102 : {
1103 0 : fd_callback_t* cb = &gdisp->fd_callbacks[ idx ];
1104 0 : if( FD_ISSET(cb->fd,&read))
1105 0 : cb->callback( cb->fd, cb->udata );
1106 : }
1107 : #endif
1108 0 : }
1109 :
1110 :
1111 :
1112 0 : static int BackgroundTimer_eh( GWindow w, GEvent* ev )
1113 : {
1114 0 : if ( ev->type == et_timer )
1115 : {
1116 0 : BackgroundTimer_t* bgt = (BackgroundTimer_t*)ev->u.timer.userdata;
1117 0 : bgt->func( bgt->userdata );
1118 : }
1119 0 : return 0;
1120 : }
1121 :
1122 :
1123 : BackgroundTimer_t*
1124 0 : BackgroundTimer_new( int32 BackgroundTimerMS,
1125 : BackgroundTimerFunc func,
1126 : void *userdata )
1127 : {
1128 0 : BackgroundTimer_t* ret = calloc( 1, sizeof(BackgroundTimer_t) );
1129 0 : ret->func = func;
1130 0 : ret->userdata = userdata;
1131 0 : ret->BackgroundTimerMS = BackgroundTimerMS;
1132 :
1133 : GWindowAttrs wattrs;
1134 0 : memset(&wattrs,0,sizeof(wattrs));
1135 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_isdlg|wam_positioned;
1136 0 : wattrs.event_masks = ~(1<<et_charup);
1137 0 : wattrs.is_dlg = true;
1138 0 : wattrs.positioned = true;
1139 0 : wattrs.utf8_window_title = "Timer Window";
1140 : GRect pos;
1141 0 : pos.width = 10;
1142 0 : pos.height = 10;
1143 0 : pos.x = 0;
1144 0 : pos.y = 0;
1145 :
1146 0 : GWindow w = GDrawCreateTopWindow( 0, &pos,
1147 : BackgroundTimer_eh, ret, &wattrs );
1148 0 : ret->timer = GDrawRequestTimer( w, BackgroundTimerMS, BackgroundTimerMS, ret );
1149 0 : ret->w = w;
1150 0 : return ret;
1151 : }
1152 :
1153 0 : void BackgroundTimer_remove( BackgroundTimer_t* t )
1154 : {
1155 0 : if( !t )
1156 0 : return;
1157 :
1158 0 : GDrawCancelTimer( t->timer );
1159 0 : GDrawDestroyWindow( t->w );
1160 0 : free(t);
1161 : }
1162 :
1163 0 : void BackgroundTimer_touch( BackgroundTimer_t* t )
1164 : {
1165 0 : if( !t )
1166 0 : return;
1167 :
1168 0 : GDrawCancelTimer( t->timer );
1169 0 : t->timer = GDrawRequestTimer( t->w, t->BackgroundTimerMS, t->BackgroundTimerMS, t );
1170 : }
1171 :
|