From 38aa9a941b6a2073ec728782359997b4902763ab Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Wed, 14 Jul 1999 23:30:15 +0000 Subject: [PATCH] Implement it. Obscure bit manipulation needed. * gdk/win32/gdkcursor.c (gdk_cursor_new_from_pixmap): Implement it. Obscure bit manipulation needed. * gdk/win32/gdkevents.c: Logging. * gtk/gtkthemes.c (gtk_theme_engine_get): (Win32) Use new DLL naming style (file name include compiler name) for theme engines. --- ChangeLog | 10 +++ ChangeLog.pre-2-0 | 10 +++ ChangeLog.pre-2-10 | 10 +++ ChangeLog.pre-2-2 | 10 +++ ChangeLog.pre-2-4 | 10 +++ ChangeLog.pre-2-6 | 10 +++ ChangeLog.pre-2-8 | 10 +++ README.win32 | 9 ++- gdk/win32/gdkcursor-win32.c | 151 +++++++++++++++++++++++------------- gdk/win32/gdkcursor.c | 151 +++++++++++++++++++++++------------- gdk/win32/gdkevents-win32.c | 11 ++- gdk/win32/gdkevents.c | 11 ++- gtk/gtkthemes.c | 12 +++ 13 files changed, 301 insertions(+), 114 deletions(-) diff --git a/ChangeLog b/ChangeLog index a897bfacd..8f55b67e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +1999-07-15 Tor Lillqvist + + * gdk/win32/gdkcursor.c (gdk_cursor_new_from_pixmap): Implement + it. Obscure bit manipulation needed. + + * gdk/win32/gdkevents.c: Logging. + + * gtk/gtkthemes.c (gtk_theme_engine_get): (Win32) Use new DLL naming + style (file name include compiler name) for theme engines. + 1999-07-13 Tor Lillqvist * gdk/win32/gdkdraw.c (gdk_draw_pixmap): Less logging verbiage. diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index a897bfacd..8f55b67e8 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,13 @@ +1999-07-15 Tor Lillqvist + + * gdk/win32/gdkcursor.c (gdk_cursor_new_from_pixmap): Implement + it. Obscure bit manipulation needed. + + * gdk/win32/gdkevents.c: Logging. + + * gtk/gtkthemes.c (gtk_theme_engine_get): (Win32) Use new DLL naming + style (file name include compiler name) for theme engines. + 1999-07-13 Tor Lillqvist * gdk/win32/gdkdraw.c (gdk_draw_pixmap): Less logging verbiage. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index a897bfacd..8f55b67e8 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,13 @@ +1999-07-15 Tor Lillqvist + + * gdk/win32/gdkcursor.c (gdk_cursor_new_from_pixmap): Implement + it. Obscure bit manipulation needed. + + * gdk/win32/gdkevents.c: Logging. + + * gtk/gtkthemes.c (gtk_theme_engine_get): (Win32) Use new DLL naming + style (file name include compiler name) for theme engines. + 1999-07-13 Tor Lillqvist * gdk/win32/gdkdraw.c (gdk_draw_pixmap): Less logging verbiage. diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index a897bfacd..8f55b67e8 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,13 @@ +1999-07-15 Tor Lillqvist + + * gdk/win32/gdkcursor.c (gdk_cursor_new_from_pixmap): Implement + it. Obscure bit manipulation needed. + + * gdk/win32/gdkevents.c: Logging. + + * gtk/gtkthemes.c (gtk_theme_engine_get): (Win32) Use new DLL naming + style (file name include compiler name) for theme engines. + 1999-07-13 Tor Lillqvist * gdk/win32/gdkdraw.c (gdk_draw_pixmap): Less logging verbiage. diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index a897bfacd..8f55b67e8 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,13 @@ +1999-07-15 Tor Lillqvist + + * gdk/win32/gdkcursor.c (gdk_cursor_new_from_pixmap): Implement + it. Obscure bit manipulation needed. + + * gdk/win32/gdkevents.c: Logging. + + * gtk/gtkthemes.c (gtk_theme_engine_get): (Win32) Use new DLL naming + style (file name include compiler name) for theme engines. + 1999-07-13 Tor Lillqvist * gdk/win32/gdkdraw.c (gdk_draw_pixmap): Less logging verbiage. diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index a897bfacd..8f55b67e8 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,13 @@ +1999-07-15 Tor Lillqvist + + * gdk/win32/gdkcursor.c (gdk_cursor_new_from_pixmap): Implement + it. Obscure bit manipulation needed. + + * gdk/win32/gdkevents.c: Logging. + + * gtk/gtkthemes.c (gtk_theme_engine_get): (Win32) Use new DLL naming + style (file name include compiler name) for theme engines. + 1999-07-13 Tor Lillqvist * gdk/win32/gdkdraw.c (gdk_draw_pixmap): Less logging verbiage. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index a897bfacd..8f55b67e8 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,13 @@ +1999-07-15 Tor Lillqvist + + * gdk/win32/gdkcursor.c (gdk_cursor_new_from_pixmap): Implement + it. Obscure bit manipulation needed. + + * gdk/win32/gdkevents.c: Logging. + + * gtk/gtkthemes.c (gtk_theme_engine_get): (Win32) Use new DLL naming + style (file name include compiler name) for theme engines. + 1999-07-13 Tor Lillqvist * gdk/win32/gdkdraw.c (gdk_draw_pixmap): Less logging verbiage. diff --git a/README.win32 b/README.win32 index 0fa3a3f26..94c592d4b 100644 --- a/README.win32 +++ b/README.win32 @@ -4,10 +4,11 @@ port, see http://www.gimp.org/tml/gimp/win32/ or http://www.iki.fi/tml/gimp/win32/ . To build GTk+ on Win32, you need either Microsoft compiler and tools, -or egcs-1.1.2 running under cygwin-b20.1. Compile in gdk\win32 and gtk -with `nmake -f makefile.msc` or `make -f makefile.cygwin`. Before -doing a install, check the BIN definition in gdk\win32\makefile.msc -(or makefile.cygwin) and gtk\makefile.msc (or makefile.cygwin). +or egcs-1.1.2 (or gcc-2.95 or later) running under +cygwin-b20.1. Compile in gdk\win32 and gtk with `nmake -f +makefile.msc` or `make -f makefile.cygwin`. Before doing a install, +check the BIN definition in gdk\win32\makefile.msc (or +makefile.cygwin) and gtk\makefile.msc (or makefile.cygwin). See the README.win32 file in the GLib distribution for preparations to build with egcs on cygwin. diff --git a/gdk/win32/gdkcursor-win32.c b/gdk/win32/gdkcursor-win32.c index c5482c92b..fe4e1638a 100644 --- a/gdk/win32/gdkcursor-win32.c +++ b/gdk/win32/gdkcursor-win32.c @@ -138,77 +138,118 @@ gdk_cursor_new (GdkCursorType cursor_type) } GdkCursor* -gdk_cursor_new_from_pixmap (GdkPixmap *source, GdkPixmap *mask, GdkColor *fg, GdkColor *bg, gint x, gint y) +gdk_cursor_new_from_pixmap (GdkPixmap *source, + GdkPixmap *mask, + GdkColor *fg, + GdkColor *bg, + gint x, + gint y) { -#if 0 /* I don't understand cursors, sigh */ GdkCursorPrivate *private; GdkCursor *cursor; - GdkPixmap *s2; GdkPixmapPrivate *source_private, *mask_private; - GdkPixmapPrivate *s2_private; - GdkGC *gc; - ICONINFO iconinfo; + GdkImage *source_image, *mask_image; HCURSOR xcursor; - HBITMAP invmask; - HDC hdc1, hdc2; - HGDIOBJ oldbm1, oldbm2; + guchar *p, *q, *XORmask, *ANDmask; + gint width, height, width32, height32; + guchar residue; + gint ix, iy; + g_return_val_if_fail (source != NULL, NULL); + g_return_val_if_fail (mask != NULL, NULL); + source_private = (GdkPixmapPrivate *) source; mask_private = (GdkPixmapPrivate *) mask; - s2 = gdk_pixmap_new (source, source_private->width, source_private->height, 1); - gc = gdk_gc_new (s2); - gdk_gc_set_foreground (gc, fg); - gdk_gc_set_background (gc, bg); - gdk_draw_pixmap (s2, gc, source, 0, 0, 0, 0, - source_private->width, source_private->height); - gdk_gc_unref (gc); - - iconinfo.fIcon = FALSE; - iconinfo.xHotspot = x; - iconinfo.yHotspot = y; -#if 1 - invmask = CreateBitmap (mask_private->width, mask_private->height, 1, 1, NULL); - hdc1 = CreateCompatibleDC (gdk_DC); - oldbm1 = SelectObject (hdc1, invmask); - hdc2 = CreateCompatibleDC (gdk_DC); - oldbm2 = SelectObject (hdc2, mask_private->xwindow); - BitBlt (hdc1, 0, 0, mask_private->width, mask_private->height, hdc2, 0, 0, NOTSRCCOPY); - SelectObject (hdc2, oldbm2); - DeleteDC (hdc2); - SelectObject (hdc1, oldbm1); - DeleteDC (hdc1); - iconinfo.hbmMask = invmask; -#else - iconinfo.hbmMask = mask_private->xwindow;; -#endif - iconinfo.hbmColor = ((GdkPixmapPrivate *) s2)->xwindow; - - if ((xcursor = CreateIconIndirect (&iconinfo)) == NULL) + g_return_val_if_fail (source_private->width == mask_private->width + && source_private->height == mask_private->height, + NULL); + width = source_private->width; + height = source_private->height; + width32 = ((width-1)/32+1)*32; + height32 = ((height-1)/32+1)*32; + + residue = (1 << ((8-(width%8))%8)) - 1; + + source_image = gdk_image_get (source, 0, 0, width, height); + mask_image = gdk_image_get (mask, 0, 0, width, height); + + if (source_image->depth != 1 || mask_image->depth != 1) { - g_warning ("gdk_cursor_new_from_private: CreateIconIndirect failed"); - gdk_pixmap_unref (s2); - return gdk_cursor_new (GDK_PIRATE); + gdk_image_destroy (source_image); + gdk_image_destroy (mask_image); + g_return_val_if_fail (source_image->depth == 1 && mask_image->depth == 1, + NULL); } - GDK_NOTE (MISC, - g_print ("gdk_cursor_new_from_private: %#x (%dx%d) %#x (%dx%d) = %#x\n", - source_private->xwindow, - source_private->width, source_private->height, - mask_private->xwindow, - mask_private->width, mask_private->height, - xcursor)); + /* Such complex bit manipulation for this simple task, sigh. + * The X cursor and Windows cursor concepts are quite different. + * We assume here that we are always called with fg == black and + * bg == white. + */ + + /* First set masked-out source bits, as all source bits matter on Windoze. + * As we invert them below, they will be clear in the final XORmask. + */ + for (iy = 0; iy < height; iy++) + { + p = source_image->mem + iy*source_image->bpl; + q = mask_image->mem + iy*mask_image->bpl; + + for (ix = 0; ix < ((width-1)/8+1); ix++) + *p++ |= ~(*q++); + } + + /* XOR mask is initialized to zero */ + XORmask = g_malloc0 (width32/8 * height32); + + for (iy = 0; iy < height; iy++) + { + p = source_image->mem + iy*source_image->bpl; + q = XORmask + iy*width32/8; + + for (ix = 0; ix < ((width-1)/8+1); ix++) + *q++ = ~(*p++); + q[-1] &= ~residue; /* Clear left-over bits */ + } + + /* AND mask is initialized to ones */ + ANDmask = g_malloc (width32/8 * height32); + memset (ANDmask, 0xFF, width32/8 * height32); + + for (iy = 0; iy < height; iy++) + { + p = mask_image->mem + iy*mask_image->bpl; + q = ANDmask + iy*width32/8; + + for (ix = 0; ix < ((width-1)/8+1); ix++) + *q++ = ~(*p++); + q[-1] |= residue; /* Set left-over bits */ + } + + xcursor = CreateCursor (gdk_ProgInstance, x, y, width32, height32, + ANDmask, XORmask); + + GDK_NOTE (MISC, g_print ("gdk_cursor_new_from_pixmap: " + "%#x (%dx%d) %#x (%dx%d) = %#x (%dx%d)\n", + source_private->xwindow, + source_private->width, source_private->height, + mask_private->xwindow, + mask_private->width, mask_private->height, + xcursor, width32, height32)); + + g_free (XORmask); + g_free (ANDmask); + + gdk_image_destroy (source_image); + gdk_image_destroy (mask_image); - gdk_pixmap_unref (s2); private = g_new (GdkCursorPrivate, 1); private->xcursor = xcursor; cursor = (GdkCursor*) private; cursor->type = GDK_CURSOR_IS_PIXMAP; return cursor; -#else /* Just return some cursor ;-) */ - return gdk_cursor_new (GDK_PIRATE); -#endif } void @@ -219,8 +260,12 @@ gdk_cursor_destroy (GdkCursor *cursor) g_return_if_fail (cursor != NULL); private = (GdkCursorPrivate *) cursor; + GDK_NOTE (MISC, g_print ("gdk_cursor_destroy: %#x\n", + (cursor->type == GDK_CURSOR_IS_PIXMAP) ? private->xcursor : 0)); + if (cursor->type == GDK_CURSOR_IS_PIXMAP) - DestroyIcon (private->xcursor); + if (!DestroyIcon (private->xcursor)) + g_warning ("gdk_cursor_destroy: DestroyIcon failed"); g_free (private); } diff --git a/gdk/win32/gdkcursor.c b/gdk/win32/gdkcursor.c index c5482c92b..fe4e1638a 100644 --- a/gdk/win32/gdkcursor.c +++ b/gdk/win32/gdkcursor.c @@ -138,77 +138,118 @@ gdk_cursor_new (GdkCursorType cursor_type) } GdkCursor* -gdk_cursor_new_from_pixmap (GdkPixmap *source, GdkPixmap *mask, GdkColor *fg, GdkColor *bg, gint x, gint y) +gdk_cursor_new_from_pixmap (GdkPixmap *source, + GdkPixmap *mask, + GdkColor *fg, + GdkColor *bg, + gint x, + gint y) { -#if 0 /* I don't understand cursors, sigh */ GdkCursorPrivate *private; GdkCursor *cursor; - GdkPixmap *s2; GdkPixmapPrivate *source_private, *mask_private; - GdkPixmapPrivate *s2_private; - GdkGC *gc; - ICONINFO iconinfo; + GdkImage *source_image, *mask_image; HCURSOR xcursor; - HBITMAP invmask; - HDC hdc1, hdc2; - HGDIOBJ oldbm1, oldbm2; + guchar *p, *q, *XORmask, *ANDmask; + gint width, height, width32, height32; + guchar residue; + gint ix, iy; + g_return_val_if_fail (source != NULL, NULL); + g_return_val_if_fail (mask != NULL, NULL); + source_private = (GdkPixmapPrivate *) source; mask_private = (GdkPixmapPrivate *) mask; - s2 = gdk_pixmap_new (source, source_private->width, source_private->height, 1); - gc = gdk_gc_new (s2); - gdk_gc_set_foreground (gc, fg); - gdk_gc_set_background (gc, bg); - gdk_draw_pixmap (s2, gc, source, 0, 0, 0, 0, - source_private->width, source_private->height); - gdk_gc_unref (gc); - - iconinfo.fIcon = FALSE; - iconinfo.xHotspot = x; - iconinfo.yHotspot = y; -#if 1 - invmask = CreateBitmap (mask_private->width, mask_private->height, 1, 1, NULL); - hdc1 = CreateCompatibleDC (gdk_DC); - oldbm1 = SelectObject (hdc1, invmask); - hdc2 = CreateCompatibleDC (gdk_DC); - oldbm2 = SelectObject (hdc2, mask_private->xwindow); - BitBlt (hdc1, 0, 0, mask_private->width, mask_private->height, hdc2, 0, 0, NOTSRCCOPY); - SelectObject (hdc2, oldbm2); - DeleteDC (hdc2); - SelectObject (hdc1, oldbm1); - DeleteDC (hdc1); - iconinfo.hbmMask = invmask; -#else - iconinfo.hbmMask = mask_private->xwindow;; -#endif - iconinfo.hbmColor = ((GdkPixmapPrivate *) s2)->xwindow; - - if ((xcursor = CreateIconIndirect (&iconinfo)) == NULL) + g_return_val_if_fail (source_private->width == mask_private->width + && source_private->height == mask_private->height, + NULL); + width = source_private->width; + height = source_private->height; + width32 = ((width-1)/32+1)*32; + height32 = ((height-1)/32+1)*32; + + residue = (1 << ((8-(width%8))%8)) - 1; + + source_image = gdk_image_get (source, 0, 0, width, height); + mask_image = gdk_image_get (mask, 0, 0, width, height); + + if (source_image->depth != 1 || mask_image->depth != 1) { - g_warning ("gdk_cursor_new_from_private: CreateIconIndirect failed"); - gdk_pixmap_unref (s2); - return gdk_cursor_new (GDK_PIRATE); + gdk_image_destroy (source_image); + gdk_image_destroy (mask_image); + g_return_val_if_fail (source_image->depth == 1 && mask_image->depth == 1, + NULL); } - GDK_NOTE (MISC, - g_print ("gdk_cursor_new_from_private: %#x (%dx%d) %#x (%dx%d) = %#x\n", - source_private->xwindow, - source_private->width, source_private->height, - mask_private->xwindow, - mask_private->width, mask_private->height, - xcursor)); + /* Such complex bit manipulation for this simple task, sigh. + * The X cursor and Windows cursor concepts are quite different. + * We assume here that we are always called with fg == black and + * bg == white. + */ + + /* First set masked-out source bits, as all source bits matter on Windoze. + * As we invert them below, they will be clear in the final XORmask. + */ + for (iy = 0; iy < height; iy++) + { + p = source_image->mem + iy*source_image->bpl; + q = mask_image->mem + iy*mask_image->bpl; + + for (ix = 0; ix < ((width-1)/8+1); ix++) + *p++ |= ~(*q++); + } + + /* XOR mask is initialized to zero */ + XORmask = g_malloc0 (width32/8 * height32); + + for (iy = 0; iy < height; iy++) + { + p = source_image->mem + iy*source_image->bpl; + q = XORmask + iy*width32/8; + + for (ix = 0; ix < ((width-1)/8+1); ix++) + *q++ = ~(*p++); + q[-1] &= ~residue; /* Clear left-over bits */ + } + + /* AND mask is initialized to ones */ + ANDmask = g_malloc (width32/8 * height32); + memset (ANDmask, 0xFF, width32/8 * height32); + + for (iy = 0; iy < height; iy++) + { + p = mask_image->mem + iy*mask_image->bpl; + q = ANDmask + iy*width32/8; + + for (ix = 0; ix < ((width-1)/8+1); ix++) + *q++ = ~(*p++); + q[-1] |= residue; /* Set left-over bits */ + } + + xcursor = CreateCursor (gdk_ProgInstance, x, y, width32, height32, + ANDmask, XORmask); + + GDK_NOTE (MISC, g_print ("gdk_cursor_new_from_pixmap: " + "%#x (%dx%d) %#x (%dx%d) = %#x (%dx%d)\n", + source_private->xwindow, + source_private->width, source_private->height, + mask_private->xwindow, + mask_private->width, mask_private->height, + xcursor, width32, height32)); + + g_free (XORmask); + g_free (ANDmask); + + gdk_image_destroy (source_image); + gdk_image_destroy (mask_image); - gdk_pixmap_unref (s2); private = g_new (GdkCursorPrivate, 1); private->xcursor = xcursor; cursor = (GdkCursor*) private; cursor->type = GDK_CURSOR_IS_PIXMAP; return cursor; -#else /* Just return some cursor ;-) */ - return gdk_cursor_new (GDK_PIRATE); -#endif } void @@ -219,8 +260,12 @@ gdk_cursor_destroy (GdkCursor *cursor) g_return_if_fail (cursor != NULL); private = (GdkCursorPrivate *) cursor; + GDK_NOTE (MISC, g_print ("gdk_cursor_destroy: %#x\n", + (cursor->type == GDK_CURSOR_IS_PIXMAP) ? private->xcursor : 0)); + if (cursor->type == GDK_CURSOR_IS_PIXMAP) - DestroyIcon (private->xcursor); + if (!DestroyIcon (private->xcursor)) + g_warning ("gdk_cursor_destroy: DestroyIcon failed"); g_free (private); } diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 9d1a9a0b7..d5b1dbfca 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -2475,11 +2475,18 @@ gdk_event_translate (GdkEvent *event, if (LOWORD (xevent->lParam) != HTCLIENT) break; if (p_grab_window != NULL && p_grab_cursor != NULL) - SetCursor (p_grab_cursor); + { + GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", p_grab_cursor)); + SetCursor (p_grab_cursor); + } else if (window_private && !window_private->destroyed && window_private->xcursor) - SetCursor (window_private->xcursor); + { + GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", + window_private->xcursor)); + SetCursor (window_private->xcursor); + } *ret_val_flagp = TRUE; *ret_valp = FALSE; break; diff --git a/gdk/win32/gdkevents.c b/gdk/win32/gdkevents.c index 9d1a9a0b7..d5b1dbfca 100644 --- a/gdk/win32/gdkevents.c +++ b/gdk/win32/gdkevents.c @@ -2475,11 +2475,18 @@ gdk_event_translate (GdkEvent *event, if (LOWORD (xevent->lParam) != HTCLIENT) break; if (p_grab_window != NULL && p_grab_cursor != NULL) - SetCursor (p_grab_cursor); + { + GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", p_grab_cursor)); + SetCursor (p_grab_cursor); + } else if (window_private && !window_private->destroyed && window_private->xcursor) - SetCursor (window_private->xcursor); + { + GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", + window_private->xcursor)); + SetCursor (window_private->xcursor); + } *ret_val_flagp = TRUE; *ret_valp = FALSE; break; diff --git a/gtk/gtkthemes.c b/gtk/gtkthemes.c index e39646de8..6ac188806 100644 --- a/gtk/gtkthemes.c +++ b/gtk/gtkthemes.c @@ -83,7 +83,19 @@ gtk_theme_engine_get (gchar *name) GModule *library; #ifndef __EMX__ +#if defined (NATIVE_WIN32) && defined (__GNUC__) + { + /* When built with gcc on Win32, use DLLs named *.gcc.dll, + * because MSVC-compiled GTK code is not fully binary compatible + * with gcc-compiled. + */ + gchar *gccname = g_strconcat (name, ".gcc", NULL); + fullname = g_module_build_path (NULL, gccname); + g_free (gccname); + } +#else fullname = g_module_build_path (NULL, name); +#endif #else fullname = g_malloc (13); gen_8_3_dll_name(name, fullname); -- 2.43.2