aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--int16kbd.h4
-rw-r--r--int33.h19
-rw-r--r--mousetsr.c13
-rw-r--r--mousetsr.h2
-rw-r--r--mousew16.c76
-rw-r--r--mousmain.c8
-rw-r--r--moustest.c838
7 files changed, 707 insertions, 253 deletions
diff --git a/int16kbd.h b/int16kbd.h
index 45db8ef..3b2c860 100644
--- a/int16kbd.h
+++ b/int16kbd.h
@@ -1,11 +1,11 @@
#ifndef INT16KBD_H
#define INT16KBD_H
-static bool int16_store_keystroke(uint16_t scancode);
+static bool int16_store_keystroke(uint8_t scancode, uint8_t character);
#pragma aux int16_store_keystroke = \
"mov ah, 0x05" \
"int 0x16" \
- __parm [cx] \
+ __parm [ch] [cl] \
__value [al] \
__modify [ax]
diff --git a/int33.h b/int33.h
index 2755379..2c34a6d 100644
--- a/int33.h
+++ b/int33.h
@@ -265,6 +265,13 @@ static void int33_set_mouse_speed(int16_t x, int16_t y);
__parm [cx] [dx] \
__modify [ax]
+static void int33_set_speed_double_threshold(uint16_t th);
+#pragma aux int33_set_speed_double_threshold = \
+ "mov ax, 0x13" \
+ "int 0x33" \
+ __parm [dx] \
+ __modify [ax]
+
static uint16_t int33_get_mouse_status_size(void);
#pragma aux int33_get_mouse_status_size = \
"mov bx, 0" \
@@ -294,6 +301,18 @@ static void int33_set_sensitivity(uint16_t sens_x, uint16_t sens_y, uint16_t dou
__parm [bx] [cx] [dx] \
__modify [ax]
+static void int33_get_sensitivity(uint16_t *sens_x, uint16_t *sens_y, uint16_t *double_speed_threshold);
+#pragma aux int33_get_sensitivity = \
+ "push dx" \
+ "mov ax, 0x1B" \
+ "int 0x33" \
+ "mov [si], bx" \
+ "mov [di], cx" \
+ "pop bx" \
+ "mov [bx], dx" \
+ __parm [si] [di] [dx] \
+ __modify [ax]
+
static uint16_t int33_get_driver_version(void);
#pragma aux int33_get_driver_version = \
"mov bx, 0" \
diff --git a/mousetsr.c b/mousetsr.c
index f9451b3..2913efd 100644
--- a/mousetsr.c
+++ b/mousetsr.c
@@ -665,11 +665,11 @@ static void handle_mouse_event(uint16_t buttons, bool absolute, int x, int y, ch
// Emulate keystrokes on (vertical) wheel movement
if (z < 0 && data.wheel_up_key) {
for (; z < 0; z++) {
- int16_store_keystroke(data.wheel_up_key);
+ int16_store_keystroke(data.wheel_up_key, 0);
}
} else if (z > 0 && data.wheel_down_key) {
for (; z > 0; z--) {
- int16_store_keystroke(data.wheel_down_key);
+ int16_store_keystroke(data.wheel_down_key, 0);
}
}
} else {
@@ -766,10 +766,13 @@ static void handle_ps2_packet(void)
if (data.ps2_packet[3] & PS2M_IMEX_VERTICAL_SCROLL) {
// Vertical scrolling, with 6 bits of precision.
z = sign_extend(data.ps2_packet[3], 6);
+ // Assume 4th/5th buttons are still pressed if they were
+ buttons |= data.buttons & (INT33_BUTTON_MASK_4TH|INT33_BUTTON_MASK_5TH);
} else if (data.ps2_packet[3] & PS2M_IMEX_HORIZONTAL_SCROLL) {
// Horizontal scrolling, with 6 bits of precision.
- z = -sign_extend(data.ps2_packet[3], 6);
+ z = sign_extend(data.ps2_packet[3], 6);
wheeln = 1;
+ buttons |= data.buttons & (INT33_BUTTON_MASK_4TH|INT33_BUTTON_MASK_5TH);
} else {
// Or 2 extra buttons (4, 5)
if (data.ps2_packet[3] & PS2M_IMEX_BUTTON_4) {
@@ -1126,8 +1129,8 @@ static void reset_mouse_settings()
static void reset_mouse_state()
{
int i;
- data.pos.x = data.min.x;
- data.pos.y = data.min.y;
+ data.pos.x = data.min.x + (data.max.x - data.min.x) / 2;
+ data.pos.y = data.min.y + (data.max.y - data.min.y) / 2;
data.pos_frac.x = 0;
data.pos_frac.y = 0;
data.delta.x = 0;
diff --git a/mousetsr.h b/mousetsr.h
index 5625ae1..05b2f24 100644
--- a/mousetsr.h
+++ b/mousetsr.h
@@ -102,7 +102,7 @@ typedef struct tsrdata {
/** Whether to enable & use wheel mouse. */
bool usewheel;
/** Key (scancode) to generate on wheel scroll up/down, or 0 for none. */
- uint16_t wheel_up_key, wheel_down_key;
+ uint8_t wheel_up_key, wheel_down_key;
#endif
// Video settings
diff --git a/mousew16.c b/mousew16.c
index 78f2315..2d539e3 100644
--- a/mousew16.c
+++ b/mousew16.c
@@ -18,6 +18,7 @@
*/
#include <string.h>
+#include <stdlib.h>
#include <windows.h>
#include "utils.h"
@@ -97,9 +98,9 @@ static void send_event(unsigned short Status, short deltaX, short deltaY, short
#if USE_WHEEL
typedef struct {
- /** Input: whether to find vertical scrollbars. */
- BOOL vertical;
- /** Output: found scrollbar handle, or 0. */
+ /** Input param: select scrollbars of either SBS_VERT or SBS_HORZ. */
+ WORD style;
+ /** Output param: found scrollbar handle, or 0 if none found. */
HWND scrollbar;
} FINDSCROLLBARDATA, FAR * LPFINDSCROLLBARDATA;
@@ -137,10 +138,11 @@ static BOOL CALLBACK __loadds find_scrollbar_enum_proc(HWND hWnd, LPARAM lParam)
if (_fstrcmp(buffer, "ScrollBar") == 0) {
LONG style = userapi.GetWindowLong(hWnd, GWL_STYLE);
- if (data->vertical && (style & SBS_VERT)) {
- data->scrollbar = hWnd;
- return ENUM_CHILD_WINDOW_STOP;
- } else if (!data->vertical && !(style & SBS_VERT)) {
+#if TRACE_WHEEL
+ dprintf(DPREFIX "hWnd=0x%x is ScrollBar style=0x%lx\n", hWnd, style);
+#endif
+
+ if (data->style == (style & (SBS_HORZ|SBS_VERT))) {
data->scrollbar = hWnd;
return ENUM_CHILD_WINDOW_STOP;
}
@@ -149,39 +151,45 @@ static BOOL CALLBACK __loadds find_scrollbar_enum_proc(HWND hWnd, LPARAM lParam)
return ENUM_CHILD_WINDOW_CONTINUE;
}
-/** Finds a scrollbar in the given window. */
-static HWND find_scrollbar(HWND hWnd, BOOL vertical)
+/** Finds a scrollbar in the given window with the given style.
+ * @param style either SBS_HORZ or SBS_VERT. */
+static HWND find_scrollbar(HWND hWnd, WORD style)
{
FINDSCROLLBARDATA data;
- data.vertical = vertical;
+ data.style = style;
data.scrollbar = 0;
#if TRACE_WHEEL
- dprintf(DPREFIX "find scrollbar on hWnd=0x%x...\n", hWnd);
+ dprintf(DPREFIX "find scrollbar on hWnd=0x%x with style=0x%x...\n", hWnd, style);
#endif
userapi.EnumChildWindows(hWnd, find_scrollbar_enum_proc, (LONG) (LPVOID) &data);
+#if TRACE_WHEEL
+ dprintf(DPREFIX " found scrollbar 0x%x\n", data.scrollbar);
+#endif
+
return data.scrollbar;
}
/** Send scrolling messages to given window.
* @param hWnd window to scroll.
- * @param vertical true if vertical, false if horizontal.
+ * @param msg either WM_HSCROLL or WM_VSCROLL
+ * @param horizontal true if horizontal, false if vertical movement.
* @param z number of lines to scroll.
* @param hScrollBar corresponding scrollbar handle.
*/
-static void post_scroll_msg(HWND hWnd, BOOL vertical, int z, HWND hScrollBar)
+static void post_scroll_msg(HWND hWnd, UINT msg, int z, HWND hScrollBar)
{
- UINT msg = vertical ? WM_VSCROLL : WM_HSCROLL;
- WPARAM wParam = z < 0 ? SB_LINEUP : SB_LINEDOWN;
+ WPARAM wParam = z < 0 ? SB_LINEUP : SB_LINEDOWN; // Same value as z < 0 ? SB_LINELEFT : SB_LINERIGHT
LPARAM lParam = MAKELPARAM(0, hScrollBar);
- UINT i, lines = (z < 0 ? -z : z);
+ UINT i, lines = abs(z);
- if (!vertical) lines *= WHEEL_SCROLL_LINES;
+ // Only vertical scroll gets multipled by speed factor
+ if (msg == WM_VSCROLL) lines *= WHEEL_SCROLL_LINES;
#if TRACE_WHEEL
- dprintf(DPREFIX "sending scroll msg to hWnd=0x%x from=0x%x vert=%d lines=%u\n", hWnd, hScrollBar, vertical, lines);
+ dprintf(DPREFIX "sending scroll msg 0x%x to hWnd=0x%x from=0x%x dir=%u lines=%u\n", msg, hWnd, hScrollBar, wParam, lines);
#endif
for (i = 0; i < lines; i++) {
@@ -191,13 +199,13 @@ static void post_scroll_msg(HWND hWnd, BOOL vertical, int z, HWND hScrollBar)
}
/** Send wheel scrolling events to the most likely candidate window. */
-static void send_wheel_movement(int8_t z, BOOL vertical)
+static void send_wheel_movement(int8_t z, BOOL horizontal)
{
POINT point;
HWND hWnd;
#if TRACE_WHEEL
- dprintf(DPREFIX "wheel=%d\n", z);
+ dprintf(DPREFIX "wheel=%d %s\n", z, horizontal ? "horiz" : "vert");
#endif
// TODO It's highly unlikely that we can call this many functions from
@@ -220,26 +228,26 @@ static void send_wheel_movement(int8_t z, BOOL vertical)
dprintf(DPREFIX "hWnd=0x%x style=0x%lx\n", hWnd, style);
#endif
- if (vertical) {
- // Check if this window is scrollable...
+ if (!horizontal) {
+ // Check if this window is vertically scrollable...
if (style & WS_VSCROLL) {
- post_scroll_msg(hWnd, TRUE, z, 0);
+ post_scroll_msg(hWnd, WM_VSCROLL, z, 0);
break;
} else if (style & WS_HSCROLL) {
- post_scroll_msg(hWnd, FALSE, z, 0);
+ post_scroll_msg(hWnd, WM_HSCROLL, z, 0);
break;
} else {
// Otherwise, let's see if we can find a vertical scroll bar in this window..
- HWND scrollbar = find_scrollbar(hWnd, TRUE);
+ HWND scrollbar = find_scrollbar(hWnd, SBS_VERT);
if (scrollbar) {
- post_scroll_msg(hWnd, TRUE, z, scrollbar);
+ post_scroll_msg(hWnd, WM_VSCROLL, z, scrollbar);
break;
}
- // Try a horizontal scrollbar second
- scrollbar = find_scrollbar(hWnd, FALSE);
+ // If no vertical scrollbar... try a horizontal scrollbar second
+ scrollbar = find_scrollbar(hWnd, SBS_HORZ);
if (scrollbar) {
- post_scroll_msg(hWnd, FALSE, z, scrollbar);
+ post_scroll_msg(hWnd, WM_HSCROLL, z, scrollbar);
break;
}
@@ -254,12 +262,12 @@ static void send_wheel_movement(int8_t z, BOOL vertical)
} else {
// Similar to above except we try only horizontal scrollbars
if (style & WS_HSCROLL) {
- post_scroll_msg(hWnd, FALSE, z, 0);
+ post_scroll_msg(hWnd, WM_HSCROLL, z, 0);
break;
} else {
- HWND scrollbar = find_scrollbar(hWnd, FALSE);
+ HWND scrollbar = find_scrollbar(hWnd, SBS_HORZ);
if (scrollbar) {
- post_scroll_msg(hWnd, FALSE, z, scrollbar);
+ post_scroll_msg(hWnd, WM_HSCROLL, z, scrollbar);
break;
}
@@ -303,9 +311,9 @@ static void FAR int33_mouse_callback(uint16_t events, uint16_t buttons, int16_t
if (flags.wheel && (events & INT33_EVENT_MASK_ANY_WHEEL_MOVEMENT)) {
// If wheel API is enabled, higher byte of buttons contains wheel movement
int8_t z = (buttons & 0xFF00) >> 8;
- BOOL vertical = !(events & INT33_EVENT_MASK_HORIZ_WHEEL_MOVEMENT);
+ BOOL horizontal = !!(events & INT33_EVENT_MASK_HORIZ_WHEEL_MOVEMENT);
if (z) {
- send_wheel_movement(z, vertical);
+ send_wheel_movement(z, horizontal);
}
}
#endif
diff --git a/mousmain.c b/mousmain.c
index e33b553..80ea1fb 100644
--- a/mousmain.c
+++ b/mousmain.c
@@ -79,12 +79,12 @@ static int set_wheel_key(LPTSRDATA data, const char *keyname)
}
if (keyname) {
if (stricmp(keyname, "updn") == 0) {
- data->wheel_up_key = 0x4800;
- data->wheel_down_key = 0x5000;
+ data->wheel_up_key = 0x48;
+ data->wheel_down_key = 0x50;
printf(_(1, 4, "Generate Up Arrow / Down Arrow key presses on wheel movement\n"));
} else if (stricmp(keyname, "pageupdn") == 0) {
- data->wheel_up_key = 0x4900;
- data->wheel_down_key = 0x5100;
+ data->wheel_up_key = 0x49;
+ data->wheel_down_key = 0x51;
printf(_(1, 5, "Generate PageUp / PageDown key presses on wheel movement\n"));
} else {
fprintf(stderr, _(3, 2, "Unknown key '%s'\n"), keyname);
diff --git a/moustest.c b/moustest.c
index 97e554b..5d43e54 100644
--- a/moustest.c
+++ b/moustest.c
@@ -2,173 +2,629 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <string.h>
#include <dos.h>
#include <conio.h>
#include <graph.h>
#include "int33.h"
+#include "int16kbd.h"
#include "utils.h"
#include "dlog.h"
#define DPREFIX "moustest: "
-bool exiting = false;
+enum T_COLOR {
+ T_BLACK = 0,
+ T_BLUE = 1,
+ T_GREEN = 2,
+ T_CYAN = 3,
+ T_RED = 4,
+ T_MAGENTA = 5,
+ T_BROWN = 6,
+ T_WHITE = 7,
+ T_BRIGHT = 8
+};
+
+bool main_exiting = false;
+
+/// Do not automatically reset the mouse driver
+bool args_no_reset = false;
+/// Do not query for wheel features
+bool args_no_wheel = false;
uint16_t driver_caps;
uint16_t num_buttons;
uint16_t num_wheels;
+struct mouseevent {
+ uint16_t events;
+ uint8_t buttons;
+ int16_t x;
+ int16_t y;
+ int8_t z;
+ int16_t delta_x;
+ int16_t delta_y;
+} lastmouseevent;
+
struct videoconfig vidconf;
+bool vidconf_is_graphics, vidconf_is_color;
+
+struct textsettings txtconf;
short ctexttop, ctextbot, ctextleft, ctextright;
struct rccoord ctextpos;
-const short ctextcolor = 7;
+const short ctextcolor = T_WHITE;
const long ctextbg = _BLACK;
-void gui_printf(const char *format, ...)
+typedef enum gui_palette {
+ GUI_COLOR_CONSOLE,
+ GUI_COLOR_BAR,
+ GUI_COLOR_WINDOW,
+ GUI_COLOR_LIST,
+ GUI_COLOR_LIST_SEL,
+
+ GUI_COLOR_COUNT
+} gui_color;
+long gui_bg_color[GUI_COLOR_COUNT];
+int gui_text_color[GUI_COLOR_COUNT];
+
+void gui_print(gui_color color, const char *str)
+{
+ if (vidconf_is_graphics) {
+ const int char_width = vidconf.numxpixels / vidconf.numtextcols;
+ const int char_height = vidconf.numypixels / vidconf.numtextrows;
+ const int text_chars = strlen(str);
+ const int text_width = text_chars * char_width;
+ const int text_height = char_height; // No multiline support.
+ struct rccoord textpos = _gettextposition();
+ const int text_x = char_width * (textpos.col - 1);
+ const int text_y = char_height * (textpos.row - 1);
+
+ _setcolor(gui_bg_color[color]);
+ _rectangle(_GFILLINTERIOR, text_x, text_y, text_x + text_width, text_y + text_height);
+
+ _setcolor(gui_text_color[color]);
+ _moveto(text_x, text_y);
+ _outgtext((char*) str);
+
+ textpos.col += text_chars;
+ _settextposition(textpos.row, textpos.col);
+ } else {
+ _settextcolor(gui_text_color[color]);
+ _setbkcolor(gui_bg_color[color]);
+ _outtext((char*) str);
+ }
+}
+
+void gui_printf(gui_color color, const char *format, ...)
{
- va_list arglist;
- char buffer[120];
+ va_list arglist;
+ char buffer[120];
- va_start(arglist, format);
- vsprintf(buffer, format, arglist);
- va_end(arglist);
+ va_start(arglist, format);
+ vsprintf(buffer, format, arglist);
+ va_end(arglist);
- _outtext(buffer);
+ gui_print(color, buffer);
}
-void gui_draw_textwindow(int top, int left, int bottom, int right, grcolor fg, long bg)
+void gui_draw_textrectangle(short top, short left, short bottom, short right, gui_color color)
{
- _settextwindow(top, left, bottom, right);
- _setbkcolor(bg);
- _settextcolor(fg);
- _clearscreen(_GWINDOW);
+ const short char_width = vidconf.numxpixels / vidconf.numtextcols;
+ const short char_height = vidconf.numypixels / vidconf.numtextrows;
+ short x1 = (left - 1) * char_width;
+ short y1 = (top - 1) * char_height;
+ short x2 = right * char_width;
+ short y2 = bottom * char_height;
+
+ _setviewport(x1, y1, x2, y2);
+ _setcolor(gui_bg_color[color]);
+ _rectangle(_GFILLINTERIOR, 0, 0, x2 - x1, y2 - y1);
+}
+
+void gui_draw_textwindow(int top, int left, int bottom, int right, gui_color color)
+{
+ _settextwindow(top, left, bottom, right);
+ _settextcolor(gui_text_color[color]); // Not really required here
+ if (vidconf_is_graphics) {
+ gui_draw_textrectangle(top, left, bottom, right, color);
+ } else {
+ _setbkcolor(gui_bg_color[color]);
+ _clearscreen(_GWINDOW);
+ }
}
void gui_draw_title()
{
- const int cols = vidconf.numtextcols;
+ const int cols = vidconf.numtextcols;
- gui_draw_textwindow(1, 1, 1, cols, 0, _WHITE);
- _outtext("MOUSTEST ESC to exit, 'r' reset, 's' show, 'h' hide");
+ gui_draw_textwindow(1, 1, 1, cols, GUI_COLOR_BAR);
+ gui_print(GUI_COLOR_BAR, "MOUSTEST ESC to exit, 'm' mode, 'r' reset, 's' show, 'h' hide");
}
void gui_draw_status()
{
- const int statusrow = vidconf.numtextrows;
- const int cols = vidconf.numtextcols;
+ const int statusrow = vidconf.numtextrows;
+ const int cols = vidconf.numtextcols;
- gui_draw_textwindow(statusrow, 1, statusrow, cols, 0, _WHITE);
+ gui_draw_textwindow(statusrow, 1, statusrow, cols, GUI_COLOR_BAR);
}
void gui_draw_console()
{
- const int rows = vidconf.numtextrows, cols = vidconf.numtextcols;
- ctexttop = 3;
- ctextbot = rows - 2;
- ctextleft = 1;
- ctextright = cols;
- gui_draw_textwindow(ctexttop, ctextleft, ctextbot, ctextright,
- ctextcolor, ctextbg);
+ const int rows = vidconf.numtextrows, cols = vidconf.numtextcols;
+ ctexttop = 3;
+ ctextbot = rows - 2;
+ ctextleft = 1;
+ ctextright = cols;
+ gui_draw_textwindow(ctexttop, ctextleft, ctextbot, ctextright, GUI_COLOR_CONSOLE);
+
+ ctextpos.row = 1;
+ ctextpos.col = 1;
}
void gui_init()
{
- _setbkcolor(_BLACK);
- _clearscreen(_GCLEARSCREEN);
+ _getvideoconfig(&vidconf);
+ _gettextsettings(&txtconf);
+
+ _clearscreen(_GCLEARSCREEN);
+
+ switch (vidconf.mode) {
+ case _TEXTBW40:
+ case _TEXTC40:
+ case _TEXTBW80:
+ case _TEXTC80:
+ case _TEXTMONO:
+ vidconf_is_graphics = false;
+ break;
+ default:
+ vidconf_is_graphics = true;
+ break;
+ }
+
+ switch (vidconf.mode) {
+ case _TEXTBW40:
+ case _TEXTBW80:
+ case _TEXTMONO:
+ case _HERCMONO:
+ case _MRESNOCOLOR:
+ case _ERESNOCOLOR:
+ case _VRES2COLOR:
+ vidconf_is_color = false;
+ break;
+ default:
+ vidconf_is_color = true;
+ break;
+ }
+
+ if (vidconf_is_graphics) {
+ if (vidconf_is_color) {
+ _remappalette(0, _BLACK);
+ _remappalette(1, _CYAN);
+ _remappalette(2, _BLUE);
+ _remappalette(3, _WHITE);
+ gui_bg_color[GUI_COLOR_CONSOLE] = 0;
+ gui_bg_color[GUI_COLOR_BAR] = 3;
+ gui_bg_color[GUI_COLOR_WINDOW] = 2;
+ gui_bg_color[GUI_COLOR_LIST] = 1;
+ gui_bg_color[GUI_COLOR_LIST_SEL] = 3;
+ gui_text_color[GUI_COLOR_CONSOLE] = 3;
+ gui_text_color[GUI_COLOR_BAR] = 0;
+ gui_text_color[GUI_COLOR_WINDOW] = 3;
+ gui_text_color[GUI_COLOR_LIST] = 0;
+ gui_text_color[GUI_COLOR_LIST_SEL] = 0;
+ } else {
+ gui_bg_color[GUI_COLOR_CONSOLE] = T_BLACK;
+ gui_bg_color[GUI_COLOR_BAR] = T_WHITE;
+ gui_bg_color[GUI_COLOR_WINDOW] = T_WHITE;
+ gui_bg_color[GUI_COLOR_LIST] = T_WHITE;
+ gui_bg_color[GUI_COLOR_LIST_SEL] = T_BLACK;
+ gui_text_color[GUI_COLOR_CONSOLE] = T_WHITE;
+ gui_text_color[GUI_COLOR_BAR] = T_BLACK;
+ gui_text_color[GUI_COLOR_WINDOW] = T_BLACK;
+ gui_text_color[GUI_COLOR_LIST] = T_BLACK;
+ gui_text_color[GUI_COLOR_LIST_SEL] = T_WHITE | T_BRIGHT;
+ }
+ } else {
+ if (vidconf_is_color) {
+ gui_bg_color[GUI_COLOR_CONSOLE] = T_BLACK;
+ gui_bg_color[GUI_COLOR_BAR] = T_WHITE;
+ gui_bg_color[GUI_COLOR_WINDOW] = T_BLUE;
+ gui_bg_color[GUI_COLOR_LIST] = T_CYAN;
+ gui_bg_color[GUI_COLOR_LIST_SEL] = T_WHITE;
+ gui_text_color[GUI_COLOR_CONSOLE] = T_WHITE;
+ gui_text_color[GUI_COLOR_BAR] = T_BLACK;
+ gui_text_color[GUI_COLOR_WINDOW] = T_WHITE;
+ gui_text_color[GUI_COLOR_LIST] = T_BLACK;
+ gui_text_color[GUI_COLOR_LIST_SEL] = T_BLACK;
+ } else {
+ gui_bg_color[GUI_COLOR_CONSOLE] = T_BLACK;
+ gui_bg_color[GUI_COLOR_BAR] = T_WHITE;
+ gui_bg_color[GUI_COLOR_WINDOW] = T_WHITE;
+ gui_bg_color[GUI_COLOR_LIST] = T_WHITE;
+ gui_bg_color[GUI_COLOR_LIST_SEL] = T_BLACK;
+ gui_text_color[GUI_COLOR_CONSOLE] = T_WHITE;
+ gui_text_color[GUI_COLOR_BAR] = T_BLACK;
+ gui_text_color[GUI_COLOR_WINDOW] = T_BLACK;
+ gui_text_color[GUI_COLOR_LIST] = T_BLACK;
+ gui_text_color[GUI_COLOR_LIST_SEL] = T_WHITE | T_BRIGHT;
+ }
+ }
+
+ _displaycursor(_GCURSOROFF);
+ _wrapon(_GWRAPOFF);
- gui_draw_title();
+ gui_draw_title();
- gui_draw_status();
+ gui_draw_status();
- gui_draw_console();
+ gui_draw_console();
}
void console_enter()
{
- _settextwindow(ctexttop, ctextleft, ctextbot, ctextright);
- _settextposition(ctextpos.row, ctextpos.col);
- _setbkcolor(ctextbg);
- _settextcolor(ctextcolor);
+ _settextwindow(ctexttop, ctextleft, ctextbot, ctextright);
+ _settextposition(ctextpos.row, ctextpos.col);
+ if (!vidconf_is_graphics) _setbkcolor(ctextbg);
+ _settextcolor(ctextcolor);
+ _wrapon(_GWRAPON);
}
void console_leave()
{
- ctextpos = _gettextposition();
+ ctextpos = _gettextposition();
+ _wrapon(_GWRAPOFF);
}
void console_print(char __far *str)
{
- _disable();
- int33_hide_cursor();
- console_enter();
- _outtext(str);
- console_leave();
- int33_show_cursor();
- _enable();
+ _disable();
+ int33_hide_cursor();
+ console_enter();
+ _outtext(str);
+ console_leave();
+ int33_show_cursor();
+ _enable();
}
void console_printf(const char *format, ...)
{
- va_list arglist;
- char buffer[120];
+ va_list arglist;
+ char buffer[120];
+
+ va_start(arglist, format);
+ vsprintf(buffer, format, arglist);
+ va_end(arglist);
+
+ console_print(buffer);
+}
+
+struct modeentry {
+ char *name;
+ int modenum;
+} modelist[] = {
+ {"TEXTBW40", _TEXTBW40},
+ {"TEXTC40", _TEXTC40},
+ {"TEXTBW80", _TEXTBW80},
+ {"TEXTC80", _TEXTC80},
+ {"MRES4COLOR", _MRES4COLOR},
+ {"MRESNOCOLOR", _MRESNOCOLOR},
+ {"HRESBW", _HRESBW},
+ {"TEXTMONO", _TEXTMONO},
+ {"HERCMONO", _HERCMONO},
+ {"MRES16COLOR", _MRES16COLOR},
+ {"HRES16COLOR", _HRES16COLOR},
+ {"ERESNOCOLOR", _ERESNOCOLOR},
+ {"ERESCOLOR", _ERESCOLOR},
+ {"VRES2COLOR", _VRES2COLOR},
+ {"VRES16COLOR", _VRES16COLOR},
+ {"MRES256COLOR", _MRES256COLOR},
+ {"URES256COLOR", _URES256COLOR},
+ {"VRES256COLOR", _VRES256COLOR},
+ {"SVRES16COLOR", _SVRES16COLOR},
+ {"SVRES256COLOR", _SVRES256COLOR},
+ {"XRES16COLOR", _XRES16COLOR},
+ {"XRES256COLOR", _XRES256COLOR},
+};
+const int num_modeentries = sizeof(modelist)/sizeof(struct modeentry);
+
+struct {
+ int first_entry;
+ int sel_entry;
+ int list_rows;
+} mlistui;
+
+void modelist_switch_to(int entry)
+{
+ struct modeentry *mode = &modelist[entry];
+
+ dprintf(DPREFIX "switching to mode %s %d\n", mode->name, mode->modenum);
+
+ _setvideomode(mode->modenum);
+}
+
+int modelist_get_current()
+{
+ int i;
+
+ for (i = 0; i < num_modeentries; ++i) {
+ if (modelist[i].modenum == vidconf.mode) {
+ return i;
+ }
+ }
+
+ return 0;
+}
+
+void __far modelist_mouse_callback(uint16_t events, uint16_t buttons, int16_t x, int16_t y, int16_t delta_x, int16_t delta_y)
+#pragma aux (INT33_CB) mouse_callback
+{
+ int8_t z = buttons >> 8;
+
+ (void) delta_x;
+ (void) delta_y;
+
+#if 1
+ dprintf(DPREFIX "modelist_mouse_callback events=0x%x buttons=0x%x x=%d y=%d dx=%d dy=%d\n",
+ events, buttons, x, y, delta_x, delta_y);
+#endif
+}
+
+void modelist_draw_window()
+{
+ const int list_width = 23;
+ const int rows = vidconf.numtextrows, cols = vidconf.numtextcols;
+ int i;
+
+ int33_hide_cursor();
+
+ gui_draw_textwindow(3, 4, rows - 3, list_width + 1, GUI_COLOR_WINDOW);
+ gui_print(GUI_COLOR_WINDOW, " Choose video mode: ");
+
+ int33_show_cursor();
+}
+
+void modelist_draw_list()
+{
+ const int list_width = 23;
+ const int rows = vidconf.numtextrows, cols = vidconf.numtextcols;
+ int i;
+
+ int33_hide_cursor();
+
+ gui_draw_textwindow(5, 5, 5 + mlistui.list_rows - 1, list_width, GUI_COLOR_LIST);
+
+ for (i = mlistui.first_entry; i < MIN(num_modeentries, mlistui.first_entry + mlistui.list_rows); ++i) {
+ const bool selected = i == mlistui.sel_entry;
+ _settextposition(1 + (i - mlistui.first_entry), 1);
+ gui_print(selected ? GUI_COLOR_LIST_SEL : GUI_COLOR_LIST, modelist[i].name);
+ }
+
+ if (mlistui.first_entry > 0) {
+ _settextposition(1, list_width);
+ gui_print(GUI_COLOR_LIST, "\x18");
+ }
+ if (mlistui.first_entry + mlistui.list_rows < num_modeentries) {
+ _settextposition(1 + mlistui.list_rows, list_width);
+ gui_print(GUI_COLOR_LIST, "\x19");
+ }
+
+ int33_show_cursor();
+}
+
+bool modelist_sel_entry(int offset)
+{
+ int new_sel_entry = mlistui.sel_entry + offset;
+ if (new_sel_entry < 0) {
+ new_sel_entry = 0;
+ } else if (new_sel_entry >= num_modeentries) {
+ new_sel_entry = num_modeentries - 1;
+ }
+ if (new_sel_entry != mlistui.sel_entry) {
+ mlistui.sel_entry = new_sel_entry;
+ if (mlistui.sel_entry < mlistui.first_entry) {
+ mlistui.first_entry = mlistui.sel_entry;
+ } else if (mlistui.sel_entry >= mlistui.first_entry + mlistui.list_rows) {
+ mlistui.first_entry = 1 + mlistui.sel_entry - mlistui.list_rows;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
- va_start(arglist, format);
- vsprintf(buffer, format, arglist);
- va_end(arglist);
+void modelist_show_modal()
+{
+ bool exiting = false;
+
+ // TODO Mouse support here :)
+ //int33_set_event_handler(INT33_EVENT_MASK_ALL, modelist_mouse_callback);
+ int33_set_event_handler(0, NULL);
+ int33_hide_cursor();
+
+ mlistui.first_entry = 0;
+ mlistui.sel_entry = 0;
+ mlistui.list_rows = vidconf.numtextrows - 8;
+
+ modelist_sel_entry(modelist_get_current());
+
+ modelist_draw_window();
+ modelist_draw_list();
+
+ while (!exiting) {
+ int c = getch();
+
+ dprintf(DPREFIX "modelist getch returns %d\n", c);
+
+ switch (c) {
+ case 27: // Escape
+ exiting = true;
+ break;
+ case '\r':
+ modelist_switch_to(mlistui.sel_entry);
+ exiting = true;
+ break;
+ case 0:
+ c = getch();
+
+ dprintf(DPREFIX "modelist getch returns extended %d\n", c);
+
+ switch (c) {
+ case 72: // Arrow-Up
+ if (modelist_sel_entry(-1)) {
+ modelist_draw_list();
+ }
+ break;
+ case 80: // Arrow-Down
+ if (modelist_sel_entry(+1)) {
+ modelist_draw_list();
+ }
+ break;
+ case 73: // Page-Up
+ if (modelist_sel_entry(-mlistui.list_rows)) {
+ modelist_draw_list();
+ }
+ break;
+ case 81: // Page-Down
+ if (modelist_sel_entry(+mlistui.list_rows)) {
+ modelist_draw_list();
+ }
+ break;
+ }
+ break;
+ }
+ }
- console_print(buffer);
+ int33_set_event_handler(0, NULL);
}
/** Called by the int33 mouse driver. */
void __far mouse_callback(uint16_t events, uint16_t buttons, int16_t x, int16_t y, int16_t delta_x, int16_t delta_y)
#pragma aux (INT33_CB) mouse_callback
{
- int8_t z = buttons >> 8;
+ _disable();
#if 1
dprintf(DPREFIX "mouse_callback events=0x%x buttons=0x%x x=%d y=%d dx=%d dy=%d\n",
events, buttons, x, y, delta_x, delta_y);
#endif
- // Update the status bar
- _disable();
- gui_draw_status();
-
- gui_printf(" %3s %4u , %4u |",
- events & INT33_EVENT_MASK_ABSOLUTE ? "ABS" : "REL", x, y);
-
- if (num_buttons <= 2) {
- gui_printf(" [%5s] [%5s] ",
- buttons & INT33_BUTTON_MASK_LEFT ? "LEFT" : "",
- buttons & INT33_BUTTON_MASK_RIGHT ? "RIGHT" : "");
- } else {
- gui_printf(" [%5s] [%5s] [%5s] ",
- buttons & INT33_BUTTON_MASK_LEFT ? "LEFT" : "",
- buttons & INT33_BUTTON_MASK_CENTER ? "MID " : "",
- buttons & INT33_BUTTON_MASK_RIGHT ? "RIGHT" : "");
- if (num_buttons > 3) {
- gui_printf(" [%3s] [%3s] ",
- buttons & INT33_BUTTON_MASK_4TH ? "4TH" : "",
- buttons & INT33_BUTTON_MASK_5TH ? "5TH" : "");
- }
- }
-
- if (num_wheels > 0) {
- char c = ' ';
- if (events & INT33_EVENT_MASK_WHEEL_MOVEMENT) {
- c = z > 0 ? 0x19 : 0x18;
- } else if (events & INT33_EVENT_MASK_HORIZ_WHEEL_MOVEMENT) {
- c = z > 0 ? 0x1A : 0x1B;
- }
- gui_printf("| %c", c);
- }
-
- _settextposition(1, 1);
- _enable();
-
- // Log the events
+ lastmouseevent.events = events;
+ lastmouseevent.buttons = buttons & 0xFFU;
+ lastmouseevent.x = x;
+ lastmouseevent.y = y;
+ lastmouseevent.z = buttons >> 8;
+ lastmouseevent.delta_x = delta_x;
+ lastmouseevent.delta_y = delta_y;
+
+ // Doing this to wake up getch()
+ int16_store_keystroke(1, 0);
+
+ _enable();
+}
+
+bool mouse_reset()
+{
+ if (!int33_reset_get_buttons(&num_buttons)) {
+ puts("Mouse not installed");
+ return false;
+ }
+
+ if (!args_no_wheel) {
+ driver_caps = int33_get_capabilities();
+ num_wheels = 0;
+ if (driver_caps & INT33_CAPABILITY_WHEEL_API) {
+ num_wheels = 1;
+ }
+ if (driver_caps & INT33_CAPABILITY_WHEEL2_API) {
+ num_wheels = 2;
+ }
+ }
+
+ int33_set_event_handler(INT33_EVENT_MASK_ALL, mouse_callback);
+
+ return true;
+}
+
+void mouse_report()
+{
+ const char __far *fstr;
+
+ if (driver_caps != 0) {
+ console_printf("Driver capabilities bits: 0x%x %s %s\n", driver_caps,
+ driver_caps & INT33_CAPABILITY_WHEEL_API ? "<wheel API>" : "",
+ driver_caps & INT33_CAPABILITY_WHEEL2_API ? "<wheel API v2>" : "");
+ }
+
+ fstr = int33_get_version_string();
+ if (fstr) {
+ console_printf("Driver version string: %Fs\n", fstr);
+ }
+
+ console_printf("Number of buttons: %u\n", num_buttons);
+ console_printf("Number of wheels: %u\n", num_wheels);
+}
+
+void mouse_quit()
+{
+ int33_reset();
+}
+
+void mouse_debug()
+{
+ // Add test code here
+}
+
+void status_report_last_event()
+{
+ uint16_t events = lastmouseevent.events;
+ uint8_t buttons = lastmouseevent.buttons;
+ int x = lastmouseevent.x;
+ int y = lastmouseevent.y;
+ int z = lastmouseevent.z;
+ lastmouseevent.events = 0;
+
+ if (!events) {
+ return;
+ }
+
+ // Update the status bar message
+ gui_draw_status();
+
+ gui_printf(GUI_COLOR_BAR, " %3s %4u , %4u |",
+ events & INT33_EVENT_MASK_ABSOLUTE ? "ABS" : "REL", x, y);
+
+
+ if (num_buttons <= 2) {
+ gui_printf(GUI_COLOR_BAR, " [%5s] [%5s] ",
+ buttons & INT33_BUTTON_MASK_LEFT ? "LEFT" : "",
+ buttons & INT33_BUTTON_MASK_RIGHT ? "RIGHT" : "");
+ } else {
+ gui_printf(GUI_COLOR_BAR, " [%5s] [%5s] [%5s] ",
+ buttons & INT33_BUTTON_MASK_LEFT ? "LEFT" : "",
+ buttons & INT33_BUTTON_MASK_CENTER ? "MID " : "",
+ buttons & INT33_BUTTON_MASK_RIGHT ? "RIGHT" : "");
+ if (num_buttons > 3) {
+ gui_printf(GUI_COLOR_BAR, " [%3s] [%3s] ",
+ buttons & INT33_BUTTON_MASK_4TH ? "4TH" : "",
+ buttons & INT33_BUTTON_MASK_5TH ? "5TH" : "");
+ }
+ }
+
+ if (num_wheels > 0) {
+ char c = ' ';
+ if (events & INT33_EVENT_MASK_WHEEL_MOVEMENT) {
+ c = z > 0 ? 0x19 : 0x18;
+ } else if (events & INT33_EVENT_MASK_HORIZ_WHEEL_MOVEMENT) {
+ c = z > 0 ? 0x1A : 0x1B;
+ }
+ gui_printf(GUI_COLOR_BAR, "| %c", c);
+ }
+
+ // Log the events to the console
if (events & INT33_EVENT_MASK_LEFT_BUTTON_PRESSED) {
console_printf("Left button pressed\n");
}
@@ -208,128 +664,96 @@ void __far mouse_callback(uint16_t events, uint16_t buttons, int16_t x, int16_t
}
}
-bool mouse_reset()
-{
- if (!int33_reset_get_buttons(&num_buttons)) {
- puts("Mouse not installed");
- return false;
- }
-
- driver_caps = int33_get_capabilities();
- num_wheels = 0;
- if (driver_caps & INT33_CAPABILITY_WHEEL_API) {
- num_wheels = 1;
- }
- if (driver_caps & INT33_CAPABILITY_WHEEL2_API) {
- num_wheels = 2;
- }
-
- int33_set_event_handler(INT33_EVENT_MASK_ALL, mouse_callback);
-
- return true;
-}
-
-void mouse_report()
+int main(int argc, const char *argv[])
{
- const char __far *fstr;
-
- if (driver_caps != 0) {
- console_printf("Driver capabilities bits: 0x%x %s %s\n", driver_caps,
- driver_caps & INT33_CAPABILITY_WHEEL_API ? "<wheel API>" : "",
- driver_caps & INT33_CAPABILITY_WHEEL2_API ? "<wheel API v2>" : "");
- }
-
- fstr = int33_get_version_string();
- if (fstr) {
- console_printf("Driver version string: %Fs\n", fstr);
- }
-
- console_printf("Number of buttons: %u\n", num_buttons);
- console_printf("Number of wheels: %u\n", num_wheels);
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (stricmp(argv[i], "/nr") == 0) {
+ args_no_reset = true;
+ } else if (stricmp(argv[i], "/nw") == 0) {
+ args_no_wheel = true;
+ }
+ }
-}
+ gui_init();
+
+ if (!args_no_reset) {
+ if (mouse_reset()) {
+ mouse_report();
+ int33_show_cursor();
+ } else {
+ console_printf("Mouse driver not found or failed to reset\n");
+ }
+ } else {
+ console_printf("Use r, s to reset and show mouse pointer\n");
+ }
-void mouse_quit()
-{
- int33_reset();
-}
+ while (!main_exiting) {
+ int c = getch();
+
+ dprintf(DPREFIX "getch returns %d\n", c);
+
+ if (c == 0) {
+ // Extended key
+ c = getch();
+
+ dprintf(DPREFIX "getch returns extended %d\n", c);
+
+ switch (c) {
+ case 1: // Internal: mouse event
+ status_report_last_event();
+ break;
+ default:
+ console_printf("Keyboard extended key %d\n", c);
+ break;
+ }
+ } else {
+ console_printf("Keyboard key %d '%c'\n", c, c);
+
+ switch (c) {
+ case 27: // Escape
+ main_exiting = true;
+ break;
+ case 'r':
+ console_printf("Reset mouse\n");
+ if (mouse_reset()) {
+ mouse_report();
+ console_printf("Mouse reset complete\n");
+ } else {
+ console_printf("Mouse reset failed\n");
+ }
+ break;
+ case 's':
+ int33_show_cursor();
+ break;
+ case 'h':
+ int33_hide_cursor();
+ break;
+ case 'm':
+ modelist_show_modal();
+ gui_init();
+ if (!args_no_reset) {
+ if (mouse_reset()) {
+ mouse_report();
+ int33_show_cursor();
+ console_printf("Mouse reset complete\n");
+ } else {
+ console_printf("Mouse reset failed\n");
+ }
+ }
+ break;
+ case 'd':
+ mouse_debug();
+ break;
+ case 'c':
+ _clearscreen(_GCLEARSCREEN);
+ break;
+ }
+ }
+ }
-void mouse_debug()
-{
- // TODO ?
- union REGS in, out;
- in.x.ax = INT33_GET_MOUSE_POSITION;
- in.x.bx = 0x4567;
- in.x.cx = 0x7845;
- in.x.dx = 0x9AAC;
- in.x.si = 0xAAAA;
- in.x.di = 0xBBBB;
-
- int86(0x33, &in, &out);
-
- console_printf("IN ax 0x%04x bx 0x%04x cx 0x%04x dx 0x%04x si 0x%04x di 0x%04x\n",
- in.x.ax, in.x.bx, in.x.cx, in.x.dx, in.x.si, in.x.di);
- console_printf("OUT ax 0x%04x bx 0x%04x cx 0x%04x dx 0x%04x si 0x%04x di 0x%04x\n",
- out.x.ax, out.x.bx, out.x.cx, out.x.dx, out.x.si, out.x.di);
-}
+ mouse_quit();
+ _setvideomode(_DEFAULTMODE);
-int main(int argc, const char *argv[])
-{
- int c;
-
- (void)argc;
- (void)argv;
-
- if (!mouse_reset()) {
- return EXIT_FAILURE;
- }
-
- _setvideomode(_TEXTC80);
- _getvideoconfig(&vidconf);
-
- gui_init();
-
- mouse_report();
-
- int33_show_cursor();
-
- while (!exiting) {
- int c;
-
- c = getch();
-
- dprintf(DPREFIX "getch returns %d\n", c);
-
- if (c == 0) {
- // Extended key
- c = getch();
- console_printf("Keyboard extended key %d\n", c);
- } else {
- console_printf("Keyboard key %d '%c'\n", c, c);
- switch (c) {
- case 27: // Escape
- exiting = true;
- break;
- case 'r':
- console_printf("Reset mouse driver\n");
- mouse_reset();
- mouse_report();
- break;
- case 's':
- int33_show_cursor();
- break;
- case 'h':
- int33_hide_cursor();
- break;
- case 'd':
- mouse_debug();
- break;
- }
- }
- }
-
- mouse_quit();
- _setvideomode(_DEFAULTMODE);
-
- return EXIT_SUCCESS;
+ return EXIT_SUCCESS;
}