LCOV - code coverage report
Current view: top level - gdraw - gdraw.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 6 705 0.9 %
Date: 2017-08-04 Functions: 2 153 1.3 %

          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             : 

Generated by: LCOV version 1.10