diff options
Diffstat (limited to 'winsup/cygwin/window.cc')
-rw-r--r-- | winsup/cygwin/window.cc | 120 |
1 files changed, 71 insertions, 49 deletions
diff --git a/winsup/cygwin/window.cc b/winsup/cygwin/window.cc index d005ae69b..554be3a5e 100644 --- a/winsup/cygwin/window.cc +++ b/winsup/cygwin/window.cc @@ -24,14 +24,21 @@ details. */ #include "perprocess.h" #include "security.h" #include "cygthread.h" +#include "sync.h" +static DWORD WINAPI winthread (VOID *); +#include "wininfo.h" -static NO_COPY UINT timer_active = 0; -static NO_COPY struct itimerval itv; -static NO_COPY DWORD start_time; -static NO_COPY HWND ourhwnd = NULL; +wininfo NO_COPY winmsg; -static LRESULT CALLBACK -WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +muto NO_COPY *wininfo::lock; + +wininfo::wininfo () +{ + new_muto_name (lock, "!winlock"); +} + +int __stdcall +wininfo::process (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { #ifndef NOSTRACE strace.wm (uMsg, wParam, lParam); @@ -50,9 +57,7 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) itv.it_interval.tv_usec / 1000; KillTimer (hwnd, timer_active); if (!elapse) - { - timer_active = 0; - } + timer_active = 0; else { timer_active = SetTimer (hwnd, 1, elapse, NULL); @@ -73,10 +78,15 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } } -static HANDLE window_started; +static LRESULT CALLBACK +process_window_events (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return winmsg.process (hwnd, uMsg, wParam, lParam); +} +/* Handle windows events. Inherits ownership of the wininfo lock */ static DWORD WINAPI -Winmain (VOID *) +winthread (VOID *arg) { MSG msg; WNDCLASS wc; @@ -85,7 +95,7 @@ Winmain (VOID *) /* Register the window class for the main window. */ wc.style = 0; - wc.lpfnWndProc = (WNDPROC) WndProc; + wc.lpfnWndProc = (WNDPROC) process_window_events; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = user_data->hmodule; @@ -96,60 +106,64 @@ Winmain (VOID *) wc.lpszClassName = classname; if (!RegisterClass (&wc)) - { - system_printf ("Cannot register window class, %E"); - return FALSE; - } + api_fatal ("cannot register window class, %E"); + wininfo *wi = (wininfo *) arg; /* Create hidden window. */ - ourhwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - (HWND) NULL, (HMENU) NULL, user_data->hmodule, - (LPVOID) NULL); - - SetEvent (window_started); - - if (!ourhwnd) - { - system_printf ("Cannot create window"); - return FALSE; - } - - /* Start the message loop. */ - - while (GetMessage (&msg, ourhwnd, 0, 0) == TRUE) + wi->hwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + (HWND) NULL, (HMENU) NULL, user_data->hmodule, + (LPVOID) NULL); + if (!wi->hwnd) + api_fatal ("couldn't create window, %E"); + wi->lock->release (); + + while (GetMessage (&msg, (HWND) arg, 0, 0) == TRUE) DispatchMessage (&msg); return 0; } -HWND __stdcall -gethwnd () +wininfo::operator +HWND () { - if (ourhwnd != NULL) - return ourhwnd; + if (hwnd) + return hwnd; + +console_printf ("hwnd is NULL\n"); + lock->acquire (); + if (hwnd) + { +console_printf ("hwnd acquired %p\n", hwnd); + lock->release (); + return hwnd; + } - cygthread *h; +console_printf ("creating window\n"); - window_started = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - h = new cygthread (Winmain, NULL, "win"); + cygthread *h = new cygthread (winthread, this, "win"); h->SetThreadPriority (THREAD_PRIORITY_HIGHEST); - WaitForSingleObject (window_started, INFINITE); - CloseHandle (window_started); h->zap_h (); - return ourhwnd; + while (!hwnd) + low_priority_sleep (0); + return hwnd; } extern "C" int setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) { - UINT elapse; - if (which != ITIMER_REAL) { set_errno (ENOSYS); return -1; } + return winmsg.setitimer (value, oldvalue); +} + +/* FIXME: Very racy */ +int __stdcall +wininfo::setitimer (const struct itimerval *value, struct itimerval *oldvalue) +{ /* Check if we will wrap */ if (itv.it_value.tv_sec >= (long) (UINT_MAX / 1000)) { @@ -158,7 +172,7 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) } if (timer_active) { - KillTimer (gethwnd (), timer_active); + KillTimer (winmsg, timer_active); timer_active = 0; } if (oldvalue) @@ -169,13 +183,13 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) return -1; } itv = *value; - elapse = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; + UINT elapse = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; if (elapse == 0) if (itv.it_value.tv_usec) elapse = 1; else return 0; - if (!(timer_active = SetTimer (gethwnd (), 1, elapse, NULL))) + if (!(timer_active = SetTimer (winmsg, 1, elapse, NULL))) { __seterrno (); return -1; @@ -187,8 +201,6 @@ setitimer (int which, const struct itimerval *value, struct itimerval *oldvalue) extern "C" int getitimer (int which, struct itimerval *value) { - UINT elapse, val; - if (which != ITIMER_REAL) { set_errno (EINVAL); @@ -199,6 +211,13 @@ getitimer (int which, struct itimerval *value) set_errno (EFAULT); return -1; } + return winmsg.getitimer (value); +} + +/* FIXME: racy */ +int __stdcall +wininfo::getitimer (struct itimerval *value) +{ *value = itv; if (!timer_active) { @@ -206,6 +225,9 @@ getitimer (int which, struct itimerval *value) value->it_value.tv_usec = 0; return 0; } + + UINT elapse, val; + elapse = GetTickCount () - start_time; val = itv.it_value.tv_sec * 1000 + itv.it_value.tv_usec / 1000; val -= elapse; |