mirror of
https://github.com/QB64-Phoenix-Edition/QB64pe.git
synced 2024-09-20 03:14:45 +00:00
Add support for _MOUSEWHEEL and _MOUSEMOVEMENTx on macOS
This commit is contained in:
parent
c7e912ace6
commit
787c9579b6
6 changed files with 123 additions and 27 deletions
2
Makefile
2
Makefile
|
@ -155,7 +155,7 @@ ifeq ($(OS),win)
|
|||
endif
|
||||
|
||||
ifeq ($(OS),osx)
|
||||
CXXLIBS += -framework OpenGL -framework IOKit -framework GLUT -framework Cocoa
|
||||
CXXLIBS += -framework OpenGL -framework IOKit -framework GLUT -framework Cocoa -framework ApplicationServices
|
||||
|
||||
# OSX doesn't strip using objcopy, so we're using `-s` instead
|
||||
ifneq ($(STRIP_SYMBOLS),n)
|
||||
|
|
|
@ -29582,11 +29582,19 @@ void GLUT_MOUSE_FUNC(int glut_button, int state, int x, int y) {
|
|||
# endif
|
||||
}
|
||||
|
||||
// This is used to save the last mouse position which is then paired with the mouse wheel event on macOS
|
||||
int g_MouseX = 0;
|
||||
int g_MouseY = 0;
|
||||
|
||||
void GLUT_MOTION_FUNC(int x, int y) {
|
||||
|
||||
int32 i, last_i;
|
||||
int32 handle;
|
||||
int32 xrel, yrel;
|
||||
|
||||
g_MouseX = x;
|
||||
g_MouseY = y;
|
||||
|
||||
handle = mouse_message_queue_first;
|
||||
mouse_message_queue_struct *queue = (mouse_message_queue_struct *)list_get(mouse_message_queue_handles, handle);
|
||||
|
||||
|
@ -29601,12 +29609,14 @@ void GLUT_MOTION_FUNC(int x, int y) {
|
|||
nextIndex = 0;
|
||||
queue->current = nextIndex;
|
||||
}
|
||||
# ifdef QB64_WINDOWS
|
||||
|
||||
# if defined(QB64_WINDOWS) || defined(QB64_MACOSX)
|
||||
// Windows calculates relative movement by intercepting WM_INPUT events
|
||||
// instead
|
||||
// macOS uses the Quartz Event Services to get relative movements
|
||||
xrel = 0;
|
||||
yrel = 0;
|
||||
# else
|
||||
// TODO: This needs to be correctly implemented on Linux
|
||||
xrel = x - queue->queue[queue->last].x;
|
||||
yrel = y - queue->queue[queue->last].y;
|
||||
# endif
|
||||
|
|
|
@ -34,7 +34,7 @@ libqb-objs-y$(DEP_CONSOLE_ONLY) += $(PATH_LIBQB)/src/glut-msg-queue.o
|
|||
libqb-objs-$(DEP_CONSOLE_ONLY) += $(PATH_LIBQB)/src/console-only-main-thread.o
|
||||
|
||||
ifeq ($(OS),osx)
|
||||
libqb-objs-y$(DEP_CONSOLE_ONLY) += $(PATH_LIBQB)/src/mac-key-monitor.o
|
||||
libqb-objs-y$(DEP_CONSOLE_ONLY) += $(PATH_LIBQB)/src/mac-key-monitor.o $(PATH_LIBQB)/src/mac-mouse-support.o
|
||||
endif
|
||||
|
||||
$(PATH_LIBQB)/src/%.o: $(PATH_LIBQB)/src/%.cpp
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
|
||||
#include "libqb-common.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <GL/glew.h>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <unordered_map>
|
||||
#include "GL/glew.h"
|
||||
|
||||
// note: MacOSX uses Apple's GLUT not FreeGLUT
|
||||
#ifdef QB64_MACOSX
|
||||
|
@ -18,12 +18,13 @@
|
|||
# include <GL/freeglut.h>
|
||||
#endif
|
||||
|
||||
#include "mutex.h"
|
||||
#include "thread.h"
|
||||
#include "completion.h"
|
||||
#include "glut-thread.h"
|
||||
#include "gui.h"
|
||||
#include "mac-key-monitor.h"
|
||||
#include "glut-thread.h"
|
||||
#include "mac-mouse-support.h"
|
||||
#include "mutex.h"
|
||||
#include "thread.h"
|
||||
|
||||
// FIXME: These extern variable and function definitions should probably go
|
||||
// somewhere more global so that they can be referenced by libqb.cpp
|
||||
|
@ -114,6 +115,10 @@ static void initialize_glut(int argc, char **argv) {
|
|||
#ifdef CORE_FREEGLUT
|
||||
glutMouseWheelFunc(GLUT_MOUSEWHEEL_FUNC);
|
||||
#endif
|
||||
|
||||
#ifdef QB64_MACOSX
|
||||
macMouseInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool glut_is_started;
|
||||
|
@ -136,9 +141,7 @@ void libqb_start_glut_thread() {
|
|||
}
|
||||
|
||||
// Checks whether the GLUT thread is running
|
||||
bool libqb_is_glut_up() {
|
||||
return glut_is_started;
|
||||
}
|
||||
bool libqb_is_glut_up() { return glut_is_started; }
|
||||
|
||||
void libqb_glut_presetup(int argc, char **argv) {
|
||||
if (!screen_hide) {
|
||||
|
@ -178,8 +181,11 @@ void libqb_start_main_thread(int argc, char **argv) {
|
|||
// from two threads at the same time).
|
||||
//
|
||||
// This is accomplished by simply queuing a GLUT message that calls exit() for us.
|
||||
void libqb_exit(int exitcode)
|
||||
{
|
||||
void libqb_exit(int exitcode) {
|
||||
#ifdef QB64_MACOSX
|
||||
macMouseDone();
|
||||
#endif
|
||||
|
||||
// If GLUT isn't running then we're free to do the exit() call from here
|
||||
if (!libqb_is_glut_up())
|
||||
exit(exitcode);
|
||||
|
|
74
internal/c/libqb/src/mac-mouse-support.cpp
Normal file
74
internal/c/libqb/src/mac-mouse-support.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Mouse support functions for macOS
|
||||
// These are required to overcome the limitations of GLUT
|
||||
|
||||
#include "libqb-common.h"
|
||||
|
||||
#include "mac-mouse-support.h"
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <GLUT/glut.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define QB64_EVENT_CLOSE 1
|
||||
#define QB64_EVENT_KEY 2
|
||||
#define QB64_EVENT_RELATIVE_MOUSE_MOVEMENT 3
|
||||
#define QB64_EVENT_FILE_DROP 4
|
||||
|
||||
extern "C" int qb64_custom_event(int event, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8, void *p1, void *p2);
|
||||
void GLUT_MOUSEWHEEL_FUNC(int wheel, int direction, int x, int y);
|
||||
|
||||
extern int g_MouseX, g_MouseY;
|
||||
|
||||
static CFMachPortRef g_EventTap = nullptr;
|
||||
static CFRunLoopSourceRef g_RunLoopSource = nullptr;
|
||||
|
||||
static CGEventRef macMouseCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *userInfo) {
|
||||
auto appPID = reinterpret_cast<int64_t>(userInfo);
|
||||
|
||||
if (CGEventGetIntegerValueField(event, kCGEventTargetUnixProcessID) == appPID) {
|
||||
if (type == kCGEventScrollWheel) {
|
||||
auto deltaScroll = CGEventGetIntegerValueField(event, kCGScrollWheelEventPointDeltaAxis1);
|
||||
GLUT_MOUSEWHEEL_FUNC(0, deltaScroll, g_MouseX, g_MouseY);
|
||||
} else {
|
||||
auto deltaX = CGEventGetIntegerValueField(event, kCGMouseEventDeltaX);
|
||||
auto deltaY = CGEventGetIntegerValueField(event, kCGMouseEventDeltaY);
|
||||
if (deltaX || deltaY)
|
||||
qb64_custom_event(QB64_EVENT_RELATIVE_MOUSE_MOVEMENT, deltaX, deltaY, 0, 0, 0, 0, 0, 0, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
void macMouseInit() {
|
||||
if (!g_EventTap) {
|
||||
CGEventMask eventMask = CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp) | CGEventMaskBit(kCGEventRightMouseDown) |
|
||||
CGEventMaskBit(kCGEventRightMouseUp) | CGEventMaskBit(kCGEventMouseMoved) | CGEventMaskBit(kCGEventLeftMouseDragged) |
|
||||
CGEventMaskBit(kCGEventRightMouseDragged) | CGEventMaskBit(kCGEventScrollWheel) | CGEventMaskBit(kCGEventOtherMouseDown) |
|
||||
CGEventMaskBit(kCGEventOtherMouseUp) | CGEventMaskBit(kCGEventOtherMouseDragged);
|
||||
|
||||
g_EventTap = CGEventTapCreate(kCGAnnotatedSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, eventMask, macMouseCallback,
|
||||
reinterpret_cast<void *>(getpid()));
|
||||
if (g_EventTap) {
|
||||
g_RunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, g_EventTap, 0);
|
||||
|
||||
if (g_RunLoopSource) {
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), g_RunLoopSource, kCFRunLoopCommonModes);
|
||||
CGEventTapEnable(g_EventTap, true);
|
||||
} else {
|
||||
CFRelease(g_EventTap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void macMouseDone() {
|
||||
if (g_EventTap) {
|
||||
CGEventTapEnable(g_EventTap, false);
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), g_RunLoopSource, kCFRunLoopCommonModes);
|
||||
CFRelease(g_RunLoopSource);
|
||||
CFRelease(g_EventTap);
|
||||
g_RunLoopSource = nullptr;
|
||||
g_EventTap = nullptr;
|
||||
}
|
||||
}
|
6
internal/c/libqb/src/mac-mouse-support.h
Normal file
6
internal/c/libqb/src/mac-mouse-support.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef QB64_MACOSX
|
||||
void macMouseInit();
|
||||
void macMouseDone();
|
||||
#endif
|
Loading…
Reference in a new issue