GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/****************************************************************************1**2*W gapgraph.c XGAP Source Frank Celler3**4**5*Y Copyright 1995-1997, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany6*Y Copyright 1997, Frank Celler, Huerth, Germany7*/8#include "utils.h"9#include "gapgraph.h"101112/****************************************************************************13**1415*F * * * * * * * * * * * * * * local variables * * * * * * * * * * * * * * *16*/1718/****************************************************************************19**2021*V GcClear . . . . . . . . . . . . . . . . . . . . . . . used to clear areas22*/23static GC GcClear;242526/****************************************************************************27**28*V GcColormap . . . . . . . . . . . . . . . . . . . . . standard color map29*/30static Colormap GcColormap;313233/****************************************************************************34**35*V GcColors . . . . . . . . . . . . . . . . . . . . . . . . . . color array36*/37static XColor GcColors[C_LAST+1];383940/****************************************************************************41**4243*F * * * * * * * * * * * * * gap graphic widget * * * * * * * * * * * * * *44*/454647/****************************************************************************48**4950*F GapGraphInitialize( <request>, <new>, <args>, <nums> ) open a new window51*/52static void GapGraphInitialize ( Widget request, Widget new, ArgList args, Cardinal *nums )53{54GapGraphicWidget w = (GapGraphicWidget) new;55XRectangle rec[1];56XGCValues val;57Display * dis;58static Boolean first = True;5960/* store width and height of our new window */61w->gap_graphic.width = request->core.width;62w->gap_graphic.height = request->core.height;63w->gap_graphic.update = True;6465/* create a new list for the graphic objects */66w->gap_graphic.objs = List(0);6768/* create a pixmap the picture */69dis = XtDisplay(new);7071/* set display */72w->gap_graphic.display = dis;7374/* create a graphic context for this window */75val.function = GXcopy;76val.plane_mask = AllPlanes;77val.foreground = BlackPixel( dis, DefaultScreen(dis) );78val.background = WhitePixel( dis, DefaultScreen(dis) );79val.line_width = 0;80val.line_style = LineSolid;81val.cap_style = CapRound;82val.fill_style = FillSolid;83w->gap_graphic.gc = XCreateGC(84dis, DefaultRootWindow(dis),85GCFunction | GCPlaneMask | GCForeground86| GCBackground | GCLineWidth | GCLineStyle87| GCCapStyle | GCFillStyle, &val );8889/* if this is the first initialize the global <GcClear> */90if ( first )91{92first = False;93val.function = GXcopy;94val.plane_mask = AllPlanes;95val.foreground = WhitePixel( dis, DefaultScreen(dis) );96val.background = BlackPixel( dis, DefaultScreen(dis) );97GcClear = XCreateGC(98dis, DefaultRootWindow(dis),99GCFunction|GCPlaneMask|GCForeground|GCBackground,100&val );101GCColorModel(dis);102}103104/* our viewport could be large then the window */105rec->x = 0;106rec->y = 0;107rec->width = w->gap_graphic.width;108rec->height = w->gap_graphic.height;109XSetClipRectangles( dis, w->gap_graphic.gc, 0, 0, rec, 1, YXSorted );110}111112113/****************************************************************************114**115*F GapGraphDestroy( <w> ) . . . . . . . . . . . . . . . . destroy a window116*/117static void GapGraphDestroy ( Widget w )118{119GGFreeGapGraphicObjects(w);120}121122123/****************************************************************************124**125*F GapGraphResize( <w> ) . . . . . . . . . . . . . . ignore resize requests126*/127static void GapGraphResize ( Widget w )128{129GapGraphicWidget gap = (GapGraphicWidget) w;130131gap->core.width = gap->gap_graphic.width;132gap->core.height = gap->gap_graphic.height;133}134135136/****************************************************************************137**138*F GapGraphExpose( <w>, <evt> ) . . . . . . . . . . . . handle an exposure139**140** The following is defined in "Xlib.h":141**142** typedef struct {143** int type;144** unsigned long serial;145** Bool send_event;146** Display *display;147** Window window;148** int x, y;149** int width, height;150** int count;151** } XExposeEvent;152**153**/154static void GapGraphExpose ( Widget w, XExposeEvent *evt, Region region )155{156GapGraphicWidget gap = (GapGraphicWidget) w;157TypeList objs = gap->gap_graphic.objs;158TypeGapGraphicObject * obj;159Int x1, y1, x2, y2;160UInt i;161162/* get the rectangle to be exposed */163x1 = evt->x; y1 = evt->y;164x2 = x1+evt->width-1; y2 = y1+evt->height-1;165166/* clear it */167XFillRectangle( gap->gap_graphic.display, XtWindow(gap), GcClear,168x1, y1, x2-x1+1, y2-y1+1 );169170/* make a sanity check for the values */171if ( x1 < 0 ) x1 = 0;172if ( x2 < 0 ) return;173if ( y1 < 0 ) y1 = 0;174if ( y2 < 0 ) return;175if ( gap->gap_graphic.width <= x1 ) return;176if ( gap->gap_graphic.width <= x2 ) x2 = gap->gap_graphic.width-1;177if ( gap->gap_graphic.height <= y1 ) return;178if ( gap->gap_graphic.height <= y2 ) y2 = gap->gap_graphic.height-1;179180/* redraw only objects inside the rectangle */181for ( i = 0; i < LEN(objs); i++ )182if ( ELM(objs,i) != 0 )183{184obj = (TypeGapGraphicObject*) ELM(objs,i);185if ( obj->x+obj->w < x1186|| obj->y+obj->h < y1187|| x2 < obj->x188|| y2 < obj->y )189continue;190GGDrawObject( w, (TypeGapGraphicObject*)ELM(objs,i), True );191}192193/* flush X11 queue (WHY?) */194XFlush( gap->gap_graphic.display );195}196197198/****************************************************************************199**200*V gapGraphicWidgetClass . . . . . . . . . . . . . . . . widget class record201*/202GapGraphicClassRec gapGraphicClassRec =203{204{205/* core fields */206/* superclass */ (WidgetClass) &widgetClassRec,207/* class_name */ "GapGraphic",208/* widget_size */ sizeof(GapGraphicRec),209/* class_initialize */ NULL,210/* class_part_initialize */ NULL,211/* class_inited */ FALSE,212/* initialize */ GapGraphInitialize,213/* initialize_hook */ NULL,214/* realize */ XtInheritRealize,215/* actions */ NULL,216/* num_actions */ 0,217/* resources */ NULL,218/* num_resources */ 0,219/* xrm_class */ NULLQUARK,220/* compress_motion */ TRUE,221/* compress_exposure */ TRUE,222/* compress_enterleave */ TRUE,223/* visible_interest */ FALSE,224/* destroy */ GapGraphDestroy,225/* resize */ XtInheritResize,226/* FIXME: Dirty Hack by Max, replaced: GapGraphResize,227I absolutely do *not* know what that means! */228/* expose */ (XtExposeProc)GapGraphExpose,229/* set_values */ NULL,230/* set_values_hook */ NULL,231/* set_values_almost */ XtInheritSetValuesAlmost,232/* get_values_hook */ NULL,233/* accept_focus */ NULL,234/* version */ XtVersion,235/* callback_private */ NULL,236/* tm_table */ NULL,237/* query_geometry */ XtInheritQueryGeometry,238/* display_accelerator */ XtInheritDisplayAccelerator,239/* extension */ NULL240},241242{243/* template fields */244/* dummy */ 0245}246};247248WidgetClass gapGraphicWidgetClass = (WidgetClass)&gapGraphicClassRec;249250251/****************************************************************************252**253254*F * * * * * * * * * * * * * color model functions * * * * * * * * * * * * *255*/256257258/****************************************************************************259**260261*F GCColorModel( <dis> ) . . . . . . . . . . . . return the color model used262**263** The following is defined in "Xlib.h":264**265** typedef struct {266** XExtData *ext_data;267** VisualID visualid;268** #if defined(__cplusplus) || defined(c_plusplus)269** int c_class;270** #else271** int class;272** #endif273** unsigned long red_mask, green_mask, blue_mask;274** int bits_per_rgb;275** int map_entries;276** } Visual;277*/278static Short gcColorModel = -1;279280static String ColorName[C_LAST+1] = {281"black", "white", "light grey", "dim grey", "red", "blue", "green"282};283284Int GCColorModel ( Display *dis )285{286Int diff, a;287Short i;288XColor c, d;289int cm; /* as defined in 'Visual' */290291if ( gcColorModel == -1 )292{293cm = DefaultVisual( dis, DefaultScreen(dis) )->class;294GcColormap = DefaultColormap( dis, DefaultScreen(dis) );295296/* reset colors */297XAllocNamedColor( dis, GcColormap, "black", &c, &d );298for ( i = 0; i <= C_LAST; i++ )299GcColors[i] = c;300301/* allocate black and white */302for ( i = 0; i <= 1; i++ )303{304XAllocNamedColor( dis, GcColormap, ColorName[i], &c, &d );305GcColors[i] = c;306}307gcColorModel = CM_BW;308309/* allocate gray */310diff = 0;311for ( i = 2; i <= C_LAST_GRAY; i++ )312{313XAllocNamedColor( dis, GcColormap, ColorName[i], &c, &d );314GcColors[i] = c;315a = (c.red+c.green+c.blue)-(d.red+c.green+c.blue);316if ( a < 0 ) diff -= a; else diff += a;317if ( c.red+c.green+c.blue == 0 )318diff = 65536;319}320if ( diff < 300 )321gcColorModel = CM_GRAY;322323/* allocate color */324if ( cm != StaticGray && cm != GrayScale )325{326diff = 0;327for ( i = C_LAST_GRAY+1; i <= C_LAST; i++ )328{329XAllocNamedColor( dis, GcColormap, ColorName[i], &c, &d );330a = (c.red+c.green+c.blue)-(d.red+c.green+c.blue);331if ( a < 0 ) diff -= a; else diff += a;332GcColors[i] = c;333if ( c.red+c.green+c.blue == 0 )334diff = 65536;335}336if ( diff < 300 )337gcColorModel = (gcColorModel==CM_GRAY)?CM_COLOR5:CM_COLOR3;338}339}340return gcColorModel;341}342343344/****************************************************************************345**346*F GCSetColorModel( <dis>, <mod> ) . . . . . . . . . . . . . set color model347*/348void GCSetColorModel ( Display *dis, Int mod, String colors )349{350Int e[10];351Int i, j; /* loop variables */352Int p;353Int s[10];354String ptr; /* pointer into <tmp> */355String tmp; /* start of split <colors> */356XColor c, d; /* allocated color */357358if ( gcColorModel != -1 )359return;360GcColormap = DefaultColormap( dis, DefaultScreen(dis) );361362/* reset colors */363XAllocNamedColor( dis, GcColormap, "black", &c, &d );364for ( i = 0; i <= C_LAST; i++ )365GcColors[i] = c;366367/* set color names */368if ( strcmp( colors, "default" ) )369{370tmp = XtMalloc(strlen(colors)+1);371strcpy( tmp, colors );372for ( i = 0, ptr = tmp; i <= C_LAST && *ptr; i++ )373{374if ( *ptr == ',' )375ptr++;376else377{378ColorName[i] = ptr;379while ( *ptr && *ptr != ',' )380ptr++;381if ( *ptr )382*ptr++ = 0;383}384}385}386387/* find ranges for color names */388p = 0;389switch ( mod )390{391case CM_BW:392s[p] = 0; e[p++] = 1;393break;394case CM_GRAY:395s[p] = 0; e[p++] = C_LAST_GRAY;396break;397case CM_COLOR3:398s[p] = 0; e[p++] = 1;399s[p] = C_LAST_GRAY+1; e[p++] = C_LAST;400break;401case CM_COLOR5:402s[p] = 0; e[p++] = C_LAST;403break;404default:405s[p] = 0; e[p++] = 1;406mod = CM_BW;407break;408}409410/* set color model */411gcColorModel = mod;412413/* allocate colors */414for ( i = 0; i < p; i++ )415for ( j = s[i]; j <= e[i]; j++ )416{417XAllocNamedColor( dis, GcColormap, ColorName[j], &c, &d );418GcColors[j] = c;419}420}421422423/****************************************************************************424**425426*F * * * * * * * * * * * gap graphic widget functions * * * * * * * * * * *427*/428429430/****************************************************************************431**432433*F GGDrawObject( <w>, <obj>, <flag> ) . . . . . . . . . . . draw an object434*/435void GGDrawObject ( Widget w, TypeGapGraphicObject *obj, Boolean flag )436{437GapGraphicWidget gap = (GapGraphicWidget) w;438GC gc;439440if ( flag )441{442gc = gap->gap_graphic.gc;443XSetForeground( gap->gap_graphic.display, gc,444GcColors[obj->color].pixel );445}446else447gc = GcClear;448switch ( obj->type )449{450case T_LINE:451XSetLineAttributes( gap->gap_graphic.display, gc,452obj->desc.line.w, LineSolid,453CapButt, JoinRound );454XDrawLine( gap->gap_graphic.display, XtWindow(gap), gc,455obj->desc.line.x1, obj->desc.line.y1,456obj->desc.line.x2, obj->desc.line.y2 );457break;458459case T_CIRCLE:460XSetLineAttributes( gap->gap_graphic.display, gc,461obj->desc.circle.w, LineSolid,462CapButt, JoinRound );463XDrawArc( gap->gap_graphic.display, XtWindow(gap), gc,464obj->desc.circle.x, obj->desc.circle.y,465obj->desc.circle.r, obj->desc.circle.r,4660, 360*64 );467break;468469case T_DISC:470XFillArc( gap->gap_graphic.display, XtWindow(gap), gc,471obj->desc.disc.x, obj->desc.disc.y,472obj->desc.disc.r, obj->desc.disc.r,4730, 360*64 );474break;475476case T_RECT:477XSetLineAttributes( gap->gap_graphic.display, gc,478obj->desc.rect.w, LineSolid,479CapButt, JoinRound );480XDrawRectangle( gap->gap_graphic.display, XtWindow(gap), gc,481obj->desc.rect.x1,482obj->desc.rect.y1,483obj->desc.rect.x2-obj->desc.rect.x1,484obj->desc.rect.y2-obj->desc.rect.y1 );485break;486487case T_BOX:488XFillRectangle( gap->gap_graphic.display, XtWindow(gap), gc,489obj->desc.rect.x1,490obj->desc.rect.y1,491obj->desc.rect.x2-obj->desc.rect.x1+1,492obj->desc.rect.y2-obj->desc.rect.y1+1 );493break;494495case T_TEXT:496XSetFont( gap->gap_graphic.display, gc,497obj->desc.text.font );498XDrawString( gap->gap_graphic.display, XtWindow(gap), gc,499obj->desc.text.x, obj->desc.text.y,500obj->desc.text.str, obj->desc.text.len );501break;502}503}504505506/****************************************************************************507**508*F GGAddObject( <w>, <obj> ) . . . . . . . . . . add to widget and draw it509*/510Int GGAddObject ( Widget w, TypeGapGraphicObject *obj )511{512GapGraphicWidget gap = (GapGraphicWidget) w;513TypeList objs = gap->gap_graphic.objs;514Int i;515516/* draw object */517GGDrawObject( w, obj, True );518519/* find free position in object list */520for ( i = 0; i < LEN(objs); i++ )521if ( ELM(objs,i) == 0 )522break;523524/* add element to the next free position */525if ( i < LEN(objs) )526ELM(objs,i) = (Pointer) obj;527else528AddList( objs, (Pointer) obj );529530/* and return the position number as object id */531return i;532}533534535/****************************************************************************536**537*F GGFreeObject( <obj> ) . . . . . . . . . . . . free memory used by <obj>538*/539void GGFreeObject ( TypeGapGraphicObject *obj )540{541switch ( obj->type )542{543case T_LINE:544case T_CIRCLE:545case T_DISC:546break;547case T_TEXT:548XtFree(obj->desc.text.str);549break;550}551XtFree((char*)obj);552}553554555/****************************************************************************556**557*F GGRemoveObject( <w>, <pos> ) . . . . . . . . . . remove and undraw <obj>558*/559Boolean GGRemoveObject ( Widget w, Int pos )560{561GapGraphicWidget gap = (GapGraphicWidget) w;562TypeList objs = gap->gap_graphic.objs;563TypeGapGraphicObject * obj;564XExposeEvent evt;565566/* find graphic object and clear entry */567if ( ( obj = (TypeGapGraphicObject*) ELM(objs,pos) ) == 0 )568return True;569ELM(objs,pos) = 0;570571/* update this region */572if ( gap->gap_graphic.fast_update )573{574if ( -1==gap->gap_graphic.lx || obj->x<gap->gap_graphic.lx )575gap->gap_graphic.lx = obj->x;576if ( -1==gap->gap_graphic.ly || obj->y<gap->gap_graphic.ly )577gap->gap_graphic.ly = obj->y;578if ( -1==gap->gap_graphic.hx || gap->gap_graphic.hx<=obj->x+obj->w )579gap->gap_graphic.hx = obj->x+obj->w+1;580if ( -1==gap->gap_graphic.hy || gap->gap_graphic.hy<=obj->y+obj->h )581gap->gap_graphic.hy = obj->y+obj->h+1;582GGDrawObject( w, obj, False );583}584else if ( gap->gap_graphic.update )585{586evt.x = obj->x;587evt.y = obj->y;588evt.width = obj->w;589evt.height = obj->h;590GapGraphExpose( w, &evt, 0 );591}592else593{594if ( -1==gap->gap_graphic.lx || obj->x<gap->gap_graphic.lx )595gap->gap_graphic.lx = obj->x;596if ( -1==gap->gap_graphic.ly || obj->y<gap->gap_graphic.ly )597gap->gap_graphic.ly = obj->y;598if ( -1==gap->gap_graphic.hx || gap->gap_graphic.hx<=obj->x+obj->w )599gap->gap_graphic.hx = obj->x+obj->w+1;600if ( -1==gap->gap_graphic.hy || gap->gap_graphic.hy<=obj->y+obj->h )601gap->gap_graphic.hy = obj->y+obj->h+1;602}603604/* free memory and return that we did something */605GGFreeObject(obj);606return False;607}608609610/****************************************************************************611**612*F GGStartRemove( <w> ) . . . . . . . . . . . . start a sequence of removes613*/614void GGStartRemove ( Widget w )615{616GapGraphicWidget gap = (GapGraphicWidget) w;617618gap->gap_graphic.update = False;619gap->gap_graphic.lx = -1;620gap->gap_graphic.hx = -1;621gap->gap_graphic.ly = -1;622gap->gap_graphic.hy = -1;623}624625626/****************************************************************************627**628*F GGStopRemove( <w> ) . . . stop a sequence of removes and update window629*/630void GGStopRemove ( Widget w )631{632GapGraphicWidget gap = (GapGraphicWidget) w;633XExposeEvent evt;634635gap->gap_graphic.update = True;636evt.x = gap->gap_graphic.lx;637evt.y = gap->gap_graphic.ly;638evt.width = gap->gap_graphic.hx - gap->gap_graphic.lx + 1;639evt.height = gap->gap_graphic.hy - gap->gap_graphic.ly + 1;640GapGraphExpose( w, &evt, 0 );641}642643644/****************************************************************************645**646*F GGFastUpdate( <w>, <flag> ) . . . . . . . . . . . en/disable fast update647*/648void GGFastUpdate ( Widget w, Boolean flag )649{650GapGraphicWidget gap = (GapGraphicWidget) w;651XExposeEvent evt;652653if ( gap->gap_graphic.fast_update == flag || !gap->gap_graphic.update )654return;655gap->gap_graphic.fast_update = flag;656if ( !flag )657{658evt.x = gap->gap_graphic.lx;659evt.y = gap->gap_graphic.ly;660evt.width = gap->gap_graphic.hx - gap->gap_graphic.lx + 1;661evt.height = gap->gap_graphic.hy - gap->gap_graphic.ly + 1;662GapGraphExpose( w, &evt, 0 );663}664else665{666gap->gap_graphic.lx = -1;667gap->gap_graphic.hx = -1;668gap->gap_graphic.ly = -1;669gap->gap_graphic.hy = -1;670}671672}673674675/****************************************************************************676**677*F GGFreeAllObjects( <w> ) . . . . . remove and undraw all window objects678*/679void GGFreeAllObjects ( Widget w )680{681GapGraphicWidget gap = (GapGraphicWidget) w;682TypeList objs = gap->gap_graphic.objs;683Int i;684685for ( i = 0; i < LEN(objs); i++ )686if ( ELM(objs,i) != 0 )687GGFreeObject(ELM(objs,i));688XFillRectangle( gap->gap_graphic.display, XtWindow(gap), GcClear,6890, 0, gap->gap_graphic.width, gap->gap_graphic.height );690LEN(objs) = 0;691}692693694/****************************************************************************695**696*F GGFreeGapGraphicObjects( <w> ) free all objects/list associated with <w>697*/698void GGFreeGapGraphicObjects ( Widget w )699{700GapGraphicWidget gap = (GapGraphicWidget) w;701TypeList objs = gap->gap_graphic.objs;702703if ( objs == 0 )704return;705GGFreeAllObjects(w);706XtFree((char*)(objs->ptr));707XtFree((char*)(objs));708gap->gap_graphic.objs = 0;709}710711712/****************************************************************************713**714*F GGResize( <w> ) . . . . . . . . . . . . . . . . . . . . . . resize <w>715*/716void GGResize ( Widget w, Int width, Int height )717{718GapGraphicWidget gap = (GapGraphicWidget) w;719XtWidgetGeometry req;720XRectangle rec[1];721722/* enter new dimensions */723req.width = gap->gap_graphic.width = width;724req.height = gap->gap_graphic.height = height;725req.request_mode = CWWidth | CWHeight;726727/* and make request, ignore the result */728XtMakeGeometryRequest( w, &req, 0 );729XtResizeWidget( w, (Dimension) width, (Dimension) height, 0 );730gap->gap_graphic.width = gap->core.width = width;731gap->gap_graphic.height = gap->core.height = height;732733/* and set new clipping */734rec->x = 0;735rec->y = 0;736rec->width = gap->gap_graphic.width;737rec->height = gap->gap_graphic.height;738XSetClipRectangles(XtDisplay(w),gap->gap_graphic.gc,0,0,rec,1,YXSorted);739}740741742/****************************************************************************743**744745*E gapgraph.c . . . . . . . . . . . . . . . . . . . . . . . . . . ends here746*/747748749750