diff options
Diffstat (limited to 'platform')
| -rw-r--r-- | platform/platform.h | 10 | ||||
| -rw-r--r-- | platform/win32.c | 80 | 
2 files changed, 90 insertions, 0 deletions
| diff --git a/platform/platform.h b/platform/platform.h new file mode 100644 index 0000000..da1efa6 --- /dev/null +++ b/platform/platform.h @@ -0,0 +1,10 @@ +#ifndef CLAK_PLATFORM_H_ +#define CLAK_PLATFORM_H_ + +bool sound_init(float volume); +void sound_play(unsigned char *buffer); +void keyboard_unhook(void); +bool keyboard_hook(void); +void enter_idle(void); + +#endif /* CLAK_PLATFORM_H_ */
\ No newline at end of file diff --git a/platform/win32.c b/platform/win32.c new file mode 100644 index 0000000..90cd37c --- /dev/null +++ b/platform/win32.c @@ -0,0 +1,80 @@ +#include <stdio.h> +#include <stdbool.h> +#include <windows.h> + +/* Required callbacks */ +extern void keyboard_on_down(void); +extern void keyboard_on_up(void); + +static HHOOK keyboard_hook_windows; + +bool sound_init(float volume) +{ +	DWORD channel_volume = volume * 0xFFFF; +	if (waveOutSetVolume(NULL, (channel_volume << 16) | channel_volume) != MMSYSERR_NOERROR) +		return false; +	return true; +} + +void sound_play(unsigned char *buffer) +{ +	PlaySound((const char *) buffer, NULL, SND_MEMORY | SND_ASYNC | SND_NODEFAULT); +} + +/* https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644985(v=vs.85) */ +static LRESULT CALLBACK keyboard_windows_callback(int nCode, WPARAM wParam, LPARAM lParam) +{ +	/* Needed to prevent repeat fires */ +	static DWORD prev_vk = 0; + +	/* Do not handle unless nCode >= 0, pass to next hook right away */ +	if (nCode >= 0) { +		BOOL down = wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN; +		KBDLLHOOKSTRUCT *hook_struct = (KBDLLHOOKSTRUCT *) lParam; +		DWORD vk = hook_struct->vkCode; +		if (down && vk != prev_vk) { +			keyboard_on_down(); +			prev_vk = vk; +		} else { +			keyboard_on_up(); +			/* Seems like repeat strokes are 0x0 or 0x1, and 'real' ones have 0x80 flag?? +			   Not really sure how to handle this one, can't find many docs... +			   Saw this though: https://github.com/pyglet/pyglet/blob/838d004d68fcc5c3ce83b733e3d088fad0643859/pyglet/window/win32/__init__.py#L794= */ +			if (hook_struct->flags & 0x80) +				prev_vk = 0; +		} +	} + +	return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +bool keyboard_hook(void) +{ +	fprintf(stderr, "Setting up keyboard hook...\n"); +	keyboard_hook_windows = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_windows_callback, NULL, 0); +	if (keyboard_hook_windows == NULL) { +		return false; +	} +	return true; +} + +void keyboard_unhook(void) +{ +	fprintf(stderr, "Cleaning up keyboard hook...\n"); +	if (!UnhookWindowsHookEx(keyboard_hook_windows)) +		printf("WARN: Windows keyboard hook could not be cleaned up! Error code: %lu\n", GetLastError()); +} + +void enter_idle(void) +{ +	MSG msg; +	BOOL status; +	while ((status = GetMessage(&msg, NULL, 0, 0))) { +		if (status == -1) { +			// error case +			printf("ERROR: Windows error, code %lu\n", GetLastError()); +			keyboard_unhook(); +			exit(1); +		} +	} +}
\ No newline at end of file | 
