Win32 version of GDK source files and resource files (cursors and icons).

This commit is contained in:
Tor Lillqvist 1999-03-05 19:53:56 +00:00
parent ced58eb136
commit 9f3b82e178
127 changed files with 46985 additions and 0 deletions

2237
gdk/win32/gdk.c Normal file

File diff suppressed because it is too large Load Diff

1033
gdk/win32/gdk.h Normal file

File diff suppressed because it is too large Load Diff

1610
gdk/win32/gdkcc.c Normal file

File diff suppressed because it is too large Load Diff

2443
gdk/win32/gdkcolor-win32.c Normal file

File diff suppressed because it is too large Load Diff

2443
gdk/win32/gdkcolor.c Normal file

File diff suppressed because it is too large Load Diff

226
gdk/win32/gdkcursor-win32.c Normal file
View File

@ -0,0 +1,226 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
static const struct { const char *name; int type; } cursors[] = {
{ "x_cursor", 0 },
{ "arrow", 2 },
{ "based_arrow_down", 4 },
{ "based_arrow_up", 6 },
{ "boat", 8 },
{ "bogosity", 10 },
{ "bottom_left_corner", 12 },
{ "bottom_right_corner", 14 },
{ "bottom_side", 16 },
{ "bottom_tee", 18 },
{ "box_spiral", 20 },
{ "center_ptr", 22 },
{ "circle", 24 },
{ "clock", 26 },
{ "coffee_mug", 28 },
{ "cross", 30 },
{ "cross_reverse", 32 },
{ "crosshair", 34 },
{ "diamond_cross", 36 },
{ "dot", 38 },
{ "dotbox", 40 },
{ "double_arrow", 42 },
{ "draft_large", 44 },
{ "draft_small", 46 },
{ "draped_box", 48 },
{ "exchange", 50 },
{ "fleur", 52 },
{ "gobbler", 54 },
{ "gumby", 56 },
{ "hand1", 58 },
{ "hand2", 60 },
{ "heart", 62 },
{ "icon", 64 },
{ "iron_cross", 66 },
{ "left_ptr", 68 },
{ "left_side", 70 },
{ "left_tee", 72 },
{ "leftbutton", 74 },
{ "ll_angle", 76 },
{ "lr_angle", 78 },
{ "man", 80 },
{ "middlebutton", 82 },
{ "mouse", 84 },
{ "pencil", 86 },
{ "pirate", 88 },
{ "plus", 90 },
{ "question_arrow", 92 },
{ "right_ptr", 94 },
{ "right_side", 96 },
{ "right_tee", 98 },
{ "rightbutton", 100 },
{ "rtl_logo", 102 },
{ "sailboat", 104 },
{ "sb_down_arrow", 106 },
{ "sb_h_double_arrow", 108 },
{ "sb_left_arrow", 110 },
{ "sb_right_arrow", 112 },
{ "sb_up_arrow", 114 },
{ "sb_v_double_arrow", 116 },
{ "shuttle", 118 },
{ "sizing", 120 },
{ "spider", 122 },
{ "spraycan", 124 },
{ "star", 126 },
{ "target", 128 },
{ "tcross", 130 },
{ "top_left_arrow", 132 },
{ "top_left_corner", 134 },
{ "top_right_corner", 136 },
{ "top_side", 138 },
{ "top_tee", 140 },
{ "trek", 142 },
{ "ul_angle", 144 },
{ "umbrella", 146 },
{ "ur_angle", 148 },
{ "watch", 150 },
{ "xterm", 152 },
{ NULL, 0 }
};
GdkCursor*
gdk_cursor_new (GdkCursorType cursor_type)
{
GdkCursorPrivate *private;
GdkCursor *cursor;
HCURSOR xcursor;
int i;
for (i = 0; cursors[i].name != NULL && cursors[i].type != cursor_type; i++)
;
if (cursors[i].name != NULL)
{
xcursor = LoadCursor (gdk_DLLInstance, cursors[i].name);
if (xcursor == NULL)
g_warning ("gdk_cursor_new: LoadCursor failed");
GDK_NOTE (MISC, g_print ("gdk_cursor_new: %#x %d\n",
xcursor, cursor_type));
}
else
{
g_warning ("gdk_cursor_new: no cursor %d found",
cursor_type);
xcursor = NULL;
}
private = g_new (GdkCursorPrivate, 1);
private->xcursor = xcursor;
cursor = (GdkCursor*) private;
cursor->type = cursor_type;
return cursor;
}
GdkCursor*
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;
HCURSOR xcursor;
HBITMAP invmask;
HDC hdc1, hdc2;
HGDIOBJ oldbm1, oldbm2;
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_warning ("gdk_cursor_new_from_private: CreateIconIndirect failed");
gdk_pixmap_unref (s2);
return gdk_cursor_new (GDK_PIRATE);
}
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));
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
gdk_cursor_destroy (GdkCursor *cursor)
{
GdkCursorPrivate *private;
g_return_if_fail (cursor != NULL);
private = (GdkCursorPrivate *) cursor;
if (cursor->type == GDK_CURSOR_IS_PIXMAP)
DestroyIcon (private->xcursor);
g_free (private);
}

226
gdk/win32/gdkcursor.c Normal file
View File

@ -0,0 +1,226 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
static const struct { const char *name; int type; } cursors[] = {
{ "x_cursor", 0 },
{ "arrow", 2 },
{ "based_arrow_down", 4 },
{ "based_arrow_up", 6 },
{ "boat", 8 },
{ "bogosity", 10 },
{ "bottom_left_corner", 12 },
{ "bottom_right_corner", 14 },
{ "bottom_side", 16 },
{ "bottom_tee", 18 },
{ "box_spiral", 20 },
{ "center_ptr", 22 },
{ "circle", 24 },
{ "clock", 26 },
{ "coffee_mug", 28 },
{ "cross", 30 },
{ "cross_reverse", 32 },
{ "crosshair", 34 },
{ "diamond_cross", 36 },
{ "dot", 38 },
{ "dotbox", 40 },
{ "double_arrow", 42 },
{ "draft_large", 44 },
{ "draft_small", 46 },
{ "draped_box", 48 },
{ "exchange", 50 },
{ "fleur", 52 },
{ "gobbler", 54 },
{ "gumby", 56 },
{ "hand1", 58 },
{ "hand2", 60 },
{ "heart", 62 },
{ "icon", 64 },
{ "iron_cross", 66 },
{ "left_ptr", 68 },
{ "left_side", 70 },
{ "left_tee", 72 },
{ "leftbutton", 74 },
{ "ll_angle", 76 },
{ "lr_angle", 78 },
{ "man", 80 },
{ "middlebutton", 82 },
{ "mouse", 84 },
{ "pencil", 86 },
{ "pirate", 88 },
{ "plus", 90 },
{ "question_arrow", 92 },
{ "right_ptr", 94 },
{ "right_side", 96 },
{ "right_tee", 98 },
{ "rightbutton", 100 },
{ "rtl_logo", 102 },
{ "sailboat", 104 },
{ "sb_down_arrow", 106 },
{ "sb_h_double_arrow", 108 },
{ "sb_left_arrow", 110 },
{ "sb_right_arrow", 112 },
{ "sb_up_arrow", 114 },
{ "sb_v_double_arrow", 116 },
{ "shuttle", 118 },
{ "sizing", 120 },
{ "spider", 122 },
{ "spraycan", 124 },
{ "star", 126 },
{ "target", 128 },
{ "tcross", 130 },
{ "top_left_arrow", 132 },
{ "top_left_corner", 134 },
{ "top_right_corner", 136 },
{ "top_side", 138 },
{ "top_tee", 140 },
{ "trek", 142 },
{ "ul_angle", 144 },
{ "umbrella", 146 },
{ "ur_angle", 148 },
{ "watch", 150 },
{ "xterm", 152 },
{ NULL, 0 }
};
GdkCursor*
gdk_cursor_new (GdkCursorType cursor_type)
{
GdkCursorPrivate *private;
GdkCursor *cursor;
HCURSOR xcursor;
int i;
for (i = 0; cursors[i].name != NULL && cursors[i].type != cursor_type; i++)
;
if (cursors[i].name != NULL)
{
xcursor = LoadCursor (gdk_DLLInstance, cursors[i].name);
if (xcursor == NULL)
g_warning ("gdk_cursor_new: LoadCursor failed");
GDK_NOTE (MISC, g_print ("gdk_cursor_new: %#x %d\n",
xcursor, cursor_type));
}
else
{
g_warning ("gdk_cursor_new: no cursor %d found",
cursor_type);
xcursor = NULL;
}
private = g_new (GdkCursorPrivate, 1);
private->xcursor = xcursor;
cursor = (GdkCursor*) private;
cursor->type = cursor_type;
return cursor;
}
GdkCursor*
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;
HCURSOR xcursor;
HBITMAP invmask;
HDC hdc1, hdc2;
HGDIOBJ oldbm1, oldbm2;
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_warning ("gdk_cursor_new_from_private: CreateIconIndirect failed");
gdk_pixmap_unref (s2);
return gdk_cursor_new (GDK_PIRATE);
}
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));
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
gdk_cursor_destroy (GdkCursor *cursor)
{
GdkCursorPrivate *private;
g_return_if_fail (cursor != NULL);
private = (GdkCursorPrivate *) cursor;
if (cursor->type == GDK_CURSOR_IS_PIXMAP)
DestroyIcon (private->xcursor);
g_free (private);
}

863
gdk/win32/gdkdnd-win32.c Normal file
View File

@ -0,0 +1,863 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
* Copyright (C) 1998-1999 Tor Lillqvist
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#define INITGUID
#include <string.h>
#include "gdk.h"
#include "gdkx.h"
#include "gdk/gdkprivate.h"
#include <ole2.h>
#include <shlobj.h>
#include <shlguid.h>
typedef struct _GdkDragContextPrivate GdkDragContextPrivate;
typedef enum {
GDK_DRAG_STATUS_DRAG,
GDK_DRAG_STATUS_MOTION_WAIT,
GDK_DRAG_STATUS_ACTION_WAIT,
GDK_DRAG_STATUS_DROP
} GtkDragStatus;
typedef enum {
GDK_DRAG_SOURCE,
GDK_DRAG_TARGET
} GdkDragKind;
#ifdef OLE2_DND
HRESULT STDMETHODCALLTYPE
m_query_interface_target (IDropTarget __RPC_FAR *This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
ULONG STDMETHODCALLTYPE
m_add_ref_target (IDropTarget __RPC_FAR *This);
ULONG STDMETHODCALLTYPE
m_release_target (IDropTarget __RPC_FAR *This);
HRESULT STDMETHODCALLTYPE
m_drag_enter (IDropTarget __RPC_FAR *This,
/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect);
HRESULT STDMETHODCALLTYPE
m_drag_over (IDropTarget __RPC_FAR *This,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect);
HRESULT STDMETHODCALLTYPE
m_drag_leave (IDropTarget __RPC_FAR *This);
HRESULT STDMETHODCALLTYPE
m_drop (IDropTarget __RPC_FAR *This,
/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect);
HRESULT STDMETHODCALLTYPE
m_query_interface_source (IDropSource __RPC_FAR *This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
ULONG STDMETHODCALLTYPE
m_add_ref_source (IDropSource __RPC_FAR *This);
ULONG STDMETHODCALLTYPE
m_release_source (IDropSource __RPC_FAR *This);
HRESULT STDMETHODCALLTYPE
m_query_continue_drag (IDropSource __RPC_FAR *This,
/* [in] */ BOOL fEscapePressed,
/* [in] */ DWORD grfKeyState);
HRESULT STDMETHODCALLTYPE
m_give_feedback (IDropSource __RPC_FAR *This,
/* [in] */ DWORD dwEffect);
#endif /* OLE2_DND */
/* Structure that holds information about a drag in progress.
* this is used on both source and destination sides.
*/
struct _GdkDragContextPrivate {
GdkDragContext context;
guint ref_count;
guint16 last_x; /* Coordinates from last event */
guint16 last_y;
HWND dest_xid;
guint drag_status; /* Current status of drag */
};
GdkDragContext *current_dest_drag = NULL;
/* Drag Contexts */
static GList *contexts;
GdkDragContext *
gdk_drag_context_new (void)
{
GdkDragContextPrivate *result;
result = g_new0 (GdkDragContextPrivate, 1);
result->ref_count = 1;
contexts = g_list_prepend (contexts, result);
return (GdkDragContext *)result;
}
#if OLE2_DND
typedef struct {
IDropTarget idt;
GdkDragContext *context;
} target_drag_context;
typedef struct {
IDropSource ids;
GdkDragContext *context;
} source_drag_context;
HRESULT STDMETHODCALLTYPE
m_query_interface_target (IDropTarget __RPC_FAR *This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
GDK_NOTE (DND, g_print ("m_query_interface_target\n"));
*ppvObject = NULL;
g_print ("riid = %.08x-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x",
((gulong *) riid)[0],
((gushort *) riid)[2],
((gushort *) riid)[3],
((guchar *) riid)[8],
((guchar *) riid)[9],
((guchar *) riid)[10],
((guchar *) riid)[11],
((guchar *) riid)[12],
((guchar *) riid)[13],
((guchar *) riid)[14],
((guchar *) riid)[15]);
if (IsEqualGUID (riid, &IID_IUnknown))
{
m_add_ref_target (This);
*ppvObject = This;
g_print ("...IUnknown\n");
return S_OK;
}
else if (IsEqualGUID (riid, &IID_IDropTarget))
{
m_add_ref_target (This);
*ppvObject = This;
g_print ("...IDropTarget\n");
return S_OK;
}
else
{
g_print ("...Huh?\n");
return E_NOINTERFACE;
}
}
ULONG STDMETHODCALLTYPE
m_add_ref_target (IDropTarget __RPC_FAR *This)
{
target_drag_context *ctx = (target_drag_context *) This;
GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
GDK_NOTE (DND, g_print ("m_add_ref_target\n"));
gdk_drag_context_ref (ctx->context);
return private->ref_count;
}
ULONG STDMETHODCALLTYPE
m_release_target (IDropTarget __RPC_FAR *This)
{
target_drag_context *ctx = (target_drag_context *) This;
GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
GDK_NOTE (DND, g_print ("m_release_target\n"));
gdk_drag_context_unref (ctx->context);
if (private->ref_count == 1)
{
gdk_drag_context_unref (ctx->context);
return 0;
}
else
return private->ref_count - 1;
}
HRESULT STDMETHODCALLTYPE
m_drag_enter (IDropTarget __RPC_FAR *This,
/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect)
{
GDK_NOTE (DND, g_print ("m_drag_enter\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_drag_over (IDropTarget __RPC_FAR *This,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect)
{
GDK_NOTE (DND, g_print ("m_drag_over\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_drag_leave (IDropTarget __RPC_FAR *This)
{
GDK_NOTE (DND, g_print ("m_drag_leave\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_drop (IDropTarget __RPC_FAR *This,
/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect)
{
GDK_NOTE (DND, g_print ("m_drop\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_query_interface_source (IDropSource __RPC_FAR *This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
GDK_NOTE (DND, g_print ("m_query_interface_source\n"));
*ppvObject = NULL;
g_print ("riid = %.02x%.02x%.02x%.02x-%.02x%.02x-%.02x%.02x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x",
((guchar *) riid)[0],
((guchar *) riid)[1],
((guchar *) riid)[2],
((guchar *) riid)[3],
((guchar *) riid)[4],
((guchar *) riid)[5],
((guchar *) riid)[6],
((guchar *) riid)[7],
((guchar *) riid)[8],
((guchar *) riid)[9],
((guchar *) riid)[10],
((guchar *) riid)[11],
((guchar *) riid)[12],
((guchar *) riid)[13],
((guchar *) riid)[14],
((guchar *) riid)[15]);
if (IsEqualGUID (riid, &IID_IUnknown))
{
m_add_ref_source (This);
*ppvObject = This;
g_print ("...IUnknown\n");
return S_OK;
}
else if (IsEqualGUID (riid, &IID_IDropSource))
{
m_add_ref_source (This);
*ppvObject = This;
g_print ("...IDropSource\n");
return S_OK;
}
else
{
g_print ("...Huh?\n");
return E_NOINTERFACE;
}
}
ULONG STDMETHODCALLTYPE
m_add_ref_source (IDropSource __RPC_FAR *This)
{
source_drag_context *ctx = (source_drag_context *) This;
GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
GDK_NOTE (DND, g_print ("m_add_ref_source\n"));
gdk_drag_context_ref (ctx->context);
return private->ref_count;
}
ULONG STDMETHODCALLTYPE
m_release_source (IDropSource __RPC_FAR *This)
{
source_drag_context *ctx = (source_drag_context *) This;
GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
GDK_NOTE (DND, g_print ("m_release_source\n"));
gdk_drag_context_unref (ctx->context);
if (private->ref_count == 1)
{
gdk_drag_context_unref (ctx->context);
return 0;
}
else
return private->ref_count - 1;
}
HRESULT STDMETHODCALLTYPE
m_query_continue_drag (IDropSource __RPC_FAR *This,
/* [in] */ BOOL fEscapePressed,
/* [in] */ DWORD grfKeyState)
{
GDK_NOTE (DND, g_print ("m_query_continue_drag\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_give_feedback (IDropSource __RPC_FAR *This,
/* [in] */ DWORD dwEffect)
{
GDK_NOTE (DND, g_print ("m_give_feedback\n"));
return E_UNEXPECTED;
}
static IDropTargetVtbl idt_vtbl = {
m_query_interface_target,
m_add_ref_target,
m_release_target,
m_drag_enter,
m_drag_over,
m_drag_leave,
m_drop
};
static IDropSourceVtbl ids_vtbl = {
m_query_interface_source,
m_add_ref_source,
m_release_source,
m_query_continue_drag,
m_give_feedback
};
target_drag_context *
target_context_new (void)
{
target_drag_context *result;
result = g_new0 (target_drag_context, 1);
result->idt.lpVtbl = &idt_vtbl;
result->context = gdk_drag_context_new ();
return result;
}
source_drag_context *
source_context_new (void)
{
source_drag_context *result;
result = g_new0 (source_drag_context, 1);
result->ids.lpVtbl = &ids_vtbl;
result->context = gdk_drag_context_new ();
return result;
}
#endif /* OLE2_DND */
void
gdk_drag_context_ref (GdkDragContext *context)
{
g_return_if_fail (context != NULL);
((GdkDragContextPrivate *)context)->ref_count++;
}
void
gdk_drag_context_unref (GdkDragContext *context)
{
GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;
g_return_if_fail (context != NULL);
private->ref_count--;
GDK_NOTE (DND, g_print ("gdk_drag_context_unref: %d%s\n",
private->ref_count,
(private->ref_count == 0 ? " freeing" : "")));
if (private->ref_count == 0)
{
g_dataset_destroy (private);
g_list_free (context->targets);
if (context->source_window)
gdk_window_unref (context->source_window);
if (context->dest_window)
gdk_window_unref (context->dest_window);
contexts = g_list_remove (contexts, private);
g_free (private);
}
}
#if 0
static GdkDragContext *
gdk_drag_context_find (gboolean is_source,
HWND source_xid,
HWND dest_xid)
{
GList *tmp_list = contexts;
GdkDragContext *context;
while (tmp_list)
{
context = (GdkDragContext *)tmp_list->data;
if ((!context->is_source == !is_source) &&
((source_xid == None) || (context->source_window &&
(GDK_WINDOW_XWINDOW (context->source_window) == source_xid))) &&
((dest_xid == None) || (context->dest_window &&
(GDK_WINDOW_XWINDOW (context->dest_window) == dest_xid))))
return context;
tmp_list = tmp_list->next;
}
return NULL;
}
#endif
/* From MS Knowledge Base article Q130698 */
/* resolve_link() fills the filename and path buffer
* with relevant information
* hWnd - calling app's window handle.
*
* lpszLinkName - name of the link file passed into the function.
*
* lpszPath - the buffer that will receive the file pathname.
*/
static HRESULT
resolve_link(HWND hWnd,
LPCTSTR lpszLinkName,
LPSTR lpszPath,
LPSTR lpszDescription)
{
HRESULT hres;
IShellLink *psl;
WIN32_FIND_DATA wfd;
/* Assume Failure to start with: */
*lpszPath = 0;
if (lpszDescription)
*lpszDescription = 0;
/* Call CoCreateInstance to obtain the IShellLink interface
* pointer. This call fails if CoInitialize is not called, so it is
* assumed that CoInitialize has been called.
*/
hres = CoCreateInstance (&CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IShellLink,
(LPVOID *)&psl);
if (SUCCEEDED (hres))
{
IPersistFile *ppf;
/* The IShellLink interface supports the IPersistFile
* interface. Get an interface pointer to it.
*/
hres = psl->lpVtbl->QueryInterface (psl,
&IID_IPersistFile,
(LPVOID *) &ppf);
if (SUCCEEDED (hres))
{
WORD wsz[MAX_PATH];
/* Convert the given link name string to wide character string. */
MultiByteToWideChar (CP_ACP, 0,
lpszLinkName,
-1, wsz, MAX_PATH);
/* Load the file. */
hres = ppf->lpVtbl->Load (ppf, wsz, STGM_READ);
if (SUCCEEDED (hres))
{
/* Resolve the link by calling the Resolve()
* interface function.
*/
hres = psl->lpVtbl->Resolve(psl, hWnd,
SLR_ANY_MATCH |
SLR_NO_UI);
if (SUCCEEDED (hres))
{
hres = psl->lpVtbl->GetPath (psl, lpszPath,
MAX_PATH,
(WIN32_FIND_DATA*)&wfd,
0);
if (SUCCEEDED (hres) && lpszDescription != NULL)
{
hres = psl->lpVtbl->GetDescription (psl,
lpszDescription,
MAX_PATH );
if (!SUCCEEDED (hres))
return FALSE;
}
}
}
ppf->lpVtbl->Release (ppf);
}
psl->lpVtbl->Release (psl);
}
return SUCCEEDED (hres);
}
static GdkFilterReturn
gdk_dropfiles_filter (GdkXEvent *xev,
GdkEvent *event,
gpointer data)
{
GdkDragContext *context;
GdkDragContextPrivate *private;
static GdkAtom text_uri_list_atom = GDK_NONE;
GString *result;
MSG *msg = (MSG *) xev;
HANDLE hdrop;
POINT pt;
gint nfiles, i, k;
guchar fileName[MAX_PATH], linkedFile[MAX_PATH];
if (text_uri_list_atom == GDK_NONE)
text_uri_list_atom = gdk_atom_intern ("text/uri-list", FALSE);
if (msg->message == WM_DROPFILES)
{
GDK_NOTE (DND, g_print ("WM_DROPFILES: %#x\n", msg->hwnd));
context = gdk_drag_context_new ();
private = (GdkDragContextPrivate *) context;
context->protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
context->is_source = FALSE;
context->source_window = (GdkWindow *) &gdk_root_parent;
context->dest_window = event->any.window;
gdk_window_ref (context->dest_window);
/* WM_DROPFILES drops are always file names */
context->targets =
g_list_append (NULL, GUINT_TO_POINTER (text_uri_list_atom));
current_dest_drag = context;
event->dnd.type = GDK_DROP_START;
event->dnd.context = current_dest_drag;
gdk_drag_context_ref (current_dest_drag);
hdrop = (HANDLE) msg->wParam;
DragQueryPoint (hdrop, &pt);
ClientToScreen (msg->hwnd, &pt);
event->dnd.x_root = pt.x;
event->dnd.y_root = pt.y;
event->dnd.time = msg->time;
nfiles = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
result = g_string_new (NULL);
for (i = 0; i < nfiles; i++)
{
g_string_append (result, "file:");
DragQueryFile (hdrop, i, fileName, MAX_PATH);
/* Resolve shortcuts */
if (resolve_link (msg->hwnd, fileName, linkedFile, NULL))
{
g_string_append (result, linkedFile);
GDK_NOTE (DND, g_print ("...%s link to %s\n",
fileName, linkedFile));
}
else
{
g_string_append (result, fileName);
GDK_NOTE (DND, g_print ("...%s\n", fileName));
}
g_string_append (result, "\015\012");
}
gdk_sel_prop_store ((GdkWindow *) &gdk_root_parent,
text_uri_list_atom, 8, result->str, result->len + 1);
DragFinish (hdrop);
return GDK_FILTER_TRANSLATE;
}
else
return GDK_FILTER_CONTINUE;
}
/*************************************************************
************************** Public API ***********************
*************************************************************/
void
gdk_dnd_init (void)
{
HRESULT hres;
hres = OleInitialize (NULL);
if (! SUCCEEDED (hres))
g_error ("OleInitialize failed");
}
void
gdk_dnd_exit (void)
{
OleUninitialize ();
}
/* Source side */
static void
gdk_drag_do_leave (GdkDragContext *context, guint32 time)
{
if (context->dest_window)
{
GDK_NOTE (DND, g_print ("gdk_drag_do_leave\n"));
gdk_window_unref (context->dest_window);
context->dest_window = NULL;
}
}
GdkDragContext *
gdk_drag_begin (GdkWindow *window,
GList *targets)
{
GList *tmp_list;
GdkDragContext *new_context;
g_return_val_if_fail (window != NULL, NULL);
GDK_NOTE (DND, g_print ("gdk_drag_begin\n"));
new_context = gdk_drag_context_new ();
new_context->is_source = TRUE;
new_context->source_window = window;
gdk_window_ref (window);
tmp_list = g_list_last (targets);
new_context->targets = NULL;
while (tmp_list)
{
new_context->targets = g_list_prepend (new_context->targets,
tmp_list->data);
tmp_list = tmp_list->prev;
}
new_context->actions = 0;
return new_context;
}
guint32
gdk_drag_get_protocol (guint32 xid,
GdkDragProtocol *protocol)
{
/* This isn't used */
return 0;
}
void
gdk_drag_find_window (GdkDragContext *context,
GdkWindow *drag_window,
gint x_root,
gint y_root,
GdkWindow **dest_window,
GdkDragProtocol *protocol)
{
GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;
GdkWindowPrivate *drag_window_private = (GdkWindowPrivate *) drag_window;
HWND recipient;
POINT pt;
GDK_NOTE (DND, g_print ("gdk_drag_find_window: %#x +%d+%d\n",
(drag_window ? drag_window_private->xwindow : 0),
x_root, y_root));
pt.x = x_root;
pt.y = y_root;
recipient = WindowFromPoint (pt);
if (recipient == NULL)
*dest_window = NULL;
else
{
*dest_window = gdk_window_lookup (recipient);
if (*dest_window)
gdk_window_ref (*dest_window);
*protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
}
}
gboolean
gdk_drag_motion (GdkDragContext *context,
GdkWindow *dest_window,
GdkDragProtocol protocol,
gint x_root,
gint y_root,
GdkDragAction suggested_action,
GdkDragAction possible_actions,
guint32 time)
{
return FALSE;
}
void
gdk_drag_drop (GdkDragContext *context,
guint32 time)
{
g_return_if_fail (context != NULL);
g_warning ("gdk_drag_drop: not implemented\n");
}
void
gdk_drag_abort (GdkDragContext *context,
guint32 time)
{
g_return_if_fail (context != NULL);
gdk_drag_do_leave (context, time);
}
/* Destination side */
void
gdk_drag_status (GdkDragContext *context,
GdkDragAction action,
guint32 time)
{
GDK_NOTE (DND, g_print ("gdk_drag_status\n"));
}
void
gdk_drop_reply (GdkDragContext *context,
gboolean ok,
guint32 time)
{
}
void
gdk_drop_finish (GdkDragContext *context,
gboolean success,
guint32 time)
{
}
void
gdk_window_register_dnd (GdkWindow *window)
{
GdkWindowPrivate *private = (GdkWindowPrivate *) window;
#if OLE2_DND
target_drag_context *context;
HRESULT hres;
#endif
g_return_if_fail (window != NULL);
GDK_NOTE (DND, g_print ("gdk_window_register_dnd: %#x\n", private->xwindow));
/* We always claim to accept dropped files, but in fact we might not,
* of course. This function is called in such a way that it cannot know
* whether the window (widget) in question actually accepts files
* (in gtk, data of type text/uri-list) or not.
*/
gdk_window_add_filter (window, gdk_dropfiles_filter, NULL);
DragAcceptFiles (private->xwindow, TRUE);
#if OLE2_DND
/* Register for OLE2 d&d */
context = target_context_new ();
hres = CoLockObjectExternal ((IUnknown *) &context->idt, TRUE, FALSE);
if (!SUCCEEDED (hres))
g_warning ("gdk_window_register_dnd: CoLockObjectExternal failed");
else
{
hres = RegisterDragDrop (private->xwindow, &context->idt);
if (hres == DRAGDROP_E_ALREADYREGISTERED)
{
g_print ("DRAGDROP_E_ALREADYREGISTERED\n");
CoLockObjectExternal ((IUnknown *) &context->idt, FALSE, FALSE);
}
else if (!SUCCEEDED (hres))
g_warning ("gdk_window_register_dnd: RegisterDragDrop failed");
}
#endif
}
/*************************************************************
* gdk_drag_get_selection:
* Returns the selection atom for the current source window
* arguments:
*
* results:
*************************************************************/
GdkAtom
gdk_drag_get_selection (GdkDragContext *context)
{
if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES)
return gdk_win32_dropfiles_atom;
else if (context->protocol == GDK_DRAG_PROTO_OLE2)
return gdk_ole2_dnd_atom;
else
return GDK_NONE;
}

863
gdk/win32/gdkdnd.c Normal file
View File

@ -0,0 +1,863 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1999 Peter Mattis, Spencer Kimball and Josh MacDonald
* Copyright (C) 1998-1999 Tor Lillqvist
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#define INITGUID
#include <string.h>
#include "gdk.h"
#include "gdkx.h"
#include "gdk/gdkprivate.h"
#include <ole2.h>
#include <shlobj.h>
#include <shlguid.h>
typedef struct _GdkDragContextPrivate GdkDragContextPrivate;
typedef enum {
GDK_DRAG_STATUS_DRAG,
GDK_DRAG_STATUS_MOTION_WAIT,
GDK_DRAG_STATUS_ACTION_WAIT,
GDK_DRAG_STATUS_DROP
} GtkDragStatus;
typedef enum {
GDK_DRAG_SOURCE,
GDK_DRAG_TARGET
} GdkDragKind;
#ifdef OLE2_DND
HRESULT STDMETHODCALLTYPE
m_query_interface_target (IDropTarget __RPC_FAR *This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
ULONG STDMETHODCALLTYPE
m_add_ref_target (IDropTarget __RPC_FAR *This);
ULONG STDMETHODCALLTYPE
m_release_target (IDropTarget __RPC_FAR *This);
HRESULT STDMETHODCALLTYPE
m_drag_enter (IDropTarget __RPC_FAR *This,
/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect);
HRESULT STDMETHODCALLTYPE
m_drag_over (IDropTarget __RPC_FAR *This,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect);
HRESULT STDMETHODCALLTYPE
m_drag_leave (IDropTarget __RPC_FAR *This);
HRESULT STDMETHODCALLTYPE
m_drop (IDropTarget __RPC_FAR *This,
/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect);
HRESULT STDMETHODCALLTYPE
m_query_interface_source (IDropSource __RPC_FAR *This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
ULONG STDMETHODCALLTYPE
m_add_ref_source (IDropSource __RPC_FAR *This);
ULONG STDMETHODCALLTYPE
m_release_source (IDropSource __RPC_FAR *This);
HRESULT STDMETHODCALLTYPE
m_query_continue_drag (IDropSource __RPC_FAR *This,
/* [in] */ BOOL fEscapePressed,
/* [in] */ DWORD grfKeyState);
HRESULT STDMETHODCALLTYPE
m_give_feedback (IDropSource __RPC_FAR *This,
/* [in] */ DWORD dwEffect);
#endif /* OLE2_DND */
/* Structure that holds information about a drag in progress.
* this is used on both source and destination sides.
*/
struct _GdkDragContextPrivate {
GdkDragContext context;
guint ref_count;
guint16 last_x; /* Coordinates from last event */
guint16 last_y;
HWND dest_xid;
guint drag_status; /* Current status of drag */
};
GdkDragContext *current_dest_drag = NULL;
/* Drag Contexts */
static GList *contexts;
GdkDragContext *
gdk_drag_context_new (void)
{
GdkDragContextPrivate *result;
result = g_new0 (GdkDragContextPrivate, 1);
result->ref_count = 1;
contexts = g_list_prepend (contexts, result);
return (GdkDragContext *)result;
}
#if OLE2_DND
typedef struct {
IDropTarget idt;
GdkDragContext *context;
} target_drag_context;
typedef struct {
IDropSource ids;
GdkDragContext *context;
} source_drag_context;
HRESULT STDMETHODCALLTYPE
m_query_interface_target (IDropTarget __RPC_FAR *This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
GDK_NOTE (DND, g_print ("m_query_interface_target\n"));
*ppvObject = NULL;
g_print ("riid = %.08x-%.04x-%.04x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x",
((gulong *) riid)[0],
((gushort *) riid)[2],
((gushort *) riid)[3],
((guchar *) riid)[8],
((guchar *) riid)[9],
((guchar *) riid)[10],
((guchar *) riid)[11],
((guchar *) riid)[12],
((guchar *) riid)[13],
((guchar *) riid)[14],
((guchar *) riid)[15]);
if (IsEqualGUID (riid, &IID_IUnknown))
{
m_add_ref_target (This);
*ppvObject = This;
g_print ("...IUnknown\n");
return S_OK;
}
else if (IsEqualGUID (riid, &IID_IDropTarget))
{
m_add_ref_target (This);
*ppvObject = This;
g_print ("...IDropTarget\n");
return S_OK;
}
else
{
g_print ("...Huh?\n");
return E_NOINTERFACE;
}
}
ULONG STDMETHODCALLTYPE
m_add_ref_target (IDropTarget __RPC_FAR *This)
{
target_drag_context *ctx = (target_drag_context *) This;
GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
GDK_NOTE (DND, g_print ("m_add_ref_target\n"));
gdk_drag_context_ref (ctx->context);
return private->ref_count;
}
ULONG STDMETHODCALLTYPE
m_release_target (IDropTarget __RPC_FAR *This)
{
target_drag_context *ctx = (target_drag_context *) This;
GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
GDK_NOTE (DND, g_print ("m_release_target\n"));
gdk_drag_context_unref (ctx->context);
if (private->ref_count == 1)
{
gdk_drag_context_unref (ctx->context);
return 0;
}
else
return private->ref_count - 1;
}
HRESULT STDMETHODCALLTYPE
m_drag_enter (IDropTarget __RPC_FAR *This,
/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect)
{
GDK_NOTE (DND, g_print ("m_drag_enter\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_drag_over (IDropTarget __RPC_FAR *This,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect)
{
GDK_NOTE (DND, g_print ("m_drag_over\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_drag_leave (IDropTarget __RPC_FAR *This)
{
GDK_NOTE (DND, g_print ("m_drag_leave\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_drop (IDropTarget __RPC_FAR *This,
/* [unique][in] */ IDataObject __RPC_FAR *pDataObj,
/* [in] */ DWORD grfKeyState,
/* [in] */ POINTL pt,
/* [out][in] */ DWORD __RPC_FAR *pdwEffect)
{
GDK_NOTE (DND, g_print ("m_drop\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_query_interface_source (IDropSource __RPC_FAR *This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
GDK_NOTE (DND, g_print ("m_query_interface_source\n"));
*ppvObject = NULL;
g_print ("riid = %.02x%.02x%.02x%.02x-%.02x%.02x-%.02x%.02x-%.02x%.02x-%.02x%.02x%.02x%.02x%.02x%.02x",
((guchar *) riid)[0],
((guchar *) riid)[1],
((guchar *) riid)[2],
((guchar *) riid)[3],
((guchar *) riid)[4],
((guchar *) riid)[5],
((guchar *) riid)[6],
((guchar *) riid)[7],
((guchar *) riid)[8],
((guchar *) riid)[9],
((guchar *) riid)[10],
((guchar *) riid)[11],
((guchar *) riid)[12],
((guchar *) riid)[13],
((guchar *) riid)[14],
((guchar *) riid)[15]);
if (IsEqualGUID (riid, &IID_IUnknown))
{
m_add_ref_source (This);
*ppvObject = This;
g_print ("...IUnknown\n");
return S_OK;
}
else if (IsEqualGUID (riid, &IID_IDropSource))
{
m_add_ref_source (This);
*ppvObject = This;
g_print ("...IDropSource\n");
return S_OK;
}
else
{
g_print ("...Huh?\n");
return E_NOINTERFACE;
}
}
ULONG STDMETHODCALLTYPE
m_add_ref_source (IDropSource __RPC_FAR *This)
{
source_drag_context *ctx = (source_drag_context *) This;
GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
GDK_NOTE (DND, g_print ("m_add_ref_source\n"));
gdk_drag_context_ref (ctx->context);
return private->ref_count;
}
ULONG STDMETHODCALLTYPE
m_release_source (IDropSource __RPC_FAR *This)
{
source_drag_context *ctx = (source_drag_context *) This;
GdkDragContextPrivate *private = (GdkDragContextPrivate *) ctx->context;
GDK_NOTE (DND, g_print ("m_release_source\n"));
gdk_drag_context_unref (ctx->context);
if (private->ref_count == 1)
{
gdk_drag_context_unref (ctx->context);
return 0;
}
else
return private->ref_count - 1;
}
HRESULT STDMETHODCALLTYPE
m_query_continue_drag (IDropSource __RPC_FAR *This,
/* [in] */ BOOL fEscapePressed,
/* [in] */ DWORD grfKeyState)
{
GDK_NOTE (DND, g_print ("m_query_continue_drag\n"));
return E_UNEXPECTED;
}
HRESULT STDMETHODCALLTYPE
m_give_feedback (IDropSource __RPC_FAR *This,
/* [in] */ DWORD dwEffect)
{
GDK_NOTE (DND, g_print ("m_give_feedback\n"));
return E_UNEXPECTED;
}
static IDropTargetVtbl idt_vtbl = {
m_query_interface_target,
m_add_ref_target,
m_release_target,
m_drag_enter,
m_drag_over,
m_drag_leave,
m_drop
};
static IDropSourceVtbl ids_vtbl = {
m_query_interface_source,
m_add_ref_source,
m_release_source,
m_query_continue_drag,
m_give_feedback
};
target_drag_context *
target_context_new (void)
{
target_drag_context *result;
result = g_new0 (target_drag_context, 1);
result->idt.lpVtbl = &idt_vtbl;
result->context = gdk_drag_context_new ();
return result;
}
source_drag_context *
source_context_new (void)
{
source_drag_context *result;
result = g_new0 (source_drag_context, 1);
result->ids.lpVtbl = &ids_vtbl;
result->context = gdk_drag_context_new ();
return result;
}
#endif /* OLE2_DND */
void
gdk_drag_context_ref (GdkDragContext *context)
{
g_return_if_fail (context != NULL);
((GdkDragContextPrivate *)context)->ref_count++;
}
void
gdk_drag_context_unref (GdkDragContext *context)
{
GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;
g_return_if_fail (context != NULL);
private->ref_count--;
GDK_NOTE (DND, g_print ("gdk_drag_context_unref: %d%s\n",
private->ref_count,
(private->ref_count == 0 ? " freeing" : "")));
if (private->ref_count == 0)
{
g_dataset_destroy (private);
g_list_free (context->targets);
if (context->source_window)
gdk_window_unref (context->source_window);
if (context->dest_window)
gdk_window_unref (context->dest_window);
contexts = g_list_remove (contexts, private);
g_free (private);
}
}
#if 0
static GdkDragContext *
gdk_drag_context_find (gboolean is_source,
HWND source_xid,
HWND dest_xid)
{
GList *tmp_list = contexts;
GdkDragContext *context;
while (tmp_list)
{
context = (GdkDragContext *)tmp_list->data;
if ((!context->is_source == !is_source) &&
((source_xid == None) || (context->source_window &&
(GDK_WINDOW_XWINDOW (context->source_window) == source_xid))) &&
((dest_xid == None) || (context->dest_window &&
(GDK_WINDOW_XWINDOW (context->dest_window) == dest_xid))))
return context;
tmp_list = tmp_list->next;
}
return NULL;
}
#endif
/* From MS Knowledge Base article Q130698 */
/* resolve_link() fills the filename and path buffer
* with relevant information
* hWnd - calling app's window handle.
*
* lpszLinkName - name of the link file passed into the function.
*
* lpszPath - the buffer that will receive the file pathname.
*/
static HRESULT
resolve_link(HWND hWnd,
LPCTSTR lpszLinkName,
LPSTR lpszPath,
LPSTR lpszDescription)
{
HRESULT hres;
IShellLink *psl;
WIN32_FIND_DATA wfd;
/* Assume Failure to start with: */
*lpszPath = 0;
if (lpszDescription)
*lpszDescription = 0;
/* Call CoCreateInstance to obtain the IShellLink interface
* pointer. This call fails if CoInitialize is not called, so it is
* assumed that CoInitialize has been called.
*/
hres = CoCreateInstance (&CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
&IID_IShellLink,
(LPVOID *)&psl);
if (SUCCEEDED (hres))
{
IPersistFile *ppf;
/* The IShellLink interface supports the IPersistFile
* interface. Get an interface pointer to it.
*/
hres = psl->lpVtbl->QueryInterface (psl,
&IID_IPersistFile,
(LPVOID *) &ppf);
if (SUCCEEDED (hres))
{
WORD wsz[MAX_PATH];
/* Convert the given link name string to wide character string. */
MultiByteToWideChar (CP_ACP, 0,
lpszLinkName,
-1, wsz, MAX_PATH);
/* Load the file. */
hres = ppf->lpVtbl->Load (ppf, wsz, STGM_READ);
if (SUCCEEDED (hres))
{
/* Resolve the link by calling the Resolve()
* interface function.
*/
hres = psl->lpVtbl->Resolve(psl, hWnd,
SLR_ANY_MATCH |
SLR_NO_UI);
if (SUCCEEDED (hres))
{
hres = psl->lpVtbl->GetPath (psl, lpszPath,
MAX_PATH,
(WIN32_FIND_DATA*)&wfd,
0);
if (SUCCEEDED (hres) && lpszDescription != NULL)
{
hres = psl->lpVtbl->GetDescription (psl,
lpszDescription,
MAX_PATH );
if (!SUCCEEDED (hres))
return FALSE;
}
}
}
ppf->lpVtbl->Release (ppf);
}
psl->lpVtbl->Release (psl);
}
return SUCCEEDED (hres);
}
static GdkFilterReturn
gdk_dropfiles_filter (GdkXEvent *xev,
GdkEvent *event,
gpointer data)
{
GdkDragContext *context;
GdkDragContextPrivate *private;
static GdkAtom text_uri_list_atom = GDK_NONE;
GString *result;
MSG *msg = (MSG *) xev;
HANDLE hdrop;
POINT pt;
gint nfiles, i, k;
guchar fileName[MAX_PATH], linkedFile[MAX_PATH];
if (text_uri_list_atom == GDK_NONE)
text_uri_list_atom = gdk_atom_intern ("text/uri-list", FALSE);
if (msg->message == WM_DROPFILES)
{
GDK_NOTE (DND, g_print ("WM_DROPFILES: %#x\n", msg->hwnd));
context = gdk_drag_context_new ();
private = (GdkDragContextPrivate *) context;
context->protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
context->is_source = FALSE;
context->source_window = (GdkWindow *) &gdk_root_parent;
context->dest_window = event->any.window;
gdk_window_ref (context->dest_window);
/* WM_DROPFILES drops are always file names */
context->targets =
g_list_append (NULL, GUINT_TO_POINTER (text_uri_list_atom));
current_dest_drag = context;
event->dnd.type = GDK_DROP_START;
event->dnd.context = current_dest_drag;
gdk_drag_context_ref (current_dest_drag);
hdrop = (HANDLE) msg->wParam;
DragQueryPoint (hdrop, &pt);
ClientToScreen (msg->hwnd, &pt);
event->dnd.x_root = pt.x;
event->dnd.y_root = pt.y;
event->dnd.time = msg->time;
nfiles = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
result = g_string_new (NULL);
for (i = 0; i < nfiles; i++)
{
g_string_append (result, "file:");
DragQueryFile (hdrop, i, fileName, MAX_PATH);
/* Resolve shortcuts */
if (resolve_link (msg->hwnd, fileName, linkedFile, NULL))
{
g_string_append (result, linkedFile);
GDK_NOTE (DND, g_print ("...%s link to %s\n",
fileName, linkedFile));
}
else
{
g_string_append (result, fileName);
GDK_NOTE (DND, g_print ("...%s\n", fileName));
}
g_string_append (result, "\015\012");
}
gdk_sel_prop_store ((GdkWindow *) &gdk_root_parent,
text_uri_list_atom, 8, result->str, result->len + 1);
DragFinish (hdrop);
return GDK_FILTER_TRANSLATE;
}
else
return GDK_FILTER_CONTINUE;
}
/*************************************************************
************************** Public API ***********************
*************************************************************/
void
gdk_dnd_init (void)
{
HRESULT hres;
hres = OleInitialize (NULL);
if (! SUCCEEDED (hres))
g_error ("OleInitialize failed");
}
void
gdk_dnd_exit (void)
{
OleUninitialize ();
}
/* Source side */
static void
gdk_drag_do_leave (GdkDragContext *context, guint32 time)
{
if (context->dest_window)
{
GDK_NOTE (DND, g_print ("gdk_drag_do_leave\n"));
gdk_window_unref (context->dest_window);
context->dest_window = NULL;
}
}
GdkDragContext *
gdk_drag_begin (GdkWindow *window,
GList *targets)
{
GList *tmp_list;
GdkDragContext *new_context;
g_return_val_if_fail (window != NULL, NULL);
GDK_NOTE (DND, g_print ("gdk_drag_begin\n"));
new_context = gdk_drag_context_new ();
new_context->is_source = TRUE;
new_context->source_window = window;
gdk_window_ref (window);
tmp_list = g_list_last (targets);
new_context->targets = NULL;
while (tmp_list)
{
new_context->targets = g_list_prepend (new_context->targets,
tmp_list->data);
tmp_list = tmp_list->prev;
}
new_context->actions = 0;
return new_context;
}
guint32
gdk_drag_get_protocol (guint32 xid,
GdkDragProtocol *protocol)
{
/* This isn't used */
return 0;
}
void
gdk_drag_find_window (GdkDragContext *context,
GdkWindow *drag_window,
gint x_root,
gint y_root,
GdkWindow **dest_window,
GdkDragProtocol *protocol)
{
GdkDragContextPrivate *private = (GdkDragContextPrivate *)context;
GdkWindowPrivate *drag_window_private = (GdkWindowPrivate *) drag_window;
HWND recipient;
POINT pt;
GDK_NOTE (DND, g_print ("gdk_drag_find_window: %#x +%d+%d\n",
(drag_window ? drag_window_private->xwindow : 0),
x_root, y_root));
pt.x = x_root;
pt.y = y_root;
recipient = WindowFromPoint (pt);
if (recipient == NULL)
*dest_window = NULL;
else
{
*dest_window = gdk_window_lookup (recipient);
if (*dest_window)
gdk_window_ref (*dest_window);
*protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
}
}
gboolean
gdk_drag_motion (GdkDragContext *context,
GdkWindow *dest_window,
GdkDragProtocol protocol,
gint x_root,
gint y_root,
GdkDragAction suggested_action,
GdkDragAction possible_actions,
guint32 time)
{
return FALSE;
}
void
gdk_drag_drop (GdkDragContext *context,
guint32 time)
{
g_return_if_fail (context != NULL);
g_warning ("gdk_drag_drop: not implemented\n");
}
void
gdk_drag_abort (GdkDragContext *context,
guint32 time)
{
g_return_if_fail (context != NULL);
gdk_drag_do_leave (context, time);
}
/* Destination side */
void
gdk_drag_status (GdkDragContext *context,
GdkDragAction action,
guint32 time)
{
GDK_NOTE (DND, g_print ("gdk_drag_status\n"));
}
void
gdk_drop_reply (GdkDragContext *context,
gboolean ok,
guint32 time)
{
}
void
gdk_drop_finish (GdkDragContext *context,
gboolean success,
guint32 time)
{
}
void
gdk_window_register_dnd (GdkWindow *window)
{
GdkWindowPrivate *private = (GdkWindowPrivate *) window;
#if OLE2_DND
target_drag_context *context;
HRESULT hres;
#endif
g_return_if_fail (window != NULL);
GDK_NOTE (DND, g_print ("gdk_window_register_dnd: %#x\n", private->xwindow));
/* We always claim to accept dropped files, but in fact we might not,
* of course. This function is called in such a way that it cannot know
* whether the window (widget) in question actually accepts files
* (in gtk, data of type text/uri-list) or not.
*/
gdk_window_add_filter (window, gdk_dropfiles_filter, NULL);
DragAcceptFiles (private->xwindow, TRUE);
#if OLE2_DND
/* Register for OLE2 d&d */
context = target_context_new ();
hres = CoLockObjectExternal ((IUnknown *) &context->idt, TRUE, FALSE);
if (!SUCCEEDED (hres))
g_warning ("gdk_window_register_dnd: CoLockObjectExternal failed");
else
{
hres = RegisterDragDrop (private->xwindow, &context->idt);
if (hres == DRAGDROP_E_ALREADYREGISTERED)
{
g_print ("DRAGDROP_E_ALREADYREGISTERED\n");
CoLockObjectExternal ((IUnknown *) &context->idt, FALSE, FALSE);
}
else if (!SUCCEEDED (hres))
g_warning ("gdk_window_register_dnd: RegisterDragDrop failed");
}
#endif
}
/*************************************************************
* gdk_drag_get_selection:
* Returns the selection atom for the current source window
* arguments:
*
* results:
*************************************************************/
GdkAtom
gdk_drag_get_selection (GdkDragContext *context)
{
if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES)
return gdk_win32_dropfiles_atom;
else if (context->protocol == GDK_DRAG_PROTO_OLE2)
return gdk_ole2_dnd_atom;
else
return GDK_NONE;
}

655
gdk/win32/gdkdraw.c Normal file
View File

@ -0,0 +1,655 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <math.h>
#include "gdk.h"
#include "gdkprivate.h"
#ifndef M_TWOPI
#define M_TWOPI (2.0 * 3.14159265358979323846)
#endif
void
gdk_draw_point (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
HBRUSH hbr;
RECT rect;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
hbr = GetCurrentObject (hdc, OBJ_BRUSH);
/* We use FillRect because SetPixel wants the COLORREF directly,
* and doesn't use the current brush, which is what we want.
*/
rect.left = x;
rect.top = y;
rect.right = rect.left + 1;
rect.bottom = rect.top + 1;
FillRect (hdc, &rect, hbr);
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_line (GdkDrawable *drawable,
GdkGC *gc,
gint x1,
gint y1,
gint x2,
gint y2)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
GDK_NOTE (MISC, g_print ("gdk_draw_line: %#x (%d) +%d+%d..+%d+%d\n",
drawable_private->xwindow, gc_private,
x1, y1, x2, y2));
MoveToEx (hdc, x1, y1, NULL);
if (!LineTo (hdc, x2, y2))
g_warning ("gdk_draw_line: LineTo #1 failed");
/* LineTo doesn't draw the last point, so if we have a pen width of 1,
* we draw the end pixel separately... With wider pens it hopefully
* doesn't matter?
*/
if (gc_private->pen_width == 1)
if (!LineTo (hdc, x2 + 1, y2))
g_warning ("gdk_draw_line: LineTo #2 failed");
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_rectangle (GdkDrawable *drawable,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
LOGBRUSH lb;
HPEN hpen;
HBRUSH hbr;
HGDIOBJ oldpen, oldbrush;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
if (width == -1)
width = drawable_private->width;
if (height == -1)
height = drawable_private->height;
hdc = gdk_gc_predraw (drawable_private, gc_private);
GDK_NOTE (MISC, g_print ("gdk_draw_rectangle: %#x (%d) %s%dx%d@+%d+%d\n",
drawable_private->xwindow,
gc_private,
(filled ? "fill " : ""),
width, height, x, y));
#if 0
{
HBRUSH hbr = GetCurrentObject (hdc, OBJ_BRUSH);
HPEN hpen = GetCurrentObject (hdc, OBJ_PEN);
LOGBRUSH lbr;
LOGPEN lpen;
GetObject (hbr, sizeof (lbr), &lbr);
GetObject (hpen, sizeof (lpen), &lpen);
g_print ("current brush: style = %s, color = 0x%.08x\n",
(lbr.lbStyle == BS_SOLID ? "SOLID" : "???"),
lbr.lbColor);
g_print ("current pen: style = %s, width = %d, color = 0x%.08x\n",
(lpen.lopnStyle == PS_SOLID ? "SOLID" : "???"),
lpen.lopnWidth,
lpen.lopnColor);
}
#endif
if (filled)
oldpen = SelectObject (hdc, GetStockObject (NULL_PEN));
else
oldbrush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
g_warning ("gdk_draw_rectangle: Rectangle failed");
if (filled)
SelectObject (hdc, oldpen);
else
SelectObject (hdc, oldbrush);
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_arc (GdkDrawable *drawable,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height,
gint angle1,
gint angle2)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
if (width == -1)
width = drawable_private->width;
if (height == -1)
height = drawable_private->height;
hdc = gdk_gc_predraw (drawable_private, gc_private);
nXStartArc = x + width/2 + (int) (sin(angle1/64.*M_TWOPI)*width);
nYStartArc = y + height/2 + (int) (cos(angle1/64.*M_TWOPI)*height);
nXEndArc = x + width/2 + (int) (sin(angle2/64.*M_TWOPI)*width);
nYEndArc = y + height/2 + (int) (cos(angle2/64.*M_TWOPI)*height);
if (filled)
{
if (!Pie (hdc, x, y, x+width, y+height,
nXStartArc, nYStartArc, nXEndArc, nYEndArc))
g_warning ("gdk_draw_arc: Pie failed");
}
else
{
if (!Arc (hdc, x, y, x+width, y+height,
nXStartArc, nYStartArc, nXEndArc, nYEndArc))
g_warning ("gdk_draw_arc: Arc failed");
}
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_polygon (GdkDrawable *drawable,
GdkGC *gc,
gint filled,
GdkPoint *points,
gint npoints)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
POINT *pts;
int i;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
pts = g_malloc ((npoints+1) * sizeof (POINT));
GDK_NOTE (MISC, g_print ("gdk_draw_polygon: %#x (%d) %d\n",
drawable_private->xwindow, gc_private,
npoints));
for (i = 0; i < npoints; i++)
{
pts[i].x = points[i].x;
pts[i].y = points[i].y;
}
if ((points[0].x != points[npoints-1].x) ||
(points[0].y != points[npoints-1].y))
{
pts[npoints].x = points[0].x;
pts[npoints].y = points[0].y;
npoints++;
}
if (filled)
{
if (!Polygon (hdc, pts, npoints))
g_warning ("gdk_draw_polygon: Polygon failed");
}
else
{
if (!Polyline (hdc, pts, npoints))
g_warning ("gdk_draw_polygon: Polyline failed");
}
g_free (pts);
gdk_gc_postdraw (drawable_private, gc_private);
}
/* gdk_draw_string
*/
void
gdk_draw_string (GdkDrawable *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const gchar *string)
{
gdk_draw_text (drawable, font, gc, x, y, string, strlen (string));
}
/* gdk_draw_text
*
* Modified by Li-Da Lho to draw 16 bits and Multibyte strings
*
* Interface changed: add "GdkFont *font" to specify font or fontset explicitely
*/
void
gdk_draw_text (GdkDrawable *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const gchar *text,
gint text_length)
{
GdkWindowPrivate *drawable_private;
GdkFontPrivate *font_private;
GdkGCPrivate *gc_private;
HDC hdc;
HFONT xfont;
HGDIOBJ oldfont;
g_return_if_fail (drawable != NULL);
g_return_if_fail (font != NULL);
g_return_if_fail (gc != NULL);
g_return_if_fail (text != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
if (font->type == GDK_FONT_FONT)
{
hdc = gdk_gc_predraw (drawable_private, gc_private);
xfont = (HFONT) font_private->xfont;
GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
"+%d+%d font: %#x \"%.*s\" length: %d\n",
drawable_private->xwindow,
gc_private, gc_private->xgc,
x, y, xfont,
(text_length > 10 ? 10 : text_length),
text, text_length));
if ((oldfont = SelectObject (hdc, xfont)) == NULL)
g_warning ("gdk_draw_text: SelectObject failed");
if (!TextOutA (hdc, x, y, text, text_length))
g_warning ("gdk_draw_text: TextOutA failed");
SelectObject (hdc, oldfont);
gdk_gc_postdraw (drawable_private, gc_private);
}
else
g_error ("undefined font type");
}
void
gdk_draw_text_wc (GdkDrawable *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const GdkWChar *text,
gint text_length)
{
GdkWindowPrivate *drawable_private;
GdkFontPrivate *font_private;
GdkGCPrivate *gc_private;
gint i;
wchar_t *wcstr;
g_return_if_fail (drawable != NULL);
g_return_if_fail (font != NULL);
g_return_if_fail (gc != NULL);
g_return_if_fail (text != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
if (font->type == GDK_FONT_FONT)
{
HDC hdc;
HFONT xfont;
HGDIOBJ oldfont;
hdc = gdk_gc_predraw (drawable_private, gc_private);
xfont = (HFONT) font_private->xfont;
GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
"+%d+%d font: %#x length: %d\n",
drawable_private->xwindow,
gc_private, gc_private->xgc,
x, y, xfont,
text_length));
if ((oldfont = SelectObject (hdc, xfont)) == NULL)
g_warning ("gdk_draw_text: SelectObject failed");
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
if (!TextOutW (hdc, x, y, wcstr, text_length))
g_warning ("gdk_draw_text: TextOutW failed");
g_free (wcstr);
SelectObject (hdc, oldfont);
gdk_gc_postdraw (drawable_private, gc_private);
}
else
g_error ("undefined font type");
}
void
gdk_draw_pixmap (GdkDrawable *drawable,
GdkGC *gc,
GdkPixmap *src,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
{
GdkWindowPrivate *drawable_private;
GdkWindowPrivate *src_private;
GdkGCPrivate *gc_private;
HDC hdc;
HDC srcdc;
HGDIOBJ hgdiobj;
g_return_if_fail (drawable != NULL);
g_return_if_fail (src != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
src_private = (GdkWindowPrivate*) src;
if (drawable_private->destroyed || src_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
if (width == -1)
width = src_private->width;
if (height == -1)
height = src_private->height;
hdc = gdk_gc_predraw (drawable_private, gc_private);
GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x destdc: (%d) %#x "
"src: %#x %dx%d@+%d+%d\n",
drawable_private->xwindow, gc_private, hdc,
src_private->xwindow,
width, height, xdest, ydest));
/* Strangely enough, this function is called also to bitblt
* from a window.
*/
if (src_private->window_type == GDK_WINDOW_PIXMAP)
{
if ((srcdc = CreateCompatibleDC (hdc)) == NULL)
g_warning ("gdk_draw_pixmap: CreateCompatibleDC failed");
if ((hgdiobj = SelectObject (srcdc, src_private->xwindow)) == NULL)
g_warning ("gdk_draw_pixmap: SelectObject #1 failed");
if (!BitBlt (hdc, xdest, ydest, width, height,
srcdc, xsrc, ysrc, SRCCOPY))
g_warning ("gdk_draw_pixmap: BitBlt failed");
if ((SelectObject (srcdc, hgdiobj) == NULL))
g_warning ("gdk_draw_pixmap: SelectObject #2 failed");
if (!DeleteDC (srcdc))
g_warning ("gdk_draw_pixmap: DeleteDC failed");
}
else
{
if ((srcdc = GetDC (src_private->xwindow)) == NULL)
g_warning ("gdk_draw_pixmap: GetDC failed");
if (!BitBlt (hdc, xdest, ydest, width, height,
srcdc, xsrc, ysrc, SRCCOPY))
g_warning ("gdk_draw_pixmap: BitBlt failed");
ReleaseDC (src_private->xwindow, srcdc);
}
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_image (GdkDrawable *drawable,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
{
GdkImagePrivate *image_private;
g_return_if_fail (drawable != NULL);
g_return_if_fail (image != NULL);
g_return_if_fail (gc != NULL);
image_private = (GdkImagePrivate*) image;
g_return_if_fail (image_private->image_put != NULL);
if (width == -1)
width = image->width;
if (height == -1)
height = image->height;
(* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
xdest, ydest, width, height);
}
void
gdk_draw_points (GdkDrawable *drawable,
GdkGC *gc,
GdkPoint *points,
gint npoints)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
HBRUSH hbr;
int i;
g_return_if_fail (drawable != NULL);
g_return_if_fail ((points != NULL) && (npoints > 0));
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
hbr = GetCurrentObject (hdc, OBJ_BRUSH);
for (i = 0; i < npoints; i++)
{
RECT rect;
rect.left = points[i].x;
rect.top = points[i].y;
rect.right = rect.left + 1;
rect.bottom = rect.top + 1;
if (!FillRect (hdc, &rect, hbr))
g_warning ("gdk_draw_points: FillRect failed");
}
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_segments (GdkDrawable *drawable,
GdkGC *gc,
GdkSegment *segs,
gint nsegs)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
int i;
if (nsegs <= 0)
return;
g_return_if_fail (drawable != NULL);
g_return_if_fail (segs != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
for (i = 0; i < nsegs; i++)
{
MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL);
if (!LineTo (hdc, segs[i].x2, segs[i].y2))
g_warning ("gdk_draw_segments: LineTo #1 failed");
/* Draw end pixel */
if (gc_private->pen_width == 1)
if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
g_warning ("gdk_draw_segments: LineTo #2 failed");
}
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_lines (GdkDrawable *drawable,
GdkGC *gc,
GdkPoint *points,
gint npoints)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
POINT *pts;
int i;
if (npoints <= 0)
return;
g_return_if_fail (drawable != NULL);
g_return_if_fail (points != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
#if 1
pts = g_malloc (npoints * sizeof (POINT));
for (i = 0; i < npoints; i++)
{
pts[i].x = points[i].x;
pts[i].y = points[i].y;
}
if (!Polyline (hdc, pts, npoints))
g_warning ("gdk_draw_lines: Polyline failed");
g_free (pts);
/* Draw end pixel */
if (gc_private->pen_width == 1)
{
MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
g_warning ("gdk_draw_lines: LineTo failed");
}
#else
MoveToEx (hdc, points[0].x, points[0].y, NULL);
for (i = 1; i < npoints; i++)
if (!LineTo (hdc, points[i].x, points[i].y))
g_warning ("gdk_draw_lines: LineTo #1 failed");
/* Draw end pixel */
if (gc_private->pen_width == 1)
if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
g_warning ("gdk_draw_lines: LineTo #2 failed");
#endif
gdk_gc_postdraw (drawable_private, gc_private);
}

View File

@ -0,0 +1,655 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <math.h>
#include "gdk.h"
#include "gdkprivate.h"
#ifndef M_TWOPI
#define M_TWOPI (2.0 * 3.14159265358979323846)
#endif
void
gdk_draw_point (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
HBRUSH hbr;
RECT rect;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
hbr = GetCurrentObject (hdc, OBJ_BRUSH);
/* We use FillRect because SetPixel wants the COLORREF directly,
* and doesn't use the current brush, which is what we want.
*/
rect.left = x;
rect.top = y;
rect.right = rect.left + 1;
rect.bottom = rect.top + 1;
FillRect (hdc, &rect, hbr);
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_line (GdkDrawable *drawable,
GdkGC *gc,
gint x1,
gint y1,
gint x2,
gint y2)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
GDK_NOTE (MISC, g_print ("gdk_draw_line: %#x (%d) +%d+%d..+%d+%d\n",
drawable_private->xwindow, gc_private,
x1, y1, x2, y2));
MoveToEx (hdc, x1, y1, NULL);
if (!LineTo (hdc, x2, y2))
g_warning ("gdk_draw_line: LineTo #1 failed");
/* LineTo doesn't draw the last point, so if we have a pen width of 1,
* we draw the end pixel separately... With wider pens it hopefully
* doesn't matter?
*/
if (gc_private->pen_width == 1)
if (!LineTo (hdc, x2 + 1, y2))
g_warning ("gdk_draw_line: LineTo #2 failed");
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_rectangle (GdkDrawable *drawable,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
LOGBRUSH lb;
HPEN hpen;
HBRUSH hbr;
HGDIOBJ oldpen, oldbrush;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
if (width == -1)
width = drawable_private->width;
if (height == -1)
height = drawable_private->height;
hdc = gdk_gc_predraw (drawable_private, gc_private);
GDK_NOTE (MISC, g_print ("gdk_draw_rectangle: %#x (%d) %s%dx%d@+%d+%d\n",
drawable_private->xwindow,
gc_private,
(filled ? "fill " : ""),
width, height, x, y));
#if 0
{
HBRUSH hbr = GetCurrentObject (hdc, OBJ_BRUSH);
HPEN hpen = GetCurrentObject (hdc, OBJ_PEN);
LOGBRUSH lbr;
LOGPEN lpen;
GetObject (hbr, sizeof (lbr), &lbr);
GetObject (hpen, sizeof (lpen), &lpen);
g_print ("current brush: style = %s, color = 0x%.08x\n",
(lbr.lbStyle == BS_SOLID ? "SOLID" : "???"),
lbr.lbColor);
g_print ("current pen: style = %s, width = %d, color = 0x%.08x\n",
(lpen.lopnStyle == PS_SOLID ? "SOLID" : "???"),
lpen.lopnWidth,
lpen.lopnColor);
}
#endif
if (filled)
oldpen = SelectObject (hdc, GetStockObject (NULL_PEN));
else
oldbrush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
g_warning ("gdk_draw_rectangle: Rectangle failed");
if (filled)
SelectObject (hdc, oldpen);
else
SelectObject (hdc, oldbrush);
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_arc (GdkDrawable *drawable,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height,
gint angle1,
gint angle2)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
if (width == -1)
width = drawable_private->width;
if (height == -1)
height = drawable_private->height;
hdc = gdk_gc_predraw (drawable_private, gc_private);
nXStartArc = x + width/2 + (int) (sin(angle1/64.*M_TWOPI)*width);
nYStartArc = y + height/2 + (int) (cos(angle1/64.*M_TWOPI)*height);
nXEndArc = x + width/2 + (int) (sin(angle2/64.*M_TWOPI)*width);
nYEndArc = y + height/2 + (int) (cos(angle2/64.*M_TWOPI)*height);
if (filled)
{
if (!Pie (hdc, x, y, x+width, y+height,
nXStartArc, nYStartArc, nXEndArc, nYEndArc))
g_warning ("gdk_draw_arc: Pie failed");
}
else
{
if (!Arc (hdc, x, y, x+width, y+height,
nXStartArc, nYStartArc, nXEndArc, nYEndArc))
g_warning ("gdk_draw_arc: Arc failed");
}
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_polygon (GdkDrawable *drawable,
GdkGC *gc,
gint filled,
GdkPoint *points,
gint npoints)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
POINT *pts;
int i;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
pts = g_malloc ((npoints+1) * sizeof (POINT));
GDK_NOTE (MISC, g_print ("gdk_draw_polygon: %#x (%d) %d\n",
drawable_private->xwindow, gc_private,
npoints));
for (i = 0; i < npoints; i++)
{
pts[i].x = points[i].x;
pts[i].y = points[i].y;
}
if ((points[0].x != points[npoints-1].x) ||
(points[0].y != points[npoints-1].y))
{
pts[npoints].x = points[0].x;
pts[npoints].y = points[0].y;
npoints++;
}
if (filled)
{
if (!Polygon (hdc, pts, npoints))
g_warning ("gdk_draw_polygon: Polygon failed");
}
else
{
if (!Polyline (hdc, pts, npoints))
g_warning ("gdk_draw_polygon: Polyline failed");
}
g_free (pts);
gdk_gc_postdraw (drawable_private, gc_private);
}
/* gdk_draw_string
*/
void
gdk_draw_string (GdkDrawable *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const gchar *string)
{
gdk_draw_text (drawable, font, gc, x, y, string, strlen (string));
}
/* gdk_draw_text
*
* Modified by Li-Da Lho to draw 16 bits and Multibyte strings
*
* Interface changed: add "GdkFont *font" to specify font or fontset explicitely
*/
void
gdk_draw_text (GdkDrawable *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const gchar *text,
gint text_length)
{
GdkWindowPrivate *drawable_private;
GdkFontPrivate *font_private;
GdkGCPrivate *gc_private;
HDC hdc;
HFONT xfont;
HGDIOBJ oldfont;
g_return_if_fail (drawable != NULL);
g_return_if_fail (font != NULL);
g_return_if_fail (gc != NULL);
g_return_if_fail (text != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
if (font->type == GDK_FONT_FONT)
{
hdc = gdk_gc_predraw (drawable_private, gc_private);
xfont = (HFONT) font_private->xfont;
GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
"+%d+%d font: %#x \"%.*s\" length: %d\n",
drawable_private->xwindow,
gc_private, gc_private->xgc,
x, y, xfont,
(text_length > 10 ? 10 : text_length),
text, text_length));
if ((oldfont = SelectObject (hdc, xfont)) == NULL)
g_warning ("gdk_draw_text: SelectObject failed");
if (!TextOutA (hdc, x, y, text, text_length))
g_warning ("gdk_draw_text: TextOutA failed");
SelectObject (hdc, oldfont);
gdk_gc_postdraw (drawable_private, gc_private);
}
else
g_error ("undefined font type");
}
void
gdk_draw_text_wc (GdkDrawable *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const GdkWChar *text,
gint text_length)
{
GdkWindowPrivate *drawable_private;
GdkFontPrivate *font_private;
GdkGCPrivate *gc_private;
gint i;
wchar_t *wcstr;
g_return_if_fail (drawable != NULL);
g_return_if_fail (font != NULL);
g_return_if_fail (gc != NULL);
g_return_if_fail (text != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
if (font->type == GDK_FONT_FONT)
{
HDC hdc;
HFONT xfont;
HGDIOBJ oldfont;
hdc = gdk_gc_predraw (drawable_private, gc_private);
xfont = (HFONT) font_private->xfont;
GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
"+%d+%d font: %#x length: %d\n",
drawable_private->xwindow,
gc_private, gc_private->xgc,
x, y, xfont,
text_length));
if ((oldfont = SelectObject (hdc, xfont)) == NULL)
g_warning ("gdk_draw_text: SelectObject failed");
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
if (!TextOutW (hdc, x, y, wcstr, text_length))
g_warning ("gdk_draw_text: TextOutW failed");
g_free (wcstr);
SelectObject (hdc, oldfont);
gdk_gc_postdraw (drawable_private, gc_private);
}
else
g_error ("undefined font type");
}
void
gdk_draw_pixmap (GdkDrawable *drawable,
GdkGC *gc,
GdkPixmap *src,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
{
GdkWindowPrivate *drawable_private;
GdkWindowPrivate *src_private;
GdkGCPrivate *gc_private;
HDC hdc;
HDC srcdc;
HGDIOBJ hgdiobj;
g_return_if_fail (drawable != NULL);
g_return_if_fail (src != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
src_private = (GdkWindowPrivate*) src;
if (drawable_private->destroyed || src_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
if (width == -1)
width = src_private->width;
if (height == -1)
height = src_private->height;
hdc = gdk_gc_predraw (drawable_private, gc_private);
GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x destdc: (%d) %#x "
"src: %#x %dx%d@+%d+%d\n",
drawable_private->xwindow, gc_private, hdc,
src_private->xwindow,
width, height, xdest, ydest));
/* Strangely enough, this function is called also to bitblt
* from a window.
*/
if (src_private->window_type == GDK_WINDOW_PIXMAP)
{
if ((srcdc = CreateCompatibleDC (hdc)) == NULL)
g_warning ("gdk_draw_pixmap: CreateCompatibleDC failed");
if ((hgdiobj = SelectObject (srcdc, src_private->xwindow)) == NULL)
g_warning ("gdk_draw_pixmap: SelectObject #1 failed");
if (!BitBlt (hdc, xdest, ydest, width, height,
srcdc, xsrc, ysrc, SRCCOPY))
g_warning ("gdk_draw_pixmap: BitBlt failed");
if ((SelectObject (srcdc, hgdiobj) == NULL))
g_warning ("gdk_draw_pixmap: SelectObject #2 failed");
if (!DeleteDC (srcdc))
g_warning ("gdk_draw_pixmap: DeleteDC failed");
}
else
{
if ((srcdc = GetDC (src_private->xwindow)) == NULL)
g_warning ("gdk_draw_pixmap: GetDC failed");
if (!BitBlt (hdc, xdest, ydest, width, height,
srcdc, xsrc, ysrc, SRCCOPY))
g_warning ("gdk_draw_pixmap: BitBlt failed");
ReleaseDC (src_private->xwindow, srcdc);
}
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_image (GdkDrawable *drawable,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
{
GdkImagePrivate *image_private;
g_return_if_fail (drawable != NULL);
g_return_if_fail (image != NULL);
g_return_if_fail (gc != NULL);
image_private = (GdkImagePrivate*) image;
g_return_if_fail (image_private->image_put != NULL);
if (width == -1)
width = image->width;
if (height == -1)
height = image->height;
(* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
xdest, ydest, width, height);
}
void
gdk_draw_points (GdkDrawable *drawable,
GdkGC *gc,
GdkPoint *points,
gint npoints)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
HBRUSH hbr;
int i;
g_return_if_fail (drawable != NULL);
g_return_if_fail ((points != NULL) && (npoints > 0));
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
hbr = GetCurrentObject (hdc, OBJ_BRUSH);
for (i = 0; i < npoints; i++)
{
RECT rect;
rect.left = points[i].x;
rect.top = points[i].y;
rect.right = rect.left + 1;
rect.bottom = rect.top + 1;
if (!FillRect (hdc, &rect, hbr))
g_warning ("gdk_draw_points: FillRect failed");
}
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_segments (GdkDrawable *drawable,
GdkGC *gc,
GdkSegment *segs,
gint nsegs)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
int i;
if (nsegs <= 0)
return;
g_return_if_fail (drawable != NULL);
g_return_if_fail (segs != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
for (i = 0; i < nsegs; i++)
{
MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL);
if (!LineTo (hdc, segs[i].x2, segs[i].y2))
g_warning ("gdk_draw_segments: LineTo #1 failed");
/* Draw end pixel */
if (gc_private->pen_width == 1)
if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
g_warning ("gdk_draw_segments: LineTo #2 failed");
}
gdk_gc_postdraw (drawable_private, gc_private);
}
void
gdk_draw_lines (GdkDrawable *drawable,
GdkGC *gc,
GdkPoint *points,
gint npoints)
{
GdkWindowPrivate *drawable_private;
GdkGCPrivate *gc_private;
HDC hdc;
POINT *pts;
int i;
if (npoints <= 0)
return;
g_return_if_fail (drawable != NULL);
g_return_if_fail (points != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
hdc = gdk_gc_predraw (drawable_private, gc_private);
#if 1
pts = g_malloc (npoints * sizeof (POINT));
for (i = 0; i < npoints; i++)
{
pts[i].x = points[i].x;
pts[i].y = points[i].y;
}
if (!Polyline (hdc, pts, npoints))
g_warning ("gdk_draw_lines: Polyline failed");
g_free (pts);
/* Draw end pixel */
if (gc_private->pen_width == 1)
{
MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
g_warning ("gdk_draw_lines: LineTo failed");
}
#else
MoveToEx (hdc, points[0].x, points[0].y, NULL);
for (i = 1; i < npoints; i++)
if (!LineTo (hdc, points[i].x, points[i].y))
g_warning ("gdk_draw_lines: LineTo #1 failed");
/* Draw end pixel */
if (gc_private->pen_width == 1)
if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
g_warning ("gdk_draw_lines: LineTo #2 failed");
#endif
gdk_gc_postdraw (drawable_private, gc_private);
}

2963
gdk/win32/gdkevents-win32.c Normal file

File diff suppressed because it is too large Load Diff

2963
gdk/win32/gdkevents.c Normal file

File diff suppressed because it is too large Load Diff

697
gdk/win32/gdkfont-win32.c Normal file
View File

@ -0,0 +1,697 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <stdio.h>
#include <ctype.h>
#include "gdk.h"
#include "gdkprivate.h"
GdkFont*
gdk_font_load (const gchar *font_name)
{
GdkFont *font;
GdkFontPrivate *private;
LOGFONT logfont;
HGDIOBJ oldfont;
TEXTMETRIC textmetric;
HANDLE *f;
DWORD fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet,
fdwOutputPrecision, fdwClipPrecision, fdwQuality, fdwPitchAndFamily;
const char *lpszFace;
int numfields, n1, n2, tries;
char foundry[32], family[100], weight[32], slant[32], set_width[32],
spacing[32], registry[32], encoding[32];
char pixel_size[10], point_size[10], res_x[10], res_y[10], avg_width[10];
int c;
char *p;
int nHeight, nWidth, nEscapement, nOrientation, fnWeight;
int logpixelsy;
private = g_new (GdkFontPrivate, 1);
font = (GdkFont*) private;
numfields = sscanf (font_name,
"-%30[^-]-%100[^-]-%30[^-]-%30[^-]-%30[^-]-%n",
foundry,
family,
weight,
slant,
set_width,
&n1);
if (numfields == 0)
{
/* Probably a plain Windows font name */
nHeight = 0;
nWidth = 0;
nEscapement = 0;
nOrientation = 0;
fnWeight = FW_DONTCARE;
fdwItalic = FALSE;
fdwUnderline = FALSE;
fdwStrikeOut = FALSE;
fdwCharSet = ANSI_CHARSET;
fdwOutputPrecision = OUT_TT_PRECIS;
fdwClipPrecision = CLIP_DEFAULT_PRECIS;
fdwQuality = PROOF_QUALITY;
fdwPitchAndFamily = DEFAULT_PITCH;
lpszFace = font_name;
}
else if (numfields != 5)
{
g_warning ("gdk_font_load: font name %s illegal", font_name);
g_free (font);
return NULL;
}
else
{
/* It must be a XLFD name */
/* Check for hex escapes in the font family,
* put in there by gtkfontsel.
*/
p = family;
while (*p)
{
if (*p == '%' && isxdigit (p[1]) && isxdigit (p[2]))
{
sscanf (p+1, "%2x", &c);
*p = c;
strcpy (p+1, p+3);
}
p++;
}
/* Skip add_style which often is empty in the requested font name */
while (font_name[n1] && font_name[n1] != '-')
n1++;
numfields++;
numfields += sscanf (font_name + n1,
"-%8[^-]-%8[^-]-%8[^-]-%8[^-]-%30[^-]-%8[^-]-%30[^-]-%30[^-]%n",
pixel_size,
point_size,
res_x,
res_y,
spacing,
avg_width,
registry,
encoding,
&n2);
if (numfields != 14 || font_name[n1 + n2] != '\0')
{
g_warning ("gdk_font_load: font name %s illegal", font_name);
g_free (font);
return NULL;
}
logpixelsy = GetDeviceCaps (gdk_DC, LOGPIXELSY);
if (strcmp (pixel_size, "*") == 0)
if (strcmp (point_size, "*") == 0)
nHeight = 0;
else
nHeight = (int) (((double) atoi (point_size))/720.*logpixelsy);
else
nHeight = atoi (pixel_size);
nWidth = 0;
nEscapement = 0;
nOrientation = 0;
if (g_strcasecmp (weight, "thin") == 0)
fnWeight = FW_THIN;
else if (g_strcasecmp (weight, "extralight") == 0)
fnWeight = FW_EXTRALIGHT;
else if (g_strcasecmp (weight, "ultralight") == 0)
fnWeight = FW_ULTRALIGHT;
else if (g_strcasecmp (weight, "light") == 0)
fnWeight = FW_LIGHT;
else if (g_strcasecmp (weight, "normal") == 0)
fnWeight = FW_NORMAL;
else if (g_strcasecmp (weight, "regular") == 0)
fnWeight = FW_REGULAR;
else if (g_strcasecmp (weight, "medium") == 0)
fnWeight = FW_MEDIUM;
else if (g_strcasecmp (weight, "semibold") == 0)
fnWeight = FW_SEMIBOLD;
else if (g_strcasecmp (weight, "demibold") == 0)
fnWeight = FW_DEMIBOLD;
else if (g_strcasecmp (weight, "bold") == 0)
fnWeight = FW_BOLD;
else if (g_strcasecmp (weight, "extrabold") == 0)
fnWeight = FW_EXTRABOLD;
else if (g_strcasecmp (weight, "ultrabold") == 0)
fnWeight = FW_ULTRABOLD;
else if (g_strcasecmp (weight, "heavy") == 0)
fnWeight = FW_HEAVY;
else if (g_strcasecmp (weight, "black") == 0)
fnWeight = FW_BLACK;
else
fnWeight = FW_DONTCARE;
if (g_strcasecmp (slant, "italic") == 0
|| g_strcasecmp (slant, "oblique") == 0
|| g_strcasecmp (slant, "i") == 0
|| g_strcasecmp (slant, "o") == 0)
fdwItalic = TRUE;
else
fdwItalic = FALSE;
fdwUnderline = FALSE;
fdwStrikeOut = FALSE;
if (g_strcasecmp (registry, "iso8859") == 0)
if (strcmp (encoding, "1") == 0)
fdwCharSet = ANSI_CHARSET;
else
fdwCharSet = ANSI_CHARSET; /* XXX ??? */
else if (g_strcasecmp (registry, "windows") == 0)
if (g_strcasecmp (encoding, "symbol") == 0)
fdwCharSet = SYMBOL_CHARSET;
else if (g_strcasecmp (encoding, "shiftjis") == 0)
fdwCharSet = SHIFTJIS_CHARSET;
else if (g_strcasecmp (encoding, "gb2312") == 0)
fdwCharSet = GB2312_CHARSET;
else if (g_strcasecmp (encoding, "hangeul") == 0)
fdwCharSet = HANGEUL_CHARSET;
else if (g_strcasecmp (encoding, "chinesebig5") == 0)
fdwCharSet = CHINESEBIG5_CHARSET;
else if (g_strcasecmp (encoding, "johab") == 0)
fdwCharSet = JOHAB_CHARSET;
else if (g_strcasecmp (encoding, "hebrew") == 0)
fdwCharSet = HEBREW_CHARSET;
else if (g_strcasecmp (encoding, "arabic") == 0)
fdwCharSet = ARABIC_CHARSET;
else if (g_strcasecmp (encoding, "greek") == 0)
fdwCharSet = GREEK_CHARSET;
else if (g_strcasecmp (encoding, "turkish") == 0)
fdwCharSet = TURKISH_CHARSET;
else if (g_strcasecmp (encoding, "easteurope") == 0)
fdwCharSet = EASTEUROPE_CHARSET;
else if (g_strcasecmp (encoding, "russian") == 0)
fdwCharSet = RUSSIAN_CHARSET;
else if (g_strcasecmp (encoding, "mac") == 0)
fdwCharSet = MAC_CHARSET;
else if (g_strcasecmp (encoding, "baltic") == 0)
fdwCharSet = BALTIC_CHARSET;
else
fdwCharSet = ANSI_CHARSET; /* XXX ??? */
else
fdwCharSet = ANSI_CHARSET; /* XXX ??? */
fdwOutputPrecision = OUT_TT_PRECIS;
fdwClipPrecision = CLIP_DEFAULT_PRECIS;
fdwQuality = PROOF_QUALITY;
if (g_strcasecmp (spacing, "m") == 0)
fdwPitchAndFamily = FIXED_PITCH;
else if (g_strcasecmp (spacing, "p") == 0)
fdwPitchAndFamily = VARIABLE_PITCH;
else
fdwPitchAndFamily = DEFAULT_PITCH;
lpszFace = family;
}
for (tries = 0; ; tries++)
{
GDK_NOTE (MISC, g_print ("gdk_font_load: trying CreateFont(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%#.02x,\"%s\")\n",
nHeight, nWidth, nEscapement, nOrientation,
fnWeight, fdwItalic, fdwUnderline, fdwStrikeOut,
fdwCharSet, fdwOutputPrecision, fdwClipPrecision,
fdwQuality, fdwPitchAndFamily, lpszFace));
if ((private->xfont =
CreateFont (nHeight, nWidth, nEscapement, nOrientation,
fnWeight, fdwItalic, fdwUnderline, fdwStrikeOut,
fdwCharSet, fdwOutputPrecision, fdwClipPrecision,
fdwQuality, fdwPitchAndFamily, lpszFace)) != NULL)
break;
/* If we fail, try some similar fonts often found on Windows. */
if (tries == 0)
{
if (g_strcasecmp (family, "helvetica") == 0)
lpszFace = "arial";
else if (g_strcasecmp (family, "new century schoolbook") == 0)
lpszFace = "century schoolbook";
else if (g_strcasecmp (family, "courier") == 0)
lpszFace = "courier new";
else if (g_strcasecmp (family, "lucida") == 0)
lpszFace = "lucida sans unicode";
else if (g_strcasecmp (family, "lucidatypewriter") == 0)
lpszFace = "lucida console";
else if (g_strcasecmp (family, "times") == 0)
lpszFace = "times new roman";
}
else if (tries == 1)
{
if (g_strcasecmp (family, "courier") == 0)
{
lpszFace = "";
fdwPitchAndFamily |= FF_MODERN;
}
else if (g_strcasecmp (family, "times new roman") == 0)
{
lpszFace = "";
fdwPitchAndFamily |= FF_ROMAN;
}
else if (g_strcasecmp (family, "helvetica") == 0
|| g_strcasecmp (family, "lucida") == 0)
{
lpszFace = "";
fdwPitchAndFamily |= FF_SWISS;
}
else
{
lpszFace = "";
fdwPitchAndFamily = (fdwPitchAndFamily & 0x0F) | FF_DONTCARE;
}
}
else
break;
tries++;
}
if (!private->xfont)
{
g_warning ("gdk_font_load: font %s not found", font_name);
g_free (font);
return NULL;
}
private->ref_count = 1;
font->type = GDK_FONT_FONT;
GetObject (private->xfont, sizeof (logfont), &logfont);
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextMetrics (gdk_DC, &textmetric);
SelectObject (gdk_DC, oldfont);
font->ascent = textmetric.tmAscent;
font->descent = textmetric.tmDescent;
GDK_NOTE (MISC, g_print ("gdk_font_load: %s = %#x asc %d desc %d\n",
font_name, private->xfont,
font->ascent, font->descent));
/* This memory is leaked, so shoot me. */
f = g_new (HANDLE, 1);
*f = (HANDLE) ((guint) private->xfont + HFONT_DITHER);
gdk_xid_table_insert (f, font);
return font;
}
GdkFont*
gdk_fontset_load (gchar *fontset_name)
{
g_warning ("gdk_fontset_load: Not implemented");
return NULL;
}
GdkFont*
gdk_font_ref (GdkFont *font)
{
GdkFontPrivate *private;
g_return_val_if_fail (font != NULL, NULL);
private = (GdkFontPrivate*) font;
private->ref_count += 1;
return font;
}
void
gdk_font_unref (GdkFont *font)
{
GdkFontPrivate *private;
g_return_if_fail (font != NULL);
private = (GdkFontPrivate*) font;
private->ref_count -= 1;
if (private->ref_count == 0)
{
switch (font->type)
{
case GDK_FONT_FONT:
GDK_NOTE (MISC, g_print ("gdk_font_unref %#x\n", private->xfont));
gdk_xid_table_remove ((HANDLE) ((guint) private->xfont + HFONT_DITHER));
DeleteObject (private->xfont);
break;
default:
g_assert_not_reached ();
}
g_free (font);
}
}
gint
gdk_font_id (const GdkFont *font)
{
const GdkFontPrivate *font_private;
g_return_val_if_fail (font != NULL, 0);
font_private = (const GdkFontPrivate*) font;
if (font->type == GDK_FONT_FONT)
return (gint) font_private->xfont;
g_assert_not_reached ();
return 0;
}
gint
gdk_font_equal (const GdkFont *fonta,
const GdkFont *fontb)
{
const GdkFontPrivate *privatea;
const GdkFontPrivate *privateb;
g_return_val_if_fail (fonta != NULL, FALSE);
g_return_val_if_fail (fontb != NULL, FALSE);
privatea = (const GdkFontPrivate*) fonta;
privateb = (const GdkFontPrivate*) fontb;
if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
return (privatea->xfont == privateb->xfont);
g_assert_not_reached ();
return 0;
}
gint
gdk_string_width (GdkFont *font,
const gchar *string)
{
return gdk_text_width (font, string, strlen (string));
}
gint
gdk_text_width (GdkFont *font,
const gchar *text,
gint text_length)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
gint width;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
SelectObject (gdk_DC, oldfont);
width = size.cx;
break;
default:
g_assert_not_reached ();
}
return width;
}
gint
gdk_text_width_wc (GdkFont *font,
const GdkWChar *text,
gint text_length)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
wchar_t *wcstr;
gint i, width;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
g_free (wcstr);
SelectObject (gdk_DC, oldfont);
width = size.cx;
break;
default:
width = 0;
}
return width;
}
gint
gdk_char_width (GdkFont *font,
gchar character)
{
return gdk_text_width (font, &character, 1);
}
gint
gdk_char_width_wc (GdkFont *font,
GdkWChar character)
{
return gdk_text_width_wc (font, &character, 1);
}
gint
gdk_string_measure (GdkFont *font,
const gchar *string)
{
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (string != NULL, -1);
return gdk_text_measure (font, string, strlen (string));
}
void
gdk_text_extents (GdkFont *font,
const gchar *text,
gint text_length,
gint *lbearing,
gint *rbearing,
gint *width,
gint *ascent,
gint *descent)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
SelectObject (gdk_DC, oldfont);
/* XXX This is all quite bogus */
if (lbearing)
*lbearing = 0;
if (rbearing)
*rbearing = 0;
if (width)
*width = size.cx;
if (ascent)
*ascent = size.cy + 1;
if (descent)
*descent = font->descent + 1;
break;
default:
g_assert_not_reached ();
}
}
void
gdk_text_extents_wc (GdkFont *font,
const GdkWChar *text,
gint text_length,
gint *lbearing,
gint *rbearing,
gint *width,
gint *ascent,
gint *descent)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
wchar_t *wcstr;
gint i;
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
g_free (wcstr);
SelectObject (gdk_DC, oldfont);
/* XXX This is all quite bogus */
if (lbearing)
*lbearing = 0;
if (rbearing)
*rbearing = 0;
if (width)
*width = size.cx;
if (ascent)
*ascent = size.cy + 1;
if (descent)
*descent = font->descent + 1;
break;
default:
g_assert_not_reached ();
}
}
void
gdk_string_extents (GdkFont *font,
const gchar *string,
gint *lbearing,
gint *rbearing,
gint *width,
gint *ascent,
gint *descent)
{
g_return_if_fail (font != NULL);
g_return_if_fail (string != NULL);
gdk_text_extents (font, string, strlen (string),
lbearing, rbearing, width, ascent, descent);
}
gint
gdk_text_measure (GdkFont *font,
const gchar *text,
gint text_length)
{
GdkFontPrivate *private;
gint width;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
return gdk_text_width (font, text, text_length); /* ??? */
break;
default:
g_assert_not_reached ();
}
return 0;
}
gint
gdk_char_measure (GdkFont *font,
gchar character)
{
g_return_val_if_fail (font != NULL, -1);
return gdk_text_measure (font, &character, 1);
}
gint
gdk_string_height (GdkFont *font,
const gchar *string)
{
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (string != NULL, -1);
return gdk_text_height (font, string, strlen (string));
}
gint
gdk_text_height (GdkFont *font,
const gchar *text,
gint text_length)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
gint height;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32 (gdk_DC, text, text_length, &size);
SelectObject (gdk_DC, oldfont);
height = size.cy;
break;
default:
g_error ("font->type = %d", font->type);
}
return height;
}
gint
gdk_char_height (GdkFont *font,
gchar character)
{
g_return_val_if_fail (font != NULL, -1);
return gdk_text_height (font, &character, 1);
}

697
gdk/win32/gdkfont.c Normal file
View File

@ -0,0 +1,697 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <stdio.h>
#include <ctype.h>
#include "gdk.h"
#include "gdkprivate.h"
GdkFont*
gdk_font_load (const gchar *font_name)
{
GdkFont *font;
GdkFontPrivate *private;
LOGFONT logfont;
HGDIOBJ oldfont;
TEXTMETRIC textmetric;
HANDLE *f;
DWORD fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet,
fdwOutputPrecision, fdwClipPrecision, fdwQuality, fdwPitchAndFamily;
const char *lpszFace;
int numfields, n1, n2, tries;
char foundry[32], family[100], weight[32], slant[32], set_width[32],
spacing[32], registry[32], encoding[32];
char pixel_size[10], point_size[10], res_x[10], res_y[10], avg_width[10];
int c;
char *p;
int nHeight, nWidth, nEscapement, nOrientation, fnWeight;
int logpixelsy;
private = g_new (GdkFontPrivate, 1);
font = (GdkFont*) private;
numfields = sscanf (font_name,
"-%30[^-]-%100[^-]-%30[^-]-%30[^-]-%30[^-]-%n",
foundry,
family,
weight,
slant,
set_width,
&n1);
if (numfields == 0)
{
/* Probably a plain Windows font name */
nHeight = 0;
nWidth = 0;
nEscapement = 0;
nOrientation = 0;
fnWeight = FW_DONTCARE;
fdwItalic = FALSE;
fdwUnderline = FALSE;
fdwStrikeOut = FALSE;
fdwCharSet = ANSI_CHARSET;
fdwOutputPrecision = OUT_TT_PRECIS;
fdwClipPrecision = CLIP_DEFAULT_PRECIS;
fdwQuality = PROOF_QUALITY;
fdwPitchAndFamily = DEFAULT_PITCH;
lpszFace = font_name;
}
else if (numfields != 5)
{
g_warning ("gdk_font_load: font name %s illegal", font_name);
g_free (font);
return NULL;
}
else
{
/* It must be a XLFD name */
/* Check for hex escapes in the font family,
* put in there by gtkfontsel.
*/
p = family;
while (*p)
{
if (*p == '%' && isxdigit (p[1]) && isxdigit (p[2]))
{
sscanf (p+1, "%2x", &c);
*p = c;
strcpy (p+1, p+3);
}
p++;
}
/* Skip add_style which often is empty in the requested font name */
while (font_name[n1] && font_name[n1] != '-')
n1++;
numfields++;
numfields += sscanf (font_name + n1,
"-%8[^-]-%8[^-]-%8[^-]-%8[^-]-%30[^-]-%8[^-]-%30[^-]-%30[^-]%n",
pixel_size,
point_size,
res_x,
res_y,
spacing,
avg_width,
registry,
encoding,
&n2);
if (numfields != 14 || font_name[n1 + n2] != '\0')
{
g_warning ("gdk_font_load: font name %s illegal", font_name);
g_free (font);
return NULL;
}
logpixelsy = GetDeviceCaps (gdk_DC, LOGPIXELSY);
if (strcmp (pixel_size, "*") == 0)
if (strcmp (point_size, "*") == 0)
nHeight = 0;
else
nHeight = (int) (((double) atoi (point_size))/720.*logpixelsy);
else
nHeight = atoi (pixel_size);
nWidth = 0;
nEscapement = 0;
nOrientation = 0;
if (g_strcasecmp (weight, "thin") == 0)
fnWeight = FW_THIN;
else if (g_strcasecmp (weight, "extralight") == 0)
fnWeight = FW_EXTRALIGHT;
else if (g_strcasecmp (weight, "ultralight") == 0)
fnWeight = FW_ULTRALIGHT;
else if (g_strcasecmp (weight, "light") == 0)
fnWeight = FW_LIGHT;
else if (g_strcasecmp (weight, "normal") == 0)
fnWeight = FW_NORMAL;
else if (g_strcasecmp (weight, "regular") == 0)
fnWeight = FW_REGULAR;
else if (g_strcasecmp (weight, "medium") == 0)
fnWeight = FW_MEDIUM;
else if (g_strcasecmp (weight, "semibold") == 0)
fnWeight = FW_SEMIBOLD;
else if (g_strcasecmp (weight, "demibold") == 0)
fnWeight = FW_DEMIBOLD;
else if (g_strcasecmp (weight, "bold") == 0)
fnWeight = FW_BOLD;
else if (g_strcasecmp (weight, "extrabold") == 0)
fnWeight = FW_EXTRABOLD;
else if (g_strcasecmp (weight, "ultrabold") == 0)
fnWeight = FW_ULTRABOLD;
else if (g_strcasecmp (weight, "heavy") == 0)
fnWeight = FW_HEAVY;
else if (g_strcasecmp (weight, "black") == 0)
fnWeight = FW_BLACK;
else
fnWeight = FW_DONTCARE;
if (g_strcasecmp (slant, "italic") == 0
|| g_strcasecmp (slant, "oblique") == 0
|| g_strcasecmp (slant, "i") == 0
|| g_strcasecmp (slant, "o") == 0)
fdwItalic = TRUE;
else
fdwItalic = FALSE;
fdwUnderline = FALSE;
fdwStrikeOut = FALSE;
if (g_strcasecmp (registry, "iso8859") == 0)
if (strcmp (encoding, "1") == 0)
fdwCharSet = ANSI_CHARSET;
else
fdwCharSet = ANSI_CHARSET; /* XXX ??? */
else if (g_strcasecmp (registry, "windows") == 0)
if (g_strcasecmp (encoding, "symbol") == 0)
fdwCharSet = SYMBOL_CHARSET;
else if (g_strcasecmp (encoding, "shiftjis") == 0)
fdwCharSet = SHIFTJIS_CHARSET;
else if (g_strcasecmp (encoding, "gb2312") == 0)
fdwCharSet = GB2312_CHARSET;
else if (g_strcasecmp (encoding, "hangeul") == 0)
fdwCharSet = HANGEUL_CHARSET;
else if (g_strcasecmp (encoding, "chinesebig5") == 0)
fdwCharSet = CHINESEBIG5_CHARSET;
else if (g_strcasecmp (encoding, "johab") == 0)
fdwCharSet = JOHAB_CHARSET;
else if (g_strcasecmp (encoding, "hebrew") == 0)
fdwCharSet = HEBREW_CHARSET;
else if (g_strcasecmp (encoding, "arabic") == 0)
fdwCharSet = ARABIC_CHARSET;
else if (g_strcasecmp (encoding, "greek") == 0)
fdwCharSet = GREEK_CHARSET;
else if (g_strcasecmp (encoding, "turkish") == 0)
fdwCharSet = TURKISH_CHARSET;
else if (g_strcasecmp (encoding, "easteurope") == 0)
fdwCharSet = EASTEUROPE_CHARSET;
else if (g_strcasecmp (encoding, "russian") == 0)
fdwCharSet = RUSSIAN_CHARSET;
else if (g_strcasecmp (encoding, "mac") == 0)
fdwCharSet = MAC_CHARSET;
else if (g_strcasecmp (encoding, "baltic") == 0)
fdwCharSet = BALTIC_CHARSET;
else
fdwCharSet = ANSI_CHARSET; /* XXX ??? */
else
fdwCharSet = ANSI_CHARSET; /* XXX ??? */
fdwOutputPrecision = OUT_TT_PRECIS;
fdwClipPrecision = CLIP_DEFAULT_PRECIS;
fdwQuality = PROOF_QUALITY;
if (g_strcasecmp (spacing, "m") == 0)
fdwPitchAndFamily = FIXED_PITCH;
else if (g_strcasecmp (spacing, "p") == 0)
fdwPitchAndFamily = VARIABLE_PITCH;
else
fdwPitchAndFamily = DEFAULT_PITCH;
lpszFace = family;
}
for (tries = 0; ; tries++)
{
GDK_NOTE (MISC, g_print ("gdk_font_load: trying CreateFont(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%#.02x,\"%s\")\n",
nHeight, nWidth, nEscapement, nOrientation,
fnWeight, fdwItalic, fdwUnderline, fdwStrikeOut,
fdwCharSet, fdwOutputPrecision, fdwClipPrecision,
fdwQuality, fdwPitchAndFamily, lpszFace));
if ((private->xfont =
CreateFont (nHeight, nWidth, nEscapement, nOrientation,
fnWeight, fdwItalic, fdwUnderline, fdwStrikeOut,
fdwCharSet, fdwOutputPrecision, fdwClipPrecision,
fdwQuality, fdwPitchAndFamily, lpszFace)) != NULL)
break;
/* If we fail, try some similar fonts often found on Windows. */
if (tries == 0)
{
if (g_strcasecmp (family, "helvetica") == 0)
lpszFace = "arial";
else if (g_strcasecmp (family, "new century schoolbook") == 0)
lpszFace = "century schoolbook";
else if (g_strcasecmp (family, "courier") == 0)
lpszFace = "courier new";
else if (g_strcasecmp (family, "lucida") == 0)
lpszFace = "lucida sans unicode";
else if (g_strcasecmp (family, "lucidatypewriter") == 0)
lpszFace = "lucida console";
else if (g_strcasecmp (family, "times") == 0)
lpszFace = "times new roman";
}
else if (tries == 1)
{
if (g_strcasecmp (family, "courier") == 0)
{
lpszFace = "";
fdwPitchAndFamily |= FF_MODERN;
}
else if (g_strcasecmp (family, "times new roman") == 0)
{
lpszFace = "";
fdwPitchAndFamily |= FF_ROMAN;
}
else if (g_strcasecmp (family, "helvetica") == 0
|| g_strcasecmp (family, "lucida") == 0)
{
lpszFace = "";
fdwPitchAndFamily |= FF_SWISS;
}
else
{
lpszFace = "";
fdwPitchAndFamily = (fdwPitchAndFamily & 0x0F) | FF_DONTCARE;
}
}
else
break;
tries++;
}
if (!private->xfont)
{
g_warning ("gdk_font_load: font %s not found", font_name);
g_free (font);
return NULL;
}
private->ref_count = 1;
font->type = GDK_FONT_FONT;
GetObject (private->xfont, sizeof (logfont), &logfont);
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextMetrics (gdk_DC, &textmetric);
SelectObject (gdk_DC, oldfont);
font->ascent = textmetric.tmAscent;
font->descent = textmetric.tmDescent;
GDK_NOTE (MISC, g_print ("gdk_font_load: %s = %#x asc %d desc %d\n",
font_name, private->xfont,
font->ascent, font->descent));
/* This memory is leaked, so shoot me. */
f = g_new (HANDLE, 1);
*f = (HANDLE) ((guint) private->xfont + HFONT_DITHER);
gdk_xid_table_insert (f, font);
return font;
}
GdkFont*
gdk_fontset_load (gchar *fontset_name)
{
g_warning ("gdk_fontset_load: Not implemented");
return NULL;
}
GdkFont*
gdk_font_ref (GdkFont *font)
{
GdkFontPrivate *private;
g_return_val_if_fail (font != NULL, NULL);
private = (GdkFontPrivate*) font;
private->ref_count += 1;
return font;
}
void
gdk_font_unref (GdkFont *font)
{
GdkFontPrivate *private;
g_return_if_fail (font != NULL);
private = (GdkFontPrivate*) font;
private->ref_count -= 1;
if (private->ref_count == 0)
{
switch (font->type)
{
case GDK_FONT_FONT:
GDK_NOTE (MISC, g_print ("gdk_font_unref %#x\n", private->xfont));
gdk_xid_table_remove ((HANDLE) ((guint) private->xfont + HFONT_DITHER));
DeleteObject (private->xfont);
break;
default:
g_assert_not_reached ();
}
g_free (font);
}
}
gint
gdk_font_id (const GdkFont *font)
{
const GdkFontPrivate *font_private;
g_return_val_if_fail (font != NULL, 0);
font_private = (const GdkFontPrivate*) font;
if (font->type == GDK_FONT_FONT)
return (gint) font_private->xfont;
g_assert_not_reached ();
return 0;
}
gint
gdk_font_equal (const GdkFont *fonta,
const GdkFont *fontb)
{
const GdkFontPrivate *privatea;
const GdkFontPrivate *privateb;
g_return_val_if_fail (fonta != NULL, FALSE);
g_return_val_if_fail (fontb != NULL, FALSE);
privatea = (const GdkFontPrivate*) fonta;
privateb = (const GdkFontPrivate*) fontb;
if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
return (privatea->xfont == privateb->xfont);
g_assert_not_reached ();
return 0;
}
gint
gdk_string_width (GdkFont *font,
const gchar *string)
{
return gdk_text_width (font, string, strlen (string));
}
gint
gdk_text_width (GdkFont *font,
const gchar *text,
gint text_length)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
gint width;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
SelectObject (gdk_DC, oldfont);
width = size.cx;
break;
default:
g_assert_not_reached ();
}
return width;
}
gint
gdk_text_width_wc (GdkFont *font,
const GdkWChar *text,
gint text_length)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
wchar_t *wcstr;
gint i, width;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
g_free (wcstr);
SelectObject (gdk_DC, oldfont);
width = size.cx;
break;
default:
width = 0;
}
return width;
}
gint
gdk_char_width (GdkFont *font,
gchar character)
{
return gdk_text_width (font, &character, 1);
}
gint
gdk_char_width_wc (GdkFont *font,
GdkWChar character)
{
return gdk_text_width_wc (font, &character, 1);
}
gint
gdk_string_measure (GdkFont *font,
const gchar *string)
{
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (string != NULL, -1);
return gdk_text_measure (font, string, strlen (string));
}
void
gdk_text_extents (GdkFont *font,
const gchar *text,
gint text_length,
gint *lbearing,
gint *rbearing,
gint *width,
gint *ascent,
gint *descent)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
SelectObject (gdk_DC, oldfont);
/* XXX This is all quite bogus */
if (lbearing)
*lbearing = 0;
if (rbearing)
*rbearing = 0;
if (width)
*width = size.cx;
if (ascent)
*ascent = size.cy + 1;
if (descent)
*descent = font->descent + 1;
break;
default:
g_assert_not_reached ();
}
}
void
gdk_text_extents_wc (GdkFont *font,
const GdkWChar *text,
gint text_length,
gint *lbearing,
gint *rbearing,
gint *width,
gint *ascent,
gint *descent)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
wchar_t *wcstr;
gint i;
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
g_free (wcstr);
SelectObject (gdk_DC, oldfont);
/* XXX This is all quite bogus */
if (lbearing)
*lbearing = 0;
if (rbearing)
*rbearing = 0;
if (width)
*width = size.cx;
if (ascent)
*ascent = size.cy + 1;
if (descent)
*descent = font->descent + 1;
break;
default:
g_assert_not_reached ();
}
}
void
gdk_string_extents (GdkFont *font,
const gchar *string,
gint *lbearing,
gint *rbearing,
gint *width,
gint *ascent,
gint *descent)
{
g_return_if_fail (font != NULL);
g_return_if_fail (string != NULL);
gdk_text_extents (font, string, strlen (string),
lbearing, rbearing, width, ascent, descent);
}
gint
gdk_text_measure (GdkFont *font,
const gchar *text,
gint text_length)
{
GdkFontPrivate *private;
gint width;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
return gdk_text_width (font, text, text_length); /* ??? */
break;
default:
g_assert_not_reached ();
}
return 0;
}
gint
gdk_char_measure (GdkFont *font,
gchar character)
{
g_return_val_if_fail (font != NULL, -1);
return gdk_text_measure (font, &character, 1);
}
gint
gdk_string_height (GdkFont *font,
const gchar *string)
{
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (string != NULL, -1);
return gdk_text_height (font, string, strlen (string));
}
gint
gdk_text_height (GdkFont *font,
const gchar *text,
gint text_length)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
gint height;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextExtentPoint32 (gdk_DC, text, text_length, &size);
SelectObject (gdk_DC, oldfont);
height = size.cy;
break;
default:
g_error ("font->type = %d", font->type);
}
return height;
}
gint
gdk_char_height (GdkFont *font,
gchar character)
{
g_return_val_if_fail (font != NULL, -1);
return gdk_text_height (font, &character, 1);
}

1373
gdk/win32/gdkgc-win32.c Normal file

File diff suppressed because it is too large Load Diff

1373
gdk/win32/gdkgc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <stdio.h>
#if !defined (X_DISPLAY_MISSING)
#include <X11/Xlib.h>
#endif
#include "gdk.h"
#include "gdkprivate.h"
guint gdk_debug_flags = 0;
HWND gdk_root_window;
HWND gdk_leader_window;
GdkWindowPrivate gdk_root_parent = { { NULL, }, NULL, };
#if !defined(X_DISPLAY_MISSING)
gchar *gdk_display_name = NULL;
gint gdk_use_xshm = TRUE;
Atom gdk_wm_delete_window;
Atom gdk_wm_take_focus;
Atom gdk_wm_protocols;
Atom gdk_wm_window_protocols[2];
GdkDndCursorInfo gdk_dnd_cursorinfo = {None, None, NULL, NULL,
{0,0}, {0,0}, NULL};
GdkDndGlobals gdk_dnd = {None,None,None,
None,None,None,
None,
&gdk_dnd_cursorinfo,
NULL,
0,
FALSE, FALSE, FALSE,
None,
{0,0},
{0,0}, {0,0},
{0,0,0,0}, NULL, None, 0};
#elif defined (WINDOWS_DISPLAY)
HDC gdk_DC;
HINSTANCE gdk_DLLInstance;
HINSTANCE gdk_ProgInstance;
UINT gdk_selection_notify_msg;
UINT gdk_selection_request_msg;
UINT gdk_selection_clear_msg;
GdkAtom gdk_clipboard_atom;
GdkAtom gdk_win32_dropfiles_atom;
GdkAtom gdk_ole2_dnd_atom;
#endif /* WINDOWS_DISPLAY */
Atom gdk_selection_property;
gchar *gdk_progclass = NULL;
gint gdk_error_code;
gint gdk_error_warnings = TRUE;
gint gdk_null_window_warnings = TRUE;
GList *gdk_default_filters = NULL;
gboolean gdk_xim_using; /* using XIM Protocol if TRUE */
GdkWindow *gdk_xim_window; /* currently using Widow */
GdkWindowPrivate *gdk_xgrab_window = NULL; /* Window that currently holds the
* x pointer grab
*/
GMutex *gdk_threads_mutex = NULL; /* Global GDK lock */
#ifdef USE_XIM
GdkICPrivate *gdk_xim_ic; /* currently using IC */
GdkWindow *gdk_xim_window; /* currently using Window */
#endif

94
gdk/win32/gdkglobals.c Normal file
View File

@ -0,0 +1,94 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <stdio.h>
#if !defined (X_DISPLAY_MISSING)
#include <X11/Xlib.h>
#endif
#include "gdk.h"
#include "gdkprivate.h"
guint gdk_debug_flags = 0;
HWND gdk_root_window;
HWND gdk_leader_window;
GdkWindowPrivate gdk_root_parent = { { NULL, }, NULL, };
#if !defined(X_DISPLAY_MISSING)
gchar *gdk_display_name = NULL;
gint gdk_use_xshm = TRUE;
Atom gdk_wm_delete_window;
Atom gdk_wm_take_focus;
Atom gdk_wm_protocols;
Atom gdk_wm_window_protocols[2];
GdkDndCursorInfo gdk_dnd_cursorinfo = {None, None, NULL, NULL,
{0,0}, {0,0}, NULL};
GdkDndGlobals gdk_dnd = {None,None,None,
None,None,None,
None,
&gdk_dnd_cursorinfo,
NULL,
0,
FALSE, FALSE, FALSE,
None,
{0,0},
{0,0}, {0,0},
{0,0,0,0}, NULL, None, 0};
#elif defined (WINDOWS_DISPLAY)
HDC gdk_DC;
HINSTANCE gdk_DLLInstance;
HINSTANCE gdk_ProgInstance;
UINT gdk_selection_notify_msg;
UINT gdk_selection_request_msg;
UINT gdk_selection_clear_msg;
GdkAtom gdk_clipboard_atom;
GdkAtom gdk_win32_dropfiles_atom;
GdkAtom gdk_ole2_dnd_atom;
#endif /* WINDOWS_DISPLAY */
Atom gdk_selection_property;
gchar *gdk_progclass = NULL;
gint gdk_error_code;
gint gdk_error_warnings = TRUE;
gint gdk_null_window_warnings = TRUE;
GList *gdk_default_filters = NULL;
gboolean gdk_xim_using; /* using XIM Protocol if TRUE */
GdkWindow *gdk_xim_window; /* currently using Widow */
GdkWindowPrivate *gdk_xgrab_window = NULL; /* Window that currently holds the
* x pointer grab
*/
GMutex *gdk_threads_mutex = NULL; /* Global GDK lock */
#ifdef USE_XIM
GdkICPrivate *gdk_xim_ic; /* currently using IC */
GdkWindow *gdk_xim_window; /* currently using Window */
#endif

248
gdk/win32/gdkim-win32.c Normal file
View File

@ -0,0 +1,248 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#if HAVE_CONFIG_H
# include <config.h>
# if STDC_HEADERS
# include <string.h>
# endif
#endif
#include "gdk.h"
#include "gdkprivate.h"
#include "gdki18n.h"
#include "gdkx.h"
/* If this variable is FALSE, it indicates that we should
* avoid trying to use multibyte conversion functions and
* assume everything is 1-byte per character
*/
static gboolean gdk_use_mb;
/*
*--------------------------------------------------------------
* gdk_set_locale
*
* Arguments:
*
* Results:
*
* Side effects:
*
*--------------------------------------------------------------
*/
gchar*
gdk_set_locale (void)
{
wchar_t result;
gchar *current_locale;
gdk_use_mb = FALSE;
if (!setlocale (LC_ALL,""))
g_warning ("locale not supported by C library");
current_locale = setlocale (LC_ALL, NULL);
if (MB_CUR_MAX > 1)
gdk_use_mb = TRUE;
GDK_NOTE (XIM, g_message ("%s multi-byte string functions.",
gdk_use_mb ? "Using" : "Not using"));
return current_locale;
}
void
gdk_im_begin (GdkIC *ic, GdkWindow* window)
{
}
void
gdk_im_end (void)
{
}
GdkIMStyle
gdk_im_decide_style (GdkIMStyle supported_style)
{
return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
GdkIMStyle
gdk_im_set_best_style (GdkIMStyle style)
{
return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
gint
gdk_im_ready (void)
{
return FALSE;
}
GdkIC *
gdk_ic_new (GdkICAttr *attr, GdkICAttributesType mask)
{
return NULL;
}
void
gdk_ic_destroy (GdkIC *ic)
{
}
GdkIMStyle
gdk_ic_get_style (GdkIC *ic)
{
return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
void
gdk_ic_set_values (GdkIC *ic, ...)
{
}
void
gdk_ic_get_values (GdkIC *ic, ...)
{
}
GdkICAttributesType
gdk_ic_set_attr (GdkIC *ic, GdkICAttr *attr, GdkICAttributesType mask)
{
return 0;
}
GdkICAttributesType
gdk_ic_get_attr (GdkIC *ic, GdkICAttr *attr, GdkICAttributesType mask)
{
return 0;
}
GdkEventMask
gdk_ic_get_events (GdkIC *ic)
{
return 0;
}
/*
* gdk_wcstombs
*
* Returns a multi-byte string converted from the specified array
* of wide characters. The string is newly allocated. The array of
* wide characters must be null-terminated. If the conversion is
* failed, it returns NULL.
*/
gchar *
gdk_wcstombs (const GdkWChar *src)
{
gchar *mbstr;
if (gdk_use_mb)
{
gint i, wcsl, mbsl;
wchar_t *src_alt;
for (wcsl = 0; src[wcsl]; wcsl++)
;
src_alt = g_new (wchar_t, wcsl+1);
for (i = wcsl; i >= 0; i--)
src_alt[i] = src[i];
mbsl = WideCharToMultiByte (CP_ACP, 0, src_alt, wcsl,
NULL, 0, NULL, NULL);
mbstr = g_new (guchar, mbsl + 1);
if (!WideCharToMultiByte (CP_ACP, 0, src_alt, wcsl,
mbstr, mbsl, NULL, NULL))
{
g_warning ("gdk_wcstombs: WideCharToMultiByte failed");
g_free (mbstr);
g_free (src_alt);
return NULL;
}
mbstr[mbsl] = '\0';
g_free (src_alt);
return mbstr;
}
else
{
gint length = 0;
gint i;
while (src[length] != 0)
length++;
mbstr = g_new (gchar, length + 1);
for (i=0; i<length+1; i++)
mbstr[i] = src[i];
}
return mbstr;
}
/*
* gdk_mbstowcs
*
* Converts the specified string into wide characters, and, returns the
* number of wide characters written. The string 'src' must be
* null-terminated. If the conversion is failed, it returns -1.
*/
gint
gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max)
{
if (gdk_use_mb)
{
gint i, wcsl;
wchar_t *wcstr;
wcsl = MultiByteToWideChar (CP_ACP, 0, src, -1, NULL, 0);
wcstr = g_new (wchar_t, wcsl + 1);
if (!MultiByteToWideChar (CP_ACP, 0, src, -1, wcstr, wcsl))
{
g_warning ("gdk_mbstowcs: MultiByteToWideChar failed");
g_free (wcstr);
return -1;
}
if (wcsl > dest_max)
wcsl = dest_max;
for (i = 0; i < wcsl; i++)
dest[i] = wcstr[i];
return wcsl;
}
else
{
gint i;
for (i=0; i<dest_max && src[i]; i++)
dest[i] = src[i];
return i;
}
}

248
gdk/win32/gdkim.c Normal file
View File

@ -0,0 +1,248 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#if HAVE_CONFIG_H
# include <config.h>
# if STDC_HEADERS
# include <string.h>
# endif
#endif
#include "gdk.h"
#include "gdkprivate.h"
#include "gdki18n.h"
#include "gdkx.h"
/* If this variable is FALSE, it indicates that we should
* avoid trying to use multibyte conversion functions and
* assume everything is 1-byte per character
*/
static gboolean gdk_use_mb;
/*
*--------------------------------------------------------------
* gdk_set_locale
*
* Arguments:
*
* Results:
*
* Side effects:
*
*--------------------------------------------------------------
*/
gchar*
gdk_set_locale (void)
{
wchar_t result;
gchar *current_locale;
gdk_use_mb = FALSE;
if (!setlocale (LC_ALL,""))
g_warning ("locale not supported by C library");
current_locale = setlocale (LC_ALL, NULL);
if (MB_CUR_MAX > 1)
gdk_use_mb = TRUE;
GDK_NOTE (XIM, g_message ("%s multi-byte string functions.",
gdk_use_mb ? "Using" : "Not using"));
return current_locale;
}
void
gdk_im_begin (GdkIC *ic, GdkWindow* window)
{
}
void
gdk_im_end (void)
{
}
GdkIMStyle
gdk_im_decide_style (GdkIMStyle supported_style)
{
return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
GdkIMStyle
gdk_im_set_best_style (GdkIMStyle style)
{
return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
gint
gdk_im_ready (void)
{
return FALSE;
}
GdkIC *
gdk_ic_new (GdkICAttr *attr, GdkICAttributesType mask)
{
return NULL;
}
void
gdk_ic_destroy (GdkIC *ic)
{
}
GdkIMStyle
gdk_ic_get_style (GdkIC *ic)
{
return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
}
void
gdk_ic_set_values (GdkIC *ic, ...)
{
}
void
gdk_ic_get_values (GdkIC *ic, ...)
{
}
GdkICAttributesType
gdk_ic_set_attr (GdkIC *ic, GdkICAttr *attr, GdkICAttributesType mask)
{
return 0;
}
GdkICAttributesType
gdk_ic_get_attr (GdkIC *ic, GdkICAttr *attr, GdkICAttributesType mask)
{
return 0;
}
GdkEventMask
gdk_ic_get_events (GdkIC *ic)
{
return 0;
}
/*
* gdk_wcstombs
*
* Returns a multi-byte string converted from the specified array
* of wide characters. The string is newly allocated. The array of
* wide characters must be null-terminated. If the conversion is
* failed, it returns NULL.
*/
gchar *
gdk_wcstombs (const GdkWChar *src)
{
gchar *mbstr;
if (gdk_use_mb)
{
gint i, wcsl, mbsl;
wchar_t *src_alt;
for (wcsl = 0; src[wcsl]; wcsl++)
;
src_alt = g_new (wchar_t, wcsl+1);
for (i = wcsl; i >= 0; i--)
src_alt[i] = src[i];
mbsl = WideCharToMultiByte (CP_ACP, 0, src_alt, wcsl,
NULL, 0, NULL, NULL);
mbstr = g_new (guchar, mbsl + 1);
if (!WideCharToMultiByte (CP_ACP, 0, src_alt, wcsl,
mbstr, mbsl, NULL, NULL))
{
g_warning ("gdk_wcstombs: WideCharToMultiByte failed");
g_free (mbstr);
g_free (src_alt);
return NULL;
}
mbstr[mbsl] = '\0';
g_free (src_alt);
return mbstr;
}
else
{
gint length = 0;
gint i;
while (src[length] != 0)
length++;
mbstr = g_new (gchar, length + 1);
for (i=0; i<length+1; i++)
mbstr[i] = src[i];
}
return mbstr;
}
/*
* gdk_mbstowcs
*
* Converts the specified string into wide characters, and, returns the
* number of wide characters written. The string 'src' must be
* null-terminated. If the conversion is failed, it returns -1.
*/
gint
gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max)
{
if (gdk_use_mb)
{
gint i, wcsl;
wchar_t *wcstr;
wcsl = MultiByteToWideChar (CP_ACP, 0, src, -1, NULL, 0);
wcstr = g_new (wchar_t, wcsl + 1);
if (!MultiByteToWideChar (CP_ACP, 0, src, -1, wcstr, wcsl))
{
g_warning ("gdk_mbstowcs: MultiByteToWideChar failed");
g_free (wcstr);
return -1;
}
if (wcsl > dest_max)
wcsl = dest_max;
for (i = 0; i < wcsl; i++)
dest[i] = wcstr[i];
return wcsl;
}
else
{
gint i;
for (i=0; i<dest_max && src[i]; i++)
dest[i] = src[i];
return i;
}
}

760
gdk/win32/gdkimage-win32.c Normal file
View File

@ -0,0 +1,760 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
static void gdk_image_put_normal (GdkDrawable *drawable,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height);
static GList *image_list = NULL;
void
gdk_image_exit (void)
{
GdkImage *image;
while (image_list)
{
image = image_list->data;
gdk_image_destroy (image);
}
}
GdkImage *
gdk_image_new_bitmap (GdkVisual *visual, gpointer data, gint w, gint h)
/*
* Desc: create a new bitmap image
*/
{
Visual *xvisual;
GdkImage *image;
GdkImagePrivate *private;
struct {
BITMAPINFOHEADER bmiHeader;
union {
WORD bmiIndices[2];
RGBQUAD bmiColors[2];
} u;
} bmi;
char *bits;
int bpl = (w-1)/8 + 1;
int bpl32 = ((w-1)/32 + 1)*4;
private = g_new(GdkImagePrivate, 1);
image = (GdkImage *) private;
private->image_put = gdk_image_put_normal;
image->type = GDK_IMAGE_NORMAL;
image->visual = visual;
image->width = w;
image->height = h;
image->depth = 1;
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
GDK_NOTE (MISC, g_print ("gdk_image_new_bitmap: %dx%d\n", w, h));
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = w;
bmi.bmiHeader.biHeight = -h;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 1;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter =
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
bmi.u.bmiColors[0].rgbBlue =
bmi.u.bmiColors[0].rgbGreen =
bmi.u.bmiColors[0].rgbRed = 0x00;
bmi.u.bmiColors[0].rgbReserved = 0x00;
bmi.u.bmiColors[1].rgbBlue =
bmi.u.bmiColors[1].rgbGreen =
bmi.u.bmiColors[1].rgbRed = 0xFF;
bmi.u.bmiColors[1].rgbReserved = 0x00;
private->ximage = CreateDIBSection (gdk_DC, (BITMAPINFO *) &bmi,
DIB_RGB_COLORS, &bits, NULL, 0);
if (bpl != bpl32)
{
/* Win32 expects scanlines in DIBs to be 32 bit aligned */
int i;
for (i = 0; i < h; i++)
memmove (bits + i*bpl32, ((char *) data) + i*bpl, bpl);
}
else
memmove (bits, data, bpl*h);
image->mem = bits;
image->bpl = bpl32;
image->byte_order = GDK_MSB_FIRST;
image->bpp = 1;
return(image);
} /* gdk_image_new_bitmap() */
void
gdk_image_init (void)
{
}
static GdkImage*
gdk_image_new_with_depth (GdkImageType type,
GdkVisual *visual,
gint width,
gint height,
gint depth)
{
GdkImage *image;
GdkImagePrivate *private;
Visual *xvisual;
struct {
BITMAPINFOHEADER bmiHeader;
union {
WORD bmiIndices[256];
DWORD bmiMasks[3];
RGBQUAD bmiColors[256];
} u;
} bmi;
UINT iUsage;
int i;
GDK_NOTE (MISC, g_print ("gdk_image_new_with_depth: %dx%dx%d\n",
width, height, depth));
switch (type)
{
case GDK_IMAGE_FASTEST:
image = gdk_image_new_with_depth (GDK_IMAGE_SHARED, visual,
width, height, depth);
if (!image)
image = gdk_image_new_with_depth (GDK_IMAGE_NORMAL, visual,
width, height, depth);
break;
default:
private = g_new (GdkImagePrivate, 1);
image = (GdkImage*) private;
private->image_put = NULL;
image->type = type;
image->visual = visual;
image->width = width;
image->height = height;
image->depth = depth;
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
switch (type)
{
case GDK_IMAGE_SHARED:
case GDK_IMAGE_SHARED_PIXMAP:
/* Fall through, Windows images are always shared */
case GDK_IMAGE_NORMAL:
private->image_put = gdk_image_put_normal;
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -height;
bmi.bmiHeader.biPlanes = 1;
if (depth == 15)
bmi.bmiHeader.biBitCount = 16;
else
bmi.bmiHeader.biBitCount = depth;
#if 1
if (depth == 16)
bmi.bmiHeader.biCompression = BI_BITFIELDS;
else
#endif
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter =
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
if (image->visual->type == GDK_VISUAL_PSEUDO_COLOR)
{
iUsage = DIB_PAL_COLORS;
for (i = 0; i < 256; i++)
bmi.u.bmiIndices[i] = i;
}
else
{
if (depth == 1)
{
bmi.u.bmiColors[0].rgbBlue =
bmi.u.bmiColors[0].rgbGreen =
bmi.u.bmiColors[0].rgbRed = 0x00;
bmi.u.bmiColors[0].rgbReserved = 0x00;
bmi.u.bmiColors[1].rgbBlue =
bmi.u.bmiColors[1].rgbGreen =
bmi.u.bmiColors[1].rgbRed = 0xFF;
bmi.u.bmiColors[1].rgbReserved = 0x00;
}
#if 1
else if (depth == 16)
{
bmi.u.bmiMasks[0] = visual->red_mask;
bmi.u.bmiMasks[1] = visual->green_mask;
bmi.u.bmiMasks[2] = visual->blue_mask;
}
#endif
iUsage = DIB_RGB_COLORS;
}
private->ximage =
CreateDIBSection (gdk_DC, (BITMAPINFO *) &bmi, iUsage,
&image->mem, NULL, 0);
if (private->ximage == NULL)
{
g_warning ("gdk_image_new_with_depth: CreateDIBSection failed");
g_free (image);
return NULL;
}
switch (depth)
{
case 1:
case 8:
image->bpp = 1;
break;
case 15:
case 16:
image->bpp = 2;
break;
case 24:
image->bpp = 3;
break;
case 32:
image->bpp = 4;
break;
default:
g_warning ("gdk_image_new_with_depth: depth = %d", depth);
g_assert_not_reached ();
}
image->byte_order = GDK_LSB_FIRST;
if (depth == 1)
image->bpl = ((width-1)/32 + 1)*4;
else
image->bpl = ((width*image->bpp - 1)/4 + 1)*4;
GDK_NOTE (MISC, g_print ("... = %#x mem = %#x, bpl = %d\n",
private->ximage, image->mem, image->bpl));
break;
case GDK_IMAGE_FASTEST:
g_assert_not_reached ();
}
break;
}
return image;
}
GdkImage*
gdk_image_new (GdkImageType type,
GdkVisual *visual,
gint width,
gint height)
{
return gdk_image_new_with_depth (type, visual, width, height, visual->depth);
}
GdkImage*
gdk_image_bitmap_new (GdkImageType type,
GdkVisual *visual,
gint width,
gint height)
{
return gdk_image_new_with_depth (type, visual, width, height, 1);
}
GdkImage*
gdk_image_get (GdkWindow *window,
gint x,
gint y,
gint width,
gint height)
{
GdkImage *image;
GdkImagePrivate *private;
GdkWindowPrivate *win_private;
HDC hdc, memdc;
struct {
BITMAPINFOHEADER bmiHeader;
union {
WORD bmiIndices[256];
DWORD bmiMasks[3];
RGBQUAD bmiColors[256];
} u;
} bmi;
HGDIOBJ oldbitmap1, oldbitmap2;
UINT iUsage;
BITMAP bm;
int i;
g_return_val_if_fail (window != NULL, NULL);
win_private = (GdkWindowPrivate *) window;
if (win_private->destroyed)
return NULL;
GDK_NOTE (MISC, g_print ("gdk_image_get: %#x %dx%d@+%d+%d\n",
win_private->xwindow, width, height, x, y));
private = g_new (GdkImagePrivate, 1);
image = (GdkImage*) private;
private->image_put = gdk_image_put_normal;
image->type = GDK_IMAGE_NORMAL;
image->visual = gdk_window_get_visual (window);
image->width = width;
image->height = height;
/* This function is called both to blit from a window and from
* a pixmap.
*/
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
if ((hdc = CreateCompatibleDC (NULL)) == NULL)
{
g_warning ("gdk_image_get: CreateCompatibleDC #1 failed");
g_free (image);
return NULL;
}
if ((oldbitmap1 = SelectObject (hdc, win_private->xwindow)) == NULL)
{
g_warning ("gdk_image_get: SelectObject #1 failed");
DeleteDC (hdc);
g_free (image);
return NULL;
}
GetObject (win_private->xwindow, sizeof (BITMAP), &bm);
GDK_NOTE (MISC,
g_print ("gdk_image_get: bmWidth = %d, bmHeight = %d, bmWidthBytes = %d, bmBitsPixel = %d\n",
bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, bm.bmBitsPixel));
image->depth = bm.bmBitsPixel;
if (image->depth <= 8)
{
iUsage = DIB_PAL_COLORS;
for (i = 0; i < 256; i++)
bmi.u.bmiIndices[i] = i;
}
else
iUsage = DIB_RGB_COLORS;
}
else
{
if ((hdc = GetDC (win_private->xwindow)) == NULL)
{
g_warning ("gdk_image_get: GetDC failed");
g_free (image);
return NULL;
}
image->depth = gdk_visual_get_system ()->depth;
if (image->visual->type == GDK_VISUAL_PSEUDO_COLOR)
{
iUsage = DIB_PAL_COLORS;
for (i = 0; i < 256; i++)
bmi.u.bmiIndices[i] = i;
}
else
iUsage = DIB_RGB_COLORS;
}
if ((memdc = CreateCompatibleDC (hdc)) == NULL)
{
g_warning ("gdk_image_get: CreateCompatibleDC #2 failed");
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
g_free (image);
return NULL;
}
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = image->depth;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter =
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
if ((private->ximage =
CreateDIBSection (hdc, (BITMAPINFO *) &bmi, iUsage,
&image->mem, NULL, 0)) == NULL)
{
g_warning ("gdk_image_get: CreateDIBSection failed");
DeleteDC (memdc);
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
g_free (image);
return NULL;
}
if ((oldbitmap2 = SelectObject (memdc, private->ximage)) == NULL)
{
g_warning ("gdk_image_get: SelectObject #2 failed");
DeleteObject (private->ximage);
DeleteDC (memdc);
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
g_free (image);
return NULL;
}
if (!BitBlt (memdc, 0, 0, width, height, hdc, x, y, SRCCOPY))
{
g_warning ("gdk_image_get: BitBlt failed");
SelectObject (memdc, oldbitmap2);
DeleteObject (private->ximage);
DeleteDC (memdc);
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
g_free (image);
return NULL;
}
if (SelectObject (memdc, oldbitmap2) == NULL)
g_warning ("gdk_image_get: SelectObject #3 failed");
if (!DeleteDC (memdc))
g_warning ("gdk_image_get: DeleteDC failed");
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
switch (image->depth)
{
case 1:
case 8:
image->bpp = 1;
break;
case 15:
case 16:
image->bpp = 2;
break;
case 24:
image->bpp = 3;
break;
case 32:
image->bpp = 4;
break;
default:
g_warning ("gdk_image_get: image->depth = %d", image->depth);
g_assert_not_reached ();
}
image->byte_order = GDK_LSB_FIRST;
if (image->depth == 1)
image->bpl = (width - 1)/8 + 1;
else
image->bpl = ((width*image->bpp - 1)/4 + 1)*4;
GDK_NOTE (MISC, g_print ("... = %#x mem = %#x, bpl = %d\n",
private->ximage, image->mem, image->bpl));
return image;
}
guint32
gdk_image_get_pixel (GdkImage *image,
gint x,
gint y)
{
guint32 pixel;
GdkImagePrivate *private;
g_return_val_if_fail (image != NULL, 0);
private = (GdkImagePrivate *) image;
g_return_val_if_fail (x >= 0 && x < image->width
&& y >= 0 && y < image->height, 0);
if (image->depth == 1)
pixel = (((char *) image->mem)[y * image->bpl + (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0;
else
{
guchar *pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
switch (image->bpp)
{
case 1:
pixel = *pixelp;
break;
/* Windows is always LSB, no need to check image->byte_order. */
case 2:
pixel = pixelp[0] | (pixelp[1] << 8);
break;
case 3:
pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
break;
case 4:
pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
break;
}
}
return pixel;
}
void
gdk_image_put_pixel (GdkImage *image,
gint x,
gint y,
guint32 pixel)
{
GdkImagePrivate *private;
g_return_if_fail (image != NULL);
private = (GdkImagePrivate *) image;
g_return_if_fail (x >= 0 && x < image->width && y >= 0 && y < image->height);
if (image->depth == 1)
if (pixel & 1)
((guchar *) image->mem)[y * image->bpl + (x >> 3)] |= (1 << (7 - (x & 0x7)));
else
((guchar *) image->mem)[y * image->bpl + (x >> 3)] &= ~(1 << (7 - (x & 0x7)));
else
{
guchar *pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
/* Windows is always LSB, no need to check image->byte_order. */
switch (image->bpp)
{
case 4:
pixelp[3] = 0;
case 3:
pixelp[2] = ((pixel >> 16) & 0xFF);
case 2:
pixelp[1] = ((pixel >> 8) & 0xFF);
case 1:
pixelp[0] = (pixel & 0xFF);
}
}
}
void
gdk_image_destroy (GdkImage *image)
{
GdkImagePrivate *private;
g_return_if_fail (image != NULL);
private = (GdkImagePrivate*) image;
GDK_NOTE (MISC, g_print ("gdk_image_destroy: %#x%s\n",
private->ximage,
(image->type == GDK_IMAGE_SHARED_PIXMAP ?
" (shared pixmap)" : "")));
switch (image->type)
{
case GDK_IMAGE_NORMAL:
case GDK_IMAGE_SHARED_PIXMAP:
break; /* The Windows bitmap has already been
* (or will be) deleted when freeing
* the corresponding pixmap.
*/
case GDK_IMAGE_SHARED: /* All images are shared in Windows */
DeleteObject (private->ximage);
break;
case GDK_IMAGE_FASTEST:
g_assert_not_reached ();
}
g_free (image);
}
static void
gdk_image_put_normal (GdkDrawable *drawable,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
{
GdkWindowPrivate *drawable_private;
GdkImagePrivate *image_private;
GdkGCPrivate *gc_private;
HDC hdc;
GdkColormapPrivate *colormap_private;
g_return_if_fail (drawable != NULL);
g_return_if_fail (image != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
image_private = (GdkImagePrivate*) image;
gc_private = (GdkGCPrivate*) gc;
/* The image can in fact be "shared", so don't test */
hdc = gdk_gc_predraw (drawable_private, gc_private);
colormap_private = (GdkColormapPrivate *) drawable_private->colormap;
if (colormap_private && colormap_private->xcolormap->rc_palette)
{
DIBSECTION ds;
static struct {
BITMAPINFOHEADER bmiHeader;
WORD bmiIndices[256];
} bmi;
static gboolean bmi_inited = FALSE;
int i;
if (!bmi_inited)
{
for (i = 0; i < 256; i++)
bmi.bmiIndices[i] = i;
bmi_inited = TRUE;
}
if (GetObject (image_private->ximage, sizeof (DIBSECTION),
&ds) != sizeof (DIBSECTION))
{
g_warning ("gdk_image_put_normal: GetObject failed");
}
#if 0
g_print("xdest = %d, ydest = %d, xsrc = %d, ysrc = %d, width = %d, height = %d\n",
xdest, ydest, xsrc, ysrc, width, height);
g_print("bmWidth = %d, bmHeight = %d, bmBitsPixel = %d, bmBits = %p\n",
ds.dsBm.bmWidth, ds.dsBm.bmHeight, ds.dsBm.bmBitsPixel, ds.dsBm.bmBits);
g_print("biWidth = %d, biHeight = %d, biBitCount = %d, biClrUsed = %d\n",
ds.dsBmih.biWidth, ds.dsBmih.biHeight, ds.dsBmih.biBitCount, ds.dsBmih.biClrUsed);
#endif
bmi.bmiHeader = ds.dsBmih;
/* I have spent hours on getting the parameters to
* SetDIBitsToDevice right. I wonder what drugs the guys in
* Redmond were on when they designed this API.
*/
if (SetDIBitsToDevice (hdc,
xdest, ydest,
width, height,
xsrc, (-ds.dsBmih.biHeight)-height-ysrc,
0, -ds.dsBmih.biHeight,
ds.dsBm.bmBits,
(CONST BITMAPINFO *) &bmi,
DIB_PAL_COLORS) == 0)
g_warning ("SetDIBitsToDevice failed");
}
else
{
HDC memdc;
HGDIOBJ oldbitmap;
if ((memdc = CreateCompatibleDC (hdc)) == NULL)
{
g_warning ("gdk_image_put_normal: CreateCompatibleDC failed");
gdk_gc_postdraw (drawable_private, gc_private);
return;
}
if ((oldbitmap = SelectObject (memdc, image_private->ximage)) == NULL)
{
g_warning ("gdk_image_put_normal: SelectObject #1 failed");
gdk_gc_postdraw (drawable_private, gc_private);
return;
}
if (!BitBlt (hdc, xdest, ydest, width, height,
memdc, xsrc, ysrc, SRCCOPY))
g_warning ("gdk_image_put_normal: BitBlt failed");
if (SelectObject (memdc, oldbitmap) == NULL)
g_warning ("gdk_image_put_normal: SelectObject #2 failed");
if (!DeleteDC (memdc))
g_warning ("gdk_image_put_normal: DeleteDC failed");
}
gdk_gc_postdraw (drawable_private, gc_private);
}

760
gdk/win32/gdkimage.c Normal file
View File

@ -0,0 +1,760 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
static void gdk_image_put_normal (GdkDrawable *drawable,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height);
static GList *image_list = NULL;
void
gdk_image_exit (void)
{
GdkImage *image;
while (image_list)
{
image = image_list->data;
gdk_image_destroy (image);
}
}
GdkImage *
gdk_image_new_bitmap (GdkVisual *visual, gpointer data, gint w, gint h)
/*
* Desc: create a new bitmap image
*/
{
Visual *xvisual;
GdkImage *image;
GdkImagePrivate *private;
struct {
BITMAPINFOHEADER bmiHeader;
union {
WORD bmiIndices[2];
RGBQUAD bmiColors[2];
} u;
} bmi;
char *bits;
int bpl = (w-1)/8 + 1;
int bpl32 = ((w-1)/32 + 1)*4;
private = g_new(GdkImagePrivate, 1);
image = (GdkImage *) private;
private->image_put = gdk_image_put_normal;
image->type = GDK_IMAGE_NORMAL;
image->visual = visual;
image->width = w;
image->height = h;
image->depth = 1;
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
GDK_NOTE (MISC, g_print ("gdk_image_new_bitmap: %dx%d\n", w, h));
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = w;
bmi.bmiHeader.biHeight = -h;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 1;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter =
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
bmi.u.bmiColors[0].rgbBlue =
bmi.u.bmiColors[0].rgbGreen =
bmi.u.bmiColors[0].rgbRed = 0x00;
bmi.u.bmiColors[0].rgbReserved = 0x00;
bmi.u.bmiColors[1].rgbBlue =
bmi.u.bmiColors[1].rgbGreen =
bmi.u.bmiColors[1].rgbRed = 0xFF;
bmi.u.bmiColors[1].rgbReserved = 0x00;
private->ximage = CreateDIBSection (gdk_DC, (BITMAPINFO *) &bmi,
DIB_RGB_COLORS, &bits, NULL, 0);
if (bpl != bpl32)
{
/* Win32 expects scanlines in DIBs to be 32 bit aligned */
int i;
for (i = 0; i < h; i++)
memmove (bits + i*bpl32, ((char *) data) + i*bpl, bpl);
}
else
memmove (bits, data, bpl*h);
image->mem = bits;
image->bpl = bpl32;
image->byte_order = GDK_MSB_FIRST;
image->bpp = 1;
return(image);
} /* gdk_image_new_bitmap() */
void
gdk_image_init (void)
{
}
static GdkImage*
gdk_image_new_with_depth (GdkImageType type,
GdkVisual *visual,
gint width,
gint height,
gint depth)
{
GdkImage *image;
GdkImagePrivate *private;
Visual *xvisual;
struct {
BITMAPINFOHEADER bmiHeader;
union {
WORD bmiIndices[256];
DWORD bmiMasks[3];
RGBQUAD bmiColors[256];
} u;
} bmi;
UINT iUsage;
int i;
GDK_NOTE (MISC, g_print ("gdk_image_new_with_depth: %dx%dx%d\n",
width, height, depth));
switch (type)
{
case GDK_IMAGE_FASTEST:
image = gdk_image_new_with_depth (GDK_IMAGE_SHARED, visual,
width, height, depth);
if (!image)
image = gdk_image_new_with_depth (GDK_IMAGE_NORMAL, visual,
width, height, depth);
break;
default:
private = g_new (GdkImagePrivate, 1);
image = (GdkImage*) private;
private->image_put = NULL;
image->type = type;
image->visual = visual;
image->width = width;
image->height = height;
image->depth = depth;
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
switch (type)
{
case GDK_IMAGE_SHARED:
case GDK_IMAGE_SHARED_PIXMAP:
/* Fall through, Windows images are always shared */
case GDK_IMAGE_NORMAL:
private->image_put = gdk_image_put_normal;
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -height;
bmi.bmiHeader.biPlanes = 1;
if (depth == 15)
bmi.bmiHeader.biBitCount = 16;
else
bmi.bmiHeader.biBitCount = depth;
#if 1
if (depth == 16)
bmi.bmiHeader.biCompression = BI_BITFIELDS;
else
#endif
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter =
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
if (image->visual->type == GDK_VISUAL_PSEUDO_COLOR)
{
iUsage = DIB_PAL_COLORS;
for (i = 0; i < 256; i++)
bmi.u.bmiIndices[i] = i;
}
else
{
if (depth == 1)
{
bmi.u.bmiColors[0].rgbBlue =
bmi.u.bmiColors[0].rgbGreen =
bmi.u.bmiColors[0].rgbRed = 0x00;
bmi.u.bmiColors[0].rgbReserved = 0x00;
bmi.u.bmiColors[1].rgbBlue =
bmi.u.bmiColors[1].rgbGreen =
bmi.u.bmiColors[1].rgbRed = 0xFF;
bmi.u.bmiColors[1].rgbReserved = 0x00;
}
#if 1
else if (depth == 16)
{
bmi.u.bmiMasks[0] = visual->red_mask;
bmi.u.bmiMasks[1] = visual->green_mask;
bmi.u.bmiMasks[2] = visual->blue_mask;
}
#endif
iUsage = DIB_RGB_COLORS;
}
private->ximage =
CreateDIBSection (gdk_DC, (BITMAPINFO *) &bmi, iUsage,
&image->mem, NULL, 0);
if (private->ximage == NULL)
{
g_warning ("gdk_image_new_with_depth: CreateDIBSection failed");
g_free (image);
return NULL;
}
switch (depth)
{
case 1:
case 8:
image->bpp = 1;
break;
case 15:
case 16:
image->bpp = 2;
break;
case 24:
image->bpp = 3;
break;
case 32:
image->bpp = 4;
break;
default:
g_warning ("gdk_image_new_with_depth: depth = %d", depth);
g_assert_not_reached ();
}
image->byte_order = GDK_LSB_FIRST;
if (depth == 1)
image->bpl = ((width-1)/32 + 1)*4;
else
image->bpl = ((width*image->bpp - 1)/4 + 1)*4;
GDK_NOTE (MISC, g_print ("... = %#x mem = %#x, bpl = %d\n",
private->ximage, image->mem, image->bpl));
break;
case GDK_IMAGE_FASTEST:
g_assert_not_reached ();
}
break;
}
return image;
}
GdkImage*
gdk_image_new (GdkImageType type,
GdkVisual *visual,
gint width,
gint height)
{
return gdk_image_new_with_depth (type, visual, width, height, visual->depth);
}
GdkImage*
gdk_image_bitmap_new (GdkImageType type,
GdkVisual *visual,
gint width,
gint height)
{
return gdk_image_new_with_depth (type, visual, width, height, 1);
}
GdkImage*
gdk_image_get (GdkWindow *window,
gint x,
gint y,
gint width,
gint height)
{
GdkImage *image;
GdkImagePrivate *private;
GdkWindowPrivate *win_private;
HDC hdc, memdc;
struct {
BITMAPINFOHEADER bmiHeader;
union {
WORD bmiIndices[256];
DWORD bmiMasks[3];
RGBQUAD bmiColors[256];
} u;
} bmi;
HGDIOBJ oldbitmap1, oldbitmap2;
UINT iUsage;
BITMAP bm;
int i;
g_return_val_if_fail (window != NULL, NULL);
win_private = (GdkWindowPrivate *) window;
if (win_private->destroyed)
return NULL;
GDK_NOTE (MISC, g_print ("gdk_image_get: %#x %dx%d@+%d+%d\n",
win_private->xwindow, width, height, x, y));
private = g_new (GdkImagePrivate, 1);
image = (GdkImage*) private;
private->image_put = gdk_image_put_normal;
image->type = GDK_IMAGE_NORMAL;
image->visual = gdk_window_get_visual (window);
image->width = width;
image->height = height;
/* This function is called both to blit from a window and from
* a pixmap.
*/
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
if ((hdc = CreateCompatibleDC (NULL)) == NULL)
{
g_warning ("gdk_image_get: CreateCompatibleDC #1 failed");
g_free (image);
return NULL;
}
if ((oldbitmap1 = SelectObject (hdc, win_private->xwindow)) == NULL)
{
g_warning ("gdk_image_get: SelectObject #1 failed");
DeleteDC (hdc);
g_free (image);
return NULL;
}
GetObject (win_private->xwindow, sizeof (BITMAP), &bm);
GDK_NOTE (MISC,
g_print ("gdk_image_get: bmWidth = %d, bmHeight = %d, bmWidthBytes = %d, bmBitsPixel = %d\n",
bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, bm.bmBitsPixel));
image->depth = bm.bmBitsPixel;
if (image->depth <= 8)
{
iUsage = DIB_PAL_COLORS;
for (i = 0; i < 256; i++)
bmi.u.bmiIndices[i] = i;
}
else
iUsage = DIB_RGB_COLORS;
}
else
{
if ((hdc = GetDC (win_private->xwindow)) == NULL)
{
g_warning ("gdk_image_get: GetDC failed");
g_free (image);
return NULL;
}
image->depth = gdk_visual_get_system ()->depth;
if (image->visual->type == GDK_VISUAL_PSEUDO_COLOR)
{
iUsage = DIB_PAL_COLORS;
for (i = 0; i < 256; i++)
bmi.u.bmiIndices[i] = i;
}
else
iUsage = DIB_RGB_COLORS;
}
if ((memdc = CreateCompatibleDC (hdc)) == NULL)
{
g_warning ("gdk_image_get: CreateCompatibleDC #2 failed");
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
g_free (image);
return NULL;
}
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = -height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = image->depth;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter =
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
if ((private->ximage =
CreateDIBSection (hdc, (BITMAPINFO *) &bmi, iUsage,
&image->mem, NULL, 0)) == NULL)
{
g_warning ("gdk_image_get: CreateDIBSection failed");
DeleteDC (memdc);
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
g_free (image);
return NULL;
}
if ((oldbitmap2 = SelectObject (memdc, private->ximage)) == NULL)
{
g_warning ("gdk_image_get: SelectObject #2 failed");
DeleteObject (private->ximage);
DeleteDC (memdc);
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
g_free (image);
return NULL;
}
if (!BitBlt (memdc, 0, 0, width, height, hdc, x, y, SRCCOPY))
{
g_warning ("gdk_image_get: BitBlt failed");
SelectObject (memdc, oldbitmap2);
DeleteObject (private->ximage);
DeleteDC (memdc);
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
g_free (image);
return NULL;
}
if (SelectObject (memdc, oldbitmap2) == NULL)
g_warning ("gdk_image_get: SelectObject #3 failed");
if (!DeleteDC (memdc))
g_warning ("gdk_image_get: DeleteDC failed");
if (win_private->window_type == GDK_WINDOW_PIXMAP)
{
SelectObject (hdc, oldbitmap1);
DeleteDC (hdc);
}
else
{
ReleaseDC (win_private->xwindow, hdc);
}
switch (image->depth)
{
case 1:
case 8:
image->bpp = 1;
break;
case 15:
case 16:
image->bpp = 2;
break;
case 24:
image->bpp = 3;
break;
case 32:
image->bpp = 4;
break;
default:
g_warning ("gdk_image_get: image->depth = %d", image->depth);
g_assert_not_reached ();
}
image->byte_order = GDK_LSB_FIRST;
if (image->depth == 1)
image->bpl = (width - 1)/8 + 1;
else
image->bpl = ((width*image->bpp - 1)/4 + 1)*4;
GDK_NOTE (MISC, g_print ("... = %#x mem = %#x, bpl = %d\n",
private->ximage, image->mem, image->bpl));
return image;
}
guint32
gdk_image_get_pixel (GdkImage *image,
gint x,
gint y)
{
guint32 pixel;
GdkImagePrivate *private;
g_return_val_if_fail (image != NULL, 0);
private = (GdkImagePrivate *) image;
g_return_val_if_fail (x >= 0 && x < image->width
&& y >= 0 && y < image->height, 0);
if (image->depth == 1)
pixel = (((char *) image->mem)[y * image->bpl + (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0;
else
{
guchar *pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
switch (image->bpp)
{
case 1:
pixel = *pixelp;
break;
/* Windows is always LSB, no need to check image->byte_order. */
case 2:
pixel = pixelp[0] | (pixelp[1] << 8);
break;
case 3:
pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
break;
case 4:
pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
break;
}
}
return pixel;
}
void
gdk_image_put_pixel (GdkImage *image,
gint x,
gint y,
guint32 pixel)
{
GdkImagePrivate *private;
g_return_if_fail (image != NULL);
private = (GdkImagePrivate *) image;
g_return_if_fail (x >= 0 && x < image->width && y >= 0 && y < image->height);
if (image->depth == 1)
if (pixel & 1)
((guchar *) image->mem)[y * image->bpl + (x >> 3)] |= (1 << (7 - (x & 0x7)));
else
((guchar *) image->mem)[y * image->bpl + (x >> 3)] &= ~(1 << (7 - (x & 0x7)));
else
{
guchar *pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
/* Windows is always LSB, no need to check image->byte_order. */
switch (image->bpp)
{
case 4:
pixelp[3] = 0;
case 3:
pixelp[2] = ((pixel >> 16) & 0xFF);
case 2:
pixelp[1] = ((pixel >> 8) & 0xFF);
case 1:
pixelp[0] = (pixel & 0xFF);
}
}
}
void
gdk_image_destroy (GdkImage *image)
{
GdkImagePrivate *private;
g_return_if_fail (image != NULL);
private = (GdkImagePrivate*) image;
GDK_NOTE (MISC, g_print ("gdk_image_destroy: %#x%s\n",
private->ximage,
(image->type == GDK_IMAGE_SHARED_PIXMAP ?
" (shared pixmap)" : "")));
switch (image->type)
{
case GDK_IMAGE_NORMAL:
case GDK_IMAGE_SHARED_PIXMAP:
break; /* The Windows bitmap has already been
* (or will be) deleted when freeing
* the corresponding pixmap.
*/
case GDK_IMAGE_SHARED: /* All images are shared in Windows */
DeleteObject (private->ximage);
break;
case GDK_IMAGE_FASTEST:
g_assert_not_reached ();
}
g_free (image);
}
static void
gdk_image_put_normal (GdkDrawable *drawable,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
{
GdkWindowPrivate *drawable_private;
GdkImagePrivate *image_private;
GdkGCPrivate *gc_private;
HDC hdc;
GdkColormapPrivate *colormap_private;
g_return_if_fail (drawable != NULL);
g_return_if_fail (image != NULL);
g_return_if_fail (gc != NULL);
drawable_private = (GdkWindowPrivate*) drawable;
if (drawable_private->destroyed)
return;
image_private = (GdkImagePrivate*) image;
gc_private = (GdkGCPrivate*) gc;
/* The image can in fact be "shared", so don't test */
hdc = gdk_gc_predraw (drawable_private, gc_private);
colormap_private = (GdkColormapPrivate *) drawable_private->colormap;
if (colormap_private && colormap_private->xcolormap->rc_palette)
{
DIBSECTION ds;
static struct {
BITMAPINFOHEADER bmiHeader;
WORD bmiIndices[256];
} bmi;
static gboolean bmi_inited = FALSE;
int i;
if (!bmi_inited)
{
for (i = 0; i < 256; i++)
bmi.bmiIndices[i] = i;
bmi_inited = TRUE;
}
if (GetObject (image_private->ximage, sizeof (DIBSECTION),
&ds) != sizeof (DIBSECTION))
{
g_warning ("gdk_image_put_normal: GetObject failed");
}
#if 0
g_print("xdest = %d, ydest = %d, xsrc = %d, ysrc = %d, width = %d, height = %d\n",
xdest, ydest, xsrc, ysrc, width, height);
g_print("bmWidth = %d, bmHeight = %d, bmBitsPixel = %d, bmBits = %p\n",
ds.dsBm.bmWidth, ds.dsBm.bmHeight, ds.dsBm.bmBitsPixel, ds.dsBm.bmBits);
g_print("biWidth = %d, biHeight = %d, biBitCount = %d, biClrUsed = %d\n",
ds.dsBmih.biWidth, ds.dsBmih.biHeight, ds.dsBmih.biBitCount, ds.dsBmih.biClrUsed);
#endif
bmi.bmiHeader = ds.dsBmih;
/* I have spent hours on getting the parameters to
* SetDIBitsToDevice right. I wonder what drugs the guys in
* Redmond were on when they designed this API.
*/
if (SetDIBitsToDevice (hdc,
xdest, ydest,
width, height,
xsrc, (-ds.dsBmih.biHeight)-height-ysrc,
0, -ds.dsBmih.biHeight,
ds.dsBm.bmBits,
(CONST BITMAPINFO *) &bmi,
DIB_PAL_COLORS) == 0)
g_warning ("SetDIBitsToDevice failed");
}
else
{
HDC memdc;
HGDIOBJ oldbitmap;
if ((memdc = CreateCompatibleDC (hdc)) == NULL)
{
g_warning ("gdk_image_put_normal: CreateCompatibleDC failed");
gdk_gc_postdraw (drawable_private, gc_private);
return;
}
if ((oldbitmap = SelectObject (memdc, image_private->ximage)) == NULL)
{
g_warning ("gdk_image_put_normal: SelectObject #1 failed");
gdk_gc_postdraw (drawable_private, gc_private);
return;
}
if (!BitBlt (hdc, xdest, ydest, width, height,
memdc, xsrc, ysrc, SRCCOPY))
g_warning ("gdk_image_put_normal: BitBlt failed");
if (SelectObject (memdc, oldbitmap) == NULL)
g_warning ("gdk_image_put_normal: SelectObject #2 failed");
if (!DeleteDC (memdc))
g_warning ("gdk_image_put_normal: DeleteDC failed");
}
gdk_gc_postdraw (drawable_private, gc_private);
}

1524
gdk/win32/gdkinput-win32.c Normal file

File diff suppressed because it is too large Load Diff

1524
gdk/win32/gdkinput.c Normal file

File diff suppressed because it is too large Load Diff

156
gdk/win32/gdkinput.h Normal file
View File

@ -0,0 +1,156 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GDK_INPUT_H__
#define __GDK_INPUT_H__
#include <wintab.h>
#define PACKETDATA (PK_CONTEXT | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | PK_NORMAL_PRESSURE | PK_ORIENTATION)
#define PACKETMODE (PK_BUTTONS)
#include <pktdef.h>
typedef struct _GdkAxisInfo GdkAxisInfo;
typedef struct _GdkInputVTable GdkInputVTable;
typedef struct _GdkDevicePrivate GdkDevicePrivate;
typedef struct _GdkInputWindow GdkInputWindow;
struct _GdkInputVTable {
gint (*set_mode) (guint32 deviceid, GdkInputMode mode);
void (*set_axes) (guint32 deviceid, GdkAxisUse *axes);
void (*set_key) (guint32 deviceid,
guint index,
guint keyval,
GdkModifierType modifiers);
GdkTimeCoord* (*motion_events) (GdkWindow *window,
guint32 deviceid,
guint32 start,
guint32 stop,
gint *nevents_return);
void (*get_pointer) (GdkWindow *window,
guint32 deviceid,
gdouble *x,
gdouble *y,
gdouble *pressure,
gdouble *xtilt,
gdouble *ytilt,
GdkModifierType *mask);
gint (*grab_pointer) (GdkWindow * window,
gint owner_events,
GdkEventMask event_mask,
GdkWindow * confine_to,
guint32 time);
void (*ungrab_pointer) (guint32 time);
void (*configure_event) (GdkEventConfigure *event, GdkWindow *window);
void (*enter_event) (GdkEventCrossing *event, GdkWindow *window);
gint (*other_event) (GdkEvent *event, MSG *xevent);
gint (*enable_window) (GdkWindow *window, GdkDevicePrivate *gdkdev);
gint (*disable_window) (GdkWindow *window, GdkDevicePrivate *gdkdev);
};
/* information about a device axis */
struct _GdkAxisInfo
{
/* reported x resolution */
gint xresolution;
/* reported x minimum/maximum values */
gint xmin_value, xmax_value;
/* calibrated resolution (for aspect ration) - only relative values
between axes used */
gint resolution;
/* calibrated minimum/maximum values */
gint min_value, max_value;
};
#define GDK_INPUT_NUM_EVENTC 6
struct _GdkDevicePrivate {
GdkDeviceInfo info;
/* information about the axes */
GdkAxisInfo *axes;
/* reverse lookup on axis use type */
gint axis_for_use[GDK_AXIS_LAST];
/* true if we need to select a different set of events, but
* can't because this is the core pointer
*/
gint needs_update;
/* State of buttons */
gint button_state;
gint *last_axis_data;
gint last_buttons;
/* WINTAB stuff: */
HCTX hctx;
/* Cursor number */
UINT cursor;
/* The cursor's CSR_PKTDATA */
WTPKT pktdata;
/* CSR_NPBTNMARKS */
UINT npbtnmarks[2];
/* Azimuth and altitude axis */
AXIS orientation_axes[2];
};
struct _GdkInputWindow
{
/* gdk window */
GdkWindow *window;
/* Extension mode (GDK_EXTENSION_EVENTS_ALL/CURSOR) */
GdkExtensionMode mode;
/* position relative to root window */
gint16 root_x;
gint16 root_y;
/* rectangles relative to window of windows obscuring this one */
GdkRectangle *obscuring;
gint num_obscuring;
/* Is there a pointer grab for this window ? */
gint grabbed;
};
/* Global data */
extern GdkInputVTable gdk_input_vtable;
extern gint gdk_input_ignore_core;
extern gint gdk_input_ignore_wintab;
/* Function declarations */
void gdk_input_window_destroy (GdkWindow *window);
#endif /* __GDK_INPUT_H__ */

2237
gdk/win32/gdkmain-win32.c Normal file

File diff suppressed because it is too large Load Diff

1059
gdk/win32/gdkpixmap-win32.c Normal file

File diff suppressed because it is too large Load Diff

1059
gdk/win32/gdkpixmap.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,420 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GDK_PRIVATE_H__
#define __GDK_PRIVATE_H__
#define STRICT /* We want strict type checks */
#include <windows.h>
#include <time.h>
#include <gdk/gdktypes.h>
/* Define corresponding Windows types for some X11 types, just for laziness.
*/
#include <glib.h>
typedef HANDLE XID;
typedef PALETTEENTRY XColor;
typedef HDC GC;
typedef ATOM Atom;
typedef HCURSOR Cursor;
typedef guint VisualID;
typedef DWORD KeySym;
typedef int Status;
/* Define some of the X11 constants also here, again just for laziness */
/* Generic null resource */
#define None 0
/* Error codes */
#define Success 0
/* Grabbing status */
#define GrabSuccess 0
#define AlreadyGrabbed 2
/* For CreateColormap */
#define AllocNone 0
#define AllocAll 1
/* Notify modes */
#define NotifyNormal 0
#define NotifyHint 1
/* Some structs are somewhat useful to emulate internally, just to
keep the code less #ifdefed. */
typedef struct {
HPALETTE palette; /* Palette handle used when drawing. */
guint size; /* Number of entries in the palette. */
gboolean stale; /* 1 if palette needs to be realized,
* otherwise 0. */
gboolean *in_use;
gboolean rc_palette; /* If RC_PALETTE is on in the RASTERCAPS */
gulong sizepalette; /* SIZEPALETTE if rc_palette */
} ColormapStruct, *Colormap;
typedef struct {
gint map_entries;
guint visualid;
guint bitspixel;
} Visual;
typedef struct {
Colormap colormap;
unsigned long red_max;
unsigned long red_mult;
unsigned long green_max;
unsigned long green_mult;
unsigned long blue_max;
unsigned long blue_mult;
unsigned long base_pixel;
} XStandardColormap;
extern LRESULT CALLBACK
gdk_WindowProc (HWND, UINT, WPARAM, LPARAM);
#define gdk_window_lookup(xid) ((GdkWindow*) gdk_xid_table_lookup (xid))
#define gdk_pixmap_lookup(xid) ((GdkPixmap*) gdk_xid_table_lookup (xid))
/* HFONTs clash with HWNDs, so add dithering to HFONTs... (hack) */
#define HFONT_DITHER 43
#define gdk_font_lookup(xid) ((GdkFont*) gdk_xid_table_lookup ((HANDLE) ((guint) xid + HFONT_DITHER)))
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _GdkWindowPrivate GdkWindowPrivate;
typedef struct _GdkWindowPrivate GdkPixmapPrivate;
typedef struct _GdkImagePrivate GdkImagePrivate;
typedef struct _GdkGCPrivate GdkGCPrivate;
typedef struct _GdkColormapPrivate GdkColormapPrivate;
typedef struct _GdkColorInfo GdkColorInfo;
typedef struct _GdkVisualPrivate GdkVisualPrivate;
typedef struct _GdkFontPrivate GdkFontPrivate;
typedef struct _GdkCursorPrivate GdkCursorPrivate;
typedef struct _GdkEventFilter GdkEventFilter;
typedef struct _GdkClientFilter GdkClientFilter;
typedef struct _GdkColorContextPrivate GdkColorContextPrivate;
typedef struct _GdkRegionPrivate GdkRegionPrivate;
struct _GdkWindowPrivate
{
GdkWindow window;
GdkWindow *parent;
HANDLE xwindow;
gint16 x;
gint16 y;
guint16 width;
guint16 height;
guint8 resize_count;
guint8 window_type;
guint ref_count;
guint destroyed : 2;
guint mapped : 1;
guint guffaw_gravity : 1;
/* We must keep the event mask here to filter them ourselves */
gint event_mask;
/* Values for bg_type */
#define GDK_WIN32_BG_NORMAL 0
#define GDK_WIN32_BG_PIXEL 1
#define GDK_WIN32_BG_PIXMAP 2
#define GDK_WIN32_BG_PARENT_RELATIVE 3
#define GDK_WIN32_BG_TRANSPARENT 4
/* We draw the background ourselves at WM_ERASEBKGND */
guchar bg_type;
GdkColor bg_pixel;
GdkPixmap *bg_pixmap;
HCURSOR xcursor;
/* Window size hints */
gint hint_flags;
gint hint_x, hint_y;
gint hint_min_width, hint_min_height;
gint hint_max_width, hint_max_height;
gint extension_events;
gboolean extension_events_selected;
GList *filters;
GdkColormap *colormap;
GList *children;
};
struct _GdkImagePrivate
{
GdkImage image;
HBITMAP ximage;
gpointer x_shm_info;
void (*image_put) (GdkDrawable *window,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height);
};
struct _GdkGCPrivate
{
GdkGC gc;
GC xgc;
/* A Windows Device Context (DC) is not equivalent to an X11
* GC. We can use a DC only in the window for which it was
* allocated, or (in the case of a memory DC) with the bitmap that
* has been selected into it. Thus, we have to release and
* reallocate a DC each time the GdkGC is used to paint into a new
* window or pixmap. We thus keep all the necessary values in the
* GdkGCPrivate struct.
*/
GdkGCValuesMask values_mask;
GdkColor foreground;
GdkColor background;
HFONT font;
gint rop2;
GdkFill fill_style;
GdkPixmap *tile;
GdkPixmap *stipple;
HRGN clip_region;
GdkSubwindowMode subwindow_mode;
gint ts_x_origin;
gint ts_y_origin;
gint clip_x_origin;
gint clip_y_origin;
gint graphics_exposures;
gint pen_width;
DWORD pen_style;
HANDLE hwnd; /* If a DC is allocated, for which window
or what bitmap is selected into it */
int saved_dc;
guint ref_count;
};
typedef enum {
GDK_COLOR_WRITEABLE = 1 << 0
} GdkColorInfoFlags;
struct _GdkColorInfo
{
GdkColorInfoFlags flags;
guint ref_count;
};
struct _GdkColormapPrivate
{
GdkColormap colormap;
Colormap xcolormap;
GdkVisual *visual;
gint private_val;
GHashTable *hash;
GdkColorInfo *info;
time_t last_sync_time;
guint ref_count;
};
struct _GdkVisualPrivate
{
GdkVisual visual;
Visual *xvisual;
};
struct _GdkFontPrivate
{
GdkFont font;
/* XFontStruct *xfont; */
/* generic pointer point to XFontStruct or XFontSet */
/* in Win32 a HFONT */
gpointer xfont;
guint ref_count;
};
struct _GdkCursorPrivate
{
GdkCursor cursor;
Cursor xcursor;
};
struct _GdkEventFilter {
GdkFilterFunc function;
gpointer data;
};
struct _GdkClientFilter {
GdkAtom type;
GdkFilterFunc function;
gpointer data;
};
#ifdef USE_XIM
typedef struct _GdkICPrivate GdkICPrivate;
struct _GdkICPrivate
{
XIC xic;
GdkICAttr *attr;
GdkICAttributesType mask;
};
#endif /* USE_XIM */
struct _GdkColorContextPrivate
{
GdkColorContext color_context;
XStandardColormap std_cmap;
};
struct _GdkRegionPrivate
{
GdkRegion region;
HRGN xregion;
};
typedef enum {
GDK_DEBUG_MISC = 1 << 0,
GDK_DEBUG_EVENTS = 1 << 1,
GDK_DEBUG_DND = 1 << 2,
GDK_DEBUG_COLOR_CONTEXT = 1 << 3,
GDK_DEBUG_XIM = 1 << 4,
GDK_DEBUG_SELECTION = 1 << 5
} GdkDebugFlag;
void gdk_events_init (void);
void gdk_window_init (void);
void gdk_visual_init (void);
void gdk_selection_init (void);
void gdk_dnd_init (void);
void gdk_dnd_exit (void);
void gdk_image_init (void);
void gdk_image_exit (void);
GdkColormap* gdk_colormap_lookup (Colormap xcolormap);
GdkVisual* gdk_visual_lookup (Visual *xvisual);
void gdk_window_add_colormap_windows (GdkWindow *window);
void gdk_window_destroy_notify (GdkWindow *window);
void gdk_xid_table_insert (XID *xid,
gpointer data);
void gdk_xid_table_remove (XID xid);
gpointer gdk_xid_table_lookup (XID xid);
/* Internal functions */
HDC gdk_gc_predraw (GdkWindowPrivate *window_private,
GdkGCPrivate *gc_private);
void gdk_gc_postdraw (GdkWindowPrivate *window_private,
GdkGCPrivate *gc_private);
HRGN BitmapToRegion (HBITMAP hBmp);
void gdk_sel_prop_store (GdkWindow *owner,
GdkAtom type,
gint format,
guchar *data,
gint length);
void gdk_event_queue_append (GdkEvent *event);
/* Please see gdkwindow.c for comments on how to use */
HWND gdk_window_xid_at(HWND base, gint bx, gint by, gint x, gint y, GList *excludes, gboolean excl_child);
HWND gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child);
extern gint gdk_debug_level;
extern gint gdk_show_events;
extern gint gdk_stack_trace;
extern gchar *gdk_display_name;
extern HWND gdk_root_window;
extern HWND gdk_leader_window;
GDKVAR GdkWindowPrivate gdk_root_parent;
GDKVAR Atom gdk_selection_property;
extern GdkWindow *selection_owner[];
GDKVAR gchar *gdk_progclass;
GDKVAR gint gdk_error_code;
GDKVAR gint gdk_error_warnings;
GDKVAR gint gdk_null_window_warnings;
extern GList *gdk_default_filters;
#ifdef USE_XIM
/* XIM support */
gint gdk_im_open (void);
void gdk_im_close (void);
void gdk_ic_cleanup (void);
extern GdkICPrivate *gdk_xim_ic; /* currently using IC */
extern GdkWindow *gdk_xim_window; /* currently using Window */
#endif /* USE_XIM */
extern HDC gdk_DC;
extern HINSTANCE gdk_DLLInstance;
extern HINSTANCE gdk_ProgInstance;
extern UINT gdk_selection_notify_msg;
extern UINT gdk_selection_request_msg;
extern UINT gdk_selection_clear_msg;
extern GdkAtom gdk_clipboard_atom;
extern GdkAtom gdk_win32_dropfiles_atom;
extern GdkAtom gdk_ole2_dnd_atom;
/* Debugging support */
#ifdef G_ENABLE_DEBUG
#define GDK_NOTE(type,action) G_STMT_START { \
if (gdk_debug_flags & GDK_DEBUG_##type) \
{ action; }; } G_STMT_END
#else /* !G_ENABLE_DEBUG */
#define GDK_NOTE(type,action)
#endif /* G_ENABLE_DEBUG */
extern guint gdk_debug_flags;
/* Internal functions for debug output etc. */
char *gdk_color_to_string (GdkColor *);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GDK_PRIVATE_H__ */

420
gdk/win32/gdkprivate.h Normal file
View File

@ -0,0 +1,420 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GDK_PRIVATE_H__
#define __GDK_PRIVATE_H__
#define STRICT /* We want strict type checks */
#include <windows.h>
#include <time.h>
#include <gdk/gdktypes.h>
/* Define corresponding Windows types for some X11 types, just for laziness.
*/
#include <glib.h>
typedef HANDLE XID;
typedef PALETTEENTRY XColor;
typedef HDC GC;
typedef ATOM Atom;
typedef HCURSOR Cursor;
typedef guint VisualID;
typedef DWORD KeySym;
typedef int Status;
/* Define some of the X11 constants also here, again just for laziness */
/* Generic null resource */
#define None 0
/* Error codes */
#define Success 0
/* Grabbing status */
#define GrabSuccess 0
#define AlreadyGrabbed 2
/* For CreateColormap */
#define AllocNone 0
#define AllocAll 1
/* Notify modes */
#define NotifyNormal 0
#define NotifyHint 1
/* Some structs are somewhat useful to emulate internally, just to
keep the code less #ifdefed. */
typedef struct {
HPALETTE palette; /* Palette handle used when drawing. */
guint size; /* Number of entries in the palette. */
gboolean stale; /* 1 if palette needs to be realized,
* otherwise 0. */
gboolean *in_use;
gboolean rc_palette; /* If RC_PALETTE is on in the RASTERCAPS */
gulong sizepalette; /* SIZEPALETTE if rc_palette */
} ColormapStruct, *Colormap;
typedef struct {
gint map_entries;
guint visualid;
guint bitspixel;
} Visual;
typedef struct {
Colormap colormap;
unsigned long red_max;
unsigned long red_mult;
unsigned long green_max;
unsigned long green_mult;
unsigned long blue_max;
unsigned long blue_mult;
unsigned long base_pixel;
} XStandardColormap;
extern LRESULT CALLBACK
gdk_WindowProc (HWND, UINT, WPARAM, LPARAM);
#define gdk_window_lookup(xid) ((GdkWindow*) gdk_xid_table_lookup (xid))
#define gdk_pixmap_lookup(xid) ((GdkPixmap*) gdk_xid_table_lookup (xid))
/* HFONTs clash with HWNDs, so add dithering to HFONTs... (hack) */
#define HFONT_DITHER 43
#define gdk_font_lookup(xid) ((GdkFont*) gdk_xid_table_lookup ((HANDLE) ((guint) xid + HFONT_DITHER)))
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _GdkWindowPrivate GdkWindowPrivate;
typedef struct _GdkWindowPrivate GdkPixmapPrivate;
typedef struct _GdkImagePrivate GdkImagePrivate;
typedef struct _GdkGCPrivate GdkGCPrivate;
typedef struct _GdkColormapPrivate GdkColormapPrivate;
typedef struct _GdkColorInfo GdkColorInfo;
typedef struct _GdkVisualPrivate GdkVisualPrivate;
typedef struct _GdkFontPrivate GdkFontPrivate;
typedef struct _GdkCursorPrivate GdkCursorPrivate;
typedef struct _GdkEventFilter GdkEventFilter;
typedef struct _GdkClientFilter GdkClientFilter;
typedef struct _GdkColorContextPrivate GdkColorContextPrivate;
typedef struct _GdkRegionPrivate GdkRegionPrivate;
struct _GdkWindowPrivate
{
GdkWindow window;
GdkWindow *parent;
HANDLE xwindow;
gint16 x;
gint16 y;
guint16 width;
guint16 height;
guint8 resize_count;
guint8 window_type;
guint ref_count;
guint destroyed : 2;
guint mapped : 1;
guint guffaw_gravity : 1;
/* We must keep the event mask here to filter them ourselves */
gint event_mask;
/* Values for bg_type */
#define GDK_WIN32_BG_NORMAL 0
#define GDK_WIN32_BG_PIXEL 1
#define GDK_WIN32_BG_PIXMAP 2
#define GDK_WIN32_BG_PARENT_RELATIVE 3
#define GDK_WIN32_BG_TRANSPARENT 4
/* We draw the background ourselves at WM_ERASEBKGND */
guchar bg_type;
GdkColor bg_pixel;
GdkPixmap *bg_pixmap;
HCURSOR xcursor;
/* Window size hints */
gint hint_flags;
gint hint_x, hint_y;
gint hint_min_width, hint_min_height;
gint hint_max_width, hint_max_height;
gint extension_events;
gboolean extension_events_selected;
GList *filters;
GdkColormap *colormap;
GList *children;
};
struct _GdkImagePrivate
{
GdkImage image;
HBITMAP ximage;
gpointer x_shm_info;
void (*image_put) (GdkDrawable *window,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height);
};
struct _GdkGCPrivate
{
GdkGC gc;
GC xgc;
/* A Windows Device Context (DC) is not equivalent to an X11
* GC. We can use a DC only in the window for which it was
* allocated, or (in the case of a memory DC) with the bitmap that
* has been selected into it. Thus, we have to release and
* reallocate a DC each time the GdkGC is used to paint into a new
* window or pixmap. We thus keep all the necessary values in the
* GdkGCPrivate struct.
*/
GdkGCValuesMask values_mask;
GdkColor foreground;
GdkColor background;
HFONT font;
gint rop2;
GdkFill fill_style;
GdkPixmap *tile;
GdkPixmap *stipple;
HRGN clip_region;
GdkSubwindowMode subwindow_mode;
gint ts_x_origin;
gint ts_y_origin;
gint clip_x_origin;
gint clip_y_origin;
gint graphics_exposures;
gint pen_width;
DWORD pen_style;
HANDLE hwnd; /* If a DC is allocated, for which window
or what bitmap is selected into it */
int saved_dc;
guint ref_count;
};
typedef enum {
GDK_COLOR_WRITEABLE = 1 << 0
} GdkColorInfoFlags;
struct _GdkColorInfo
{
GdkColorInfoFlags flags;
guint ref_count;
};
struct _GdkColormapPrivate
{
GdkColormap colormap;
Colormap xcolormap;
GdkVisual *visual;
gint private_val;
GHashTable *hash;
GdkColorInfo *info;
time_t last_sync_time;
guint ref_count;
};
struct _GdkVisualPrivate
{
GdkVisual visual;
Visual *xvisual;
};
struct _GdkFontPrivate
{
GdkFont font;
/* XFontStruct *xfont; */
/* generic pointer point to XFontStruct or XFontSet */
/* in Win32 a HFONT */
gpointer xfont;
guint ref_count;
};
struct _GdkCursorPrivate
{
GdkCursor cursor;
Cursor xcursor;
};
struct _GdkEventFilter {
GdkFilterFunc function;
gpointer data;
};
struct _GdkClientFilter {
GdkAtom type;
GdkFilterFunc function;
gpointer data;
};
#ifdef USE_XIM
typedef struct _GdkICPrivate GdkICPrivate;
struct _GdkICPrivate
{
XIC xic;
GdkICAttr *attr;
GdkICAttributesType mask;
};
#endif /* USE_XIM */
struct _GdkColorContextPrivate
{
GdkColorContext color_context;
XStandardColormap std_cmap;
};
struct _GdkRegionPrivate
{
GdkRegion region;
HRGN xregion;
};
typedef enum {
GDK_DEBUG_MISC = 1 << 0,
GDK_DEBUG_EVENTS = 1 << 1,
GDK_DEBUG_DND = 1 << 2,
GDK_DEBUG_COLOR_CONTEXT = 1 << 3,
GDK_DEBUG_XIM = 1 << 4,
GDK_DEBUG_SELECTION = 1 << 5
} GdkDebugFlag;
void gdk_events_init (void);
void gdk_window_init (void);
void gdk_visual_init (void);
void gdk_selection_init (void);
void gdk_dnd_init (void);
void gdk_dnd_exit (void);
void gdk_image_init (void);
void gdk_image_exit (void);
GdkColormap* gdk_colormap_lookup (Colormap xcolormap);
GdkVisual* gdk_visual_lookup (Visual *xvisual);
void gdk_window_add_colormap_windows (GdkWindow *window);
void gdk_window_destroy_notify (GdkWindow *window);
void gdk_xid_table_insert (XID *xid,
gpointer data);
void gdk_xid_table_remove (XID xid);
gpointer gdk_xid_table_lookup (XID xid);
/* Internal functions */
HDC gdk_gc_predraw (GdkWindowPrivate *window_private,
GdkGCPrivate *gc_private);
void gdk_gc_postdraw (GdkWindowPrivate *window_private,
GdkGCPrivate *gc_private);
HRGN BitmapToRegion (HBITMAP hBmp);
void gdk_sel_prop_store (GdkWindow *owner,
GdkAtom type,
gint format,
guchar *data,
gint length);
void gdk_event_queue_append (GdkEvent *event);
/* Please see gdkwindow.c for comments on how to use */
HWND gdk_window_xid_at(HWND base, gint bx, gint by, gint x, gint y, GList *excludes, gboolean excl_child);
HWND gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child);
extern gint gdk_debug_level;
extern gint gdk_show_events;
extern gint gdk_stack_trace;
extern gchar *gdk_display_name;
extern HWND gdk_root_window;
extern HWND gdk_leader_window;
GDKVAR GdkWindowPrivate gdk_root_parent;
GDKVAR Atom gdk_selection_property;
extern GdkWindow *selection_owner[];
GDKVAR gchar *gdk_progclass;
GDKVAR gint gdk_error_code;
GDKVAR gint gdk_error_warnings;
GDKVAR gint gdk_null_window_warnings;
extern GList *gdk_default_filters;
#ifdef USE_XIM
/* XIM support */
gint gdk_im_open (void);
void gdk_im_close (void);
void gdk_ic_cleanup (void);
extern GdkICPrivate *gdk_xim_ic; /* currently using IC */
extern GdkWindow *gdk_xim_window; /* currently using Window */
#endif /* USE_XIM */
extern HDC gdk_DC;
extern HINSTANCE gdk_DLLInstance;
extern HINSTANCE gdk_ProgInstance;
extern UINT gdk_selection_notify_msg;
extern UINT gdk_selection_request_msg;
extern UINT gdk_selection_clear_msg;
extern GdkAtom gdk_clipboard_atom;
extern GdkAtom gdk_win32_dropfiles_atom;
extern GdkAtom gdk_ole2_dnd_atom;
/* Debugging support */
#ifdef G_ENABLE_DEBUG
#define GDK_NOTE(type,action) G_STMT_START { \
if (gdk_debug_flags & GDK_DEBUG_##type) \
{ action; }; } G_STMT_END
#else /* !G_ENABLE_DEBUG */
#define GDK_NOTE(type,action)
#endif /* G_ENABLE_DEBUG */
extern guint gdk_debug_flags;
/* Internal functions for debug output etc. */
char *gdk_color_to_string (GdkColor *);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GDK_PRIVATE_H__ */

View File

@ -0,0 +1,221 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <string.h>
#include "gdk.h"
#include "gdkprivate.h"
GdkAtom
gdk_atom_intern (const gchar *atom_name,
gint only_if_exists)
{
GdkAtom retval;
static GHashTable *atom_hash = NULL;
if (!atom_hash)
atom_hash = g_hash_table_new (g_str_hash, g_str_equal);
retval = GPOINTER_TO_UINT (g_hash_table_lookup (atom_hash, atom_name));
if (!retval)
{
if (strcmp (atom_name, "PRIMARY") == 0)
retval = GDK_SELECTION_PRIMARY;
else if (strcmp (atom_name, "SECONDARY") == 0)
retval = GDK_SELECTION_SECONDARY;
else if (strcmp (atom_name, "ATOM") == 0)
retval = GDK_SELECTION_TYPE_ATOM;
else if (strcmp (atom_name, "BITMAP") == 0)
retval = GDK_SELECTION_TYPE_BITMAP;
else if (strcmp (atom_name, "COLORMAP") == 0)
retval = GDK_SELECTION_TYPE_COLORMAP;
else if (strcmp (atom_name, "DRAWABLE") == 0)
retval = GDK_SELECTION_TYPE_DRAWABLE;
else if (strcmp (atom_name, "INTEGER") == 0)
retval = GDK_SELECTION_TYPE_INTEGER;
else if (strcmp (atom_name, "PIXMAP") == 0)
retval = GDK_SELECTION_TYPE_PIXMAP;
else if (strcmp (atom_name, "WINDOW") == 0)
retval = GDK_SELECTION_TYPE_WINDOW;
else if (strcmp (atom_name, "STRING") == 0)
retval = GDK_SELECTION_TYPE_STRING;
else
{
retval = GlobalFindAtom (atom_name);
if (only_if_exists && retval == 0)
retval = 0;
else
retval = GlobalAddAtom (atom_name);
}
g_hash_table_insert (atom_hash,
g_strdup (atom_name),
GUINT_TO_POINTER (retval));
}
return retval;
}
gchar *
gdk_atom_name (GdkAtom atom)
{
gchar name[256];
switch (atom)
{
case GDK_SELECTION_PRIMARY: return g_strdup ("PRIMARY");
case GDK_SELECTION_SECONDARY: return g_strdup ("SECONDARY");
case GDK_SELECTION_TYPE_ATOM: return g_strdup ("ATOM");
case GDK_SELECTION_TYPE_BITMAP: return g_strdup ("BITMAP");
case GDK_SELECTION_TYPE_COLORMAP: return g_strdup ("COLORMAP");
case GDK_SELECTION_TYPE_DRAWABLE: return g_strdup ("DRAWABLE");
case GDK_SELECTION_TYPE_INTEGER: return g_strdup ("INTEGER");
case GDK_SELECTION_TYPE_PIXMAP: return g_strdup ("PIXMAP");
case GDK_SELECTION_TYPE_WINDOW: return g_strdup ("WINDOW");
case GDK_SELECTION_TYPE_STRING: return g_strdup ("STRING");
}
if (atom < 0xC000)
return g_strdup_printf ("#%x", atom);
else if (GlobalGetAtomName (atom, name, sizeof (name)) == 0)
return NULL;
return g_strdup (name);
}
gint
gdk_property_get (GdkWindow *window,
GdkAtom property,
GdkAtom type,
gulong offset,
gulong length,
gint pdelete,
GdkAtom *actual_property_type,
gint *actual_format_type,
gint *actual_length,
guchar **data)
{
g_warning ("gdk_property_get: Not implemented");
return FALSE;
}
void
gdk_property_change (GdkWindow *window,
GdkAtom property,
GdkAtom type,
gint format,
GdkPropMode mode,
guchar *data,
gint nelements)
{
GdkWindowPrivate *private;
HGLOBAL hdata;
gint i, length;
gchar *prop_name, *type_name;
guchar *ptr;
private = (GdkWindowPrivate*) window;
if (private->destroyed)
return;
GDK_NOTE (SELECTION,
(prop_name = gdk_atom_name (property),
type_name = gdk_atom_name (type),
g_print ("gdk_property_change: %#x %#x (%s) %#x (%s) %s %d*%d bytes %.10s\n",
private->xwindow, property, prop_name,
type, type_name,
(mode == GDK_PROP_MODE_REPLACE ? "REPLACE" :
(mode == GDK_PROP_MODE_PREPEND ? "PREPEND" :
(mode == GDK_PROP_MODE_APPEND ? "APPEND" :
"???"))),
format, nelements, data),
g_free (prop_name),
g_free (type_name)));
if (property == gdk_selection_property
&& type == GDK_TARGET_STRING
&& format == 8
&& mode == GDK_PROP_MODE_REPLACE)
{
length = nelements;
ptr = data;
for (i = 0; i < nelements; i++)
if (*ptr++ == '\n')
length++;
#if 1
if (!OpenClipboard (private->xwindow))
{
g_warning ("gdk_property_change: OpenClipboard failed");
return;
}
#endif
hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, length + 1);
ptr = GlobalLock (hdata);
GDK_NOTE (SELECTION, g_print ("...hdata=%#x, ptr=%#x\n", hdata, ptr));
for (i = 0; i < nelements; i++)
{
if (*data == '\n')
*ptr++ = '\r';
*ptr++ = *data++;
}
*ptr++ = '\0';
GlobalUnlock (hdata);
if (!SetClipboardData(CF_TEXT, hdata))
g_warning ("gdk_property_change: SetClipboardData failed: %d",
GetLastError ());
#if 1
if (!CloseClipboard ())
{
g_warning ("gdk_property_change: CloseClipboard failed");
return;
}
#endif
}
else
g_warning ("gdk_property_change: General case not implemented");
}
void
gdk_property_delete (GdkWindow *window,
GdkAtom property)
{
GdkWindowPrivate *private;
gchar *prop_name, *type_name;
extern void gdk_selection_property_delete (GdkWindowPrivate *);
private = (GdkWindowPrivate*) window;
GDK_NOTE (SELECTION,
(prop_name = gdk_atom_name (property),
g_print ("gdk_property_delete: %#x %#x (%s)\n",
(window ? private->xwindow : 0), property, prop_name),
g_free (prop_name)));
if (property == gdk_selection_property)
gdk_selection_property_delete (private);
else
g_warning ("gdk_property_delete: General case not implemented");
}

221
gdk/win32/gdkproperty.c Normal file
View File

@ -0,0 +1,221 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <string.h>
#include "gdk.h"
#include "gdkprivate.h"
GdkAtom
gdk_atom_intern (const gchar *atom_name,
gint only_if_exists)
{
GdkAtom retval;
static GHashTable *atom_hash = NULL;
if (!atom_hash)
atom_hash = g_hash_table_new (g_str_hash, g_str_equal);
retval = GPOINTER_TO_UINT (g_hash_table_lookup (atom_hash, atom_name));
if (!retval)
{
if (strcmp (atom_name, "PRIMARY") == 0)
retval = GDK_SELECTION_PRIMARY;
else if (strcmp (atom_name, "SECONDARY") == 0)
retval = GDK_SELECTION_SECONDARY;
else if (strcmp (atom_name, "ATOM") == 0)
retval = GDK_SELECTION_TYPE_ATOM;
else if (strcmp (atom_name, "BITMAP") == 0)
retval = GDK_SELECTION_TYPE_BITMAP;
else if (strcmp (atom_name, "COLORMAP") == 0)
retval = GDK_SELECTION_TYPE_COLORMAP;
else if (strcmp (atom_name, "DRAWABLE") == 0)
retval = GDK_SELECTION_TYPE_DRAWABLE;
else if (strcmp (atom_name, "INTEGER") == 0)
retval = GDK_SELECTION_TYPE_INTEGER;
else if (strcmp (atom_name, "PIXMAP") == 0)
retval = GDK_SELECTION_TYPE_PIXMAP;
else if (strcmp (atom_name, "WINDOW") == 0)
retval = GDK_SELECTION_TYPE_WINDOW;
else if (strcmp (atom_name, "STRING") == 0)
retval = GDK_SELECTION_TYPE_STRING;
else
{
retval = GlobalFindAtom (atom_name);
if (only_if_exists && retval == 0)
retval = 0;
else
retval = GlobalAddAtom (atom_name);
}
g_hash_table_insert (atom_hash,
g_strdup (atom_name),
GUINT_TO_POINTER (retval));
}
return retval;
}
gchar *
gdk_atom_name (GdkAtom atom)
{
gchar name[256];
switch (atom)
{
case GDK_SELECTION_PRIMARY: return g_strdup ("PRIMARY");
case GDK_SELECTION_SECONDARY: return g_strdup ("SECONDARY");
case GDK_SELECTION_TYPE_ATOM: return g_strdup ("ATOM");
case GDK_SELECTION_TYPE_BITMAP: return g_strdup ("BITMAP");
case GDK_SELECTION_TYPE_COLORMAP: return g_strdup ("COLORMAP");
case GDK_SELECTION_TYPE_DRAWABLE: return g_strdup ("DRAWABLE");
case GDK_SELECTION_TYPE_INTEGER: return g_strdup ("INTEGER");
case GDK_SELECTION_TYPE_PIXMAP: return g_strdup ("PIXMAP");
case GDK_SELECTION_TYPE_WINDOW: return g_strdup ("WINDOW");
case GDK_SELECTION_TYPE_STRING: return g_strdup ("STRING");
}
if (atom < 0xC000)
return g_strdup_printf ("#%x", atom);
else if (GlobalGetAtomName (atom, name, sizeof (name)) == 0)
return NULL;
return g_strdup (name);
}
gint
gdk_property_get (GdkWindow *window,
GdkAtom property,
GdkAtom type,
gulong offset,
gulong length,
gint pdelete,
GdkAtom *actual_property_type,
gint *actual_format_type,
gint *actual_length,
guchar **data)
{
g_warning ("gdk_property_get: Not implemented");
return FALSE;
}
void
gdk_property_change (GdkWindow *window,
GdkAtom property,
GdkAtom type,
gint format,
GdkPropMode mode,
guchar *data,
gint nelements)
{
GdkWindowPrivate *private;
HGLOBAL hdata;
gint i, length;
gchar *prop_name, *type_name;
guchar *ptr;
private = (GdkWindowPrivate*) window;
if (private->destroyed)
return;
GDK_NOTE (SELECTION,
(prop_name = gdk_atom_name (property),
type_name = gdk_atom_name (type),
g_print ("gdk_property_change: %#x %#x (%s) %#x (%s) %s %d*%d bytes %.10s\n",
private->xwindow, property, prop_name,
type, type_name,
(mode == GDK_PROP_MODE_REPLACE ? "REPLACE" :
(mode == GDK_PROP_MODE_PREPEND ? "PREPEND" :
(mode == GDK_PROP_MODE_APPEND ? "APPEND" :
"???"))),
format, nelements, data),
g_free (prop_name),
g_free (type_name)));
if (property == gdk_selection_property
&& type == GDK_TARGET_STRING
&& format == 8
&& mode == GDK_PROP_MODE_REPLACE)
{
length = nelements;
ptr = data;
for (i = 0; i < nelements; i++)
if (*ptr++ == '\n')
length++;
#if 1
if (!OpenClipboard (private->xwindow))
{
g_warning ("gdk_property_change: OpenClipboard failed");
return;
}
#endif
hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, length + 1);
ptr = GlobalLock (hdata);
GDK_NOTE (SELECTION, g_print ("...hdata=%#x, ptr=%#x\n", hdata, ptr));
for (i = 0; i < nelements; i++)
{
if (*data == '\n')
*ptr++ = '\r';
*ptr++ = *data++;
}
*ptr++ = '\0';
GlobalUnlock (hdata);
if (!SetClipboardData(CF_TEXT, hdata))
g_warning ("gdk_property_change: SetClipboardData failed: %d",
GetLastError ());
#if 1
if (!CloseClipboard ())
{
g_warning ("gdk_property_change: CloseClipboard failed");
return;
}
#endif
}
else
g_warning ("gdk_property_change: General case not implemented");
}
void
gdk_property_delete (GdkWindow *window,
GdkAtom property)
{
GdkWindowPrivate *private;
gchar *prop_name, *type_name;
extern void gdk_selection_property_delete (GdkWindowPrivate *);
private = (GdkWindowPrivate*) window;
GDK_NOTE (SELECTION,
(prop_name = gdk_atom_name (property),
g_print ("gdk_property_delete: %#x %#x (%s)\n",
(window ? private->xwindow : 0), property, prop_name),
g_free (prop_name)));
if (property == gdk_selection_property)
gdk_selection_property_delete (private);
else
g_warning ("gdk_property_delete: General case not implemented");
}

108
gdk/win32/gdkrectangle.c Normal file
View File

@ -0,0 +1,108 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "gdk.h"
void
gdk_rectangle_union (GdkRectangle *src1,
GdkRectangle *src2,
GdkRectangle *dest)
{
g_return_if_fail (src1 != NULL);
g_return_if_fail (src2 != NULL);
g_return_if_fail (dest != NULL);
dest->x = MIN (src1->x, src2->x);
dest->y = MIN (src1->y, src2->y);
dest->width = MAX (src1->x + src1->width, src2->x + src2->width) - dest->x;
dest->height = MAX (src1->y + src1->height, src2->y + src2->height) - dest->y;
}
gint
gdk_rectangle_intersect (GdkRectangle *src1,
GdkRectangle *src2,
GdkRectangle *dest)
{
GdkRectangle *temp;
gint src1_x2, src1_y2;
gint src2_x2, src2_y2;
gint return_val;
g_return_val_if_fail (src1 != NULL, FALSE);
g_return_val_if_fail (src2 != NULL, FALSE);
g_return_val_if_fail (dest != NULL, FALSE);
return_val = FALSE;
if (src2->x < src1->x)
{
temp = src1;
src1 = src2;
src2 = temp;
}
dest->x = src2->x;
src1_x2 = src1->x + src1->width;
src2_x2 = src2->x + src2->width;
if (src2->x < src1_x2)
{
if (src1_x2 < src2_x2)
dest->width = src1_x2 - dest->x;
else
dest->width = src2_x2 - dest->x;
if (src2->y < src1->y)
{
temp = src1;
src1 = src2;
src2 = temp;
}
dest->y = src2->y;
src1_y2 = src1->y + src1->height;
src2_y2 = src2->y + src2->height;
if (src2->y < src1_y2)
{
return_val = TRUE;
if (src1_y2 < src2_y2)
dest->height = src1_y2 - dest->y;
else
dest->height = src2_y2 - dest->y;
if (dest->height == 0)
return_val = FALSE;
if (dest->width == 0)
return_val = FALSE;
}
}
return return_val;
}

350
gdk/win32/gdkregion-win32.c Normal file
View File

@ -0,0 +1,350 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
GdkRegion*
gdk_region_new (void)
{
GdkRegionPrivate *private;
GdkRegion *region;
HRGN xregion;
/* Create an empty region */
xregion = CreateRectRgn (1, 1, 0, 0);
private = g_new (GdkRegionPrivate, 1);
private->xregion = xregion;
region = (GdkRegion*) private;
region->user_data = NULL;
return region;
}
void
gdk_region_destroy (GdkRegion *region)
{
GdkRegionPrivate *private;
g_return_if_fail (region != NULL);
private = (GdkRegionPrivate *) region;
DeleteObject (private->xregion);
g_free (private);
}
gboolean
gdk_region_empty (GdkRegion *region)
{
GdkRegionPrivate *private;
RECT rect;
g_return_val_if_fail (region != NULL, 0);
private = (GdkRegionPrivate *) region;
return (GetRgnBox (private->xregion, &rect) == NULLREGION);
}
gboolean
gdk_region_equal (GdkRegion *region1,
GdkRegion *region2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
g_return_val_if_fail (region1 != NULL, 0);
g_return_val_if_fail (region2 != NULL, 0);
private1 = (GdkRegionPrivate *) region1;
private2 = (GdkRegionPrivate *) region2;
return EqualRgn (private1->xregion, private2->xregion);
}
void
gdk_region_get_clipbox(GdkRegion *region,
GdkRectangle *rectangle)
{
GdkRegionPrivate *rp;
RECT r;
g_return_if_fail(region != NULL);
g_return_if_fail(rectangle != NULL);
rp = (GdkRegionPrivate *)region;
GetRgnBox (rp->xregion, &r);
rectangle->x = r.left;
rectangle->y = r.top;
rectangle->width = r.right - r.left;
rectangle->height = r.bottom - r.top;
}
gboolean
gdk_region_point_in (GdkRegion *region,
gint x,
gint y)
{
GdkRegionPrivate *private;
g_return_val_if_fail (region != NULL, 0);
private = (GdkRegionPrivate *) region;
return PtInRegion (private->xregion, x, y);
}
GdkOverlapType
gdk_region_rect_in (GdkRegion *region,
GdkRectangle *rect)
{
GdkRegionPrivate *private;
RECT r;
int res;
g_return_val_if_fail (region != NULL, 0);
private = (GdkRegionPrivate *) region;
r.left = rect->x;
r.top = rect->y;
r.right = rect->x + rect->width;
r.bottom = rect->y + rect->height;
if (RectInRegion (private->xregion, &r))
return GDK_OVERLAP_RECTANGLE_PART;
return GDK_OVERLAP_RECTANGLE_OUT; /*what else ? */
}
GdkRegion *
gdk_region_polygon (GdkPoint *points,
gint npoints,
GdkFillRule fill_rule)
{
GdkRegionPrivate *private;
GdkRegion *region;
HRGN xregion;
POINT *pts;
gint xfill_rule = ALTERNATE;
gint i;
g_return_val_if_fail (points != NULL, NULL);
g_return_val_if_fail (npoints != 0, NULL); /* maybe we should check for at least three points */
switch (fill_rule)
{
case GDK_EVEN_ODD_RULE:
xfill_rule = ALTERNATE;
break;
case GDK_WINDING_RULE:
xfill_rule = WINDING;
break;
}
pts = g_malloc (npoints * sizeof (*pts));
for (i = 0; i < npoints; i++)
{
pts[i].x = points[i].x;
pts[i].y = points[i].y;
}
xregion = CreatePolygonRgn (pts, npoints, xfill_rule);
g_free (pts);
private = g_new (GdkRegionPrivate, 1);
private->xregion = xregion;
region = (GdkRegion *) private;
region->user_data = NULL;
return region;
}
void
gdk_region_offset (GdkRegion *region,
gint dx,
gint dy)
{
GdkRegionPrivate *private;
g_return_if_fail (region != NULL);
private = (GdkRegionPrivate *) region;
OffsetRgn (private->xregion, dx, dy);
}
void
gdk_region_shrink (GdkRegion *region,
gint dx,
gint dy)
{
GdkRegionPrivate *private;
RECT r;
g_return_if_fail (region != NULL);
private = (GdkRegionPrivate *) region;
/* Is it correct just to intersect it with a smaller bounding box? */
GetRgnBox (private->xregion, &r);
if (-dx > r.right - r.left)
{
r.left += dx/2;
r.right -= dx/2;
}
if (-dy > r.bottom - r.top)
{
r.top += dy/2;
r.bottom -= dy/2;
}
CombineRgn (private->xregion, private->xregion,
CreateRectRgnIndirect (&r), RGN_AND);
}
GdkRegion*
gdk_region_union_with_rect (GdkRegion *region,
GdkRectangle *rect)
{
GdkRegionPrivate *private;
GdkRegion *res;
GdkRegionPrivate *res_private;
RECT xrect;
g_return_val_if_fail (region != NULL, NULL);
private = (GdkRegionPrivate *) region;
xrect.left = rect->x;
xrect.top = rect->y;
xrect.right = rect->x + rect->width;
xrect.bottom = rect->y + rect->height;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private->xregion,
CreateRectRgnIndirect (&xrect), RGN_OR);
return res;
}
GdkRegion*
gdk_regions_intersect (GdkRegion *source1,
GdkRegion *source2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
GdkRegion *res;
GdkRegionPrivate *res_private;
g_return_val_if_fail (source1 != NULL, NULL);
g_return_val_if_fail (source2 != NULL, NULL);
private1 = (GdkRegionPrivate *) source1;
private2 = (GdkRegionPrivate *) source2;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
RGN_AND);
return res;
}
GdkRegion*
gdk_regions_union (GdkRegion *source1,
GdkRegion *source2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
GdkRegion *res;
GdkRegionPrivate *res_private;
g_return_val_if_fail (source1 != NULL, NULL);
g_return_val_if_fail (source2 != NULL, NULL);
private1 = (GdkRegionPrivate *) source1;
private2 = (GdkRegionPrivate *) source2;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
RGN_OR);
return res;
}
GdkRegion*
gdk_regions_subtract (GdkRegion *source1,
GdkRegion *source2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
GdkRegion *res;
GdkRegionPrivate *res_private;
g_return_val_if_fail (source1 != NULL, NULL);
g_return_val_if_fail (source2 != NULL, NULL);
private1 = (GdkRegionPrivate *) source1;
private2 = (GdkRegionPrivate *) source2;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
RGN_DIFF);
return res;
}
GdkRegion*
gdk_regions_xor (GdkRegion *source1,
GdkRegion *source2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
GdkRegion *res;
GdkRegionPrivate *res_private;
g_return_val_if_fail (source1 != NULL, NULL);
g_return_val_if_fail (source2 != NULL, NULL);
private1 = (GdkRegionPrivate *) source1;
private2 = (GdkRegionPrivate *) source2;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
RGN_XOR);
return res;
}

350
gdk/win32/gdkregion.c Normal file
View File

@ -0,0 +1,350 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
GdkRegion*
gdk_region_new (void)
{
GdkRegionPrivate *private;
GdkRegion *region;
HRGN xregion;
/* Create an empty region */
xregion = CreateRectRgn (1, 1, 0, 0);
private = g_new (GdkRegionPrivate, 1);
private->xregion = xregion;
region = (GdkRegion*) private;
region->user_data = NULL;
return region;
}
void
gdk_region_destroy (GdkRegion *region)
{
GdkRegionPrivate *private;
g_return_if_fail (region != NULL);
private = (GdkRegionPrivate *) region;
DeleteObject (private->xregion);
g_free (private);
}
gboolean
gdk_region_empty (GdkRegion *region)
{
GdkRegionPrivate *private;
RECT rect;
g_return_val_if_fail (region != NULL, 0);
private = (GdkRegionPrivate *) region;
return (GetRgnBox (private->xregion, &rect) == NULLREGION);
}
gboolean
gdk_region_equal (GdkRegion *region1,
GdkRegion *region2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
g_return_val_if_fail (region1 != NULL, 0);
g_return_val_if_fail (region2 != NULL, 0);
private1 = (GdkRegionPrivate *) region1;
private2 = (GdkRegionPrivate *) region2;
return EqualRgn (private1->xregion, private2->xregion);
}
void
gdk_region_get_clipbox(GdkRegion *region,
GdkRectangle *rectangle)
{
GdkRegionPrivate *rp;
RECT r;
g_return_if_fail(region != NULL);
g_return_if_fail(rectangle != NULL);
rp = (GdkRegionPrivate *)region;
GetRgnBox (rp->xregion, &r);
rectangle->x = r.left;
rectangle->y = r.top;
rectangle->width = r.right - r.left;
rectangle->height = r.bottom - r.top;
}
gboolean
gdk_region_point_in (GdkRegion *region,
gint x,
gint y)
{
GdkRegionPrivate *private;
g_return_val_if_fail (region != NULL, 0);
private = (GdkRegionPrivate *) region;
return PtInRegion (private->xregion, x, y);
}
GdkOverlapType
gdk_region_rect_in (GdkRegion *region,
GdkRectangle *rect)
{
GdkRegionPrivate *private;
RECT r;
int res;
g_return_val_if_fail (region != NULL, 0);
private = (GdkRegionPrivate *) region;
r.left = rect->x;
r.top = rect->y;
r.right = rect->x + rect->width;
r.bottom = rect->y + rect->height;
if (RectInRegion (private->xregion, &r))
return GDK_OVERLAP_RECTANGLE_PART;
return GDK_OVERLAP_RECTANGLE_OUT; /*what else ? */
}
GdkRegion *
gdk_region_polygon (GdkPoint *points,
gint npoints,
GdkFillRule fill_rule)
{
GdkRegionPrivate *private;
GdkRegion *region;
HRGN xregion;
POINT *pts;
gint xfill_rule = ALTERNATE;
gint i;
g_return_val_if_fail (points != NULL, NULL);
g_return_val_if_fail (npoints != 0, NULL); /* maybe we should check for at least three points */
switch (fill_rule)
{
case GDK_EVEN_ODD_RULE:
xfill_rule = ALTERNATE;
break;
case GDK_WINDING_RULE:
xfill_rule = WINDING;
break;
}
pts = g_malloc (npoints * sizeof (*pts));
for (i = 0; i < npoints; i++)
{
pts[i].x = points[i].x;
pts[i].y = points[i].y;
}
xregion = CreatePolygonRgn (pts, npoints, xfill_rule);
g_free (pts);
private = g_new (GdkRegionPrivate, 1);
private->xregion = xregion;
region = (GdkRegion *) private;
region->user_data = NULL;
return region;
}
void
gdk_region_offset (GdkRegion *region,
gint dx,
gint dy)
{
GdkRegionPrivate *private;
g_return_if_fail (region != NULL);
private = (GdkRegionPrivate *) region;
OffsetRgn (private->xregion, dx, dy);
}
void
gdk_region_shrink (GdkRegion *region,
gint dx,
gint dy)
{
GdkRegionPrivate *private;
RECT r;
g_return_if_fail (region != NULL);
private = (GdkRegionPrivate *) region;
/* Is it correct just to intersect it with a smaller bounding box? */
GetRgnBox (private->xregion, &r);
if (-dx > r.right - r.left)
{
r.left += dx/2;
r.right -= dx/2;
}
if (-dy > r.bottom - r.top)
{
r.top += dy/2;
r.bottom -= dy/2;
}
CombineRgn (private->xregion, private->xregion,
CreateRectRgnIndirect (&r), RGN_AND);
}
GdkRegion*
gdk_region_union_with_rect (GdkRegion *region,
GdkRectangle *rect)
{
GdkRegionPrivate *private;
GdkRegion *res;
GdkRegionPrivate *res_private;
RECT xrect;
g_return_val_if_fail (region != NULL, NULL);
private = (GdkRegionPrivate *) region;
xrect.left = rect->x;
xrect.top = rect->y;
xrect.right = rect->x + rect->width;
xrect.bottom = rect->y + rect->height;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private->xregion,
CreateRectRgnIndirect (&xrect), RGN_OR);
return res;
}
GdkRegion*
gdk_regions_intersect (GdkRegion *source1,
GdkRegion *source2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
GdkRegion *res;
GdkRegionPrivate *res_private;
g_return_val_if_fail (source1 != NULL, NULL);
g_return_val_if_fail (source2 != NULL, NULL);
private1 = (GdkRegionPrivate *) source1;
private2 = (GdkRegionPrivate *) source2;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
RGN_AND);
return res;
}
GdkRegion*
gdk_regions_union (GdkRegion *source1,
GdkRegion *source2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
GdkRegion *res;
GdkRegionPrivate *res_private;
g_return_val_if_fail (source1 != NULL, NULL);
g_return_val_if_fail (source2 != NULL, NULL);
private1 = (GdkRegionPrivate *) source1;
private2 = (GdkRegionPrivate *) source2;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
RGN_OR);
return res;
}
GdkRegion*
gdk_regions_subtract (GdkRegion *source1,
GdkRegion *source2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
GdkRegion *res;
GdkRegionPrivate *res_private;
g_return_val_if_fail (source1 != NULL, NULL);
g_return_val_if_fail (source2 != NULL, NULL);
private1 = (GdkRegionPrivate *) source1;
private2 = (GdkRegionPrivate *) source2;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
RGN_DIFF);
return res;
}
GdkRegion*
gdk_regions_xor (GdkRegion *source1,
GdkRegion *source2)
{
GdkRegionPrivate *private1;
GdkRegionPrivate *private2;
GdkRegion *res;
GdkRegionPrivate *res_private;
g_return_val_if_fail (source1 != NULL, NULL);
g_return_val_if_fail (source2 != NULL, NULL);
private1 = (GdkRegionPrivate *) source1;
private2 = (GdkRegionPrivate *) source2;
res = gdk_region_new ();
res_private = (GdkRegionPrivate *) res;
CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
RGN_XOR);
return res;
}

3205
gdk/win32/gdkrgb.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,392 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <string.h>
#include "gdk.h"
#include "gdkx.h"
#include "gdkprivate.h"
/* We emulate the GDK_SELECTION window properties by storing
* it's data in a per-window hashtable.
*/
typedef struct {
guchar *data;
gint length;
gint format;
GdkAtom type;
} GdkSelProp;
static GHashTable *sel_prop_table = NULL;
void
gdk_selection_init (void)
{
if (sel_prop_table == NULL)
sel_prop_table = g_hash_table_new (g_int_hash, g_int_equal);
}
void
gdk_sel_prop_store (GdkWindow *owner,
GdkAtom type,
gint format,
guchar *data,
gint length)
{
GdkWindowPrivate *private = (GdkWindowPrivate *) owner;
GdkSelProp *prop;
prop = g_hash_table_lookup (sel_prop_table, &private->xwindow);
if (prop != NULL)
{
g_free (prop->data);
g_hash_table_remove (sel_prop_table, &private->xwindow);
}
prop = g_new (GdkSelProp, 1);
prop->data = data;
prop->length = length;
prop->format = format;
prop->type = type;
g_hash_table_insert (sel_prop_table, &private->xwindow, prop);
}
gint
gdk_selection_owner_set (GdkWindow *owner,
GdkAtom selection,
guint32 time,
gint send_event)
{
GdkWindowPrivate *private;
gchar *sel_name;
HWND xwindow;
private = (GdkWindowPrivate *) owner;
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
g_print ("gdk_selection_owner_set: %#x %#x (%s)\n",
(private ? private->xwindow : 0),
selection, sel_name),
g_free (sel_name)));
if (selection != gdk_clipboard_atom)
return FALSE;
if (owner != NULL)
xwindow = private->xwindow;
else
xwindow = NULL;
if (!OpenClipboard (xwindow))
{
g_warning ("gdk_selection_owner_set: OpenClipboard failed");
return FALSE;
}
if (!EmptyClipboard ())
{
g_warning ("gdk_selection_owner_set: EmptyClipboard failed");
CloseClipboard ();
return FALSE;
}
#if 0
/* No delayed rendering */
if (xwindow != NULL)
SetClipboardData (CF_TEXT, NULL);
#endif
if (!CloseClipboard ())
{
g_warning ("gdk_selection_owner_set: CloseClipboard failed");
return FALSE;
}
if (owner != NULL)
{
/* Send ourselves an ersatz selection request message so that
* gdk_property_change will be called to store the clipboard data.
*/
SendMessage (private->xwindow, gdk_selection_request_msg,
selection, 0);
}
return TRUE;
}
GdkWindow*
gdk_selection_owner_get (GdkAtom selection)
{
GdkWindow *window;
GdkWindowPrivate *private;
gchar *sel_name;
if (selection != gdk_clipboard_atom)
window = NULL;
else
window = gdk_window_lookup (GetClipboardOwner ());
private = (GdkWindowPrivate *) window;
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
g_print ("gdk_selection_owner_get: %#x (%s) = %#x\n",
selection, sel_name,
(private ? private->xwindow : 0)),
g_free (sel_name)));
return window;
}
void
gdk_selection_convert (GdkWindow *requestor,
GdkAtom selection,
GdkAtom target,
guint32 time)
{
GdkWindowPrivate *private;
HGLOBAL hdata;
GdkSelProp *prop;
guchar *ptr, *data, *datap, *p;
guint i, length, slength;
gchar *sel_name, *tgt_name;
g_return_if_fail (requestor != NULL);
private = (GdkWindowPrivate*) requestor;
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
tgt_name = gdk_atom_name (target),
g_print ("gdk_selection_convert: %#x %#x (%s) %#x (%s)\n",
private->xwindow, selection, sel_name, target, tgt_name),
g_free (sel_name),
g_free (tgt_name)));
if (selection == gdk_clipboard_atom)
{
/* Converting the CLIPBOARD selection means he wants the
* contents of the clipboard. Get the clipboard data,
* and store it for later.
*/
if (!OpenClipboard (private->xwindow))
{
g_warning ("gdk_selection_convert: OpenClipboard failed");
return;
}
if ((hdata = GetClipboardData (CF_TEXT)) != NULL)
{
if ((ptr = GlobalLock (hdata)) != NULL)
{
length = GlobalSize (hdata);
GDK_NOTE (SELECTION, g_print ("...got data: %d bytes: %.10s\n",
length, ptr));
slength = 0;
p = ptr;
for (i = 0; i < length; i++)
{
if (*p == '\0')
break;
else if (*p != '\r')
slength++;
p++;
}
data = datap = g_malloc (slength + 1);
p = ptr;
for (i = 0; i < length; i++)
{
if (*p == '\0')
break;
else if (*p != '\r')
*datap++ = *p;
p++;
}
*datap++ = '\0';
gdk_sel_prop_store (requestor, GDK_TARGET_STRING, 8,
data, strlen (data) + 1);
GlobalUnlock (hdata);
}
}
CloseClipboard ();
/* Send ourselves an ersatz selection notify message so that we actually
* fetch the data.
*/
SendMessage (private->xwindow, gdk_selection_notify_msg, selection, target);
}
else if (selection == gdk_win32_dropfiles_atom)
{
/* This means he wants the names of the dropped files.
* gdk_dropfiles_filter already has stored the text/uri-list
* data, tempoarily on gdk_root_parent's selection "property".
*/
GdkSelProp *prop;
prop = g_hash_table_lookup (sel_prop_table, &gdk_root_parent.xwindow);
if (prop != NULL)
{
g_hash_table_remove (sel_prop_table, &gdk_root_parent.xwindow);
gdk_sel_prop_store (requestor, prop->type, prop->format,
prop->data, prop->length);
g_free (prop);
SendMessage (private->xwindow, gdk_selection_notify_msg, selection, target);
}
}
else
{
g_warning ("gdk_selection_convert: General case not implemented");
}
}
gint
gdk_selection_property_get (GdkWindow *requestor,
guchar **data,
GdkAtom *ret_type,
gint *ret_format)
{
GdkWindowPrivate *private;
GdkSelProp *prop;
g_return_val_if_fail (requestor != NULL, 0);
private = (GdkWindowPrivate*) requestor;
if (private->destroyed)
return 0;
GDK_NOTE (SELECTION, g_print ("gdk_selection_property_get: %#x\n",
private->xwindow));
prop = g_hash_table_lookup (sel_prop_table, &private->xwindow);
if (prop == NULL)
{
*data = NULL;
return 0;
}
*data = g_malloc (prop->length);
if (prop->length > 0)
memmove (*data, prop->data, prop->length);
if (ret_type)
*ret_type = prop->type;
if (ret_format)
*ret_format = prop->format;
return prop->length;
}
void
gdk_selection_property_delete (GdkWindowPrivate *private)
{
GdkSelProp *prop;
prop = g_hash_table_lookup (sel_prop_table, &private->xwindow);
if (prop != NULL)
{
g_free (prop->data);
g_hash_table_remove (sel_prop_table, &private->xwindow);
}
else
g_warning ("huh?");
}
void
gdk_selection_send_notify (guint32 requestor,
GdkAtom selection,
GdkAtom target,
GdkAtom property,
guint32 time)
{
gchar *sel_name, *tgt_name, *prop_name;
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
tgt_name = gdk_atom_name (target),
prop_name = gdk_atom_name (property),
g_print ("gdk_selection_send_notify: %#x %#x (%s) %#x (%s) %#x (%s)\n",
requestor,
selection, sel_name,
target, tgt_name,
property, prop_name),
g_free (sel_name),
g_free (tgt_name),
g_free (prop_name)));
/* Send ourselves a selection clear message sot that gtk thinks we doen't
* have the selection, and will claim it anew when needed, and
* we thus get a chance to store data in the Windows clipboard.
* Otherwise, if a gtkeditable does a copy to clipboard several times
* only the first one actually gets copied to the Windows clipboard,
* as only he first one causes a call to gdk_property_change.
*/
SendMessage ((HWND) requestor, gdk_selection_clear_msg, selection, 0);
}
gint
gdk_text_property_to_text_list (GdkAtom encoding,
gint format,
guchar *text,
gint length,
gchar ***list)
{
GDK_NOTE (SELECTION,
g_print ("gdk_text_property_to_text_list not implemented\n"));
return 0;
}
void
gdk_free_text_list (gchar **list)
{
g_return_if_fail (list != NULL);
/* ??? */
}
gint
gdk_string_to_compound_text (gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length)
{
g_warning ("gdk_string_to_compound_text: Not implemented");
return 0;
}
void
gdk_free_compound_text (guchar *ctext)
{
g_warning ("gdk_free_compound_text: Not implemented");
}

392
gdk/win32/gdkselection.c Normal file
View File

@ -0,0 +1,392 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include <string.h>
#include "gdk.h"
#include "gdkx.h"
#include "gdkprivate.h"
/* We emulate the GDK_SELECTION window properties by storing
* it's data in a per-window hashtable.
*/
typedef struct {
guchar *data;
gint length;
gint format;
GdkAtom type;
} GdkSelProp;
static GHashTable *sel_prop_table = NULL;
void
gdk_selection_init (void)
{
if (sel_prop_table == NULL)
sel_prop_table = g_hash_table_new (g_int_hash, g_int_equal);
}
void
gdk_sel_prop_store (GdkWindow *owner,
GdkAtom type,
gint format,
guchar *data,
gint length)
{
GdkWindowPrivate *private = (GdkWindowPrivate *) owner;
GdkSelProp *prop;
prop = g_hash_table_lookup (sel_prop_table, &private->xwindow);
if (prop != NULL)
{
g_free (prop->data);
g_hash_table_remove (sel_prop_table, &private->xwindow);
}
prop = g_new (GdkSelProp, 1);
prop->data = data;
prop->length = length;
prop->format = format;
prop->type = type;
g_hash_table_insert (sel_prop_table, &private->xwindow, prop);
}
gint
gdk_selection_owner_set (GdkWindow *owner,
GdkAtom selection,
guint32 time,
gint send_event)
{
GdkWindowPrivate *private;
gchar *sel_name;
HWND xwindow;
private = (GdkWindowPrivate *) owner;
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
g_print ("gdk_selection_owner_set: %#x %#x (%s)\n",
(private ? private->xwindow : 0),
selection, sel_name),
g_free (sel_name)));
if (selection != gdk_clipboard_atom)
return FALSE;
if (owner != NULL)
xwindow = private->xwindow;
else
xwindow = NULL;
if (!OpenClipboard (xwindow))
{
g_warning ("gdk_selection_owner_set: OpenClipboard failed");
return FALSE;
}
if (!EmptyClipboard ())
{
g_warning ("gdk_selection_owner_set: EmptyClipboard failed");
CloseClipboard ();
return FALSE;
}
#if 0
/* No delayed rendering */
if (xwindow != NULL)
SetClipboardData (CF_TEXT, NULL);
#endif
if (!CloseClipboard ())
{
g_warning ("gdk_selection_owner_set: CloseClipboard failed");
return FALSE;
}
if (owner != NULL)
{
/* Send ourselves an ersatz selection request message so that
* gdk_property_change will be called to store the clipboard data.
*/
SendMessage (private->xwindow, gdk_selection_request_msg,
selection, 0);
}
return TRUE;
}
GdkWindow*
gdk_selection_owner_get (GdkAtom selection)
{
GdkWindow *window;
GdkWindowPrivate *private;
gchar *sel_name;
if (selection != gdk_clipboard_atom)
window = NULL;
else
window = gdk_window_lookup (GetClipboardOwner ());
private = (GdkWindowPrivate *) window;
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
g_print ("gdk_selection_owner_get: %#x (%s) = %#x\n",
selection, sel_name,
(private ? private->xwindow : 0)),
g_free (sel_name)));
return window;
}
void
gdk_selection_convert (GdkWindow *requestor,
GdkAtom selection,
GdkAtom target,
guint32 time)
{
GdkWindowPrivate *private;
HGLOBAL hdata;
GdkSelProp *prop;
guchar *ptr, *data, *datap, *p;
guint i, length, slength;
gchar *sel_name, *tgt_name;
g_return_if_fail (requestor != NULL);
private = (GdkWindowPrivate*) requestor;
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
tgt_name = gdk_atom_name (target),
g_print ("gdk_selection_convert: %#x %#x (%s) %#x (%s)\n",
private->xwindow, selection, sel_name, target, tgt_name),
g_free (sel_name),
g_free (tgt_name)));
if (selection == gdk_clipboard_atom)
{
/* Converting the CLIPBOARD selection means he wants the
* contents of the clipboard. Get the clipboard data,
* and store it for later.
*/
if (!OpenClipboard (private->xwindow))
{
g_warning ("gdk_selection_convert: OpenClipboard failed");
return;
}
if ((hdata = GetClipboardData (CF_TEXT)) != NULL)
{
if ((ptr = GlobalLock (hdata)) != NULL)
{
length = GlobalSize (hdata);
GDK_NOTE (SELECTION, g_print ("...got data: %d bytes: %.10s\n",
length, ptr));
slength = 0;
p = ptr;
for (i = 0; i < length; i++)
{
if (*p == '\0')
break;
else if (*p != '\r')
slength++;
p++;
}
data = datap = g_malloc (slength + 1);
p = ptr;
for (i = 0; i < length; i++)
{
if (*p == '\0')
break;
else if (*p != '\r')
*datap++ = *p;
p++;
}
*datap++ = '\0';
gdk_sel_prop_store (requestor, GDK_TARGET_STRING, 8,
data, strlen (data) + 1);
GlobalUnlock (hdata);
}
}
CloseClipboard ();
/* Send ourselves an ersatz selection notify message so that we actually
* fetch the data.
*/
SendMessage (private->xwindow, gdk_selection_notify_msg, selection, target);
}
else if (selection == gdk_win32_dropfiles_atom)
{
/* This means he wants the names of the dropped files.
* gdk_dropfiles_filter already has stored the text/uri-list
* data, tempoarily on gdk_root_parent's selection "property".
*/
GdkSelProp *prop;
prop = g_hash_table_lookup (sel_prop_table, &gdk_root_parent.xwindow);
if (prop != NULL)
{
g_hash_table_remove (sel_prop_table, &gdk_root_parent.xwindow);
gdk_sel_prop_store (requestor, prop->type, prop->format,
prop->data, prop->length);
g_free (prop);
SendMessage (private->xwindow, gdk_selection_notify_msg, selection, target);
}
}
else
{
g_warning ("gdk_selection_convert: General case not implemented");
}
}
gint
gdk_selection_property_get (GdkWindow *requestor,
guchar **data,
GdkAtom *ret_type,
gint *ret_format)
{
GdkWindowPrivate *private;
GdkSelProp *prop;
g_return_val_if_fail (requestor != NULL, 0);
private = (GdkWindowPrivate*) requestor;
if (private->destroyed)
return 0;
GDK_NOTE (SELECTION, g_print ("gdk_selection_property_get: %#x\n",
private->xwindow));
prop = g_hash_table_lookup (sel_prop_table, &private->xwindow);
if (prop == NULL)
{
*data = NULL;
return 0;
}
*data = g_malloc (prop->length);
if (prop->length > 0)
memmove (*data, prop->data, prop->length);
if (ret_type)
*ret_type = prop->type;
if (ret_format)
*ret_format = prop->format;
return prop->length;
}
void
gdk_selection_property_delete (GdkWindowPrivate *private)
{
GdkSelProp *prop;
prop = g_hash_table_lookup (sel_prop_table, &private->xwindow);
if (prop != NULL)
{
g_free (prop->data);
g_hash_table_remove (sel_prop_table, &private->xwindow);
}
else
g_warning ("huh?");
}
void
gdk_selection_send_notify (guint32 requestor,
GdkAtom selection,
GdkAtom target,
GdkAtom property,
guint32 time)
{
gchar *sel_name, *tgt_name, *prop_name;
GDK_NOTE (SELECTION,
(sel_name = gdk_atom_name (selection),
tgt_name = gdk_atom_name (target),
prop_name = gdk_atom_name (property),
g_print ("gdk_selection_send_notify: %#x %#x (%s) %#x (%s) %#x (%s)\n",
requestor,
selection, sel_name,
target, tgt_name,
property, prop_name),
g_free (sel_name),
g_free (tgt_name),
g_free (prop_name)));
/* Send ourselves a selection clear message sot that gtk thinks we doen't
* have the selection, and will claim it anew when needed, and
* we thus get a chance to store data in the Windows clipboard.
* Otherwise, if a gtkeditable does a copy to clipboard several times
* only the first one actually gets copied to the Windows clipboard,
* as only he first one causes a call to gdk_property_change.
*/
SendMessage ((HWND) requestor, gdk_selection_clear_msg, selection, 0);
}
gint
gdk_text_property_to_text_list (GdkAtom encoding,
gint format,
guchar *text,
gint length,
gchar ***list)
{
GDK_NOTE (SELECTION,
g_print ("gdk_text_property_to_text_list not implemented\n"));
return 0;
}
void
gdk_free_text_list (gchar **list)
{
g_return_if_fail (list != NULL);
/* ??? */
}
gint
gdk_string_to_compound_text (gchar *str,
GdkAtom *encoding,
gint *format,
guchar **ctext,
gint *length)
{
g_warning ("gdk_string_to_compound_text: Not implemented");
return 0;
}
void
gdk_free_compound_text (guchar *ctext)
{
g_warning ("gdk_free_compound_text: Not implemented");
}

1279
gdk/win32/gdktypes.h Normal file

File diff suppressed because it is too large Load Diff

527
gdk/win32/gdkvisual-win32.c Normal file
View File

@ -0,0 +1,527 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
#include "gdkx.h"
static void gdk_visual_add (GdkVisual *visual);
static void gdk_visual_decompose_mask (gulong mask,
gint *shift,
gint *prec);
static guint gdk_visual_hash (Visual *key);
static gint gdk_visual_compare (Visual *a,
Visual *b);
static GdkVisualPrivate *system_visual;
static GdkVisualPrivate *visuals;
static gint nvisuals;
static gint available_depths[7];
static gint navailable_depths;
static GdkVisualType available_types[6];
static gint navailable_types;
#ifdef G_ENABLE_DEBUG
static const gchar* visual_names[] =
{
"static gray",
"grayscale",
"static color",
"pseudo color",
"true color",
"direct color",
};
#endif /* G_ENABLE_DEBUG */
static GHashTable *visual_hash = NULL;
void
gdk_visual_init (void)
{
struct
{
BITMAPINFOHEADER bi;
union
{
RGBQUAD colors[256];
DWORD fields[256];
} u;
} bmi;
HBITMAP hbm;
static const gint possible_depths[7] = { 32, 24, 16, 15, 8, 4, 1 };
static const GdkVisualType possible_types[6] =
{
GDK_VISUAL_DIRECT_COLOR,
GDK_VISUAL_TRUE_COLOR,
GDK_VISUAL_PSEUDO_COLOR,
GDK_VISUAL_STATIC_COLOR,
GDK_VISUAL_GRAYSCALE,
GDK_VISUAL_STATIC_GRAY
};
static const gint npossible_depths = sizeof(possible_depths)/sizeof(gint);
static const gint npossible_types = sizeof(possible_types)/sizeof(GdkVisualType);
int rastercaps, numcolors, sizepalette, colorres, bitspixel;
Visual *default_xvisual;
GdkVisualPrivate temp_visual;
int nxvisuals;
int i, j;
nxvisuals = 1;
visuals = g_new (GdkVisualPrivate, nxvisuals);
nvisuals = 0;
for (i = 0; i < nxvisuals; i++)
{
if (1)
{
bitspixel = GetDeviceCaps (gdk_DC, BITSPIXEL);
rastercaps = GetDeviceCaps (gdk_DC, RASTERCAPS);
default_xvisual = g_new (Visual, 1);
visuals[nvisuals].xvisual = default_xvisual;
visuals[nvisuals].xvisual->visualid = nvisuals;
visuals[nvisuals].xvisual->bitspixel = bitspixel;
if (rastercaps & RC_PALETTE)
{
visuals[nvisuals].visual.type = GDK_VISUAL_PSEUDO_COLOR;
numcolors = GetDeviceCaps (gdk_DC, NUMCOLORS);
sizepalette = GetDeviceCaps (gdk_DC, SIZEPALETTE);
colorres = GetDeviceCaps (gdk_DC, COLORRES);
visuals[nvisuals].xvisual->map_entries = sizepalette;
}
else if (bitspixel == 1)
{
visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_GRAY;
visuals[nvisuals].xvisual->map_entries = 2;
}
else if (bitspixel == 4)
{
visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
visuals[nvisuals].xvisual->map_entries = 16;
}
else if (bitspixel == 8)
{
visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
visuals[nvisuals].xvisual->map_entries = 256;
}
else if (bitspixel == 16)
{
visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
#if 1
/* This code by Mike Enright,
* see http://www.users.cts.com/sd/m/menright/display.html
*/
memset (&bmi, 0, sizeof (bmi));
bmi.bi.biSize = sizeof (bmi.bi);
hbm = CreateCompatibleBitmap (gdk_DC, 1, 1);
GetDIBits (gdk_DC, hbm, 0, 1, NULL,
(BITMAPINFO *) &bmi, DIB_RGB_COLORS);
GetDIBits (gdk_DC, hbm, 0, 1, NULL,
(BITMAPINFO *) &bmi, DIB_RGB_COLORS);
DeleteObject (hbm);
if (bmi.bi.biCompression != BI_BITFIELDS)
{
/* Either BI_RGB or BI_RLE_something
* .... or perhaps (!!) something else.
* Theoretically biCompression might be
* mmioFourCC('c','v','i','d') but I doubt it.
*/
if (bmi.bi.biCompression == BI_RGB)
{
/* It's 555 */
bitspixel = 15;
visuals[nvisuals].visual.red_mask = 0x00007C00;
visuals[nvisuals].visual.green_mask = 0x000003E0;
visuals[nvisuals].visual.blue_mask = 0x0000001F;
}
else
{
g_assert_not_reached ();
}
}
else
{
DWORD allmasks =
bmi.u.fields[0] | bmi.u.fields[1] | bmi.u.fields[2];
int k = 0;
while (allmasks)
{
if (allmasks&1)
k++;
allmasks/=2;
}
bitspixel = k;
visuals[nvisuals].visual.red_mask = bmi.u.fields[0];
visuals[nvisuals].visual.green_mask = bmi.u.fields[1];
visuals[nvisuals].visual.blue_mask = bmi.u.fields[2];
}
#else
/* Old, incorrect (but still working) code. */
#if 0
visuals[nvisuals].visual.red_mask = 0x0000F800;
visuals[nvisuals].visual.green_mask = 0x000007E0;
visuals[nvisuals].visual.blue_mask = 0x0000001F;
#else
visuals[nvisuals].visual.red_mask = 0x00007C00;
visuals[nvisuals].visual.green_mask = 0x000003E0;
visuals[nvisuals].visual.blue_mask = 0x0000001F;
#endif
#endif
}
else if (bitspixel == 24 || bitspixel == 32)
{
visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
visuals[nvisuals].visual.red_mask = 0x00FF0000;
visuals[nvisuals].visual.green_mask = 0x0000FF00;
visuals[nvisuals].visual.blue_mask = 0x000000FF;
}
else
g_error ("gdk_visual_init: unsupported BITSPIXEL: %d\n", bitspixel);
visuals[nvisuals].visual.depth = bitspixel;
visuals[nvisuals].visual.byte_order = GDK_LSB_FIRST;
visuals[nvisuals].visual.bits_per_rgb = 42; /* Not used? */
if ((visuals[nvisuals].visual.type == GDK_VISUAL_TRUE_COLOR) ||
(visuals[nvisuals].visual.type == GDK_VISUAL_DIRECT_COLOR))
{
gdk_visual_decompose_mask (visuals[nvisuals].visual.red_mask,
&visuals[nvisuals].visual.red_shift,
&visuals[nvisuals].visual.red_prec);
gdk_visual_decompose_mask (visuals[nvisuals].visual.green_mask,
&visuals[nvisuals].visual.green_shift,
&visuals[nvisuals].visual.green_prec);
gdk_visual_decompose_mask (visuals[nvisuals].visual.blue_mask,
&visuals[nvisuals].visual.blue_shift,
&visuals[nvisuals].visual.blue_prec);
visuals[nvisuals].xvisual->map_entries =
1 << (MAX (visuals[nvisuals].visual.red_prec,
MAX (visuals[nvisuals].visual.green_prec,
visuals[nvisuals].visual.blue_prec)));
}
else
{
visuals[nvisuals].visual.red_mask = 0;
visuals[nvisuals].visual.red_shift = 0;
visuals[nvisuals].visual.red_prec = 0;
visuals[nvisuals].visual.green_mask = 0;
visuals[nvisuals].visual.green_shift = 0;
visuals[nvisuals].visual.green_prec = 0;
visuals[nvisuals].visual.blue_mask = 0;
visuals[nvisuals].visual.blue_shift = 0;
visuals[nvisuals].visual.blue_prec = 0;
}
visuals[nvisuals].visual.colormap_size = visuals[nvisuals].xvisual->map_entries;
nvisuals += 1;
}
}
for (i = 0; i < nvisuals; i++)
{
for (j = i+1; j < nvisuals; j++)
{
if (visuals[j].visual.depth >= visuals[i].visual.depth)
{
if ((visuals[j].visual.depth == 8) && (visuals[i].visual.depth == 8))
{
if (visuals[j].visual.type == GDK_VISUAL_PSEUDO_COLOR)
{
temp_visual = visuals[j];
visuals[j] = visuals[i];
visuals[i] = temp_visual;
}
else if ((visuals[i].visual.type != GDK_VISUAL_PSEUDO_COLOR) &&
visuals[j].visual.type > visuals[i].visual.type)
{
temp_visual = visuals[j];
visuals[j] = visuals[i];
visuals[i] = temp_visual;
}
}
else if ((visuals[j].visual.depth > visuals[i].visual.depth) ||
((visuals[j].visual.depth == visuals[i].visual.depth) &&
(visuals[j].visual.type > visuals[i].visual.type)))
{
temp_visual = visuals[j];
visuals[j] = visuals[i];
visuals[i] = temp_visual;
}
}
}
}
for (i = 0; i < nvisuals; i++)
if (default_xvisual->visualid == visuals[i].xvisual->visualid)
{
system_visual = &visuals[i];
break;
}
navailable_depths = 0;
for (i = 0; i < npossible_depths; i++)
{
for (j = 0; j < nvisuals; j++)
{
if (visuals[j].visual.depth == possible_depths[i])
{
available_depths[navailable_depths++] = visuals[j].visual.depth;
break;
}
}
}
if (navailable_depths == 0)
g_error ("unable to find a usable depth");
navailable_types = 0;
for (i = 0; i < npossible_types; i++)
{
for (j = 0; j < nvisuals; j++)
{
if (visuals[j].visual.type == possible_types[i])
{
available_types[navailable_types++] = visuals[j].visual.type;
break;
}
}
}
for (i = 0; i < nvisuals; i++)
gdk_visual_add ((GdkVisual*) &visuals[i]);
if (npossible_types == 0)
g_error ("unable to find a usable visual type");
}
GdkVisual*
gdk_visual_ref (GdkVisual *visual)
{
return visual;
}
void
gdk_visual_unref (GdkVisual *visual)
{
return;
}
gint
gdk_visual_get_best_depth (void)
{
return available_depths[0];
}
GdkVisualType
gdk_visual_get_best_type (void)
{
return available_types[0];
}
GdkVisual*
gdk_visual_get_system (void)
{
return ((GdkVisual*) system_visual);
}
GdkVisual*
gdk_visual_get_best (void)
{
return ((GdkVisual*) &(visuals[0]));
}
GdkVisual*
gdk_visual_get_best_with_depth (gint depth)
{
GdkVisual *return_val;
int i;
return_val = NULL;
for (i = 0; i < nvisuals; i++)
if (depth == visuals[i].visual.depth)
{
return_val = (GdkVisual*) &(visuals[i]);
break;
}
return return_val;
}
GdkVisual*
gdk_visual_get_best_with_type (GdkVisualType visual_type)
{
GdkVisual *return_val;
int i;
return_val = NULL;
for (i = 0; i < nvisuals; i++)
if (visual_type == visuals[i].visual.type)
{
return_val = (GdkVisual*) &(visuals[i]);
break;
}
return return_val;
}
GdkVisual*
gdk_visual_get_best_with_both (gint depth,
GdkVisualType visual_type)
{
GdkVisual *return_val;
int i;
return_val = NULL;
for (i = 0; i < nvisuals; i++)
if ((depth == visuals[i].visual.depth) &&
(visual_type == visuals[i].visual.type))
{
return_val = (GdkVisual*) &(visuals[i]);
break;
}
return return_val;
}
void
gdk_query_depths (gint **depths,
gint *count)
{
*count = navailable_depths;
*depths = available_depths;
}
void
gdk_query_visual_types (GdkVisualType **visual_types,
gint *count)
{
*count = navailable_types;
*visual_types = available_types;
}
GList*
gdk_list_visuals (void)
{
GList *list;
guint i;
list = NULL;
for (i = 0; i < nvisuals; ++i)
list = g_list_append (list, (gpointer) &visuals[i]);
return list;
}
GdkVisual*
gdk_visual_lookup (Visual *xvisual)
{
GdkVisual *visual;
if (!visual_hash)
return NULL;
visual = g_hash_table_lookup (visual_hash, xvisual);
return visual;
}
GdkVisual*
gdkx_visual_get (VisualID xvisualid)
{
int i;
for (i = 0; i < nvisuals; i++)
if (xvisualid == visuals[i].xvisual->visualid)
return (GdkVisual*) &visuals[i];
return NULL;
}
static void
gdk_visual_add (GdkVisual *visual)
{
GdkVisualPrivate *private;
if (!visual_hash)
visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
(GCompareFunc) gdk_visual_compare);
private = (GdkVisualPrivate*) visual;
g_hash_table_insert (visual_hash, private->xvisual, visual);
}
static void
gdk_visual_decompose_mask (gulong mask,
gint *shift,
gint *prec)
{
*shift = 0;
*prec = 0;
while (!(mask & 0x1))
{
(*shift)++;
mask >>= 1;
}
while (mask & 0x1)
{
(*prec)++;
mask >>= 1;
}
}
/* This hash stuff is pretty useless on Windows, as there is only
one visual... */
static guint
gdk_visual_hash (Visual *key)
{
return key->visualid;
}
static gint
gdk_visual_compare (Visual *a,
Visual *b)
{
return (a->visualid == b->visualid);
}

527
gdk/win32/gdkvisual.c Normal file
View File

@ -0,0 +1,527 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
#include "gdkx.h"
static void gdk_visual_add (GdkVisual *visual);
static void gdk_visual_decompose_mask (gulong mask,
gint *shift,
gint *prec);
static guint gdk_visual_hash (Visual *key);
static gint gdk_visual_compare (Visual *a,
Visual *b);
static GdkVisualPrivate *system_visual;
static GdkVisualPrivate *visuals;
static gint nvisuals;
static gint available_depths[7];
static gint navailable_depths;
static GdkVisualType available_types[6];
static gint navailable_types;
#ifdef G_ENABLE_DEBUG
static const gchar* visual_names[] =
{
"static gray",
"grayscale",
"static color",
"pseudo color",
"true color",
"direct color",
};
#endif /* G_ENABLE_DEBUG */
static GHashTable *visual_hash = NULL;
void
gdk_visual_init (void)
{
struct
{
BITMAPINFOHEADER bi;
union
{
RGBQUAD colors[256];
DWORD fields[256];
} u;
} bmi;
HBITMAP hbm;
static const gint possible_depths[7] = { 32, 24, 16, 15, 8, 4, 1 };
static const GdkVisualType possible_types[6] =
{
GDK_VISUAL_DIRECT_COLOR,
GDK_VISUAL_TRUE_COLOR,
GDK_VISUAL_PSEUDO_COLOR,
GDK_VISUAL_STATIC_COLOR,
GDK_VISUAL_GRAYSCALE,
GDK_VISUAL_STATIC_GRAY
};
static const gint npossible_depths = sizeof(possible_depths)/sizeof(gint);
static const gint npossible_types = sizeof(possible_types)/sizeof(GdkVisualType);
int rastercaps, numcolors, sizepalette, colorres, bitspixel;
Visual *default_xvisual;
GdkVisualPrivate temp_visual;
int nxvisuals;
int i, j;
nxvisuals = 1;
visuals = g_new (GdkVisualPrivate, nxvisuals);
nvisuals = 0;
for (i = 0; i < nxvisuals; i++)
{
if (1)
{
bitspixel = GetDeviceCaps (gdk_DC, BITSPIXEL);
rastercaps = GetDeviceCaps (gdk_DC, RASTERCAPS);
default_xvisual = g_new (Visual, 1);
visuals[nvisuals].xvisual = default_xvisual;
visuals[nvisuals].xvisual->visualid = nvisuals;
visuals[nvisuals].xvisual->bitspixel = bitspixel;
if (rastercaps & RC_PALETTE)
{
visuals[nvisuals].visual.type = GDK_VISUAL_PSEUDO_COLOR;
numcolors = GetDeviceCaps (gdk_DC, NUMCOLORS);
sizepalette = GetDeviceCaps (gdk_DC, SIZEPALETTE);
colorres = GetDeviceCaps (gdk_DC, COLORRES);
visuals[nvisuals].xvisual->map_entries = sizepalette;
}
else if (bitspixel == 1)
{
visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_GRAY;
visuals[nvisuals].xvisual->map_entries = 2;
}
else if (bitspixel == 4)
{
visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
visuals[nvisuals].xvisual->map_entries = 16;
}
else if (bitspixel == 8)
{
visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
visuals[nvisuals].xvisual->map_entries = 256;
}
else if (bitspixel == 16)
{
visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
#if 1
/* This code by Mike Enright,
* see http://www.users.cts.com/sd/m/menright/display.html
*/
memset (&bmi, 0, sizeof (bmi));
bmi.bi.biSize = sizeof (bmi.bi);
hbm = CreateCompatibleBitmap (gdk_DC, 1, 1);
GetDIBits (gdk_DC, hbm, 0, 1, NULL,
(BITMAPINFO *) &bmi, DIB_RGB_COLORS);
GetDIBits (gdk_DC, hbm, 0, 1, NULL,
(BITMAPINFO *) &bmi, DIB_RGB_COLORS);
DeleteObject (hbm);
if (bmi.bi.biCompression != BI_BITFIELDS)
{
/* Either BI_RGB or BI_RLE_something
* .... or perhaps (!!) something else.
* Theoretically biCompression might be
* mmioFourCC('c','v','i','d') but I doubt it.
*/
if (bmi.bi.biCompression == BI_RGB)
{
/* It's 555 */
bitspixel = 15;
visuals[nvisuals].visual.red_mask = 0x00007C00;
visuals[nvisuals].visual.green_mask = 0x000003E0;
visuals[nvisuals].visual.blue_mask = 0x0000001F;
}
else
{
g_assert_not_reached ();
}
}
else
{
DWORD allmasks =
bmi.u.fields[0] | bmi.u.fields[1] | bmi.u.fields[2];
int k = 0;
while (allmasks)
{
if (allmasks&1)
k++;
allmasks/=2;
}
bitspixel = k;
visuals[nvisuals].visual.red_mask = bmi.u.fields[0];
visuals[nvisuals].visual.green_mask = bmi.u.fields[1];
visuals[nvisuals].visual.blue_mask = bmi.u.fields[2];
}
#else
/* Old, incorrect (but still working) code. */
#if 0
visuals[nvisuals].visual.red_mask = 0x0000F800;
visuals[nvisuals].visual.green_mask = 0x000007E0;
visuals[nvisuals].visual.blue_mask = 0x0000001F;
#else
visuals[nvisuals].visual.red_mask = 0x00007C00;
visuals[nvisuals].visual.green_mask = 0x000003E0;
visuals[nvisuals].visual.blue_mask = 0x0000001F;
#endif
#endif
}
else if (bitspixel == 24 || bitspixel == 32)
{
visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
visuals[nvisuals].visual.red_mask = 0x00FF0000;
visuals[nvisuals].visual.green_mask = 0x0000FF00;
visuals[nvisuals].visual.blue_mask = 0x000000FF;
}
else
g_error ("gdk_visual_init: unsupported BITSPIXEL: %d\n", bitspixel);
visuals[nvisuals].visual.depth = bitspixel;
visuals[nvisuals].visual.byte_order = GDK_LSB_FIRST;
visuals[nvisuals].visual.bits_per_rgb = 42; /* Not used? */
if ((visuals[nvisuals].visual.type == GDK_VISUAL_TRUE_COLOR) ||
(visuals[nvisuals].visual.type == GDK_VISUAL_DIRECT_COLOR))
{
gdk_visual_decompose_mask (visuals[nvisuals].visual.red_mask,
&visuals[nvisuals].visual.red_shift,
&visuals[nvisuals].visual.red_prec);
gdk_visual_decompose_mask (visuals[nvisuals].visual.green_mask,
&visuals[nvisuals].visual.green_shift,
&visuals[nvisuals].visual.green_prec);
gdk_visual_decompose_mask (visuals[nvisuals].visual.blue_mask,
&visuals[nvisuals].visual.blue_shift,
&visuals[nvisuals].visual.blue_prec);
visuals[nvisuals].xvisual->map_entries =
1 << (MAX (visuals[nvisuals].visual.red_prec,
MAX (visuals[nvisuals].visual.green_prec,
visuals[nvisuals].visual.blue_prec)));
}
else
{
visuals[nvisuals].visual.red_mask = 0;
visuals[nvisuals].visual.red_shift = 0;
visuals[nvisuals].visual.red_prec = 0;
visuals[nvisuals].visual.green_mask = 0;
visuals[nvisuals].visual.green_shift = 0;
visuals[nvisuals].visual.green_prec = 0;
visuals[nvisuals].visual.blue_mask = 0;
visuals[nvisuals].visual.blue_shift = 0;
visuals[nvisuals].visual.blue_prec = 0;
}
visuals[nvisuals].visual.colormap_size = visuals[nvisuals].xvisual->map_entries;
nvisuals += 1;
}
}
for (i = 0; i < nvisuals; i++)
{
for (j = i+1; j < nvisuals; j++)
{
if (visuals[j].visual.depth >= visuals[i].visual.depth)
{
if ((visuals[j].visual.depth == 8) && (visuals[i].visual.depth == 8))
{
if (visuals[j].visual.type == GDK_VISUAL_PSEUDO_COLOR)
{
temp_visual = visuals[j];
visuals[j] = visuals[i];
visuals[i] = temp_visual;
}
else if ((visuals[i].visual.type != GDK_VISUAL_PSEUDO_COLOR) &&
visuals[j].visual.type > visuals[i].visual.type)
{
temp_visual = visuals[j];
visuals[j] = visuals[i];
visuals[i] = temp_visual;
}
}
else if ((visuals[j].visual.depth > visuals[i].visual.depth) ||
((visuals[j].visual.depth == visuals[i].visual.depth) &&
(visuals[j].visual.type > visuals[i].visual.type)))
{
temp_visual = visuals[j];
visuals[j] = visuals[i];
visuals[i] = temp_visual;
}
}
}
}
for (i = 0; i < nvisuals; i++)
if (default_xvisual->visualid == visuals[i].xvisual->visualid)
{
system_visual = &visuals[i];
break;
}
navailable_depths = 0;
for (i = 0; i < npossible_depths; i++)
{
for (j = 0; j < nvisuals; j++)
{
if (visuals[j].visual.depth == possible_depths[i])
{
available_depths[navailable_depths++] = visuals[j].visual.depth;
break;
}
}
}
if (navailable_depths == 0)
g_error ("unable to find a usable depth");
navailable_types = 0;
for (i = 0; i < npossible_types; i++)
{
for (j = 0; j < nvisuals; j++)
{
if (visuals[j].visual.type == possible_types[i])
{
available_types[navailable_types++] = visuals[j].visual.type;
break;
}
}
}
for (i = 0; i < nvisuals; i++)
gdk_visual_add ((GdkVisual*) &visuals[i]);
if (npossible_types == 0)
g_error ("unable to find a usable visual type");
}
GdkVisual*
gdk_visual_ref (GdkVisual *visual)
{
return visual;
}
void
gdk_visual_unref (GdkVisual *visual)
{
return;
}
gint
gdk_visual_get_best_depth (void)
{
return available_depths[0];
}
GdkVisualType
gdk_visual_get_best_type (void)
{
return available_types[0];
}
GdkVisual*
gdk_visual_get_system (void)
{
return ((GdkVisual*) system_visual);
}
GdkVisual*
gdk_visual_get_best (void)
{
return ((GdkVisual*) &(visuals[0]));
}
GdkVisual*
gdk_visual_get_best_with_depth (gint depth)
{
GdkVisual *return_val;
int i;
return_val = NULL;
for (i = 0; i < nvisuals; i++)
if (depth == visuals[i].visual.depth)
{
return_val = (GdkVisual*) &(visuals[i]);
break;
}
return return_val;
}
GdkVisual*
gdk_visual_get_best_with_type (GdkVisualType visual_type)
{
GdkVisual *return_val;
int i;
return_val = NULL;
for (i = 0; i < nvisuals; i++)
if (visual_type == visuals[i].visual.type)
{
return_val = (GdkVisual*) &(visuals[i]);
break;
}
return return_val;
}
GdkVisual*
gdk_visual_get_best_with_both (gint depth,
GdkVisualType visual_type)
{
GdkVisual *return_val;
int i;
return_val = NULL;
for (i = 0; i < nvisuals; i++)
if ((depth == visuals[i].visual.depth) &&
(visual_type == visuals[i].visual.type))
{
return_val = (GdkVisual*) &(visuals[i]);
break;
}
return return_val;
}
void
gdk_query_depths (gint **depths,
gint *count)
{
*count = navailable_depths;
*depths = available_depths;
}
void
gdk_query_visual_types (GdkVisualType **visual_types,
gint *count)
{
*count = navailable_types;
*visual_types = available_types;
}
GList*
gdk_list_visuals (void)
{
GList *list;
guint i;
list = NULL;
for (i = 0; i < nvisuals; ++i)
list = g_list_append (list, (gpointer) &visuals[i]);
return list;
}
GdkVisual*
gdk_visual_lookup (Visual *xvisual)
{
GdkVisual *visual;
if (!visual_hash)
return NULL;
visual = g_hash_table_lookup (visual_hash, xvisual);
return visual;
}
GdkVisual*
gdkx_visual_get (VisualID xvisualid)
{
int i;
for (i = 0; i < nvisuals; i++)
if (xvisualid == visuals[i].xvisual->visualid)
return (GdkVisual*) &visuals[i];
return NULL;
}
static void
gdk_visual_add (GdkVisual *visual)
{
GdkVisualPrivate *private;
if (!visual_hash)
visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
(GCompareFunc) gdk_visual_compare);
private = (GdkVisualPrivate*) visual;
g_hash_table_insert (visual_hash, private->xvisual, visual);
}
static void
gdk_visual_decompose_mask (gulong mask,
gint *shift,
gint *prec)
{
*shift = 0;
*prec = 0;
while (!(mask & 0x1))
{
(*shift)++;
mask >>= 1;
}
while (mask & 0x1)
{
(*prec)++;
mask >>= 1;
}
}
/* This hash stuff is pretty useless on Windows, as there is only
one visual... */
static guint
gdk_visual_hash (Visual *key)
{
return key->visualid;
}
static gint
gdk_visual_compare (Visual *a,
Visual *b)
{
return (a->visualid == b->visualid);
}

59
gdk/win32/gdkwin32.h Normal file
View File

@ -0,0 +1,59 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GDK_X_H__
#define __GDK_X_H__
#include <gdk/gdk.h>
#include <gdk/gdkprivate.h>
#include <time.h>
#include <locale.h>
#define GDK_ROOT_WINDOW() ((guint32) HWND_DESKTOP)
#define GDK_ROOT_PARENT() ((GdkWindow *)&gdk_root_parent)
#define GDK_DISPLAY() NULL
#define GDK_WINDOW_XDISPLAY(win) NULL
#define GDK_WINDOW_XWINDOW(win) (((GdkWindowPrivate*) win)->xwindow)
#define GDK_IMAGE_XDISPLAY(image) NULL
#define GDK_IMAGE_XIMAGE(image) (((GdkImagePrivate*) image)->ximage)
#define GDK_GC_XDISPLAY(gc) NULL
#define GDK_GC_XGC(gc) (((GdkGCPrivate*) gc)->xgc)
#define GDK_COLORMAP_XDISPLAY(cmap) NULL
#define GDK_COLORMAP_XCOLORMAP(cmap) (((GdkColormapPrivate*) cmap)->xcolormap)
#define GDK_VISUAL_XVISUAL(vis) (((GdkVisualPrivate*) vis)->xvisual)
#define GDK_FONT_XDISPLAY(font) NULL
#define GDK_FONT_XFONT(font) (((GdkFontPrivate*) font)->xfont)
GdkVisual* gdkx_visual_get (VisualID xvisualid);
/* XXX: Do not use this function until it is fixed. An X Colormap
* is useless unless we also have the visual. */
GdkColormap* gdkx_colormap_get (Colormap xcolormap);
/* Functions to create GDK pixmaps and windows from their native equivalents */
GdkPixmap *gdk_pixmap_foreign_new (guint32 anid);
GdkWindow *gdk_window_foreign_new (guint32 anid);
#endif /* __GDK_X_H__ */

87
gdk/win32/gdkwin32id.c Normal file
View File

@ -0,0 +1,87 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
#include <stdio.h>
static guint gdk_xid_hash (XID *xid);
static gint gdk_xid_compare (XID *a,
XID *b);
static GHashTable *xid_ht = NULL;
void
gdk_xid_table_insert (XID *xid,
gpointer data)
{
g_return_if_fail (xid != NULL);
if (!xid_ht)
xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
(GCompareFunc) gdk_xid_compare);
g_hash_table_insert (xid_ht, xid, data);
}
void
gdk_xid_table_remove (XID xid)
{
if (!xid_ht)
xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
(GCompareFunc) gdk_xid_compare);
g_hash_table_remove (xid_ht, &xid);
}
gpointer
gdk_xid_table_lookup (XID xid)
{
gpointer data = NULL;
if (xid_ht)
data = g_hash_table_lookup (xid_ht, &xid);
return data;
}
static guint
gdk_xid_hash (XID *xid)
{
return (guint) *xid;
}
static gint
gdk_xid_compare (XID *a,
XID *b)
{
return (*a == *b);
}

2560
gdk/win32/gdkwindow-win32.c Normal file

File diff suppressed because it is too large Load Diff

2560
gdk/win32/gdkwindow.c Normal file

File diff suppressed because it is too large Load Diff

59
gdk/win32/gdkx.h Normal file
View File

@ -0,0 +1,59 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GDK_X_H__
#define __GDK_X_H__
#include <gdk/gdk.h>
#include <gdk/gdkprivate.h>
#include <time.h>
#include <locale.h>
#define GDK_ROOT_WINDOW() ((guint32) HWND_DESKTOP)
#define GDK_ROOT_PARENT() ((GdkWindow *)&gdk_root_parent)
#define GDK_DISPLAY() NULL
#define GDK_WINDOW_XDISPLAY(win) NULL
#define GDK_WINDOW_XWINDOW(win) (((GdkWindowPrivate*) win)->xwindow)
#define GDK_IMAGE_XDISPLAY(image) NULL
#define GDK_IMAGE_XIMAGE(image) (((GdkImagePrivate*) image)->ximage)
#define GDK_GC_XDISPLAY(gc) NULL
#define GDK_GC_XGC(gc) (((GdkGCPrivate*) gc)->xgc)
#define GDK_COLORMAP_XDISPLAY(cmap) NULL
#define GDK_COLORMAP_XCOLORMAP(cmap) (((GdkColormapPrivate*) cmap)->xcolormap)
#define GDK_VISUAL_XVISUAL(vis) (((GdkVisualPrivate*) vis)->xvisual)
#define GDK_FONT_XDISPLAY(font) NULL
#define GDK_FONT_XFONT(font) (((GdkFontPrivate*) font)->xfont)
GdkVisual* gdkx_visual_get (VisualID xvisualid);
/* XXX: Do not use this function until it is fixed. An X Colormap
* is useless unless we also have the visual. */
GdkColormap* gdkx_colormap_get (Colormap xcolormap);
/* Functions to create GDK pixmaps and windows from their native equivalents */
GdkPixmap *gdk_pixmap_foreign_new (guint32 anid);
GdkWindow *gdk_window_foreign_new (guint32 anid);
#endif /* __GDK_X_H__ */

87
gdk/win32/gdkxid.c Normal file
View File

@ -0,0 +1,87 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gdk.h"
#include "gdkprivate.h"
#include <stdio.h>
static guint gdk_xid_hash (XID *xid);
static gint gdk_xid_compare (XID *a,
XID *b);
static GHashTable *xid_ht = NULL;
void
gdk_xid_table_insert (XID *xid,
gpointer data)
{
g_return_if_fail (xid != NULL);
if (!xid_ht)
xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
(GCompareFunc) gdk_xid_compare);
g_hash_table_insert (xid_ht, xid, data);
}
void
gdk_xid_table_remove (XID xid)
{
if (!xid_ht)
xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
(GCompareFunc) gdk_xid_compare);
g_hash_table_remove (xid_ht, &xid);
}
gpointer
gdk_xid_table_lookup (XID xid)
{
gpointer data = NULL;
if (xid_ht)
data = g_hash_table_lookup (xid_ht, &xid);
return data;
}
static guint
gdk_xid_hash (XID *xid)
{
return (guint) *xid;
}
static gint
gdk_xid_compare (XID *a,
XID *b)
{
return (*a == *b);
}

BIN
gdk/win32/rc/cursor00.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor02.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor04.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor06.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor08.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor0a.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor0c.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor0e.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor10.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor12.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor14.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor16.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor18.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor1a.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor1c.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

BIN
gdk/win32/rc/cursor1e.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor20.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor22.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor24.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor26.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor28.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor2a.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor2c.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor2e.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor30.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor32.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor34.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor36.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor38.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor3a.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

BIN
gdk/win32/rc/cursor3c.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor3e.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor40.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor42.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor44.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor46.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor48.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor4a.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor4c.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor4e.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor50.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor52.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor54.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor56.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor58.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor5a.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor5c.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor5e.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor60.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor62.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor64.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
gdk/win32/rc/cursor66.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Some files were not shown because too many files have changed in this diff Show More