/*------------------------------------------------------------\
|                                                             |
| Tool    :                   GRAAL                           |
|                                                             |
| File    :                   Event.c                         |
|                                                             |
| Authors :      Venot Frederic and Jacomme Ludovic           |
|                                                             |
| Date    :                  01.08.93                         |
|                                                             |
\------------------------------------------------------------*/

/*------------------------------------------------------------\
|                                                             |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/

# include <stdio.h>
# include <X11/Intrinsic.h>
# include <X11/StringDefs.h>
# include <Xm/Xm.h>

 
# include MUT_H
# include MPH_H
# include RDS_H
# include RPR_H
# include GSB_H
# include GRM_H
# include GMX_H
# include GTB_H
# include GMV_H
# include GMS_H
# include GME_H
# include GMH_H
# include "GMX_motif.h"
# include "GMX_grid.h"
# include "GMX_cursor.h"
# include "GMX_event.h"
# include "GMX_message.h"

/*------------------------------------------------------------\
|                                                             |
|                           Constants                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                            Types                            |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Translation                        |
|                                                             |
\------------------------------------------------------------*/

  static String GraalEventTranslation =

    "<Btn1Down>:    CallbackEvent( 0 )\n\
     <Btn2Down>:    CallbackEvent( 1 )\n\
     <Btn3Down>:    CallbackEvent( 2 )\n\
     <Motion>:      CallbackEvent( 3 )\n\
     <EnterWindow>: CallbackEvent( 4 )\n\
     <LeaveWindow>: CallbackEvent( 5 )";

/*------------------------------------------------------------\
|                                                             |
|                         Event Count                         |
|                                                             |
\------------------------------------------------------------*/

  static char GraalMaxEventEditTable[] =

  {
    2,  /* GRAAL_EDIT_MEASURE           */
    2,  /* GRAAL_CREATE_SEGMENT         */
    2,  /* GRAAL_CREATE_SEGMENT_WIRE    */
    1,  /* GRAAL_CREATE_VIA             */
    2,  /* GRAAL_CREATE_TRANSISTOR      */
    2,  /* GRAAL_CREATE_TRANSISTOR_WIRE */
    1,  /* GRAAL_CREATE_CONNECTOR       */
    1,  /* GRAAL_CREATE_INSTANCE        */
    1,  /* GRAAL_CREATE_REFERENCE       */
    2,  /* GRAAL_CREATE_ABUTMENTBOX     */
    1,  /* GRAAL_SELECT_POINT_IDENTIFY  */
    1,  /* GRAAL_SELECT_POINT_COPY      */
    1,  /* GRAAL_SELECT_POINT_MOVE      */
    1,  /* GRAAL_SELECT_POINT_DELETE    */
    1,  /* GRAAL_SELECT_POINT_STRETCH   */
    1,  /* GRAAL_SELECT_POINT_MODIFY    */
    2,  /* GRAAL_SELECT_WINDOW_IDENTIFY */
    2,  /* GRAAL_SELECT_WINDOW_COPY     */
    2,  /* GRAAL_SELECT_WINDOW_MOVE     */
    2,  /* GRAAL_SELECT_WINDOW_DELETE   */
    2,  /* GRAAL_SELECT_WINDOW_MODIFY   */
    2,  /* GRAAL_EDIT_COPY_POINT        */
    2,  /* GRAAL_EDIT_COPY_WINDOW       */
    2,  /* GRAAL_EDIT_MOVE_POINT        */
    2,  /* GRAAL_EDIT_MOVE_WINDOW       */
    2,  /* GRAAL_EDIT_STRETCH_POINT     */
    1,  /* GRAAL_TOOLS_EQUI             */
    2,  /* GRAAL_TOOLS_FLATTEN          */
    2,  /* GRAAL_TOOLS_UNFLATTEN        */
    2,  /* GRAAL_TOOLS_PEEK             */
    2   /* GRAAL_TOOLS_DRUC             */
  };

  static char GraalInputEventEditTable[] =

  {
    GRAAL_INPUT_HALF_BOX, /* GRAAL_EDIT_MEASURE           */
    GRAAL_INPUT_ORTHO,    /* GRAAL_CREATE_SEGMENT         */
    GRAAL_INPUT_LSTRING,  /* GRAAL_CREATE_SEGMENT_WIRE    */
    GRAAL_INPUT_POINT,    /* GRAAL_CREATE_VIA             */
    GRAAL_INPUT_ORTHO,    /* GRAAL_CREATE_TRANSISTOR      */
    GRAAL_INPUT_LSTRING,  /* GRAAL_CREATE_TRANSISTOR_WIRE */
    GRAAL_INPUT_POINT,    /* GRAAL_CREATE_CONNECTOR       */
    GRAAL_INPUT_POINT,    /* GRAAL_CREATE_INSTANCE        */
    GRAAL_INPUT_POINT,    /* GRAAL_CREATE_REFERENCE       */
    GRAAL_INPUT_BOX,      /* GRAAL_CREATE_ABUTMENTBOX     */
    GRAAL_INPUT_POINT,    /* GRAAL_SELECT_POINT_IDENTIFY  */
    GRAAL_INPUT_POINT,    /* GRAAL_SELECT_POINT_COPY      */
    GRAAL_INPUT_POINT,    /* GRAAL_SELECT_POINT_MOVE      */ 
    GRAAL_INPUT_POINT,    /* GRAAL_SELECT_POINT_DELETE    */ 
    GRAAL_INPUT_POINT,    /* GRAAL_SELECT_POINT_STRETCH   */ 
    GRAAL_INPUT_POINT,    /* GRAAL_SELECT_POINT_MODIFY    */ 
    GRAAL_INPUT_BOX,      /* GRAAL_SELECT_WINDOW_IDENTIFY */
    GRAAL_INPUT_BOX,      /* GRAAL_SELECT_WINDOW_COPY     */ 
    GRAAL_INPUT_BOX,      /* GRAAL_SELECT_WINDOW_MOVE     */ 
    GRAAL_INPUT_BOX,      /* GRAAL_SELECT_WINDOW_DELETE   */ 
    GRAAL_INPUT_BOX,      /* GRAAL_SELECT_WINDOW_MODIFY   */ 
    GRAAL_INPUT_LINE,     /* GRAAL_EDIT_COPY_POINT        */ 
    GRAAL_INPUT_LINE,     /* GRAAL_EDIT_COPY_WINDOW       */ 
    GRAAL_INPUT_LINE,     /* GRAAL_EDIT_MOVE_POINT        */ 
    GRAAL_INPUT_LINE,     /* GRAAL_EDIT_MOVE_WINDOW       */ 
    GRAAL_INPUT_ORTHO,    /* GRAAL_EDIT_STRETCH_POINT     */ 
    GRAAL_INPUT_POINT,    /* GRAAL_TOOLS_EQUI             */
    GRAAL_INPUT_BOX,      /* GRAAL_TOOLS_FLATTEN          */
    GRAAL_INPUT_BOX,      /* GRAAL_TOOLS_UNFLATTEN        */
    GRAAL_INPUT_BOX,      /* GRAAL_TOOLS_PEEK             */
    GRAAL_INPUT_BOX       /* GRAAL_TOOLS_DRUC             */
  };

  static char GraalMaxEventZoomTable[] =

  {
    1,  /* GRAAL_ZOOM_CENTER            */
    2,  /* GRAAL_ZOOM_IN                */
    2   /* GRAAL_ZOOM_PAN               */
  };

  static char GraalInputEventZoomTable[] =

  {
    GRAAL_INPUT_POINT,  /* GRAAL_ZOOM_CENTER            */
    GRAAL_INPUT_BOX,    /* GRAAL_ZOOM_IN                */
    GRAAL_INPUT_LINE    /* GRAAL_ZOOM_PAN               */
  };

/*------------------------------------------------------------\
|                                                             |
|                          Translation                        |
|                                                             |
\------------------------------------------------------------*/

/*------------------------------------------------------------\
|                                                             |
|                      Expose Edit Zoom                       |
|                                                             |
\------------------------------------------------------------*/

  static long     GraalLambdaEventZoomX[ 2 ] = { 0, 0 };
  static long     GraalLambdaEventZoomY[ 2 ] = { 0, 0 };
  static char     GraalMaxEventZoom          = 0;
         char     GraalCountEventZoom        = 0;

  static long     GraalLambdaEventEditX[ 2 ] = { 0, 0 };
  static long     GraalLambdaEventEditY[ 2 ] = { 0, 0 };
  static char     GraalMaxEventEdit          = 2;
         char     GraalCountEventEdit        = 0;

  static char     GraalFirstExpose           = GRAAL_TRUE;

/*------------------------------------------------------------\
|                                                             |
|                          Input                              |
|                                                             |
\------------------------------------------------------------*/

 static char GraalInputMode     = GRAAL_INPUT_HALF_BOX;
 static char GraalSaveInputMode = GRAAL_INPUT_HALF_BOX;
 static char GraalEditMode      = GRAAL_EDIT_MEASURE;
 static char GraalSaveEditMode  = GRAAL_EDIT_MEASURE;

/*------------------------------------------------------------\
|                                                             |
|                          Edit Message                       |
|                                                             |
\------------------------------------------------------------*/

  static void (*GraalPromptMessage)()     = GraalPromptEditMeasure;
  static void (*GraalSavePromptMessage)() = GraalPromptEditMeasure;

/*------------------------------------------------------------\
|                                                             |
|                           Functions                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                     GraalChangeEditMode                     |
|                                                             |
\------------------------------------------------------------*/
 
  void GraalChangeEditMode( EditMode , PromptMessage )
 
     char  EditMode;
     void (*PromptMessage)();
  {
    if ( EditMode & GRAAL_ZOOM_MARK )
    {
      EditMode = EditMode & ~GRAAL_ZOOM_MARK;

      GraalCountEventZoom = 0;
      GraalMaxEventZoom   = GraalMaxEventZoomTable[ EditMode ];

      if ( ! ( GraalEditMode & GRAAL_ZOOM_MARK ) )
      {
        GraalSaveEditMode      = GraalEditMode;
        GraalSaveInputMode     = GraalInputMode;
        GraalSavePromptMessage = GraalPromptMessage;
      }

      GraalInputMode     = GraalInputEventZoomTable[ EditMode ];
      GraalPromptMessage = PromptMessage;
      GraalEditMode      = EditMode | GRAAL_ZOOM_MARK;

      GraalChangeCursorType( NULL, NULL, 0, GraalInputMode );
    }  
    else
    {
      if ( GraalEditMode & GRAAL_ZOOM_MARK )
      {
        GraalSaveEditMode      = EditMode;
        GraalSaveInputMode     = GraalInputEventEditTable[ EditMode ];
        GraalSavePromptMessage = PromptMessage;
        GraalCountEventEdit    = 0;
        GraalMaxEventEdit      = GraalMaxEventEditTable[ EditMode ];
      }
      else
      {
        if ( GraalEditMode != EditMode )
        {
          GraalCountEventEdit = 0;
          GraalMaxEventEdit   = GraalMaxEventEditTable[ EditMode ];
          GraalEditMode       = EditMode;
          GraalInputMode      = GraalInputEventEditTable[ EditMode ];
          GraalPromptMessage  = PromptMessage;

          GraalChangeCursorType( NULL, NULL, 0, GraalInputMode );
        }
      }

      GraalEditUnselectAll();
    }

    GraalPromptMessage();
  }

/*------------------------------------------------------------\
|                                                             |
|                   GraalContinueEditMode                     |
|                                                             |
\------------------------------------------------------------*/

  void GraalContinueEditMode( EditMode , PromptMessage, CountEvent )

     char  EditMode;
     void (*PromptMessage)();
     char  CountEvent;
  {
    if ( GraalEditMode & GRAAL_ZOOM_MARK )
    {
      GraalSaveEditMode      = EditMode;
      GraalSaveInputMode     = GraalInputEventEditTable[ EditMode ];
      GraalSavePromptMessage = PromptMessage;
      GraalCountEventEdit    = CountEvent;
      GraalMaxEventEdit      = GraalMaxEventEditTable[ EditMode ];
    }
    else
    {
      GraalCountEventEdit = CountEvent;
      GraalMaxEventEdit   = GraalMaxEventEditTable[ EditMode ];
      GraalEditMode       = EditMode;
      GraalInputMode      = GraalInputEventEditTable[ EditMode ];
      GraalPromptMessage  = PromptMessage;

      GraalChangeCursorType( GraalLambdaEventEditX,
                             GraalLambdaEventEditY,
                             GraalCountEventEdit,
                             GraalInputMode );

    }

    GraalPromptMessage();
  }

/*------------------------------------------------------------\
|                                                             |
|                      GraalTreatEventZoom                    |
|                                                             |
\------------------------------------------------------------*/

  void GraalTreatEventZoom()

  {
    GraalChangeCursorType( GraalLambdaEventEditX,
                           GraalLambdaEventEditY,
                           GraalCountEventEdit,
                           GraalSaveInputMode );

    switch ( GraalEditMode )
    {
      case GRAAL_ZOOM_CENTER :
                                
        GraalZoomCenter( GraalLambdaEventZoomX[ 0 ], 
                         GraalLambdaEventZoomY[ 0 ] );
        break;
  
      case GRAAL_ZOOM_IN     :

        GraalZoomIn( GraalLambdaEventZoomX[ 0 ],
                     GraalLambdaEventZoomY[ 0 ],
                     GraalLambdaEventZoomX[ 1 ],
                     GraalLambdaEventZoomY[ 1 ] );
        break;

      case GRAAL_ZOOM_PAN    :

        GraalZoomPan( GraalLambdaEventZoomX[ 0 ],
                      GraalLambdaEventZoomY[ 0 ],
                      GraalLambdaEventZoomX[ 1 ],
                      GraalLambdaEventZoomY[ 1 ] );
        break;
    }
  }

/*------------------------------------------------------------\
|                                                             |
|                      GraalTreatEventEdit                    |
|                                                             |
\------------------------------------------------------------*/

  void GraalTreatEventEdit()

  { 
    long DeltaX;
    long DeltaY;
    long X1;
    long X2;
    long Y1;
    long Y2;

    X1 = GraalLambdaEventEditX[0];
    X2 = GraalLambdaEventEditX[1];
    Y1 = GraalLambdaEventEditY[0];
    Y2 = GraalLambdaEventEditY[1];

    if ( ( GraalInputMode == GRAAL_INPUT_LSTRING ) || 
         ( GraalInputMode == GRAAL_INPUT_ORTHO   ) ||
         ( GraalInputMode == GRAAL_INPUT_SORTHO  ) )
    {
      DeltaX = X1 - X2;
      DeltaY = Y1 - Y2;

      if ( DeltaX < 0 ) DeltaX = - DeltaX;
      if ( DeltaY < 0 ) DeltaY = - DeltaY;

      if ( DeltaX > DeltaY )
      {
        Y2 = Y1;

        GraalLambdaEventEditX[0] = X2;
        GraalLambdaEventEditY[0] = Y2;
      }  
      else
      {   
        X2 = X1;

        GraalLambdaEventEditX[0] = X2;
        GraalLambdaEventEditY[0] = Y2;
      }
    }

    if ( GraalInputMode == GRAAL_INPUT_LSTRING )
    {   
      GraalChangeCursorType( GraalLambdaEventEditX,
                             GraalLambdaEventEditY,
                             1, GraalInputMode );
 
      GraalCountEventEdit = 1;
    }
    else
    {
      GraalChangeCursorType( NULL, NULL, 0,
                             GraalInputMode );

      GraalCountEventEdit = 0;
    }

    switch ( GraalEditMode )
    {
      case GRAAL_EDIT_MEASURE           :

        break;

      case GRAAL_CREATE_SEGMENT         :
      case GRAAL_CREATE_SEGMENT_WIRE    :

        GraalCreateSegmentMbk( X1, Y1, X2, Y2 );

        break;

      case GRAAL_CREATE_VIA             :

        GraalCreateViaMbk( X1, Y1 );

        break;
 
      case GRAAL_CREATE_TRANSISTOR      :
      case GRAAL_CREATE_TRANSISTOR_WIRE :

        GraalCreateTransistorMbk( X1, Y1, X2, Y2 );

        break;

      case GRAAL_CREATE_CONNECTOR       :

        GraalCreateConnectorMbk( X1, Y1 );

        break;

      case GRAAL_CREATE_REFERENCE       :

        GraalCreateReferenceMbk( X1, Y1 );

        break;

      case GRAAL_CREATE_INSTANCE        :

        GraalCreateInstanceMbk( X1, Y1 );

        break;

      case GRAAL_CREATE_ABUTMENTBOX  :

       GraalCreateAbutmentBoxMbk( X1, Y1, X2, Y2 );

      break;

      case GRAAL_SELECT_POINT_IDENTIFY :
 
        GraalEditSelectPoint( X1, Y1 );
        GraalEditIdentify();

      break;

      case GRAAL_SELECT_WINDOW_IDENTIFY :

        GraalEditSelectFence( X1, Y1, X2, Y2 );
        GraalEditIdentify();

      break;

      case GRAAL_SELECT_POINT_COPY :

        GraalEditSelectPointCopy( X1, Y1 );

      break;

      case GRAAL_SELECT_WINDOW_COPY :

        GraalEditSelectWindowCopy( X1, Y1, X2, Y2 );

      break;

      case GRAAL_EDIT_COPY_POINT :

        GraalEditCopy( X1, Y1, X2, Y2, 0 );

      break;

      case GRAAL_EDIT_COPY_WINDOW :
 
        GraalEditCopy( X1, Y1, X2, Y2, 1 );

      break;

      case GRAAL_SELECT_POINT_MOVE :

        GraalEditSelectPointMove( X1, Y1 );

      break;

      case GRAAL_SELECT_WINDOW_MOVE :

        GraalEditSelectWindowMove( X1, Y1, X2, Y2 );

      break;

      case GRAAL_EDIT_MOVE_POINT :

        GraalEditMove( X1, Y1, X2, Y2, 0 );

      break;

      case GRAAL_EDIT_MOVE_WINDOW :

        GraalEditMove( X1, Y1, X2, Y2, 1 );

      break;

      case GRAAL_SELECT_POINT_DELETE :

        GraalEditSelectPointDelete( X1, Y1 );

      break;

      case GRAAL_SELECT_WINDOW_DELETE :

        GraalEditSelectWindowDelete( X1, Y1, X2, Y2 );

      break;

      case GRAAL_SELECT_POINT_STRETCH :

        GraalEditSelectPointStretch( X1, Y1 );

      break;

      case GRAAL_EDIT_STRETCH_POINT :

        GraalEditStretch( X1, Y1, X2, Y2 );

      break;

      case GRAAL_SELECT_POINT_MODIFY :

        GraalEditSelectPointModify( X1, Y1 );

      break;

      case GRAAL_SELECT_WINDOW_MODIFY :

        GraalEditSelectWindowModify( X1, Y1, X2, Y2 );

      break;

      case GRAAL_TOOLS_EQUI :

        GraalToolsSelectEqui( X1, Y1 );

      break;

      case GRAAL_TOOLS_PEEK :

         GraalToolsPeek( X1, Y1, X2, Y2 );

      break;

      case GRAAL_TOOLS_FLATTEN :

        GraalToolsSelectFlatten( X1, Y1, X2, Y2 );

      break;

      case GRAAL_TOOLS_UNFLATTEN :

        GraalToolsSelectUnflatten( X1, Y1, X2, Y2 );

      break;

      case GRAAL_TOOLS_DRUC :

        GraalToolsDruc( X1, Y1, X2, Y2 );

      break;
    }
  }

/*------------------------------------------------------------\
|                                                             |
|                       CallbackEvent                         |
|                                                             |
\------------------------------------------------------------*/

  void CallbackEvent ( MyWidget, Event, Args, Argc )

       Widget        MyWidget;
       XButtonEvent *Event;
       String       *Args;
       int          *Argc;
  {
    Display  *EventDisplay;
    char      MouseEvent;
    Position  OldLambdaCursorX;
    Position  OldLambdaCursorY;

    EventDisplay = Event->display;

    MouseEvent = Args[ 0 ][ 0 ] - '0';

    if ( MouseEvent == GRAAL_LEAVE )
    {
      GraalUndisplayCursor();
      GraalCursorInside = GRAAL_FALSE;
    }
    else
    {
      OldLambdaCursorX = GraalLambdaCursorX;
      OldLambdaCursorY = GraalLambdaCursorY;

      GraalComputeCursor( Event->x, Event->y );

      switch ( MouseEvent )
      {
        case GRAAL_B1UP   : 

          if ( GraalEditMode & GRAAL_ZOOM_MARK )
          {
            if ( GraalCountEventZoom < GraalMaxEventZoom )
            {
              GraalLambdaEventZoomX[ GraalCountEventZoom ] = GraalLambdaCursorX;
              GraalLambdaEventZoomY[ GraalCountEventZoom ] = GraalLambdaCursorY;

              GraalCountEventZoom = GraalCountEventZoom + 1;

              GraalPointCursor();
            
              if ( GraalCountEventZoom == GraalMaxEventZoom )
              {
                GraalTreatEventZoom();

                GraalInputMode      = GraalSaveInputMode;
                GraalEditMode       = GraalSaveEditMode;
                GraalPromptMessage  = GraalSavePromptMessage;
                GraalSaveEditMode   = GRAAL_EDIT_MEASURE;
                GraalSaveInputMode  = GRAAL_INPUT_HALF_BOX;
                GraalCountEventZoom = 0;
                GraalMaxEventZoom   = 0;

                GraalComputeCursor( Event->x, Event->y );
                GraalDisplayCursor();
              }
            }
          }
          else
          {
            if ( GraalCountEventEdit < GraalMaxEventEdit )
            {
              GraalLambdaEventEditX[ GraalCountEventEdit ] = GraalLambdaCursorX;
              GraalLambdaEventEditY[ GraalCountEventEdit ] = GraalLambdaCursorY;

              GraalCountEventEdit = GraalCountEventEdit + 1;

              GraalPointCursor();

              if ( GraalCountEventEdit == GraalMaxEventEdit )
              {
                GraalTreatEventEdit();

                GraalDisplayCursor();
              }
            }
          }

          GraalPromptMessage();

          break;

        case GRAAL_B2UP   :

          break;

        case GRAAL_B3UP   :

          if ( GraalEditMode & GRAAL_ZOOM_MARK )
          {
            if ( GraalCountEventZoom != 0 )
            {
              GraalCountEventZoom = GraalCountEventZoom - 1;

              GraalResetCursor();
            }
            else
            { 
              GraalChangeCursorType( GraalLambdaEventEditX,
                                     GraalLambdaEventEditY,
                                     GraalCountEventEdit,
                                     GraalSaveInputMode );

              GraalInputMode          = GraalSaveInputMode;
              GraalEditMode           = GraalSaveEditMode;
              GraalPromptMessage      = GraalSavePromptMessage;
              GraalSaveEditMode       = GRAAL_EDIT_MEASURE;
              GraalSaveInputMode      = GRAAL_INPUT_HALF_BOX;
              GraalSavePromptMessage  = GraalPromptEditMeasure;
              GraalCountEventZoom     = 0;
              GraalMaxEventZoom       = 0;
            }
          }
          else
          {
            if ( GraalCountEventEdit != 0 )
            {
              GraalCountEventEdit = GraalCountEventEdit - 1;

              GraalResetCursor();
            }
            else
            {
              GraalEditUnselectAll();

              GraalChangeCursorType( NULL, NULL, 0,
                                     GRAAL_INPUT_HALF_BOX );

              GraalInputMode      = GRAAL_INPUT_HALF_BOX;
              GraalEditMode       = GRAAL_EDIT_MEASURE;
              GraalPromptMessage  = GraalPromptEditMeasure;
              GraalCountEventEdit = 0;
              GraalMaxEventEdit   = 2;
            }
          }

          GraalPromptMessage();

          break; 

        case GRAAL_MOTION :

          break;

        case GRAAL_ENTER  : GraalCursorInside = GRAAL_TRUE;
                            GraalDisplayCursor();
                            break;
      }

      if ( ( OldLambdaCursorX != GraalLambdaCursorX ) ||
           ( OldLambdaCursorY != GraalLambdaCursorY ) )
      {
        GraalDisplayCoordinates(); 
        GraalDisplayCursor();
      }
    }
  }

/*------------------------------------------------------------\
|                                                             |
|                       CallbackResize                        |
|                                                             |
\------------------------------------------------------------*/

  void CallbackResize( MyWidget, ClientData, CallData )

       Widget                       MyWidget;
       XtPointer                    ClientData;
       XmDrawingAreaCallbackStruct *CallData;
  {
    if ( GraalFirstExpose == GRAAL_FALSE )
    {
      GraalSetMouseCursor( GraalGraphicWindow, GRAAL_WATCH_CURSOR );
      GraalUndisplayCursor();

      GraalResizeGraphicWindow();
      GraalRefreshGraphicWindow( 0, 0,
                                 GraalGraphicDx, GraalGraphicDy );
      GraalSetMouseCursor( GraalGraphicWindow, GRAAL_NORMAL_CURSOR );
      GraalDisplayCursor();
    }
  }
  
/*------------------------------------------------------------\
|                                                             |
|                       CallbackExpose                        |
|                                                             |
\------------------------------------------------------------*/
  
  void CallbackExpose( MyWidget, ClientData, CallData )

       Widget                       MyWidget;
       XtPointer                    ClientData;
       XmDrawingAreaCallbackStruct *CallData;
  {
    XExposeEvent *ExposeEvent;

    ExposeEvent = (XExposeEvent *)CallData->event;

    if ( GraalFirstExpose == GRAAL_TRUE )
    {
      GraalFirstExpose = GRAAL_FALSE;
      GraalInitializeGraphicWindow();
      GraalUndisplayCursor();

      GraalLoadConfig( GRAAL_FALSE );

      if ( GraalFigureMbk != (phfig_list *)NULL )
      {
        GraalSetMouseCursor( GraalGraphicWindow, GRAAL_WATCH_CURSOR );

        GraalAddFigure();
        GraalInitializeZoom();
        GraalDisplayToolsMessage();
        GraalDisplayFigure( 0, 0, GraalGraphicDx, GraalGraphicDy );

        GraalSetMouseCursor( GraalGraphicWindow, GRAAL_NORMAL_CURSOR );
      }

      GraalRefreshGraphicWindow( 0, 0, GraalGraphicDx, GraalGraphicDy );
      GraalDisplayCursor();

      GraalEnterDialog( &GraalPresentDialog );
    }
    else
    {
      GraalUndisplayCursor();
      GraalRefreshGraphicWindow( ExposeEvent->x, ExposeEvent->y,
                                 ExposeEvent->width, ExposeEvent->height );
      GraalDisplayCursor();
    }
  }

/*------------------------------------------------------------\
|                                                             |
|                     GraalInitializeEvent                    |
|                                                             |
\------------------------------------------------------------*/

  void GraalInitializeEvent()

  {
    XtActionsRec NewActions;

    XtVaSetValues( GraalGraphicWindow,
                   XmNtranslations,
                   XtParseTranslationTable( GraalEventTranslation ),
                   NULL
                 );

    NewActions.string = "CallbackEvent";
    NewActions.proc   =  CallbackEvent;

    XtAppAddActions( GraalApplication, &NewActions, 1 );

    XtAddCallback( GraalGraphicWindow, 
                   XmNresizeCallback, 
                   CallbackResize, NULL );

    XtAddCallback( GraalGraphicWindow, 
                   XmNexposeCallback, 
                   CallbackExpose, NULL );
  }
