dispatch MSG_QUIT and MSG_GUI_REDRAW messages. Thanks also to Filip.

svn path=/trunk/; revision=10509
This commit is contained in:
Thomas Bluemel 2004-08-12 23:38:17 +00:00
parent a7d6dcd7c1
commit cd550a1f78
6 changed files with 306 additions and 72 deletions

View file

@ -3,4 +3,5 @@
*/
#include <rosky/structs.h>
#include <rosky/defines.h>

View file

@ -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;

View file

@ -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 */

View file

@ -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

View file

@ -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
*/

View file

@ -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
*/