/****************************************************************************
* *
* W gapgraph . c XGAP Source Frank Celler
* *
* *
* Y Copyright 1995 - 1997 , Lehrstuhl D fuer Mathematik , RWTH Aachen , Germany
* Y Copyright 1997 , Frank Celler , Huerth , Germany
*/
#include "utils.h"
#include "gapgraph.h"
/****************************************************************************
* *
* F * * * * * * * * * * * * * * local variables * * * * * * * * * * * * * * *
*/
/****************************************************************************
* *
* V GcClear . . . . . . . . . . . . . . . . . . . . . . . used to clear areas
*/
static GC GcClear;
/****************************************************************************
* *
* V GcColormap . . . . . . . . . . . . . . . . . . . . . standard color map
*/
static Colormap GcColormap;
/****************************************************************************
* *
* V GcColors . . . . . . . . . . . . . . . . . . . . . . . . . . color array
*/
static XColor GcColors[C_LAST+1 ];
/****************************************************************************
* *
* F * * * * * * * * * * * * * gap graphic widget * * * * * * * * * * * * * *
*/
/****************************************************************************
* *
* F GapGraphInitialize ( < request > , < new > , < args > , < nums > ) open a new window
*/
static void GapGraphInitialize ( Widget request, Widget new , ArgList args, Cardinal *nums )
{
GapGraphicWidget w = (GapGraphicWidget) new ;
XRectangle rec[1 ];
XGCValues val;
Display * dis;
static Boolean first = True ;
/* store width and height of our new window */
w->gap_graphic.width = request->core.width;
w->gap_graphic.height = request->core.height;
w->gap_graphic.update = True ;
/* create a new list for the graphic objects */
w->gap_graphic.objs = List(0 );
/* create a pixmap the picture */
dis = XtDisplay(new );
/* set display */
w->gap_graphic.display = dis;
/* create a graphic context for this window */
val.function = GXcopy;
val.plane_mask = AllPlanes;
val.foreground = BlackPixel( dis, DefaultScreen(dis) );
val.background = WhitePixel( dis, DefaultScreen(dis) );
val.line_width = 0 ;
val.line_style = LineSolid;
val.cap_style = CapRound;
val.fill_style = FillSolid;
w->gap_graphic.gc = XCreateGC(
dis, DefaultRootWindow(dis),
GCFunction | GCPlaneMask | GCForeground
| GCBackground | GCLineWidth | GCLineStyle
| GCCapStyle | GCFillStyle, &val );
/* if this is the first initialize the global <GcClear> */
if ( first )
{
first = False ;
val.function = GXcopy;
val.plane_mask = AllPlanes;
val.foreground = WhitePixel( dis, DefaultScreen(dis) );
val.background = BlackPixel( dis, DefaultScreen(dis) );
GcClear = XCreateGC(
dis, DefaultRootWindow(dis),
GCFunction|GCPlaneMask|GCForeground|GCBackground,
&val );
GCColorModel(dis);
}
/* our viewport could be large then the window */
rec->x = 0 ;
rec->y = 0 ;
rec->width = w->gap_graphic.width;
rec->height = w->gap_graphic.height;
XSetClipRectangles( dis, w->gap_graphic.gc, 0 , 0 , rec, 1 , YXSorted );
}
/****************************************************************************
* *
* F GapGraphDestroy ( < w > ) . . . . . . . . . . . . . . . . destroy a window
*/
static void GapGraphDestroy ( Widget w )
{
GGFreeGapGraphicObjects(w);
}
/****************************************************************************
* *
* F GapGraphResize ( < w > ) . . . . . . . . . . . . . . ignore resize requests
*/
static void GapGraphResize ( Widget w )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
gap->core.width = gap->gap_graphic.width;
gap->core.height = gap->gap_graphic.height;
}
/****************************************************************************
* *
* F GapGraphExpose ( < w > , < evt > ) . . . . . . . . . . . . handle an exposure
* *
* * The following is defined in " Xlib . h " :
* *
* * typedef struct {
* * int type ;
* * unsigned long serial ;
* * Bool send_event ;
* * Display * display ;
* * Window window ;
* * int x , y ;
* * int width , height ;
* * int count ;
* * } XExposeEvent ;
* *
**/
static void GapGraphExpose ( Widget w, XExposeEvent *evt, Region region )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
TypeList objs = gap->gap_graphic.objs;
TypeGapGraphicObject * obj;
Int x1, y1, x2, y2;
UInt i;
/* get the rectangle to be exposed */
x1 = evt->x; y1 = evt->y;
x2 = x1+evt->width-1 ; y2 = y1+evt->height-1 ;
/* clear it */
XFillRectangle( gap->gap_graphic.display, XtWindow(gap), GcClear,
x1, y1, x2-x1+1 , y2-y1+1 );
/* make a sanity check for the values */
if ( x1 < 0 ) x1 = 0 ;
if ( x2 < 0 ) return ;
if ( y1 < 0 ) y1 = 0 ;
if ( y2 < 0 ) return ;
if ( gap->gap_graphic.width <= x1 ) return ;
if ( gap->gap_graphic.width <= x2 ) x2 = gap->gap_graphic.width-1 ;
if ( gap->gap_graphic.height <= y1 ) return ;
if ( gap->gap_graphic.height <= y2 ) y2 = gap->gap_graphic.height-1 ;
/* redraw only objects inside the rectangle */
for ( i = 0 ; i < LEN(objs); i++ )
if ( ELM(objs,i) != 0 )
{
obj = (TypeGapGraphicObject*) ELM(objs,i);
if ( obj->x+obj->w < x1
|| obj->y+obj->h < y1
|| x2 < obj->x
|| y2 < obj->y )
continue ;
GGDrawObject( w, (TypeGapGraphicObject*)ELM(objs,i), True );
}
/* flush X11 queue (WHY?) */
XFlush( gap->gap_graphic.display );
}
/****************************************************************************
* *
* V gapGraphicWidgetClass . . . . . . . . . . . . . . . . widget class record
*/
GapGraphicClassRec gapGraphicClassRec =
{
{
/* core fields */
/* superclass */ (WidgetClass) &widgetClassRec,
/* class_name */ "GapGraphic",
/* widget_size */ sizeof(GapGraphicRec),
/* class_initialize */ NULL,
/* class_part_initialize */ NULL,
/* class_inited */ FALSE,
/* initialize */ GapGraphInitialize,
/* initialize_hook */ NULL,
/* realize */ XtInheritRealize,
/* actions */ NULL,
/* num_actions */ 0,
/* resources */ NULL,
/* num_resources */ 0,
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave */ TRUE,
/* visible_interest */ FALSE,
/* destroy */ GapGraphDestroy,
/* resize */ XtInheritResize,
/* FIXME: Dirty Hack by Max, replaced: GapGraphResize,
I absolutely do *not* know what that means! */
/* expose */ (XtExposeProc)GapGraphExpose,
/* set_values */ NULL,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ NULL,
/* query_geometry */ XtInheritQueryGeometry,
/* display_accelerator */ XtInheritDisplayAccelerator,
/* extension */ NULL
},
{
/* template fields */
/* dummy */ 0
}
};
WidgetClass gapGraphicWidgetClass = (WidgetClass)&gapGraphicClassRec;
/****************************************************************************
* *
* F * * * * * * * * * * * * * color model functions * * * * * * * * * * * * *
*/
/****************************************************************************
* *
* F GCColorModel ( < dis > ) . . . . . . . . . . . . return the color model used
* *
* * The following is defined in " Xlib . h " :
* *
* * typedef struct {
* * XExtData * ext_data ;
* * VisualID visualid ;
* * # if defined ( _ _ cplusplus ) | | defined ( c_plusplus )
* * int c_class ;
* * # else
* * int class ;
* * # endif
* * unsigned long red_mask , green_mask , blue_mask ;
* * int bits_per_rgb ;
* * int map_entries ;
* * } Visual ;
*/
static Short gcColorModel = -1 ;
static String ColorName[C_LAST+1 ] = {
"black" , "white" , "light grey" , "dim grey" , "red" , "blue" , "green"
};
Int GCColorModel ( Display *dis )
{
Int diff, a;
Short i;
XColor c, d;
int cm; /* as defined in 'Visual' */
if ( gcColorModel == -1 )
{
cm = DefaultVisual( dis, DefaultScreen(dis) )->class ;
GcColormap = DefaultColormap( dis, DefaultScreen(dis) );
/* reset colors */
XAllocNamedColor( dis, GcColormap, "black" , &c, &d );
for ( i = 0 ; i <= C_LAST; i++ )
GcColors[i] = c;
/* allocate black and white */
for ( i = 0 ; i <= 1 ; i++ )
{
XAllocNamedColor( dis, GcColormap, ColorName[i], &c, &d );
GcColors[i] = c;
}
gcColorModel = CM_BW;
/* allocate gray */
diff = 0 ;
for ( i = 2 ; i <= C_LAST_GRAY; i++ )
{
XAllocNamedColor( dis, GcColormap, ColorName[i], &c, &d );
GcColors[i] = c;
a = (c.red+c.green+c.blue)-(d.red+c.green+c.blue);
if ( a < 0 ) diff -= a; else diff += a;
if ( c.red+c.green+c.blue == 0 )
diff = 65536 ;
}
if ( diff < 300 )
gcColorModel = CM_GRAY;
/* allocate color */
if ( cm != StaticGray && cm != GrayScale )
{
diff = 0 ;
for ( i = C_LAST_GRAY+1 ; i <= C_LAST; i++ )
{
XAllocNamedColor( dis, GcColormap, ColorName[i], &c, &d );
a = (c.red+c.green+c.blue)-(d.red+c.green+c.blue);
if ( a < 0 ) diff -= a; else diff += a;
GcColors[i] = c;
if ( c.red+c.green+c.blue == 0 )
diff = 65536 ;
}
if ( diff < 300 )
gcColorModel = (gcColorModel==CM_GRAY)?CM_COLOR5:CM_COLOR3;
}
}
return gcColorModel;
}
/****************************************************************************
* *
* F GCSetColorModel ( < dis > , < mod > ) . . . . . . . . . . . . . set color model
*/
void GCSetColorModel ( Display *dis, Int mod, String colors )
{
Int e[10 ];
Int i, j; /* loop variables */
Int p;
Int s[10 ];
String ptr; /* pointer into <tmp> */
String tmp; /* start of split <colors> */
XColor c, d; /* allocated color */
if ( gcColorModel != -1 )
return ;
GcColormap = DefaultColormap( dis, DefaultScreen(dis) );
/* reset colors */
XAllocNamedColor( dis, GcColormap, "black" , &c, &d );
for ( i = 0 ; i <= C_LAST; i++ )
GcColors[i] = c;
/* set color names */
if ( strcmp( colors, "default" ) )
{
tmp = XtMalloc(strlen(colors)+1 );
strcpy( tmp, colors );
for ( i = 0 , ptr = tmp; i <= C_LAST && *ptr; i++ )
{
if ( *ptr == ',' )
ptr++;
else
{
ColorName[i] = ptr;
while ( *ptr && *ptr != ',' )
ptr++;
if ( *ptr )
*ptr++ = 0 ;
}
}
}
/* find ranges for color names */
p = 0 ;
switch ( mod )
{
case CM_BW:
s[p] = 0 ; e[p++] = 1 ;
break ;
case CM_GRAY:
s[p] = 0 ; e[p++] = C_LAST_GRAY;
break ;
case CM_COLOR3:
s[p] = 0 ; e[p++] = 1 ;
s[p] = C_LAST_GRAY+1 ; e[p++] = C_LAST;
break ;
case CM_COLOR5:
s[p] = 0 ; e[p++] = C_LAST;
break ;
default :
s[p] = 0 ; e[p++] = 1 ;
mod = CM_BW;
break ;
}
/* set color model */
gcColorModel = mod;
/* allocate colors */
for ( i = 0 ; i < p; i++ )
for ( j = s[i]; j <= e[i]; j++ )
{
XAllocNamedColor( dis, GcColormap, ColorName[j], &c, &d );
GcColors[j] = c;
}
}
/****************************************************************************
* *
* F * * * * * * * * * * * gap graphic widget functions * * * * * * * * * * *
*/
/****************************************************************************
* *
* F GGDrawObject ( < w > , < obj > , < flag > ) . . . . . . . . . . . draw an object
*/
void GGDrawObject ( Widget w, TypeGapGraphicObject *obj, Boolean flag )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
GC gc;
if ( flag )
{
gc = gap->gap_graphic.gc;
XSetForeground( gap->gap_graphic.display, gc,
GcColors[obj->color].pixel );
}
else
gc = GcClear;
switch ( obj->type )
{
case T_LINE:
XSetLineAttributes( gap->gap_graphic.display, gc,
obj->desc.line.w, LineSolid,
CapButt, JoinRound );
XDrawLine( gap->gap_graphic.display, XtWindow(gap), gc,
obj->desc.line.x1, obj->desc.line.y1,
obj->desc.line.x2, obj->desc.line.y2 );
break ;
case T_CIRCLE:
XSetLineAttributes( gap->gap_graphic.display, gc,
obj->desc.circle.w, LineSolid,
CapButt, JoinRound );
XDrawArc( gap->gap_graphic.display, XtWindow(gap), gc,
obj->desc.circle.x, obj->desc.circle.y,
obj->desc.circle.r, obj->desc.circle.r,
0 , 360 *64 );
break ;
case T_DISC:
XFillArc( gap->gap_graphic.display, XtWindow(gap), gc,
obj->desc.disc.x, obj->desc.disc.y,
obj->desc.disc.r, obj->desc.disc.r,
0 , 360 *64 );
break ;
case T_RECT:
XSetLineAttributes( gap->gap_graphic.display, gc,
obj->desc.rect.w, LineSolid,
CapButt, JoinRound );
XDrawRectangle( gap->gap_graphic.display, XtWindow(gap), gc,
obj->desc.rect.x1,
obj->desc.rect.y1,
obj->desc.rect.x2-obj->desc.rect.x1,
obj->desc.rect.y2-obj->desc.rect.y1 );
break ;
case T_BOX:
XFillRectangle( gap->gap_graphic.display, XtWindow(gap), gc,
obj->desc.rect.x1,
obj->desc.rect.y1,
obj->desc.rect.x2-obj->desc.rect.x1+1 ,
obj->desc.rect.y2-obj->desc.rect.y1+1 );
break ;
case T_TEXT:
XSetFont( gap->gap_graphic.display, gc,
obj->desc.text.font );
XDrawString( gap->gap_graphic.display, XtWindow(gap), gc,
obj->desc.text.x, obj->desc.text.y,
obj->desc.text.str, obj->desc.text.len );
break ;
}
}
/****************************************************************************
* *
* F GGAddObject ( < w > , < obj > ) . . . . . . . . . . add to widget and draw it
*/
Int GGAddObject ( Widget w, TypeGapGraphicObject *obj )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
TypeList objs = gap->gap_graphic.objs;
Int i;
/* draw object */
GGDrawObject( w, obj, True );
/* find free position in object list */
for ( i = 0 ; i < LEN(objs); i++ )
if ( ELM(objs,i) == 0 )
break ;
/* add element to the next free position */
if ( i < LEN(objs) )
ELM(objs,i) = (Pointer) obj;
else
AddList( objs, (Pointer) obj );
/* and return the position number as object id */
return i;
}
/****************************************************************************
* *
* F GGFreeObject ( < obj > ) . . . . . . . . . . . . free memory used by < obj >
*/
void GGFreeObject ( TypeGapGraphicObject *obj )
{
switch ( obj->type )
{
case T_LINE:
case T_CIRCLE:
case T_DISC:
break ;
case T_TEXT:
XtFree(obj->desc.text.str);
break ;
}
XtFree((char *)obj);
}
/****************************************************************************
* *
* F GGRemoveObject ( < w > , < pos > ) . . . . . . . . . . remove and undraw < obj >
*/
Boolean GGRemoveObject ( Widget w, Int pos )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
TypeList objs = gap->gap_graphic.objs;
TypeGapGraphicObject * obj;
XExposeEvent evt;
/* find graphic object and clear entry */
if ( ( obj = (TypeGapGraphicObject*) ELM(objs,pos) ) == 0 )
return True ;
ELM(objs,pos) = 0 ;
/* update this region */
if ( gap->gap_graphic.fast_update )
{
if ( -1 ==gap->gap_graphic.lx || obj->x<gap->gap_graphic.lx )
gap->gap_graphic.lx = obj->x;
if ( -1 ==gap->gap_graphic.ly || obj->y<gap->gap_graphic.ly )
gap->gap_graphic.ly = obj->y;
if ( -1 ==gap->gap_graphic.hx || gap->gap_graphic.hx<=obj->x+obj->w )
gap->gap_graphic.hx = obj->x+obj->w+1 ;
if ( -1 ==gap->gap_graphic.hy || gap->gap_graphic.hy<=obj->y+obj->h )
gap->gap_graphic.hy = obj->y+obj->h+1 ;
GGDrawObject( w, obj, False );
}
else if ( gap->gap_graphic.update )
{
evt.x = obj->x;
evt.y = obj->y;
evt.width = obj->w;
evt.height = obj->h;
GapGraphExpose( w, &evt, 0 );
}
else
{
if ( -1 ==gap->gap_graphic.lx || obj->x<gap->gap_graphic.lx )
gap->gap_graphic.lx = obj->x;
if ( -1 ==gap->gap_graphic.ly || obj->y<gap->gap_graphic.ly )
gap->gap_graphic.ly = obj->y;
if ( -1 ==gap->gap_graphic.hx || gap->gap_graphic.hx<=obj->x+obj->w )
gap->gap_graphic.hx = obj->x+obj->w+1 ;
if ( -1 ==gap->gap_graphic.hy || gap->gap_graphic.hy<=obj->y+obj->h )
gap->gap_graphic.hy = obj->y+obj->h+1 ;
}
/* free memory and return that we did something */
GGFreeObject(obj);
return False ;
}
/****************************************************************************
* *
* F GGStartRemove ( < w > ) . . . . . . . . . . . . start a sequence of removes
*/
void GGStartRemove ( Widget w )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
gap->gap_graphic.update = False ;
gap->gap_graphic.lx = -1 ;
gap->gap_graphic.hx = -1 ;
gap->gap_graphic.ly = -1 ;
gap->gap_graphic.hy = -1 ;
}
/****************************************************************************
* *
* F GGStopRemove ( < w > ) . . . stop a sequence of removes and update window
*/
void GGStopRemove ( Widget w )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
XExposeEvent evt;
gap->gap_graphic.update = True ;
evt.x = gap->gap_graphic.lx;
evt.y = gap->gap_graphic.ly;
evt.width = gap->gap_graphic.hx - gap->gap_graphic.lx + 1 ;
evt.height = gap->gap_graphic.hy - gap->gap_graphic.ly + 1 ;
GapGraphExpose( w, &evt, 0 );
}
/****************************************************************************
* *
* F GGFastUpdate ( < w > , < flag > ) . . . . . . . . . . . en / disable fast update
*/
void GGFastUpdate ( Widget w, Boolean flag )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
XExposeEvent evt;
if ( gap->gap_graphic.fast_update == flag || !gap->gap_graphic.update )
return ;
gap->gap_graphic.fast_update = flag;
if ( !flag )
{
evt.x = gap->gap_graphic.lx;
evt.y = gap->gap_graphic.ly;
evt.width = gap->gap_graphic.hx - gap->gap_graphic.lx + 1 ;
evt.height = gap->gap_graphic.hy - gap->gap_graphic.ly + 1 ;
GapGraphExpose( w, &evt, 0 );
}
else
{
gap->gap_graphic.lx = -1 ;
gap->gap_graphic.hx = -1 ;
gap->gap_graphic.ly = -1 ;
gap->gap_graphic.hy = -1 ;
}
}
/****************************************************************************
* *
* F GGFreeAllObjects ( < w > ) . . . . . remove and undraw all window objects
*/
void GGFreeAllObjects ( Widget w )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
TypeList objs = gap->gap_graphic.objs;
Int i;
for ( i = 0 ; i < LEN(objs); i++ )
if ( ELM(objs,i) != 0 )
GGFreeObject(ELM(objs,i));
XFillRectangle( gap->gap_graphic.display, XtWindow(gap), GcClear,
0 , 0 , gap->gap_graphic.width, gap->gap_graphic.height );
LEN(objs) = 0 ;
}
/****************************************************************************
* *
* F GGFreeGapGraphicObjects ( < w > ) free all objects / list associated with < w >
*/
void GGFreeGapGraphicObjects ( Widget w )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
TypeList objs = gap->gap_graphic.objs;
if ( objs == 0 )
return ;
GGFreeAllObjects(w);
XtFree((char *)(objs->ptr));
XtFree((char *)(objs));
gap->gap_graphic.objs = 0 ;
}
/****************************************************************************
* *
* F GGResize ( < w > ) . . . . . . . . . . . . . . . . . . . . . . resize < w >
*/
void GGResize ( Widget w, Int width, Int height )
{
GapGraphicWidget gap = (GapGraphicWidget) w;
XtWidgetGeometry req;
XRectangle rec[1 ];
/* enter new dimensions */
req.width = gap->gap_graphic.width = width;
req.height = gap->gap_graphic.height = height;
req.request_mode = CWWidth | CWHeight;
/* and make request, ignore the result */
XtMakeGeometryRequest( w, &req, 0 );
XtResizeWidget( w, (Dimension) width, (Dimension) height, 0 );
gap->gap_graphic.width = gap->core.width = width;
gap->gap_graphic.height = gap->core.height = height;
/* and set new clipping */
rec->x = 0 ;
rec->y = 0 ;
rec->width = gap->gap_graphic.width;
rec->height = gap->gap_graphic.height;
XSetClipRectangles(XtDisplay(w),gap->gap_graphic.gc,0 ,0 ,rec,1 ,YXSorted);
}
/****************************************************************************
* *
* E gapgraph . c . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
*/
Messung V0.5 in Prozent C=88 H=86 G=86
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet am 2026-07-01)
¤
*© Formatika GbR, Deutschland