Mouse wheel support added.
This commit is contained in:
parent
937be903af
commit
5cf6db01e1
5 changed files with 106 additions and 5 deletions
43
dvx/dvxApp.c
43
dvx/dvxApp.c
|
|
@ -1096,6 +1096,39 @@ static void dispatchEvents(AppContextT *ctx) {
|
||||||
win->onMouse(win, relX, relY, buttons);
|
win->onMouse(win, relX, relY, buttons);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mouse wheel — scroll the focused window's vertical scrollbar.
|
||||||
|
// Each notch moves MOUSE_WHEEL_STEP lines. If no vertical scrollbar,
|
||||||
|
// try horizontal (for windows with only horizontal scroll).
|
||||||
|
if (ctx->mouseWheel != 0 && ctx->stack.focusedIdx >= 0) {
|
||||||
|
WindowT *win = ctx->stack.windows[ctx->stack.focusedIdx];
|
||||||
|
ScrollbarT *sb = win->vScroll ? win->vScroll : win->hScroll;
|
||||||
|
|
||||||
|
if (sb) {
|
||||||
|
int32_t oldValue = sb->value;
|
||||||
|
sb->value += ctx->mouseWheel * MOUSE_WHEEL_STEP;
|
||||||
|
|
||||||
|
if (sb->value < sb->min) {
|
||||||
|
sb->value = sb->min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sb->value > sb->max) {
|
||||||
|
sb->value = sb->max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sb->value != oldValue) {
|
||||||
|
int32_t sbScreenX = win->x + sb->x;
|
||||||
|
int32_t sbScreenY = win->y + sb->y;
|
||||||
|
dirtyListAdd(&ctx->dirty, sbScreenX, sbScreenY,
|
||||||
|
sb->orient == ScrollbarVerticalE ? SCROLLBAR_WIDTH : sb->length,
|
||||||
|
sb->orient == ScrollbarVerticalE ? sb->length : SCROLLBAR_WIDTH);
|
||||||
|
|
||||||
|
if (win->onScroll) {
|
||||||
|
win->onScroll(win, sb->orient, sb->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1549,10 +1582,11 @@ int32_t dvxInit(AppContextT *ctx, int32_t requestedW, int32_t requestedH, int32_
|
||||||
ctx->cursorBg = packColor(&ctx->display, 0, 0, 0);
|
ctx->cursorBg = packColor(&ctx->display, 0, 0, 0);
|
||||||
|
|
||||||
platformMouseInit(ctx->display.width, ctx->display.height);
|
platformMouseInit(ctx->display.width, ctx->display.height);
|
||||||
ctx->mouseX = ctx->display.width / 2;
|
ctx->hasMouseWheel = platformMouseWheelInit();
|
||||||
ctx->mouseY = ctx->display.height / 2;
|
ctx->mouseX = ctx->display.width / 2;
|
||||||
ctx->prevMouseX = ctx->mouseX;
|
ctx->mouseY = ctx->display.height / 2;
|
||||||
ctx->prevMouseY = ctx->mouseY;
|
ctx->prevMouseX = ctx->mouseX;
|
||||||
|
ctx->prevMouseY = ctx->mouseY;
|
||||||
|
|
||||||
ctx->running = true;
|
ctx->running = true;
|
||||||
ctx->lastIconClickId = -1;
|
ctx->lastIconClickId = -1;
|
||||||
|
|
@ -3367,6 +3401,7 @@ static void pollMouse(AppContextT *ctx) {
|
||||||
ctx->mouseX = mx;
|
ctx->mouseX = mx;
|
||||||
ctx->mouseY = my;
|
ctx->mouseY = my;
|
||||||
ctx->mouseButtons = buttons;
|
ctx->mouseButtons = buttons;
|
||||||
|
ctx->mouseWheel = platformMouseWheelPoll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ typedef struct AppContextT {
|
||||||
int32_t mouseX;
|
int32_t mouseX;
|
||||||
int32_t mouseY;
|
int32_t mouseY;
|
||||||
int32_t mouseButtons;
|
int32_t mouseButtons;
|
||||||
|
int32_t mouseWheel; // wheel delta this frame (positive=down, negative=up)
|
||||||
|
bool hasMouseWheel; // true if CuteMouse Wheel API detected
|
||||||
int32_t keyModifiers; // current BIOS shift state (KEY_MOD_xxx)
|
int32_t keyModifiers; // current BIOS shift state (KEY_MOD_xxx)
|
||||||
// Previous-frame mouse state for edge detection (button press/release
|
// Previous-frame mouse state for edge detection (button press/release
|
||||||
// transitions and delta-based cursor movement).
|
// transitions and delta-based cursor movement).
|
||||||
|
|
|
||||||
|
|
@ -553,6 +553,9 @@ typedef struct {
|
||||||
#define MOUSE_RIGHT 2
|
#define MOUSE_RIGHT 2
|
||||||
#define MOUSE_MIDDLE 4
|
#define MOUSE_MIDDLE 4
|
||||||
|
|
||||||
|
// Scrollbar lines to scroll per mouse wheel notch
|
||||||
|
#define MOUSE_WHEEL_STEP 3
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Mouse cursor
|
// Mouse cursor
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,18 @@ void platformMouseInit(int32_t screenW, int32_t screenH);
|
||||||
// to detect press/release edges.
|
// to detect press/release edges.
|
||||||
void platformMousePoll(int32_t *mx, int32_t *my, int32_t *buttons);
|
void platformMousePoll(int32_t *mx, int32_t *my, int32_t *buttons);
|
||||||
|
|
||||||
|
// Detect and activate mouse wheel support. Returns true if the mouse
|
||||||
|
// driver supports the CuteMouse Wheel API (INT 33h AX=0011h). This
|
||||||
|
// call also activates wheel reporting — after it returns true, function
|
||||||
|
// 03h will return wheel delta in BH. Must be called after platformMouseInit.
|
||||||
|
bool platformMouseWheelInit(void);
|
||||||
|
|
||||||
|
// Read the accumulated wheel delta since the last call. Positive = scroll
|
||||||
|
// down, negative = scroll up. Returns 0 if no wheel movement or if wheel
|
||||||
|
// is not supported. The delta is cleared on each read (accumulated by the
|
||||||
|
// driver between polls).
|
||||||
|
int32_t platformMouseWheelPoll(void);
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Input — Keyboard
|
// Input — Keyboard
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
|
||||||
|
|
@ -686,6 +686,13 @@ void platformMouseInit(int32_t screenW, int32_t screenH) {
|
||||||
// on every mickeyed movement, which is wasteful when we only sample
|
// on every mickeyed movement, which is wasteful when we only sample
|
||||||
// once per frame anyway.
|
// once per frame anyway.
|
||||||
|
|
||||||
|
// Wheel state: detected by platformMouseWheelInit, read by platformMousePoll.
|
||||||
|
// The wheel delta is extracted from function 03h BH in the same INT call that
|
||||||
|
// reads position and buttons, avoiding a double call that would clear the
|
||||||
|
// accumulated counter.
|
||||||
|
static bool sHasMouseWheel = false;
|
||||||
|
static int32_t sLastWheelDelta = 0;
|
||||||
|
|
||||||
void platformMousePoll(int32_t *mx, int32_t *my, int32_t *buttons) {
|
void platformMousePoll(int32_t *mx, int32_t *my, int32_t *buttons) {
|
||||||
__dpmi_regs r;
|
__dpmi_regs r;
|
||||||
|
|
||||||
|
|
@ -695,7 +702,49 @@ void platformMousePoll(int32_t *mx, int32_t *my, int32_t *buttons) {
|
||||||
|
|
||||||
*mx = r.x.cx;
|
*mx = r.x.cx;
|
||||||
*my = r.x.dx;
|
*my = r.x.dx;
|
||||||
*buttons = r.x.bx;
|
*buttons = r.x.bx & 0x07; // BL only: bits 0-2 = left/right/middle
|
||||||
|
|
||||||
|
// BH = signed 8-bit wheel counter (cleared on read by the driver).
|
||||||
|
// Only meaningful if the wheel API was activated via platformMouseWheelInit.
|
||||||
|
if (sHasMouseWheel) {
|
||||||
|
sLastWheelDelta = (int32_t)(int8_t)(r.x.bx >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// platformMouseWheelInit
|
||||||
|
// ============================================================
|
||||||
|
//
|
||||||
|
// Detects and activates the CuteMouse Wheel API 1.0 (INT 33h AX=0011h).
|
||||||
|
// The driver returns AX=574Dh ('WM') if supported, with CX bit 0 set if
|
||||||
|
// a wheel is physically present. Calling this function also switches the
|
||||||
|
// driver from "wheelkey" mode (faking keypresses) to real wheel reporting
|
||||||
|
// via function 03h BH. Must be called after platformMouseInit.
|
||||||
|
|
||||||
|
bool platformMouseWheelInit(void) {
|
||||||
|
__dpmi_regs r;
|
||||||
|
|
||||||
|
memset(&r, 0, sizeof(r));
|
||||||
|
r.x.ax = 0x0011;
|
||||||
|
__dpmi_int(0x33, &r);
|
||||||
|
|
||||||
|
// 0x574D = 'WM' (Wheel Mouse) magic signature
|
||||||
|
sHasMouseWheel = (r.x.ax == 0x574D) && (r.x.cx & 0x0001);
|
||||||
|
return sHasMouseWheel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// platformMouseWheelPoll
|
||||||
|
// ============================================================
|
||||||
|
//
|
||||||
|
// Returns the wheel delta captured by the last platformMousePoll call.
|
||||||
|
// Positive = scroll down, negative = scroll up. Returns 0 if no wheel
|
||||||
|
// movement or if the wheel is not supported.
|
||||||
|
|
||||||
|
int32_t platformMouseWheelPoll(void) {
|
||||||
|
return sLastWheelDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue