home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / ft-beta.zip / freetype / test / gwin_x11.c < prev    next >
C/C++ Source or Header  |  1997-10-06  |  11KB  |  448 lines

  1. /*******************************************************************
  2.  *
  3.  *  gwin_x11.c  graphics utility X-Window driver.              1.0
  4.  *
  5.  *  This is the driver for windowed display under X11, used by the
  6.  *  graphics utility of the FreeType test suite.
  7.  *
  8.  *  Copyright 1996, 1997 by
  9.  *  David Turner, Robert Wilhelm, and Werner Lemberg.
  10.  *
  11.  *  This file is part of the FreeType project, and may only be used
  12.  *  modified and distributed under the terms of the FreeType project
  13.  *  license, LICENSE.TXT. By continuing to use, modify or distribute 
  14.  *  this file you indicate that you have read the license and
  15.  *  understand and accept it fully.
  16.  *
  17.  ******************************************************************/
  18.  
  19. #include "gdriver.h"
  20. #include "gmain.h"
  21. #include "gevents.h"
  22.  
  23. #include "ttconfig.h"
  24. #include "tttypes.h"
  25. #include "tterror.h" /* for Trace */
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <X11/Xlib.h>
  31. #include <X11/Xutil.h>
  32. #include <X11/cursorfont.h>
  33.  
  34.   /* Translator added to ease changes to control keys */
  35.  
  36.   typedef struct  _Translator
  37.   {
  38.     char    key;
  39.     GEvent  event_class;
  40.     int     event_info;
  41.   } Translator;
  42.  
  43. #define NUM_Translators  16
  44.  
  45.   static const Translator  trans[NUM_Translators] =
  46.   {
  47.     { (char)27, event_Quit,            0 },
  48.     { 'q',      event_Quit,            0 },
  49.  
  50.     { 'x',      event_Rotate_Glyph,   -1 },
  51.     { 'c',      event_Rotate_Glyph,    1 },
  52.     { 'v',      event_Rotate_Glyph,  -16 },
  53.     { 'b',      event_Rotate_Glyph,   16 },
  54.  
  55.     { '9',      event_Change_Glyph, -100 },
  56.     { '0',      event_Change_Glyph,  100 },
  57.     { 'i',      event_Change_Glyph,  -10 },
  58.     { 'o',      event_Change_Glyph,   10 },
  59.     { 'k',      event_Change_Glyph,   -1 },
  60.     { 'l',      event_Change_Glyph,    1 },
  61.  
  62.     { '+',      event_Scale_Glyph,    10 },
  63.     { '-',      event_Scale_Glyph,   -10 },
  64.     { 'u',      event_Scale_Glyph,     1 },
  65.     { 'j',      event_Scale_Glyph,    -1 }
  66.   };
  67.  
  68.   /* End of translators addition. See Get_Event() below */
  69.  
  70.   extern char      Header[];    /* defined in the test programs */
  71.  
  72.   static Window    win;
  73.   static GC        gcblack;
  74.   static XColor    color[5];
  75.  
  76.   Display*         display;
  77.   static char*     displayname = "";
  78.  
  79.   static XImage*   image;
  80.  
  81.   static Visual*   visual;
  82.   static Colormap  colormap;
  83.   static int       depth;
  84.   static Bool      gray;
  85.  
  86.   static Cursor    idle;
  87.   static Cursor    busy;
  88.  
  89.   static int       win_origin_x, win_origin_y,
  90.                    win_width, win_height;
  91.   static int       image_width, image_height;
  92.  
  93.   long             vioBufOfs;
  94.  
  95.  
  96.  
  97.   /* restore acreen to its original state */
  98.  
  99.   int  Driver_Restore_Mode()
  100.   {
  101.     XUnmapWindow( display, win );
  102.     XCloseDisplay( display );
  103.  
  104.     return 1;       /* success */
  105.   }
  106.  
  107.  
  108.   /* set graphics mode */
  109.  
  110.   void  x11init()
  111.   {
  112.     int                   screen_num, i;
  113.     XTextProperty         xtp;
  114.     XSizeHints            xsh;
  115.     XSetWindowAttributes  xswa;
  116.  
  117. #if 1
  118.     unsigned short colors[5] = { 0, 16, 32, 48, 63 }; /* gamma = 1.0 */
  119. #else
  120.     unsigned short colors[5] = { 0, 34, 46, 55, 63 }; /* gamma = 2.2 */
  121. #endif
  122.  
  123.  
  124.     XrmInitialize();
  125.  
  126.     if( !( display = XOpenDisplay( displayname ) ) )
  127.       Panic( "ERROR: cannot open display\n" );
  128.  
  129.     screen_num = DefaultScreen  ( display );
  130.     colormap   = DefaultColormap( display, screen_num );
  131.     depth      = DefaultDepth   ( display, screen_num );
  132.     visual     = DefaultVisual  ( display, screen_num );
  133.  
  134.     idle       = XCreateFontCursor( display, XC_left_ptr );
  135.     busy       = XCreateFontCursor( display, XC_watch );
  136.  
  137.     if ( gray )
  138.     {
  139.       int                   count;
  140.       XPixmapFormatValues*  formats;
  141.  
  142.  
  143.       formats           = XListPixmapFormats( display, &count );
  144.       vio_ScanLineWidth = 0;
  145.  
  146.       while ( count > 0 )
  147.       {
  148.         --count;
  149.         if ( formats[count].depth == depth )
  150.         {
  151.           int  bits;
  152.  
  153.           bits = win_width * formats[count].bits_per_pixel;
  154.           if ( bits % formats[count].scanline_pad )
  155.           {
  156.             bits -= bits % formats[count].scanline_pad;
  157.             bits += formats[count].scanline_pad;
  158.           }
  159.  
  160.           vio_ScanLineWidth = bits / 8;
  161.           break;
  162.         }
  163.       }
  164.       if ( !vio_ScanLineWidth )
  165.         Panic( "ERROR: the display doesn't offer a suitable pixmap format\n" );
  166.  
  167.       XFree( formats );
  168.     }
  169.  
  170.     Vio = (char*)malloc( win_height * vio_ScanLineWidth );
  171.  
  172.     if ( !Vio )
  173.       Panic( "ERROR: cannot malloc display memory\n" );
  174.  
  175.     xswa.border_pixel     = BlackPixel( display, screen_num );
  176.     xswa.background_pixel = WhitePixel( display, screen_num );
  177.     xswa.cursor           = busy;
  178.  
  179.     xswa.event_mask = KeyPressMask | ExposureMask;
  180.     
  181.     win = XCreateWindow( display,
  182.                          RootWindow( display, screen_num ),
  183.                          win_origin_x,
  184.                          win_origin_y,
  185.                          win_width,
  186.                          win_height,
  187.                          10,
  188.                          depth,
  189.                          InputOutput, 
  190.                          visual,
  191.                          CWBackPixel | CWBorderPixel | CWEventMask | CWCursor,
  192.                          &xswa );
  193.  
  194.     XMapWindow( display, win );
  195.  
  196.     gcblack = XCreateGC( display, RootWindow( display, screen_num ),
  197.                          0L, NULL );
  198.     XSetForeground( display, gcblack, BlackPixel( display, screen_num ) );
  199.     XSetBackground( display, gcblack, WhitePixel( display, screen_num ) );
  200.  
  201.     /* allocate colors */
  202.  
  203.     if ( gray )
  204.       for ( i = 0; i < 5; i++ )
  205.       {
  206.         gray_palette[i] = i;
  207.   
  208.         color[i].red   =
  209.         color[i].green =
  210.         color[i].blue  = 65535 - ( colors[i] * 65535 ) / 63;
  211.   
  212.         if ( !XAllocColor( display, colormap, &color[i] ) )
  213.           Panic( "ERROR: cannot allocate Color\n" );
  214.       }
  215.  
  216.     image = XCreateImage( display, 
  217.                           visual,
  218.                           gray ? depth   : 1, 
  219.                           gray ? ZPixmap : XYBitmap,
  220.                           0, 
  221.                           (char*)Vio, 
  222.                           win_width, 
  223.                           win_height, 
  224.                           8, 
  225.                           0 );
  226.     if ( !image )
  227.       Panic( "ERROR: cannot create image\n" );
  228.  
  229.     if ( !gray )
  230.     {
  231.       image->byte_order       = MSBFirst;
  232.       image->bitmap_bit_order = MSBFirst;
  233.     }
  234.  
  235.     /* make window manager happy :-) */
  236.     xtp.value    = (unsigned char*)"FreeType";
  237.     xtp.encoding = 31;
  238.     xtp.format   = 8;
  239.     xtp.nitems   = strlen( (char*)xtp.value );
  240.  
  241.     xsh.x = win_origin_x;
  242.     xsh.y = win_origin_y;
  243.  
  244.     xsh.width  = win_width;
  245.     xsh.height = win_height;
  246.     xsh.flags  = (PPosition | PSize);
  247.     xsh.flags  = 0;
  248.  
  249.     XSetWMProperties( display, win, &xtp, &xtp, NULL, 0, &xsh, NULL, NULL );
  250.   }
  251.  
  252.  
  253.   int  Driver_Set_Graphics( int  mode )
  254.   {
  255.     if ( mode == Graphics_Mode_Gray )
  256.     {
  257.       gray = 1;
  258.       vio_ScanLineWidth = 320;
  259.  
  260.       win_origin_x = 0;
  261.       win_origin_y = 0;
  262.       win_width  = 320;
  263.       win_height = 200;
  264.     }
  265.     else if ( mode == Graphics_Mode_Mono )
  266.     {
  267.       gray = 0;
  268.       vio_ScanLineWidth = 80;
  269.  
  270.       win_origin_x = 0;
  271.       win_origin_y = 0;
  272.       win_width  = 640;
  273.       win_height = 450;
  274.     }
  275.     else
  276.       Panic( "ERROR: mode %d not supported\n", mode );
  277.  
  278.     vio_Width  = win_width;
  279.     vio_Height = win_height;
  280.  
  281.     x11init();
  282.  
  283.     return 1;       /* success */
  284.   }
  285.  
  286.  
  287.   void  Put_Image( int  x, int  y, int  w, int  h )
  288.   {
  289.     XPutImage( display, win, gcblack, image, x, y, x, y, w, h );
  290.   }
  291.  
  292.  
  293.   int  Driver_Display_Bitmap( char*  buffer, int  line, int  col )
  294.   {
  295.     int    z, y, used_col;
  296.     char*  target;
  297.  
  298.  
  299.     XClearWindow( display, win );
  300.  
  301.     /* this displays the Header string in the window title */
  302.     XStoreName( display, win, Header );
  303.  
  304.     if ( line > win_height )
  305.       line = win_height;
  306.  
  307.     if ( !gray )
  308.     {
  309.       if ( col > vio_ScanLineWidth )
  310.         used_col = vio_ScanLineWidth;
  311.       else
  312.         used_col = col;
  313.  
  314.       target = Vio + ( line - 1 ) * vio_ScanLineWidth;
  315.  
  316.       for ( y = 0; y < line; y++ )
  317.       {
  318.         memcpy( (char*)target, buffer, used_col );
  319.         target -= vio_ScanLineWidth;
  320.         buffer += col;
  321.       }
  322.  
  323.       Put_Image( 0, 0, used_col * 8, line );
  324.       image_width  = used_col * 8;
  325.       image_height = line;
  326.     }
  327.     else
  328.     {
  329.       if ( col > win_width )
  330.         used_col = win_width;
  331.       else
  332.         used_col = col;
  333.  
  334.       for ( y = line - 1; y >= 0; y-- )
  335.       {
  336.         char*  bufp;
  337.  
  338.  
  339.         bufp = buffer;
  340.  
  341.         for ( z = 0; z < used_col; z++ )
  342.         {
  343.           int  c;
  344.  
  345.  
  346.           c = *bufp++;
  347.  
  348.           if ( c < 0 || c >= 5 ) /* security check */
  349.           {
  350.             Message( "weird grayshade: %d\n", c );
  351.             c = 0;
  352.           }
  353.           XPutPixel( image, z, y, color[c].pixel );
  354.         }
  355.  
  356.         buffer += col;
  357.       }
  358.  
  359.       Put_Image( 0, 0, used_col, line );
  360.       image_width  = used_col;
  361.       image_height = line;
  362.     }
  363.  
  364.     return 1;
  365.   }
  366.  
  367.  
  368.   /* This function maps X keystrokes into GEvents. Note that */
  369.   /* currently only keystrokes events exit this function.    */
  370.  
  371.   void  Get_Event( TEvent*  event )
  372.   {
  373.     static char     key_buffer[10];
  374.     static int      key_cursor = 0;
  375.     static int      key_number = 0;
  376.     static XEvent   x_event;
  377.            KeySym   key;
  378.  
  379.     int             i, bool_exit;
  380.     char            c;
  381.  
  382.     XComposeStatus  compose;
  383.  
  384.  
  385.     bool_exit = key_cursor < key_number;
  386.  
  387.     XDefineCursor( display, win, idle );
  388.  
  389.     while ( !bool_exit )
  390.     {
  391.       XNextEvent( display, &x_event );
  392.  
  393.       switch ( x_event.type )
  394.       {
  395.       case KeyPress:
  396.         key_number = XLookupString( &x_event.xkey,
  397.                                     key_buffer,
  398.                                     sizeof ( key_buffer ),
  399.                                     &key,
  400.                                     &compose );
  401.         key_cursor = 0;
  402.  
  403.         if ( key_number > 0 )
  404.           bool_exit = 1;
  405.         break;
  406.  
  407.       case MappingNotify:
  408.         XRefreshKeyboardMapping( &x_event.xmapping );
  409.         break;
  410.       
  411.       case Expose:
  412. #if 0
  413.         Put_Image( x_event.xexpose.x, 
  414.                    x_event.xexpose.y,
  415.                    x_event.xexpose.width, 
  416.                    x_event.xexpose.height );
  417. #else
  418.         /* we always redraw the whole image */
  419.         Put_Image( 0, 0, image_width, image_height );
  420. #endif
  421.         break;
  422.  
  423.       /* You should add more cases to handle mouse events, etc. */
  424.       }
  425.     }
  426.  
  427.     XDefineCursor( display, win, busy );
  428.     XFlush       ( display );
  429.  
  430.     c = key_buffer[key_cursor++];
  431.  
  432.     for ( i = 0; i < NUM_Translators; i++ )
  433.     {
  434.       if ( c == trans[i].key )
  435.       {
  436.         event->what = trans[i].event_class;
  437.         event->info = trans[i].event_info;
  438.         return;
  439.       }
  440.     }
  441.  
  442.     event->what = event_Keyboard;
  443.     event->info = (int)c;
  444.   }
  445.  
  446.  
  447. /* End */
  448.