diff options
| -rw-r--r-- | Makefile | 15 | ||||
| -rw-r--r-- | clak.c | 86 | ||||
| -rw-r--r-- | platform/platform.h | 10 | ||||
| -rw-r--r-- | platform/win32.c | 80 | 
4 files changed, 116 insertions, 75 deletions
| @@ -5,14 +5,23 @@ BOARDS = mxblue quack  CC = gcc  CFLAGS += -std=c99 -Wall -Wextra -Wshadow -Werror -pedantic -LDLIBS = -lWinmm  BOARD_FILES = $(addsuffix /board.h,$(addprefix board/,$(BOARDS))) +ifeq ($(OS),Windows_NT) +    LDLIBS = -lWinmm +    PLATFORM = win32 +else +    UNAME_S := $(shell uname) +    ifeq ($(UNAME_S),Linux) +        PLATFORM = linux +    endif +endif +  default: $(NAME) -$(NAME): $(NAME).c $(BOARD_FILES) board/boards.h -	$(CC) $(CFLAGS) $(NAME).c $(LDLIBS) -o $(NAME) +$(NAME): $(NAME).c platform/$(PLATFORM).c $(BOARD_FILES) board/boards.h +	$(CC) $(CFLAGS) $(NAME).c platform/$(PLATFORM).c $(LDLIBS) -o $(NAME)  board/boards.h:  	printf "#ifndef BOARD_DEFAULTS_H\n#define BOARD_DEFAULTS_H\n\n" > board/boards.h @@ -1,15 +1,16 @@  #include <stdio.h>  #include <unistd.h>  #include <string.h> -#include <signal.h> - -#include <windows.h> +#include <stdbool.h> +#include <stdlib.h>  #define VOLUME 0.15  #include "board/boards.h"  #define BOARD(str, buf) { .name = str, .wav = buf }, +#include "platform/platform.h" +  typedef struct {  	char *name;  	unsigned char* wav; @@ -20,16 +21,7 @@ Board boards[] = {  };  int const boards_n = sizeof(boards) / sizeof(boards[0]); -void sound_init(void) -{ -	DWORD channel_volume = VOLUME * 0xFFFF; -	waveOutSetVolume(NULL, (channel_volume << 16) | channel_volume); -} - -void sound_play(unsigned char *buffer) -{ -	PlaySound((const char *) buffer, NULL, SND_MEMORY | SND_ASYNC | SND_NODEFAULT); -} +Board *board = NULL;  Board *get_board(char *board_name)  { @@ -40,15 +32,6 @@ Board *get_board(char *board_name)  	return NULL;  } -HHOOK keyboard_hook_windows; - -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 do_exit(int code)  {  	keyboard_unhook(); @@ -57,8 +40,6 @@ void do_exit(int code)  }  void on_clean_exit(void) { do_exit(0); } -Board *board = NULL; -  void keyboard_on_down(void)  {  	if (board == NULL) @@ -72,43 +53,6 @@ void keyboard_on_up(void)  	// 	return;  } -/* https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644985(v=vs.85) */ -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); -} - -void 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) { -		printf("ERROR: Could not set up Windows keyboard hook.\n"); -		do_exit(1); -	} -} -  int main(int argc, char **argv)  {  	if (argc < 2 || (board = get_board(argv[1])) == NULL) { @@ -120,20 +64,18 @@ int main(int argc, char **argv)  		return 1;  	} -	sound_init(); -	keyboard_hook(); +	if (!sound_init(VOLUME)) { +		printf("ERROR: Could not initialise sound system.\n"); +		return 1; +	} +	if (!keyboard_hook()) { +		printf("ERROR: Could not set up keyboard hooks.\n"); +		return 1; +	}  	atexit(on_clean_exit);  	fprintf(stderr, "Hooks set up, welcome to Clak!\n"); -	MSG msg; -	BOOL status; -	while ((status = GetMessage(&msg, NULL, 0, 0))) { -		if (status == -1) { -			// error case -			printf("ERROR: Windows error, code %lu\n", GetLastError()); -			exit(1); -		} -	} +	enter_idle();  	return 0;  }
\ No newline at end of file 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 | 
