Release 970202
Sun Feb 2 12:31:03 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
* [files/drive.c]
Fixed SetCurrentDirectory() to also change the current drive.
* [win32/except.c] [tools/build.c]
Use Win32 register functions to implement exception handling.
Fixed UnhandledExceptionFilter.
Fri Jan 31 15:42:41 1997 David Faure <david.faure@ihamy.insa-lyon.fr>
* [windows/keyboard.c]
Added KEYBOARD_GenerateMsg to generate Caps Lock and NumLock events
Added calls to KEYBOARD_GenerateMsg when the key is pressed/released
or when the state has changed, out of wine.
Changed type 3-state 'ToggleKeyState' to boolean. The On/Off is given
by InputKeyStateTable.
Wed Jan 29 21:53:04 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [loader/*resource.c][if1632/thunk.c]
EnumResource* added.
* [loader/pe_resource.] [loader/resource.c]
SizeofResource32(), LoadAccelerators32() added.
* [misc/lstr.c]
FormatMessage %n added.
* [misc/crtdll.c][include/ctrdll.h][if1632/crtdll.spec]
_chdrive,_errno,_isctype added.
* [misc/cpu.c]
Replaced runtime_cpu by GetSystemInfo().
* [windows/hook.c][include/hook.h]
Fixed mapping of hooks to win32/unicode.
* [windows/keyboard.c] [windows/defwnd.c]
Updated to win32 standard.
ALT-<Menukey> fixed.
* [windows/queue.c]
GetWindowThreadProcessId() implemented.
Mon Jan 27 16:42:49 1997 John Harvey <john@division.co.uk>
* [graphics/metafiledrv/*] [graphics/x11drv/*]
[objects/bitmap.c] [objects/brush.c] [objects/font.c]
[objects/gdiobj.c] [objects/pen.c]
Moved SelectObject to graphics drivers. Printer support now works
in a few cases but is definitely not complete. Generic/text driver
works. The postscript driver works if true type fonts are disabled
from the control panel. To enable printer support add Printer=on
to the wine section of your wine.conf file. This causes write not
to work properly. I know that several other printer drivers do not
work.
* [tools/build.c]
Make .stabs not used for svr4 since it doesn't use GNU assembler.
* [misc/fontengine.c]
Make sure a printf doesn't crash the system.
Sat Jan 25 15:53:35 1997 Huw D M Davies <h.davies1@physics.oxford.ac.uk>
* [objects/metafile.c]
Fixed some problems with PlayMetaFileRecord().
* [objects/dc.c]
hClipRgn gets initialized in GetDCState().
Fri Jan 24 21:22:26 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
* [debugger/stabs.c]
Handle file names beginning with '/'.
Fri Jan 24 18:33:04 1997 Robert Pouliot <krynos@clic.net>
* [*/*]
Some more patches for OS/2 support.
Fri Jan 24 11:30:41 1997 Bang Jun-Young <bangjy@nownuri.nowcom.co.kr>
* [resources/sysres_Ko.rc]
Updated support for Korean (Ko) language.
diff --git a/graphics/metafiledrv/Makefile.in b/graphics/metafiledrv/Makefile.in
index 5246a6c..ff538f2 100644
--- a/graphics/metafiledrv/Makefile.in
+++ b/graphics/metafiledrv/Makefile.in
@@ -10,6 +10,7 @@
graphics.c \
init.c \
mapping.c \
+ objects.c \
text.c
all: $(MODULE).o
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index 6545c9e..08dac5d 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -52,7 +52,7 @@
MFDRV_ScaleViewportExt, /* pScaleViewportExt */
MFDRV_ScaleWindowExt, /* pScaleWindowExt */
NULL, /* pSelectClipRgn */
- NULL, /* pSelectObject */
+ MFDRV_SelectObject, /* pSelectObject */
NULL, /* pSelectPalette */
NULL, /* pSetBkColor */
NULL, /* pSetBkMode */
diff --git a/graphics/metafiledrv/objects.c b/graphics/metafiledrv/objects.c
new file mode 100644
index 0000000..2c1aa22
--- /dev/null
+++ b/graphics/metafiledrv/objects.c
@@ -0,0 +1,104 @@
+/*
+ * GDI objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "bitmap.h"
+#include "brush.h"
+#include "font.h"
+#include "metafile.h"
+#include "metafiledrv.h"
+#include "pen.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+/***********************************************************************
+ * MFDRV_BITMAP_SelectObject
+ */
+static HBITMAP16 MFDRV_BITMAP_SelectObject( DC * dc, HBITMAP16 hbitmap,
+ BITMAPOBJ * bmp )
+{
+ return 0;
+}
+
+
+/***********************************************************************
+ * MFDRV_BRUSH_SelectObject
+ */
+static HBRUSH32 MFDRV_BRUSH_SelectObject( DC * dc, HBRUSH32 hbrush,
+ BRUSHOBJ * brush )
+{
+ LOGBRUSH16 logbrush = { brush->logbrush.lbStyle,
+ brush->logbrush.lbColor,
+ brush->logbrush.lbHatch };
+ switch (brush->logbrush.lbStyle)
+ {
+ case BS_SOLID:
+ case BS_HATCHED:
+ case BS_HOLLOW:
+ if (!MF_CreateBrushIndirect( dc, hbrush, &logbrush )) return 0;
+ break;
+ case BS_PATTERN:
+ case BS_DIBPATTERN:
+ if (!MF_CreatePatternBrush( dc, hbrush, &logbrush )) return 0;
+ break;
+ }
+ return 1; /* FIXME? */
+}
+
+
+/***********************************************************************
+ * MFDRV_FONT_SelectObject
+ */
+static HFONT16 MFDRV_FONT_SelectObject( DC * dc, HFONT16 hfont,
+ FONTOBJ * font )
+{
+ HFONT16 prevHandle = dc->w.hFont;
+ if (MF_CreateFontIndirect(dc, hfont, &(font->logfont))) return prevHandle;
+ return 0;
+}
+
+
+/***********************************************************************
+ * MFDRV_PEN_SelectObject
+ */
+static HPEN32 MFDRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen )
+{
+ HPEN32 prevHandle = dc->w.hPen;
+ LOGPEN16 logpen = { pen->logpen.lopnStyle,
+ { pen->logpen.lopnWidth.x, pen->logpen.lopnWidth.y },
+ pen->logpen.lopnColor };
+ if (MF_CreatePenIndirect( dc, hpen, &logpen )) return prevHandle;
+ return 0;
+}
+
+
+/***********************************************************************
+ * MFDRV_SelectObject
+ */
+HGDIOBJ32 MFDRV_SelectObject( DC *dc, HGDIOBJ32 handle )
+{
+ GDIOBJHDR * ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
+
+ if (!ptr) return 0;
+ dprintf_gdi(stddeb, "SelectObject: hdc=%04x %04x\n", dc->hSelf, handle );
+
+ switch(ptr->wMagic)
+ {
+ case PEN_MAGIC:
+ return MFDRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
+ case BRUSH_MAGIC:
+ return MFDRV_BRUSH_SelectObject( dc, handle, (BRUSHOBJ *)ptr );
+ case BITMAP_MAGIC:
+ return MFDRV_BITMAP_SelectObject( dc, handle, (BITMAPOBJ *)ptr );
+ case FONT_MAGIC:
+ return MFDRV_FONT_SelectObject( dc, handle, (FONTOBJ *)ptr );
+ case REGION_MAGIC:
+ return (HGDIOBJ16)SelectClipRgn16( dc->hSelf, handle );
+ }
+ return 0;
+}
diff --git a/graphics/x11drv/Makefile.in b/graphics/x11drv/Makefile.in
index 1fd36db..9001dad 100644
--- a/graphics/x11drv/Makefile.in
+++ b/graphics/x11drv/Makefile.in
@@ -7,10 +7,14 @@
C_SRCS = \
bitblt.c \
+ bitmap.c \
+ brush.c \
clipping.c \
font.c \
graphics.c \
init.c \
+ objects.c \
+ pen.c \
text.c
all: $(MODULE).o
diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c
new file mode 100644
index 0000000..d0cc825
--- /dev/null
+++ b/graphics/x11drv/bitmap.c
@@ -0,0 +1,81 @@
+/*
+ * GDI bitmap objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "gdi.h"
+#include "callback.h"
+#include "dc.h"
+#include "bitmap.h"
+#include "heap.h"
+#include "stddebug.h"
+#include "debug.h"
+
+/***********************************************************************
+ * X11DRV_BITMAP_Init
+ */
+BOOL32 X11DRV_BITMAP_Init(void)
+{
+ Pixmap tmpPixmap;
+
+ /* Create the necessary GCs */
+
+ if ((tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 )))
+ {
+ 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)))
+ {
+ BITMAP_colorGC = XCreateGC( display, tmpPixmap, 0, NULL );
+ XSetGraphicsExposures( display, BITMAP_colorGC, False );
+ XFreePixmap( display, tmpPixmap );
+ }
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * X11DRV_BITMAP_SelectObject
+ */
+HBITMAP32 X11DRV_BITMAP_SelectObject( DC * dc, HBITMAP32 hbitmap,
+ BITMAPOBJ * bmp )
+{
+ HRGN32 hrgn;
+ HBITMAP32 prevHandle = dc->w.hBitmap;
+
+ if (!(dc->w.flags & DC_MEMORY)) return 0;
+
+ if (dc->w.hVisRgn)
+ SetRectRgn(dc->w.hVisRgn, 0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight );
+ else
+ {
+ hrgn = CreateRectRgn32(0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
+ if (!hrgn) return 0;
+ dc->w.hVisRgn = hrgn;
+ }
+
+ dc->u.x.drawable = bmp->pixmap;
+ dc->w.hBitmap = hbitmap;
+
+ /* Change GC depth if needed */
+
+ if (dc->w.bitsPerPixel != bmp->bitmap.bmBitsPixel)
+ {
+ XFreeGC( display, dc->u.x.gc );
+ dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL );
+ dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
+ DC_InitDC( dc );
+ }
+ else CLIPPING_UpdateGCRegion( dc ); /* Just update GC clip region */
+ return prevHandle;
+}
diff --git a/graphics/x11drv/brush.c b/graphics/x11drv/brush.c
new file mode 100644
index 0000000..62bc41f
--- /dev/null
+++ b/graphics/x11drv/brush.c
@@ -0,0 +1,270 @@
+/*
+ * GDI brush objects
+ *
+ * Copyright 1993, 1994 Alexandre Julliard
+ */
+
+#include <stdlib.h>
+#include "brush.h"
+#include "bitmap.h"
+#include "color.h"
+#include "x11drv.h"
+#include "stddebug.h"
+#include "debug.h"
+
+static const char HatchBrushes[NB_HATCH_STYLES][8] =
+{
+ { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HS_HORIZONTAL */
+ { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HS_VERTICAL */
+ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HS_FDIAGONAL */
+ { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HS_BDIAGONAL */
+ { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HS_CROSS */
+ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 } /* HS_DIAGCROSS */
+};
+
+ /* Levels of each primary for dithering */
+#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 */
+};
+
+#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;
+
+
+/***********************************************************************
+ * BRUSH_Init
+ *
+ * Create the X image used for dithering.
+ */
+BOOL32 X11DRV_BRUSH_Init(void)
+{
+ XCREATEIMAGE( ditherImage, MATRIX_SIZE, MATRIX_SIZE, screenDepth );
+ return (ditherImage != NULL);
+}
+
+
+/***********************************************************************
+ * BRUSH_DitherColor
+ */
+static Pixmap BRUSH_DitherColor( DC *dc, COLORREF color )
+{
+ static COLORREF prevColor = 0xffffffff;
+ unsigned int x, y;
+ Pixmap pixmap;
+
+ 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;
+
+ 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;
+}
+
+
+/***********************************************************************
+ * BRUSH_SelectSolidBrush
+ */
+static void BRUSH_SelectSolidBrush( DC *dc, COLORREF color )
+{
+ if ((dc->w.bitsPerPixel > 1) && (screenDepth <= 8) && !COLOR_IsSolid( color ))
+ {
+ /* Dithered brush */
+ dc->u.x.brush.pixmap = BRUSH_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
+ */
+static BOOL32 BRUSH_SelectPatternBrush( DC * dc, HBITMAP32 hbitmap )
+{
+ 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 );
+
+ if (bmp->bitmap.bmBitsPixel > 1)
+ {
+ dc->u.x.brush.fillStyle = FillTiled;
+ dc->u.x.brush.pixel = 0; /* Ignored */
+ }
+ else
+ {
+ dc->u.x.brush.fillStyle = FillOpaqueStippled;
+ dc->u.x.brush.pixel = -1; /* Special case (see DC_SetupGCForBrush) */
+ }
+ return TRUE;
+}
+
+
+
+
+/***********************************************************************
+ * BRUSH_SelectObject
+ */
+HBRUSH32 X11DRV_BRUSH_SelectObject( DC * dc, HBRUSH32 hbrush, BRUSHOBJ * brush )
+{
+ HBITMAP16 hBitmap;
+ BITMAPINFO * bmpInfo;
+ HBRUSH16 prevHandle = dc->w.hBrush;
+
+ dprintf_gdi(stddeb, "Brush_SelectObject: hdc=%04x hbrush=%04x\n",
+ dc->hSelf,hbrush);
+#ifdef NOTDEF
+ if (dc->header.wMagic == METAFILE_DC_MAGIC)
+ {
+ LOGBRUSH16 logbrush = { brush->logbrush.lbStyle,
+ brush->logbrush.lbColor,
+ brush->logbrush.lbHatch };
+ switch (brush->logbrush.lbStyle)
+ {
+ case BS_SOLID:
+ case BS_HATCHED:
+ case BS_HOLLOW:
+ if (!MF_CreateBrushIndirect( dc, hbrush, &logbrush )) return 0;
+ break;
+ case BS_PATTERN:
+ case BS_DIBPATTERN:
+ if (!MF_CreatePatternBrush( dc, hbrush, &logbrush )) return 0;
+ break;
+ }
+ return 1; /* FIXME? */
+ }
+#endif
+ dc->w.hBrush = hbrush;
+
+ if (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_NULL:
+ dprintf_gdi( stddeb,"BS_NULL\n" );
+ break;
+
+ case BS_SOLID:
+ dprintf_gdi( stddeb,"BS_SOLID\n" );
+ BRUSH_SelectSolidBrush( dc, brush->logbrush.lbColor );
+ break;
+
+ case BS_HATCHED:
+ dprintf_gdi( stddeb, "BS_HATCHED\n" );
+ 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;
+
+ case BS_PATTERN:
+ dprintf_gdi( stddeb, "BS_PATTERN\n");
+ BRUSH_SelectPatternBrush( dc, (HBRUSH16)brush->logbrush.lbHatch );
+ break;
+
+ case BS_DIBPATTERN:
+ dprintf_gdi( stddeb, "BS_DIBPATTERN\n");
+ if ((bmpInfo = (BITMAPINFO *) GlobalLock16( (HGLOBAL16)brush->logbrush.lbHatch )))
+ {
+ int size = DIB_BitmapInfoSize( bmpInfo, brush->logbrush.lbColor );
+ hBitmap = CreateDIBitmap32( dc->hSelf, &bmpInfo->bmiHeader,
+ CBM_INIT, ((char *)bmpInfo) + size,
+ bmpInfo,
+ (WORD)brush->logbrush.lbColor );
+ BRUSH_SelectPatternBrush( dc, hBitmap );
+ DeleteObject16( hBitmap );
+ GlobalUnlock16( (HGLOBAL16)brush->logbrush.lbHatch );
+ }
+
+ break;
+ }
+
+ return prevHandle;
+}
diff --git a/graphics/x11drv/font.c b/graphics/x11drv/font.c
index 4b816e2..a2f5151 100644
--- a/graphics/x11drv/font.c
+++ b/graphics/x11drv/font.c
@@ -4,9 +4,250 @@
* Copyright 1996 Alexandre Julliard
*/
-#include "windows.h"
-#include "x11drv.h"
-#include "gdi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xatom.h>
+#include "font.h"
+#include "heap.h"
+#include "metafile.h"
+#include "options.h"
+#include "xmalloc.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+struct FontStructure {
+ char *window;
+ char *x11;
+} FontNames[32];
+int FontSize;
+
+
+/***********************************************************************
+ * X11DRV_FONT_Init
+ */
+BOOL32 X11DRV_FONT_Init( void )
+{
+ char temp[1024];
+ LPSTR ptr;
+ int i;
+
+ if (PROFILE_GetWineIniString( "fonts", NULL, "*", temp, sizeof(temp) ) > 2 )
+ {
+ for( ptr = temp, i = 1; strlen(ptr) != 0; ptr += strlen(ptr) + 1 )
+ if( strcmp( ptr, "default" ) )
+ FontNames[i++].window = xstrdup( ptr );
+ FontSize = i;
+
+ for( i = 1; i < FontSize; i++ )
+ {
+ PROFILE_GetWineIniString( "fonts", FontNames[i].window, "*",
+ temp, sizeof(temp) );
+ FontNames[i].x11 = xstrdup( temp );
+ }
+ PROFILE_GetWineIniString( "fonts", "default", "*", temp, sizeof(temp) );
+ FontNames[0].x11 = xstrdup( temp );
+
+ } else {
+ FontNames[0].window = NULL; FontNames[0].x11 = "*-helvetica";
+ FontNames[1].window = "ms sans serif"; FontNames[1].x11 = "*-helvetica";
+ FontNames[2].window = "ms serif"; FontNames[2].x11 = "*-times";
+ FontNames[3].window = "fixedsys"; FontNames[3].x11 = "*-fixed";
+ FontNames[4].window = "arial"; FontNames[4].x11 = "*-helvetica";
+ FontNames[5].window = "helv"; FontNames[5].x11 = "*-helvetica";
+ FontNames[6].window = "roman"; FontNames[6].x11 = "*-times";
+ FontNames[7].window = "system"; FontNames[7].x11 = "*-helvetica";
+ FontSize = 8;
+ }
+ return TRUE;
+}
+/***********************************************************************
+ * FONT_ChkX11Family
+ *
+ * returns a valid X11 equivalent if a Windows face name
+ * is like a X11 family - or NULL if translation is needed
+ */
+static char *FONT_ChkX11Family(char *winFaceName )
+{
+ static char x11fam[32+2]; /* will be returned */
+ int i;
+
+ for(i = 0; lpLogFontList[i] != NULL; i++)
+ if( !lstrcmpi32A(winFaceName, lpLogFontList[i]->lfFaceName) )
+ {
+ strcpy(x11fam,"*-");
+ return strcat(x11fam,winFaceName);
+ }
+ return NULL; /* a FONT_TranslateName() call is needed */
+}
+
+
+
+/***********************************************************************
+ * FONT_TranslateName
+ *
+ * Translate a Windows face name to its X11 equivalent.
+ * This will probably have to be customizable.
+ */
+static const char *FONT_TranslateName( char *winFaceName )
+{
+ int i;
+
+ for (i = 1; i < FontSize; i ++)
+ if( !lstrcmpi32A( winFaceName, FontNames[i].window ) ) {
+ dprintf_font(stddeb, "---- Mapped %s to %s\n", winFaceName, FontNames[i].x11 );
+ return FontNames[i].x11;
+ }
+ return FontNames[0].x11;
+}
+
+
+/***********************************************************************
+ * FONT_MatchFont
+ *
+ * Find a X font matching the logical font.
+ */
+static XFontStruct * FONT_MatchFont( LOGFONT16 * font, DC * dc )
+{
+ char pattern[100];
+ const char *family, *weight, *charset;
+ char **names;
+ char slant, oldspacing, spacing;
+ int width, height, oldheight, count;
+ XFontStruct * fontStruct;
+
+ dprintf_font(stddeb,
+ "FONT_MatchFont(H,W = %d,%d; Weight = %d; Italic = %d; FaceName = '%s'\n",
+ font->lfHeight, font->lfWidth, font->lfWeight, font->lfItalic, font->lfFaceName);
+ weight = (font->lfWeight > 550) ? "bold" : "medium";
+ slant = font->lfItalic ? 'i' : 'r';
+ if (font->lfHeight == -1)
+ height = 0;
+ else
+ height = font->lfHeight * dc->vportExtX / dc->wndExtX;
+ if (height == 0) height = 120; /* Default height = 12 */
+ else if (height < 0)
+ {
+ /* If height is negative, it means the height of the characters */
+ /* *without* the internal leading. So we adjust it a bit to */
+ /* compensate. 5/4 seems to give good results for small fonts. */
+ /*
+ * J.M.: This causes wrong font size for bigger fonts e.g. in Winword & Write
+ height = 10 * (-height * 9 / 8);
+ * may be we have to use an non linear function
+ */
+ /* assume internal leading is 2 pixels. Else small fonts will become
+ * very small. */
+ height = (height-2) * -10;
+ }
+ else height *= 10;
+ width = 10 * (font->lfWidth * dc->vportExtY / dc->wndExtY);
+ if (width < 0) {
+ dprintf_font( stddeb, "FONT_MatchFont: negative width %d(%d)\n",
+ width, font->lfWidth );
+ width = -width;
+ }
+
+ spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
+ (font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
+
+
+ charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*-*";
+ if (*font->lfFaceName) {
+ family = FONT_ChkX11Family(font->lfFaceName);
+ /*--do _not_ translate if lfFaceName is family from X11 A.K.*/
+ if (!family)
+ family = FONT_TranslateName( font->lfFaceName );
+ /* FIX ME: I don't if that's correct but it works J.M. */
+ spacing = '*';
+ }
+ else switch(font->lfPitchAndFamily & 0xf0)
+ {
+ case FF_ROMAN:
+ family = FONT_TranslateName( "roman" );
+ break;
+ case FF_SWISS:
+ family = FONT_TranslateName( "swiss" );
+ break;
+ case FF_MODERN:
+ family = FONT_TranslateName( "modern" );
+ break;
+ case FF_SCRIPT:
+ family = FONT_TranslateName( "script" );
+ break;
+ case FF_DECORATIVE:
+ family = FONT_TranslateName( "decorative" );
+ break;
+ default:
+ family = "*-*";
+ break;
+ }
+ sprintf( pattern, "-%s-%s-*-normal-*-*-*-*-*-*-*-%s",
+ family, weight, charset);
+ dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
+ names = XListFonts( display, pattern, 1, &count );
+ if (names) XFreeFontNames( names );
+ else
+ {
+ if (strcmp(family, "*-*") == 0)
+ {
+ fprintf(stderr, "FONT_MatchFont(%s) : returning NULL\n", pattern);
+ return NULL;
+ }
+ else family = "*-*";
+ }
+ oldheight = height;
+ oldspacing = spacing;
+ while (TRUE) {
+ /* 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);
+ dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
+ names = XListFonts( display, pattern, 1, &count );
+ if (count > 0) break;
+ if (spacing == 'm') /* try 'c' if no 'm' found */ {
+
+ spacing = 'c';
+ continue;
+ } else if (spacing == 'p') /* try '*' if no 'p' found */ {
+ spacing = '*';
+ continue;
+ }
+ spacing = oldspacing;
+ height -= 10;
+ if (height < 10) {
+ if (slant == 'i') {
+ /* try oblique if no italic font */
+ slant = 'o';
+ height = oldheight;
+ continue;
+ }
+ if (spacing == 'm' && strcmp(family, "*-*") != 0) {
+ /* If a fixed spacing font could not be found, ignore
+ * the family */
+ family = "*-*";
+ height = oldheight;
+ continue;
+ }
+ fprintf(stderr, "FONT_MatchFont(%s) : returning NULL\n", pattern);
+ return NULL;
+ }
+ }
+ dprintf_font(stddeb," Found '%s'\n", *names );
+ if (!*font->lfFaceName)
+ FONT_ParseFontParms(*names, 2, font->lfFaceName , LF_FACESIZE-1);
+ /* we need a font name for function GetTextFace() even if there isn't one ;-) */
+
+ fontStruct = XLoadQueryFont( display, *names );
+ XFreeFontNames( names );
+ return fontStruct;
+}
+
/***********************************************************************
* X11DRV_GetTextExtentPoint
@@ -62,4 +303,156 @@
}
+/***********************************************************************
+ * X11DRV_FONT_SelectObject
+ */
+HFONT32 X11DRV_FONT_SelectObject( DC * dc, HFONT32 hfont, FONTOBJ * font )
+{
+ static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
+ static struct {
+ HFONT32 id;
+ LOGFONT16 logfont;
+ int access;
+ int used;
+ X_PHYSFONT cacheFont; } cacheFonts[FONTCACHE], *cacheFontsMin;
+ int i;
+
+ X_PHYSFONT * stockPtr;
+ HFONT32 prevHandle = dc->w.hFont;
+ XFontStruct * fontStruct;
+ dprintf_font(stddeb,"FONT_SelectObject(%p, %04x, %p)\n", dc, hfont, font);
+
+#if 0 /* From the code in SelectObject, this can not happen */
+ /* Load font if necessary */
+ if (!font)
+ {
+ HFONT16 hnewfont;
+
+ hnewfont = CreateFont16(10, 7, 0, 0, FW_DONTCARE,
+ FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
+ DEFAULT_QUALITY, FF_DONTCARE, "*" );
+ font = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hnewfont );
+ }
+#endif
+
+ if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
+ stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT];
+ else {
+ stockPtr = NULL;
+ /*
+ * Ok, It's not a stock font but
+ * may be it's cached in dynamic cache
+ */
+ for(i=0; i<FONTCACHE; i++) /* search for same handle */
+ if (cacheFonts[i].id==hfont) { /* Got the handle */
+ /*
+ * Check if Handle matches the font
+ */
+ if(memcmp(&cacheFonts[i].logfont,&(font->logfont), sizeof(LOGFONT16))) {
+ /* No: remove handle id from dynamic font cache */
+ cacheFonts[i].access=0;
+ cacheFonts[i].used=0;
+ cacheFonts[i].id=0;
+ /* may be there is an unused handle which contains the font */
+ for(i=0; i<FONTCACHE; i++) {
+ if((cacheFonts[i].used == 0) &&
+ (memcmp(&cacheFonts[i].logfont,&(font->logfont), sizeof(LOGFONT16)))== 0) {
+ /* got it load from cache and set new handle id */
+ stockPtr = &cacheFonts[i].cacheFont;
+ cacheFonts[i].access=1;
+ cacheFonts[i].used=1;
+ cacheFonts[i].id=hfont;
+ dprintf_font(stddeb,"FONT_SelectObject: got font from unused handle\n");
+ break;
+ }
+ }
+
+ }
+ else {
+ /* Yes: load from dynamic font cache */
+ stockPtr = &cacheFonts[i].cacheFont;
+ cacheFonts[i].access++;
+ cacheFonts[i].used++;
+ }
+ break;
+ }
+ }
+ if (!stockPtr || !stockPtr->fstruct)
+ {
+ if (!(fontStruct = FONT_MatchFont( &font->logfont, dc )))
+ {
+ /* If it is not a stock font, we can simply return 0 */
+ if (!stockPtr) return 0;
+ /* Otherwise we must try to find a substitute */
+ dprintf_font(stddeb,"Loading font 'fixed' for %04x\n", hfont );
+ font->logfont.lfPitchAndFamily &= ~VARIABLE_PITCH;
+ font->logfont.lfPitchAndFamily |= FIXED_PITCH;
+ fontStruct = XLoadQueryFont( display, "fixed" );
+ if (!fontStruct)
+ {
+ fprintf( stderr, "No system font could be found. Please check your font path.\n" );
+ exit( 1 );
+ }
+ }
+ }
+ else
+ {
+ fontStruct = stockPtr->fstruct;
+ dprintf_font(stddeb,
+ "FONT_SelectObject: Loaded font from cache %04x %p\n",
+ hfont, fontStruct );
+ }
+
+ /* Unuse previous font */
+ for (i=0; i < FONTCACHE; i++) {
+ if (cacheFonts[i].id == prevHandle) {
+ if(cacheFonts[i].used == 0)
+ fprintf(stderr, "Trying to decrement a use count of 0.\n");
+ else
+ cacheFonts[i].used--;
+ }
+ }
+
+ /* Store font */
+ dc->w.hFont = hfont;
+ if (stockPtr)
+ {
+ if (!stockPtr->fstruct)
+ {
+ stockPtr->fstruct = fontStruct;
+ FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
+ }
+ memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
+ }
+ else
+ {
+ /*
+ * Check in cacheFont
+ */
+ cacheFontsMin=NULL;
+ for (i=0; i < FONTCACHE; i++) {
+ if (cacheFonts[i].used==0)
+ if ((!cacheFontsMin) || ((cacheFontsMin) && (cacheFontsMin->access > cacheFonts[i].access)))
+ cacheFontsMin=&cacheFonts[i];
+ }
+ if (!cacheFontsMin) {
+ fprintf(stderr,"No unused font cache entry !!!!\n" );
+ return prevHandle;
+ }
+ if (cacheFontsMin->id!=0) {
+ dprintf_font(stddeb,
+ "FONT_SelectObject: Freeing %04x \n",cacheFontsMin->id );
+ XFreeFont( display, cacheFontsMin->cacheFont.fstruct );
+ }
+ cacheFontsMin->cacheFont.fstruct = fontStruct;
+ FONT_GetMetrics( &font->logfont, fontStruct, &cacheFontsMin->cacheFont.metrics );
+ cacheFontsMin->access=1;
+ cacheFontsMin->used=1;
+ cacheFontsMin->id=hfont;
+ memcpy( &dc->u.x.font, &(cacheFontsMin->cacheFont), sizeof(cacheFontsMin->cacheFont) );
+ memcpy(&cacheFontsMin->logfont,&(font->logfont), sizeof(LOGFONT16));
+
+ }
+ return prevHandle;
+}
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index a7fd361..6f34f63 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -52,7 +52,7 @@
NULL, /* pScaleViewportExt (optional) */
NULL, /* pScaleWindowExt (optional) */
NULL, /* pSelectClipRgn */
- NULL, /* pSelectObject */
+ X11DRV_SelectObject, /* pSelectObject */
NULL, /* pSelectPalette */
NULL, /* pSetBkColor */
NULL, /* pSetBkMode */
@@ -84,6 +84,18 @@
*/
BOOL32 X11DRV_Init(void)
{
+ /* Create default bitmap */
+
+ if (!X11DRV_BITMAP_Init()) return FALSE;
+
+ /* Initialize brush dithering */
+
+ if (!X11DRV_BRUSH_Init()) return FALSE;
+
+ /* Initialize fonts */
+
+ if (!X11DRV_FONT_Init()) return FALSE;
+
return DRIVER_RegisterDriver( "DISPLAY", &X11DRV_Funcs );
}
diff --git a/graphics/x11drv/objects.c b/graphics/x11drv/objects.c
new file mode 100644
index 0000000..fb2f0b8
--- /dev/null
+++ b/graphics/x11drv/objects.c
@@ -0,0 +1,50 @@
+/*
+ * GDI objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "bitmap.h"
+#include "brush.h"
+#include "font.h"
+#include "pen.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+extern HBITMAP32 X11DRV_BITMAP_SelectObject( DC * dc, HBITMAP32 hbitmap,
+ BITMAPOBJ * bmp );
+extern HBRUSH32 X11DRV_BRUSH_SelectObject( DC * dc, HBRUSH32 hbrush,
+ BRUSHOBJ * brush );
+extern HFONT32 X11DRV_FONT_SelectObject( DC * dc, HFONT32 hfont,
+ FONTOBJ * font );
+extern HPEN32 X11DRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen );
+
+
+/***********************************************************************
+ * X11DRV_SelectObject
+ */
+HGDIOBJ32 X11DRV_SelectObject( DC *dc, HGDIOBJ32 handle )
+{
+ GDIOBJHDR *ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
+
+ if (!ptr) return 0;
+ dprintf_gdi(stddeb, "SelectObject: hdc=%04x %04x\n", dc->hSelf, handle );
+
+ switch(ptr->wMagic)
+ {
+ case PEN_MAGIC:
+ return X11DRV_PEN_SelectObject( dc, handle, (PENOBJ *)ptr );
+ case BRUSH_MAGIC:
+ return X11DRV_BRUSH_SelectObject( dc, handle, (BRUSHOBJ *)ptr );
+ case BITMAP_MAGIC:
+ return X11DRV_BITMAP_SelectObject( dc, handle, (BITMAPOBJ *)ptr );
+ case FONT_MAGIC:
+ return X11DRV_FONT_SelectObject( dc, handle, (FONTOBJ *)ptr );
+ case REGION_MAGIC:
+ return (HGDIOBJ16)SelectClipRgn16( dc->hSelf, handle );
+ }
+ return 0;
+}
diff --git a/graphics/x11drv/pen.c b/graphics/x11drv/pen.c
new file mode 100644
index 0000000..8516569
--- /dev/null
+++ b/graphics/x11drv/pen.c
@@ -0,0 +1,51 @@
+/*
+ * GDI pen objects
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#include "pen.h"
+#include "color.h"
+#include "stddebug.h"
+#include "debug.h"
+
+static const char PEN_dash[] = { 5,3 }; /* ----- ----- ----- */
+static const char PEN_dot[] = { 1,1 }; /* -- -- -- -- -- -- */
+static const char PEN_dashdot[] = { 4,3,2,3 }; /* ---- -- ---- -- */
+static const char PEN_dashdotdot[] = { 4,2,2,2,2,2 }; /* ---- -- -- ---- */
+
+/***********************************************************************
+ * PEN_SelectObject
+ */
+HPEN32 X11DRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen )
+{
+ HPEN32 prevHandle = dc->w.hPen;
+
+ dc->w.hPen = hpen;
+ dc->u.x.pen.style = pen->logpen.lopnStyle;
+ dc->u.x.pen.width = pen->logpen.lopnWidth.x * dc->vportExtX / dc->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 = COLOR_ToPhysical( dc, pen->logpen.lopnColor );
+ switch(pen->logpen.lopnStyle)
+ {
+ case PS_DASH:
+ dc->u.x.pen.dashes = (char *)PEN_dash;
+ dc->u.x.pen.dash_len = 2;
+ break;
+ case PS_DOT:
+ dc->u.x.pen.dashes = (char *)PEN_dot;
+ dc->u.x.pen.dash_len = 2;
+ break;
+ case PS_DASHDOT:
+ dc->u.x.pen.dashes = (char *)PEN_dashdot;
+ dc->u.x.pen.dash_len = 4;
+ break;
+ case PS_DASHDOTDOT:
+ dc->u.x.pen.dashes = (char *)PEN_dashdotdot;
+ dc->u.x.pen.dash_len = 6;
+ break;
+ }
+
+ return prevHandle;
+}