/****************************************************************************
**
*W xgap.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" /* utility functions */
#include "popdial.h" /* popup dialogs */
#include "gapgraph.h" /* gap graphic sheet */
#include "gaptext.h" /* gap text sheet */
#include "popdial.h" /* popup dialogs */
#include "xcmds.h"
#include "pty.h"
#include "selfile.h"
#include "xgap.h"
/****************************************************************************
**
*F * * * * * * * * * * * * * * global variables * * * * * * * * * * * * * *
*/
/****************************************************************************
**
*V AppContext . . . . . . . . . . . . . . . . . . . . . application context
*/
XtAppContext AppContext;
/****************************************************************************
**
*V GapDisplay . . . . . . . . . . . . . . . . . . . . . . . current display
*/
Display * GapDisplay;
/****************************************************************************
**
*V GapScreen . . . . . . . . . . . . . . . . . . . . . . . . current screen
*/
long GapScreen;
/****************************************************************************
**
*V GapState . . . . . . . . . . . . . . . . . . . . . . . . . status of gap
*/
#define GAP_NOGAP 0
#define GAP_RUNNING 1
#define GAP_INPUT 2
#define GAP_ERROR 3
#define GAP_HELP 4
Int GapState = GAP_NOGAP;
/****************************************************************************
**
*V GapTalk . . . . . . . . . . . . . . . . . . . . . . . . . gap text window
*/
Widget GapTalk;
/****************************************************************************
**
*V MyRootWindow . . . . . . . . . . . . . . . . . . . . current root window
*/
Drawable MyRootWindow;
/****************************************************************************
**
*V SpyMode . . . . . . . . . . . . . . . . . . . . copy GAP output to stderr
*/
Boolean SpyMode = False;
/****************************************************************************
**
*V WmDeleteWindowAtom . . . . . . . window manager "delete window" request
*/
Atom WmDeleteWindowAtom;
/****************************************************************************
**
*V XGap . . . . . . . . . . . . . . . . . . . . . . . . . . toplevel shell
*/
Widget XGap;
/****************************************************************************
**
*F * * * * * * * * * * * * * * various symbols * * * * * * * * * * * * * * *
*/
/****************************************************************************
**
*V CheckMarkSymbol . . . . . . . . . . . . . symbol for checked menu entries
*/
Pixmap CheckMarkSymbol;
/****************************************************************************
**
*V CursorTL . . . . . . . . . . . . . . . . . . . . . . . . top left arrow
*/
Cursor CursorTL;
/****************************************************************************
**
*V EmptyMarkSymbol . . . . . . . . . . . . symbol for unchecked menu entries
*/
Pixmap EmptyMarkSymbol;
/****************************************************************************
**
*V ExMarkSymbol . . . . . . . . . . . . . . . . . . . . . exclamation mark
*/
Pixmap ExMarkSymbol;
/****************************************************************************
**
*V MenuSymbol . . . . . . . . . . . . . . . . . symbol for drop down menus
*/
Pixmap MenuSymbol;
/****************************************************************************
**
*F * * * * * * * * * * * * * * local variables * * * * * * * * * * * * * * *
*/
/****************************************************************************
**
*V CommandOptions . . . . . . . . . . . . . . . . . . command line options
*/
static XrmOptionDescRec CommandOptions[] =
{
{ "-colorModel", "*colorModel", XrmoptionSepArg, 0 },
{ "-colors", "*colors", XrmoptionSepArg, 0 },
{ "-huge", "*hugeFont", XrmoptionSepArg, 0 },
{ "-hugeFont", "*hugeFont", XrmoptionSepArg, 0 },
{ "-large", "*largeFont", XrmoptionSepArg, 0 },
{ "-largeFont", "*largeFont", XrmoptionSepArg, 0 },
{ "-normal", "*normalFont", XrmoptionSepArg, 0 },
{ "-normalFont", "*normalFont", XrmoptionSepArg, 0 },
{ "-positionTitle", "*titlePosition", XrmoptionSepArg, 0 },
{ "-small", "*smallFont", XrmoptionSepArg, 0 },
{ "-smallFont", "*smallFont", XrmoptionSepArg, 0 },
{ "-tiny", "*tinyFont", XrmoptionSepArg, 0 },
{ "-tinyFont", "*tinyFont", XrmoptionSepArg, 0 },
{ "-titlePosition", "*titlePosition", XrmoptionSepArg, 0 },
{ "-tp", "*titlePosition", XrmoptionSepArg, 0 },
};
/****************************************************************************
**
*V FallbackResources . . . . . . . . . . . . . . . . . . . default resources
*/
static char *FallbackResources[] =
{
"*menu.line.height: 10",
"*xgapMenu*shapeStyle: Oval",
"*xgapDialog*shapeStyle: Oval",
/* gap talk window */
"*xgapTalk.height: 600",
"*xgapTalk.width: 600",
"*xgapMenu.showGrip: False",
"*xgapTalk.showGrip: False",
"*xgapTalk.quitGapCtrD: True",
"*xgapTalk.pasteGapPrompt: True",
/* gap menu */
"*xgapMenu.gapButton.label: GAP",
"*xgapMenu.gapButton*pastePrompt.label: Paste 'gap>'",
"*xgapMenu.gapButton*quitGapCTRD.label: Quit on CTR-D",
"*xgapMenu.gapButton*editFile.label: Edit File ...",
"*xgapMenu.gapButton*readFile.label: Read File ...",
"*xgapMenu.gapButton*changeLib.label: Change Library ...",
#ifdef DEBUG_ON
"*xgapMenu.gapButton*resyncGap.label: Resync with GAP",
#endif
"*xgapMenu.gapButton*quit.label: Quit GAP",
"*xgapMenu.gapButton*kill.label: Kill GAP",
/* run menu */
"*xgapMenu.runButton.label: Run",
"*xgapMenu.runButton*quitBreak.label: Leave Breakloop",
"*xgapMenu.runButton*contBreak.label: Continue Execution",
"*xgapMenu.runButton*interrupt.label: Interrupt",
"*xgapMenu.runButton*garbColl.label: Collect Garbage",
"*xgapMenu.runButton*garbMesg.label: Toggle GC Messages",
/* help menu */
"*xgapMenu.helpButton.label: Help",
"*xgapMenu.helpButton*copyHelp.label: Copyright",
"*xgapMenu.helpButton*helpHelp.label: Helpsystem",
"*xgapMenu.helpButton*chpsHelp.label: Chapters",
"*xgapMenu.helpButton*secsHelp.label: Sections",
"*xgapMenu.helpButton*nchpHelp.label: Next Chapter",
"*xgapMenu.helpButton*pchpHelp.label: Previous Chapter",
"*xgapMenu.helpButton*nextHelp.label: Next Help Section",
"*xgapMenu.helpButton*prevHelp.label: Previous Help Section",
/* gap graphic window */
"*xgapWindowViewport.width: 800",
"*xgapWindowViewport.height: 600",
/* query a input file name */
#ifdef NO_FILE_SELECTOR
"*queryFileName.xgapDialog.icon: Term",
#else
"*selFileCancel*ShapeStyle: Oval",
"*selFileCancel*label: Cancel",
"*selFileOK*ShapeStyle: Oval",
"*selFileOK*label: OK",
"*selFileHome*ShapeStyle: Oval",
"*selFileHome*label: Home",
#endif
0
};
/****************************************************************************
**
*F * * * * * * * * * * * * gap talk window menus * * * * * * * * * * * * * *
*/
/****************************************************************************
**
*V GapMenu . . . . . . . . . . . . . . . . . . . . . . . . xgap's "GAP" menu
**
*/
static void MenuQuitGap (TypeMenuItem *item)
{
KeyboardInput( "@C@A@Kquit;\nquit;\n", 18 );
}
static void MenuKillGap (TypeMenuItem *item)
{
KillGap();
}
#ifdef DEBUG_ON
static void MenuResyncGap ()
{
ExecRunning = 0;
GapState = GAP_INPUT;
UpdateMenus(GapState);
UpdateXCMDS(True);
ProcessStoredInput(0);
}
#endif
static void MenuPastePrompt (
TypeMenuItem * item)
{
static Boolean paste = False;
paste = !paste;
GTDropGapPrompt( GapTalk, !paste );
if ( paste )
XtVaSetValues( item->entry, XtNrightBitmap, (XtArgVal)CheckMarkSymbol,
(String)NULL );
else
XtVaSetValues( item->entry, XtNrightBitmap, (XtArgVal)EmptyMarkSymbol,
(String)NULL );
}
static void MenuQuitGapCTRD (
TypeMenuItem * item)
{
QuitGapCtrlD = !QuitGapCtrlD;
if ( QuitGapCtrlD )
XtVaSetValues( item->entry, XtNrightBitmap, (XtArgVal)CheckMarkSymbol,
(String)NULL );
else
XtVaSetValues( item->entry, XtNrightBitmap, (XtArgVal)EmptyMarkSymbol,
(String)NULL );
}
#ifndef NO_FILE_SELECTOR
void MenuReadFile (
TypeMenuItem * item)
{
Int res;
String str;
String input;
res = XsraSelFile( XGap, "Select a File", 0, 0, &str );
if ( res && str[0] )
{
input = XtMalloc( strlen(str)+30 );
strcpy( input, "Read( \"" );
strcat( input, str );
strcat( input, "\" );\n" );
SimulateInput(input);
XtFree(input);
XtFree(str);
}
}
#endif
static TypeMenuItem GapMenu[] =
{
{ "pastePrompt", MenuPastePrompt, S_ALWAYS, 0 },
{ "quitGapCTRD", MenuQuitGapCTRD, S_ALWAYS, 0 },
{ "-----------", 0, 0, 0 },
#ifndef NO_FILE_SELECTOR
{ "readFile", MenuReadFile, S_NORMAL_ONLY, 0 },
#endif
{ "-----------", 0, 0, 0 },
#ifdef DEBUG_ON
{ "resyncGap", MenuResyncGap, S_ALWAYS, 0 },
#endif
{ "quit", MenuQuitGap, S_ALWAYS, 0 },
{ "kill", MenuKillGap, S_ALWAYS, 0 },
{ 0, 0, 0, 0 }
};
/****************************************************************************
**
*V HelpMenu . . . . . . . . . . . . . . . . . . . . . . xgap's "Help" menu
**
*/
static void MenuChapters (TypeMenuItem *item) { SimulateInput( "?Chapters\n" ); }
static void MenuSections (TypeMenuItem *item) { SimulateInput( "?Sections\n" ); }
static void MenuCopyright (TypeMenuItem *item) { SimulateInput( "?Copyright\n" );}
static void MenuHelp (TypeMenuItem *item) { SimulateInput( "?Help\n" ); }
static void MenuNextHelp (TypeMenuItem *item) { SimulateInput( "?>\n" ); }
static void MenuNextChapter (TypeMenuItem *item) { SimulateInput( "?>>\n" ); }
static void MenuPrevChapter (TypeMenuItem *item) { SimulateInput( "?<<\n" ); }
static void MenuPrevHelp (TypeMenuItem *item) { SimulateInput( "?<\n" ); }
static TypeMenuItem HelpMenu[] =
{
{ "copyHelp", MenuCopyright, S_INPUT_ONLY, 0 },
{ "helpHelp", MenuHelp, S_INPUT_ONLY, 0 },
{ "---------", 0, 0, 0 },
{ "chpsHelp", MenuChapters, S_INPUT_ONLY, 0 },
{ "secsHelp", MenuSections, S_INPUT_ONLY, 0 },
{ "---------", 0, 0, 0 },
{ "nchpHelp", MenuNextChapter, S_INPUT_ONLY, 0 },
{ "pchpHelp", MenuPrevChapter, S_INPUT_ONLY, 0 },
{ "nextHelp", MenuNextHelp, S_INPUT_ONLY, 0 },
{ "prevHelp", MenuPrevHelp, S_INPUT_ONLY, 0 },
{ 0, 0, 0, 0 }
};
/****************************************************************************
**
*V RunMenu . . . . . . . . . . . . . . . . . . . . . . . . xgap's "Run" menu
**
*/
static void MenuInterrupt (TypeMenuItem *item) { InterruptGap(); }
static void MenuQuitBreak (TypeMenuItem *item) { SimulateInput( "quit;\n" ); }
static void MenuContBreak (TypeMenuItem *item) { SimulateInput( "return;\n" ); }
static void MenuGarbColl (TypeMenuItem *item) { SimulateInput( "GASMAN(\"collect\");\n" ); }
static void MenuGarbMesg (TypeMenuItem *item) { SimulateInput( "GASMAN(\"message\");\n" ); }
static TypeMenuItem RunMenu[] =
{
{ "interrupt", MenuInterrupt, S_RUNNING_ONLY, 0 },
{ "---------", 0, 0, 0 },
{ "quitBreak", MenuQuitBreak, S_ERROR_ONLY, 0 },
{ "contBreak", MenuContBreak, S_ERROR_ONLY, 0 },
{ "---------", 0, 0, 0 },
{ "garbColl", MenuGarbColl, S_INPUT_ONLY, 0 },
{ "garbMesg", MenuGarbMesg, S_INPUT_ONLY, 0 },
{ 0, 0, 0, 0 }
};
/****************************************************************************
**
*F CreateMenu( <button>, <items> ) . . . . . . . . . . . . create a pop menu
**
** RESOURCES
** *menu.line.height
** height of menu line separator, default 10
*/
static TypeList ListInputOnly = 0;
static TypeList ListErrorOnly = 0;
static TypeList ListNormalOnly = 0;
static TypeList ListRunningOnly = 0;
static TypeList ListHelpOnly = 0;
static void MenuSelected ( Widget, TypeMenuItem *, caddr_t );
static void CreateMenu (
Widget button,
TypeMenuItem * items )
{
Widget menu;
/* if this is the first call, create lists */
if ( ListInputOnly == 0 )
{
ListErrorOnly = List(0);
ListHelpOnly = List(0);
ListInputOnly = List(0);
ListNormalOnly = List(0);
ListRunningOnly = List(0);
}
/* create new simple menu */
menu = XtCreatePopupShell( "menu", simpleMenuWidgetClass, button, 0, 0 );
/* and add menu buttons */
for ( ; items->label != 0; items++ )
{
if ( *(items->label) == '-' )
(void) XtVaCreateManagedWidget( "line",
smeLineObjectClass, menu, (String)NULL );
else
{
items->entry = XtVaCreateManagedWidget(
items->label, smeBSBObjectClass, menu,
XtNrightMargin, (XtArgVal)14,
XtNrightBitmap, (XtArgVal)EmptyMarkSymbol,
(String)NULL );
XtAddCallback( items->entry, XtNcallback,
(XtCallbackProc)MenuSelected, items );
switch ( items->sensitive )
{
case S_INPUT_ONLY:
AddList( ListInputOnly, items->entry );
XtVaSetValues( items->entry, XtNsensitive, (XtArgVal)False,
(String)NULL );
break;
case S_ERROR_ONLY:
AddList( ListErrorOnly, items->entry );
XtVaSetValues( items->entry, XtNsensitive, (XtArgVal)False,
(String)NULL );
break;
case S_NORMAL_ONLY:
AddList( ListNormalOnly, items->entry );
XtVaSetValues( items->entry, XtNsensitive, (XtArgVal)False,
(String)NULL );
break;
case S_RUNNING_ONLY:
AddList( ListRunningOnly, items->entry );
XtVaSetValues( items->entry, XtNsensitive, (XtArgVal)False,
(String)NULL );
break;
case S_HELP_ONLY:
AddList( ListHelpOnly, items->entry );
XtVaSetValues( items->entry, XtNsensitive, (XtArgVal)False,
(String)NULL );
break;
case S_ALWAYS:
break;
}
}
}
}
static void MenuSelected (
Widget w,
TypeMenuItem * item,
caddr_t dummy )
{
if ( item->click != 0 )
(*(item->click))(item);
else
{
fputs( "Warning: menu item ", stderr );
fputs( XtName(w), stderr );
fputs( " has been selected.\n", stderr );
}
}
/****************************************************************************
**
*F UpdateMenus( <state> ) . . . . . . update menus in case of state change
*/
void UpdateMenus (
Int state)
{
TypeList l;
Int i;
/* menu entry active only in break loop */
l = ListErrorOnly;
for ( i = 0; i < l->len; i++ )
{
if ( state == GAP_ERROR )
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)True,
(String)NULL );
else
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)False,
(String)NULL );
}
/* menu entry active only during input */
l = ListInputOnly;
for ( i = 0; i < l->len; i++ )
{
if ( state == GAP_ERROR || state == GAP_INPUT )
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)True,
(String)NULL );
else
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)False,
(String)NULL );
}
/* menu entry active only during normal input */
l = ListNormalOnly;
for ( i = 0; i < l->len; i++ )
{
if ( state == GAP_INPUT )
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)True,
(String)NULL );
else
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)False,
(String)NULL );
}
/* menu entry active only while gap is running */
l = ListRunningOnly;
for ( i = 0; i < l->len; i++ )
{
if ( state == GAP_RUNNING )
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)True,
(String)NULL );
else
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)False,
(String)NULL );
}
/* menu entry active only while gap is helping */
l = ListHelpOnly;
for ( i = 0; i < l->len; i++ )
{
if ( state == GAP_HELP )
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)True,
(String)NULL );
else
XtVaSetValues( (Widget)l->ptr[i], XtNsensitive, (XtArgVal)False,
(String)NULL );
}
}
/****************************************************************************
**
*F * * * * * * * * * * * * * * gap talk window * * * * * * * * * * * * * * *
*/
/****************************************************************************
**
*F UpdateMemoryInfo( <type>, <val> ) . . . . . . . . . update memory usage
*/
static Widget LabelLiveObjects;
static Widget LabelLiveKB;
static Widget LabelTotalKBytes;
void UpdateMemoryInfo (
Int type,
Int val)
{
char tmp[30];
switch ( type )
{
case 1:
snprintf( tmp, sizeof(tmp), "Objects: %-5d ", val );
XtVaSetValues( LabelLiveObjects, XtNlabel, (XtArgVal)tmp,
(String)NULL );
break;
case 2:
snprintf( tmp, sizeof(tmp), "MB used: %.1f ", val/(float)1024 );
XtVaSetValues( LabelLiveKB, XtNlabel, (XtArgVal)tmp,
(String)NULL );
break;
case 6:
snprintf( tmp, sizeof(tmp), "MB total: %.1f ", val/(float)1024 );
XtVaSetValues( LabelTotalKBytes, XtNlabel, (XtArgVal)tmp,
(String)NULL );
break;
}
}
/****************************************************************************
**
*F GapTalkResized( <talk>, <cd>, <evt>, <ctd> ) . . . . . . resize callback
*/
static void GapTalkResized (
Widget talk,
XtPointer cd,
XEvent * evt,
Boolean * ctd )
{
Int i;
String ptr;
Widget snk;
XFontStruct * font;
char buf[128];
static UInt h, h1 = 0;
static UInt w, w1 = 0;
/* is this a resize event */
if ( evt->type == ConfigureNotify )
{
/* compute a sensible size */
XtVaGetValues( talk, XtNtextSink, (XtArgVal)&snk, (String)NULL );
XtVaGetValues( snk, XtNfont, (XtArgVal)&font, (String)NULL );
w = evt->xconfigure.width / font->max_bounds.width - 3;
h = evt->xconfigure.height / ( font->max_bounds.ascent
+ font->max_bounds.descent ) - 2;
if ( w < 2 ) w = 2;
if ( h < 2 ) h = 2;
if ( w == w1 && h == h1 )
return;
w1 = w;
h1 = h;
/* construct gap command */
strcpy( buf, "SizeScreen([ " );
ptr = buf + strlen(buf);
for ( i = 3; 0 <= i; i--, w = w / 10 )
ptr[i] = w%10 + '0';
ptr += 4;
*ptr++ = ',';
*ptr++ = ' ';
for ( i = 3; 0 <= i; i--, h = h / 10 )
ptr[i] = h%10 + '0';
ptr += 4;
strcpy( ptr, " ]);;\n" );
/* if gap is waiting for input, do it */
if ( GapState == GAP_INPUT || GapState == GAP_ERROR )
SimulateInput( buf );
else
strcpy( ScreenSizeBuffer, buf );
}
}
/****************************************************************************
**
*F CreateGapWindow() . . . . . . . . . . . . . . create communication window
**
** RESOURCES
** *xgapMenu*shapeStyle
** style of the menu buttons, default "Oval"
** *xgap.height
** *xgap.width
** start size of the communication text window
*/
static void CreateGapWindow ( void )
{
Widget paned;
Widget box;
Widget button;
Pixmap symbol;
Display * display;
Boolean flag;
Int i;
/* create a "paned" for the menu and text window */
paned = XtVaCreateManagedWidget( "paned", panedWidgetClass,
XGap, (String)NULL );
/* create a menu box for the menu buttons */
box = XtVaCreateManagedWidget( "xgapMenu", boxWidgetClass,
paned,
XtNx, (XtArgVal)0,
XtNy, (XtArgVal)0,
XtNresizeToPreferred, (XtArgVal)True,
(String)NULL );
/* create a menu button drop down symbol */
display = XtDisplay(box);
symbol = XCreateBitmapFromData( display,
DefaultRootWindow(display),
"\376\3\2\2\2\6\162\6\2\6\162\6\2\6\162\6\2\6\2\6\376\7\370\7",
12, 12 );
/* create file menu button and file menu */
button = XtVaCreateManagedWidget( "gapButton", menuButtonWidgetClass,
box,
XtNleftBitmap, (XtArgVal)symbol,
XtNx, (XtArgVal)0,
(String)NULL );
CreateMenu( button, GapMenu );
/* create run menu button and run menu */
button = XtVaCreateManagedWidget( "runButton", menuButtonWidgetClass,
box,
XtNleftBitmap, (XtArgVal)symbol,
XtNx, (XtArgVal)10,
(String)NULL );
CreateMenu( button, RunMenu );
/* create help menu button and help menu */
button = XtVaCreateManagedWidget( "helpButton", menuButtonWidgetClass,
box,
XtNleftBitmap, (XtArgVal)symbol,
XtNx, (XtArgVal)10,
(String)NULL );
CreateMenu( button, HelpMenu );
/* create the communication window */
GapTalk = XtVaCreateManagedWidget( "xgapTalk", gapTextWidgetClass,
paned,
XtNinputCallback, (XtArgVal)KeyboardInput,
XtNcheckCaretPos, (XtArgVal)CheckCaretPos,
XtNscrollHorizontal, (XtArgVal)XawtextScrollWhenNeeded,
XtNscrollVertical, (XtArgVal)XawtextScrollAlways,
XtNeditType, (XtArgVal)XawtextEdit,
XtNbottomMargin, (XtArgVal)15,
XtNx, (XtArgVal)0,
XtNy, (XtArgVal)10,
XtNdisplayCaret, (XtArgVal)True,
(String)NULL );
XtAddEventHandler(GapTalk,StructureNotifyMask,False,GapTalkResized,0);
GTDropGapPrompt( GapTalk, True );
/* to quit or not do quit on CTR-D */
XtVaGetValues( GapTalk, XtNquitGapCtrD, (XtArgVal)&flag, (String)NULL );
if ( flag )
{
for ( i = 0; GapMenu[i].label; i++ )
if ( !strcmp( GapMenu[i].label, "quitGapCTRD" ) )
break;
if ( GapMenu[i].label && GapMenu[i].click )
GapMenu[i].click(&(GapMenu[i]));
}
/* paste GAP prompt into talk window? */
XtVaGetValues( GapTalk, XtNpasteGapPrompt, &flag, NULL );
if ( flag )
{
for ( i = 0; GapMenu[i].label; i++ )
if ( !strcmp( GapMenu[i].label, "pastePrompt" ) )
break;
if ( GapMenu[i].label && GapMenu[i].click )
GapMenu[i].click(&(GapMenu[i]));
}
/* create a box and labels for garbage info */
box = XtVaCreateManagedWidget( "xgapInfo", boxWidgetClass,
paned,
XtNx, (XtArgVal)0,
XtNy, (XtArgVal)20,
XtNskipAdjust, (XtArgVal)True,
XtNresizeToPreferred, (XtArgVal)True,
(String)NULL );
LabelLiveObjects = XtVaCreateManagedWidget( "liveObjects",
labelWidgetClass, box,
XtNborderWidth, (XtArgVal)0,
(String)NULL );
LabelLiveKB = XtVaCreateManagedWidget( "liveBytes",
labelWidgetClass, box,
XtNborderWidth, (XtArgVal)0,
(String)NULL );
LabelTotalKBytes = XtVaCreateManagedWidget( "totalBytes",
labelWidgetClass, box,
XtNborderWidth, (XtArgVal)0,
(String)NULL );
UpdateMemoryInfo( 1, 0 );
UpdateMemoryInfo( 2, 0 );
UpdateMemoryInfo( 6, 0 );
}
/****************************************************************************
**
*F * * * * * * * * * * * * * * error handler * * * * * * * * * * * * * * * *
*/
/****************************************************************************
**
*F MyErrorHandler(<dis>) . . . . . . . . . . . . kill gap in case of X error
*/
static int (*OldErrorHandler)(Display *, XErrorEvent *);
static int MyErrorHandler (
Display * dis,
XErrorEvent * evt)
{
# ifdef DEBUG_ON
fputs( "killing gap because of X error\n", stderr );
# endif
KillGap();
return OldErrorHandler( dis, evt );
}
/****************************************************************************
**
*F MyIOErrorHandler(<dis>) . . . . . . . . . . . kill gap in case of X error
*/
static int (*OldIOErrorHandler)(Display *);
static int MyIOErrorHandler (
Display * dis)
{
# ifdef DEBUG_ON
fputs( "killing gap because of X IO error\n", stderr );
# endif
KillGap();
return OldIOErrorHandler(dis);
}
/****************************************************************************
**
*F MySignalHandler() . . . . . . . . . . . . . . kill gap in case of signal
*/
#ifdef DEBUG_ON
static void (*OldSignalHandlerHUP)(int);
static void (*OldSignalHandlerINT)(int);
static void (*OldSignalHandlerQUIT)(int);
static void (*OldSignalHandlerILL)(int);
static void (*OldSignalHandlerIOT)(int);
static void (*OldSignalHandlerBUS)(int);
static void (*OldSignalHandlerSEGV)(int);
static void MySignalHandlerHUP (int signo)
{
fputs( "killing gap because of signal HUP\n", stderr );
KillGap();
OldSignalHandlerHUP(signo);
exit(1);
}
static void MySignalHandlerINT (int signo)
{
fputs( "killing gap because of signal INT\n", stderr );
KillGap();
OldSignalHandlerINT(signo);
exit(1);
}
static void MySignalHandlerQUIT (int signo)
{
fputs( "killing gap because of signal QUIT\n", stderr );
KillGap();
OldSignalHandlerQUIT(signo);
exit(1);
}
static void MySignalHandlerILL (int signo)
{
fputs( "killing gap because of signal ILL\n", stderr );
KillGap();
OldSignalHandlerILL(signo);
exit(1);
}
static void MySignalHandlerIOT (int signo)
{
fputs( "killing gap because of signal IOT\n", stderr );
KillGap();
OldSignalHandlerIOT(signo);
exit(1);
}
static void MySignalHandlerBUS (int signo)
{
fputs( "killing gap because of signal BUS\n", stderr );
KillGap();
OldSignalHandlerBUS(signo);
exit(1);
}
static void MySignalHandlerSEGV (int signo)
{
fputs( "killing gap because of signal SEGV\n", stderr );
KillGap();
OldSignalHandlerSEGV(signo);
exit(1);
}
#else
static void MySignalHandler (int signo)
{
KillGap();
exit(1);
}
#endif
/****************************************************************************
**
*F * * * * * * * * * * * * * * * main program * * * * * * * * * * * * * * *
*/
/****************************************************************************
**
*F ParseArgs( <argc>, <argv> ) . . . create argument array for gap subprocess
*/
static char * nargv[1024];
static void ParseArgs (
Int argc,
char ** argv)
{
Int nargc;
Int i, j;
String p;
/* at first assume that "gap" is started with "gap", append "-p" */
nargc = 0;
nargv[nargc++] = "gap";
nargv[nargc++] = "-p";
/* parse XGAP arguments till we see '--' */
for ( argv++, argc--; 0 < argc; argv++, argc-- ) {
/* start of an argument */
if ( *argv[0] == '-' ) {
/* don't group any options */
if ( strlen(*argv) != 2 ) {
fputs("XGAP: sorry options must not be grouped '", stderr);
fputs(*argv, stderr);
fputs("'.\n", stderr);
goto usage;
}
switch( argv[0][1] ) {
/* catch unknown arguments */
default:
fputs("XGAP: unknown option '", stderr);
fputs(*argv, stderr);
fputs("'.\n", stderr);
goto usage;
/* start of GAP options */
case '-':
argv++;
argc--;
goto gap;
/* print a help */
case 'h':
goto fullusage;
/* toggle debug */
case 'D':
# ifdef DEBUG_ON
if ( argc-- < 2 ) {
fputs( "XGAP: option '-D' must have an argument.\n",
stderr );
goto usage;
}
Debug = atoi(*++argv);
# else
fputs( "XGAP: compile XGAP using 'COPTS=-DDEBUG_ON'.\n",
stderr );
goto usage;
# endif
break;
/* broken window manager */
case 'W':
PopupDialogBrokenWM();
break;
/* copy GAP output to stderr */
case 'E':
SpyMode = !SpyMode;
break;
/* get name of gap subprocess */
case 'G':
if ( argc-- < 2 ) {
fputs( "XGAP: option '-G' must have an argument.\n",
stderr );
goto usage;
}
p = *++argv;
nargv[0] = p;
j = 0;
while ( *++p ) {
if ( *p == ' ' )
{
*p = '\0';
j = j + 1;
}
}
if ( 0 < j ) {
for ( i = nargc-1; 0 < i; i-- )
nargv[i+j] = nargv[i];
nargc = nargc + j;
while ( 0 < j )
{
while ( *--p ) ;
nargv[j--] = p+1;
}
}
break;
}
}
/* non-arguments are not allowed here */
else {
goto usage;
}
}
/* copy any remaining arguments */
gap:
for ( ; 0 < argc; argv++, argc-- )
nargv[nargc++] = *argv;
nargv[nargc] = 0;
return;
/* print a usage message */
usage:
fputs("usage: xgap [OPTIONS] -- [GAP OPTIONS]\n",stderr);
fputs(" run the X-Windows front-end for GAP,\n",stderr);
fputs(" use '-h' option to get help.\n",stderr);
fputs("\n",stderr);
exit(1);
fullusage:
fputs("usage: xgap [OPTIONS] -- [GAP OPTIONS]\n",stderr);
fputs(" run the X-Windows front-end for GAP,\n",stderr);
fputs("\n",stderr);
fputs(" -h print this help message\n",stderr);
fputs(" -D <num> set debug level\n",stderr);
fputs(" -W try to workaround broken wm\n",stderr);
fputs(" -E toggle spy mode\n",stderr);
fputs(" -G <file> filename of the GAP executable\n",stderr);
exit(1);
}
/****************************************************************************
**
*F main( <argc>, <argv> ) . . . . . . . . . . . . . . . . main event loop
*/
#include "bitmaps/checksym.bm"
#include "bitmaps/emptymk.bm"
#include "bitmaps/exmark.bm"
#include "bitmaps/menusym.bm"
int main (
int argc,
char ** argv)
{
String color;
String colors;
int fromGap;
Int mod = -1;
Int len;
Int i;
Int j;
/* options after '--' are for gap */
for ( i = 0; i < argc; i++ )
if ( ! strcmp( argv[i], "--" ) )
break;
len = i;
/* create a new top level shell and an applictation context */
XGap = XtVaAppInitialize( &AppContext, "XGap",
CommandOptions, XtNumber(CommandOptions),
&i, argv, FallbackResources, (String)NULL );
for ( j = len; j <= argc; j++ ) {
argv[i+(j-len)] = argv[j];
}
argc = argc + (i-len);
GapDisplay = XtDisplay(XGap);
GapScreen = DefaultScreen(GapDisplay);
MyRootWindow = RootWindow( GapDisplay, GapScreen );
/* parse remaining arguments */
ParseArgs( argc, argv );
fromGap = StartGapProcess( nargv[0], nargv );
/* create top left arrow cusor */
CursorTL = XCreateFontCursor( XtDisplay(XGap), XC_top_left_arrow );
/* create menu symbol */
MenuSymbol = XCreateBitmapFromData( GapDisplay, MyRootWindow,
menusym_bits, menusym_width,
menusym_height );
/* create check mark and empty mark */
CheckMarkSymbol = XCreateBitmapFromData( GapDisplay, MyRootWindow,
checksym_bits, checksym_width,
checksym_height );
EmptyMarkSymbol = XCreateBitmapFromData( GapDisplay, MyRootWindow,
emptymk_bits, emptymk_width,
emptymk_height );
/* exclamation mark */
ExMarkSymbol = XCreateBitmapFromData( GapDisplay, MyRootWindow,
exmark_bits, exmark_width,
exmark_height );
/* WM_DELETE_WINDOW atom */
WmDeleteWindowAtom = XInternAtom(GapDisplay, "WM_DELETE_WINDOW", False);
/* install our error handler, we have to kill gap in this case */
OldIOErrorHandler = XSetIOErrorHandler( MyIOErrorHandler );
OldErrorHandler = XSetErrorHandler ( MyErrorHandler );
/***************WIN32 CYGWIN fix***************/
/* SIGIOT not defined in CYGWIN signal.h unless !defined(SIGTRAP)
there may be a way to get ...? */
#ifdef __CYGWIN__
# define SIGIOT 6 /* IOT instruction */
# define SIGABRT 6 /* used by abort, replace SIGIOT in the future */
#endif
/***************WIN32 CYGWIN fix***************/
/* install your signal handler, we have to kill gap in this case */
# ifdef DEBUG_ON
OldSignalHandlerHUP = signal( SIGHUP, MySignalHandlerHUP );
OldSignalHandlerINT = signal( SIGINT, MySignalHandlerINT );
OldSignalHandlerQUIT = signal( SIGQUIT, MySignalHandlerQUIT );
OldSignalHandlerILL = signal( SIGILL, MySignalHandlerILL );
OldSignalHandlerIOT = signal( SIGIOT, MySignalHandlerIOT );
OldSignalHandlerBUS = signal( SIGBUS, MySignalHandlerBUS );
OldSignalHandlerSEGV = signal( SIGSEGV, MySignalHandlerSEGV );
# else
signal( SIGHUP, MySignalHandler );
signal( SIGINT, MySignalHandler );
signal( SIGQUIT, MySignalHandler );
signal( SIGILL, MySignalHandler );
signal( SIGIOT, MySignalHandler );
signal( SIGBUS, MySignalHandler );
signal( SIGSEGV, MySignalHandler );
# endif
/* create the gap talk window */
CreateGapWindow();
XtRealizeWidget(XGap);
/* initialize window commands */
InitXCMDS();
/* get color model */
XtVaGetValues( GapTalk, XtNcolorModel, (XtArgVal)&color, (String)NULL );
len = strlen(color);
if ( !strncmp( color, "black&white", len ) )
mod = CM_BW;
else if ( !strncmp( color, "monochrome", len ) )
mod = CM_BW;
else if ( !strncmp( color, "grey", len ) )
mod = CM_GRAY;
else if ( !strncmp( color, "gray", len ) )
mod = CM_GRAY;
else if ( !strncmp( color, "color5", len ) )
mod = CM_COLOR5;
else if ( !strncmp( color, "color3", len ) )
mod = CM_COLOR3;
else if ( !strncmp( color, "default", len ) )
mod = -1;
else
{
fputs( "XGAP: unknown color model '", stderr );
fputs( color, stderr );
fputs( "'\n", stderr );
mod = -1;
}
if ( mod != -1 ) {
XtVaGetValues( GapTalk, XtNcolors, (XtArgVal)&colors, (String)NULL );
GCSetColorModel( GapDisplay, mod, colors );
}
/* add callback for output from gap*/
XtAppAddInput( AppContext, fromGap, (XtPointer) XtInputReadMask,
(XtInputCallbackProc) GapOutput, (XtPointer) 0 );
StoreInput( "LoadPackage(\"xgap\");;\n",22 );
/* force a garbage collection in the beginning */
StoreInput( "GASMAN(\"collect\");\n", 19 );
/* talk window is drawn only partial during start up otherwise (why?) */
/*XFlush( GapDisplay );
sleep(1);
XFlush( GapDisplay );
sleep(1);
XFlush( GapDisplay );
sleep(1);*/
/* FIXME: No longer necessary??? */
/* enter main read-eval loop */
XtAppMainLoop(AppContext);
return 0;
}
/****************************************************************************
**
*E xgap.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
*/
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|