Apply the same fixes and improvements as to the gtk-1-3-win32-production

2002-01-10  Tor Lillqvist  <tml@iki.fi>

	Apply the same fixes and improvements as to the
	gtk-1-3-win32-production branch: Bug fixes and cleanup of
	selection and DND functionality. Still doesn't work as well as the
	win32-production branch, though, but getting closer.

	After this, need to add Archaeopteryx Software's OLE2 DND support.

	* gdk/win32/gdkselection-win32.c (gdk_selection_owner_set,
	gdk_selection_send_notify, generate_selection_notify): Don't use
	SendMessage() to generate events for the same app, instead use
	gdk_event_put().

	* gdk/win32/gdkprivate-win32.h
	* gdk/win32/gdkglobals-win32.c
	* gdk/win32/gdkmain-win32.c
	* gdk/win32/gdkevents-win32.c: Thus, remove declaration, definition,
	initialisation and handling of gdk_selection_notify_msg,
	gdk_selection_request_msg and gdk_selection_clear_msg.

	* gdk/win32/gdkselection-win32.c (gdk_text_property_to_text_list,
	gdk_free_text_list, gdk_string_to_compound_text,
	gdk_free_compound_text): Implement trivially, witrh a text_list
	always having a single element, and a compound text always
	consisting of just a single (UTF-8!) string. Let's see how well
	this works.

	* gdk/win32/gdkselection-win32.c (gdk_selection_convert): Fix
	non-ASCII paste from the clipboard: Try getting the same formats
	from the Windows clipboard that gdk_property_change() puts there:
	CF_UNICODETEXT, UTF8_STRING or CF_TEXT+CF_LOCALE.

	* gdk/win32/gdkproperty-win32.c (gdk_property_change): When
	storing text on the clipboard, handle non-ASCII text
	correctly. The logic is as follows:

	If we have only ASCII characters, use CF_TEXT.

	Else, if we are on NT, use CF_UNICODETEXT.

	Else (we are on Win9x), if all the characters are present in the
	code page of some installed locale, use CF_TEXT and also set
	CF_LOCALE to that locale.

	Else (still on Win9x) store as RTF. We use a very simple RTF
	string, just the text, no fonts or other crap, with the non-ASCII
	characters as Unicode \uN keywords. Additionally, also store the
	UTF-8 string as such, under the format "UTF8_STRING", so that GDK
	can also paste from the Clipboard what it has copied there. (Thus
	no need to implement any RTF parser.)

	(find_common_locale): New function, implements the search for a
	locale for case 3 above.

	* gdk/win32/gdkglobals-win32.c: New global variables
	compound_text, text_uri_list, utf8_string, cf_rtf and
	cf_utf8_string.

	* gdk/win32/gdkim-win32.c (_gdk_ucs2_to_utf8): New function,
	converts from a wchar_t string to UTF-8.
	(_gdk_utf8_to_ucs2): Rename from _gdk_win32_nmbstowchar_ts.
	(_gdk_utf8_to_wcs): Rename from gdk_nmbstowchar_ts.

	* gdk/win32/gdkevents-win32.c (build_keypress_event): Use
	_gdk_ucs2_to_utf8().

	* gdk/win32/gdkselection-win32.c: Remove some unnecessary logging.

	* gdk/win32/gdkdnd-win32.c: Plug memory leaks, the
	gdk_drag_context_ref() was called unnecessarily in a couple of
	places, meaning drag contexts were never freed. The same memory
	leaks seem to be present in gdk/linux-fb/gdkselection-fb.c, BTW.

	(gdk_drop_reply): For WIN32_DROPFILES drops, free the temporarily
	stored file list.

	* gdk/win32/gdkselection-win32.c: Clarify the use of the
	sel_prop_table. Now it is used only for storing the GDK_SELECTION
	"properties".

	The file names dropped with WM_DROPFILES -style DND is stored
	temporarily (between the drop and the target picking them up) in a
	separate place.

	Have a separate hash table to map selection atoms to owner
	windows. This used to be quite mixed up.

	(_gdk_dropfiles_store): New function, to store the dropped file
	list for the drop target to possibly fetch, and clear it
	afterwards, from gdk_drop_reply().

	(gdk_selection_owner_get): Much simplified now.
This commit is contained in:
Tor Lillqvist
2002-01-10 00:53:39 +00:00
committed by Tor Lillqvist
parent f3f0ad29f1
commit 1b7cff4755
18 changed files with 1465 additions and 435 deletions

View File

@ -840,9 +840,9 @@ build_keypress_event (GdkWindowImplWin32 *impl,
MSG *msg)
{
HIMC himc;
gint i, bytecount, ucount, ucleft, len;
guchar buf[100], *bp;
wchar_t wbuf[100], *wcp;
gint i, bytecount, ucount;
guchar buf[100];
wchar_t wbuf[100];
event->key.type = GDK_KEY_PRESS;
event->key.time = msg->time;
@ -889,8 +889,7 @@ build_keypress_event (GdkWindowImplWin32 *impl,
*/
ucount = MultiByteToWideChar (impl->charset_info.ciACP,
0, buf, bytecount,
wbuf, sizeof (wbuf) / sizeof (wbuf[0]));
wbuf, G_N_ELEMENTS (wbuf));
}
if (ucount == 0)
event->key.keyval = GDK_VoidSymbol;
@ -911,68 +910,18 @@ build_keypress_event (GdkWindowImplWin32 *impl,
build_key_event_state (event);
/* Build UTF-8 string */
ucleft = ucount;
len = 0;
wcp = wbuf;
while (ucleft-- > 0)
if (ucount == 1 && wbuf[0] < 0200)
{
wchar_t c = *wcp++;
if (c < 0x80)
len += 1;
else if (c < 0x800)
len += 2;
else
len += 3;
event->key.string = g_malloc (2);
event->key.string[0] = wbuf[0];
event->key.string[1] = '\0';
event->key.length = 1;
}
event->key.string = g_malloc (len + 1);
event->key.length = len;
ucleft = ucount;
wcp = wbuf;
bp = event->key.string;
while (ucleft-- > 0)
else
{
int first;
wchar_t c = *wcp++;
if (c < 0x80)
{
first = 0;
len = 1;
}
else if (c < 0x800)
{
first = 0xc0;
len = 2;
}
else
{
first = 0xe0;
len = 3;
}
#if 1
/* Woo-hoo! */
switch (len)
{
case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
case 1: bp[0] = c | first;
}
#else
for (i = len - 1; i > 0; --i)
{
bp[i] = (c & 0x3f) | 0x80;
c >>= 6;
}
bp[0] = c | first;
#endif
bp += len;
event->key.string = _gdk_ucs2_to_utf8 (wbuf, ucount);
event->key.length = strlen (event->key.string);
}
*bp = 0;
}
static void
@ -1647,55 +1596,7 @@ gdk_event_translate (GdkEvent *event,
/* to translate coordinates to the internal > 16 bit system */
_gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
if (msg->message == gdk_selection_notify_msg)
{
GDK_NOTE (EVENTS, g_print ("gdk_selection_notify_msg: %#lx\n",
(gulong) msg->hwnd));
event->selection.type = GDK_SELECTION_NOTIFY;
event->selection.window = window;
event->selection.selection = GDK_POINTER_TO_ATOM (msg->wParam);
event->selection.target = GDK_POINTER_TO_ATOM (msg->lParam);
event->selection.property = _gdk_selection_property;
event->selection.time = msg->time;
return_val = !GDK_WINDOW_DESTROYED (window);
goto done;
}
else if (msg->message == gdk_selection_request_msg)
{
GDK_NOTE (EVENTS, g_print ("gdk_selection_request_msg: %#lx\n",
(gulong) msg->hwnd));
event->selection.type = GDK_SELECTION_REQUEST;
event->selection.window = window;
event->selection.selection = gdk_clipboard_atom;
event->selection.target = GDK_TARGET_STRING;
event->selection.property = _gdk_selection_property;
event->selection.requestor = (guint32) msg->hwnd;
event->selection.time = msg->time;
return_val = !GDK_WINDOW_DESTROYED (window);
goto done;
}
else if (msg->message == gdk_selection_clear_msg)
{
GDK_NOTE (EVENTS, g_print ("gdk_selection_clear_msg: %#lx\n",
(gulong) msg->hwnd));
event->selection.type = GDK_SELECTION_CLEAR;
event->selection.window = window;
event->selection.selection = GDK_POINTER_TO_ATOM (msg->wParam);
event->selection.target = GDK_POINTER_TO_ATOM (msg->lParam);
event->selection.time = msg->time;
return_val = !GDK_WINDOW_DESTROYED (window);
goto done;
}
else if (msg->message == msh_mousewheel_msg)
if (msg->message == msh_mousewheel_msg)
{
GDK_NOTE (EVENTS, g_print ("MSH_MOUSEWHEEL: %#lx %d\n",
(gulong) msg->hwnd, msg->wParam));