forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			298 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			298 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #pragma once
 | ||
|  | 
 | ||
|  | #include <kinc/global.h>
 | ||
|  | 
 | ||
|  | #include <stdbool.h>
 | ||
|  | 
 | ||
|  | /*! \file mouse.h
 | ||
|  |     \brief Provides mouse-support. | ||
|  | */ | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | extern "C" { | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #define KINC_MOUSE_LEFT 0
 | ||
|  | #define KINC_MOUSE_RIGHT 1
 | ||
|  | #define KINC_MOUSE_MIDDLE 2
 | ||
|  | // eg backward sidebutton
 | ||
|  | #define KINC_MOUSE_EXTRA1 3
 | ||
|  | // eg forward sidebutton
 | ||
|  | #define KINC_MOUSE_EXTRA2 4
 | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Sets the mouse-press-callback which is called when a mouse-button is pressed.
 | ||
|  | /// The button callback argument will usually contain one of the KINC_MOUSE_* values,
 | ||
|  | /// but can contain higher values on certain platforms when mice with a lot of buttons are used.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="value">The callback</param>
 | ||
|  | KINC_FUNC void kinc_mouse_set_press_callback(void (*value)(int /*window*/, int /*button*/, int /*x*/, int /*y*/, void * /*data*/), void *data); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Sets the mouse-release-callback which is called when a mouse-button is released.
 | ||
|  | /// The button callback argument will usually contain one of the KINC_MOUSE_* values,
 | ||
|  | /// but can contain higher values on certain platforms when mice with a lot of buttons are used.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="value">The callback</param>
 | ||
|  | KINC_FUNC void kinc_mouse_set_release_callback(void (*value)(int /*window*/, int /*button*/, int /*x*/, int /*y*/, void * /*data*/), void *data); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Sets the mouse-move-callback which is called when the mouse is moved.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="value">The callback</param>
 | ||
|  | KINC_FUNC void kinc_mouse_set_move_callback(void (*value)(int /*window*/, int /*x*/, int /*y*/, int /*movement_x*/, int /*movement_y*/, void * /*data*/), | ||
|  |                                             void *data); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Sets the mouse-scroll-callback which is called when the mouse wheel is spinning.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="value">The callback</param>
 | ||
|  | KINC_FUNC void kinc_mouse_set_scroll_callback(void (*value)(int /*window*/, int /*delta*/, void * /*data*/), void *data); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Sets the mouse-enter-window-callback which is called when the mouse-cursor enters the application-window.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="value">The callback</param>
 | ||
|  | KINC_FUNC void kinc_mouse_set_enter_window_callback(void (*value)(int /*window*/, void * /*data*/), void *data); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Sets the mouse-leave-window-callback which is called when the mouse-cursor leaves the application-window.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="value">The callback</param>
 | ||
|  | KINC_FUNC void kinc_mouse_set_leave_window_callback(void (*value)(int /*window*/, void * /*data*/), void *data); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Figures out whether mouse-locking is supported.
 | ||
|  | /// </summary>
 | ||
|  | /// <returns>Whether mouse-locking is supported</returns>
 | ||
|  | KINC_FUNC bool kinc_mouse_can_lock(void); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Figures out whether the mouse is currently locked.
 | ||
|  | /// </summary>
 | ||
|  | /// <returns>Whether the mouse is currently locked</returns>
 | ||
|  | KINC_FUNC bool kinc_mouse_is_locked(void); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Locks the mouse to a window.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="window">The window to lock the mouse to</param>
 | ||
|  | KINC_FUNC void kinc_mouse_lock(int window); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Unlocks the mouse.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name=""></param>
 | ||
|  | /// <returns></returns>
 | ||
|  | KINC_FUNC void kinc_mouse_unlock(void); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Change the cursor-image to something that's semi-randomly based on the provided int.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="cursor">Defines what the cursor is changed to - somehow</param>
 | ||
|  | KINC_FUNC void kinc_mouse_set_cursor(int cursor); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Shows the mouse-cursor.
 | ||
|  | /// </summary>
 | ||
|  | KINC_FUNC void kinc_mouse_show(void); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Hides the mouse-cursor.
 | ||
|  | /// </summary>
 | ||
|  | KINC_FUNC void kinc_mouse_hide(void); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Manually sets the mouse-cursor-position.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="window">The window to place the cursor in</param>
 | ||
|  | /// <param name="x">The x-position inside the window to place the cursor at</param>
 | ||
|  | /// <param name="y">The y-position inside the window to place the cursor at</param>
 | ||
|  | KINC_FUNC void kinc_mouse_set_position(int window, int x, int y); | ||
|  | 
 | ||
|  | /// <summary>
 | ||
|  | /// Gets the current mouse-position relative to a window.
 | ||
|  | /// </summary>
 | ||
|  | /// <param name="window">The window to base the returned position on</param>
 | ||
|  | /// <param name="x">A pointer where the cursor's x-position is put into</param>
 | ||
|  | /// <param name="y">A pointer where the cursor's y-position is put into</param>
 | ||
|  | KINC_FUNC void kinc_mouse_get_position(int window, int *x, int *y); | ||
|  | 
 | ||
|  | void kinc_internal_mouse_trigger_press(int window, int button, int x, int y); | ||
|  | void kinc_internal_mouse_trigger_release(int window, int button, int x, int y); | ||
|  | void kinc_internal_mouse_trigger_move(int window, int x, int y); | ||
|  | void kinc_internal_mouse_trigger_scroll(int window, int delta); | ||
|  | void kinc_internal_mouse_trigger_enter_window(int window); | ||
|  | void kinc_internal_mouse_trigger_leave_window(int window); | ||
|  | void kinc_internal_mouse_lock(int window); | ||
|  | void kinc_internal_mouse_unlock(void); | ||
|  | void kinc_internal_mouse_window_activated(int window); | ||
|  | void kinc_internal_mouse_window_deactivated(int window); | ||
|  | 
 | ||
|  | #ifdef KINC_IMPLEMENTATION_INPUT
 | ||
|  | #define KINC_IMPLEMENTATION
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifdef KINC_IMPLEMENTATION
 | ||
|  | 
 | ||
|  | #undef KINC_IMPLEMENTATION
 | ||
|  | #include <kinc/window.h>
 | ||
|  | #define KINC_IMPLEMENTATION
 | ||
|  | 
 | ||
|  | #include <memory.h>
 | ||
|  | #include <stddef.h>
 | ||
|  | 
 | ||
|  | static void (*mouse_press_callback)(int /*window*/, int /*button*/, int /*x*/, int /*y*/, void * /*data*/) = NULL; | ||
|  | static void *mouse_press_callback_data = NULL; | ||
|  | static void (*mouse_release_callback)(int /*window*/, int /*button*/, int /*x*/, int /*y*/, void * /*data*/) = NULL; | ||
|  | static void *mouse_release_callback_data = NULL; | ||
|  | static void (*mouse_move_callback)(int /*window*/, int /*x*/, int /*y*/, int /*movementX*/, int /*movementY*/, void * /*data*/) = NULL; | ||
|  | static void *mouse_move_callback_data = NULL; | ||
|  | static void (*mouse_scroll_callback)(int /*window*/, int /*delta*/, void * /*data*/) = NULL; | ||
|  | static void *mouse_scroll_callback_data = NULL; | ||
|  | static void (*mouse_enter_window_callback)(int /*window*/, void * /*data*/) = NULL; | ||
|  | static void *mouse_enter_window_callback_data = NULL; | ||
|  | static void (*mouse_leave_window_callback)(int /*window*/, void * /*data*/) = NULL; | ||
|  | static void *mouse_leave_window_callback_data = NULL; | ||
|  | 
 | ||
|  | void kinc_mouse_set_press_callback(void (*value)(int /*window*/, int /*button*/, int /*x*/, int /*y*/, void * /*data*/), void *data) { | ||
|  | 	mouse_press_callback = value; | ||
|  | 	mouse_press_callback_data = data; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_mouse_set_release_callback(void (*value)(int /*window*/, int /*button*/, int /*x*/, int /*y*/, void * /*data*/), void *data) { | ||
|  | 	mouse_release_callback = value; | ||
|  | 	mouse_release_callback_data = data; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_mouse_set_move_callback(void (*value)(int /*window*/, int /*x*/, int /*y*/, int /*movement_x*/, int /*movement_y*/, void * /*data*/), void *data) { | ||
|  | 	mouse_move_callback = value; | ||
|  | 	mouse_move_callback_data = data; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_mouse_set_scroll_callback(void (*value)(int /*window*/, int /*delta*/, void * /*data*/), void *data) { | ||
|  | 	mouse_scroll_callback = value; | ||
|  | 	mouse_scroll_callback_data = data; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_mouse_set_enter_window_callback(void (*value)(int /*window*/, void * /*data*/), void *data) { | ||
|  | 	mouse_enter_window_callback = value; | ||
|  | 	mouse_enter_window_callback_data = data; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_mouse_set_leave_window_callback(void (*value)(int /*window*/, void * /*data*/), void *data) { | ||
|  | 	mouse_leave_window_callback = value; | ||
|  | 	mouse_leave_window_callback_data = data; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_internal_mouse_trigger_release(int window, int button, int x, int y) { | ||
|  | 	if (mouse_release_callback != NULL) { | ||
|  | 		mouse_release_callback(window, button, x, y, mouse_release_callback_data); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_internal_mouse_trigger_scroll(int window, int delta) { | ||
|  | 	if (mouse_scroll_callback != NULL) { | ||
|  | 		mouse_scroll_callback(window, delta, mouse_scroll_callback_data); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_internal_mouse_trigger_enter_window(int window) { | ||
|  | 	if (mouse_enter_window_callback != NULL) { | ||
|  | 		mouse_enter_window_callback(window, mouse_enter_window_callback_data); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_internal_mouse_trigger_leave_window(int window) { | ||
|  | 	if (mouse_leave_window_callback != NULL) { | ||
|  | 		mouse_leave_window_callback(window, mouse_leave_window_callback_data); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_internal_mouse_window_activated(int window) { | ||
|  | 	if (kinc_mouse_is_locked()) { | ||
|  | 		kinc_internal_mouse_lock(window); | ||
|  | 	} | ||
|  | } | ||
|  | void kinc_internal_mouse_window_deactivated(int window) { | ||
|  | 	if (kinc_mouse_is_locked()) { | ||
|  | 		kinc_internal_mouse_unlock(); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | // TODO: handle state per window
 | ||
|  | static bool moved = false; | ||
|  | static bool locked = false; | ||
|  | static int preLockWindow = 0; | ||
|  | static int preLockX = 0; | ||
|  | static int preLockY = 0; | ||
|  | static int centerX = 0; | ||
|  | static int centerY = 0; | ||
|  | static int lastX = 0; | ||
|  | static int lastY = 0; | ||
|  | 
 | ||
|  | void kinc_internal_mouse_trigger_press(int window, int button, int x, int y) { | ||
|  | 	lastX = x; | ||
|  | 	lastY = y; | ||
|  | 	if (mouse_press_callback != NULL) { | ||
|  | 		mouse_press_callback(window, button, x, y, mouse_press_callback_data); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_internal_mouse_trigger_move(int window, int x, int y) { | ||
|  | 	int movementX = 0; | ||
|  | 	int movementY = 0; | ||
|  | 	if (kinc_mouse_is_locked()) { | ||
|  | 		movementX = x - centerX; | ||
|  | 		movementY = y - centerY; | ||
|  | 		if (movementX != 0 || movementY != 0) { | ||
|  | 			kinc_mouse_set_position(window, centerX, centerY); | ||
|  | 			x = centerX; | ||
|  | 			y = centerY; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	else if (moved) { | ||
|  | 		movementX = x - lastX; | ||
|  | 		movementY = y - lastY; | ||
|  | 	} | ||
|  | 	moved = true; | ||
|  | 
 | ||
|  | 	lastX = x; | ||
|  | 	lastY = y; | ||
|  | 	if (mouse_move_callback != NULL && (movementX != 0 || movementY != 0)) { | ||
|  | 		mouse_move_callback(window, x, y, movementX, movementY, mouse_move_callback_data); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | bool kinc_mouse_is_locked(void) { | ||
|  | 	return locked; | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_mouse_lock(int window) { | ||
|  | 	if (!kinc_mouse_can_lock()) { | ||
|  | 		return; | ||
|  | 	} | ||
|  | 	locked = true; | ||
|  | 	kinc_internal_mouse_lock(window); | ||
|  | 	kinc_mouse_get_position(window, &preLockX, &preLockY); | ||
|  | 	centerX = kinc_window_width(window) / 2; | ||
|  | 	centerY = kinc_window_height(window) / 2; | ||
|  | 	kinc_mouse_set_position(window, centerX, centerY); | ||
|  | } | ||
|  | 
 | ||
|  | void kinc_mouse_unlock(void) { | ||
|  | 	if (!kinc_mouse_can_lock()) { | ||
|  | 		return; | ||
|  | 	} | ||
|  | 	moved = false; | ||
|  | 	locked = false; | ||
|  | 	kinc_internal_mouse_unlock(); | ||
|  | 	kinc_mouse_set_position(preLockWindow, preLockX, preLockY); | ||
|  | } | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifdef __cplusplus
 | ||
|  | } | ||
|  | #endif
 |