131 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
| /* window.cc: hidden windows for signals/itimer support
 | |
| 
 | |
|    Written by Sergey Okhapkin <sos@prospect.com.ru>
 | |
| 
 | |
| This file is part of Cygwin.
 | |
| 
 | |
| This software is a copyrighted work licensed under the terms of the
 | |
| Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 | |
| details. */
 | |
| 
 | |
| #include "winsup.h"
 | |
| #include <sys/time.h>
 | |
| #define USE_SYS_TYPES_FD_SET
 | |
| #include <winsock2.h>
 | |
| #include "perprocess.h"
 | |
| #include "cygtls.h"
 | |
| #include "sync.h"
 | |
| #include "wininfo.h"
 | |
| 
 | |
| wininfo NO_COPY winmsg;
 | |
| 
 | |
| muto NO_COPY wininfo::_lock;
 | |
| 
 | |
| int __reg3
 | |
| wininfo::process (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
| #ifndef NOSTRACE
 | |
|   strace.wm (uMsg, wParam, lParam);
 | |
| #endif
 | |
|   switch (uMsg)
 | |
|     {
 | |
|     case WM_PAINT:
 | |
|       return 0;
 | |
|     case WM_DESTROY:
 | |
|       PostQuitMessage (0);
 | |
|       return 0;
 | |
|     case WM_ASYNCIO:
 | |
|       if (WSAGETSELECTEVENT (lParam) == FD_OOB)
 | |
| 	raise (SIGURG);
 | |
|       else
 | |
| 	raise (SIGIO);
 | |
|       return 0;
 | |
|     default:
 | |
|       return DefWindowProcW (hwnd, uMsg, wParam, lParam);
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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 */
 | |
| DWORD __reg1 WINAPI
 | |
| wininfo::winthread ()
 | |
| {
 | |
|   MSG msg;
 | |
|   WNDCLASSW wc;
 | |
|   static NO_COPY WCHAR classname[] = L"CygwinWndClass";
 | |
| 
 | |
|   _lock.grab ();
 | |
|   /* Register the window class for the main window. */
 | |
| 
 | |
|   wc.style = 0;
 | |
|   wc.lpfnWndProc = (WNDPROC) process_window_events;
 | |
|   wc.cbClsExtra = 0;
 | |
|   wc.cbWndExtra = 0;
 | |
|   wc.hInstance = user_data->hmodule;
 | |
|   wc.hIcon = NULL;
 | |
|   wc.hCursor = NULL;
 | |
|   wc.hbrBackground = NULL;
 | |
|   wc.lpszMenuName = NULL;
 | |
|   wc.lpszClassName = classname;
 | |
| 
 | |
|   if (!RegisterClassW (&wc))
 | |
|     api_fatal ("cannot register window class, %E");
 | |
| 
 | |
|   /* Create hidden window. */
 | |
|   hwnd = CreateWindowExW (0, classname, classname, WS_POPUP, CW_USEDEFAULT,
 | |
| 			  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
 | |
| 			  (HWND) NULL, (HMENU) NULL, user_data->hmodule,
 | |
| 			  (LPVOID) NULL);
 | |
|   if (!hwnd)
 | |
|     api_fatal ("couldn't create window, %E");
 | |
|   release ();
 | |
| 
 | |
|   int ret;
 | |
|   while ((ret = (int) GetMessageW (&msg, hwnd, 0, 0)) > 0)
 | |
|     DispatchMessageW (&msg);
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static DWORD WINAPI
 | |
| winthread (VOID *arg)
 | |
| {
 | |
|   return  ((wininfo *) arg)->winthread ();
 | |
| }
 | |
| 
 | |
| wininfo::operator
 | |
| HWND ()
 | |
| {
 | |
|   if (hwnd)
 | |
|     return hwnd;
 | |
| 
 | |
|   lock ();
 | |
|   if (!hwnd)
 | |
|     {
 | |
|       _lock.upforgrabs ();
 | |
|       cygthread *h = new cygthread (::winthread, this, "win");
 | |
|       h->SetThreadPriority (THREAD_PRIORITY_HIGHEST);
 | |
|       h->zap_h ();
 | |
|       lock ();
 | |
|     }
 | |
|   release ();
 | |
|   return hwnd;
 | |
| }
 | |
| 
 | |
| void
 | |
| wininfo::lock ()
 | |
| {
 | |
|   _lock.init ("wininfo_lock")->acquire ();
 | |
| }
 | |
| 
 | |
| void
 | |
| wininfo::release ()
 | |
| {
 | |
|   _lock.release ();
 | |
| }
 |