Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/GAP/pkg/xgap/src.x11/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 14.8.2025 mit Größe 60 kB image not shown  

Quelle  xcmds.c   Sprache: C

 
/****************************************************************************
**
*W  xcmds.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    "xgap.h"
#include    "pty.h"
#include    "selfile.h"

#include    "xcmds.h"

/****************************************************************************
**

*F  * * * * * * * * * * * * *  local variables  * * * * * * * * * * * * * * *
*/



/****************************************************************************
**

*V  DialogOkCancel  . . . . . . . . . . . . . . . . .  Cancel/OK popup dialog
*/

static TypePopupDialog DialogOkCancel;


/****************************************************************************
**
*V  GapWindows . . . . . . . . . . . . . . . . . . . list of all gap windows
*/

static TypeList GapWindows;


/****************************************************************************
**
*V  HugeFont  . . . . . . . . . . . . . . . . . . . huge font for text output
*/

static XFontStruct * HugeFont;


/****************************************************************************
**
*V  LargeFont . . . . . . . . . . . . . . . . . .  large font for text output
*/

static XFontStruct * LargeFont;


/****************************************************************************
**
*V  NormalFont  . . . . . . . . . . . . . . . . . normal font for text output
*/

XFontStruct * NormalFont;


/****************************************************************************
**
*V  PopupMenus  . . . . . . . . . . . . . . . . . . . list of all popup menus
*/

static TypeList PopupMenus;


/****************************************************************************
**
*V  RunCursor . . . . . . . . . . . . cursor used when GAP is accepting input
*/

static Cursor RunCursor;


/****************************************************************************
**
*V  SleepCursor . . . . . . . . .  cursor used when GAP isn't accepting input
*/

static Cursor SleepCursor;


/****************************************************************************
**
*V  SmallFont . . . . . . . . . . . . . . . . . .  small font for text output
*/

static XFontStruct * SmallFont;


/****************************************************************************
**
*V  TextSelectors . . . . . . . . . . . . . . . .  list of all text selectors
*/

static TypeList TextSelectors;


/****************************************************************************
**
*V  TinyFont  . . . . . . . . . . . . . . . . . . . tiny font for text output
*/

static XFontStruct * TinyFont;


/****************************************************************************
**

*F  * * * * * * * * * * * *  communication with GAP * * * * * * * * * * * * *
*/



/****************************************************************************
**

*F  AnswerGap( <format>, <arg1>, <arg2>, <arg3>, <arg4> ) . . . return answer
*/

#define ANSWER_GAP(a,b,c,d,e)  \
    AnswerGap( a, (Long)(b), (Long)(c), (Long)(d), (Long)(e) )

static Boolean AnswerGap (
    String       format,
    Long         a1,
    Long         a2,
    Long         a3,
    Long         a4 )
{
    Int          arg;
    Int          len;
    Int          m;
    Int          n;
    Long         args[4];
    String       ptr;
    String       qtr;
    String       str;
    String       wtr;
    Char         hdr[14];

    /* give debug information */
    DEBUG( D_COMM, ( "AnswerGap( \"%s\", ... )\n", format ) );

    /* compute length of return string */
    args[0] = a1;  args[1] = a2;  args[2] = a3;  args[3] = a4;
    len = 12;
    arg = 0;
    for ( ptr = format;  *ptr;  ptr++ )
    {
 if ( arg == 4 )
     return False;
 switch ( *ptr )
 {
     case 'O':
     case 'o':  len += 9;  break;
     case 'E':
     case 'e':  len += 9;  break;
     case 'D':
     case 'd':  len += 9;  arg++;  break;
     case 'S':
     case 's':  len += 9 + strlen((String)args[arg++]);  break;
     default :  return False;
 }
    }

    /* allocate a string of length <len> */
    str = XtMalloc(len);

    /* parse arguments again */
    arg = 0;
    qtr = str;
    for ( ptr = format;  *ptr;  ptr++ )
    {
 switch ( *ptr )
 {
     case 'O':
     case 'o':
         strcpy( qtr, "I0+" );
  qtr += 3;
  break;
     case 'E':
     case 'e':
  strcpy( qtr, "I1+" );
  qtr += 3;
  break;
     case 'D':
     case 'd':
  *qtr++ = 'I';
  n = (Int)args[arg++];
  for ( m = ( 0 < n ) ? n : -n;  0 < m;  m /= 10 )
      *qtr++ = '0' + (m%10);
  if ( n < 0 )
      *qtr++ = '-';
  else
      *qtr++ = '+';
  break;
     case 'S':
     case 's':
  *qtr++ = 'S';
  wtr = (String)(args[arg++]);
  for ( m = strlen(wtr);  0 < m;  m /= 10 )
      *qtr++ = '0' + (m%10);
  *qtr++ = '+';
  while ( *wtr )
      *qtr++ = *wtr++;
  break;
 }
    }
    *qtr = '\0';

    /* write header */
    hdr[0] = '@';
    hdr[1] = 'a';
    qtr = hdr+2;
    for ( m = strlen(str);  0 < m;  m/= 10 ) {
 *qtr++ = '0' + (m%10);
    }
    *qtr++ = '+';
    *qtr = '\0';
    WriteGap( hdr, strlen(hdr) );

    /* write result back to gap process */
    WriteGap( str, strlen(str) );
    XtFree(str);
    return True;
}


/****************************************************************************
**
*F  ParseInt( <buf>, <val> ) . . . . . . . . . . . . . . . get a int value
*/

static Boolean ParseInt (
    String    * buf,
    Int       * val )
{
    Int         mult;

    if ( *(*buf)++ != 'I' )
 return False;
    *val = 0;
    mult = 1;
    do
    {
 if ( **buf == '+' )
 {
     (*buf)++;
     return True;
 }
 else if ( **buf == '-' )
 {
     (*buf)++;
     *val = -*val;
     return True;
 }
 else if ( '0' <= **buf && **buf <= '9' )
     *val += mult * (*((*buf)++)-'0');
 else
     return False;
 mult = mult * 10;
    } while (1);
}


/****************************************************************************
**
*F  ParseString( <buf>, <str>, <len> ) . . . . . . . get a string from <ptr>
*/

static Boolean ParseString (
     String   * buf,
     String       * str,
     Int          * len )
{
     Int            i;
     Int            m;
     String         ptr;

     if ( (*buf)[0] != 'S' )
         return False;
     ptr = (*buf)+1;
     for ( m=1,*len=0;  '0' <= *ptr && *ptr <= '9';  ptr++,m *= 10 )
  *len += ( *ptr - '0' ) * m;
     *buf = ptr+1;
     *str = XtMalloc( (*len)+1 );
     for ( ptr = *str, i = *len;  0 < i;  i--, ptr++, (*buf)++ )
  if ( **buf == '@' )
  {
      (*buf)++;
      if ( **buf == '@' )
   *ptr = **buf;
      else
   *ptr = (**buf) - 'A';
  }
  else
      *ptr = **buf;
     *ptr = 0;
     return True;
}


/****************************************************************************
**
*F  GapWindowCmd( <cstr>, <len> ) . . . . . . . execute window command <cstr>
*/

extern TypeWindowCommand WindowCommands[];

Boolean GapWindowCmd (
    String              cstr,
    Int                 len )
{
    Boolean             ret;
    Int   ca;
    Int   ci;
    Int   cs;
    Int                 i;
    String              pa;
    String              str = cstr+3;
    TypeArg         arg;
    TypeWindowCommand * cmd;
    char                name[4];

    /* give debug information */
    name[0] = cstr[0];  name[1] = cstr[1];  name[2] = cstr[2];  name[3] = 0;
    DEBUG( D_XCMD, ( "GapWindowCmd( \"%s\" )\n", name ) );

    /* try to find the command in <WindowCommands> */
    cmd = WindowCommands;
    while ( cmd->name )
 if ( !strncmp( cmd->name, name, 3 ) )
     break;
 else
     cmd++;
    if ( !cmd->name )
 return ANSWER_GAP( "esss""unknown command '", name, "'", 0 );

    /* parse arguments */
    arg.opts = 0;
    ci = cs = 0;
    ca = 1;
    pa = cmd->args;
    while ( *pa )
    {
 if ( *pa == '*' )
 {
     arg.opts = str;
     break;
 }
 else if ( *pa == 'S' || *pa == 's' )
 {
     if ( !ParseString( &str, &(arg.sargs[cs]), &len ) )
     {
  ret = ANSWER_GAP("eds",ca,".th arg must be a string",0,0);
  goto free_strings;
     }
     else
  cs++;
 }
 else if ( *pa == '#' )
 {
     if ( !ParseInt( &str, &i ) )
     {
  ret = ANSWER_GAP("eds",ca,".th arg must be a window nr",0,0);
  goto free_strings;
     }
     arg.iargs[ci++] = i;
     if ( LEN(GapWindows) <= arg.iargs[0] || arg.iargs[0] < 0 )
     {
  ret = ANSWER_GAP( "es""illegal window number", 0, 0, 0 );
  goto free_strings;
     }
     arg.win = (TypeGapWindow*)(ELM(GapWindows,arg.iargs[0]));
     if ( ! arg.win->used )
     {
  ret = ANSWER_GAP( "es""window not used", 0, 0, 0 );
  goto free_strings;
     }
 }
 else if ( *pa == 'T' )
 {
     if ( !ParseInt( &str, &i ) )
     {
  ret = ANSWER_GAP("eds",ca,".th arg must be a selector",0,0);
  goto free_strings;
     }
     arg.iargs[ci++] = i;
     if ( LEN(TextSelectors) <= arg.iargs[0] || arg.iargs[0] < 0 )
     {
  ret = ANSWER_GAP( "es""illegal selector number", 0, 0, 0 );
  goto free_strings;
     }
     arg.sel = (TypeTextSelector*)(ELM(TextSelectors,arg.iargs[0]));
     if ( arg.sel == 0)
     {
  ret = ANSWER_GAP( "es""selector not used", 0, 0, 0 );
  goto free_strings;
     }
 }
 else if ( *pa == 'F' )
 {
     if ( !ParseInt( &str, &i ) )
     {
  ret = ANSWER_GAP("eds",ca,".th arg must be an integer",0,0);
  goto free_strings;
     }
     arg.iargs[ci++] = i;
     switch ( (int)arg.iargs[ci-1] )
     {
  case 1:  arg.font = TinyFont;   break;
  case 2:  arg.font = SmallFont;  break;
  case 3:  arg.font = NormalFont; break;
  case 4:  arg.font = LargeFont;  break;
  case 5:  arg.font = HugeFont;   break;
  default:
      ret = ANSWER_GAP( "eds", ca,
          ".th arg must be a font number", 0, 0 );
      goto free_strings;
      break;
     }
 }
 else
 {
     if ( !ParseInt( &str, &i ) )
     {
  ret = ANSWER_GAP("eds",ca,".th arg must be an integer",0,0);
  goto free_strings;
     }
     arg.iargs[ci++] = i;
 }
 ca++;
 pa++;
    }
    if ( *pa != '*' && *str )
    {
 ret = ANSWER_GAP( "es""too many arguments", 0, 0, 0 );
 goto free_strings;
    }


    /* call command */
    ret = cmd->func( &arg );

    /* free argument strings */
free_strings:
    for ( i = 0;  i < cs;  i++ )
 XtFree( arg.sargs[i] );
    return ret;
}


/****************************************************************************
**

*F  * * * * * * * * * * * functions for TextSelectors * * * * * * * * * * * *
*/



/****************************************************************************
**

*F  FunOpenSelector( <name>, <list>, <buttons> )  .  open a new text selector
*/

static void ButtonSelected (
    Widget     w,
    XtPointer       cl,
    XtPointer       ca )
{
    Int             i = ((Int) ((Long)cl&0xffff)) % 256;
    Int             n = ((Int) ((Long)cl&0xffff)) / 256;
    char            buf[128];

    DEBUG( D_XCMD, ("ButtonSelected( #%ld, #%ld )\n", (long)n, (long)i) );
    sprintf( buf, "ButtonSelected(%ld,%ld);\n", (long)n, (long)i );
    SimulateInput(buf);
}

static void TextSelected (
    Widget             w,
    XtPointer               cl,
    XtPointer               ca )
{
    XawListReturnStruct   * ret = (XawListReturnStruct*) ca;
    Int                     n = (Int) ((Long)cl&0xffff);
    Int                     m = (Int) ret->list_index;
    char                    buf[128];

    DEBUG( D_XCMD, ("TextSelected( #%ld, $%ld )\n", (long)n, (long)m+1 ) );
    sprintf( buf, "TextSelected(%ld,%ld);\n", (long)n, (long)m+1 );
    SimulateInput(buf);
}

static void NotifyClick (
    Widget        w,
    XEvent              * evt,
    String         * str,
    Cardinal       * n )
{
    XawListReturnStruct   * ret;
    Int                     i;
    char                    buf[128];

    /* get currently selected */
    ret = XawListShowCurrent(w);

    /* if something is set,  return */
    if ( ret->list_index != XAW_LIST_NONE )
 return;

    /* find widget */
    for ( i = 0;  i < LEN(TextSelectors);  i++ )
 if ( ((TypeTextSelector*)ELM(TextSelectors,i))->list == w )
 {
     sprintf( buf, "TextSelected(%ld,0);\n", (long)i );
     SimulateInput(buf);
     return;
 }
    
}

static char ButtonPressTrans[] =
    ",: Notify() NotifyClick()"

static Boolean FunOpenSelector (
    TypeArg           * arg )
{
    Int                 i;
    Int                 n;
    String              name = arg->sargs[0];
    String              ptr;
    String              qtr;
    TypeTextSelector  * selector;
    Widget              box;
    Widget              button;
    Widget              paned;
    Widget              viewport;
    char                buf[512];

    /* give debug info */
    DEBUG( D_XCMD, ( "OpenSelector( \"%s\", \"%s\", \"%s\" )\n",
     arg->sargs[0], arg->sargs[1], arg->sargs[2] ) );

    /* create a new selector entry */
    selector = (TypeTextSelector*) XtMalloc( sizeof(TypeTextSelector) );

    /* create a new top level shell */
    selector->top = XtAppCreateShell(
          "TextSelector""XGap", topLevelShellWidgetClass,
   GapDisplay, 0, 0 );

    /* create a "paned" for the menu and text window */
    paned = XtVaCreateManagedWidget(
         "textSelector", panedWidgetClass, selector->top, (String)NULL );

    /* create a headline */
    XtVaCreateManagedWidget(
        "textSelectorTitle", labelWidgetClass, paned,
        XtNlabel, (XtArgVal)name, (String)NULL );
        

    /* create a viewport for the text selectors */
    viewport = XtVaCreateManagedWidget(
            "textSelectorViewport", viewportWidgetClass, paned,
     XtNallowHoriz,       (XtArgVal)False,
     XtNallowVert,        (XtArgVal)True,
     XtNuseBottom,        (XtArgVal)True,
     XtNshowGrip,         (XtArgVal)False,
     (String)NULL );

    /* compute number of entries */
    for ( i = 2, qtr = arg->sargs[1];  *qtr;  qtr++ )
 if ( *qtr == '|' )
     i++;
    selector->text = (String*) XtMalloc(i*sizeof(String));

    /* parse text */
    for ( ptr = arg->sargs[1], i = 0;  *ptr;  i++ )
    {
     qtr = buf;
     while ( *ptr && *ptr != '|' )
         *qtr++ = *ptr++;
     *qtr = 0;
     if ( *ptr )  ptr++;
     DEBUG( D_XCMD, ( " entry = \"%s\"\n", buf ) );
 selector->text[i] = (String) XtMalloc(strlen(buf)+1);
 strcpy( selector->text[i], buf );
    }
    selector->text[i] = 0;

    /* find free entry in <TextSelectors> */
    for ( n = 0;  n < LEN(TextSelectors);  n++ )
 if ( ELM(TextSelectors,n) == 0 )
     break;
    if ( n == LEN(TextSelectors) )
 AddList( TextSelectors, selector );
    else
 ELM(TextSelectors,n) = selector;
    
    /* create a list widget containing the text */
    selector->list = XtVaCreateManagedWidget(
           "textSelectorList", listWidgetClass, viewport,
    XtNlist,           (XtArgVal)selector->text,
    XtNdefaultColumns, (XtArgVal)1,
    XtNforceColumns,   (XtArgVal)True,
    (String)NULL );
    XtOverrideTranslations( selector->list, 
       XtParseTranslationTable(ButtonPressTrans) );
    XtAddCallback( selector->list, XtNcallback, TextSelected,
     (XtPointer)(n&0xffffL) );

    /* create a box containing the buttons */
    box = XtVaCreateManagedWidget(
       "textSelectorBox", boxWidgetClass, paned,
       XtNorientation,           (XtArgVal)XtorientHorizontal,
              XtNshowGrip,              (XtArgVal)False,
       XtNskipAdjust,            (XtArgVal)True,
       XtNresizeToPreferred,  (XtArgVal)True,
       (String)NULL );

    /* parse buttons */
    selector->buttons = List(0);
    for ( ptr = arg->sargs[2], i = 1;  *ptr;  i++ )
    {
     qtr = buf;
     while ( *ptr && *ptr != '|' )
         *qtr++ = *ptr++;
     *qtr = 0;
     if ( *ptr )  ptr++;
     DEBUG( D_XCMD, ( " button = \"%s\"\n", buf ) );
 button = XtVaCreateManagedWidget(
              "textSelectorButton", commandWidgetClass, box,
              XtNlabel,      (XtArgVal)buf,
              XtNshapeStyle, (XtArgVal)XmuShapeOval,
              (String)NULL );
 XtAddCallback(button,XtNcallback,ButtonSelected,
        (XtPointer)((i+n*256)&0xffffL));
 AddList( selector->buttons, button );
    }


    /* realize the window and return the number */
    XtRealizeWidget(selector->top);

    /* add window to list and return window number */
    return ANSWER_GAP( "od", n, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunCloseSelector( <sel> ) . . . . . . . . . destroy an open text selector
*/

static Boolean FunCloseSelector (
    TypeArg   * arg )
{
    Int         i;

    /* give debug info */
    DEBUG( D_XCMD, ( "CloseSelector( #%ld )\n", (long)arg->iargs[0] ) );

    /* destroy top level shell (this will destroy all children) */
    XtDestroyWidget(arg->sel->top);

    /* clear text */
    for ( i = 0;  arg->sel->text[i];  i++ )
 XtFree( arg->sel->text[i] );
    XtFree( (char*) arg->sel->text );

    /* clear button list */
    XtFree( (char*) arg->sel->buttons->ptr );
    XtFree( (char*) arg->sel->buttons );

    /* clear entry in <TextSelectors> */
    ELM(TextSelectors,arg->iargs[0]) = 0;
    XtFree((char*)arg->sel);

    /* return OK */
    return AnswerGap( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunChangeList( <sel>, <buttons> )   . . . .  change list in text selector
*/

static Boolean FunChangeList (
    TypeArg       * arg )
{
    Int             i;
    String          ptr;
    String          qtr;
    String        * text;
    char            buf[512];

    /* give debug info */
    DEBUG( D_XCMD, ( "ChangeList( #%ld, \"%s\" )\n", (long)arg->iargs[0],
    arg->sargs[0] ) );

    /* compute number of entries */
    for ( i = 2, qtr = arg->sargs[0];  *qtr;  qtr++ )
 if ( *qtr == '|' )
     i++;
    text = (String*) XtMalloc(i*sizeof(String));

    /* parse text */
    for ( ptr = arg->sargs[0], i = 0;  *ptr;  i++ )
    {
     qtr = buf;
     while ( *ptr && *ptr != '|' )
         *qtr++ = *ptr++;
     *qtr = 0;
     if ( *ptr )  ptr++;
     DEBUG( D_XCMD, ( " entry = \"%s\"\n", buf ) );
 text[i] = (String) XtMalloc(strlen(buf)+1);
 strcpy( text[i], buf );
    }
    text[i] = 0;

    /* change list */
    XawListChange( arg->sel->list, (const char **)text, 0, 0, True );

    /* clear old text */
    for ( i = 0;  arg->sel->text[i];  i++ )
 XtFree( arg->sel->text[i] );
    XtFree( (char*) arg->sel->text );
    arg->sel->text = text;

    /* return OK */
    return AnswerGap( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunEnableButton( <sel>, <but>, <enable> ) . . . . enable/disable a button
*/

static Boolean FunEnableButton (
    TypeArg   * arg )
{
    Int         i;
    Widget      entry;

    /* give debug info */
    DEBUG( D_XCMD, ( "EnableButton( #%ld, #%ld, #%ld )\n"
           (long)arg->iargs[0], (long)arg->iargs[1], (long)arg->iargs[2] ) );

    /* check button number */
    i = arg->iargs[1]-1;
    if ( LEN(arg->sel->buttons) <= i || i < 0 )
 return ANSWER_GAP( "es""illegal button number", 0, 0, 0 );
    entry = ELM(arg->sel->buttons,i);

    /* enable/disable */
    if ( arg->iargs[2] )
 XtVaSetValues( entry, XtNsensitive, (XtArgVal)True, (String)NULL );
    else
 XtVaSetValues( entry, XtNsensitive, (XtArgVal)False, (String)NULL );

    /* return OK */
    return AnswerGap( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunUnhighlihtSelector( <sel> )  . . . . . . . . . . ..  unhighlight entry
*/

static Boolean FunUnhighlihtSelector (
    TypeArg   * arg )
{
    /* give debug info */
    DEBUG( D_XCMD, ( "Unhighlight( #%ld )\n", (long)arg->iargs[0] ) );

    /* unhighlight entry */
    XawListUnhighlight(arg->sel->list);

    /* return OK */
    return AnswerGap( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**

*F  * * * * * * * * * * *  functions for PopupMenus * * * * * * * * * * * * *
*/



/****************************************************************************
**

*F  FunPopupShell( <name>, <str> )  . . . . . . . . . .  create a popup shell
*/

static Int ChosenPane = 0;

static void PaneChosen (
    Widget     w,
    XtPointer       cl,
    XtPointer       ca )
{
    TypePaneData  * pd = (TypePaneData*) cl;

    DEBUG( D_XCMD, ( "PaneChosen( #%ld, #%ld )\n", (long)pd->popup,
           (long)pd->pane ) );
    ChosenPane = pd->pane;
}

static void PopingDown (
    Widget w,
    XtPointer   cl,
    XtPointer   ca )
{
    DEBUG( D_XCMD, ( "PopingDown\n" ) );
    ANSWER_GAP( "od", ChosenPane, 0, 0, 0 );
}

static char PopingDownTrans[] =
    ": notify() MenuPopdown() unhighlight()"

static Boolean FunPopupShell (
    TypeArg       * arg )
{
    Int             i;
    String          ptr;
    String          qtr;
    TypeMenu      * menu;
    TypePaneData  * pd;
    Widget          pane;
    Widget          pshell;
    char     buf[128];

    /* search for an identical popup shell */
    for ( i = 0;  i < LEN(PopupMenus);  i++ )
    {
 menu = ELM(PopupMenus,i);
 if (    ! strcmp( menu->name,   arg->sargs[0]  )
      && ! strcmp( menu->string, arg->sargs[1]) )
     break;
    }
    if ( i < LEN(PopupMenus) )
 return ANSWER_GAP( "od", i, 0, 0, 0 );

    /* create a shell */
    pshell = XtVaCreatePopupShell( "pshell", simpleMenuWidgetClass,
                       XGap, XtNcursor, (XtArgVal)CursorTL, 
                                   (String)NULL );
    XtOverrideTranslations( pshell, 
       XtParseTranslationTable(PopingDownTrans) );

    /* create headline */
    DEBUG( D_XCMD, ( "PopupShell( \"%s\", ... )\n", arg->sargs[0] ) );
    XtVaCreateManagedWidget( "menulabel", smeBSBObjectClass, pshell,
                    XtNsensitive, (XtArgVal)False,
                    XtNlabel,     (XtArgVal)(arg->sargs[0]),
                    (String)NULL );
    XtVaCreateManagedWidget( "line", smeLineObjectClass, pshell, (String)NULL );

    /* add popdown callback */
    XtAddCallback( pshell, XtNpopdownCallback, PopingDown, 0 );

    /* create menu entries */
    menu = (TypeMenu*) XtMalloc( sizeof(TypeMenu) );
    menu->shell   = pshell;
    menu->entries = List(0);
    menu->name    = XtMalloc(strlen(arg->sargs[0])+1);
    menu->string  = XtMalloc(strlen(arg->sargs[1])+1);
    strcpy( menu->name,   arg->sargs[0] );
    strcpy( menu->string, arg->sargs[1] );
    for ( ptr = arg->sargs[1], i = 1;  *ptr;  i++ )
    {
     qtr = buf;
     while ( *ptr && *ptr != '|' )
         *qtr++ = *ptr++;
     *qtr = 0;
     if ( *ptr )  ptr++;
     DEBUG( D_XCMD, ( " entry = \"%s\"\n", buf ) );
     pane = XtVaCreateManagedWidget( "menupane", smeBSBObjectClass,
                         pshell, XtNlabel, (XtArgVal)buf, 
                                        (String)NULL );
     pd = (TypePaneData*) XtMalloc( sizeof(TypePaneData) );
     pd->pane   = i;
     pd->popup  = LEN(PopupMenus);
     pd->shell  = pshell;
     XtAddCallback( pane, XtNcallback, PaneChosen, pd );
 AddList( menu->entries, (void*) pd );
    }

    /* add shell to popup shell list */
    AddList( PopupMenus, (void*) menu );
    return ANSWER_GAP( "od", LEN(PopupMenus)-1, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunShowPopup( <nr> )  . . . . . . . . . . . . . . . . popup a popup shell
*/

static Boolean FunShowPopup (
    TypeArg       * arg )
{
    Dimension       w1,  h1,  bw;
    Int             x,  y,  x2,  y2;
    Position        tmp;
    UInt            bt;
    Widget          popup;
    Window          child;
    Window          root;

    /* check popup number */
    if ( LEN(PopupMenus) <= arg->iargs[0] || arg->iargs[0] < 0 )
 return ANSWER_GAP("esd","illegal popup menu ",arg->iargs[0],0,0);
    popup = ((TypeMenu*)ELM(PopupMenus,arg->iargs[0]))->shell;

    /* get size of popup dialog */
    XtVaGetValues( popup,
                   XtNwidth,       (XtArgVal)&w1,
                   XtNheight,      (XtArgVal)&h1,
                   XtNborderWidth, (XtArgVal)&bw,
                   (String)NULL );

    /* compute screen position */
    XQueryPointer( GapDisplay, MyRootWindow,
             &root, &child, &x, &y, &x2, &y2, &bt );
    tmp = DisplayWidth( GapDisplay, GapScreen );
    if ( x+w1 > tmp )
 x = tmp-w1;
    tmp = DisplayHeight( GapDisplay, GapScreen );
    if ( y+h1 > tmp )
 y = tmp-h1;

    /* popup the popup shell */
    XtVaSetValues( popup, XtNx, (XtArgVal)(x-10), XtNy, (XtArgVal)(y-10), 
                   (String)NULL );
    XawSimpleMenuClearActiveEntry( popup );
    XtPopupSpringLoaded( popup );
    XtGrabPointer( popup, True, ButtonPressMask|ButtonReleaseMask,
     GrabModeAsync, GrabModeAsync, None, None, CurrentTime );

    /* reset 'ChosenPane' */
    ChosenPane = 0;

    /* gap will be answered by 'PopingDown' */
    return True;
}


/****************************************************************************
**

*F  * * * * * * * * * * * * functions for Dialogs * * * * * * * * * * * * * *
*/



/****************************************************************************
**

*F  FunShowDialog( <nr>, <msg>, <def> ) . . . . . . . . . . show popup dialog
*/

static Boolean FunShowDialog (
    TypeArg       * arg )
{
    Int             first;
    Int             res;
    String          str;
#ifndef NO_FILE_SELECTOR
    static String   tmp = 0;
#endif

    /* OK/Cancel dialog */
    if ( arg->iargs[0] == 1 )
    {
 first  = 4;
 res    = PopupDialog( DialogOkCancel, arg->sargs[0],
         arg->sargs[1], &str );
    }

    /* filename dialog */
    else if ( arg->iargs[0] == 2 )
    {
#       ifdef NO_FILE_SELECTOR
   first  = 4;
   res    = PopupDialog( DialogOkCancel, arg->sargs[0],
           arg->sargs[1], &str );
#       else

   /* free memory from the previous run */
   if ( tmp ) {
       XtFree(tmp);
              tmp = NULL;
          }

   /* call the file selector */
   if ( *(arg->sargs[1]) )
       res = XsraSelFile(XGap,arg->sargs[0],arg->sargs[1],0,&str);
   else
       res = XsraSelFile(XGap,arg->sargs[0],0,0,&str);

   /* ok is first button */
   first = 1;
   if ( res != first )
       str = "";
          else
       tmp = str;

#       endif
    }

    /* unknown dialog */
    else
 return ANSWER_GAP("esd","illegal popup dialog ",arg->iargs[0],0,0);

    /* return the result */
    return ANSWER_GAP( "ods", (res==first)?0:1, str, 0, 0 );
}


/****************************************************************************
**

*F  * * * * * * * * * * * * functions for Windows * * * * * * * * * * * * * *
*/



/****************************************************************************
**

*F  CloseWindow( <win> )  . . . . . . . . . . . . . . .  close an open window
*/

static void CloseWindow (
    TypeGapWindow * win )
{
    Int             i;
    Int             j;
    TypeMenu      * menu;

    /* set <used> to false */
    win->used = False;

    /* free all menus */
    for ( i = 0;  i < LEN(win->menus);  i++ )
 if ( (menu=ELM(win->menus,i)) != 0 )
 {
     for ( j = 0;  j < LEN(menu->entries);  j++ )
  XtFree((char*)ELM(menu->entries,j));
     XtFree((char*)menu->entries->ptr);
     XtFree((char*)menu->entries);
     XtFree((char*)menu);
 }
    XtFree((char*)win->menus->ptr);
    XtFree((char*)win->menus);

    /* destroy top level shell (this will destroy all children) */
    XtDestroyWidget(win->top);
}
    

/****************************************************************************
**
*F  MouseClickWindow( <talk>, <cd>, <evt>, <ctd> )  . .  handle a mouse click
*/

static void MouseClickWindow (
    Widget      talk,
    XtPointer       cd,
    XEvent        * evt,
    Boolean       * ctd )
{
    Int             bn;
    TypeGapWindow * gap = ELM(GapWindows,(Int)((Long)cd&0xffff));
    char            buf[100];

    /* we only have a two button mouse */
    if ( evt->xbutton.button == Button1 )
        bn = 1;
    else if ( evt->xbutton.button == Button3 )
        bn = 2;
    else
 return;

    /* check boundaries */
    if ( gap->width <= evt->xbutton.x || gap->height <= evt->xbutton.y )
 return;

    /* give debug information */
    DEBUG( D_XCMD, ( "MouseClickWindow( %ld, %ld, %ld, %ld )\n", (long)cd,
     (long)(evt->xbutton.x), (long)(evt->xbutton.y), (long)bn ) );

    /* construct gap command */
    sprintf( buf, "PointerButtonDown(%ld,%ld,%ld,%ld);\n", (long)cd,
      (long)evt->xbutton.x, (long)evt->xbutton.y, (long)bn );
    SimulateInput(buf);
}


/****************************************************************************
**
*F  WmDeleteWindow( <w>, <event>, <pars>, <n> ) . . . . . . wm delete request
*/

static char * WmDeleteWindowTranslation =
    "WM_PROTOCOLS: WmDeleteWindow()\n";

static void WmDeleteWindow (
    Widget      w,
    XEvent        * event,
    String        * pars,
    Cardinal      * n )
{
    TypeGapWindow * win;
    Int             i;

    if ( event->type == ClientMessage
         && event->xclient.data.l[0] != WmDeleteWindowAtom )
 return;
    for ( i = 0;  i < LEN(GapWindows);  i++ )
    {
 win = (TypeGapWindow*)ELM(GapWindows,i);
 if ( win->used && win->top == w )
     break;
    }
    if ( i < LEN(GapWindows) )
 CloseWindow(win);
}


/****************************************************************************
**
*F  FunOpenWindow( <name>, <width>, <height> ) . open a new window, external
*/

static Widget CreateTitleWindow (
    Widget     paned )
{
    return XtVaCreateManagedWidget(
         "xgapWindowText",
         labelWidgetClass,     paned,
         XtNlabel,             (XtArgVal)"GAP window",
          XtNskipAdjust,        (XtArgVal)True,
         XtNshowGrip,          (XtArgVal)False,
         (String)NULL );
}


static Boolean FunOpenWindow (
    TypeArg       * arg )
{
    Int             h = arg->iargs[1];
    Int             w = arg->iargs[0];
    Short           h1;
    Short           w1;
    String          name = arg->sargs[0];
    String          title;
    TypeGapWindow * window;
    Widget          button;
    Widget          paned;

    /* check arguments */
    if ( arg->iargs[0] < 1 || arg->iargs[1] < 1 )
 return ANSWER_GAP( "esdsd""illegal window dimensions ",
      arg->iargs[0], "x", arg->iargs[1] );
    /* give debug info */
    DEBUG( D_XCMD, ( "OpenWindow( \"%s\", %ld, %ld )\n", arg->sargs[0],
    (long)arg->iargs[0], (long)arg->iargs[1] ) );

    /* setup a new window structure, this structure will live forever */
    window = (TypeGapWindow*) XtMalloc( sizeof(TypeGapWindow) );
    window->line_width = 0;
    window->color      = C_BLACK;
    window->menus      = List(0);
    window->used       = True;
    window->text       = 0;

    /* find title position */
    XtVaGetValues( GapTalk, XtNtitlePosition, (XtArgVal)&title, (String)NULL );

    /* create a new top level shell */
    window->top = XtVaAppCreateShell(
        "XGap""GraphicSheet",
        topLevelShellWidgetClass, GapDisplay,
        (String)NULL );

    /* create a "paned" for the menu and text window */
    paned = XtVaCreateManagedWidget(
         "xgapWindow", panedWidgetClass, window->top, (String)NULL );

    /* add TOP tile */
    if ( *title == 'T' || *title == 't' )
 window->text = CreateTitleWindow(paned);

    /* create a menu box for the menu buttons */
    window->box = XtVaCreateManagedWidget(
        "xgapWindowMenu", boxWidgetClass, paned,
         XtNskipAdjust,     (XtArgVal)True,
        XtNresizeToPreferred,  (XtArgVal)True,
        XtNshowGrip,       (XtArgVal)False,
        (String)NULL );

    /* create a dummy menu button */
    button = XtVaCreateManagedWidget( "dummy", commandWidgetClass,
          window->box, XtNx, (XtArgVal)0, 
                                      (String)NULL );

    /* add MIDDLE tile */
    if ( *title == 'M' || *title == 'm' )
 window->text = CreateTitleWindow(paned);

    /* create a viewport for the window */
    window->viewport = XtVaCreateManagedWidget(
            "xgapWindowViewport",
     viewportWidgetClass, paned,
     XtNallowHoriz,       (XtArgVal)True,
     XtNallowVert,        (XtArgVal)True,
     XtNuseBottom,        (XtArgVal)True,
     XtNshowGrip,         (XtArgVal)False,
                          XtNresizable,        (XtArgVal)True,
     (String)NULL );

    /* create a drawable */
    window->draw = XtVaCreateManagedWidget(
                "xgapWindowDrawable",
         gapGraphicWidgetClass, window->viewport,
                       XtNwidth,              (XtArgVal)w,
                XtNheight,             (XtArgVal)h,
         (String)NULL );
    window->width  = w;
    window->height = h;

    /* fix dimensions of viewport */
    XtVaGetValues( window->viewport, XtNwidth, (XtArgVal)&w1, 
                                     XtNheight, (XtArgVal)&h1,
                                     (String)NULL );
    w1 = ( w1 < w ) ? w1 : w;
    h1 = ( h1 < h ) ? h1 : h;
    XtVaSetValues( window->viewport, XtNwidth, (XtArgVal)w1, 
                                     XtNheight, (XtArgVal)h1, (String)NULL );

    /* add BOTTOM tile */
    if ( window->text == 0 )
 window->text = CreateTitleWindow(paned);

    /* realize the window and return the number */
    XtRealizeWidget(window->top);

    /* add event handler for mouse clicks */
    XtAddEventHandler( window->draw, ButtonPressMask,
         False, MouseClickWindow,
         (XtPointer)(LEN(GapWindows)&0xffffL) );

    /* set handler for WM_DELETE_WINDOW */
    XSetWMProtocols(GapDisplay,XtWindow(window->top),&WmDeleteWindowAtom,1);
    XtOverrideTranslations(
 window->top, 
        XtParseTranslationTable(WmDeleteWindowTranslation) );

    /* remove dummy button and dummy text */
    XtDestroyWidget(button);
    XtVaSetValues( window->text, XtNlabel, (XtArgVal)name, (String)NULL );

    /* define cursor */
    XDefineCursor( GapDisplay, XtWindow(window->top), SleepCursor );

    /* add window to list and return window number */
    AddList( GapWindows, (void*) window );
    return ANSWER_GAP( "od", LEN(GapWindows)-1, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunCloseWindow( <win> ) . . . . . . . . .  close an open window, external
*/

static Boolean FunCloseWindow (
    TypeArg   * arg )
{
    /* give debug info */
    DEBUG( D_XCMD, ( "CloseWindow( #%ld )\n", (long)arg->iargs[0] ) );

    /* close window */
    CloseWindow(arg->win);

    /* return OK */
    return AnswerGap( "o", 0, 0, 0, 0 );
}

/****************************************************************************
**
*F  FunAddTitle( <win>, <str> ) . . . . . . . . . . . . . . add a (sub) title
*/

static Boolean FunAddTitle (
    TypeArg   * arg )
{
    XtVaSetValues( arg->win->text, XtNlabel, (XtArgVal)(arg->sargs[0]), 
                   (String)NULL );
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunColorModel() . . . . . . . color model used for gap graphics, external
*/

static Boolean FunColorModel (
    TypeArg   * arg )
{
    return ANSWER_GAP( "od", GCColorModel(GapDisplay), 0, 0, 0 );
}


/****************************************************************************
**
*F  FunFastUpdate( <win>, <flag> )  . . . . . . . . . en-/disable fast update
*/

static Boolean FunFastUpdate (
    TypeArg * arg )
{
    Boolean flag;

    flag = ( arg->iargs[1] == 0 ) ? False : True;
    if ( arg->win->fast_update != flag )
    {
 arg->win->fast_update = flag;
 GGFastUpdate( arg->win->draw, flag );
    }
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}



/****************************************************************************
**
*F  FunFontInfo( <win>, <fid> ) . . . . . . . . . .   information about fonts
*/

static Boolean FunFontInfo (
    TypeArg * arg )
{
    XFontStruct * font = arg->font;

    return ANSWER_GAP( "oddd", font->ascent, font->descent,
                 font->max_bounds.width, 0 );
}


/****************************************************************************
**
*F  FunQueryPointer( <win> )  . . . . . . . . . . . . . . . . . query pointer
*/

static Boolean FunQueryPointer (
    TypeArg       * arg )
{
    Int             x,  y,  x2,  y2;
    UInt            bt;
    UInt            md;
    UInt            pt;
    Window          child;
    Window          root;

    /* query pointer */
    XQueryPointer( XtDisplay(arg->win->draw), XtWindow(arg->win->draw),
             &root, &child, &x, &y, &x2, &y2, &pt );

    /* and make a sanity check */
    if ( arg->win->width < x2 || x2 < 0 )
 x2 = -1;
    if ( arg->win->height < y2 || y2 < 0 )
 y2 = -1;

    /* check mouse buttons */
    bt = 0;
    if ( pt & Button1Mask )
 bt |= 1;
    if ( pt & Button3Mask )
 bt |= 2;

    /* check modifier keys */
    md = 0;
    if ( pt & ShiftMask )
 md |= 1;
    if ( pt & ControlMask )
 md |= 2;
    if ( pt & Mod1Mask )
 md |= 4;

    /* gap will be answered by 'PopingDown' */
    return ANSWER_GAP( "odddd", x2, y2, bt, md );
}


/****************************************************************************
**
*F  FunResize( <win>, <width>, <height> ) . . . . . . . . . . . resize window
*/

static Boolean FunResize (
    TypeArg *   arg )
{
    ViewportWidget viewport = (ViewportWidget)arg->win->viewport;
    Widget              dummy;

    /* check arguments */
    if ( arg->iargs[1] < 1 || arg->iargs[2] < 1 )
 return ANSWER_GAP( "esdsd""illegal window dimensions ",
      arg->iargs[1], "x", arg->iargs[2] );

    /* resize window */
    arg->win->width  = arg->iargs[1];
    arg->win->height = arg->iargs[2];
    GGResize( arg->win->draw, arg->iargs[1], arg->iargs[2] );

    /* try to update scrollbars */
    XtUnmanageChild(arg->win->draw);
    dummy = XtVaCreateManagedWidget(
                "xgapWindowDrawable",
         gapGraphicWidgetClass, (Widget)viewport,
                       XtNwidth,              (XtArgVal)(arg->win->width),
                XtNheight,             (XtArgVal)(arg->win->height),
         (String)NULL );
    XtUnmanageChild(dummy);
    XtManageChild(arg->win->draw);
    XtDestroyWidget(dummy);

    /* and return */
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**

*F  * * * * * * * * * * * * * functions for Menus * * * * * * * * * * * * * *
*/



/****************************************************************************
**

*F  FunMenu( <win>, <name>, <str> ) . . . . . . . . . . . create a menu entry
*/

static void MenuClick (
    Widget     w,
    XtPointer       cl,
    XtPointer       ca )
{
    TypeMenuData  * pd = (TypeMenuData*) cl;
    char            buf[128];

    DEBUG( D_XCMD, ("MenuSelected( #%ld, #%ld, #%ld )\n", (long)pd->window,
    (long)pd->popup, (long)pd->pane) );
    sprintf( buf, "MenuSelected( %ld, %ld, %ld );\n", (long)pd->window,
      (long)pd->popup, (long)pd->pane );
    SimulateInput(buf);
}

static Boolean FunMenu (
    TypeArg       * arg )
{
    Int             i;
    String          ptr;
    String          qtr;
    TypeMenu      * menu;
    TypeMenuData  * pd;
    Widget          button;
    Widget          pane;
    Widget          pshell;
    char     buf[128];

    /* create a menu button */
    DEBUG( D_XCMD, ( "Menu( \"%s\", ... )\n", arg->sargs[0] ) );
    button = XtVaCreateManagedWidget( "menuButton", menuButtonWidgetClass,
          arg->win->box,
          XtNlabel,      (XtArgVal)(arg->sargs[0]),
          XtNshapeStyle, (XtArgVal)XmuShapeOval,
          XtNleftBitmap, (XtArgVal)MenuSymbol,
          (String)NULL );

    /* create a shell */
    pshell = XtVaCreatePopupShell( "menu", simpleMenuWidgetClass,
                       button, XtNcursor, (XtArgVal)CursorTL, 
                                   (String)NULL );

    /* create menu entries */
    menu = (TypeMenu*) XtMalloc( sizeof(TypeMenu) );
    menu->button  = button;
    menu->shell   = pshell;
    menu->entries = List(0);
    for ( ptr = arg->sargs[1], i = 1;  *ptr; )
    {
     qtr = buf;
     while ( *ptr && *ptr != '|' )
         *qtr++ = *ptr++;
     *qtr = 0;
     if ( *ptr )  ptr++;
     DEBUG( D_XCMD, ( " entry = \"%s\"\n", buf ) );
 if ( *buf == '-' )
     XtVaCreateManagedWidget( "line", smeLineObjectClass, pshell, 
                                     (String)NULL );
 else
 {
     pane = XtVaCreateManagedWidget( buf, smeBSBObjectClass,
                             pshell,
         XtNlabel,       (XtArgVal)buf,
         XtNrightMargin, (XtArgVal)14,
                                            XtNrightBitmap, 
                                                    (XtArgVal)EmptyMarkSymbol,
                                     (String)NULL );
     pd = (TypeMenuData*) XtMalloc( sizeof(TypeMenuData) );
     pd->window = arg->iargs[0];
     pd->pane   = i;
     pd->popup  = LEN(arg->win->menus);
     pd->shell  = pane;
     XtAddCallback( pane, XtNcallback, MenuClick, pd );
     i++;
     AddList( menu->entries, (void*) pd );
 }
    }

    /* add shell to popup shell list */
    AddList( arg->win->menus, (void*) menu );
    return ANSWER_GAP( "od", LEN(arg->win->menus)-1, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunDeleteMenu( <win>, <menu> )  . . . . . . . . . . . . . . delete a menu
*/

static Boolean FunDeleteMenu (
    TypeArg   * arg )
{
    TypeMenu  * menu;
    Int         j;

    /* check menu number */
    DEBUG( D_XCMD, ( "CheckMenuEntry( #%ld, #%ld, #%ld, %ld )\n",
    (long)arg->iargs[0], (long)arg->iargs[1], (long)arg->iargs[2],
    (long)arg->iargs[3] ) );
    if ( LEN(arg->win->menus) <= arg->iargs[1] || arg->iargs[1] < 0 )
 return ANSWER_GAP("esd","illegal menu number ",arg->iargs[1],0,0);
    menu = (TypeMenu*)ELM(arg->win->menus,arg->iargs[1]);
    if ( menu == 0 )
 return ANSWER_GAP( "esds""menu ", arg->iargs[1],
       " is no longer used", 0 );

    /* delete this entry */
    ELM( arg->win->menus, arg->iargs[1] ) = 0;
    for ( j = 0;  j < LEN(menu->entries);  j++ )
 XtFree((char*)ELM(menu->entries,j));
    XtFree((char*)menu->entries->ptr);
    XtFree((char*)menu->entries);
    XtDestroyWidget(menu->button);
    XtFree((char*)menu);
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}    


/****************************************************************************
**
*F  FunCheckMenuEntry( <win>, <menu>, <entry>, <check> )  . .  add check mark
*/

static Boolean FunCheckMenuEntry (
    TypeArg   * arg )
{
    TypeMenu  * menu;
    Widget      entry;

    /* check menu number */
    DEBUG( D_XCMD, ( "CheckMenuEntry( #%ld, #%ld, #%ld, %ld )\n",
    (long)arg->iargs[0], (long)arg->iargs[1], (long)arg->iargs[2],
    (long)arg->iargs[3] ) );
    if ( LEN(arg->win->menus) <= arg->iargs[1] || arg->iargs[1] < 0 )
 return ANSWER_GAP("esd","illegal menu number ",arg->iargs[1],0,0);
    menu = (TypeMenu*)ELM(arg->win->menus,arg->iargs[1]);
    if ( menu == 0 )
 return ANSWER_GAP( "esds""menu ", arg->iargs[1],
      " is no longer used", 0 );

    /* check menu entry number */
    if ( LEN(menu->entries) < arg->iargs[2] || arg->iargs[2] <= 0 )
 return ANSWER_GAP("esd","illegal menu entry ",arg->iargs[2],0,0);
    entry = ((TypeMenuData*)ELM(menu->entries,arg->iargs[2]-1))->shell;

    /* set or clear check mark */
    if ( arg->iargs[3] )
 XtVaSetValues( entry, XtNrightBitmap, (XtArgVal)CheckMarkSymbol, 
                       (String)NULL );
    else
 XtVaSetValues( entry, XtNrightBitmap, (XtArgVal)EmptyMarkSymbol, 
                       (String)NULL );
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunEnableMenuEntry( <win>, <menu>, <entry>, <check> ) . .  enable/disable
*/

static Boolean FunEnableMenuEntry (
    TypeArg   * arg )
{
    TypeMenu  * menu;
    Widget      entry;

    /* check menu number */
    DEBUG( D_XCMD, ( "EnableMenuEntry( #%ld, #%ld, #%ld, %ld )\n",
    (long)arg->iargs[0], (long)arg->iargs[1], (long)arg->iargs[2],
    (long)arg->iargs[3] ) );
    if ( LEN(arg->win->menus) <= arg->iargs[1] || arg->iargs[1] < 0 )
 return ANSWER_GAP("esd","illegal menu number ",arg->iargs[1],0,0);
    menu = (TypeMenu*)ELM(arg->win->menus,arg->iargs[1]);
    if ( menu == 0 )
 return ANSWER_GAP( "esds""menu ", arg->iargs[1],
      " is no longer used", 0 );

    /* check menu entry number */
    if ( LEN(menu->entries) < arg->iargs[2] || arg->iargs[2] <= 0 )
 return ANSWER_GAP("esd","illegal menu entry ",arg->iargs[2],0,0);
    entry = ((TypeMenuData*)ELM(menu->entries,arg->iargs[2]-1))->shell;

    /* set or clear check mark */
    if ( arg->iargs[3] )
 XtVaSetValues( entry, XtNsensitive, (XtArgVal)True, (String)NULL );
    else
 XtVaSetValues( entry, XtNsensitive, (XtArgVal)False, (String)NULL );
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**

*F  * * * * * * * * * * * functions for GraphicObjects  * * * * * * * * * * *
*/



/****************************************************************************
**

*D  CHECK_BBOX( <obj> ) . . . . . . . . . .  check dimensions of bounding box
*/

#define CHECK_BBOX(obj) obj->x = ( obj->x < 0 ) ? 0 : obj-> x; \
                        obj->y = ( obj->y < 0 ) ? 0 : obj-> y


/****************************************************************************
**
*F  FunClearAll( <win> )  . . . . . . . . . . . . . . . . . clear all objects
*/

static Boolean FunClearAll (
    TypeArg   * arg )
{
    GGFreeAllObjects( arg->win->draw );
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunRemoveObjects( <win>, <obj>, ... )   . . . . .  remove a window object
*/

static Boolean FunRemoveObjects (
    TypeArg     * arg )
{
    String   str;
    Int           n;

    /* return if no optional args are given */
    if ( (str=arg->opts) == 0 )
 return ANSWER_GAP( "es""no objects given", 0, 0, 0 );

    /* give debug info */
    DEBUG( D_XCMD, ("RemoveObject( #%ld, %s )\n",(long)arg->iargs[0],str) );

    /* remove objects */
    if ( !arg->win->fast_update )
 GGStartRemove(arg->win->draw);
    while ( *str )
    {
 if ( !ParseInt( &str, &n ) )
 {
     if ( !arg->win->fast_update )
  GGStopRemove(arg->win->draw);
     return ANSWER_GAP( "es""illegal argument", 0, 0, 0 );
 }
 if ( GGRemoveObject( arg->win->draw, n ) )
 {
     if ( !arg->win->fast_update )
  GGStopRemove(arg->win->draw);
     return ANSWER_GAP("esds","illegal object number: '",n,"'",0);
 }
    }
    if ( !arg->win->fast_update )
 GGStopRemove(arg->win->draw);
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunSetLineWidth( <win>, <wdt> ) . . . . . set line width for next objects
*/

static Boolean FunSetLineWidth (
    TypeArg   * arg )
{
    arg->win->line_width = ( arg->iargs[1] <= 1 ) ? 0 : arg->iargs[1];
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunSetColor( <win>, <col> ) . . . . . . . . .  set color for next objects
*/

static Boolean FunSetColor (
    TypeArg   * arg )
{
    if ( arg->iargs[1] < 0 )
 arg->win->color = C_BLACK;
    else if ( C_LAST < arg->iargs[1] )
 arg->win->color = C_BLACK;
    else
 arg->win->color = arg->iargs[1];
    return ANSWER_GAP( "o", 0, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunDrawBox( <win>, <x1>, <y1>, <x2>, <y2> ) . . . draw a filled rectangle
*/

static Boolean FunDrawBox (
    TypeArg               * arg )
{
    TypeGapGraphicObject  * obj;
    Int                     n;

    /* create a line object */
    obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );

    /* convert <x> and <y> coordinates to X windows style */
    obj->type  = T_BOX;
    obj->color = arg->win->color;
    obj->desc.rect.x1 = MIN( arg->iargs[1], arg->iargs[3] );
    obj->desc.rect.y1 = MIN( arg->iargs[2], arg->iargs[4] );
    obj->desc.rect.x2 = MAX( arg->iargs[1], arg->iargs[3] );
    obj->desc.rect.y2 = MAX( arg->iargs[2], arg->iargs[4] );
    obj->x = MIN( obj->desc.rect.x1, obj->desc.rect.x2 )-1;
    obj->y = MIN( obj->desc.rect.y1, obj->desc.rect.y2 )-1;
    obj->w = MAX( obj->desc.rect.x1, obj->desc.rect.x2 )+1;
    obj->h = MAX( obj->desc.rect.y1, obj->desc.rect.y2 )+1;
    CHECK_BBOX(obj);
    DEBUG( D_XCMD, ( "DrawBox( #%ld, %ld, %ld, %ld )\n",
    (long)arg->iargs[0], (long)arg->iargs[1], 
    (long)arg->iargs[2], (long)arg->iargs[3] ) );

    /* use 'GGAddObject' to draw the object */
    n = GGAddObject( arg->win->draw, obj );
    return ANSWER_GAP( "od", n, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunDrawCircle( <win>, <x>, <y>, <r> ) . . . . . . . . . . . draw a circle
*/

static Boolean FunDrawCircle (
    TypeArg               * arg )
{
    TypeGapGraphicObject  * obj;
    Int              n;
    Int                     w;

    /* create a circle object */
    obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );

    /* convert <x> and <y> coordinates to X windows style */
    obj->type  = T_CIRCLE;
    obj->color = arg->win->color;
    obj->desc.circle.r = 2 * arg->iargs[3];
    obj->desc.circle.x = arg->iargs[1] - arg->iargs[3];
    obj->desc.circle.y = arg->iargs[2] - arg->iargs[3];
    w = obj->desc.circle.w  = arg->win->line_width;
    obj->x = obj->desc.circle.x - w - 1;
    obj->y = obj->desc.circle.y - w - 1;
    obj->w = obj->desc.circle.r+1 + 2*w + 2;
    obj->h = obj->desc.circle.r+1 + 2*w + 2;
    CHECK_BBOX(obj);
    DEBUG( D_XCMD, ( "DrawCircle( #%ld, %ld, %ld, %ld )\n",
    (long)arg->iargs[0], (long)arg->iargs[1],
    (long)arg->iargs[2], (long)arg->iargs[3] ) );

    /* use 'GGAddObject' to draw the object */
    n = GGAddObject( arg->win->draw, obj );
    return ANSWER_GAP( "od", n, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunDrawDisc( <win>, <x>, <y>, <r> ) . . . . . . . . . . draw a solid disc
*/

static Boolean FunDrawDisc (
    TypeArg               * arg )
{
    TypeGapGraphicObject  * obj;
    Int              n;

    /* create a disc object */
    obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );

    /* convert <x> and <y> coordinates to X windows style */
    obj->type  = T_DISC;
    obj->color = arg->win->color;
    obj->desc.disc.r = 2 * arg->iargs[3];
    obj->desc.disc.x = arg->iargs[1] - arg->iargs[3];
    obj->desc.disc.y = arg->iargs[2] - arg->iargs[3];
    obj->x = obj->desc.disc.x;
    obj->y = obj->desc.disc.y;
    obj->w = obj->desc.disc.r+1;
    obj->h = obj->desc.disc.r+1;
    CHECK_BBOX(obj);
    DEBUG( D_XCMD, ( "DrawCircle( #%ld, %ld, %ld, %ld )\n",
    (long)arg->iargs[0], (long)arg->iargs[1],
    (long)arg->iargs[2], (long)arg->iargs[3] ) );

    /* use 'GGAddObject' to draw the object */
    n = GGAddObject( arg->win->draw, obj );
    return ANSWER_GAP( "od", n, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunDrawLine( <win>, <x1>, <y1>, <x2>, <y2> )  . . . . . . . . draw a line
*/

static Boolean FunDrawLine (
    TypeArg               * arg )
{
    TypeGapGraphicObject  * obj;
    Int              n;
    Int                     w;

    /* create a line object */
    obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );
    obj->type  = T_LINE;
    obj->color = arg->win->color;
    obj->desc.line.x1 = arg->iargs[1];
    obj->desc.line.y1 = arg->iargs[2];
    obj->desc.line.x2 = arg->iargs[3];
    obj->desc.line.y2 = arg->iargs[4];
    w = obj->desc.line.w  = arg->win->line_width;
    obj->x = MIN( obj->desc.line.x1, obj->desc.line.x2 ) - w;
    obj->y = MIN( obj->desc.line.y1, obj->desc.line.y2 ) - w;
    obj->w = MAX( obj->desc.line.x1, obj->desc.line.x2 ) - obj->x + 1 + 2*w;
    obj->h = MAX( obj->desc.line.y1, obj->desc.line.y2 ) - obj->y + 1 + 2*w;
    CHECK_BBOX(obj);
    DEBUG( D_XCMD, ( "DrawLine( #%ld, %ld, %ld, %ld, %ld )\n",
    (long)arg->iargs[0], (long)obj->desc.line.x1,
    (long)obj->desc.line.y1, (long)obj->desc.line.x2,
    (long)obj->desc.line.y2 ) );

    /* use 'GGAddObject' to draw the object */
    n = GGAddObject( arg->win->draw, obj );
    return ANSWER_GAP( "od", n, 0, 0, 0 );
}



/****************************************************************************
**
*F  FunDrawRectangle( <win>, <x1>, <y1>, <x2>, <y2> ) . . .  draw a rectangle
*/

static Boolean FunDrawRectangle (
    TypeArg               * arg )
{
    TypeGapGraphicObject  * obj;
    Int              n;
    Int                     w;

    /* create a line object */
    obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );

    /* convert <x> and <y> coordinates to X windows style */
    obj->type  = T_RECT;
    obj->color = arg->win->color;
    obj->desc.rect.x1 = MIN( arg->iargs[1], arg->iargs[3] );
    obj->desc.rect.y1 = MIN( arg->iargs[2], arg->iargs[4] );
    obj->desc.rect.x2 = MAX( arg->iargs[1], arg->iargs[3] );
    obj->desc.rect.y2 = MAX( arg->iargs[2], arg->iargs[4] );
    w = obj->desc.rect.w  = arg->win->line_width;
    obj->x = MIN( obj->desc.rect.x1, obj->desc.rect.x2 ) - w;
    obj->y = MIN( obj->desc.rect.y1, obj->desc.rect.y2 ) - w;
    obj->w = MAX( obj->desc.rect.x1, obj->desc.rect.x2 ) - obj->x + 1 + 2*w;
    obj->h = MAX( obj->desc.rect.y1, obj->desc.rect.y2 ) - obj->y + 1 + 2*w;
    CHECK_BBOX(obj);
    DEBUG( D_XCMD, ( "DrawRectangle( #%ld, %ld, %ld, %ld )\n",
    (long)arg->iargs[0], (long)arg->iargs[1],
    (long)arg->iargs[2], (long)arg->iargs[3] ) );

    /* use 'GGAddObject' to draw the object */
    n = GGAddObject( arg->win->draw, obj );
    return ANSWER_GAP( "od", n, 0, 0, 0 );
}


/****************************************************************************
**
*F  FunDrawText( <win>, <fid>, <x>, <y>, <str> )  . . . . . . draw text <str>
*/

static Boolean FunDrawText (
    TypeArg               * arg )
{
    TypeGapGraphicObject  * obj;
    XFontStruct           * font = arg->font;
    Int               n;

    /* create a TEXT object */
    obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );

    /* convert <x> and <y> coordinates to X windows style */
    obj->type  = T_TEXT;
    obj->color = arg->win->color;
    obj->desc.text.x    = arg->iargs[2];
    obj->desc.text.y    = arg->iargs[3];
    obj->desc.text.font = font->fid;
    obj->desc.text.len  = strlen(arg->sargs[0]);
    obj->desc.text.str  = XtMalloc(obj->desc.text.len+1);
    strcpy( obj->desc.text.str, arg->sargs[0] );
    obj->x = arg->iargs[2] - 1;
    obj->y = arg->iargs[3] - font->ascent - 1;
    obj->w = obj->desc.text.len*font->max_bounds.width + 2;
    obj->h = font->descent + font->ascent + 2;
    CHECK_BBOX(obj);
    DEBUG( D_XCMD, ( "DrawText( #%ld, %ld, %ld, %s )\n",
    (long)arg->iargs[0], (long)arg->iargs[1],
    (long)arg->iargs[2], arg->sargs[0] ) );

    /* use 'GGAddObject' to draw the object */
    n = GGAddObject( arg->win->draw, obj );
    return ANSWER_GAP( "od", n, 0, 0, 0 );
}


/****************************************************************************
**

*F  FunPlaybackFile( <filename> ) . . . . . . . . .  playback file <filename>
*/

static Boolean FunPlaybackFile (
    TypeArg               * arg )
{
    return PlaybackFile(arg->sargs[0]) ? 
        ANSWER_GAP( "o", 0, 0, 0, 0 ) 
      : ANSWER_GAP( "es""cannot open file", 0, 0, 0 );
}


/****************************************************************************
**
*F  FunResumePlayback() . . . . . . . . . . . . . . . resume playback of file
*/

static Boolean FunResumePlayback (
    TypeArg               * arg )
{
    return ResumePlayback() ? 
        ANSWER_GAP( "o", 0, 0, 0, 0 ) 
      : ANSWER_GAP( "es""no playback in progress", 0, 0, 0 );
}


/****************************************************************************
**

*F  * * * * * * * * * *  interface to the main program  * * * * * * * * * * *
*/



/****************************************************************************
**

*V  WindowCommands[]  . . . . . . . . . .  . . . . .  list of window commands
*/

TypeWindowCommand WindowCommands[] =
{
    { "XAT",    "#S",       FunAddTitle             },
    { "XCA",    "#",        FunClearAll             },
    { "XCL",    "TS",       FunChangeList           },
    { "XCM",    "#III",     FunCheckMenuEntry      },
    { "XCN",    "",         FunColorModel           },
    { "XCO",    "#I",       FunSetColor             },
    { "XCS",    "T",        FunCloseSelector        },
    { "XCW",    "#",        FunCloseWindow          },
    { "XDB",    "#IIII",    FunDrawBox              },
    { "XDC",    "#III",     FunDrawCircle           },
    { "XDD",    "#III",     FunDrawDisc             },
    { "XDL",    "#IIII",    FunDrawLine             },
    { "XDM",    "#I",       FunDeleteMenu           },
    { "XDR",    "#IIII",    FunDrawRectangle        },
    { "XDT",    "#FIIS",    FunDrawText             },
    { "XEB",    "TII",      FunEnableButton         },
    { "XEM",    "#III",     FunEnableMenuEntry      },
    { "XFI",    "F",        FunFontInfo             },
    { "XFU",    "#I",       FunFastUpdate           },
    { "XLW",    "#I",       FunSetLineWidth         },
    { "XME",    "#SS",      FunMenu                 },
    { "XOS",    "SSS",      FunOpenSelector         },
    { "XOW",   "SII",      FunOpenWindow           },
    { "XPF",    "S",        FunPlaybackFile         },
    { "XPS",    "SS" ,      FunPopupShell           },
    { "XQP",    "#",        FunQueryPointer         },
    { "XRE",    "#II",      FunResize               },
    { "XRP",    "",         FunResumePlayback       },
    { "XRO",    "#*",       FunRemoveObjects        },
    { "XSD",    "ISS",      FunShowDialog           },
    { "XSP",    "I",        FunShowPopup            },
    { "XUS",    "T",        FunUnhighlihtSelector   },
    { 0L,       0L,         0L                   }
};


/****************************************************************************
**
*V  PrivateActions  . . . . . . . . . . . . . . . . . . . .  action functions
*/

static XtActionsRec PrivateActions[] =
{
    { "NotifyClick",   NotifyClick    },
    { "WmDeleteWindow", WmDeleteWindow }
};


/****************************************************************************
**
*F  InitXCMDS() . . . . . . . . . . . . . . .  initialize all global variables
*/

void InitXCMDS ()
{

    /* get the fonts form the database for <GapTalk> */
    XtVaGetValues( GapTalk,
     XtNtinyFont,     (XtArgVal)&TinyFont,
     XtNsmallFont,    (XtArgVal)&SmallFont,
     XtNnormalFont,   (XtArgVal)&NormalFont,
     XtNlargeFont,    (XtArgVal)&LargeFont,
                   XtNhugeFont,     (XtArgVal)&HugeFont,
     (String)NULL );

    /* create lists for windows, popups, and selectors */
    GapWindows    = List(0);
    PopupMenus    = List(0);
    TextSelectors = List(0);

    /* create cursors */
    SleepCursor = XCreateFontCursor( GapDisplay, XC_watch );
    RunCursor   = XCreateFontCursor( GapDisplay, XC_top_left_arrow );

    /* create popup dialogs */
    DialogOkCancel = CreatePopupDialog( AppContext, XGap, "OkCancelDialog",
            PD_OK | PD_CANCEL, PD_OK, 0 );

    /* register private actions */
    XtAppAddActions( AppContext, PrivateActions, XtNumber(PrivateActions) );
}


/****************************************************************************
**
*F  UpdateXCMDS( <state> )  . . . . . . . . . .  gap is/isn't accepting input
*/

void UpdateXCMDS (
    Boolean             state)
{
    TypeGapWindow * win;
    Int                 i;

    /* GAP accepts input */
    if ( state )
    {
 for ( i = 0;  i < LEN(GapWindows);  i++ )
 {
     win = ELM( GapWindows, i );
     if ( win && win->used == True )
  XDefineCursor( GapDisplay, XtWindow(win->top), RunCursor );
 }
    }

    /* GAP doesn't accept input */
    else
    {
 for ( i = 0;  i < LEN(GapWindows);  i++ )
 {
     win = ELM( GapWindows, i );
     if ( win && win->used == True )
  XDefineCursor( GapDisplay, XtWindow(win->top), SleepCursor );
 }
    }
}


/****************************************************************************
**
*F  ExitXCMDS() . . . . . . . . . . . . . . . . .  clear all global variables
*/

void ExitXCMDS ()
{
    TypeArg         arg;
    TypeMenu      * menu;
    Int             i;
    Int             j;

    /* clear list of windows and popups */
    for ( i = 0;  i < LEN(GapWindows);  i++ )
    {
 arg.win = ELM(GapWindows,i);
 if ( arg.win->used )
     FunCloseWindow(&arg);
 XtFree((char*)ELM(GapWindows,i));
    }
    XtFree((char*)GapWindows);
    for ( i = 0;  i < LEN(TextSelectors);  i++ )
    {
 arg.sel = ELM(TextSelectors,i);
 if ( arg.sel != 0 )
 {
     FunCloseSelector(&arg);
     XtFree((char*)ELM(TextSelectors,i));
 }
    }
    XtFree((char*)TextSelectors);
    for (i = 0;  i < LEN(PopupMenus);  i++ )
 if ( (menu = ELM(PopupMenus,i)) != 0 )
 {
     for ( j = 0;  j < LEN(menu->entries);  j++ )
  XtFree((char*)ELM(menu->entries,j));
     XtFree((char*)menu->entries);
     XtFree((char*)menu);
 }
    XtFree((char*)PopupMenus);
}


/****************************************************************************
**

*E  xcmds.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
*/

94%


¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.23Angebot  Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können  ¤

*Eine klare Vorstellung vom Zielzustand






Normalansicht

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.