From cd550a1f781be2595363e95f58d267cf0d7af0da Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Thu, 12 Aug 2004 23:38:17 +0000 Subject: [PATCH] dispatch MSG_QUIT and MSG_GUI_REDRAW messages. Thanks also to Filip. svn path=/trunk/; revision=10509 --- reactos/include/rosky/rosky.h | 1 + reactos/include/rosky/structs.h | 2 +- reactos/lib/rosky/libsky/stubs.c | 6 +- reactos/lib/rosky/libskygi/Makefile | 4 +- reactos/lib/rosky/libskygi/libskygi.c | 339 ++++++++++++++++++++++---- reactos/lib/rosky/libskygi/stubs.c | 26 +- 6 files changed, 306 insertions(+), 72 deletions(-) diff --git a/reactos/include/rosky/rosky.h b/reactos/include/rosky/rosky.h index 992bc0625aa..2c36abbb175 100644 --- a/reactos/include/rosky/rosky.h +++ b/reactos/include/rosky/rosky.h @@ -3,4 +3,5 @@ */ #include +#include diff --git a/reactos/include/rosky/structs.h b/reactos/include/rosky/structs.h index 47dc3ed7f21..586a96a2f59 100644 --- a/reactos/include/rosky/structs.h +++ b/reactos/include/rosky/structs.h @@ -191,7 +191,7 @@ typedef struct s_window unsigned int width; unsigned int orgx; unsigned int orgy; - unsigned long (__cdecl *win_func)(HANDLE win, s_gi_msg *m); + unsigned long (__cdecl *win_func)(struct s_window *win, s_gi_msg *m); HANDLE handle; struct s_window *parent; diff --git a/reactos/lib/rosky/libsky/stubs.c b/reactos/lib/rosky/libsky/stubs.c index 248e99ec57d..e2b11ffed2d 100644 --- a/reactos/lib/rosky/libsky/stubs.c +++ b/reactos/lib/rosky/libsky/stubs.c @@ -1,4 +1,4 @@ -/* $Id: stubs.c,v 1.2 2004/08/12 15:41:36 weiden Exp $ +/* $Id: stubs.c,v 1.3 2004/08/12 23:38:17 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: SkyOS library @@ -118,8 +118,8 @@ ctor_dtor_initialize(func_ptr *__CTOR_LIST__, unsigned long long __cdecl get_usec_counter(void) { - STUB("get_usec_counter() returns 0x0LL!\n"); - return 0x0LL; + /* FIXME - better implementation */ + return (unsigned long long)GetTickCount() * 1000LL; } /* EOF */ diff --git a/reactos/lib/rosky/libskygi/Makefile b/reactos/lib/rosky/libskygi/Makefile index 2c6b83c5790..5fca8ee044d 100644 --- a/reactos/lib/rosky/libskygi/Makefile +++ b/reactos/lib/rosky/libskygi/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.2 2004/08/12 19:27:12 weiden Exp $ +# $Id: Makefile,v 1.3 2004/08/12 23:38:17 weiden Exp $ PATH_TO_TOP = ../../.. @@ -18,7 +18,7 @@ TARGET_CFLAGS = \ TARGET_LFLAGS = -nostartfiles -nostdlib -TARGET_SDKLIBS = ntdll.a kernel32.a user32.a +TARGET_SDKLIBS = kernel32.a ntdll.a user32.a TARGET_ENTRY = 0x00000000 diff --git a/reactos/lib/rosky/libskygi/libskygi.c b/reactos/lib/rosky/libskygi/libskygi.c index f4a731ca136..9759c8f0645 100644 --- a/reactos/lib/rosky/libskygi/libskygi.c +++ b/reactos/lib/rosky/libskygi/libskygi.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: libskygi.c,v 1.2 2004/08/12 19:27:12 weiden Exp $ +/* $Id: libskygi.c,v 1.3 2004/08/12 23:38:17 weiden Exp $ * * PROJECT: SkyOS GI library * FILE: lib/libskygi/libskygi.c @@ -41,36 +41,223 @@ typedef struct static ATOM SkyClassAtom; static BOOL SkyClassRegistered = FALSE; -LRESULT CALLBACK -SkyWndDefaultWin32Proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +/** + * Map a SkyOS window style to Windows one. + * + * @param SkyStyle SkyOS window style (WF_* flags). + * @param ExStyle Contains Windows extended window style on exit. + * + * @return Windows window style (WS_* flags). + * + * @todo Handle + * WF_MODAL, WF_HAS_MENU, WF_HAS_STATUSBAR, WF_FREEFORM, WF_FOCUSABLE, + * WF_USER, WF_DESKTOP, WF_NOT_MOVEABLE, WF_NO_BUTTONS, WF_TRANSPARENT, + * WF_NO_INITIAL_DRAW, WF_USE_BACKGROUND, WF_DONT_EREASE_BACKGROUND, + * WF_NO_FRAME. + */ +ULONG +IntMapWindowStyle(ULONG SkyStyle, ULONG *ExStyle) { - PSKY_WINDOW skw = (PSKY_WINDOW)GetWindowLong(hWnd, GWL_USERDATA); + ULONG Style; + + Style = (SkyStyle & WF_HIDE) ? 0 : WS_VISIBLE; + Style |= (SkyStyle & WF_NO_TITLE) ? 0 : WS_CAPTION; + Style |= (SkyStyle & WF_NOT_SIZEABLE) ? WS_THICKFRAME : 0; + Style |= (SkyStyle & WF_POPUP) ? WS_POPUP : 0; + Style |= (SkyStyle & WF_NO_BUTTONS) ? 0 : WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU; + *ExStyle = (SkyStyle & WF_SMALL_TITLE) ? WS_EX_TOOLWINDOW : 0; + + return Style; +} + + +/** + * Dispatch a Sky Message to the appropriate window callback + * + * @param win Specifies the destination window + * @param type The type of the message (see MSG_ constants) + * @param para1 Additional parameter 1 + * @param para2 Additional parameter 2 + * + * @return Returns the return value of the window callback function + */ +unsigned long +IntDispatchMsg(s_window *win, unsigned int type, unsigned int para1, unsigned int para2) +{ + s_gi_msg msg; + unsigned long Ret; + + /* fill the members of the struct */ + msg.win = win; + msg.type = type; + msg.para1 = para1; + msg.para2 = para2; + msg.next = NULL; /* ??? */ + msg.prev = NULL; /* ??? */ + /* FIXME */ + msg.timestamp = (unsigned long long)GetTickCount() * 1000LL; + + DBG("Dispatching window (0x%x) message type %d\n", win, type); + Ret = win->win_func(win, &msg); + DBG("Dispatched window (0x%x) message type %d, returned 0x%x\n", win, type, Ret); + return Ret; +} + + +/** + * Dispatch a Sky Message with a update rect to the appropriate window callback + * + * @param win Specifies the destination window + * @param type The type of the message (see MSG_ constants) + * @param para1 Additional parameter 1 + * @param para2 Additional parameter 2 + * @param rect Rectangle of the window to be repainted + * + * @return Returns the return value of the window callback function + */ +unsigned long +IntDispatchMsgRect(s_window *win, unsigned int type, unsigned int para1, unsigned int para2, s_region *rect) +{ + s_gi_msg msg; + unsigned long Ret; + + /* fill the members of the struct */ + msg.win = win; + msg.type = type; + msg.para1 = para1; + msg.para2 = para2; + msg.next = NULL; /* ??? */ + msg.prev = NULL; /* ??? */ + msg.rect = *rect; + /* FIXME */ + msg.timestamp = (unsigned long long)GetTickCount() * 1000LL; + + DBG("Dispatching window (0x%x) message type %d\n", win, type); + Ret = win->win_func(win, &msg); + DBG("Dispatched window (0x%x) message type %d, returned 0x%x\n", win, type, Ret); + return Ret; +} + + +/** + * Determines whether a win32 message should cause a Sky message to be dispatched + * + * @param skw Specifies the destination window + * @param Msg Contains the win32 message + * @param smsg Address to the sky message structure that will be filled in with + * appropriate information in case a sky message should be dispatched + * + * @return Returns TRUE if a Sky message should be dispatched + */ +BOOL +IntIsSkyMessage(PSKY_WINDOW skw, MSG *Msg, s_gi_msg *smsg) +{ + switch(Msg->message) + { + case WM_DESTROY: + smsg->type = MSG_DESTROY; + smsg->para1 = 0; + smsg->para2 = 0; + return TRUE; + + case WM_PAINT: + { + RECT rc; + + if(GetUpdateRect(skw->hWnd, &rc, FALSE)) + { + smsg->type = MSG_GUI_REDRAW; + smsg->para1 = 0; + smsg->para2 = 0; + + smsg->rect.x1 = rc.left; + smsg->rect.y1 = rc.top; + smsg->rect.x2 = rc.right; + smsg->rect.y2 = rc.bottom; + + return TRUE; + } + } + + case WM_QUIT: + smsg->type = MSG_QUIT; + smsg->para1 = 0; + smsg->para2 = 0; + smsg->win = (s_window*)Msg->wParam; + return TRUE; + } + + return FALSE; +} + + +/** + * The standard win32 window procedure that handles win32 messages delivered from ReactOS + * + * @param hWnd Handle of the window + * @param msg Specifies the type of the message + * @param wParam Additional data to the message + * @param lParam Additional data to the message + * + * @return Depends on the message type + */ +LRESULT CALLBACK +IntDefaultWin32Proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + PSKY_WINDOW skw = (PSKY_WINDOW)GetWindowLongW(hWnd, GWL_USERDATA); if(skw != NULL) { switch(msg) { + case WM_ERASEBKGND: + return 1; /* don't handle this message */ + + case WM_PAINT: + { + PAINTSTRUCT ps; + s_region srect; + + BeginPaint(hWnd, &ps); + srect.x1 = ps.rcPaint.left; + srect.y1 = ps.rcPaint.top; + srect.x2 = ps.rcPaint.right; + srect.y2 = ps.rcPaint.bottom; + IntDispatchMsgRect(&skw->Window, MSG_GUI_REDRAW, 0, 0, &srect); + EndPaint(hWnd, &ps); + + return 0; + } + case WM_CLOSE: - PostQuitMessage(0); - break; - case WM_NCDESTROY: + IntDispatchMsg(&skw->Window, MSG_DESTROY, 0, 0); + return 0; + + case WM_DESTROY: + SetWindowLongW(hWnd, GWL_USERDATA, 0); /* free the SKY_WINDOW structure */ HeapFree(GetProcessHeap(), 0, skw); - break; + return 0; } } - return DefWindowProc(hWnd, msg, wParam, lParam); + return DefWindowProcW(hWnd, msg, wParam, lParam); } + +/** + * Registers a Win32 window class for all Sky windows + * + * @return Returns the atom of the class registered. + */ ATOM -SkyWndRegisterClass(void) +IntRegisterClass(void) { - WNDCLASS wc; + WNDCLASSW wc; - wc.lpszClassName = "ROSkyWindow"; - wc.lpfnWndProc = SkyWndDefaultWin32Proc; + wc.lpszClassName = L"ROSkyWindow"; + wc.lpfnWndProc = IntDefaultWin32Proc; wc.style = CS_VREDRAW | CS_HREDRAW; - wc.hInstance = GetModuleHandle(NULL); + wc.hInstance = GetModuleHandleW(NULL); wc.hIcon = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, (LPCTSTR)IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); @@ -78,7 +265,7 @@ SkyWndRegisterClass(void) wc.cbClsExtra = 0; wc.cbWndExtra = 0; - return RegisterClass(&wc); + return RegisterClassW(&wc); } @@ -89,13 +276,15 @@ s_window* __cdecl GI_create_app(app_para *p) { PSKY_WINDOW skw; + ULONG Style, ExStyle; + WCHAR WindowName[sizeof(p->cpName) / sizeof(p->cpName[0])]; DBG("GI_create_app(0x%x)\n", p); /* FIXME - lock */ if(!SkyClassRegistered) { - SkyClassAtom = SkyWndRegisterClass(); + SkyClassAtom = IntRegisterClass(); SkyClassRegistered = SkyClassAtom != 0; if(!SkyClassRegistered) @@ -105,7 +294,7 @@ GI_create_app(app_para *p) } } /* FIXME - unlock */ - + skw = (PSKY_WINDOW)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SKY_WINDOW)); @@ -115,17 +304,26 @@ GI_create_app(app_para *p) return NULL; } - skw->hWnd = CreateWindow("ROSkyWindow", - (p->cpName[0] != '\0' ? (char*)p->cpName : ""), - WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, - p->ulX, - p->ulY, - p->ulWidth, - p->ulHeight, - NULL, - NULL, - GetModuleHandle(NULL), - NULL); + /* Convert the Sky window style to a Win32 window style */ + Style = IntMapWindowStyle(p->ulStyle, &ExStyle); + + /* convert the window caption to unicode */ + MultiByteToWideChar(CP_UTF8, 0, p->cpName, -1, WindowName, + sizeof(WindowName) / sizeof(WindowName[0])); + + /* create the Win32 window */ + skw->hWnd = CreateWindowExW(ExStyle, + L"ROSkyWindow", + WindowName, + WS_OVERLAPPEDWINDOW, + p->ulX, + p->ulY, + p->ulWidth, + p->ulHeight, + NULL, + NULL, + GetModuleHandleW(NULL), + NULL); if(skw->hWnd == NULL) { @@ -140,7 +338,7 @@ GI_create_app(app_para *p) /* save the pointer to the structure so we can access it later when dispatching the win32 messages so we know which sky window it is and dispatch the right messages */ - SetWindowLong(skw->hWnd, GWL_USERDATA, (LONG)skw); + SetWindowLongW(skw->hWnd, GWL_USERDATA, (LONG)skw); DBG("Created Win32 window: 0x%x\n", skw->hWnd); @@ -178,25 +376,47 @@ GI_wait_message(s_gi_msg *m, filterwnd = (w != NULL ? (PSKY_WINDOW)w : NULL); hwndFilter = (w != NULL ? filterwnd->hWnd : NULL); - Ret = GetMessage(&Msg, hwndFilter, 0, 0); - if(Ret) + for(;;) { - if(Msg.hwnd != NULL) + /* loop until we found a message that a sky app would handle, too */ + RtlZeroMemory(m, sizeof(s_gi_msg)); + + Ret = GetMessage(&Msg, hwndFilter, 0, 0); + if(Ret) { - msgwnd = (PSKY_WINDOW)GetWindowLong(Msg.hwnd, GWL_USERDATA); - msgwnd->LastMsg = Msg; + if(Msg.hwnd != NULL && (msgwnd = (PSKY_WINDOW)GetWindowLongW(Msg.hwnd, GWL_USERDATA))) + { + msgwnd->LastMsg = Msg; + if(!IntIsSkyMessage(msgwnd, &Msg, m)) + { + /* We're not interested in dispatching a sky message, try again */ + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + } + else + { + /* We're not interested in dispatching a sky message, try again */ + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } } else { - msgwnd = NULL; + /* break the loop, the sky app is supposed to shut down */ + m->type = MSG_QUIT; + break; } } - RtlZeroMemory(m, sizeof(s_gi_msg)); - m->win = (msgwnd != NULL ? &msgwnd->Window : NULL); - /* FIXME - fill in the other messags */ + if(m->win == NULL) + { + /* only set the win field if it's not set yet by IntIsSkyMessage() */ + m->win = (msgwnd != NULL ? &msgwnd->Window : NULL); + } + /* FIXME */ - return (int)Ret; + return (m->type != MSG_QUIT); } @@ -210,8 +430,16 @@ GI_dispatch_message(s_window *win, PSKY_WINDOW skywnd = (PSKY_WINDOW)win; DBG("GI_dispatch_message(0x%x, 0x%x)\n", win, m); - skywnd->DispatchMsg = *m; - DispatchMessage(&skywnd->LastMsg); + /* FIXME - why is win==1?! */ + if(win == (s_window*)0x1) return 0; + + if(win != NULL) + { + /* save the dispatched message */ + skywnd->DispatchMsg = *m; + /* dispatch the last win32 message to the win32 window procedure */ + DispatchMessage(&skywnd->LastMsg); + } return 1; } @@ -225,13 +453,38 @@ GI_ShowApplicationWindow(s_window *win) { PSKY_WINDOW skywnd = (PSKY_WINDOW)win; DBG("GI_ShowApplicationWindow(0x%x)\n", win); - - DBG("->0x%x\n", skywnd->hWnd); ShowWindow(skywnd->hWnd, SW_SHOW); return 1; } +/* + * @implemented + */ +int __cdecl +GI_redraw_window(s_window *win) +{ + DBG("GI_redraw_window(0x%x)!\n", win); + PSKY_WINDOW skywnd = (PSKY_WINDOW)win; + if(skywnd != NULL) + { + RedrawWindow(skywnd->hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); + } + return 1; +} + + +/* + * @unimplemented + */ +void __cdecl +GI_post_quit(s_window *win) +{ + DBG("GI_post_quit(0x%x)\n", win); + PostQuitMessage((int)win); +} + + /* * @implemented */ diff --git a/reactos/lib/rosky/libskygi/stubs.c b/reactos/lib/rosky/libskygi/stubs.c index 82cc0429573..1fbdfb959d6 100644 --- a/reactos/lib/rosky/libskygi/stubs.c +++ b/reactos/lib/rosky/libskygi/stubs.c @@ -1,4 +1,4 @@ -/* $Id: stubs.c,v 1.3 2004/08/12 19:27:12 weiden Exp $ +/* $Id: stubs.c,v 1.4 2004/08/12 23:38:17 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: SkyOS GI library @@ -213,15 +213,6 @@ GI_messagebox(HANDLE hWnd, return 0; } -/* - * @unimplemented - */ -void __cdecl -GI_post_quit(HANDLE win) -{ - STUB("GI_post_quit(0x%x)\n", win); -} - /* * @unimplemented @@ -255,7 +246,7 @@ int __cdecl GC_set_fg_color(GC *gc, COLOR col) { - STUB("GC_set_fg_color(0x%x, 0x%x) returns 0!\n", gc, col); + //STUB("GC_set_fg_color(0x%x, 0x%x) returns 0!\n", gc, col); return 0; } @@ -476,7 +467,7 @@ GC_draw_pixel(GC *gc, int x, int y) { - STUB("GC_draw_pixel(0x%x, 0x%x, 0x%x) returns 0!\n", gc, x, y); + //STUB("GC_draw_pixel(0x%x, 0x%x, 0x%x) returns 0!\n", gc, x, y); return 0; } @@ -509,17 +500,6 @@ GI_create_DIB(void *data, } -/* - * @unimplemented - */ -int __cdecl -GI_redraw_window(s_window *win) -{ - STUB("GI_redraw_window(0x%x) returns 0!\n", win); - return 0; -} - - /* * @unimplemented */