⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grx11.c

📁 Ftee type Demo for Linux open source
💻 C
📖 第 1 页 / 共 3 页
字号:
  /************************************************************************/
  /************************************************************************/

  typedef struct  grX11Surface_
  {
    grSurface           root;
    Display*            display;
    Window              win;
    Visual*             visual;
    Colormap            colormap;
    GC                  gc;
    int                 depth;
    XImage*             ximage;
    grBitmap            ximage_bitmap;

    const grX11Format*  format;
    grX11ConvertFunc    convert;

    int                 win_org_x,   win_org_y;
    int                 win_width,   win_height;
    int                 image_width, image_height;

    char                key_buffer[10];
    int                 key_cursor;
    int                 key_number;

  } grX11Surface;


  /* close a given window */
  static void
  gr_x11_surface_done( grX11Surface*  surface )
  {
    Display*  display = surface->display;


    if ( display )
    {
      if ( surface->ximage )
      {
        XDestroyImage( surface->ximage );
        surface->ximage = 0;
      }

      if ( surface->win )
      {
        XUnmapWindow( display, surface->win );
        surface->win = 0;
      }
    }
  }


  static void
  gr_x11_surface_refresh_rect( grX11Surface*  surface,
                               int            x,
                               int            y,
                               int            w,
                               int            h )
  {
    grX11Blitter  blit;


    if ( !gr_x11_blitter_reset( &blit, &surface->root.bitmap,
                                &surface->ximage_bitmap,
                                x, y, w, h ) )
    {
      surface->convert( &blit );

      XPutImage( surface->display,
                 surface->win,
                 surface->gc,
                 surface->ximage,
                 blit.x, blit.y, blit.x, blit.y, blit.width, blit.height );
    }
  }


  static void
  gr_x11_surface_refresh( grX11Surface*  surface )
  {
    gr_x11_surface_refresh_rect( surface, 0, 0,
                                 surface->root.bitmap.width,
                                 surface->root.bitmap.rows );
  }


  static void
  gr_x11_surface_set_title( grX11Surface*  surface,
                             const char*   title )
  {
    XStoreName( surface->display, surface->win, title );
  }


  static grKey
  KeySymTogrKey( KeySym  key )
  {
    grKey        k;
    int          count = sizeof ( key_translators ) /
                           sizeof( key_translators[0] );
    Translator*  trans = key_translators;
    Translator*  limit = trans + count;


    k = grKeyNone;

    while ( trans < limit )
    {
      if ( trans->xkey == key )
      {
        k = trans->grkey;
        break;
      }
      trans++;
    }

    return k;
  }


  static void
  gr_x11_surface_listen_event( grX11Surface*  surface,
                               int            event_mask,
                               grEvent*       grevent )
  {
    XEvent     x_event;
    KeySym     key;
    Display*   display = surface->display;

    int        bool_exit;
    grKey      grkey;

    XComposeStatus  compose;

    /* XXX: for now, ignore the event mask, and only exit when */
    /*      a key is pressed                                   */
    (void)event_mask;

    bool_exit = surface->key_cursor < surface->key_number;

    XDefineCursor( display, surface->win, x11dev.idle );

    while ( !bool_exit )
    {
      XNextEvent( display, &x_event );

      switch ( x_event.type )
      {
      case KeyPress:
        surface->key_number = XLookupString( &x_event.xkey,
                                             surface->key_buffer,
                                             sizeof ( surface->key_buffer ),
                                             &key,
                                             &compose );
        surface->key_cursor = 0;

        if ( surface->key_number == 0 ||
             key > 512       )
        {
          /* this may be a special key like F1, F2, etc. */
          grkey = KeySymTogrKey( key );
          if ( grkey != grKeyNone )
            goto Set_Key;
        }
        else
          bool_exit = 1;
        break;

      case MappingNotify:
        XRefreshKeyboardMapping( &x_event.xmapping );
        break;

      case Expose:
#if 1
        /* we don't need to convert the bits on each expose! */
        XPutImage( surface->display,
                   surface->win,
                   surface->gc,
                   surface->ximage,
                   x_event.xexpose.x,
                   x_event.xexpose.y,
                   x_event.xexpose.x,
                   x_event.xexpose.y,
                   x_event.xexpose.width,
                   x_event.xexpose.height );
#else
        gr_x11_surface_refresh_rectangle( surface,
                                          x_event.xexpose.x,
                                          x_event.xexpose.y,
                                          x_event.xexpose.width,
                                          x_event.xexpose.height );
#endif
        break;

      /* You should add more cases to handle mouse events, etc. */
      }
    }

    XDefineCursor( display, surface->win, x11dev.busy );
    XFlush       ( display );

    /* now, translate the keypress to a grKey; */
    /* if this wasn't part of the simple translated keys, */
    /* simply get the charcode from the character buffer  */
    grkey = grKEY( surface->key_buffer[surface->key_cursor++] );

  Set_Key:
    grevent->type = gr_key_down;
    grevent->key  = grkey;
  }


  static int
  gr_x11_surface_init( grX11Surface*  surface,
                       grBitmap*      bitmap )
  {
    Display*            display;
    int                 screen;
    grBitmap*           pximage = &surface->ximage_bitmap;
    const grX11Format*  format;


    surface->key_number = 0;
    surface->key_cursor = 0;
    surface->display    = display = x11dev.display;

    screen = DefaultScreen( display );

    surface->depth    = x11dev.format->x_depth;
    surface->visual   = x11dev.visual;

    surface->format      = format = x11dev.format;
    surface->root.bitmap = *bitmap;

    switch ( bitmap->mode )
    {
    case gr_pixel_mode_rgb24:
      surface->convert = format->rgb_convert;
      break;

    case gr_pixel_mode_gray:
      /* we only support 256-gray level 8-bit pixmaps */
      if ( bitmap->grays == 256 )
      {
        surface->convert = format->gray_convert;
        break;
      }

    default:
      /* we don't support other modes */
      return 0;
    }

    /* allocate surface image */
    {
      int  bits, over;


      bits = bitmap->width * format->x_bits_per_pixel;
      over = bits % x11dev.scanline_pad;

      if ( over )
        bits += x11dev.scanline_pad - over;

      pximage->pitch  = bits >> 3;
      pximage->width  = bitmap->width;
      pximage->rows   = bitmap->rows;
    }

    pximage->buffer =
      (unsigned char*)grAlloc( pximage->pitch * pximage->rows );
    if ( !pximage->buffer )
      return 0;

    /* create the bitmap */
    if ( grNewBitmap( bitmap->mode,
                      bitmap->grays,
                      bitmap->width,
                      bitmap->rows,
                      bitmap ) )
      return 0;

    surface->root.bitmap = *bitmap;

    /* Now create the surface X11 image */
    surface->ximage = XCreateImage( display,
                                    surface->visual,
                                    format->x_depth,
                                    ZPixmap,
                                    0,
                                    (char*)pximage->buffer,
                                    pximage->width,
                                    pximage->rows,
                                    x11dev.scanline_pad,
                                    0 );
    if ( !surface->ximage )
      return 0;

    {
      XColor                color, dummy;
      XTextProperty         xtp;
      XSizeHints            xsh;
      XSetWindowAttributes  xswa;
      long                  xswa_mask = CWBackPixel | CWEventMask | CWCursor;

      xswa.border_pixel = BlackPixel( display, screen);

      if (surface->visual == DefaultVisual( display, screen ) )
      {
        xswa.background_pixel = WhitePixel( display, screen );
        surface->colormap     = DefaultColormap( display, screen );
      }
      else
      {
        xswa_mask             |= CWColormap | CWBorderPixel;
        xswa.colormap         = XCreateColormap( display, 
                                                 RootWindow( display, screen ), 
                                                 surface->visual, 
                                                 AllocNone );
        XAllocNamedColor( display, xswa.colormap, "white", &color, &dummy );
        xswa.background_pixel = color.pixel;
        surface->colormap     = xswa.colormap;
      }

      xswa.cursor           = x11dev.busy;

      xswa.event_mask = KeyPressMask | ExposureMask;

      surface->win = XCreateWindow( display,
                                    RootWindow( display, screen ),
                                    0,
                                    0,
                                    bitmap->width,
                                    bitmap->rows,
                                    10,
                                    format->x_depth,
                                    InputOutput,
                                    surface->visual,
                                    xswa_mask,
                                    &xswa );

      XMapWindow( display, surface->win );

      surface->gc = XCreateGC( display, surface->win,
                               0L, NULL );
      XSetForeground( display, surface->gc, xswa.border_pixel     );
      XSetBackground( display, surface->gc, xswa.background_pixel );

      /* make window manager happy :-) */
      xtp.value    = (unsigned char*)"FreeType";
      xtp.encoding = 31;
      xtp.format   = 8;
      xtp.nitems   = strlen( (char*)xtp.value );

      xsh.x = 0;
      xsh.y = 0;

      xsh.width  = bitmap->width;
      xsh.height = bitmap->rows;
      xsh.flags  = PPosition | PSize;
      xsh.flags  = 0;

      XSetWMProperties( display, surface->win, &xtp, &xtp,
                        NULL, 0, &xsh, NULL, NULL );
    }

    surface->root.done         = (grDoneSurfaceFunc)gr_x11_surface_done;
    surface->root.refresh_rect = (grRefreshRectFunc)gr_x11_surface_refresh_rect;
    surface->root.set_title    = (grSetTitleFunc)   gr_x11_surface_set_title;
    surface->root.listen_event = (grListenEventFunc)gr_x11_surface_listen_event;

    gr_x11_surface_refresh( surface );

    return 1;
  }


  grDevice  gr_x11_device =
  {
    sizeof( grX11Surface ),
    "x11",

    gr_x11_device_init,
    gr_x11_device_done,

    (grDeviceInitSurfaceFunc) gr_x11_surface_init,

    0,
    0
  };


#ifdef TEST

  typedef struct  grKeyName
  {
    grKey        key;
    const char*  name;

  } grKeyName;


  static const grKeyName  key_names[] =
  {
    { grKeyF1,   "F1"  },
    { grKeyF2,   "F2"  },
    { grKeyF3,   "F3"  },
    { grKeyF4,   "F4"  },
    { grKeyF5,   "F5"  },
    { grKeyF6,   "F6"  },
    { grKeyF7,   "F7"  },
    { grKeyF8,   "F8"  },
    { grKeyF9,   "F9"  },
    { grKeyF10,  "F10" },
    { grKeyF11,  "F11" },
    { grKeyF12,  "F12" },
    { grKeyEsc,  "Esc" },
    { grKeyHome, "Home" },
    { grKeyEnd,  "End"  },

    { grKeyPageUp,   "Page_Up" },
    { grKeyPageDown, "Page_Down" },
    { grKeyLeft,     "Left" },
    { grKeyRight,    "Right" },
    { grKeyUp,       "Up" },
    { grKeyDown,     "Down" },
    { grKeyBackSpace, "BackSpace" },
    { grKeyReturn,   "Return" }
  };


#if 0
  int
  main( void )
  {
    grSurface*  surface;
    int         n;


    grInit();
    surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
    if ( !surface )
      Panic( "Could not create window\n" );
    else
    {
      grColor      color;
      grEvent      event;
      const char*  string;
      int          x;


      grSetSurfaceRefresh( surface, 1 );
      grSetTitle( surface, "X11 driver demonstration" );

      for ( x = -10; x < 10; x++ )
      {
        for ( n = 0; n < 128; n++ )
        {
          color.value = ( n * 3 ) & 127;
          grWriteCellChar( surface,
                           x + ( ( n % 60 ) << 3 ),
                           80 + ( x + 10 ) * 8 * 3 + ( ( n / 60 ) << 3 ),
                           n, color );
        }
      }

      color.value = 64;
      grWriteCellString( surface, 0, 0, "just an example", color );

      do
      {
        listen_event( (grXSurface*)surface, 0, &event );

        /* return if ESC was pressed */
        if ( event.key == grKeyEsc )
          return 0;

        /* otherwise, display key string */
        color.value = ( color.value + 8 ) & 127;
        {
          int          count = sizeof ( key_names ) / sizeof ( key_names[0] );
          grKeyName*   name  = key_names;
          grKeyName*   limit = name + count;
          const char*  kname = 0;
          char         kname_temp[16];


          while ( name < limit )
          {
            if ( name->key == event.key )
            {
              kname = name->name;
              break;
            }
            name++;
          }

          if ( !kname )
          {
            sprintf( kname_temp, "char '%c'", (char)event.key );
            kname = kname_temp;
          }

          grWriteCellString( surface, 30, 30, kname, color );
          grRefreshSurface( surface );
          paint_rectangle( surface, 0, 0,
                           surface->bitmap.width, surface->bitmap.rows );
        }
      } while ( 1 );
    }

    return 0;
  }
#endif /* O */
#endif /* TEST */


/* END */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -