1999-11-11 22:12:27 +00:00
|
|
|
/* GDK - The GIMP Drawing Kit
|
|
|
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
2004-11-21 21:01:28 +00:00
|
|
|
* Copyright (C) 1998-2004 Tor Lillqvist
|
2005-04-03 21:03:08 +00:00
|
|
|
* Copyright (C) 2001-2005 Hans Breuer
|
1999-11-11 22:12:27 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
2000-07-26 11:33:08 +00:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
1999-11-11 22:12:27 +00:00
|
|
|
* 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
|
2000-07-26 11:33:08 +00:00
|
|
|
* Lesser General Public License for more details.
|
1999-11-11 22:12:27 +00:00
|
|
|
*
|
2000-07-26 11:33:08 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
1999-11-11 22:12:27 +00:00
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2000-07-26 11:33:08 +00:00
|
|
|
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
1999-11-11 22:12:27 +00:00
|
|
|
* 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/.
|
|
|
|
*/
|
|
|
|
|
2008-06-22 14:28:52 +00:00
|
|
|
#include "config.h"
|
1999-11-11 22:12:27 +00:00
|
|
|
#include <math.h>
|
Massive changes. Too many to list here, but I'll try a summary:
2002-02-17 Tor Lillqvist <tml@iki.fi>
* gdk/win32/*.c: Massive changes. Too many to list here, but I'll
try a summary:
1) Unify GdkPixmap and GdkImage implementation: For each
GdkPixmap, allocate a GdkImage, and vice versa.
GdkPixmapImplWin32Data has a pointer to the GdkImage.
GdkImage::windowing_data is a pointer to the GdkPixmap.
This simplifies many pixmap and image related functions a lot, and
reduces duplicated code snippets. For instance, there is only one
place in gdk/win32 where CreateDIBSection() is called, in the
function _gdk_win32_new_pixmap(). Converting a bitmap (GdkPixmap)
to a Windows region is almost trivial, with the bitmap bits being
readily accessible in the associated GdkImage.
All blitting between GdkPixmaps, GdkWindows and GdkImages goes
through handled the _gdk_win32_blit() function, which calls
different functions to handle the cases of blitting from pixmaps,
inside windows (scrolling), or from windows, which all require
somewhat different handling.
2) Support 256-color mode. This has long been very broken, now it
works more or less OK. Keep the logical palette for each colormap
as small as possible while allocating and freeing colors. Select
and realize the logical palette associated with a GdkColormap into
a DC before drawing or blitting.
When the display is in 256-color mode, make it possible for the
user to override the size of the palette(s) used with either the
GDK_WIN32_MAX_COLORS environment variable, or a -max-colors
command line option. It is possible to reduce the palette size all
the way down to using just the 16 static colors (which causes the
system visual to be of type GDK_VISUAL_STATIC_COLOR. This could
possibly be useful if one desperately wants to avoid color
flashing. (Note that in order for this to work properly, an as of
yet not commited fix to gdkrgb.c is needed.)
Handle the palette messages. On WM_PALETTECHANGED, call
UpdateColors() for the given window hierarchy. Do this only if a
window in some other top-level window hierarchy caused the palette
change (realized a palette). Do this max five times in a row (an
arbitrarily chosen limit), though, otherwise redraw by generating
expose events. On WM_QUERYNEWPALETTE, cause a redraw of the whole
window hierarchy by generating GDK_EXPOSE events.
3) Code cleanup in general. For instance, remove the "emulated"
X11 structs ColormapStruct, Visual and XStandardColormap. Use the
new GDK_DEBUG_* flags for debugging output in the relevant source
files. Remove the unused colormap hash table in gdkcolor-win32.c
4) Plug some resource leaks.
2002-02-14 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkdnd-win32.c (gdk_dropfiles_filter): Use
g_filename_to_uri() to actually create legal URIs in the
text/uri-list data.
2002-02-17 00:25:05 +00:00
|
|
|
#include <stdio.h>
|
1999-11-17 00:45:37 +00:00
|
|
|
#include <glib.h>
|
1999-11-11 22:12:27 +00:00
|
|
|
|
2000-07-23 21:43:23 +00:00
|
|
|
#include <pango/pangowin32.h>
|
2005-03-18 01:23:23 +00:00
|
|
|
#include <cairo-win32.h>
|
1999-11-11 22:12:27 +00:00
|
|
|
|
2002-06-20 23:59:27 +00:00
|
|
|
#include "gdkscreen.h" /* gdk_screen_get_default() */
|
Large changes to the Win32 backend, partially made necessary by the
2000-05-02 Tor Lillqvist <tml@iki.fi>
Large changes to the Win32 backend, partially made necessary by
the changes to the backend-independent internal
structures. Attempts to implement similar backing store stuff as
on X11. The current (CVS) version of the Win32 backend is *not* as
stable as it was before the no-flicker branch was merged. A
zipfile with that version is available from
http://www.gimp.org/win32/. That should be use by "production"
code until this CVS version is usable. (But note, the Win32
backend has never been claimed to be "production quality".)
* README.win32: Add the above comment about versions.
* gdk/gdkwindow.c: Don't use backing store for now on Win32.
* gdk/gdk.def: Update.
* gdk/gdkfont.h: Declare temporary Win32-only functions. Will
presumably be replaced by some more better mechanism as 1.4 gets
closer to release shape.
* gdk/makefile.{cygwin,msc}: Update.
* gdk/win32/*.c: Correct inclusions of the backend-specific and
internal headers. Change code according to changes in these. Use
gdk_drawable_*, not gdk_window_* where necessary.
* gdk/win32/gdkdnd-win32.c: Use MISC selector for GDK_NOTE, not
our old DND.
* gdk/win32/gdkdrawable-win32.c (gdk_win32_draw_text): Don't try
to interpret single characters as UTF-8. Thanks to Hans Breuer.
Use correct function name in warning messages.
* gdk/win32/gdkevents-win32.c: Use correct parameter lists for the
GSourceFuncs gdk_event_prepare and gdk_event_check.
(gdk_event_get_graphics_expose): Do implement, use
PeekMessage. Thanks to Hans Breuer.
(event_mask_string): Debugging function to print an GdkEventMask.
(gdk_pointer_grab): Use it.
* gdk/win32/gdkfont-win32.c: The Unicode subrange that the
(old) book I used claimed was Hangul actually is CJK Unified
Ideographs Extension A. Also, Hangul Syllables were missing.
Improve logging.
* gdk/win32/gdkgc-win32.c: Largish changes.
* gdk/win32/gdkim-win32.c (gdk_set_locale): Use
g_win32_getlocale() from GLib, and not setlocale() to get current
locale name.
* gdk/win32/gdkprivate-win32.h
* gdk/win32/gdkwin32.h: Move stuff from gdkprivate-win32.h to
gdkwin32.h, similarily as in the X11 backend.
* gdk/win32/gdkwindow-win32.c (gdk_propagate_shapes): Bugfix,
assignment was used instead of equals in if test. Thanks to Hans
Breuer.
* gdk/win32/makefile.{cygwin,msc}
* gtk/makefile.{cygwin,msc}: Updates. Better kludge to get the
path to the Win32 headers that works also with the mingw compiler.
* gtk/gtkstyle.c: Include <string.h>.
2000-05-01 22:06:49 +00:00
|
|
|
#include "gdkprivate-win32.h"
|
1999-11-17 00:45:37 +00:00
|
|
|
|
Reflect recent renamings and removals of functions.
2002-11-15 Tor Lillqvist <tml@iki.fi>
* gdk/gdk.def: Reflect recent renamings and removals of functions.
Merge from stable:
Start implementing all fill styles (i.e. tiled, stippled, and
opaque stippled in addition to the plain solid style) in the Win32
backend in an elegant and generic way. For now only did the
draw_rectangle() and draw_glyphs() methods. The rest will
follow. Previously some of the drawing methods implemented opaque
stippling, but not tiles or non-opaque stippling.
Seems to work fine, now the check marks show up in check buttons,
the stippled background and stippled text in gtk-demo's Text
Widget look as they should, and GtkText's line wrap arrow shows
correctly instead of an ugly rectangle. [This refers to the stable
branch, haven't actually checked HEAD.]
The implementation does do a lot of pixmap handling and blitting
back and forth, especially on Win9x. But performance is hopefully
not an issue. I don't think many applications do a lot of tiled or
stippled drawing.
* gdk/win32/gdkprivate-win32.h: Define a new macro, GDI_CALL, that
calls a GDI function and prints a warning if it failed. Also
API_CALL for non-GDI calls. Cleans all the the if (!BlaBla())
WIN32_GDI_FAILED ("BlaBla") snippets, these can now be written
GDI_CALL (BlaBla, ()). Declare new functions.
* gdk/win32/gdkdrawable-win32.c: Use GDI_CALL macro in lots of places.
(generic_draw): New function that handles all the blitting
necessary to implement tiles and stipples. A function that
actually draws stuff is passed as a parameter to
generic_draw(). If the fill style is solid, it is called
directly, to draw on the destination drawable. Otherwise it is
called to draw on a temporary mask bitmap, which then is used in
blitting operations. The tiles and/or stipples are rendered into
another temporary pixmap. If MaskBlt() is available (on NT/2k/XP),
it is used, otherwise a sequence of BitBlt() is used to do the
final composition onto the destination drawable.
(draw_tiles_lowlevel, draw_tiles): Some renaming and code
reorg. Use BitBlt() to blit each tile, not gdk_draw_drawable().
(rop2_to_rop3): New function, does binary->ternary rop mapping.
(blit_from_pixmap, blit_inside_window, blit_from_window): Use
rop2_to_rop3(). Previously used SRCCOPY always...
(draw_rectangle, gdk_win32_draw_rectangle, draw_glyphs,
gdk_win32_draw_glyphs): Split functionality into two functions,
with generic_draw() doing its magic inbetween.
* gdk/win32/gdkevents-win32.c: Remove the TrackMouseEvent code, it
was ifdeffed out and wouldn't have done anything even if
enabled. Remove the GDK_EVENT_FUNC_FROM_WINDOW_PROC code, didn't
have any effect any more anyway after all the changes GTK+ has
gone through in the last years. Remove some #if 0 code.
* gdk/win32/gdkgc-win32.c (gdk_gc_copy): Set the copy's hdc field
to NULL in case a GC is copied while it has a Windows DC active.
* gdk/win32/gdkprivate-win32.h
* gdk/win32/gdkglobals-win32.c: Remove gdk_event_func_from_window_proc.
* gdk/win32/gdkmain-win32.c: Remove -event-func-from-window-proc
option. If there is a PRETEND_WIN9X envvar, set windows_version as
if on Win9x.
* gdk/win32/gdkpixmap-win32.c (_gdk_win32_pixmap_new,
gdk_pixmap_new): Combine these two, _gdk_win32_pixmap_new() wasn't
used or exported. Make a bit more like the X11 version. Hopefully
I didn't break the fragile palettized display ("pseudocolor")
code.
* gdk/win32/gdkgc-win32.c: Various debugging output improvements.
(predraw_set_foreground): Check whether
tile/stipple origins are valid when calling SetBrushOrgEx().
(gdk_win32_hdc_get): Ifdef out code that tries to handle the
stipple by converting it into a region, and combining the clip
region with that. A stipple shouldn't work like that, it should
replicate in x and y directions. Stipples are now handled by
generic_draw() in gdkdrawable-win32.c.
* gdk/win32/gdkmain-win32.c: (gdk_win32_gcvalues_mask_to_string,
gdk_win32_rop2_to_string): New debugging functions.
(gdk_win32_print_dc): Print also DC's rop2 and text color.
2002-11-16 01:12:10 +00:00
|
|
|
#define ROP3_D 0x00AA0029
|
|
|
|
#define ROP3_DSna 0x00220326
|
Merge from stable:
2002-12-09 Tor Lillqvist <tml@iki.fi>
Merge from stable:
* gdk/win32/gdkdrawable-win32.c (generic_draw): Don't leak
stipple_gc. More checks for errors. Use correct ternary ROP when
blitting the foreground into the tile pixmap onto those pixels
where the stipple is set. (I didn't notice that I had used the
wrong one, as it didn't matter on Win2k, where DIB sections
apparently are zeroed upon creation. But on Win98 they have random
initial contents. Thanks to Hans Breuer for reporting this.)
(gdk_win32_draw_rectangle, gdk_win32_draw_arc,
gdk_win32_draw_polygon): Don't pass the LINE_ATTRIBUTES bits to
generic_draw() if drawing a filled figure.
* gdk/win32/gdkmain-win32.c (_gdk_win32_print_dc): Minor cosmetics.
(_gdk_win32_gcvalues_mask_to_string): Initialize buffer as empty.
(_gdk_win32_window_state_to_string): New debugging output helper
function.
* gdk/win32/gdkevents-win32.c: Minor debugging output changes.
(gdk_event_translate): Ignore the WM_SHOWWINDOW/SW_OTHERUNZOOM or
SW_OTHERZOOM messages. Do not generate a GDK_UNMAP event for
WM_SIZE/SIZE_MINIMIZED messages, they do not really corrspond to
unmapping on X11. Set window state correctly for all three of
SIZE_{MINIMIZED,MAXIMIZED,RESTORED}. A maximized and then iconified
("minimized" in Windows terminology) window still has the
"maximized" property, i.e. when deiconified, it will reappear as
maximized. (#10557)
* gdk/win32/gdkprivate-win32.h: Declare new function.
(WIN32_API_FAILED, WIN32_GDI_FAILED, OTHER_API_FAILED): Don't use
__PRETTY_FUNCTION__ if __GNUC__ >= 3, to avoid warning message.
* gdk/win32/gdkwindow-win32.c (show_window_internal): Handle more
situations. Add parameter to tell whether deiconifying. Code
reorg: Return early when appropriate instead of using nested if
statements. If just deiconifying without raising, restore active
window. (#10557)
(gdk_window_hide, gdk_window_withdraw, gdk_window_iconify,
gdk_window_deiconify, gdk_window_maximize, gdk_window_unmaximize,
gdk_window_focus): Use _gdk_win32_window_state_to_string() in
debugging output.
(gdk_window_iconify): Restore active window after calling
ShowWindow(). Otherwise the "next" window gets activated.
(gdk_window_stick, gdk_window_unstick): Don't output any warnings.
(gdk_window_set_transient_for): Rewrite. Just call SetWindowLong()
with GWL_HWNDPARENT, which despite its name sets the *owner*
window, which should be exactly what we want. The PSDK
documentation is said to be misleading. testgtk's modal window
test now works much better. (#50586)
2002-12-09 00:43:42 +00:00
|
|
|
#define ROP3_DSPDxax 0x00E20746
|
Reflect recent renamings and removals of functions.
2002-11-15 Tor Lillqvist <tml@iki.fi>
* gdk/gdk.def: Reflect recent renamings and removals of functions.
Merge from stable:
Start implementing all fill styles (i.e. tiled, stippled, and
opaque stippled in addition to the plain solid style) in the Win32
backend in an elegant and generic way. For now only did the
draw_rectangle() and draw_glyphs() methods. The rest will
follow. Previously some of the drawing methods implemented opaque
stippling, but not tiles or non-opaque stippling.
Seems to work fine, now the check marks show up in check buttons,
the stippled background and stippled text in gtk-demo's Text
Widget look as they should, and GtkText's line wrap arrow shows
correctly instead of an ugly rectangle. [This refers to the stable
branch, haven't actually checked HEAD.]
The implementation does do a lot of pixmap handling and blitting
back and forth, especially on Win9x. But performance is hopefully
not an issue. I don't think many applications do a lot of tiled or
stippled drawing.
* gdk/win32/gdkprivate-win32.h: Define a new macro, GDI_CALL, that
calls a GDI function and prints a warning if it failed. Also
API_CALL for non-GDI calls. Cleans all the the if (!BlaBla())
WIN32_GDI_FAILED ("BlaBla") snippets, these can now be written
GDI_CALL (BlaBla, ()). Declare new functions.
* gdk/win32/gdkdrawable-win32.c: Use GDI_CALL macro in lots of places.
(generic_draw): New function that handles all the blitting
necessary to implement tiles and stipples. A function that
actually draws stuff is passed as a parameter to
generic_draw(). If the fill style is solid, it is called
directly, to draw on the destination drawable. Otherwise it is
called to draw on a temporary mask bitmap, which then is used in
blitting operations. The tiles and/or stipples are rendered into
another temporary pixmap. If MaskBlt() is available (on NT/2k/XP),
it is used, otherwise a sequence of BitBlt() is used to do the
final composition onto the destination drawable.
(draw_tiles_lowlevel, draw_tiles): Some renaming and code
reorg. Use BitBlt() to blit each tile, not gdk_draw_drawable().
(rop2_to_rop3): New function, does binary->ternary rop mapping.
(blit_from_pixmap, blit_inside_window, blit_from_window): Use
rop2_to_rop3(). Previously used SRCCOPY always...
(draw_rectangle, gdk_win32_draw_rectangle, draw_glyphs,
gdk_win32_draw_glyphs): Split functionality into two functions,
with generic_draw() doing its magic inbetween.
* gdk/win32/gdkevents-win32.c: Remove the TrackMouseEvent code, it
was ifdeffed out and wouldn't have done anything even if
enabled. Remove the GDK_EVENT_FUNC_FROM_WINDOW_PROC code, didn't
have any effect any more anyway after all the changes GTK+ has
gone through in the last years. Remove some #if 0 code.
* gdk/win32/gdkgc-win32.c (gdk_gc_copy): Set the copy's hdc field
to NULL in case a GC is copied while it has a Windows DC active.
* gdk/win32/gdkprivate-win32.h
* gdk/win32/gdkglobals-win32.c: Remove gdk_event_func_from_window_proc.
* gdk/win32/gdkmain-win32.c: Remove -event-func-from-window-proc
option. If there is a PRETEND_WIN9X envvar, set windows_version as
if on Win9x.
* gdk/win32/gdkpixmap-win32.c (_gdk_win32_pixmap_new,
gdk_pixmap_new): Combine these two, _gdk_win32_pixmap_new() wasn't
used or exported. Make a bit more like the X11 version. Hopefully
I didn't break the fragile palettized display ("pseudocolor")
code.
* gdk/win32/gdkgc-win32.c: Various debugging output improvements.
(predraw_set_foreground): Check whether
tile/stipple origins are valid when calling SetBrushOrgEx().
(gdk_win32_hdc_get): Ifdef out code that tries to handle the
stipple by converting it into a region, and combining the clip
region with that. A stipple shouldn't work like that, it should
replicate in x and y directions. Stipples are now handled by
generic_draw() in gdkdrawable-win32.c.
* gdk/win32/gdkmain-win32.c: (gdk_win32_gcvalues_mask_to_string,
gdk_win32_rop2_to_string): New debugging functions.
(gdk_win32_print_dc): Print also DC's rop2 and text color.
2002-11-16 01:12:10 +00:00
|
|
|
|
Merge from stable:
2002-11-24 Tor Lillqvist <tml@iki.fi>
Merge from stable:
Implement tiles and stipples for all drawing methids (except the
deprecated draw_text() and draw_text_wc()).
* gdk/win32/gdkdrawable-win32.c: Remove the already ifdeffed-out
code that didn't use generic_draw().
(generic_draw): When drawing into the mask (for tiled/stippled
fill styles), copy the line attributes from the actual GC. Also
ask for text drawing setup if needed. Use differently set up HDCs
in the normal and tiled/stippled cases.
(draw_lines, gdk_win32_draw_lines, draw_polygon,
gdk_win32_draw_polygon, draw_segments, gdk_win32_draw_segments,
draw_arc, gdk_win32_draw_arc): Use generic_draw(), thus
implementing tiled and stippled fill styles for lines, polygons,
segments, and args.
(gdk_win32_draw_points): Use Rectangle() instead of
SetPixel(). Rectangle() uses the function (raster op) set for the
HDC, SetPixel() doesn't.
(widen_bounds): New function, refactoring.
* gdk/win32/gdkgc-win32.c: Remove ifdeffed-out code.
(predraw_set_foreground, gdk_win32_hdc_get): Some code moved
around. Call SetROP2() only if necessary. Call SetTextColor() only
if GDK_GC_FOREGROUND flag present. Don't handle
GDK_OPAQUE_STIPPLED here, has been superseded by the code in
generic_draw(). Always create a solid brush.
Remove background color handling from here. The background color
of a GdkGC is supposed to affect only GDK_OPAQUE_STIPPLED fill
style, which it is already handled in generic_draw(), and
GDK_LINE_DOUBLE_DASH lines, which aren't implemented properly
anyway. Calling SetBkColor() is unnecessary as we always use
TRANSPARENT text output.
(gdk_win32_hdc_get, gdk_win32_hdc_release): Add doc comments, as
these are public functions.
* gdk/win32/gdkevents-win32.c (synthesize_expose_events): Don't
synthesize expose events for GDK_INPUT_ONLY windows.
(gdk_event_translate): On WM_SIZE, call
gdk_synthesize_window_state() if window was iconified, restored or
maximized. (#98983, Arnaud Charlet)
* gtk+/gdk/win32/gdkwindow-win32.c
(gdk_window_get_frame_extents): Fix typo in setting y. (#98983,
Arnaud Charlet)
2002-11-24 23:54:01 +00:00
|
|
|
#define LINE_ATTRIBUTES (GDK_GC_LINE_WIDTH|GDK_GC_LINE_STYLE| \
|
|
|
|
GDK_GC_CAP_STYLE|GDK_GC_JOIN_STYLE)
|
|
|
|
|
Improve and simplify line segment rendering on Win32, especially the
2005-06-23 Tor Lillqvist <tml@novell.com>
Improve and simplify line segment rendering on Win32, especially
the implementation of GDK_CAP_NOT_LAST, and dashed lines. Fixes
bug #306396.
* gdk/win32/gdkprivate-win32.h (GdkGCWin32): Save the GdkGC's
line_style, cap_style and join_style as such in the
GdkGCWin32. Don't need to keep the pen_double_dash flag, we can
check the line_style.
* gdk/win32/gdkgc-win32.c (fixup_pen): New internal function. Sets
up the GDI pen type, style, end cap and join attributes to use
based on the pen width, GDK line style, end cap style, and join
style.
For a narrow (zero-width) GDK pen with the GDK_CAP_NOT_LAST end
cap style, which typically are used for XOR drawing where it is
essential that the last pixel is not drawn, use a GDI cosmetic
pen. Only for a cosmetic pen does GDI not draw the last pixel. I
deduced this by experimetation, the documentation is rather vague.
For other GDK pens use a geometric GDI pen. If the width is 0 or 1
and the GDK end cap style is GDK_CAP_BUTT, and the line style is
GDK_LINE_SOLID, use PS_ENDCAP_ROUND. This ensures that also
single-pixel length lines are drawn. (For sngle-pixel width lines
roundness as such is of course irrelevant.) For dashed lines, use
PS_ENDCAP_FLAT.
For wide lines use PS_ENDCAP_FLAT, _ROUND or _SQUARE,
respectively, for GDK_CAP_BUTT, GDK_CAP_ROUND and GDK_CAP_PROJECTING.
For one pixel on-off dashed lines, use PS_ALTERNATE, it seems to
work better than PS_USERSTYLE. For other dashed lines, use
PS_USERSTYLE and the dashes as set by the user (or the default
four-pixel on-off style).
(gdk_win32_gc_values_to_win32values, gdk_win32_gc_set_dashes):
Call fixup_pen() to do the pen settings after modifying some of
the GDK GC attributes that affect pens.
* gdk/win32/gdkdrawable-win32.c (render_line_horizontal,
render_line_vertical, draw_segments): Check GdkGCWin32::line_style
instead of the the removed pen_double_dash member. Don't use
PATCOPY unconditionally in the PatBlt() call, use a raster ope
code that depends on the GC function in use.
(draw_rectangle, draw_segments, draw_lines): Be more careful in
deciding when to do the manual dash rendering.
(draw_segments): Don't do any manual "last point" drawing at
all. The above changes takes care of narrow line segments being
drawn correctly in most cases, at least on NT-based Windows.
2005-06-24 13:00:05 +00:00
|
|
|
#define MUST_RENDER_DASHES_MANUALLY(gcwin32) \
|
|
|
|
(gcwin32->line_style == GDK_LINE_DOUBLE_DASH || \
|
2006-08-29 23:01:53 +00:00
|
|
|
(gcwin32->line_style == GDK_LINE_ON_OFF_DASH && gcwin32->pen_dash_offset))
|
Improve and simplify line segment rendering on Win32, especially the
2005-06-23 Tor Lillqvist <tml@novell.com>
Improve and simplify line segment rendering on Win32, especially
the implementation of GDK_CAP_NOT_LAST, and dashed lines. Fixes
bug #306396.
* gdk/win32/gdkprivate-win32.h (GdkGCWin32): Save the GdkGC's
line_style, cap_style and join_style as such in the
GdkGCWin32. Don't need to keep the pen_double_dash flag, we can
check the line_style.
* gdk/win32/gdkgc-win32.c (fixup_pen): New internal function. Sets
up the GDI pen type, style, end cap and join attributes to use
based on the pen width, GDK line style, end cap style, and join
style.
For a narrow (zero-width) GDK pen with the GDK_CAP_NOT_LAST end
cap style, which typically are used for XOR drawing where it is
essential that the last pixel is not drawn, use a GDI cosmetic
pen. Only for a cosmetic pen does GDI not draw the last pixel. I
deduced this by experimetation, the documentation is rather vague.
For other GDK pens use a geometric GDI pen. If the width is 0 or 1
and the GDK end cap style is GDK_CAP_BUTT, and the line style is
GDK_LINE_SOLID, use PS_ENDCAP_ROUND. This ensures that also
single-pixel length lines are drawn. (For sngle-pixel width lines
roundness as such is of course irrelevant.) For dashed lines, use
PS_ENDCAP_FLAT.
For wide lines use PS_ENDCAP_FLAT, _ROUND or _SQUARE,
respectively, for GDK_CAP_BUTT, GDK_CAP_ROUND and GDK_CAP_PROJECTING.
For one pixel on-off dashed lines, use PS_ALTERNATE, it seems to
work better than PS_USERSTYLE. For other dashed lines, use
PS_USERSTYLE and the dashes as set by the user (or the default
four-pixel on-off style).
(gdk_win32_gc_values_to_win32values, gdk_win32_gc_set_dashes):
Call fixup_pen() to do the pen settings after modifying some of
the GDK GC attributes that affect pens.
* gdk/win32/gdkdrawable-win32.c (render_line_horizontal,
render_line_vertical, draw_segments): Check GdkGCWin32::line_style
instead of the the removed pen_double_dash member. Don't use
PATCOPY unconditionally in the PatBlt() call, use a raster ope
code that depends on the GC function in use.
(draw_rectangle, draw_segments, draw_lines): Be more careful in
deciding when to do the manual dash rendering.
(draw_segments): Don't do any manual "last point" drawing at
all. The above changes takes care of narrow line segments being
drawn correctly in most cases, at least on NT-based Windows.
2005-06-24 13:00:05 +00:00
|
|
|
|
2005-03-18 01:23:23 +00:00
|
|
|
static cairo_surface_t *gdk_win32_ref_cairo_surface (GdkDrawable *drawable);
|
2010-08-25 20:16:28 +00:00
|
|
|
static cairo_surface_t *gdk_win32_create_cairo_surface (GdkDrawable *drawable,
|
|
|
|
int width,
|
|
|
|
int height);
|
2005-03-18 01:23:23 +00:00
|
|
|
|
2001-11-09 21:52:52 +00:00
|
|
|
static void gdk_drawable_impl_win32_finalize (GObject *object);
|
|
|
|
|
2005-03-18 01:23:23 +00:00
|
|
|
static const cairo_user_data_key_t gdk_win32_cairo_key;
|
2000-07-23 21:43:23 +00:00
|
|
|
|
2009-07-26 17:10:13 +00:00
|
|
|
G_DEFINE_TYPE (GdkDrawableImplWin32, _gdk_drawable_impl_win32, GDK_TYPE_DRAWABLE)
|
|
|
|
|
1999-11-17 00:45:37 +00:00
|
|
|
|
2000-07-23 21:43:23 +00:00
|
|
|
static void
|
2009-07-26 17:10:13 +00:00
|
|
|
_gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass)
|
2000-07-23 21:43:23 +00:00
|
|
|
{
|
|
|
|
GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
|
2001-11-09 21:52:52 +00:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
2000-07-23 21:43:23 +00:00
|
|
|
|
2001-11-09 21:52:52 +00:00
|
|
|
object_class->finalize = gdk_drawable_impl_win32_finalize;
|
|
|
|
|
2005-03-18 01:23:23 +00:00
|
|
|
drawable_class->ref_cairo_surface = gdk_win32_ref_cairo_surface;
|
2010-08-25 20:16:28 +00:00
|
|
|
drawable_class->create_cairo_surface = gdk_win32_create_cairo_surface;
|
2000-07-23 21:43:23 +00:00
|
|
|
}
|
1999-11-17 00:45:37 +00:00
|
|
|
|
2009-07-26 17:10:13 +00:00
|
|
|
static void
|
|
|
|
_gdk_drawable_impl_win32_init (GdkDrawableImplWin32 *impl)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2001-11-09 21:52:52 +00:00
|
|
|
static void
|
|
|
|
gdk_drawable_impl_win32_finalize (GObject *object)
|
|
|
|
{
|
2009-07-26 17:10:13 +00:00
|
|
|
G_OBJECT_CLASS (_gdk_drawable_impl_win32_parent_class)->finalize (object);
|
2001-11-09 21:52:52 +00:00
|
|
|
}
|
|
|
|
|
1999-11-17 00:45:37 +00:00
|
|
|
/*****************************************************
|
|
|
|
* Win32 specific implementations of generic functions *
|
|
|
|
*****************************************************/
|
1999-11-11 22:12:27 +00:00
|
|
|
|
1999-11-17 00:45:37 +00:00
|
|
|
/* Drawing
|
|
|
|
*/
|
1999-11-11 22:12:27 +00:00
|
|
|
|
2005-03-18 01:23:23 +00:00
|
|
|
/**
|
|
|
|
* _gdk_win32_drawable_acquire_dc
|
|
|
|
* @drawable: a Win32 #GdkDrawable implementation
|
|
|
|
*
|
|
|
|
* Gets a DC with the given drawable selected into
|
|
|
|
* it.
|
|
|
|
*
|
|
|
|
* Return value: The DC, on success. Otherwise
|
|
|
|
* %NULL. If this function succeeded
|
|
|
|
* _gdk_win32_drawable_release_dc() must be called
|
|
|
|
* release the DC when you are done using it.
|
|
|
|
**/
|
|
|
|
HDC
|
|
|
|
_gdk_win32_drawable_acquire_dc (GdkDrawable *drawable)
|
|
|
|
{
|
|
|
|
GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
|
|
|
|
|
|
|
|
if (GDK_IS_WINDOW_IMPL_WIN32 (drawable) &&
|
|
|
|
GDK_WINDOW_DESTROYED (impl->wrapper))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!impl->hdc)
|
|
|
|
{
|
|
|
|
if (GDK_IS_PIXMAP_IMPL_WIN32 (impl))
|
|
|
|
{
|
|
|
|
impl->hdc = CreateCompatibleDC (NULL);
|
|
|
|
if (!impl->hdc)
|
|
|
|
WIN32_GDI_FAILED ("CreateCompatibleDC");
|
|
|
|
|
|
|
|
if (impl->hdc)
|
|
|
|
{
|
|
|
|
impl->saved_dc_bitmap = SelectObject (impl->hdc,
|
|
|
|
impl->handle);
|
|
|
|
if (!impl->saved_dc_bitmap)
|
|
|
|
{
|
|
|
|
WIN32_GDI_FAILED ("CreateCompatibleDC");
|
|
|
|
DeleteDC (impl->hdc);
|
|
|
|
impl->hdc = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
impl->hdc = GetDC (impl->handle);
|
|
|
|
if (!impl->hdc)
|
|
|
|
WIN32_GDI_FAILED ("GetDC");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (impl->hdc)
|
|
|
|
{
|
|
|
|
impl->hdc_count++;
|
|
|
|
return impl->hdc;
|
|
|
|
}
|
|
|
|
else
|
2009-03-01 13:55:50 +00:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-03-18 01:23:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* _gdk_win32_drawable_release_dc
|
|
|
|
* @drawable: a Win32 #GdkDrawable implementation
|
|
|
|
*
|
|
|
|
* Releases the reference count for the DC
|
|
|
|
* from _gdk_win32_drawable_acquire_dc()
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
_gdk_win32_drawable_release_dc (GdkDrawable *drawable)
|
|
|
|
{
|
|
|
|
GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
|
|
|
|
|
|
|
|
g_return_if_fail (impl->hdc_count > 0);
|
|
|
|
|
|
|
|
impl->hdc_count--;
|
|
|
|
if (impl->hdc_count == 0)
|
|
|
|
{
|
|
|
|
if (impl->saved_dc_bitmap)
|
|
|
|
{
|
|
|
|
GDI_CALL (SelectObject, (impl->hdc, impl->saved_dc_bitmap));
|
|
|
|
impl->saved_dc_bitmap = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (impl->hdc)
|
|
|
|
{
|
2006-06-09 09:17:47 +00:00
|
|
|
if (GDK_IS_PIXMAP_IMPL_WIN32 (impl))
|
|
|
|
GDI_CALL (DeleteDC, (impl->hdc));
|
|
|
|
else
|
|
|
|
GDI_CALL (ReleaseDC, (impl->handle, impl->hdc));
|
2005-03-18 01:23:23 +00:00
|
|
|
impl->hdc = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-25 20:16:28 +00:00
|
|
|
static cairo_surface_t *
|
|
|
|
gdk_win32_create_cairo_surface (GdkDrawable *drawable,
|
|
|
|
gint width,
|
|
|
|
gint height)
|
2009-02-14 18:23:54 +00:00
|
|
|
{
|
2009-07-18 11:08:13 +00:00
|
|
|
/* width and height are determined from the DC */
|
|
|
|
return gdk_win32_ref_cairo_surface (drawable);
|
2009-02-14 18:23:54 +00:00
|
|
|
}
|
|
|
|
|
2005-03-18 01:23:23 +00:00
|
|
|
static void
|
|
|
|
gdk_win32_cairo_surface_destroy (void *data)
|
|
|
|
{
|
|
|
|
GdkDrawableImplWin32 *impl = data;
|
|
|
|
|
|
|
|
_gdk_win32_drawable_release_dc (GDK_DRAWABLE (impl));
|
|
|
|
impl->cairo_surface = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cairo_surface_t *
|
|
|
|
gdk_win32_ref_cairo_surface (GdkDrawable *drawable)
|
|
|
|
{
|
|
|
|
GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
|
|
|
|
|
|
|
|
if (GDK_IS_WINDOW_IMPL_WIN32 (drawable) &&
|
|
|
|
GDK_WINDOW_DESTROYED (impl->wrapper))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!impl->cairo_surface)
|
|
|
|
{
|
2009-07-18 11:08:13 +00:00
|
|
|
HDC hdc = _gdk_win32_drawable_acquire_dc (drawable);
|
|
|
|
if (!hdc)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
impl->cairo_surface = cairo_win32_surface_create (hdc);
|
2005-03-18 01:23:23 +00:00
|
|
|
|
|
|
|
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key,
|
2009-02-16 18:26:35 +00:00
|
|
|
drawable, gdk_win32_cairo_surface_destroy);
|
2005-03-18 01:23:23 +00:00
|
|
|
}
|
|
|
|
else
|
2009-07-18 11:08:13 +00:00
|
|
|
cairo_surface_reference (impl->cairo_surface);
|
2005-03-18 01:23:23 +00:00
|
|
|
|
|
|
|
return impl->cairo_surface;
|
|
|
|
}
|
|
|
|
|
2010-08-08 16:17:29 +00:00
|
|
|
gboolean
|
2009-02-14 18:23:54 +00:00
|
|
|
_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface,
|
2009-02-16 18:26:35 +00:00
|
|
|
gint width,
|
|
|
|
gint height)
|
2009-02-14 18:23:54 +00:00
|
|
|
{
|
2009-02-16 18:26:35 +00:00
|
|
|
// Do nothing. The surface size is determined by the DC
|
2010-08-08 16:17:29 +00:00
|
|
|
return FALSE;
|
2009-02-14 18:23:54 +00:00
|
|
|
}
|
|
|
|
|
Massive changes. Too many to list here, but I'll try a summary:
2002-02-17 Tor Lillqvist <tml@iki.fi>
* gdk/win32/*.c: Massive changes. Too many to list here, but I'll
try a summary:
1) Unify GdkPixmap and GdkImage implementation: For each
GdkPixmap, allocate a GdkImage, and vice versa.
GdkPixmapImplWin32Data has a pointer to the GdkImage.
GdkImage::windowing_data is a pointer to the GdkPixmap.
This simplifies many pixmap and image related functions a lot, and
reduces duplicated code snippets. For instance, there is only one
place in gdk/win32 where CreateDIBSection() is called, in the
function _gdk_win32_new_pixmap(). Converting a bitmap (GdkPixmap)
to a Windows region is almost trivial, with the bitmap bits being
readily accessible in the associated GdkImage.
All blitting between GdkPixmaps, GdkWindows and GdkImages goes
through handled the _gdk_win32_blit() function, which calls
different functions to handle the cases of blitting from pixmaps,
inside windows (scrolling), or from windows, which all require
somewhat different handling.
2) Support 256-color mode. This has long been very broken, now it
works more or less OK. Keep the logical palette for each colormap
as small as possible while allocating and freeing colors. Select
and realize the logical palette associated with a GdkColormap into
a DC before drawing or blitting.
When the display is in 256-color mode, make it possible for the
user to override the size of the palette(s) used with either the
GDK_WIN32_MAX_COLORS environment variable, or a -max-colors
command line option. It is possible to reduce the palette size all
the way down to using just the 16 static colors (which causes the
system visual to be of type GDK_VISUAL_STATIC_COLOR. This could
possibly be useful if one desperately wants to avoid color
flashing. (Note that in order for this to work properly, an as of
yet not commited fix to gdkrgb.c is needed.)
Handle the palette messages. On WM_PALETTECHANGED, call
UpdateColors() for the given window hierarchy. Do this only if a
window in some other top-level window hierarchy caused the palette
change (realized a palette). Do this max five times in a row (an
arbitrarily chosen limit), though, otherwise redraw by generating
expose events. On WM_QUERYNEWPALETTE, cause a redraw of the whole
window hierarchy by generating GDK_EXPOSE events.
3) Code cleanup in general. For instance, remove the "emulated"
X11 structs ColormapStruct, Visual and XStandardColormap. Use the
new GDK_DEBUG_* flags for debugging output in the relevant source
files. Remove the unused colormap hash table in gdkcolor-win32.c
4) Plug some resource leaks.
2002-02-14 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkdnd-win32.c (gdk_dropfiles_filter): Use
g_filename_to_uri() to actually create legal URIs in the
text/uri-list data.
2002-02-17 00:25:05 +00:00
|
|
|
HGDIOBJ
|
2001-09-21 19:58:35 +00:00
|
|
|
gdk_win32_drawable_get_handle (GdkDrawable *drawable)
|
|
|
|
{
|
Massive changes. Too many to list here, but I'll try a summary:
2002-02-17 Tor Lillqvist <tml@iki.fi>
* gdk/win32/*.c: Massive changes. Too many to list here, but I'll
try a summary:
1) Unify GdkPixmap and GdkImage implementation: For each
GdkPixmap, allocate a GdkImage, and vice versa.
GdkPixmapImplWin32Data has a pointer to the GdkImage.
GdkImage::windowing_data is a pointer to the GdkPixmap.
This simplifies many pixmap and image related functions a lot, and
reduces duplicated code snippets. For instance, there is only one
place in gdk/win32 where CreateDIBSection() is called, in the
function _gdk_win32_new_pixmap(). Converting a bitmap (GdkPixmap)
to a Windows region is almost trivial, with the bitmap bits being
readily accessible in the associated GdkImage.
All blitting between GdkPixmaps, GdkWindows and GdkImages goes
through handled the _gdk_win32_blit() function, which calls
different functions to handle the cases of blitting from pixmaps,
inside windows (scrolling), or from windows, which all require
somewhat different handling.
2) Support 256-color mode. This has long been very broken, now it
works more or less OK. Keep the logical palette for each colormap
as small as possible while allocating and freeing colors. Select
and realize the logical palette associated with a GdkColormap into
a DC before drawing or blitting.
When the display is in 256-color mode, make it possible for the
user to override the size of the palette(s) used with either the
GDK_WIN32_MAX_COLORS environment variable, or a -max-colors
command line option. It is possible to reduce the palette size all
the way down to using just the 16 static colors (which causes the
system visual to be of type GDK_VISUAL_STATIC_COLOR. This could
possibly be useful if one desperately wants to avoid color
flashing. (Note that in order for this to work properly, an as of
yet not commited fix to gdkrgb.c is needed.)
Handle the palette messages. On WM_PALETTECHANGED, call
UpdateColors() for the given window hierarchy. Do this only if a
window in some other top-level window hierarchy caused the palette
change (realized a palette). Do this max five times in a row (an
arbitrarily chosen limit), though, otherwise redraw by generating
expose events. On WM_QUERYNEWPALETTE, cause a redraw of the whole
window hierarchy by generating GDK_EXPOSE events.
3) Code cleanup in general. For instance, remove the "emulated"
X11 structs ColormapStruct, Visual and XStandardColormap. Use the
new GDK_DEBUG_* flags for debugging output in the relevant source
files. Remove the unused colormap hash table in gdkcolor-win32.c
4) Plug some resource leaks.
2002-02-14 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkdnd-win32.c (gdk_dropfiles_filter): Use
g_filename_to_uri() to actually create legal URIs in the
text/uri-list data.
2002-02-17 00:25:05 +00:00
|
|
|
return GDK_DRAWABLE_HANDLE (drawable);
|
2001-09-21 19:58:35 +00:00
|
|
|
}
|
2004-07-27 21:58:09 +00:00
|
|
|
|
2005-03-18 01:23:23 +00:00
|
|
|
/**
|
|
|
|
* _gdk_win32_drawable_finish
|
|
|
|
* @drawable: a Win32 #GdkDrawable implementation
|
|
|
|
*
|
|
|
|
* Releases any resources allocated internally for the drawable.
|
2010-08-27 15:05:48 +00:00
|
|
|
* This is called when the drawable becomes unusable, i.e.
|
|
|
|
* gdk_window_destroy() is called.
|
2005-03-18 01:23:23 +00:00
|
|
|
**/
|
|
|
|
void
|
|
|
|
_gdk_win32_drawable_finish (GdkDrawable *drawable)
|
2004-07-27 21:58:09 +00:00
|
|
|
{
|
2005-03-18 01:23:23 +00:00
|
|
|
GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
|
|
|
|
|
|
|
|
if (impl->cairo_surface)
|
|
|
|
{
|
|
|
|
cairo_surface_finish (impl->cairo_surface);
|
2009-03-01 13:55:50 +00:00
|
|
|
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key, NULL, NULL);
|
2005-03-18 01:23:23 +00:00
|
|
|
}
|
2009-03-01 13:55:50 +00:00
|
|
|
|
2009-07-18 11:08:13 +00:00
|
|
|
g_assert (impl->hdc_count == 0);
|
2004-07-27 21:58:09 +00:00
|
|
|
}
|
2005-03-18 01:23:23 +00:00
|
|
|
|