?? grx11.c
字號:
/************************************************************************/ /************************************************************************/ 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 + -