diff options
-rw-r--r-- | int16kbd.h | 4 | ||||
-rw-r--r-- | int33.h | 19 | ||||
-rw-r--r-- | mousetsr.c | 13 | ||||
-rw-r--r-- | mousetsr.h | 2 | ||||
-rw-r--r-- | mousew16.c | 76 | ||||
-rw-r--r-- | mousmain.c | 8 | ||||
-rw-r--r-- | moustest.c | 838 |
7 files changed, 707 insertions, 253 deletions
@@ -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] @@ -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" \ @@ -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; @@ -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 @@ -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 @@ -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); @@ -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; } |