?? gros2pm.c
字號(hào):
#include "grobjs.h"#include "grdevice.h"#define INCL_DOS#define INCL_WIN#define INCL_GPI#define INCL_SUB#include <os2.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdarg.h>#define DEBUGxxx#ifdef DEBUG#define LOG(x) LogMessage##x#else#define LOG(x) /* rien */#endif#ifdef DEBUG static void LogMessage( const char* fmt, ... ) { va_list ap; va_start( ap, fmt ); vfprintf( stderr, fmt, ap ); va_end( ap ); }#endif typedef struct Translator { ULONG os2key; grKey grkey; } Translator; static Translator key_translators[] = { { VK_BACKSPACE, grKeyBackSpace }, { VK_TAB, grKeyTab }, { VK_ENTER, grKeyReturn }, { VK_ESC, grKeyEsc }, { VK_HOME, grKeyHome }, { VK_LEFT, grKeyLeft }, { VK_UP, grKeyUp }, { VK_RIGHT, grKeyRight }, { VK_DOWN, grKeyDown }, { VK_PAGEUP, grKeyPageUp }, { VK_PAGEDOWN, grKeyPageDown }, { VK_END, grKeyEnd }, { VK_F1, grKeyF1 }, { VK_F2, grKeyF2 }, { VK_F3, grKeyF3 }, { VK_F4, grKeyF4 }, { VK_F5, grKeyF5 }, { VK_F6, grKeyF6 }, { VK_F7, grKeyF7 }, { VK_F8, grKeyF8 }, { VK_F9, grKeyF9 }, { VK_F10, grKeyF10 }, { VK_F11, grKeyF11 }, { VK_F12, grKeyF12 } };#define MAX_PIXEL_MODES 32 static HAB gr_anchor; /* device anchor block */ typedef POINTL PMBlitPoints[4]; typedef struct grPMSurface_ { grSurface root; grBitmap image; HAB anchor; /* handle to anchor block for surface's window */ HWND frame_window; /* handle to window's frame */ HWND client_window; /* handle to window's client */ HWND title_window; /* handle to window's title bar */ HPS image_ps; /* memory presentation space used to hold */ /* the surface's content under PM */ HDC image_dc; /* memory device context for the image */ HEV event_lock; /* semaphore used in listen_surface */ HMTX image_lock; /* a mutex used to synchronise access */ /* to the memory presentation space */ /* used to hold the surface */ TID message_thread; /* thread used to process this surface's */ /* messages.. */ PBITMAPINFO2 bitmap_header;/* os/2 bitmap descriptor */ HBITMAP os2_bitmap; /* Handle to OS/2 bitmap contained in image */ BOOL ready; /* ??? */ long shades[256]; /* indices of gray levels in pixel_mode_gray */ POINTL surface_blit[4]; /* surface blitting table */ POINTL magnify_blit[4]; /* magnifier blitting table */ int magnification; /* level of magnification */ POINTL magnify_center; SIZEL magnify_size; grEvent event; PMBlitPoints blit_points; } grPMSurface; /* we use a static variable to pass a pointer to the PM Surface */ /* to the client window. This is a bit ugly, but it makes things */ /* a lot more simple.. */ static grPMSurface* the_surface; static void enable_os2_iostreams( void ) { PTIB thread_block; PPIB process_block; /* XXX : This is a very nasty hack, it fools OS/2 and let the program */ /* call PM functions, even though stdin/stdout/stderr are still */ /* directed to the standard i/o streams.. */ /* The program must be compiled with WINDOWCOMPAT */ /* */ /* Credits go to Michal for finding this !! */ /* */ DosGetInfoBlocks( &thread_block, &process_block ); process_block->pib_ultype = 3; } static int init_device( void ) { enable_os2_iostreams(); /* create an anchor block. This will allow this thread (i.e. the */ /* main one) to call Gpi functions.. */ gr_anchor = WinInitialize(0); if (!gr_anchor) { /* could not initialise Presentation Manager */ return -1; } return 0; } static void done_device( void ) { /* Indicates that we do not use the Presentation Manager, this */ /* will also release all associated resources.. */ WinTerminate( gr_anchor ); } /* close a given window */ static void done_surface( grPMSurface* surface ) { LOG(( "Os2PM: done_surface(%08lx)\n", (long)surface )); if ( surface->frame_window ) WinDestroyWindow( surface->frame_window ); WinReleasePS( surface->image_ps ); grDoneBitmap( &surface->image ); grDoneBitmap( &surface->root.bitmap ); }#define LOCK(x) DosRequestMutexSem( x, SEM_INDEFINITE_WAIT )#define UNLOCK(x) DosReleaseMutexSem( x ) static const int pixel_mode_bit_count[] = { 0, 1, /* mono */ 4, /* pal4 */ 8, /* pal8 */ 8, /* grays */ 15, /* rgb15 */ 16, /* rgb16 */ 24, /* rgb24 */ 32 /* rgb32 */ }; /************************************************************************ * * Technical note : how the OS/2 Presntation Manager driver works * * PM is, in my opinion, a bloated and over-engineered graphics * sub-system, even though it has lots of nice features. Here are * a few tidbits about it : * * * - under PM, a "bitmap" is a device-specific object whose bits are * not directly accessible to the client application. This means * that we must use a scheme like the following to display our * surfaces : * * - hold, for each surface, its own bitmap buffer where the * rest of the graph library writes directly. * * - create a PM bitmap object with the same dimensions (and * possibly format). * * - copy the content of each updated rectangle into the * PM bitmap with the function 'GpiSetBitmapBits'. * * - finally, "blit" the PM bitmap to the screen calling * 'GpiBlitBlt' * * - but there is more : you cannot directly blit a PM bitmap to the * screen with PM. The 'GpiBlitBlt' only works with presentation * spaces. This means that we also need to create, for each surface : * * - a memory presentation space, used to hold the PM bitmap * - a "memory device context" for the presentation space * * The blit is then performed from the memory presentation space * to the screen's presentation space.. * * * - because each surface creates its own event-handling thread, * we must protect the surface's presentation space from concurrent * accesses (i.e. calls to 'GpiSetBitmapBits' when drawing to the * surface, and calls to 'GpiBlitBlt' when drawing it on the screen * are performed in two different threads). * * we use a simple mutex to do this. * * * - we also use a semaphore to perform a rendez-vous between the * main and event-handling threads (needed in "listen_event"). * ************************************************************************/ static void RunPMWindow( grPMSurface* surface ); static void refresh_rectangle( grPMSurface* surface, int x, int y, int w, int h ) { LOG(( "Os2PM: refresh_rectangle( %08lx, %d, %d, %d, %d )\n", (long)surface, x, y, w, h )); (void)x; (void)y; (void)w; (void)h; /* convert_rectangle( surface, x, y, w, h ); */ LOCK( surface->image_lock ); GpiSetBitmapBits( surface->image_ps, 0, surface->root.bitmap.rows, surface->root.bitmap.buffer, surface->bitmap_header ); UNLOCK( surface->image_lock ); WinInvalidateRect( surface->client_window, NULL, FALSE ); WinUpdateWindow( surface->frame_window ); } static void set_title( grPMSurface* surface, const char* title ) { ULONG rc;#if 1 LOG(( "Os2PM: set_title( %08lx == %08lx, %s )\n", (long)surface, surface->client_window, title ));#endif LOG(( " -- frame = %08lx\n", (long)surface->frame_window )); LOG(( " -- client parent = %08lx\n", (long)WinQueryWindow( surface->client_window, QW_PARENT ) )); rc = WinSetWindowText( surface->client_window, (PSZ)title ); LOG(( " -- returned rc = %ld\n",rc )); } static void listen_event( grPMSurface* surface, int event_mask, grEvent* grevent ) { ULONG ulRequestCount; (void) event_mask; /* ignored for now */ /* the listen_event function blocks until there is an event to process */ DosWaitEventSem( surface->event_lock, SEM_INDEFINITE_WAIT ); DosQueryEventSem( surface->event_lock, &ulRequestCount ); *grevent = surface->event; DosResetEventSem( surface->event_lock, &ulRequestCount ); return; } static grPMSurface* init_surface( grPMSurface* surface, grBitmap* bitmap ) { PBITMAPINFO2 bit; SIZEL sizl = { 0, 0 }; LONG palette[256]; LOG(( "Os2PM: init_surface( %08lx, %08lx )\n", (long)surface, (long)bitmap )); LOG(( " -- input bitmap =\n" )); LOG(( " -- mode = %d\n", bitmap->mode )); LOG(( " -- grays = %d\n", bitmap->grays )); LOG(( " -- width = %d\n", bitmap->width )); LOG(( " -- height = %d\n", bitmap->rows )); /* create the bitmap - under OS/2, we support all modes as PM */ /* handles all conversions automatically.. */ if ( grNewBitmap( bitmap->mode, bitmap->grays, bitmap->width, bitmap->rows, bitmap ) ) return 0; LOG(( " -- output bitmap =\n" )); LOG(( " -- mode = %d\n", bitmap->mode )); LOG(( " -- grays = %d\n", bitmap->grays )); LOG(( " -- width = %d\n", bitmap->width )); LOG(( " -- height = %d\n", bitmap->rows )); bitmap->pitch = -bitmap->pitch; surface->root.bitmap = *bitmap; /* create the image and event lock */ DosCreateEventSem( NULL, &surface->event_lock, 0, TRUE ); DosCreateMutexSem( NULL, &surface->image_lock, 0, FALSE ); /* create the image's presentation space */ surface->image_dc = DevOpenDC( gr_anchor, OD_MEMORY, (PSZ)"*", 0L, 0L, 0L ); surface->image_ps = GpiCreatePS( gr_anchor, surface->image_dc, &sizl, PU_PELS | GPIT_MICRO |
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -