diff --git a/pc/drive.c b/pc/drive.c index de24a7664..1c23190dd 100644 --- a/pc/drive.c +++ b/pc/drive.c @@ -1,218 +1,218 @@ -/* Ch-Drive command for Windows NT and OS/2 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Bug: - the code will not work if you have more drives than those that - can fit in a panel. - */ - -#include -#ifdef _OS_NT -#include -#include "util_win32.h" -#endif -#include -#include -#include -#include -#include "../src/tty.h" -#include "../src/mad.h" -#include "../src/util.h" -#include "../src/win.h" -#include "../src/color.h" -#include "../src/dlg.h" -#include "../src/widget.h" -#include "../src/dialog.h" -#include "../src/dir.h" -#include "../src/panel.h" -#include "../src/main.h" -#include "../src/cmd.h" - -struct Dlg_head *drive_dlg; -WPanel *this_panel; - -static int drive_dlg_callback (Dlg_head *h, int Par, int Msg); -static void drive_dlg_refresh (void); -static void drive_cmd(void); - -#define B_DRIVE_BASE 100 -#define MAX_LGH 13 /* Length for drives */ - -static void drive_cmd() -{ - int i, nNewDrive, nDrivesAvail; - char szTempBuf[7], szDrivesAvail[27*4], *p; - - /* Dialogbox position */ - int x_pos; - int y_pos = (LINES-6)/2-3; - int y_height; - int x_width; - - int m_drv; - - /* Get drives name and count */ -#ifdef _OS_NT - GetLogicalDriveStrings (255, szDrivesAvail); - for (nDrivesAvail = 0, p = szDrivesAvail; *p; nDrivesAvail++) - p+=4; -#else - unsigned long uDriveNum, uDriveMap; - nDrivesAvail = 0; - p = szDrivesAvail; - DosQueryCurrentDisk(&uDriveNum, &uDriveMap); - for (i = 0; i < 26; i++) { - if ( uDriveMap & (1 << i) ) { - *p = 'A' + i; - p += 4; - nDrivesAvail++; - } - } - *p = 0; -#endif - - /* Create Dialog */ - do_refresh (); - - m_drv = ((nDrivesAvail > MAX_LGH) ? MAX_LGH: nDrivesAvail); - /* Center on x, relative to panel */ - x_pos = this_panel->widget.x + (this_panel->widget.cols - m_drv*3)/2 + 2; - - if (nDrivesAvail > MAX_LGH) { - y_height = 8; - x_width = 33; - } else { - y_height = 6; - x_width = (nDrivesAvail - 1) * 2 + 9; - } - - drive_dlg = create_dlg (y_pos, x_pos, y_height, x_width, dialog_colors, - drive_dlg_callback, "[ChDrive]", "drive", DLG_NONE); - - x_set_dialog_title (drive_dlg, "Change Drive"); - - if (nDrivesAvail>MAX_LGH) { - for (i = 0; i < nDrivesAvail - MAX_LGH; i++) { - p -= 4; - sprintf(szTempBuf, "&%c", *p); - add_widgetl(drive_dlg, - button_new (5, - (m_drv-i-1)*2+4 - (MAX_LGH*2 - nDrivesAvail) * 2, - B_DRIVE_BASE + nDrivesAvail - i - 1, - HIDDEN_BUTTON, - szTempBuf, 0, NULL, NULL), - XV_WLAY_RIGHTOF); - } - } - - /* Add a button for each drive */ - for (i = 0; i < m_drv; i++) { - p -= 4; - sprintf (szTempBuf, "&%c", *p); - add_widgetl(drive_dlg, - button_new (3, (m_drv-i-1)*2+4, B_DRIVE_BASE+m_drv-i-1, - HIDDEN_BUTTON, szTempBuf, 0, NULL, NULL), - XV_WLAY_RIGHTOF); - } - - run_dlg(drive_dlg); - - /* do action */ - if (drive_dlg->ret_value != B_CANCEL) { - int errocc = 0; /* no error */ - int rtn; - char drvLetter; - - nNewDrive = drive_dlg->ret_value - B_DRIVE_BASE; - drvLetter = (char) *(szDrivesAvail + (nNewDrive*4)); -#ifdef _OS_NT - if (win32_GetPlatform() == OS_WinNT) { /* Windows NT */ - rtn = _chdrive(drvLetter - 'A' + 1); - } else { /* Windows 95 */ - rtn = 1; - SetCurrentDirectory(szDrivesAvail+(nNewDrive*4)); - } -#else - rtn = DosSetDefaultDisk(nNewDrive + 1); -#endif - if (rtn == -1) - errocc = 1; - else { - getcwd (this_panel->cwd, sizeof (this_panel->cwd)-2); - if (toupper(drvLetter) == toupper(*(this_panel->cwd))) { - clean_dir (&this_panel->dir, this_panel->count); - this_panel->count = do_load_dir(&this_panel->dir, - this_panel->sort_type, - this_panel->reverse, - this_panel->case_sensitive, - this_panel->filter); - this_panel->top_file = 0; - this_panel->selected = 0; - this_panel->marked = 0; - this_panel->total = 0; - show_dir(this_panel); - reread_cmd(); - } else - errocc = 1; - } - if (errocc) - message (1, " Error ", " Can't access drive %c: ", - *(szDrivesAvail+(nNewDrive*4)) ); - } - destroy_dlg (drive_dlg); - repaint_screen (); -} - -void drive_cmd_a() -{ - this_panel = left_panel; - drive_cmd(); -} - -void drive_cmd_b() -{ - this_panel = right_panel; - drive_cmd(); -} - -void drive_chg(WPanel *panel) -{ - this_panel = panel; - drive_cmd(); -} - -static int drive_dlg_callback (Dlg_head *h, int Par, int Msg) -{ - switch (Msg) { -#ifndef HAVE_X - case DLG_DRAW: - drive_dlg_refresh (); - break; -#endif - } - return 0; -} - -static void drive_dlg_refresh (void) -{ - attrset (dialog_colors[0]); - dlg_erase (drive_dlg); - draw_box (drive_dlg, 1, 1, drive_dlg->lines-2, drive_dlg->cols-2); - - attrset (dialog_colors[2]); - dlg_move (drive_dlg, 1, drive_dlg->cols/2 - 7); - addstr (" Change Drive "); -} +/* Ch-Drive command for Windows NT and OS/2 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Bug: + the code will not work if you have more drives than those that + can fit in a panel. + */ + +#include +#ifdef _OS_NT +#include +#include "util_win32.h" +#endif +#include +#include +#include +#include +#include "../src/tty.h" +#include "../src/mad.h" +#include "../src/util.h" +#include "../src/win.h" +#include "../src/color.h" +#include "../src/dlg.h" +#include "../src/widget.h" +#include "../src/dialog.h" +#include "../src/dir.h" +#include "../src/panel.h" +#include "../src/main.h" +#include "../src/cmd.h" + +struct Dlg_head *drive_dlg; +WPanel *this_panel; + +static int drive_dlg_callback (Dlg_head *h, int Par, int Msg); +static void drive_dlg_refresh (void); +static void drive_cmd(void); + +#define B_DRIVE_BASE 100 +#define MAX_LGH 13 /* Length for drives */ + +static void drive_cmd() +{ + int i, nNewDrive, nDrivesAvail; + char szTempBuf[7], szDrivesAvail[27*4], *p; + + /* Dialogbox position */ + int x_pos; + int y_pos = (LINES-6)/2-3; + int y_height; + int x_width; + + int m_drv; + + /* Get drives name and count */ +#ifdef _OS_NT + GetLogicalDriveStrings (255, szDrivesAvail); + for (nDrivesAvail = 0, p = szDrivesAvail; *p; nDrivesAvail++) + p+=4; +#else + unsigned long uDriveNum, uDriveMap; + nDrivesAvail = 0; + p = szDrivesAvail; + DosQueryCurrentDisk(&uDriveNum, &uDriveMap); + for (i = 0; i < 26; i++) { + if ( uDriveMap & (1 << i) ) { + *p = 'A' + i; + p += 4; + nDrivesAvail++; + } + } + *p = 0; +#endif + + /* Create Dialog */ + do_refresh (); + + m_drv = ((nDrivesAvail > MAX_LGH) ? MAX_LGH: nDrivesAvail); + /* Center on x, relative to panel */ + x_pos = this_panel->widget.x + (this_panel->widget.cols - m_drv*3)/2 + 2; + + if (nDrivesAvail > MAX_LGH) { + y_height = 8; + x_width = 33; + } else { + y_height = 6; + x_width = (nDrivesAvail - 1) * 2 + 9; + } + + drive_dlg = create_dlg (y_pos, x_pos, y_height, x_width, dialog_colors, + drive_dlg_callback, "[ChDrive]", "drive", DLG_NONE); + + x_set_dialog_title (drive_dlg, "Change Drive"); + + if (nDrivesAvail>MAX_LGH) { + for (i = 0; i < nDrivesAvail - MAX_LGH; i++) { + p -= 4; + sprintf(szTempBuf, "&%c", *p); + add_widgetl(drive_dlg, + button_new (5, + (m_drv-i-1)*2+4 - (MAX_LGH*2 - nDrivesAvail) * 2, + B_DRIVE_BASE + nDrivesAvail - i - 1, + HIDDEN_BUTTON, + szTempBuf, 0, NULL, NULL), + XV_WLAY_RIGHTOF); + } + } + + /* Add a button for each drive */ + for (i = 0; i < m_drv; i++) { + p -= 4; + sprintf (szTempBuf, "&%c", *p); + add_widgetl(drive_dlg, + button_new (3, (m_drv-i-1)*2+4, B_DRIVE_BASE+m_drv-i-1, + HIDDEN_BUTTON, szTempBuf, 0, NULL, NULL), + XV_WLAY_RIGHTOF); + } + + run_dlg(drive_dlg); + + /* do action */ + if (drive_dlg->ret_value != B_CANCEL) { + int errocc = 0; /* no error */ + int rtn; + char drvLetter; + + nNewDrive = drive_dlg->ret_value - B_DRIVE_BASE; + drvLetter = (char) *(szDrivesAvail + (nNewDrive*4)); +#ifdef _OS_NT + if (win32_GetPlatform() == OS_WinNT) { /* Windows NT */ + rtn = _chdrive(drvLetter - 'A' + 1); + } else { /* Windows 95 */ + rtn = 1; + SetCurrentDirectory(szDrivesAvail+(nNewDrive*4)); + } +#else + rtn = DosSetDefaultDisk(nNewDrive + 1); +#endif + if (rtn == -1) + errocc = 1; + else { + getcwd (this_panel->cwd, sizeof (this_panel->cwd)-2); + if (toupper(drvLetter) == toupper(*(this_panel->cwd))) { + clean_dir (&this_panel->dir, this_panel->count); + this_panel->count = do_load_dir(&this_panel->dir, + this_panel->sort_type, + this_panel->reverse, + this_panel->case_sensitive, + this_panel->filter); + this_panel->top_file = 0; + this_panel->selected = 0; + this_panel->marked = 0; + this_panel->total = 0; + show_dir(this_panel); + reread_cmd(); + } else + errocc = 1; + } + if (errocc) + message (1, " Error ", " Can't access drive %c: ", + *(szDrivesAvail+(nNewDrive*4)) ); + } + destroy_dlg (drive_dlg); + repaint_screen (); +} + +void drive_cmd_a() +{ + this_panel = left_panel; + drive_cmd(); +} + +void drive_cmd_b() +{ + this_panel = right_panel; + drive_cmd(); +} + +void drive_chg(WPanel *panel) +{ + this_panel = panel; + drive_cmd(); +} + +static int drive_dlg_callback (Dlg_head *h, int Par, int Msg) +{ + switch (Msg) { +#ifndef HAVE_X + case DLG_DRAW: + drive_dlg_refresh (); + break; +#endif + } + return 0; +} + +static void drive_dlg_refresh (void) +{ + attrset (dialog_colors[0]); + dlg_erase (drive_dlg); + draw_box (drive_dlg, 1, 1, drive_dlg->lines-2, drive_dlg->cols-2); + + attrset (dialog_colors[2]); + dlg_move (drive_dlg, 1, drive_dlg->cols/2 - 7); + addstr (" Change Drive "); +} diff --git a/pc/key_nt.c b/pc/key_nt.c index d2e98279c..3fcf72faa 100644 --- a/pc/key_nt.c +++ b/pc/key_nt.c @@ -1,309 +1,309 @@ -/* Keyboard support routines. - for Windows NT system. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Bugs: - Have trouble with non-US keyboards, "Alt-gr"+keys (API tells CTRL-ALT is pressed) - */ -#include -#ifndef _OS_NT -#error This file is for Win32 systems. -#else - -#include -#include -#include "../src/mouse.h" -#include "../src/global.h" -#include "../src/main.h" -#include "../src/key.h" -#include "../vfs/vfs.h" -#include "../src/tty.h" -#include "trace_nt.h" - -/* Global variables */ -int old_esc_mode = 0; -HANDLE hConsoleInput; -DWORD dwSaved_ControlState; -Gpm_Event evSaved_Event; - -/* Unused variables */ -int double_click_speed; /* they are here to keep linker happy */ -int mou_auto_repeat; -int use_8th_bit_as_meta = 0; - -/* Static Tables */ -struct { - int key_code; - int vkcode; -} key_table [] = { - { KEY_F(1), VK_F1 }, - { KEY_F(2), VK_F2 }, - { KEY_F(3), VK_F3 }, - { KEY_F(4), VK_F4 }, - { KEY_F(5), VK_F5 }, - { KEY_F(6), VK_F6 }, - { KEY_F(7), VK_F7 }, - { KEY_F(8), VK_F8 }, - { KEY_F(9), VK_F9 }, - { KEY_F(10), VK_F10 }, - { KEY_F(11), VK_F11 }, - { KEY_F(12), VK_F12 }, - { KEY_F(13), VK_F13 }, - { KEY_F(14), VK_F14 }, - { KEY_F(15), VK_F15 }, - { KEY_F(16), VK_F16 }, - { KEY_F(17), VK_F17 }, - { KEY_F(18), VK_F18 }, - { KEY_F(19), VK_F19 }, - { KEY_F(20), VK_F20 }, - { KEY_IC, VK_INSERT }, - { KEY_DC, VK_DELETE }, - { KEY_BACKSPACE, VK_BACK }, - - { KEY_PPAGE, VK_PRIOR }, - { KEY_NPAGE, VK_NEXT }, - { KEY_LEFT, VK_LEFT }, - { KEY_RIGHT, VK_RIGHT }, - { KEY_UP, VK_UP }, - { KEY_DOWN, VK_DOWN }, - { KEY_HOME, VK_HOME }, - { KEY_END, VK_END }, - - { ALT('*'), VK_MULTIPLY }, - { ALT('+'), VK_ADD }, - { ALT('-'), VK_SUBTRACT }, - - { ESC_CHAR, VK_ESCAPE }, - - { 0, 0} -}; - -/* init_key - Called in main.c to initialize ourselves - Get handle to console input -*/ -void init_key (void) -{ - win32APICALL_HANDLE (hConsoleInput, GetStdHandle (STD_INPUT_HANDLE)); -} - -int ctrl_pressed () -{ - return dwSaved_ControlState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED); -} - -int shift_pressed () -{ - return dwSaved_ControlState & SHIFT_PRESSED; -} - -int alt_pressed () -{ - return dwSaved_ControlState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED); -} - -static int VKtoCurses (int a_vkc) -{ - int i; - - for (i = 0; key_table[i].vkcode != 0; i++) - if (a_vkc == key_table[i].vkcode) { - return key_table[i].key_code; - } - return 0; -} - -static int translate_key_code(int asc, int scan) -{ - int c; - c = VKtoCurses (scan); - if (!asc && !c) - return 0; - if (asc && c) - return c; - if (!asc) - { - if (shift_pressed() && (c >= KEY_F(1)) && (c <= KEY_F(10))) - c += 10; - if (alt_pressed() && (c >= KEY_F(1)) && (c <= KEY_F(2))) - c += 10; - if (alt_pressed() && (c == KEY_F(7))) - c = ALT('?'); - if (ctrl_pressed() && c == '\t') - c = ALT('\t'); - return c; - } - if (ctrl_pressed()) - return XCTRL(asc); - if (alt_pressed()) - return ALT(asc); - if (asc == 13) - return 10; - return asc; -} - -int get_key_code (int no_delay) -{ - INPUT_RECORD ir; /* Input record */ - DWORD dw; /* number of records actually read */ - int ch, vkcode, j; - - if (no_delay) { - /* Check if any input pending, otherwise return */ - nodelay (stdscr, TRUE); - win32APICALL(PeekConsoleInput(hConsoleInput, &ir, 1, &dw)); - if (!dw) - return 0; - } - - do { - win32APICALL(ReadConsoleInput(hConsoleInput, &ir, 1, &dw)); - switch (ir.EventType) { - case KEY_EVENT: - if (!ir.Event.KeyEvent.bKeyDown) /* Process key just once: when pressed */ - break; - - vkcode = ir.Event.KeyEvent.wVirtualKeyCode; -#ifndef __MINGW32__ - ch = ir.Event.KeyEvent.uChar.AsciiChar; -#else - ch = ir.Event.KeyEvent.AsciiChar; -#endif - dwSaved_ControlState = ir.Event.KeyEvent.dwControlKeyState; - j = translate_key_code (ch, vkcode); - if (j) - return j; - break; - - case MOUSE_EVENT: - /* Save event as a GPM-like event */ - evSaved_Event.x = ir.Event.MouseEvent.dwMousePosition.X; - evSaved_Event.y = ir.Event.MouseEvent.dwMousePosition.Y+1; - evSaved_Event.buttons = ir.Event.MouseEvent.dwButtonState; - switch (ir.Event.MouseEvent.dwEventFlags) { - case 0: - evSaved_Event.type = GPM_DOWN | GPM_SINGLE; - break; - case MOUSE_MOVED: - evSaved_Event.type = GPM_MOVE; - break; - case DOUBLE_CLICK: - evSaved_Event.type = GPM_DOWN | GPM_DOUBLE; - break; - }; - return 0; - } - } while (!no_delay); - return 0; -} - -static int getch_with_delay (void) -{ - int c; - - while (1) { - /* Try to get a character */ - c = get_key_code (0); - if (c != ERR) - break; - } - /* Success -> return the character */ - return c; -} - -/* Returns a character read from stdin with appropriate interpretation */ -int get_event (Gpm_Event *event, int redo_event, int block) -{ - int c; - static int flag; /* Return value from select */ - static int dirty = 3; - - if ((dirty == 1) || is_idle ()){ - refresh (); - doupdate (); - dirty = 1; - } else - dirty++; - - vfs_timeout_handler (); - - c = block ? getch_with_delay () : get_key_code (1); - - if (!c) { - /* Code is 0, so this is a Control key or mouse event */ - return EV_NONE; /* FIXME: mouse not supported */ - } - - return c; -} - -/* Returns a key press, mouse events are discarded */ -int mi_getch () -{ - Gpm_Event ev; - int key; - - while ((key = get_event (&ev, 0, 1)) == 0) - ; - return key; -} - -/* - is_idle - A function to check if we're idle. - It checks for any waiting event (that can be a Key, Mouse event, - and other internal events like focus or menu) -*/ -int is_idle (void) -{ - DWORD dw; - if (GetNumberOfConsoleInputEvents (hConsoleInput, &dw)) - if (dw > 15) - return 0; - return 1; -} - -/* get_modifier */ -int get_modifier() -{ - int retval = 0; - - if (dwSaved_ControlState & LEFT_ALT_PRESSED) /* code is not clean, because we return Linux-like bitcodes*/ - retval |= ALTL_PRESSED; - if (dwSaved_ControlState & RIGHT_ALT_PRESSED) - retval |= ALTR_PRESSED; - - if (dwSaved_ControlState & RIGHT_CTRL_PRESSED || - dwSaved_ControlState & LEFT_CTRL_PRESSED) - retval |= CONTROL_PRESSED; - - if (dwSaved_ControlState & SHIFT_PRESSED) - retval |= SHIFT_PRESSED; - - return retval; -} - -/* void functions for UNIX compatibility */ -void define_sequence (int code, char* vkcode, int action) {} -void channels_up() {} -void channels_down() {} -void init_key_input_fd (void) {} -void numeric_keypad_mode (void) {} -void application_keypad_mode (void) {} - -/* mouse is not yet supported, sorry */ -void init_mouse (void) {} -void shut_mouse (void) {} - -#endif /* _OS_NT */ +/* Keyboard support routines. + for Windows NT system. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Bugs: + Have trouble with non-US keyboards, "Alt-gr"+keys (API tells CTRL-ALT is pressed) + */ +#include +#ifndef _OS_NT +#error This file is for Win32 systems. +#else + +#include +#include +#include "../src/mouse.h" +#include "../src/global.h" +#include "../src/main.h" +#include "../src/key.h" +#include "../vfs/vfs.h" +#include "../src/tty.h" +#include "trace_nt.h" + +/* Global variables */ +int old_esc_mode = 0; +HANDLE hConsoleInput; +DWORD dwSaved_ControlState; +Gpm_Event evSaved_Event; + +/* Unused variables */ +int double_click_speed; /* they are here to keep linker happy */ +int mou_auto_repeat; +int use_8th_bit_as_meta = 0; + +/* Static Tables */ +struct { + int key_code; + int vkcode; +} fkt_table [] = { + { KEY_F(1), VK_F1 }, + { KEY_F(2), VK_F2 }, + { KEY_F(3), VK_F3 }, + { KEY_F(4), VK_F4 }, + { KEY_F(5), VK_F5 }, + { KEY_F(6), VK_F6 }, + { KEY_F(7), VK_F7 }, + { KEY_F(8), VK_F8 }, + { KEY_F(9), VK_F9 }, + { KEY_F(10), VK_F10 }, + { KEY_F(11), VK_F11 }, + { KEY_F(12), VK_F12 }, + { KEY_F(13), VK_F13 }, + { KEY_F(14), VK_F14 }, + { KEY_F(15), VK_F15 }, + { KEY_F(16), VK_F16 }, + { KEY_F(17), VK_F17 }, + { KEY_F(18), VK_F18 }, + { KEY_F(19), VK_F19 }, + { KEY_F(20), VK_F20 }, + { KEY_IC, VK_INSERT }, + { KEY_DC, VK_DELETE }, + { KEY_BACKSPACE, VK_BACK }, + + { KEY_PPAGE, VK_PRIOR }, + { KEY_NPAGE, VK_NEXT }, + { KEY_LEFT, VK_LEFT }, + { KEY_RIGHT, VK_RIGHT }, + { KEY_UP, VK_UP }, + { KEY_DOWN, VK_DOWN }, + { KEY_HOME, VK_HOME }, + { KEY_END, VK_END }, + + { ALT('*'), VK_MULTIPLY }, + { ALT('+'), VK_ADD }, + { ALT('-'), VK_SUBTRACT }, + + { ESC_CHAR, VK_ESCAPE }, + + { 0, 0} +}; + +/* init_key - Called in main.c to initialize ourselves + Get handle to console input +*/ +void init_key (void) +{ + win32APICALL_HANDLE (hConsoleInput, GetStdHandle (STD_INPUT_HANDLE)); +} + +int ctrl_pressed () +{ + return dwSaved_ControlState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED); +} + +int shift_pressed () +{ + return dwSaved_ControlState & SHIFT_PRESSED; +} + +int alt_pressed () +{ + return dwSaved_ControlState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED); +} + +static int VKtoCurses (int a_vkc) +{ + int i; + + for (i = 0; fkt_table[i].vkcode != 0; i++) + if (a_vkc == fkt_table[i].vkcode) { + return fkt_table[i].key_code; + } + return 0; +} + +static int translate_key_code(int asc, int scan) +{ + int c; + c = VKtoCurses (scan); + if (!asc && !c) + return 0; + if (asc && c) + return c; + if (!asc) + { + if (shift_pressed() && (c >= KEY_F(1)) && (c <= KEY_F(10))) + c += 10; + if (alt_pressed() && (c >= KEY_F(1)) && (c <= KEY_F(2))) + c += 10; + if (alt_pressed() && (c == KEY_F(7))) + c = ALT('?'); + if (ctrl_pressed() && c == '\t') + c = ALT('\t'); + return c; + } + if (ctrl_pressed()) + return XCTRL(asc); + if (alt_pressed()) + return ALT(asc); + if (asc == 13) + return 10; + return asc; +} + +int get_key_code (int no_delay) +{ + INPUT_RECORD ir; /* Input record */ + DWORD dw; /* number of records actually read */ + int ch, vkcode, j; + + if (no_delay) { + /* Check if any input pending, otherwise return */ + nodelay (stdscr, TRUE); + win32APICALL(PeekConsoleInput(hConsoleInput, &ir, 1, &dw)); + if (!dw) + return 0; + } + + do { + win32APICALL(ReadConsoleInput(hConsoleInput, &ir, 1, &dw)); + switch (ir.EventType) { + case KEY_EVENT: + if (!ir.Event.KeyEvent.bKeyDown) /* Process key just once: when pressed */ + break; + + vkcode = ir.Event.KeyEvent.wVirtualKeyCode; +#ifndef __MINGW32__ + ch = ir.Event.KeyEvent.uChar.AsciiChar; +#else + ch = ir.Event.KeyEvent.AsciiChar; +#endif + dwSaved_ControlState = ir.Event.KeyEvent.dwControlKeyState; + j = translate_key_code (ch, vkcode); + if (j) + return j; + break; + + case MOUSE_EVENT: + /* Save event as a GPM-like event */ + evSaved_Event.x = ir.Event.MouseEvent.dwMousePosition.X; + evSaved_Event.y = ir.Event.MouseEvent.dwMousePosition.Y+1; + evSaved_Event.buttons = ir.Event.MouseEvent.dwButtonState; + switch (ir.Event.MouseEvent.dwEventFlags) { + case 0: + evSaved_Event.type = GPM_DOWN | GPM_SINGLE; + break; + case MOUSE_MOVED: + evSaved_Event.type = GPM_MOVE; + break; + case DOUBLE_CLICK: + evSaved_Event.type = GPM_DOWN | GPM_DOUBLE; + break; + }; + return 0; + } + } while (!no_delay); + return 0; +} + +static int getch_with_delay (void) +{ + int c; + + while (1) { + /* Try to get a character */ + c = get_key_code (0); + if (c != ERR) + break; + } + /* Success -> return the character */ + return c; +} + +/* Returns a character read from stdin with appropriate interpretation */ +int get_event (Gpm_Event *event, int redo_event, int block) +{ + int c; + static int flag; /* Return value from select */ + static int dirty = 3; + + if ((dirty == 1) || is_idle ()){ + refresh (); + doupdate (); + dirty = 1; + } else + dirty++; + + vfs_timeout_handler (); + + c = block ? getch_with_delay () : get_key_code (1); + + if (!c) { + /* Code is 0, so this is a Control key or mouse event */ + return EV_NONE; /* FIXME: mouse not supported */ + } + + return c; +} + +/* Returns a key press, mouse events are discarded */ +int mi_getch () +{ + Gpm_Event ev; + int key; + + while ((key = get_event (&ev, 0, 1)) == 0) + ; + return key; +} + +/* + is_idle - A function to check if we're idle. + It checks for any waiting event (that can be a Key, Mouse event, + and other internal events like focus or menu) +*/ +int is_idle (void) +{ + DWORD dw; + if (GetNumberOfConsoleInputEvents (hConsoleInput, &dw)) + if (dw > 15) + return 0; + return 1; +} + +/* get_modifier */ +int get_modifier() +{ + int retval = 0; + + if (dwSaved_ControlState & LEFT_ALT_PRESSED) /* code is not clean, because we return Linux-like bitcodes*/ + retval |= ALTL_PRESSED; + if (dwSaved_ControlState & RIGHT_ALT_PRESSED) + retval |= ALTR_PRESSED; + + if (dwSaved_ControlState & RIGHT_CTRL_PRESSED || + dwSaved_ControlState & LEFT_CTRL_PRESSED) + retval |= CONTROL_PRESSED; + + if (dwSaved_ControlState & SHIFT_PRESSED) + retval |= SHIFT_PRESSED; + + return retval; +} + +/* void functions for UNIX compatibility */ +void define_sequence (int code, char* vkcode, int action) {} +void channels_up() {} +void channels_down() {} +void init_key_input_fd (void) {} +void numeric_keypad_mode (void) {} +void application_keypad_mode (void) {} + +/* mouse is not yet supported, sorry */ +void init_mouse (void) {} +void shut_mouse (void) {} + +#endif /* _OS_NT */