Throughout, use user32 UNICODE functions rather than ANSI functions.

* autoload.cc: Convert all definitions for ANSI user32 functions to
	definitions for the corresponding UNICODE function.
	(SendMessageA): Remove.
	(SendNotifyMessageW): Define.
	* fhandler_windows.cc (fhandler_windows::write): Use SendNotifyMessageW
	call rather than SendMessage to make function always return immediately.
	(fhandler_windows::read): Make function interruptible and a cancellation
	point.  Handle O_NONBLOCK.
	* select.cc (peek_serial): Don't wait for signal_arrived here.
	* window.cc (wininfo::winthread): Call CreateWindowExW directly rather
	than CreateWindow wrapper.
This commit is contained in:
Corinna Vinschen 2011-05-01 14:35:12 +00:00
parent c60d0bbe68
commit 79e741ef6f
7 changed files with 93 additions and 63 deletions

View File

@ -1,6 +1,6 @@
/* assert.cc: Handle the assert macro for WIN32. /* assert.cc: Handle the assert macro for WIN32.
Copyright 1997, 1998, 2000, 2001, 2007, 2008, 2009 Red Hat, Inc. Copyright 1997, 1998, 2000, 2001, 2007, 2008, 2009, 2011 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -37,13 +37,13 @@ __assert_func (const char *file, int line, const char *func,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE) if (h == INVALID_HANDLE_VALUE)
{ {
char *buf; PWCHAR buf = (PWCHAR) alloca ((100 + strlen (failedexpr))
* sizeof (WCHAR));
buf = (char *) alloca (100 + strlen (failedexpr)); __small_swprintf (buf,
__small_sprintf (buf, "Failed assertion\n\t%s\nat line %d of file %s%s%s", L"Failed assertion\n\t%s\nat line %d of file %s%s%s",
failedexpr, line, file, failedexpr, line, file,
func ? "\nin function " : "", func ? func : ""); func ? "\nin function " : "", func ? func : "");
MessageBox (NULL, buf, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL); MessageBoxW (NULL, buf, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
} }
else else
{ {

View File

@ -432,30 +432,30 @@ LoadDLLfunc (CloseClipboard, 0, user32)
LoadDLLfunc (CloseDesktop, 4, user32) LoadDLLfunc (CloseDesktop, 4, user32)
LoadDLLfunc (CloseWindowStation, 4, user32) LoadDLLfunc (CloseWindowStation, 4, user32)
LoadDLLfunc (CreateDesktopW, 24, user32) LoadDLLfunc (CreateDesktopW, 24, user32)
LoadDLLfunc (CreateWindowExA, 48, user32) LoadDLLfunc (CreateWindowExW, 48, user32)
LoadDLLfunc (CreateWindowStationW, 16, user32) LoadDLLfunc (CreateWindowStationW, 16, user32)
LoadDLLfunc (DefWindowProcA, 16, user32) LoadDLLfunc (DefWindowProcW, 16, user32)
LoadDLLfunc (DispatchMessageA, 4, user32) LoadDLLfunc (DispatchMessageW, 4, user32)
LoadDLLfunc (EmptyClipboard, 0, user32) LoadDLLfunc (EmptyClipboard, 0, user32)
LoadDLLfunc (GetClipboardData, 4, user32) LoadDLLfunc (GetClipboardData, 4, user32)
LoadDLLfunc (GetForegroundWindow, 0, user32) LoadDLLfunc (GetForegroundWindow, 0, user32)
LoadDLLfunc (GetKeyboardLayout, 4, user32) LoadDLLfunc (GetKeyboardLayout, 4, user32)
LoadDLLfunc (GetMessageA, 16, user32) LoadDLLfunc (GetMessageW, 16, user32)
LoadDLLfunc (GetPriorityClipboardFormat, 8, user32) LoadDLLfunc (GetPriorityClipboardFormat, 8, user32)
LoadDLLfunc (GetProcessWindowStation, 0, user32) LoadDLLfunc (GetProcessWindowStation, 0, user32)
LoadDLLfunc (GetThreadDesktop, 4, user32) LoadDLLfunc (GetThreadDesktop, 4, user32)
LoadDLLfunc (GetUserObjectInformationW, 20, user32) LoadDLLfunc (GetUserObjectInformationW, 20, user32)
LoadDLLfunc (GetWindowThreadProcessId, 8, user32) LoadDLLfunc (GetWindowThreadProcessId, 8, user32)
LoadDLLfunc (MessageBeep, 4, user32) LoadDLLfunc (MessageBeep, 4, user32)
LoadDLLfunc (MessageBoxA, 16, user32) LoadDLLfunc (MessageBoxW, 16, user32)
LoadDLLfunc (MsgWaitForMultipleObjectsEx, 20, user32) LoadDLLfunc (MsgWaitForMultipleObjectsEx, 20, user32)
LoadDLLfunc (OpenClipboard, 4, user32) LoadDLLfunc (OpenClipboard, 4, user32)
LoadDLLfunc (PeekMessageA, 20, user32) LoadDLLfunc (PeekMessageW, 20, user32)
LoadDLLfunc (PostMessageA, 16, user32) LoadDLLfunc (PostMessageW, 16, user32)
LoadDLLfunc (PostQuitMessage, 4, user32) LoadDLLfunc (PostQuitMessage, 4, user32)
LoadDLLfunc (RegisterClassA, 4, user32) LoadDLLfunc (RegisterClassW, 4, user32)
LoadDLLfunc (RegisterClipboardFormatA, 4, user32) LoadDLLfunc (RegisterClipboardFormatW, 4, user32)
LoadDLLfunc (SendMessageA, 16, user32) LoadDLLfunc (SendNotifyMessageW, 16, user32)
LoadDLLfunc (SetClipboardData, 8, user32) LoadDLLfunc (SetClipboardData, 8, user32)
LoadDLLfunc (SetParent, 8, user32) LoadDLLfunc (SetParent, 8, user32)
LoadDLLfunc (SetProcessWindowStation, 4, user32) LoadDLLfunc (SetProcessWindowStation, 4, user32)

View File

@ -1319,7 +1319,6 @@ class fhandler_windows: public fhandler_base
select_record *select_read (select_stuff *); select_record *select_read (select_stuff *);
select_record *select_write (select_stuff *); select_record *select_write (select_stuff *);
select_record *select_except (select_stuff *); select_record *select_except (select_stuff *);
bool is_slow () {return true;}
}; };
class fhandler_dev_dsp: public fhandler_base class fhandler_dev_dsp: public fhandler_base

View File

@ -1,7 +1,6 @@
/* fhandler_dev_clipboard: code to access /dev/clipboard /* fhandler_dev_clipboard: code to access /dev/clipboard
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2011 Red Hat, Inc
Red Hat, Inc
Written by Charles Wilson (cwilson@ece.gatech.edu) Written by Charles Wilson (cwilson@ece.gatech.edu)
@ -25,7 +24,7 @@ details. */
* changed? How does /dev/clipboard operate under (say) linux? * changed? How does /dev/clipboard operate under (say) linux?
*/ */
static const NO_COPY char *CYGWIN_NATIVE = "CYGWIN_NATIVE_CLIPBOARD"; static const NO_COPY WCHAR *CYGWIN_NATIVE = L"CYGWIN_NATIVE_CLIPBOARD";
/* this is MT safe because windows format id's are atomic */ /* this is MT safe because windows format id's are atomic */
static int cygnativeformat; static int cygnativeformat;
@ -35,7 +34,7 @@ fhandler_dev_clipboard::fhandler_dev_clipboard ()
{ {
/* FIXME: check for errors and loop until we can open the clipboard */ /* FIXME: check for errors and loop until we can open the clipboard */
OpenClipboard (NULL); OpenClipboard (NULL);
cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE); cygnativeformat = RegisterClipboardFormatW (CYGWIN_NATIVE);
CloseClipboard (); CloseClipboard ();
} }
@ -69,7 +68,7 @@ fhandler_dev_clipboard::open (int flags, mode_t)
free (membuffer); free (membuffer);
membuffer = NULL; membuffer = NULL;
if (!cygnativeformat) if (!cygnativeformat)
cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE); cygnativeformat = RegisterClipboardFormatW (CYGWIN_NATIVE);
nohandle (true); nohandle (true);
set_open_status (); set_open_status ();
return 1; return 1;
@ -96,7 +95,7 @@ set_clipboard (const void *buf, size_t len)
GlobalUnlock (hmem); GlobalUnlock (hmem);
EmptyClipboard (); EmptyClipboard ();
if (!cygnativeformat) if (!cygnativeformat)
cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE); cygnativeformat = RegisterClipboardFormatW (CYGWIN_NATIVE);
HANDLE ret = SetClipboardData (cygnativeformat, hmem); HANDLE ret = SetClipboardData (cygnativeformat, hmem);
CloseClipboard (); CloseClipboard ();
/* According to MSDN, hmem must not be free'd after transferring the /* According to MSDN, hmem must not be free'd after transferring the

View File

@ -1,7 +1,7 @@
/* fhandler_windows.cc: code to access windows message queues. /* fhandler_windows.cc: code to access windows message queues.
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
Red Hat, Inc. 2011 Red Hat, Inc.
Written by Sergey S. Okhapkin (sos@prospect.com.ru). Written by Sergey S. Okhapkin (sos@prospect.com.ru).
Feedback and testing by Andy Piper (andyp@parallax.co.uk). Feedback and testing by Andy Piper (andyp@parallax.co.uk).
@ -18,13 +18,15 @@ details. */
#include "cygerrno.h" #include "cygerrno.h"
#include "path.h" #include "path.h"
#include "fhandler.h" #include "fhandler.h"
#include "sigproc.h"
#include "thread.h"
/* /*
The following unix-style calls are supported: The following unix-style calls are supported:
open ("/dev/windows", flags, mode=0) open ("/dev/windows", flags, mode=0)
- create a unix fd for message queue. - create a unix fd for message queue.
O_NONBLOCK flag controls the read() call behavior.
read (fd, buf, len) read (fd, buf, len)
- return next message from queue. buf must point to MSG - return next message from queue. buf must point to MSG
@ -67,16 +69,19 @@ fhandler_windows::write (const void *buf, size_t)
if (method_ == WINDOWS_POST) if (method_ == WINDOWS_POST)
{ {
if (!PostMessage (ptr->hwnd, ptr->message, ptr->wParam, ptr->lParam)) if (!PostMessageW (ptr->hwnd, ptr->message, ptr->wParam, ptr->lParam))
{ {
__seterrno (); __seterrno ();
return -1; return -1;
} }
else
return sizeof (MSG);
} }
else else if (!SendNotifyMessageW (ptr->hwnd, ptr->message, ptr->wParam,
return SendMessage (ptr->hwnd, ptr->message, ptr->wParam, ptr->lParam); ptr->lParam))
{
__seterrno ();
return -1;
}
return sizeof (MSG);
} }
void __stdcall void __stdcall
@ -91,10 +96,47 @@ fhandler_windows::read (void *buf, size_t& len)
return; return;
} }
len = (size_t) GetMessage (ptr, hWnd_, 0, 0); HANDLE w4[3] = { get_handle (), signal_arrived, NULL };
DWORD cnt = 2;
if ((ssize_t) len == -1) pthread_t thread = pthread::self ();
__seterrno (); if (thread && thread->cancel_event
&& thread->cancelstate != PTHREAD_CANCEL_DISABLE)
w4[cnt++] = thread->cancel_event;
restart:
switch (MsgWaitForMultipleObjectsEx (cnt, w4,
is_nonblocking () ? 0 : INFINITE,
QS_ALLINPUT | QS_ALLPOSTMESSAGE,
MWMO_INPUTAVAILABLE))
{
case WAIT_OBJECT_0:
if (!PeekMessageW (ptr, hWnd_, 0, 0, PM_REMOVE))
{
len = (size_t) -1;
__seterrno ();
}
else if (ptr->message == WM_QUIT)
len = 0;
else
len = sizeof (MSG);
break;
case WAIT_OBJECT_0 + 1:
if (_my_tls.call_signal_handler ())
goto restart;
len = (size_t) -1;
set_errno (EINTR);
break;
case WAIT_OBJECT_0 + 2:
pthread::static_cancel_self ();
break;
case WAIT_TIMEOUT:
len = (size_t) -1;
set_errno (EAGAIN);
break;
default:
len = (size_t) -1;
__seterrno ();
break;
}
} }
int int

View File

@ -1055,14 +1055,7 @@ peek_serial (select_record *s, bool)
} }
} }
HANDLE w4[2]; switch (WaitForSingleObject (fh->io_status.hEvent, 10L))
DWORD to;
w4[0] = fh->io_status.hEvent;
w4[1] = signal_arrived;
to = 10;
switch (WaitForMultipleObjects (2, w4, FALSE, to))
{ {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
if (!ClearCommError (h, &fh->ev, &st)) if (!ClearCommError (h, &fh->ev, &st))
@ -1071,18 +1064,13 @@ peek_serial (select_record *s, bool)
goto err; goto err;
} }
else if (!st.cbInQue) else if (!st.cbInQue)
Sleep (to); Sleep (10L);
else else
{ {
return s->read_ready = true; return s->read_ready = true;
select_printf ("got something"); select_printf ("got something");
} }
break; break;
case WAIT_OBJECT_0 + 1:
select_printf ("interrupt");
set_sig_errno (EINTR);
ready = -1;
break;
case WAIT_TIMEOUT: case WAIT_TIMEOUT:
break; break;
default: default:
@ -1547,7 +1535,7 @@ peek_windows (select_record *me, bool)
if (me->read_selected && me->read_ready) if (me->read_selected && me->read_ready)
return 1; return 1;
if (PeekMessage (&m, (HWND) h, 0, 0, PM_NOREMOVE)) if (PeekMessageW (&m, (HWND) h, 0, 0, PM_NOREMOVE))
{ {
me->read_ready = true; me->read_ready = true;
select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ()); select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());

View File

@ -1,6 +1,7 @@
/* window.cc: hidden windows for signals/itimer support /* window.cc: hidden windows for signals/itimer support
Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc. Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2010,
2011 Red Hat, Inc.
Written by Sergey Okhapkin <sos@prospect.com.ru> Written by Sergey Okhapkin <sos@prospect.com.ru>
@ -45,7 +46,7 @@ wininfo::process (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
raise (SIGIO); raise (SIGIO);
return 0; return 0;
default: default:
return DefWindowProc (hwnd, uMsg, wParam, lParam); return DefWindowProcW (hwnd, uMsg, wParam, lParam);
} }
} }
@ -60,8 +61,8 @@ DWORD WINAPI
wininfo::winthread () wininfo::winthread ()
{ {
MSG msg; MSG msg;
WNDCLASS wc; WNDCLASSW wc;
static NO_COPY char classname[] = "CygwinWndClass"; static NO_COPY WCHAR classname[] = L"CygwinWndClass";
_lock.grab (); _lock.grab ();
/* Register the window class for the main window. */ /* Register the window class for the main window. */
@ -77,20 +78,21 @@ wininfo::winthread ()
wc.lpszMenuName = NULL; wc.lpszMenuName = NULL;
wc.lpszClassName = classname; wc.lpszClassName = classname;
if (!RegisterClass (&wc)) if (!RegisterClassW (&wc))
api_fatal ("cannot register window class, %E"); api_fatal ("cannot register window class, %E");
/* Create hidden window. */ /* Create hidden window. */
hwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT, hwnd = CreateWindowExW (0, classname, classname, WS_POPUP, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
(HWND) NULL, (HMENU) NULL, user_data->hmodule, (HWND) NULL, (HMENU) NULL, user_data->hmodule,
(LPVOID) NULL); (LPVOID) NULL);
if (!hwnd) if (!hwnd)
api_fatal ("couldn't create window, %E"); api_fatal ("couldn't create window, %E");
release (); release ();
while (GetMessage (&msg, hwnd, 0, 0) == TRUE) int ret;
DispatchMessage (&msg); while ((ret = (int) GetMessageW (&msg, hwnd, 0, 0)) > 0)
DispatchMessageW (&msg);
return 0; return 0;
} }