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

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

# include <stdio.h>
# include <X11/cursorfont.h>
# include <X11/Intrinsic.h>
# include GTB_H
# include "GTB_cursor.h"

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

  static GraalMouseCursor GraalMouseCursorArray [ GRAAL_MAX_CURSOR ] =

         {
           { 0                , True  },
           { XC_watch         , True  },
           { XC_pirate        , True  },
           { XC_cross_reverse , True  }
         };

  static char  GraalCursorMaskOr [ 8 ] = 

  {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };

  static char  GraalCursorMaskAnd [ 8 ] =

  {
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  };

/*------------------------------------------------------------\
|                                                             |
|                          Functions                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                      GraalSetMouseCursor                    |
|                                                             |
\------------------------------------------------------------*/

  void GraalSetMouseCursor( MainWidget, CursorType )

       Widget MainWidget;
       char   CursorType;
  {
    Display          *DisplayId;
    XEvent            MouseEvent;
    Widget            TopShell;
    Widget            ScanShell;
    Window            TopWindow;
    Window            ScanWindow;
    XWindowAttributes WindowAtt;
    XtAppContext      Context;
    XColor            White;
    XColor            Black;
    XColor            ForgetIt;
    Colormap          ColorMap;
    Pixmap            MaskOr;
    Pixmap            MaskAnd;
    Cursor            NewCursor;

    ScanShell = MainWidget;

    while ( ! XtIsShell( ScanShell ) )
    {
      ScanShell = XtParent( ScanShell );
    }

    TopShell = ScanShell;

    while ( ! XtIsTopLevelShell( TopShell ) )
    {
      TopShell = XtParent( TopShell );
    }

    XFlush(XtDisplay (TopShell));

    DisplayId = XtDisplay( ScanShell );

    TopWindow  = XtWindow( TopShell  );
    ScanWindow = XtWindow( ScanShell );

    if ( GraalMouseCursorArray[ CursorType ].MAKE == True )
    {
      if ( GraalMouseCursorArray[ CursorType ].CURSOR != 0 )
      {
        NewCursor = XCreateFontCursor( DisplayId, 
                                       GraalMouseCursorArray[ CursorType ].CURSOR );
      }
      else
      {
        ColorMap = DefaultColormapOfScreen ( XtScreen( MainWidget ) );

        XAllocNamedColor( DisplayId, ColorMap, "black", &Black, &ForgetIt );
        XAllocNamedColor( DisplayId, ColorMap, "white", &White, &ForgetIt );

        MaskOr = 

          XCreatePixmapFromBitmapData( DisplayId,
                                       XtWindow( MainWidget ),
                                       GraalCursorMaskOr,
                                       8, 8,
                                       Black.pixel,
                                       White.pixel, 1 );
        MaskAnd =

          XCreatePixmapFromBitmapData( DisplayId,
                                       XtWindow( MainWidget ),
                                       GraalCursorMaskAnd,
                                       8, 8,
                                       Black.pixel,
                                       White.pixel, 1 );

        NewCursor = XCreatePixmapCursor( DisplayId, 
                                         MaskAnd, MaskOr,
                                         &Black, &White, 0, 0 );
      }

      GraalMouseCursorArray[ CursorType ].CURSOR = NewCursor;
      GraalMouseCursorArray[ CursorType ].MAKE   = False;
    }

    XDefineCursor( XtDisplay( TopShell ), 
                   XtWindow( MainWidget ),
                   GraalMouseCursorArray[ CursorType ].CURSOR );

    Context = XtWidgetToApplicationContext( TopShell );

    if ( XtIsRealized( ScanShell ) && XtIsRealized( TopShell ) )
    {
      while ( ( XGetWindowAttributes( DisplayId, ScanWindow, &WindowAtt ) ) &&
              ( WindowAtt.map_state != IsViewable                         ) )
      {
        if ( ( XGetWindowAttributes( DisplayId, TopWindow, &WindowAtt ) ) && 
             ( WindowAtt.map_state != IsViewable                        ) ) 

            break;

        XtAppNextEvent( Context, &MouseEvent );
        XtDispatchEvent( &MouseEvent );
      }
    }

    XmUpdateDisplay( TopShell );
  }
