Release 940405 Tue Apr 5 14:36:59 1994 Bob Amstadt (bob@pooh) * [include/mdi.h] [windows/mdi.c] Use WM_PARENTNOTIFY messages to activate children. Generate WM_CHILDACTIVATE messages. Beginnings handler for maxmized child window. Clean up when children are destroyed. * [windows/message.c] [windows/nonclient.c] [windows/winpos.c] Removed code add 94/03/26. Apr 4, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [control/menu.c] Make mouse menu navigation working again. :-)) (be carefull, clicking outside menus (ie.: clientrect) not resolved yet) * [windows/nonclient.c] [controls/scroll.c] Bugs fix in NCTrackScrollBars(). * [misc/dos_fs.c] Bug fix in 'ToDos()' in conversion for '/', (example: '/window/' was translated to 'WINDOWs'). * [miscemu/int21.c] Function ChangeDir() extract possible drive before DOS_ChangeDir(). * [loader/library.c] [loader/wine.c] Playing around moving function GetProcAddress() and put some code in. Mon Apr 4 21:39:07 1994 Alexandre Julliard (julliard@lamisun.epfl.ch) * [misc/main.c] Better explanation of command-line options. * [objects/dib.c] Implemented SetDIBitsToDevice(). * [windows/dc.c] Bug fix in SetDCState(). * [windows/event.c] Removed WS_DISABLED handling (now done in message.c). * [windows/message.c] Added sending a WM_PARENTNOTIFY message in MSG_TranslateMouseMsg(). Use WindowFromPoint() to find the window for mouse events, taking into account disabled windows. * [windows/painting.c] Bug fix in BeginPaint() to allow calling it at other times than on WM_PAINT (Solitaire needs it...) * [windows/win.c] Implemented FindWindow(). Rewritten EnableWindow() to behave more like Windows. * [windows/winpos.c] Rewritten WindowFromPoint() to also search child windows. Mon Apr 4 17:36:32 1994 Erik Bos (erik@trashcan.hacktic.nl) * [include/int21.h] -> [msdos.h] renamed. * [miscemu/int10.h] [miscemu/int25.h] [miscemu/int26.h] new, added for int 10, 25 and 26. * [miscemu/ioports.c] new, added to allow win apps to use ioports. * [loader/signal.c] Added support for in, inb, out, outb instructions. Sun Mar 27 13:40:25 1994 Bob Amstadt (bob@pooh) * controls/menu.c (InsertMenu): Changed to use FindMenuItem(). Sat Mar 26 21:23:55 1994 Bob Amstadt (bob@pooh) * [windows/mdi.c] Window list properly updated. * [windows/message.c] Call WINPOS_ChildActivate() when mouse pressed. * [windows/nonclient.c] Use WINPOS_IsAnActiveWindow() instead of GetActiveWindow() in NC_HandleNCPaint(). * [windows/winpos.c] Created functions WINPOS_IsAnActiveWindow() and WINPOS_ActivateChild() Thu Mar 24 14:49:17 1994 Bob Amstadt (bob@pooh) * controls/menu.c (DeleteMenu): Changed to use FindMenuItem (DeleteMenu): Many bug fixes. * [controls/menu.c] Created function FindMenuItem(). Thu Mar 24 14:17:24 1994 Bob Amstadt (bob@pooh) * [windows/win.c] Removed incorrect MDI handling code from CreateWindowEx(). * [controls/menu.c] MF_STRING items needed to allocate a private copy of string. * [controls/menu.c] Fixed buggy calls to GlobalFree(). * [memory/global.c] Eliminated some redundant code with function call. Wed Mar 23 1994 Pentti Moilanen (pentti.moilanen@ntc.nokia.com) * [windows/timer.c] timer list pointers looped in InsertTimer Tue Mar 29 13:32:08 MET DST 1994 julliard@di.epfl.ch (Alexandre Julliard) * [misc/cursor.c] A few changes for desktop window support. * [misc/main.c] Added -depth option. * [misc/rect.c] Yet another bug fix in SubtractRect(). * [objects/bitmap.c] Changes to use only one depth (specified with -depth) for color bitmaps. * [objects/brush.c] Added support for dithered solid brushes. * [objects/color.c] Use the same 20 system colors as in Windows. System palette initialisation now done in COLOR_InitPalette(). Added support for a color mapping table to map logical color indexes to X colormap entries. Implemented GetNearestColor() and RealizeDefaultPalette(). * [objects/dib.c] Added support for color mapping table. * [objects/dither.c] (New file) Implemented solid color dithering. * [objects/palette.c] Implemented GetSystemPaletteEntries() and SelectPalette(). * [windows/class.c] Make a copy of the menu name in RegisterClass(). * [windows/dc.c] Fixed device caps when using a desktop window. Added support for the color mapping table in DCs. * [windows/event.c] Added ConfigureNotify handler on desktop window. * [windows/message.c] Removed call to XTranslateCoordinates() on every mouse motion New function MSG_Synchronize() to synchronize with the X server. * [windows/syscolor.c] Rewritten SYSCOLOR_Init() to read the system colors from WIN.INI. * [windows/winpos.c] Added synchronization on window mapping. Solves the double redraw problem when starting Solitaire. Mar 27, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [control/menu.c] * [windows/defwnd.c] Make keyboard navigation working with menubar, but temporarely inserted a bug in menubar mouse handling ... :-(( (it will be fix next week !) * [windows/defwnd.c] Connect VK_MENU to menubar navigation. * [loader/library.c] GetModuleHandle() return 'fictive 0xF000+ handles' for built-in DLLs. Sun Mar 20 22:32:13 1994 Erik Bos (erik@trashcan.hacktic.nl) * [misc/main.c] Added Copy(). Added a check for `-h' to show usage. * [misc/dos_fs.c] Fixed bug in FindFile(), to load directories as dlls. * [misc/dos_fs.c] Fixed ToUnix() and ToDos() again, as my previous patch didn't make it. * [misc/dos_fs.c] [miscemu/int21.c] Bug fixes, should be able to handle all winfile and progman int21 requests now except for a few small things. Tue Mar 29 06:25:54 1994 crw@harris.mlb.semi.harris.com (Carl Williams) * [memory/heap.c] Implemented GetFreeSystemResources(). Mon Mar 21 17:32:25 1994 Bob Amstadt (bob@pooh) * controls/menu.c (GetSubMenu): Function did not return correct value * [windows/mdi.c] Beginnings of menu handling. Thu Mar 10 11:32:06 1994 Stefan (SAM) Muenzel (muenzel@tat.physik.uni-tuebingen.de) * [objects/font.c] if font.width equals zero use asterix instead. Mon Mar 21 17:23:37 MET 1994 julliard@di.epfl.ch (Alexandre Julliard) * [objects/bitmap.c] Rewritten bitmap code to use exclusively X pixmaps; *much* faster. * [objects/brush.c] Some changes with pattern brushes because of the new bitmap code. * [objects/color.c] Added function COLOR_ToPhysical for better color mapping. * [objects/dib.c] Heavily optimized SetDIBits(). * [windows/dc.c] Opimized SetDCState() and DC_SetupGC*() functions. Added stub for CreateIC(). Mar 20, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [misc/message.c] Call SetFocus() after closing box to give back focus to previous owner. * [misc/files.c] Small bug fix in GetTempFilename() : replace a '\' to '\\'. * [control/scroll.c] Calls to BitBlt() replace by StretchBlt(). * [control/menu.c] Call SetFocus() to previous owner after closing Popups. Fill stub DeleteMenu(). * [control/listbox.c] * [control/combo.c] Use SetFocus() in WM_LBUTTONDOWN. Close ComboBox List upon WM_KILLFOCUS. Early development of WM_MEASUREITEM mecanism. * [windows/defwnd.c] Early development of WM_MEASUREITEM mecanism. Tue Mar 22 10:44:57 1994 Miguel de Icaza (miguel@xochitl) * [misc/atom.c] Fixed sintaxis problem when building the library. Tue Mar 15 13:11:56 1994 Bob Amstadt (bob@pooh) * [include/windows.h] Added message types and structures for MDI * [include/mdi.h] Created internal structures for handling MDI * [windows/mdi.c] Began creating MDI support Thu Mar 10 16:51:46 1994 Bob Amstadt (bob@pooh) * [loader/wine.c] [include/wine.h] Added new field to "struct w_files" to hold the "name table" resource for Windows 3.0 programs * [loader/resource.c] Added code to handle programs with a "name table" resource. LoadResourceByName() modified to check for the existence of this resource. Mon Mar 14 22:31:42 MET 1994 julliard@di.epfl.ch (Alexandre Julliard) * [objects/color.c] Added installing the private colormap on the desktop window. * [windows/event.c] Cleaned up focus event handling (see focus.c). Use GetFocus() to direct key events to the correct window. * [windows/focus.c] Rewritten SetFocus() to: - only set X focus on top-level windows - send WM_SETFOCUS and WM_KILLFOCUS messages (was done in event.c) - prevent setting focus to disabled windows - install private colormap so -privatemap option works again * [windows/message.c] [windows/timer.c] Changed timer management to no longer use PostMessage(), but to generate timer messages on the fly. Also fixed a related bug in GetMessage() which could cause busy-waiting. * [windows/win.c] Only select focus events on top-level windows. * [windows/winpos.c] Added some sanity checks for desktop window. Fri Mar 4 20:42:01 1994 Erik Bos (erik@trashcan.hacktic.nl) * [misc/dos_fs.c] bug fixes in ToUnix(), WinIniFileName(), GetUnixFileName(). Support for tilde symbol added for rootdirectories in [drives] section of wine's configfile. * [misc/file.c] hread(), hwrite() added. * [misc/main.c] hmemcpy() added. * [if1632/stress.spec] [include/stress.h] [misc/stress.c] Added STRESS.DLL, an useless dll used to stress a windows system. * [*/*] Added missing #includes, fixed prototypes for prototype checking. * [include/prototypes.h] Added prototypes for loader/*c, if1632/*c. Tue Mar 8 09:54:34 1994 Bob Amstadt (bob@pooh) * [Configure] Added reminder to set WINEPATH, if it is not set. * [Imakefile] Removed #elif's * [controls/button.c] Added BN_CLICKED notification for owner-draw buttons. * [if1632/kernel.spec] [memory/heap.c] Changed Local* functions to WIN16_Local* to prevent unconcious use of these functions. * [if1632/relay.c] Push old Stack16Frame on stack before setting. * [include/atom.h] [misc/atom.c] [include/heap.h] [memory/local.c] Added multiple local heap handling in Atom* functions. * [include/regfunc.h] [miscemu/int21.c] Rewrote DOS3Call() use context frame that is already on the stack. * [misc/profile.c] Fixed to allow leading ";" to mark comments. * [misc/spy.c] Fixed bugs and added support for "include" and "exclude" filters. * [misc/user.c] Rearranged calls in InitApp(). * [misc/font.c] Fixed font handling to create system fonts, if they are used. * [windows/dc.c] If text drawn on window with no font specified, then default the font to the system font. Mon Mar 7 20:32:09 MET 1994 julliard@di.epfl.ch (Alexandre Julliard) * [controls/desktop.c] Added handling of WM_NCCREATE and WM_ERASEBKGND functions. Implemented SetDeskPattern(). * [misc/main.c] Added -desktop option to get a large desktop window with everything inside it. Added -name option. * [misc/rect.c] Bug fix in SubtractRect(). * [objects/*.c] Replaced the DefaultRootWindow() macro by the rootWindow variable. * [windows/event.c] [windows/message.c] [windows/nonclient.c] [windows/win.c] A few changes to accomodate the new desktop window. Tue Mar 8 11:13:03 1994 Miguel de Icaza (miguel@xochitl.nuclecu.unam.mx) * [toolkit/arch.c] --New file-- Routines for converting little endian data structures to big-endian data structures, currently only BITMAP structures are converted. * [misc/atom.c] When used as part of the WineLib, the code is much simpler. Doesn't depend on alignement. * [loader/wine.c] Ifdefed Emulator dependent code if compiling WineLib. * [loader/resource.c] Moved misc/resource.c to loader/resource.c. * [loader/dump.c,ldt.c,ldtlib.c,library,c,selector.c,signal.c] Ifdefed whole code if compiling WINELIB. * [include/winsock.h] Added compilation define to allow compilation on SunOS. * [include/wine.h] Removed load_typeinfo and load_nameinfo prototypes, they belong to neexe.h * [include/neexe.h] Added load_typeinfo and load_nameinfo prototypes. * [include/arch.h] Fixed some bugs in the conversion routines. Added macros for Bitmap loading. Tue Mar 8 12:52:05 1994 crw@maniac.mlb.semi.harris.com (Carl Williams) * [if1632/kernel.spec] [memory/global.c] Implemented GetFreeSpace() * [if1632/user.spec] [loader/resource.c] Implemented CreateIcon()
diff --git a/objects/Imakefile b/objects/Imakefile index 458761d..bce8061 100644 --- a/objects/Imakefile +++ b/objects/Imakefile
@@ -16,7 +16,8 @@ clipping.c \ bitblt.c \ linedda.c \ - color.c + color.c \ + dither.c OBJS = \ bitmap.o \ @@ -32,7 +33,8 @@ clipping.o \ bitblt.o \ linedda.o \ - color.o + color.o \ + dither.o WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) DependTarget()
diff --git a/objects/bitblt.c b/objects/bitblt.c index bbfa3bd..992f7ca 100644 --- a/objects/bitblt.c +++ b/objects/bitblt.c
@@ -314,7 +314,7 @@ sxi = XGetImage(display, dcSrc->u.x.drawable, xs1, ys1, widthSrc, heightSrc, AllPlanes, ZPixmap); dxi = XCreateImage(display, DefaultVisualOfScreen(screen), - DefaultDepthOfScreen(screen), ZPixmap, + screenDepth, ZPixmap, 0, NULL, widthDest, heightDest, 32, 0); dxi->data = malloc(dxi->bytes_per_line * heightDest);
diff --git a/objects/bitmap.c b/objects/bitmap.c index ffec3e9..6c21e0c 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c
@@ -6,22 +6,18 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> #include "gdi.h" +#include "bitmap.h" -/* A GDI bitmap object contains a handle to a packed BITMAP, - * which is stored on the global heap. - * A packed BITMAP is a BITMAP structure followed by the bitmap bits. - */ /* Handle of the bitmap selected by default in a memory DC */ -HBITMAP BITMAP_hbitmapMemDC; +HBITMAP BITMAP_hbitmapMemDC = 0; - /* List of supported depths */ -static int depthCount; -static int * depthList; - - /* List of GC used for bitmap to pixmap operations (one for each depth) */ -static GC * bitmapGC; + /* GCs used for B&W and color bitmap operations */ +GC BITMAP_monoGC = 0, BITMAP_colorGC = 0; /*********************************************************************** @@ -29,27 +25,25 @@ */ BOOL BITMAP_Init() { - int i; Pixmap tmpPixmap; - depthList = XListDepths( XT_display, DefaultScreen(XT_display), - &depthCount ); - if (!depthList || !depthCount) return FALSE; - if (!(bitmapGC = (GC *) malloc( depthCount * sizeof(GC) ))) return FALSE; - /* Create the necessary GCs */ - for (i = 0; i < depthCount; i++) + if ((tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 ))) { - tmpPixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display), - 1, 1, depthList[i] ); - if (tmpPixmap) + BITMAP_monoGC = XCreateGC( display, tmpPixmap, 0, NULL ); + XSetGraphicsExposures( display, BITMAP_monoGC, False ); + XFreePixmap( display, tmpPixmap ); + } + + if (screenDepth != 1) + { + if ((tmpPixmap = XCreatePixmap(display, rootWindow, 1,1,screenDepth))) { - bitmapGC[i] = XCreateGC( XT_display, tmpPixmap, 0, NULL ); - XSetGraphicsExposures( XT_display, bitmapGC[i], False ); - XFreePixmap( XT_display, tmpPixmap ); + BITMAP_colorGC = XCreateGC( display, tmpPixmap, 0, NULL ); + XSetGraphicsExposures( display, BITMAP_colorGC, False ); + XFreePixmap( display, tmpPixmap ); } - else bitmapGC[i] = 0; } BITMAP_hbitmapMemDC = CreateBitmap( 1, 1, 1, 1, NULL ); @@ -58,26 +52,13 @@ /*********************************************************************** - * BITMAP_FindGCForDepth - * - * Return a GC appropriate for operations with the given depth. - */ -GC BITMAP_FindGCForDepth( int depth ) -{ - int i; - for (i = 0; i < depthCount; i++) - if (depthList[i] == depth) return bitmapGC[i]; - return 0; -} - - -/*********************************************************************** * BITMAP_BmpToImage * * Create an XImage pointing to the bitmap data. */ -XImage * BITMAP_BmpToImage( BITMAP * bmp, void * bmpData ) +static XImage *BITMAP_BmpToImage( BITMAP * bmp, void * bmpData ) { + extern void _XInitImageFuncPtrs( XImage* ); XImage * image; image = XCreateImage( XT_display, DefaultVisualOfScreen(XT_screen), @@ -93,57 +74,6 @@ /*********************************************************************** - * BITMAP_CopyToPixmap - * - * Copy the content of the bitmap to the pixmap. Both must have the same depth. - */ -BOOL BITMAP_CopyToPixmap( BITMAP * bmp, Pixmap pixmap, - int x, int y, int width, int height ) -{ - GC gc; - XImage * image; - - gc = BITMAP_FindGCForDepth( bmp->bmBitsPixel ); - if (!gc) return FALSE; - - image = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) ); - if (!image) return FALSE; - -#ifdef DEBUG_GDI - printf( "BITMAP_CopyToPixmap: %dx%d %d colors -> %d,%d %dx%d\n", - bmp->bmWidth, bmp->bmHeight, 1 << bmp->bmBitsPixel, x, y, width, height ); -#endif - XPutImage(XT_display, pixmap, gc, image, 0, 0, x, y, width, height); - image->data = NULL; - XDestroyImage( image ); - return TRUE; -} - - -/*********************************************************************** - * BITMAP_CopyFromPixmap - * - * Copy the content of the pixmap to the bitmap. Both must have - * the same dimensions and depth. - */ -BOOL BITMAP_CopyFromPixmap( BITMAP * bmp, Pixmap pixmap ) -{ - XImage *image = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) ); - if (!image) return FALSE; - -#ifdef DEBUG_GDI - printf( "BITMAP_CopyFromPixmap: %dx%d %d colors\n", - bmp->bmWidth, bmp->bmHeight, 1 << bmp->bmBitsPixel ); -#endif - XGetSubImage( XT_display, pixmap, 0, 0, bmp->bmWidth, bmp->bmHeight, - AllPlanes, ZPixmap, image, 0, 0 ); - image->data = NULL; - XDestroyImage( image ); - return TRUE; -} - - -/*********************************************************************** * CreateBitmap (GDI.48) */ HBITMAP CreateBitmap( short width, short height, @@ -154,9 +84,6 @@ printf( "CreateBitmap: %dx%d, %d colors\n", width, height, 1 << (planes*bpp) ); #endif - if (!width || !height) return 0; - if ((planes != 1) && (bpp != 1)) return 0; - bitmap.bmWidthBytes = (width * bpp + 15) / 16 * 2; return CreateBitmapIndirect( &bitmap ); } @@ -166,15 +93,12 @@ */ HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height ) { - HBITMAP hbitmap; DC * dc; #ifdef DEBUG_GDI printf( "CreateCompatibleBitmap: %d %dx%d\n", hdc, width, height ); #endif - dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); - if (!dc) return 0; - hbitmap = CreateBitmap( width, height, dc->w.planes, dc->w.bitsPerPixel, NULL); - return hbitmap; + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + return CreateBitmap( width, height, 1, dc->w.bitsPerPixel, NULL ); } @@ -184,72 +108,34 @@ HBITMAP CreateBitmapIndirect( BITMAP * bmp ) { BITMAPOBJ * bmpObjPtr; - char * bmpPtr; HBITMAP hbitmap; - int size = bmp->bmPlanes * bmp->bmHeight * bmp->bmWidthBytes; - - /* Create the BITMAPOBJ */ + /* Check parameters */ + if (!bmp->bmHeight || !bmp->bmWidth) return 0; + if (bmp->bmPlanes != 1) return 0; + if ((bmp->bmBitsPixel != 1) && (bmp->bmBitsPixel != screenDepth)) return 0; + + /* Create the BITMAPOBJ */ hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC ); if (!hbitmap) return 0; bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_ADDR( hbitmap ); - - /* Create the bitmap in global heap */ - bmpObjPtr->hBitmap = GlobalAlloc( GMEM_MOVEABLE, sizeof(BITMAP) + size ); - if (!bmpObjPtr->hBitmap) + bmpObjPtr->size.cx = 0; + bmpObjPtr->size.cy = 0; + bmpObjPtr->bitmap = *bmp; + bmpObjPtr->bitmap.bmBits = NULL; + bmpObjPtr->bitmap.bmWidthBytes = (bmp->bmWidth*bmp->bmBitsPixel+15)/16 * 2; + + /* Create the pixmap */ + bmpObjPtr->pixmap = XCreatePixmap( display, rootWindow, bmp->bmWidth, + bmp->bmHeight, bmp->bmBitsPixel ); + if (!bmpObjPtr->pixmap) { - GDI_FreeObject( hbitmap ); - return 0; + GDI_HEAP_FREE( hbitmap ); + hbitmap = 0; } - bmpPtr = (char *) GlobalLock( bmpObjPtr->hBitmap ); - memcpy( bmpPtr, bmp, sizeof(BITMAP) ); - ((BITMAP *)bmpPtr)->bmBits = NULL; - if (bmp->bmBits) memcpy( bmpPtr + sizeof(BITMAP), bmp->bmBits, size ); - GlobalUnlock( bmpObjPtr->hBitmap ); - - bmpObjPtr->bSelected = FALSE; - bmpObjPtr->hdc = 0; - bmpObjPtr->size.cx = 0; - bmpObjPtr->size.cy = 0; - return hbitmap; -} - - -/*********************************************************************** - * BITMAP_GetSetBitmapBits - */ -LONG BITMAP_GetSetBitmapBits( HBITMAP hbitmap, LONG count, - LPSTR buffer, int set ) -{ - BITMAPOBJ * bmpObjPtr; - BITMAP * bmp; - DC * dc = NULL; - int maxSize; - - if (!count) return 0; - bmpObjPtr = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); - if (!bmpObjPtr) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bmpObjPtr->hBitmap ))) return 0; - - if (bmpObjPtr->bSelected) - dc = (DC *) GDI_GetObjPtr( bmpObjPtr->hdc, DC_MAGIC ); - - maxSize = bmp->bmPlanes * bmp->bmHeight * bmp->bmWidthBytes; - if (count > maxSize) count = maxSize; - - if (set) - { - memcpy( bmp+1, buffer, count ); - if (dc) BITMAP_CopyToPixmap( bmp, dc->u.x.drawable, - 0, 0, bmp->bmWidth, bmp->bmHeight ); - } - else - { - if (dc) BITMAP_CopyFromPixmap( bmp, dc->u.x.drawable ); - memcpy( buffer, bmp+1, count ); - } - GlobalUnlock( bmpObjPtr->hBitmap ); + else if (bmp->bmBits) /* Set bitmap bits */ + SetBitmapBits( hbitmap, bmp->bmHeight*bmp->bmWidthBytes, bmp->bmBits ); return hbitmap; } @@ -259,7 +145,29 @@ */ LONG GetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer ) { - return BITMAP_GetSetBitmapBits( hbitmap, count, buffer, 0 ); + BITMAPOBJ * bmp; + LONG height; + XImage * image; + + bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + if (!bmp) return 0; + +#ifdef DEBUG_BITMAP + printf( "GetBitmapBits: %dx%d %d colors %p\n", + bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, + 1 << bmp->bitmap.bmBitsPixel, buffer ); +#endif + /* Only get entire lines */ + height = count / bmp->bitmap.bmWidthBytes; + if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight; + if (!height) return 0; + + if (!(image = BITMAP_BmpToImage( &bmp->bitmap, buffer ))) return 0; + XGetSubImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth, height, + AllPlanes, ZPixmap, image, 0, 0 ); + image->data = NULL; + XDestroyImage( image ); + return height * bmp->bitmap.bmWidthBytes; } @@ -268,7 +176,29 @@ */ LONG SetBitmapBits( HBITMAP hbitmap, LONG count, LPSTR buffer ) { - return BITMAP_GetSetBitmapBits( hbitmap, count, buffer, 1 ); + BITMAPOBJ * bmp; + LONG height; + XImage * image; + + bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + if (!bmp) return 0; + +#ifdef DEBUG_BITMAP + printf( "SetBitmapBits: %dx%d %d colors %p\n", + bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, + 1 << bmp->bitmap.bmBitsPixel, buffer ); +#endif + /* Only set entire lines */ + height = count / bmp->bitmap.bmWidthBytes; + if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight; + if (!height) return 0; + + if (!(image = BITMAP_BmpToImage( &bmp->bitmap, buffer ))) return 0; + XPutImage( display, bmp->pixmap, BITMAP_GC(bmp), image, 0, 0, + 0, 0, bmp->bitmap.bmWidth, height ); + image->data = NULL; + XDestroyImage( image ); + return height * bmp->bitmap.bmWidthBytes; } @@ -277,8 +207,7 @@ */ BOOL BMP_DeleteObject( HBITMAP hbitmap, BITMAPOBJ * bitmap ) { - /* Free bitmap on global heap */ - GlobalFree( bitmap->hBitmap ); + XFreePixmap( display, bitmap->pixmap ); return GDI_FreeObject( hbitmap ); } @@ -286,95 +215,39 @@ /*********************************************************************** * BMP_GetObject */ -int BMP_GetObject( BITMAPOBJ * bitmap, int count, LPSTR buffer ) +int BMP_GetObject( BITMAPOBJ * bmp, int count, LPSTR buffer ) { - char * bmpPtr = (char *) GlobalLock( bitmap->hBitmap ); if (count > sizeof(BITMAP)) count = sizeof(BITMAP); - memcpy( buffer, bmpPtr, count ); - GlobalUnlock( bitmap->hBitmap ); + memcpy( buffer, &bmp->bitmap, count ); return count; } - -/*********************************************************************** - * BITMAP_UnselectBitmap - * - * Unselect the bitmap from the DC. Used by SelectObject and DeleteDC. - */ -BOOL BITMAP_UnselectBitmap( DC * dc ) -{ - BITMAPOBJ * bmp; - BITMAP * bmpPtr; - - if (!dc->w.hBitmap) return TRUE; - bmp = (BITMAPOBJ *) GDI_GetObjPtr( dc->w.hBitmap, BITMAP_MAGIC ); - if (!bmp) return FALSE; - - if (!(bmpPtr = (BITMAP *) GlobalLock( bmp->hBitmap ))) return FALSE; - - BITMAP_CopyFromPixmap( bmpPtr, dc->u.x.drawable ); - XFreePixmap( XT_display, dc->u.x.drawable ); - bmp->bSelected = FALSE; - bmp->hdc = 0; - GlobalUnlock( bmp->hBitmap ); - return TRUE; -} - /*********************************************************************** * BITMAP_SelectObject */ HBITMAP BITMAP_SelectObject( HDC hdc, DC * dc, HBITMAP hbitmap, - BITMAPOBJ * bitmap ) + BITMAPOBJ * bmp ) { - BITMAP * bmp; HBITMAP prevHandle = dc->w.hBitmap; if (!(dc->w.flags & DC_MEMORY)) return 0; - if (bitmap->bSelected && hbitmap != BITMAP_hbitmapMemDC) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bitmap->hBitmap ))) return 0; - - /* Make sure the bitmap has the right format */ - - if ((bmp->bmPlanes != 1) || !BITMAP_FindGCForDepth( bmp->bmBitsPixel )) - { - GlobalUnlock( bitmap->hBitmap ); - return 0; - } - - /* Unselect the previous bitmap */ - - if (!BITMAP_UnselectBitmap( dc )) - { - GlobalUnlock( bitmap->hBitmap ); - return 0; - } - - /* Create the pixmap */ - - dc->u.x.drawable = XCreatePixmap( XT_display, - DefaultRootWindow( XT_display ), - bmp->bmWidth, bmp->bmHeight, - bmp->bmBitsPixel ); - dc->w.DCSizeX = bmp->bmWidth; - dc->w.DCSizeY = bmp->bmHeight; - BITMAP_CopyToPixmap( bmp, dc->u.x.drawable, - 0, 0, bmp->bmWidth, bmp->bmHeight ); + dc->u.x.drawable = bmp->pixmap; + dc->w.DCSizeX = bmp->bitmap.bmWidth; + dc->w.DCSizeY = bmp->bitmap.bmHeight; + dc->w.hBitmap = hbitmap; /* Change GC depth if needed */ - if (dc->w.bitsPerPixel != bmp->bmBitsPixel) + if (dc->w.bitsPerPixel != bmp->bitmap.bmBitsPixel) { - XFreeGC( XT_display, dc->u.x.gc ); - dc->u.x.gc = XCreateGC( XT_display, dc->u.x.drawable, 0, NULL ); - dc->w.bitsPerPixel = bmp->bmBitsPixel; - DC_SetDeviceInfo( hdc, dc ); + XFreeGC( display, dc->u.x.gc ); + dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL ); + dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel; + /* Re-select objects with changed depth */ + SelectObject( hdc, dc->w.hPen ); + SelectObject( hdc, dc->w.hBrush ); } - - GlobalUnlock( bitmap->hBitmap ); - dc->w.hBitmap = hbitmap; - bitmap->bSelected = TRUE; - bitmap->hdc = hdc; return prevHandle; }
diff --git a/objects/brush.c b/objects/brush.c index 582349e..9464184 100644 --- a/objects/brush.c +++ b/objects/brush.c
@@ -7,6 +7,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "gdi.h" +#include "bitmap.h" +#include "prototypes.h" #define NB_HATCH_STYLES 6 @@ -21,7 +23,8 @@ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 } /* HS_DIAGCROSS */ }; -extern XImage * BITMAP_BmpToImage( BITMAP *, void * ); +extern WORD COLOR_ToPhysical( DC *dc, COLORREF color ); + /*********************************************************************** * CreateBrushIndirect (GDI.50) @@ -57,23 +60,21 @@ HBRUSH CreatePatternBrush( HBITMAP hbitmap ) { LOGBRUSH logbrush = { BS_PATTERN, 0, 0 }; - BITMAPOBJ * bmpObj; - BITMAP * bmp; - + BITMAPOBJ *bmp, *newbmp; + #ifdef DEBUG_GDI printf( "CreatePatternBrush: %d\n", hbitmap ); #endif /* Make a copy of the bitmap */ - if (!(bmpObj = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) + if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0; - logbrush.lbHatch = CreateBitmap( bmp->bmWidth, bmp->bmHeight, - bmp->bmPlanes, bmp->bmBitsPixel, - ((char *)bmp) + sizeof(BITMAP) ); - GlobalUnlock( bmpObj->hBitmap ); - if (!logbrush.lbHatch) return 0; + logbrush.lbHatch = CreateBitmapIndirect( &bmp->bitmap ); + newbmp = (BITMAPOBJ *) GDI_GetObjPtr( logbrush.lbHatch, BITMAP_MAGIC ); + if (!newbmp) return 0; + XCopyArea( display, bmp->pixmap, newbmp->pixmap, BITMAP_GC(bmp), + 0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, 0, 0 ); return CreateBrushIndirect( &logbrush ); } @@ -172,32 +173,46 @@ /*********************************************************************** + * BRUSH_MakeSolidBrush + */ +static void BRUSH_SelectSolidBrush( DC *dc, COLORREF color ) +{ + if ((dc->w.bitsPerPixel > 1) && !COLOR_IsSolid( color )) + { + /* Dithered brush */ + dc->u.x.brush.pixmap = DITHER_DitherColor( dc, color ); + dc->u.x.brush.fillStyle = FillTiled; + dc->u.x.brush.pixel = 0; + } + else + { + /* Solid brush */ + dc->u.x.brush.pixel = COLOR_ToPhysical( dc, color ); + dc->u.x.brush.fillStyle = FillSolid; + } +} + + +/*********************************************************************** * BRUSH_SelectPatternBrush */ -BOOL BRUSH_SelectPatternBrush( DC * dc, HBITMAP hbitmap ) +static BOOL BRUSH_SelectPatternBrush( DC * dc, HBITMAP hbitmap ) { - BITMAPOBJ * bmpObjPtr; - BITMAP * bmp; + BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); + if (!bmp) return FALSE; + dc->u.x.brush.pixmap = XCreatePixmap( display, rootWindow, + 8, 8, bmp->bitmap.bmBitsPixel ); + XCopyArea( display, bmp->pixmap, dc->u.x.brush.pixmap, + BITMAP_GC(bmp), 0, 0, 8, 8, 0, 0 ); - bmpObjPtr = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); - if (!bmpObjPtr) return FALSE; - if (!(bmp = (BITMAP *) GlobalLock( bmpObjPtr->hBitmap ))) return FALSE; - - dc->u.x.brush.pixmap = XCreatePixmap( XT_display, - DefaultRootWindow(XT_display), - 8, 8, bmp->bmBitsPixel ); - BITMAP_CopyToPixmap( bmp, dc->u.x.brush.pixmap, 0, 0, 8, 8 ); - - if (bmp->bmBitsPixel > 1) + if (bmp->bitmap.bmBitsPixel > 1) { dc->u.x.brush.fillStyle = FillTiled; - XSetTile( XT_display, dc->u.x.gc, dc->u.x.brush.pixmap ); dc->u.x.brush.pixel = 0; /* Ignored */ } else { dc->u.x.brush.fillStyle = FillOpaqueStippled; - XSetStipple( XT_display, dc->u.x.gc, dc->u.x.brush.pixmap ); dc->u.x.brush.pixel = -1; /* Special case (see DC_SetupGCForBrush) */ } return TRUE; @@ -218,28 +233,24 @@ if (dc->u.x.brush.pixmap) { - XFreePixmap( XT_display, dc->u.x.brush.pixmap ); + XFreePixmap( display, dc->u.x.brush.pixmap ); dc->u.x.brush.pixmap = 0; } dc->u.x.brush.style = brush->logbrush.lbStyle; switch(brush->logbrush.lbStyle) { - case BS_SOLID: case BS_NULL: - dc->u.x.brush.pixel = GetNearestPaletteIndex( dc->w.hPalette, - brush->logbrush.lbColor ); - dc->u.x.brush.fillStyle = FillSolid; + break; + + case BS_SOLID: + BRUSH_SelectSolidBrush( dc, brush->logbrush.lbColor ); break; case BS_HATCHED: - dc->u.x.brush.pixel = GetNearestPaletteIndex( dc->w.hPalette, - brush->logbrush.lbColor ); - dc->u.x.brush.pixmap = XCreateBitmapFromData(XT_display, - DefaultRootWindow(XT_display), - HatchBrushes[brush->logbrush.lbHatch], - 8, 8 ); - XSetStipple( XT_display, dc->u.x.gc, dc->u.x.brush.pixmap ); + dc->u.x.brush.pixel = COLOR_ToPhysical( dc, brush->logbrush.lbColor ); + dc->u.x.brush.pixmap = XCreateBitmapFromData( display, rootWindow, + HatchBrushes[brush->logbrush.lbHatch], 8, 8 ); dc->u.x.brush.fillStyle = FillStippled; break; @@ -264,5 +275,3 @@ return prevHandle; } - -
diff --git a/objects/color.c b/objects/color.c index 8eb9c2e..41f3ae6 100644 --- a/objects/color.c +++ b/objects/color.c
@@ -11,55 +11,46 @@ #include "windows.h" #include "options.h" - -extern Display * display; -extern Screen * screen; +#include "gdi.h" Colormap COLOR_WinColormap = 0; + /* System palette static colors */ - /* System colors */ +#define NB_RESERVED_COLORS 20 -static const char * SysColors[] = + /* The first and last eight colors are EGA colors */ +static PALETTEENTRY COLOR_sysPaletteEntries[NB_RESERVED_COLORS] = { - /* Low pixel values (0..7) */ + /* red green blue flags */ + { 0x00, 0x00, 0x00, 0 }, + { 0x80, 0x00, 0x00, 0 }, + { 0x00, 0x80, 0x00, 0 }, + { 0x80, 0x80, 0x00, 0 }, + { 0x00, 0x00, 0x80, 0 }, + { 0x80, 0x00, 0x80, 0 }, + { 0x00, 0x80, 0x80, 0 }, + { 0xc0, 0xc0, 0xc0, 0 }, + { 0xc0, 0xdc, 0xc0, 0 }, + { 0xa6, 0xca, 0xf0, 0 }, - "black", "red4", "green4", "yellow4", - "blue4", "magenta4", "cyan4", "gray50", - - /* High pixel values (max-7..max) */ - - "gray75", "red", "green", "yellow", - "blue", "magenta", "cyan", "white" + { 0xff, 0xfb, 0xf0, 0 }, + { 0xa0, 0xa0, 0xa4, 0 }, + { 0x80, 0x80, 0x80, 0 }, + { 0xff, 0x00, 0x00, 0 }, + { 0x00, 0xff, 0x00, 0 }, + { 0xff, 0xff, 0x00, 0 }, + { 0x00, 0x00, 0xff, 0 }, + { 0xff, 0x00, 0xff, 0 }, + { 0x00, 0xff, 0xff, 0 }, + { 0xff, 0xff, 0xff, 0 } }; -#define NB_SYS_COLORS (sizeof(SysColors) / sizeof(SysColors[0])) +static HANDLE hSysColorTranslation = 0; - -/*********************************************************************** - * COLOR_FillDefaultMap - * - * Try to allocate colors from default screen map (used when we - * don't want to or can't use a private map). - */ -static int COLOR_FillDefaultMap() -{ - XColor color; - int i, total = 0; - - for (i = 0; i < NB_SYS_COLORS; i++) - { - if (XParseColor( display, DefaultColormapOfScreen( screen ), - SysColors[i], &color )) - { - if (XAllocColor( display, DefaultColormapOfScreen( screen ), - &color )) - total++; - } - } - return total; -} + /* Map an EGA index (0..15) to a pixel value. Used for dithering. */ +int COLOR_mapEGAPixel[16]; /*********************************************************************** @@ -70,50 +61,108 @@ static BOOL COLOR_BuildMap( Colormap map, int depth, int size ) { XColor color; - int i; + int r, g, b, red_incr, green_incr, blue_incr; + int index = 0; /* Fill the whole map with a range of colors */ - if ((1 << depth) > NB_SYS_COLORS) - { - int red_incr, green_incr, blue_incr; - int r, g, b; - - blue_incr = 0x10000 >> (depth / 3); - red_incr = 0x10000 >> ((depth + 1) / 3); - green_incr = 0x10000 >> ((depth + 2) / 3); + blue_incr = 0x10000 >> (depth / 3); + red_incr = 0x10000 >> ((depth + 1) / 3); + green_incr = 0x10000 >> ((depth + 2) / 3); - for (i = 0, r = red_incr - 1; r < 0x10000; r += red_incr) - for (g = green_incr - 1; g < 0x10000; g += green_incr) - for (b = blue_incr - 1; b < 0x10000; b += blue_incr) - { - if (i >= size) break; - color.pixel = i++; - color.red = r; - color.green = g; - color.blue = b; - XStoreColor( display, map, &color ); - } - } - - /* Store the system palette colors */ + for (r = red_incr - 1; r < 0x10000; r += red_incr) + for (g = green_incr - 1; g < 0x10000; g += green_incr) + for (b = blue_incr - 1; b < 0x10000; b += blue_incr) + { + if (index >= size) break; + color.pixel = index++; + color.red = r; + color.green = g; + color.blue = b; + XStoreColor( display, map, &color ); + } - for (i = 0; i < NB_SYS_COLORS; i++) - { - if (!XParseColor( display, map, SysColors[i], &color )) - color.red = color.green = color.blue = color.flags = 0; - if (i < NB_SYS_COLORS/2) color.pixel = i; - else color.pixel = (1 << depth) - NB_SYS_COLORS + i; - if (color.pixel < size) XStoreColor( display, map, &color ); - } return TRUE; } /*********************************************************************** - * COLOR_Init + * COLOR_InitPalette + * + * Create the system palette. */ -BOOL COLOR_Init() +static HPALETTE COLOR_InitPalette() +{ + int i, size; + XColor color; + HPALETTE hpalette; + LOGPALETTE * palPtr; + WORD *colorTranslation; + + if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE, + sizeof(WORD)*NB_RESERVED_COLORS ))) return FALSE; + colorTranslation = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation ); + size = DefaultVisual( display, DefaultScreen(display) )->map_entries; + for (i = 0; i < NB_RESERVED_COLORS; i++) + { + color.red = COLOR_sysPaletteEntries[i].peRed * 65535 / 255; + color.green = COLOR_sysPaletteEntries[i].peGreen * 65535 / 255; + color.blue = COLOR_sysPaletteEntries[i].peBlue * 65535 / 255; + color.flags = DoRed | DoGreen | DoBlue; + + if (COLOR_WinColormap != DefaultColormapOfScreen(screen)) + { + if (i < NB_RESERVED_COLORS/2) + { + /* Bottom half of the colormap */ + color.pixel = i; + if (color.pixel >= size/2) continue; + } + else + { + /* Top half of the colormap */ + color.pixel = size - NB_RESERVED_COLORS + i; + if (color.pixel < size/2) continue; + } + XStoreColor( display, COLOR_WinColormap, &color ); + } + else if (!XAllocColor( display, COLOR_WinColormap, &color )) + { + printf( "Warning: Not enough free colors. Try using the -privatemap option.\n" ); + color.pixel = color.red = color.green = color.blue = 0; + } + colorTranslation[i] = color.pixel; +#if 0 + /* Put the allocated colors back in the list */ + COLOR_sysPaletteEntries[i].peRed = color.red >> 8; + COLOR_sysPaletteEntries[i].peGreen = color.green >> 8; + COLOR_sysPaletteEntries[i].peBlue = color.blue >> 8; +#endif + /* Set EGA mapping if color in the first or last eight */ + if (i < 8) + COLOR_mapEGAPixel[i] = color.pixel; + else if (i >= NB_RESERVED_COLORS-8) + COLOR_mapEGAPixel[i - (NB_RESERVED_COLORS-16)] = color.pixel; + } + + palPtr = malloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) ); + if (!palPtr) return FALSE; + palPtr->palVersion = 0x300; + palPtr->palNumEntries = NB_RESERVED_COLORS; + memcpy( palPtr->palPalEntry, COLOR_sysPaletteEntries, + sizeof(COLOR_sysPaletteEntries) ); + hpalette = CreatePalette( palPtr ); + free( palPtr ); + return hpalette; +} + + +/*********************************************************************** + * COLOR_Init + * + * Initialize color map and system palette. + */ +HPALETTE COLOR_Init() { Visual * visual = DefaultVisual( display, DefaultScreen(display) ); @@ -124,14 +173,19 @@ case DirectColor: if (Options.usePrivateMap) { - COLOR_WinColormap = XCreateColormap( display, - DefaultRootWindow(display), + COLOR_WinColormap = XCreateColormap( display, rootWindow, visual, AllocAll ); if (COLOR_WinColormap) { - COLOR_BuildMap(COLOR_WinColormap, - DefaultDepth(display, DefaultScreen(display)), - visual->map_entries ); + COLOR_BuildMap( COLOR_WinColormap, screenDepth, + visual->map_entries ); + if (rootWindow != DefaultRootWindow(display)) + { + XSetWindowAttributes win_attr; + win_attr.colormap = COLOR_WinColormap; + XChangeWindowAttributes( display, rootWindow, + CWColormap, &win_attr ); + } break; } } @@ -139,9 +193,109 @@ case StaticGray: case StaticColor: case TrueColor: - COLOR_FillDefaultMap(); COLOR_WinColormap = DefaultColormapOfScreen( screen ); break; } - return TRUE; + return COLOR_InitPalette(); +} + + +/*********************************************************************** + * COLOR_IsSolid + * + * Check whether 'color' can be represented with a solid color. + */ +BOOL COLOR_IsSolid( COLORREF color ) +{ + int i; + PALETTEENTRY *pEntry = COLOR_sysPaletteEntries; + + if (color & 0xff000000) return TRUE; + if (!color || (color == 0xffffff)) return TRUE; + for (i = NB_RESERVED_COLORS; i > 0; i--, pEntry++) + { + if ((GetRValue(color) == pEntry->peRed) && + (GetGValue(color) == pEntry->peGreen) && + (GetBValue(color) == pEntry->peBlue)) return TRUE; + } + return FALSE; +} + + +/*********************************************************************** + * COLOR_ToPhysical + * + * Return the physical color closest to 'color'. + */ +WORD COLOR_ToPhysical( DC *dc, COLORREF color ) +{ + WORD index = 0; + WORD *mapping; + + if (!dc->u.x.pal.hMapping) return 0; + switch(color & 0xff000000) + { + case 0: /* RGB */ + index = GetNearestPaletteIndex( STOCK_DEFAULT_PALETTE, color ); + break; + case 1: /* PALETTEINDEX */ + index = color & 0xffff; + break; + case 2: /* PALETTERGB */ + index = GetNearestPaletteIndex( dc->w.hPalette, color ); + break; + } + if (index >= dc->u.x.pal.mappingSize) return 0; + mapping = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping ); + return mapping[index]; +} + + +/*********************************************************************** + * COLOR_SetMapping + * + * Set the color-mapping table in a DC. + */ +void COLOR_SetMapping( DC *dc, HANDLE map, WORD size ) +{ + WORD *pmap, *pnewmap; + + if (dc->u.x.pal.hMapping && (dc->u.x.pal.hMapping != hSysColorTranslation)) + GDI_HEAP_FREE( dc->u.x.pal.hMapping ); + if (map && (map != hSysColorTranslation)) + { + /* Copy mapping table */ + dc->u.x.pal.hMapping = GDI_HEAP_ALLOC(GMEM_MOVEABLE,sizeof(WORD)*size); + pmap = (WORD *) GDI_HEAP_ADDR( map ); + pnewmap = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping ); + memcpy( pnewmap, pmap, sizeof(WORD)*size ); + } + else dc->u.x.pal.hMapping = map; + dc->u.x.pal.mappingSize = size; +} + + +/*********************************************************************** + * GetNearestColor (GDI.154) + */ +COLORREF GetNearestColor( HDC hdc, COLORREF color ) +{ + WORD index; + DC *dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + if (!dc) return 0; + index = COLOR_ToPhysical( dc, color & 0xffffff ); + return PALETTEINDEX( index ); +} + + +/*********************************************************************** + * RealizeDefaultPalette (GDI.365) + */ +WORD RealizeDefaultPalette( HDC hdc ) +{ + DC *dc; + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + dc->w.hPalette = STOCK_DEFAULT_PALETTE; + COLOR_SetMapping( dc, hSysColorTranslation, NB_RESERVED_COLORS ); + return NB_RESERVED_COLORS; }
diff --git a/objects/dcvalues.c b/objects/dcvalues.c index 73c98aa..12b775f 100644 --- a/objects/dcvalues.c +++ b/objects/dcvalues.c
@@ -40,7 +40,6 @@ 0, /* breakCount */ 0, /* breakExtra */ 0, /* breakRem */ - 1, /* planes */ 1, /* bitsPerPixel */ MM_TEXT, /* MapMode */ 0, /* DCOrgX */
diff --git a/objects/dib.c b/objects/dib.c index 15e3d09..c6d9d44 100644 --- a/objects/dib.c +++ b/objects/dib.c
@@ -8,13 +8,13 @@ #include <stdio.h> #include <stdlib.h> - +#include <X11/Xlib.h> +#include <X11/Xutil.h> #include "gdi.h" +#include "bitmap.h" #include "icon.h" - -extern XImage * BITMAP_BmpToImage( BITMAP *, void * ); - +extern WORD COLOR_ToPhysical( DC *dc, COLORREF color ); /* color.c */ /*********************************************************************** * DIB_BitmapInfoSize @@ -39,8 +39,9 @@ * * Create an XImage pointing to the bitmap data. */ -XImage * DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData ) +static XImage *DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData ) { + extern void _XInitImageFuncPtrs( XImage* ); XImage * image; int bytesPerLine = (bmp->biWidth * bmp->biBitCount + 31) / 32 * 4; @@ -57,70 +58,251 @@ /*********************************************************************** + * DIB_SetImageBits_1 + * + * SetDIBits for a 1-bit deep DIB. + */ +static void DIB_SetImageBits_1( WORD lines, BYTE *bits, WORD width, + WORD *colors, XImage *bmpImage ) +{ + WORD i, x; + BYTE pad, pix; + + if (!(width & 31)) pad = 0; + else pad = ((32 - (width & 31)) + 7) / 8; + + while (lines--) + { + for (i = width/8, x = 0; (i > 0); i--) + { + pix = *bits++; + XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 6) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 5) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 4) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 3) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 2) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[(pix >> 1) & 1] ); + XPutPixel( bmpImage, x++, lines, colors[pix & 1] ); + } + pix = *bits; + switch(width & 7) + { + case 7: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 6: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 5: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 4: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 3: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 2: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1; + case 1: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); + } + bits += pad; + } +} + + +/*********************************************************************** + * DIB_SetImageBits_4 + * + * SetDIBits for a 4-bit deep DIB. + */ +static void DIB_SetImageBits_4( WORD lines, BYTE *bits, WORD width, + WORD *colors, XImage *bmpImage ) +{ + WORD i, x; + BYTE pad; + + if (!(width & 7)) pad = 0; + else pad = ((8 - (width & 7)) + 1) / 2; + + while (lines--) + { + for (i = width/2, x = 0; i > 0; i--) + { + BYTE pix = *bits++; + XPutPixel( bmpImage, x++, lines, colors[pix >> 4] ); + XPutPixel( bmpImage, x++, lines, colors[pix & 0x0f] ); + } + if (width & 1) XPutPixel( bmpImage, x, lines, colors[*bits >> 4] ); + bits += pad; + } +} + + +/*********************************************************************** + * DIB_SetImageBits_8 + * + * SetDIBits for an 8-bit deep DIB. + */ +static void DIB_SetImageBits_8( WORD lines, BYTE *bits, WORD width, + WORD *colors, XImage *bmpImage ) +{ + WORD x; + BYTE pad = (4 - (width & 3)) & 3; + + while (lines--) + { + for (x = 0; x < width; x++) + XPutPixel( bmpImage, x, lines, colors[*bits++] ); + bits += pad; + } +} + + +/*********************************************************************** + * DIB_SetImageBits_24 + * + * SetDIBits for a 24-bit deep DIB. + */ +static void DIB_SetImageBits_24( WORD lines, BYTE *bits, WORD width, + DC *dc, XImage *bmpImage ) +{ + WORD x; + BYTE pad = (4 - ((width*3) & 3)) & 3; + + while (lines--) + { + for (x = 0; x < width; x++, bits += 3) + { + XPutPixel( bmpImage, x, lines, + COLOR_ToPhysical( dc, RGB(bits[0],bits[1],bits[2]) )); + } + bits += pad; + } +} + + +/*********************************************************************** + * DIB_SetImageBits + * + * Transfer the bits to an X image. + * Helper function for SetDIBits() and SetDIBitsToDevice(). + */ +static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits, + BITMAPINFO *info, WORD coloruse, + Drawable drawable, GC gc, int xSrc, int ySrc, + int xDest, int yDest, int width, int height ) +{ + WORD *colorMapping; + XImage *bmpImage; + void *bmpData; + int i, colors, widthBytes; + + /* Build the color mapping table */ + + if (info->bmiHeader.biBitCount == 24) colorMapping = NULL; + else + { + colors = info->bmiHeader.biClrUsed; + if (!colors) colors = 1 << info->bmiHeader.biBitCount; + if (!(colorMapping = (WORD *)malloc( colors * sizeof(WORD) ))) + return 0; + if (coloruse == DIB_RGB_COLORS) + { + RGBQUAD * rgbPtr = info->bmiColors; + for (i = 0; i < colors; i++, rgbPtr++) + colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgbPtr->rgbRed, + rgbPtr->rgbGreen, + rgbPtr->rgbBlue) ); + } + else + { + WORD * index = (WORD *)info->bmiColors; + for (i = 0; i < colors; i++, index++) + colorMapping[i] = COLOR_ToPhysical( dc, PALETTEINDEX(*index) ); + } + } + + /* Transfer the pixels */ + + widthBytes = (info->bmiHeader.biWidth * depth + 31) / 32 * 4; + bmpData = malloc( lines * widthBytes ); + bmpImage = XCreateImage( display, DefaultVisualOfScreen(screen), + depth, ZPixmap, 0, bmpData, + info->bmiHeader.biWidth, lines, 32, widthBytes ); + + switch(info->bmiHeader.biBitCount) + { + case 1: + DIB_SetImageBits_1( lines, bits, info->bmiHeader.biWidth, + colorMapping, bmpImage ); + break; + case 4: + DIB_SetImageBits_4( lines, bits, info->bmiHeader.biWidth, + colorMapping, bmpImage ); + break; + case 8: + DIB_SetImageBits_8( lines, bits, info->bmiHeader.biWidth, + colorMapping, bmpImage ); + break; + case 24: + DIB_SetImageBits_24( lines, bits, info->bmiHeader.biWidth, + dc, bmpImage ); + break; + } + if (colorMapping) free(colorMapping); + + XPutImage( display, drawable, gc, bmpImage, xSrc, ySrc, + xDest, yDest, width, height ); + XDestroyImage( bmpImage ); + return lines; +} + + +/*********************************************************************** * SetDIBits (GDI.440) */ int SetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines, LPSTR bits, BITMAPINFO * info, WORD coloruse ) { DC * dc; - BITMAPOBJ * bmpObj; - BITMAP * bmp; - WORD * colorMapping; - RGBQUAD * rgbPtr; - XImage * bmpImage, * dibImage; - int i, x, y, pixel, colors; - - if (!lines) return 0; + BITMAPOBJ * bmp; + + /* Check parameters */ + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; - if (!(bmpObj = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) + if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0; + if (!lines || (startscan >= (WORD)info->bmiHeader.biHeight)) return 0; + if (startscan+lines > info->bmiHeader.biHeight) + lines = info->bmiHeader.biHeight - startscan; - /* Build the color mapping table */ + return DIB_SetImageBits( dc, lines, bmp->bitmap.bmBitsPixel, + bits, info, coloruse, bmp->pixmap, BITMAP_GC(bmp), + 0, 0, 0, startscan, bmp->bitmap.bmWidth, lines ); +} - if (info->bmiHeader.biBitCount == 24) colorMapping = NULL; - else if (coloruse == DIB_RGB_COLORS) - { - colors = info->bmiHeader.biClrUsed; - if (!colors) colors = 1 << info->bmiHeader.biBitCount; - if (!(colorMapping = (WORD *)malloc( colors * sizeof(WORD) ))) - { - GlobalUnlock( bmpObj->hBitmap ); - return 0; - } - for (i = 0, rgbPtr = info->bmiColors; i < colors; i++, rgbPtr++) - colorMapping[i] = GetNearestPaletteIndex( dc->w.hPalette, - RGB(rgbPtr->rgbRed, - rgbPtr->rgbGreen, - rgbPtr->rgbBlue) ); - } - else colorMapping = (WORD *)info->bmiColors; - /* Transfer the pixels (very slow...) */ +/*********************************************************************** + * SetDIBitsToDevice (GDI.443) + */ +int SetDIBitsToDevice( HDC hdc, short xDest, short yDest, WORD cx, WORD cy, + WORD xSrc, WORD ySrc, WORD startscan, WORD lines, + LPSTR bits, BITMAPINFO * info, WORD coloruse ) +{ + DC * dc; - bmpImage = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) ); - dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits ); + /* Check parameters */ - for (y = 0; y < lines; y++) - { - for (x = 0; x < info->bmiHeader.biWidth; x++) - { - pixel = XGetPixel( dibImage, x, y ); - if (colorMapping) pixel = colorMapping[pixel]; - else pixel = GetNearestPaletteIndex(dc->w.hPalette,(COLORREF)pixel); - XPutPixel( bmpImage, x, bmp->bmHeight - startscan - y - 1, pixel ); - } - } + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + if (!lines || (startscan >= info->bmiHeader.biHeight)) return 0; + if (startscan+lines > info->bmiHeader.biHeight) + lines = info->bmiHeader.biHeight - startscan; + if (ySrc < startscan) ySrc = startscan; + else if (ySrc >= startscan+lines) return 0; + if (xSrc >= info->bmiHeader.biWidth) return 0; + if (ySrc+cy >= startscan+lines) cy = startscan + lines - ySrc; + if (xSrc+cx >= info->bmiHeader.biWidth) cx = info->bmiHeader.biWidth-xSrc; + if (!cx || !cy) return 0; - bmpImage->data = NULL; - dibImage->data = NULL; - XDestroyImage( bmpImage ); - XDestroyImage( dibImage ); - - if (colorMapping && (coloruse == DIB_RGB_COLORS)) free(colorMapping); - - GlobalUnlock( bmpObj->hBitmap ); - return lines; + DC_SetupGCForText( dc ); /* To have the correct ROP */ + return DIB_SetImageBits( dc, lines, dc->w.bitsPerPixel, + bits, info, coloruse, + dc->u.x.drawable, dc->u.x.gc, + xSrc, ySrc - startscan, + dc->w.DCOrgX + XLPTODP( dc, xDest ), + dc->w.DCOrgY + YLPTODP( dc, yDest ), + cx, cy ); } @@ -131,8 +313,7 @@ LPSTR bits, BITMAPINFO * info, WORD coloruse ) { DC * dc; - BITMAPOBJ * bmpObj; - BITMAP * bmp; + BITMAPOBJ * bmp; PALETTEENTRY * palEntry; PALETTEOBJ * palette; XImage * bmpImage, * dibImage; @@ -140,11 +321,10 @@ if (!lines) return 0; if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; - if (!(bmpObj = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) + if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0; if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC ))) return 0; - if (!(bmp = (BITMAP *) GlobalLock( bmpObj->hBitmap ))) return 0; /* Transfer color info */ @@ -165,7 +345,8 @@ if (bits) { - bmpImage = BITMAP_BmpToImage( bmp, ((char *)bmp) + sizeof(BITMAP) ); + bmpImage = XGetImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth, + bmp->bitmap.bmHeight, AllPlanes, ZPixmap ); dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits ); for (y = 0; y < lines; y++) @@ -173,18 +354,15 @@ for (x = 0; x < info->bmiHeader.biWidth; x++) { XPutPixel( dibImage, x, y, - XGetPixel(bmpImage, x, bmp->bmHeight-startscan-y-1) ); + XGetPixel(bmpImage, x, bmp->bitmap.bmHeight-startscan-y-1) ); } } - bmpImage->data = NULL; dibImage->data = NULL; - XDestroyImage( bmpImage ); XDestroyImage( dibImage ); + XDestroyImage( bmpImage ); } - - GlobalUnlock( bmpObj->hBitmap ); return lines; }
diff --git a/objects/dither.c b/objects/dither.c new file mode 100644 index 0000000..5210106 --- /dev/null +++ b/objects/dither.c
@@ -0,0 +1,140 @@ +/* + * Dithering functions + * + * Copyright 1994 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1994"; + +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#include "gdi.h" +#include "bitmap.h" + + + /* Levels of each primary */ +#define PRIMARY_LEVELS 3 +#define TOTAL_LEVELS (PRIMARY_LEVELS*PRIMARY_LEVELS*PRIMARY_LEVELS) + + /* Dithering matrix size */ +#define MATRIX_SIZE 8 +#define MATRIX_SIZE_2 (MATRIX_SIZE*MATRIX_SIZE) + + /* Total number of possible levels for a dithered primary color */ +#define DITHER_LEVELS (MATRIX_SIZE_2 * (PRIMARY_LEVELS-1) + 1) + + /* Dithering matrix */ +static const int dither_matrix[MATRIX_SIZE_2] = +{ + 0, 32, 8, 40, 2, 34, 10, 42, + 48, 16, 56, 24, 50, 18, 58, 26, + 12, 44, 4, 36, 14, 46, 6, 38, + 60, 28, 52, 20, 62, 30, 54, 22, + 3, 35, 11, 43, 1, 33, 9, 41, + 51, 19, 59, 27, 49, 17, 57, 25, + 15, 47, 7, 39, 13, 45, 5, 37, + 63, 31, 55, 23, 61, 29, 53, 21 +}; + + /* Mapping between (R,G,B) triples and EGA colors */ +static const int EGAmapping[TOTAL_LEVELS] = +{ + 0, /* 000000 -> 000000 */ + 4, /* 00007f -> 000080 */ + 12, /* 0000ff -> 0000ff */ + 2, /* 007f00 -> 008000 */ + 6, /* 007f7f -> 008080 */ + 6, /* 007fff -> 008080 */ + 10, /* 00ff00 -> 00ff00 */ + 6, /* 00ff7f -> 008080 */ + 14, /* 00ffff -> 00ffff */ + 1, /* 7f0000 -> 800000 */ + 5, /* 7f007f -> 800080 */ + 5, /* 7f00ff -> 800080 */ + 3, /* 7f7f00 -> 808000 */ + 8, /* 7f7f7f -> 808080 */ + 7, /* 7f7fff -> c0c0c0 */ + 3, /* 7fff00 -> 808000 */ + 7, /* 7fff7f -> c0c0c0 */ + 7, /* 7fffff -> c0c0c0 */ + 9, /* ff0000 -> ff0000 */ + 5, /* ff007f -> 800080 */ + 13, /* ff00ff -> ff00ff */ + 3, /* ff7f00 -> 808000 */ + 7, /* ff7f7f -> c0c0c0 */ + 7, /* ff7fff -> c0c0c0 */ + 11, /* ffff00 -> ffff00 */ + 7, /* ffff7f -> c0c0c0 */ + 15 /* ffffff -> ffffff */ +}; + + /* Map an EGA index (0..15) to a pixel value */ +extern int COLOR_mapEGAPixel[16]; /* in color.c */ + +#define PIXEL_VALUE(r,g,b) \ + COLOR_mapEGAPixel[EGAmapping[((r)*PRIMARY_LEVELS+(g))*PRIMARY_LEVELS+(b)]] + + /* X image for building dithered pixmap */ +static XImage *ditherImage = NULL; +static char *imageData = NULL; + + +/*********************************************************************** + * DITHER_Init + * + * Create the X image used for dithering. + */ +BOOL DITHER_Init() +{ + int bytes_per_line = (screenDepth * MATRIX_SIZE + 7) / 8; + if (!(imageData = (char *) malloc( bytes_per_line * MATRIX_SIZE ))) + return FALSE; + ditherImage = XCreateImage( display, DefaultVisualOfScreen(screen), + screenDepth, ZPixmap, 0, imageData, + MATRIX_SIZE, MATRIX_SIZE, 8, bytes_per_line ); + return (ditherImage != NULL); +} + + +/*********************************************************************** + * DITHER_DitherColor + */ +Pixmap DITHER_DitherColor( DC *dc, COLORREF color ) +{ + static COLORREF prevColor = 0xffffffff; + unsigned int x, y; + Pixmap pixmap; + +/* printf( "Dither: %x\n", color ); */ + + if (color != prevColor) + { + int r = GetRValue( color ) * DITHER_LEVELS; + int g = GetGValue( color ) * DITHER_LEVELS; + int b = GetBValue( color ) * DITHER_LEVELS; + const int *pmatrix = dither_matrix; + + WORD *mapping = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping ); + + for (y = 0; y < MATRIX_SIZE; y++) + { + for (x = 0; x < MATRIX_SIZE; x++) + { + int d = *pmatrix++ * 256; + int dr = ((r + d) / MATRIX_SIZE_2) / 256; + int dg = ((g + d) / MATRIX_SIZE_2) / 256; + int db = ((b + d) / MATRIX_SIZE_2) / 256; + XPutPixel( ditherImage, x, y, PIXEL_VALUE(dr,dg,db) ); + } + } + prevColor = color; + } + + pixmap = XCreatePixmap( display, rootWindow, + MATRIX_SIZE, MATRIX_SIZE, screenDepth ); + XPutImage( display, pixmap, BITMAP_colorGC, ditherImage, 0, 0, + 0, 0, MATRIX_SIZE, MATRIX_SIZE ); + return pixmap; +}
diff --git a/objects/font.c b/objects/font.c index 883e699..382976b 100644 --- a/objects/font.c +++ b/objects/font.c
@@ -8,6 +8,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <X11/Xatom.h> #include "gdi.h" @@ -17,7 +18,7 @@ * * Find a X font matching the logical font. */ -XFontStruct * FONT_MatchFont( DC * dc, LOGFONT * font ) +static XFontStruct * FONT_MatchFont( LOGFONT * font ) { char pattern[100]; char *family, *weight, *charset; @@ -44,8 +45,16 @@ default: family = "*"; break; } - sprintf( pattern, "-*-%s-%s-%c-normal--*-%d-*-*-%c-%d-%s", - family, weight, slant, height, spacing, width, charset ); + /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */ + if ( width == 0 ) + sprintf( pattern, "-*-%s-%s-%c-normal--*-%d-*-*-%c-*-%s", + family, weight, slant, height, spacing, charset + ); + else + sprintf( pattern, "-*-%s-%s-%c-normal--*-%d-*-*-%c-%d-%s", + family, weight, slant, height, spacing, width, charset + ); + #ifdef DEBUG_FONT printf( "FONT_MatchFont: '%s'\n", pattern ); #endif @@ -166,13 +175,24 @@ /* Load font if necessary */ + if (!font) + { + HFONT hnewfont; + + hnewfont = CreateFont(10, 7, 0, 0, FW_DONTCARE, + FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, + DEFAULT_QUALITY, FF_DONTCARE, "*" ); + font = (FONTOBJ *) GDI_HEAP_ADDR( hnewfont ); + } + if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT)) stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT]; - else stockPtr = NULL; + else + stockPtr = NULL; if (!stockPtr || !stockPtr->fstruct) { - fontStruct = FONT_MatchFont( dc, &font->logfont ); + fontStruct = FONT_MatchFont( &font->logfont ); } else {
diff --git a/objects/gdiobj.c b/objects/gdiobj.c index bc59d86..cd78887 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c
@@ -6,11 +6,14 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include <stdlib.h> +#include <stdio.h> #include "gdi.h" - +#include "prototypes.h" MDESC *GDI_Heap = NULL; +extern HPALETTE COLOR_Init(); /* color.c */ /*********************************************************************** * GDI stock objects @@ -130,12 +133,10 @@ (GDIOBJHDR *) &AnsiVarFont, (GDIOBJHDR *) &SystemFont, (GDIOBJHDR *) &DeviceDefaultFont, - NULL, /* DEFAULT_PALETTE created by PALETTE_Init */ + NULL, /* DEFAULT_PALETTE created by COLOR_Init */ (GDIOBJHDR *) &SystemFixedFont }; -extern GDIOBJHDR * PALETTE_systemPalette; - /*********************************************************************** * GDI_Init @@ -144,6 +145,7 @@ */ BOOL GDI_Init() { + HPALETTE hpalette; struct segment_descriptor_s * s; #ifndef WINELIB @@ -156,9 +158,8 @@ /* Create default palette */ - COLOR_Init(); - PALETTE_Init(); - StockObjects[DEFAULT_PALETTE] = PALETTE_systemPalette; + if (!(hpalette = COLOR_Init())) return FALSE; + StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *) GDI_HEAP_ADDR( hpalette ); /* Create default bitmap */ @@ -168,6 +169,10 @@ if (!REGION_Init()) return FALSE; + /* Initialise dithering */ + + if (!DITHER_Init()) return FALSE; + return TRUE; } @@ -217,7 +222,6 @@ BOOL GDI_FreeObject( HANDLE handle ) { GDIOBJHDR * object; - HANDLE prev; /* Can't free stock objects */ if (handle >= FIRST_STOCK_HANDLE) return FALSE;
diff --git a/objects/palette.c b/objects/palette.c index 03300c4..dc52635 100644 --- a/objects/palette.c +++ b/objects/palette.c
@@ -1,62 +1,32 @@ /* * GDI palette objects * - * Copyright 1993 Alexandre Julliard + * Copyright 1993,1994 Alexandre Julliard */ -static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +static char Copyright[] = "Copyright Alexandre Julliard, 1993,1994"; #include <stdlib.h> +#include <string.h> +#include <limits.h> +/* #ifdef linux #include <values.h> #endif +*/ + #if !defined (MAXINT) #include <limits.h> #define MAXINT INT_MAX #endif #include <X11/Xlib.h> - #include "gdi.h" +extern void COLOR_SetMapping( DC *dc, HANDLE map, WORD size ); /* color.c */ + extern Colormap COLOR_WinColormap; -GDIOBJHDR * PALETTE_systemPalette; - - -/*********************************************************************** - * PALETTE_Init - */ -BOOL PALETTE_Init() -{ - int i, size; - XColor color; - HPALETTE hpalette; - LOGPALETTE * palPtr; - - size = DefaultVisual( display, DefaultScreen(display) )->map_entries; - palPtr = malloc( sizeof(LOGPALETTE) + (size-1)*sizeof(PALETTEENTRY) ); - if (!palPtr) return FALSE; - palPtr->palVersion = 0x300; - palPtr->palNumEntries = size; - memset( palPtr->palPalEntry, 0xff, size*sizeof(PALETTEENTRY) ); - - for (i = 0; i < size; i++) - { - color.pixel = i; - XQueryColor( display, COLOR_WinColormap, &color ); - palPtr->palPalEntry[i].peRed = color.red >> 8; - palPtr->palPalEntry[i].peGreen = color.green >> 8; - palPtr->palPalEntry[i].peBlue = color.blue >> 8; - palPtr->palPalEntry[i].peFlags = 0; - } - - hpalette = CreatePalette( palPtr ); - PALETTE_systemPalette = (GDIOBJHDR *) GDI_HEAP_ADDR( hpalette ); - free( palPtr ); - return TRUE; -} - /*********************************************************************** * CreatePalette (GDI.360) @@ -117,6 +87,33 @@ /*********************************************************************** + * GetSystemPaletteEntries (GDI.375) + */ +WORD GetSystemPaletteEntries( HDC hdc, WORD start, WORD count, + LPPALETTEENTRY entries ) +{ + WORD i; + DC *dc; + XColor color; + + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + if (start >= dc->w.devCaps->sizePalette) return 0; + if (start+count >= dc->w.devCaps->sizePalette) + count = dc->w.devCaps->sizePalette - start; + for (i = 0; i < count; i++) + { + color.pixel = start + i; + XQueryColor( display, COLOR_WinColormap, &color ); + entries[i].peRed = color.red >> 8; + entries[i].peGreen = color.green >> 8; + entries[i].peBlue = color.blue >> 8; + entries[i].peFlags = 0; + } + return count; +} + + +/*********************************************************************** * GetNearestPaletteIndex (GDI.370) */ WORD GetNearestPaletteIndex( HPALETTE hpalette, COLORREF color ) @@ -143,7 +140,8 @@ b = GetBValue(color); entry = palPtr->logpalette.palPalEntry; - for (i = 0, minDist = MAXINT; i < palPtr->logpalette.palNumEntries; i++) + for (i = 0, minDist = MAXINT; minDist !=0 && + i < palPtr->logpalette.palNumEntries ; i++) { if (entry->peFlags != 0xff) { @@ -178,18 +176,51 @@ /*********************************************************************** + * GDISelectPalette (GDI.361) + */ +HPALETTE GDISelectPalette( HDC hdc, HPALETTE hpal ) +{ + HPALETTE prev; + DC *dc; + +#ifdef DEBUG_PALETTE + printf( "GDISelectPalette: %d %d\n", hdc, hpal ); +#endif + if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0; + prev = dc->w.hPalette; + dc->w.hPalette = hpal; + if (hpal != STOCK_DEFAULT_PALETTE) COLOR_SetMapping( dc, 0, 0 ); + else RealizeDefaultPalette( hdc ); /* Always realize default palette */ + return prev; +} + + +/*********************************************************************** + * GDIRealizePalette (GDI.362) + */ +UINT GDIRealizePalette( HDC hdc ) +{ +#ifdef DEBUG_PALETTE + printf( "GDIRealizePalette: %d\n", hdc ); +#endif + return 0; +} + + +/*********************************************************************** * SelectPalette (USER.282) */ HPALETTE SelectPalette(HDC hDC, HPALETTE hPal, BOOL bForceBackground) { - return (HPALETTE)NULL; + return GDISelectPalette( hDC, hPal ); } + /*********************************************************************** * RealizePalette (USER.283) */ -int RealizePalette(HDC hDC) +UINT RealizePalette(HDC hDC) { - return 0; + return GDIRealizePalette( hDC ); }
diff --git a/objects/pen.c b/objects/pen.c index a0a7ad7..48da252 100644 --- a/objects/pen.c +++ b/objects/pen.c
@@ -8,6 +8,7 @@ #include "gdi.h" +extern WORD COLOR_ToPhysical( DC *dc, COLORREF color ); /*********************************************************************** * CreatePen (GDI.61) @@ -68,21 +69,24 @@ / dc->w.WndExtX; if (dc->u.x.pen.width < 0) dc->u.x.pen.width = -dc->u.x.pen.width; if (dc->u.x.pen.width == 1) dc->u.x.pen.width = 0; /* Faster */ - dc->u.x.pen.pixel = GetNearestPaletteIndex( dc->w.hPalette, - pen->logpen.lopnColor ); + dc->u.x.pen.pixel = COLOR_ToPhysical( dc, pen->logpen.lopnColor ); switch(pen->logpen.lopnStyle) { case PS_DASH: - XSetDashes( XT_display, dc->u.x.gc, 0, dash_dash, 2 ); + dc->u.x.pen.dashes = dash_dash; + dc->u.x.pen.dash_len = 2; break; case PS_DOT: - XSetDashes( XT_display, dc->u.x.gc, 0, dash_dot, 2 ); + dc->u.x.pen.dashes = dash_dot; + dc->u.x.pen.dash_len = 2; break; case PS_DASHDOT: - XSetDashes( XT_display, dc->u.x.gc, 0, dash_dashdot, 4 ); + dc->u.x.pen.dashes = dash_dashdot; + dc->u.x.pen.dash_len = 4; break; case PS_DASHDOTDOT: - XSetDashes( XT_display, dc->u.x.gc, 0, dash_dashdotdot, 6 ); + dc->u.x.pen.dashes = dash_dashdotdot; + dc->u.x.pen.dash_len = 6; break; }
diff --git a/objects/region.c b/objects/region.c index 3a7b9ef..afe4dd4 100644 --- a/objects/region.c +++ b/objects/region.c
@@ -8,13 +8,13 @@ #include <stdlib.h> #include <stdio.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> #include "gdi.h" - /* GC used for region operations */ static GC regionGC = 0; - /*********************************************************************** * REGION_Init */ @@ -23,8 +23,7 @@ Pixmap tmpPixmap; /* CreateGC needs a drawable */ - tmpPixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display), - 1, 1, 1 ); + tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 ); if (tmpPixmap) { regionGC = XCreateGC( XT_display, tmpPixmap, 0, NULL ); @@ -68,8 +67,7 @@ /* Create pixmap */ - region->pixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display), - width, height, 1 ); + region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 ); if (!region->pixmap) return FALSE; /* Fill pixmap */ @@ -576,8 +574,19 @@ width = region->box.right - region->box.left; height = region->box.bottom - region->box.top; - region->pixmap = XCreatePixmap( XT_display, DefaultRootWindow(XT_display), - width, height, 1 ); + if (!width || !height) + { + printf( "CombineRgn: width or height is 0. Please report this.\n" ); + printf( "src1=%d,%d-%d,%d src2=%d,%d-%d,%d dst=%d,%d-%d,%d op=%d\n", + src1Obj->region.box.left, src1Obj->region.box.top, + src1Obj->region.box.right, src1Obj->region.box.bottom, + src2Obj->region.box.left, src2Obj->region.box.top, + src2Obj->region.box.right, src2Obj->region.box.bottom, + region->box.left, region->box.top, + region->box.right, region->box.bottom, mode ); + exit(1); + } + region->pixmap = XCreatePixmap( display, rootWindow, width, height, 1 ); switch(mode) {
diff --git a/objects/text.c b/objects/text.c index 787b0f7..a900baa 100644 --- a/objects/text.c +++ b/objects/text.c
@@ -221,7 +221,6 @@ (rect->bottom - rect->top) / 2 - size.cy / 2; else if (flags & DT_BOTTOM) y = rect->bottom - size.cy; } - if (!(flags & DT_CALCRECT)) if (!TextOut(hdc, x, y, line, len)) return 0; if (prefix_offset != -1)