/* GDK - The GIMP Drawing Kit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 * Copyright (C) 1998-2002 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/. 
 */

#ifndef __GDK_PRIVATE_WIN32_H__
#define __GDK_PRIVATE_WIN32_H__

#ifndef STRICT
#define STRICT			/* We want strict type checks */
#endif
#include <windows.h>
#include <commctrl.h>

/* Make up for mingw32 header lossage */

/* PS_JOIN_MASK is missing from the mingw32 headers */
#ifndef PS_JOIN_MASK
#define PS_JOIN_MASK (PS_JOIN_BEVEL|PS_JOIN_MITER|PS_JOIN_ROUND)
#endif

/* CLR_INVALID is missing */
#ifndef CLR_INVALID
#define CLR_INVALID CLR_NONE
#endif

/* Some charsets are missing */
#ifndef JOHAB_CHARSET
#define JOHAB_CHARSET 130
#endif
#ifndef VIETNAMESE_CHARSET
#define VIETNAMESE_CHARSET 163
#endif

#ifndef FS_VIETNAMESE
#define FS_VIETNAMESE 0x100
#endif

#ifndef VM_OEM_PLUS
#define VK_OEM_PLUS 0xBB
#endif
#ifndef VK_OEM_COMMA
#define VK_OEM_COMMA 0xBC
#endif
#ifndef VK_OEM_MINUS
#define VK_OEM_MINUS 0xBD
#endif
#ifndef VK_OEM_PERIOD
#define VK_OEM_PERIOD 0xBE
#endif

#ifndef VK_OEM_1
#define VK_OEM_1 0xBA
#endif
#ifndef VK_OEM_2
#define VK_OEM_2 0xBF
#endif
#ifndef VK_OEM_3
#define VK_OEM_3 0xC0
#endif
#ifndef VK_OEM_4
#define VK_OEM_4 0xDB
#endif
#ifndef VK_OEM_5
#define VK_OEM_5 0xDC
#endif
#ifndef VK_OEM_6
#define VK_OEM_6 0xDD
#endif
#ifndef VK_OEM_7
#define VK_OEM_7 0xDE
#endif
#ifndef VK_OEM_8
#define VK_OEM_8 0xDF
#endif

/* Missing messages */
#ifndef WM_SYNCPAINT
#define WM_SYNCPAINT 0x88
#endif
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0X20A
#endif
#ifndef WM_GETOBJECT
#define WM_GETOBJECT 0x003D
#endif
#ifndef WM_NCXBUTTONDOWN
#define WM_NCXBUTTONDOWN 0x00AB
#endif
#ifndef WM_NCXBUTTONUP
#define WM_NCXBUTTONUP 0x00AC
#endif
#ifndef WM_NCXBUTTONDBLCLK
#define WM_NCXBUTTONDBLCLK 0x00AD
#endif
#ifndef WM_MENURBUTTONUP
#define WM_MENURBUTTONUP 0x0122
#endif
#ifndef WM_MENUDRAG
#define WM_MENUDRAG 0x0123
#endif
#ifndef WM_MENUGETOBJECT
#define WM_MENUGETOBJECT 0x0124
#endif
#ifndef WM_UNINITMENUPOPUP
#define WM_UNINITMENUPOPUP 0x0125
#endif
#ifndef WM_MENUCOMMAND
#define WM_MENUCOMMAND 0x0126
#endif
#ifndef WM_CHANGEUISTATE
#define WM_CHANGEUISTATE 0x0127
#endif
#ifndef WM_UPDATEUISTATE
#define WM_UPDATEUISTATE 0x0128
#endif
#ifndef WM_QUERYUISTATE
#define WM_QUERYUISTATE 0x0129
#endif
#ifndef WM_XBUTTONDOWN
#define WM_XBUTTONDOWN 0x020B
#endif
#ifndef WM_XBUTTONUP
#define WM_XBUTTONUP 0x020C
#endif
#ifndef WM_XBUTTONDBLCLK
#define WM_XBUTTONDBLCLK 0x020D
#endif
#ifndef WM_IME_REQUEST
#define WM_IME_REQUEST 0x0288
#endif
#ifndef WM_MOUSEHOVER
#define WM_MOUSEHOVER 0x02A1
#endif
#ifndef WM_MOUSELEAVE
#define WM_MOUSELEAVE 0x02A3
#endif
#ifndef WM_NCMOUSEHOVER
#define WM_NCMOUSEHOVER 0x02A0
#endif
#ifndef WM_NCMOUSELEAVE
#define WM_NCMOUSELEAVE 0x02A2
#endif
#ifndef WM_APPCOMMAND
#define WM_APPCOMMAND 0x0319
#endif
#ifndef WM_HANDHELDFIRST
#define WM_HANDHELDFIRST 0x0358
#endif
#ifndef WM_HANDHELDLAST
#define WM_HANDHELDLAST 0x035F
#endif
#ifndef WM_AFXFIRST
#define WM_AFXFIRST 0x0360
#endif
#ifndef WM_AFXLAST
#define WM_AFXLAST 0x037F
#endif

#ifndef CopyCursor
#define CopyCursor(pcur) ((HCURSOR)CopyIcon((HICON)(pcur)))
#endif

#include <gdk/gdktypes.h>
#include <gdk/gdkprivate.h>

#include <gdk/gdkcursor.h>
#include <gdk/gdkevents.h>
#include <gdk/gdkfont.h>
#include <gdk/gdkgc.h>
#include <gdk/gdkim.h>
#include <gdk/gdkimage.h>
#include <gdk/gdkvisual.h>
#include <gdk/gdkwindow.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* Define some of the X11 constants also here, just for laziness */

/* Error codes */
#define Success            0

/* Grabbing status */
#define GrabSuccess	   0
#define AlreadyGrabbed	   2

typedef struct _GdkGCWin32Data          GdkGCWin32Data;
typedef struct _GdkDrawableWin32Data    GdkDrawableWin32Data;
typedef struct _GdkWindowWin32Data      GdkWindowWin32Data;
typedef struct _GdkColormapPrivateWin32 GdkColormapPrivateWin32;
typedef struct _GdkCursorPrivate        GdkCursorPrivate;
typedef struct _GdkWin32SingleFont      GdkWin32SingleFont;
typedef struct _GdkFontPrivateWin32     GdkFontPrivateWin32;
typedef struct _GdkImagePrivateWin32    GdkImagePrivateWin32;
typedef struct _GdkVisualPrivate        GdkVisualPrivate;
typedef struct _GdkRegionPrivate        GdkRegionPrivate;
typedef struct _GdkICPrivate            GdkICPrivate;

#define GDK_DRAWABLE_WIN32DATA(win) ((GdkDrawableWin32Data *)(((GdkDrawablePrivate*)(win))->klass_data))
#define GDK_WINDOW_WIN32DATA(win) ((GdkWindowWin32Data *)(((GdkDrawablePrivate*)(win))->klass_data))
#define GDK_GC_WIN32DATA(gc) ((GdkGCWin32Data *)(((GdkGCPrivate*)(gc))->klass_data))

struct _GdkGCWin32Data
{
  /* 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
   * GdkGCWin32Data struct.
   */
  HDC xgc;
  GdkGCValuesMask values_mask;
  gulong foreground;		/* Pixel values from GdkColor, */
  gulong background;		/* not Win32 COLORREFs */
  GdkFont *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
				 */
  HPALETTE holdpal;
};

struct _GdkDrawableWin32Data
{
  HANDLE xid;

  GdkImage *image;		/* For GdkPixmaps, a pointer to the GdkImage
				 * containing the pixels.
				 */
};

struct _GdkWindowWin32Data
{
  GdkDrawableWin32Data drawable;

  DWORD owner_thread_id;

  /* 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;
  gulong bg_pixel;		/* GdkColor pixel, not COLORREF */
  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;

  gboolean extension_events_selected;

  HKL input_locale;
  CHARSETINFO charset_info;
};

struct _GdkCursorPrivate
{
  GdkCursor cursor;
  HCURSOR xcursor;
};

struct _GdkWin32SingleFont
{
  HFONT xfont;
  UINT charset;
  UINT codepage;
  FONTSIGNATURE fs;
  GdkFont* font_set;
};

struct _GdkFontPrivateWin32
{
  GdkFontPrivate base;
  GSList *fonts;		/* List of GdkWin32SingleFonts */
  GSList *names;
};

struct _GdkVisualPrivate
{
  GdkVisual visual;
};

typedef enum {
  GDK_WIN32_PE_STATIC,
  GDK_WIN32_PE_AVAILABLE,
  GDK_WIN32_PE_INUSE
} GdkWin32PalEntryState;

struct _GdkColormapPrivateWin32
{
  GdkColormapPrivate base;
  HPALETTE hpal;
  gint current_size;		/* Current size of hpal */
  GdkWin32PalEntryState *use;
  gint private_val;
  GHashTable *hash;
  GdkColorInfo *info;
};

struct _GdkImagePrivateWin32
{
  GdkImagePrivate base;
  GdkDrawable *pixmap;
};

struct _GdkRegionPrivate
{
  GdkRegion region;
  HRGN xregion;
};

void gdk_win32_selection_init (void);
void gdk_win32_dnd_exit (void);


void	 gdk_xid_table_insert    (HANDLE   *hnd,
				  gpointer data);
void	 gdk_xid_table_remove    (HANDLE xid);
gpointer gdk_xid_table_lookup    (HANDLE xid);

GdkGC *  _gdk_win32_gc_new       (GdkDrawable        *drawable,
				  GdkGCValues        *values,
				  GdkGCValuesMask     values_mask);
COLORREF gdk_win32_colormap_color_pack (GdkColormapPrivateWin32 *colormap_private,
					gulong                   pixel);
void     gdk_win32_colormap_color_unpack (GdkColormapPrivateWin32 *colormap_private,
					  COLORREF                 color,
					  GdkColor                *result);
HDC	 gdk_gc_predraw          (GdkDrawable        *drawable,
				  GdkGCPrivate       *gc_private,
				  GdkGCValuesMask     usage);
void	 gdk_gc_postdraw         (GdkDrawable        *drawable,
				  GdkGCPrivate       *gc_private,
				  GdkGCValuesMask     usage);

void    gdk_win32_clear_hdc_cache (void);
void    gdk_win32_clear_hdc_cache_for_hwnd (HWND hwnd);

GdkPixmap* gdk_win32_pixmap_new (GdkWindow *window,
				 GdkVisual *visual,
				 gint       width,
				 gint       height,
				 gint       depth);

void     gdk_win32_blit         (gboolean     use_fg_bg,
				 GdkDrawable *drawable,
				 GdkGC       *gc,
				 GdkPixmap   *src,
				 gint         xsrc,
				 gint         ysrc,
				 gint         xdest,
				 gint         ydest,
				 gint         width,
				 gint         height);

GdkImagePrivateWin32 *gdk_win32_image_alloc (void);

HRGN	gdk_win32_bitmap_to_region (GdkPixmap *pixmap);

void    gdk_win32_dropfiles_store(gchar *data);

void    gdk_selection_property_delete (GdkWindow *);

gint gdk_nmbstowcs               (GdkWChar    *dest,
				  const gchar *src,
				  gint         src_len,
				  gint         dest_max);
gint gdk_nmbstowchar_ts          (wchar_t     *dest,
				  const gchar *src,
				  gint         src_len,
				  gint         dest_max);

gchar *gdk_nwchar_ts_to_mbs      (const wchar_t *src,
				  gint           src_len);

void gdk_wchar_text_handle       (GdkFont       *font,
				  const wchar_t *wcstr,
				  int            wclen,
				  void         (*handler)(GdkWin32SingleFont *,
							  const wchar_t *,
							  int,
							  void *),
				  void          *arg);

void   gdk_win32_api_failed      (const gchar *where,
				  gint         line,
				  const gchar *api);
void   gdk_other_api_failed      (const gchar *where,
				  gint         line,
				  const gchar *api);
void   gdk_win32_gdi_failed      (const gchar *where,
				  gint         line,
				  const gchar *api);
#ifdef __GNUC__
#define WIN32_API_FAILED(api) gdk_win32_api_failed (__FILE__ ":" __PRETTY_FUNCTION__, __LINE__, api)
#define WIN32_GDI_FAILED(api) gdk_win32_gdi_failed (__FILE__ ":" __PRETTY_FUNCTION__, __LINE__, api)
#define OTHER_API_FAILED(api) gdk_other_api_failed (__FILE__ ":" __PRETTY_FUNCTION__, __LINE__, api)
#else
#define WIN32_API_FAILED(api) gdk_win32_api_failed (__FILE__, __LINE__, api)
#define WIN32_GDI_FAILED(api) gdk_win32_gdi_failed (__FILE__, __LINE__, api)
#define OTHER_API_FAILED(api) gdk_other_api_failed (__FILE__, __LINE__, api)
#endif
 
#ifdef G_ENABLE_DEBUG
gchar *gdk_win32_color_to_string      (const        GdkColor *color);
gchar *gdk_win32_cap_style_to_string  (GdkCapStyle  cap_style);
gchar *gdk_win32_fill_style_to_string (GdkFill      fill);
gchar *gdk_win32_function_to_string   (GdkFunction  function);
gchar *gdk_win32_join_style_to_string (GdkJoinStyle join_style);
gchar *gdk_win32_line_style_to_string (GdkLineStyle line_style);
gchar *gdk_win32_drawable_type_to_string (GdkDrawableType type);
gchar *gdk_win32_drawable_description (GdkDrawable *d);
gchar *gdk_win32_message_name         (UINT msg);
void   gdk_win32_print_paletteentries (const PALETTEENTRY *pep,
				       const int           nentries);
void   gdk_win32_print_system_palette (void);
void   gdk_win32_print_hpalette (HPALETTE hpal);
#endif

extern LRESULT CALLBACK gdk_WindowProc (HWND, UINT, WPARAM, LPARAM);

extern GdkDrawableClass  _gdk_win32_drawable_class;
extern HWND		 gdk_root_window;
GDKVAR gchar		*gdk_progclass;
extern gboolean		 gdk_event_func_from_window_proc;
extern gint		 gdk_max_colors;

extern HDC		 gdk_DC;
extern HINSTANCE	 gdk_DLLInstance;
extern HINSTANCE	 gdk_ProgInstance;

GDKVAR GdkAtom		 gdk_selection_property;
extern GdkAtom		 text_uri_list_atom;
extern GdkAtom		 compound_text_atom;
extern GdkAtom		 gdk_clipboard_atom;
extern GdkAtom		 gdk_win32_dropfiles_atom;
extern GdkAtom		 gdk_ole2_dnd_atom;
extern WORD		 cf_rtf;
extern WORD		 cf_utf8_string;

typedef enum {
  GDK_WIN32_DND_NONE = 0,
  GDK_WIN32_DND_PENDING = 1,
  GDK_WIN32_DND_DROPPED = 2,
  GDK_WIN32_DND_FAILED = 3,
  GDK_WIN32_DND_DRAGGING = 4,
} GdkWin32DndState;
extern GdkWin32DndState  gdk_win32_dnd_target_state;
extern GdkWin32DndState  gdk_win32_dnd_source_state;

extern DWORD		 windows_version;

#define IS_WIN_NT(dwVersion) (dwVersion < 0x80000000)

#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* __GDK_PRIVATE_WIN32_H__ */
