Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Win32 event handling
  • Loading branch information
r-lyeh authored and Riku Salminen committed Jan 4, 2013
1 parent 169faef commit 3cd5fed
Show file tree
Hide file tree
Showing 5 changed files with 390 additions and 36 deletions.
242 changes: 210 additions & 32 deletions src/win32/events.c
@@ -1,59 +1,237 @@
#include <glwt_internal.h>

LRESULT CALLBACK glwtWin32WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
#include <windows.h>
#include <windowsx.h> /* GET_X_LPARAM, GET_Y_LPARAM macros */

static int GetModifiers()
{
return
(GetKeyState(VK_SHIFT) & 0x8000 ? GLWT_MOD_SHIFT : 0) |
(GetKeyState(VK_CONTROL) & 0x8000 ? GLWT_MOD_CTRL : 0) |
(GetKeyState(VK_LMENU) & 0x8000 ? GLWT_MOD_ALT : 0) |
(GetKeyState(VK_RMENU) & 0x8000 ? GLWT_MOD_ALTGR : 0) |
(GetKeyState(VK_NUMLOCK) & 0x8000 ? GLWT_MOD_NUM_LOCK : 0) |
(GetKeyState(VK_CAPITAL) & 0x8000 ? GLWT_MOD_CAPS_LOCK : 0) |
(GetKeyState(VK_LWIN) & 0x8000 ? GLWT_MOD_SUPER : 0) |
(GetKeyState(VK_RWIN) & 0x8000 ? GLWT_MOD_SUPER : 0);
}

LRESULT CALLBACK glwtWin32WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
GLWTWindow *win = (GLWTWindow*)GetWindowLongPtr(hwnd, 0);

if(win)
{
switch(message)
switch(uMsg)
{
case WM_CLOSE:
win->closed = 1;
return 1;
case WM_PAINT:
if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = GLWT_WINDOW_EXPOSE;
event.dummy.dummy = 0;
win->win_callback(win, &event, win->userdata);
}

ValidateRect(hwnd, NULL);
return 1;
case WM_SETFOCUS:
case WM_KILLFOCUS:
return 1;
case WM_SIZE:

case WM_KEYUP:
if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = GLWT_WINDOW_KEY_UP;
event.key.keysym = keymap_lookup(&glwt.win32.keymap, wParam);
event.key.scancode = (lParam >> 16) & 0xff;
event.key.mod = GetModifiers();
win->win_callback(win, &event, win->userdata);
}

return 1;
case WM_MOUSEMOVE:

case WM_KEYDOWN:
if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = GLWT_WINDOW_KEY_DOWN;
event.key.keysym = keymap_lookup(&glwt.win32.keymap, wParam);
event.key.scancode = (lParam >> 16) & 0xff;
event.key.mod = GetModifiers();
win->win_callback(win, &event, win->userdata);
}

return 1;
case WM_LBUTTONDOWN:

case WM_LBUTTONUP:
case WM_MBUTTONDOWN:
case WM_LBUTTONDOWN:
case WM_MBUTTONUP:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONUP:
case WM_XBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_XBUTTONUP:
case WM_MOUSEWHEEL:
#ifdef WM_MOUSEHWHEEL
case WM_MOUSEHWHEEL:
#endif
case WM_XBUTTONDOWN:
if(win->win_callback)
{
GLWTWindowEvent event;
int button;

if(uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDOWN) button = 0;
else if(uMsg == WM_MBUTTONUP || uMsg == WM_MBUTTONDOWN) button = 1;
else if(uMsg == WM_RBUTTONUP || uMsg == WM_RBUTTONDOWN) button = 2;
else button = (wParam & MK_XBUTTON2 ? 4 : 3);

event.window = win;
event.type =
(uMsg == WM_LBUTTONUP || uMsg == WM_MBUTTONUP || uMsg == WM_RBUTTONUP || uMsg == WM_XBUTTONUP)
? GLWT_WINDOW_BUTTON_UP : GLWT_WINDOW_BUTTON_DOWN;
event.button.x = LOWORD(lParam);
event.button.y = HIWORD(lParam);
event.button.button = button;
event.button.mod = GetModifiers();
win->win_callback(win, &event, win->userdata);
}

return 1;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:

case WM_MOUSEMOVE:
if(win->win_callback)
{
GLWTWindowEvent event;

/* Keep mouse enter/leave events alive */
if( win->win32.hover == 0 )
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_HOVER|TME_LEAVE;
tme.hwndTrack = hwnd;
tme.dwHoverTime = 1;
TrackMouseEvent(&tme);

win->win32.hover = -1;
}

event.window = win;
event.type = GLWT_WINDOW_MOUSE_MOTION;
event.motion.x = GET_X_LPARAM(lParam);
event.motion.y = GET_Y_LPARAM(lParam);
event.motion.buttons =
(wParam & MK_LBUTTON ? 1 : 0) |
(wParam & MK_RBUTTON ? 2 : 0) |
(wParam & MK_MBUTTON ? 4 : 0) |
(wParam & MK_XBUTTON1 ? 8 : 0) |
(wParam & MK_XBUTTON2 ? 16 : 0);
win->win_callback(win, &event, win->userdata);
}

return 1;
case WM_CHAR:
// TODO: character events
case WM_ENTERSIZEMOVE:
case WM_EXITSIZEMOVE:
case WM_GETMINMAXINFO:
case WM_ERASEBKGND:
// TODO: use these event to deal with window resizing and size limits

case WM_SETFOCUS:
if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = GLWT_WINDOW_FOCUS_IN;
event.dummy.dummy = 0;
win->win_callback(win, &event, win->userdata);
}

return 1;

case WM_KILLFOCUS:
if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = GLWT_WINDOW_FOCUS_OUT;
event.dummy.dummy = 0;
win->win_callback(win, &event, win->userdata);
}

return 1;

case WM_MOUSEHOVER:
if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = (win->win32.hover == 1 ? GLWT_WINDOW_NO_EVENT : GLWT_WINDOW_MOUSE_ENTER);
event.dummy.dummy = 0;
win->win32.hover = 1;
win->win_callback(win, &event, win->userdata);
}

return 1;

case WM_MOUSELEAVE:
// TODO: mouseover events
if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = GLWT_WINDOW_MOUSE_LEAVE;
event.dummy.dummy = 0;
win->win32.hover = 0;
win->win_callback(win, &event, win->userdata);
}

return 1;

case WM_SHOWWINDOW:
if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = (wParam == TRUE ? GLWT_WINDOW_SHOW : GLWT_WINDOW_HIDE);
event.dummy.dummy = 0;
win->win_callback(win, &event, win->userdata);
}

return 1;

case WM_SIZE:
if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = GLWT_WINDOW_RESIZE;
event.resize.width = LOWORD(lParam);
event.resize.height = HIWORD(lParam);
win->win_callback(win, &event, win->userdata);
}

return 1;

case WM_CLOSE:
win->closed = 1;

if(win->win_callback)
{
GLWTWindowEvent event;
event.window = win;
event.type = GLWT_WINDOW_CLOSE;
event.dummy.dummy = 0;
win->win_callback(win, &event, win->userdata);
}

return 1;

case WM_CHAR:
// TODO: Handle text input

case WM_DESTROY:
case WM_QUIT:
// TODO: Handle destroy and quit messages

default:
break;
break;

}
}

return DefWindowProc(hwnd, message, wparam, lparam);
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int glwtEventHandle(int wait)
Expand Down
6 changes: 4 additions & 2 deletions src/win32/glwt_win32.c
Expand Up @@ -39,6 +39,8 @@ int glwtInit(
glwt.error_callback = error_callback;
glwt.userdata = userdata;

keymap_init(&glwt.win32.keymap);

glwt.win32.hinstance = GetModuleHandle(0);
if(!glwt.win32.hinstance)
{
Expand All @@ -53,7 +55,7 @@ int glwtInit(
klass.cbWndExtra = sizeof(GLWTWindow*);
klass.hInstance = glwt.win32.hinstance;
klass.hIcon = 0;
klass.hCursor = 0;
klass.hCursor = LoadCursor( NULL, IDC_ARROW );
klass.hbrBackground = 0;
klass.lpszMenuName = 0;
klass.lpszClassName = klassname;
Expand All @@ -69,7 +71,7 @@ int glwtInit(
L"", // window title
WS_POPUP | WS_DISABLED,
CW_USEDEFAULT, CW_USEDEFAULT,
100, 100, // width, height
100, 100, /* width, height */
0,
0,
glwt.win32.hinstance,
Expand Down
4 changes: 4 additions & 0 deletions src/win32/glwt_win32.h
Expand Up @@ -4,19 +4,23 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <win32/keymap.h>

struct glwt_win32
{
HINSTANCE hinstance;
ATOM classatom;
HWND dummy_hwnd;
HDC dummy_hdc;
int pixel_format;
struct keymap keymap;
};

struct glwt_window_win32
{
HWND hwnd;
HDC hdc;
int hover;
};

void glwtWin32Error(const char *msg);
Expand Down

0 comments on commit 3cd5fed

Please sign in to comment.