89 static short int inputline_offset; |
89 static short int inputline_offset; |
90 static int completion_started; |
90 static int completion_started; |
91 static GList *cmdhisto; |
91 static GList *cmdhisto; |
92 static GList *cmdhisto_cur; |
92 static GList *cmdhisto_cur; |
93 static char cmdhisto_backup[INPUTLINE_LENGTH+1]; |
93 static char cmdhisto_backup[INPUTLINE_LENGTH+1]; |
|
94 |
|
95 #define MAX_KEYSEQ_LENGTH 8 |
|
96 |
|
97 typedef struct { |
|
98 char *seqstr; |
|
99 guint mkeycode; |
|
100 gint value; |
|
101 } keyseq; |
|
102 |
|
103 GSList *keyseqlist; |
|
104 static void add_keyseq(char *seqstr, guint mkeycode, gint value); |
94 |
105 |
95 |
106 |
96 /* Functions */ |
107 /* Functions */ |
97 |
108 |
98 static int scr_WindowWidth(WINDOW * win) |
109 static int scr_WindowWidth(WINDOW * win) |
207 } |
218 } |
208 } |
219 } |
209 |
220 |
210 void scr_InitCurses(void) |
221 void scr_InitCurses(void) |
211 { |
222 { |
|
223 /* Key sequences initialization */ |
|
224 add_keyseq("O5A", MKEY_EQUIV, 521); // Ctrl-Up |
|
225 add_keyseq("O5B", MKEY_EQUIV, 514); // Ctrl-Down |
|
226 add_keyseq("O5C", MKEY_EQUIV, 518); // Ctrl-Right |
|
227 add_keyseq("O5D", MKEY_EQUIV, 516); // Ctrl-Left |
|
228 add_keyseq("O6A", MKEY_EQUIV, 520); // Ctrl-Shift-Up |
|
229 add_keyseq("O6B", MKEY_EQUIV, 513); // Ctrl-Shift-Down |
|
230 add_keyseq("O6C", MKEY_EQUIV, 402); // Ctrl-Shift-Right |
|
231 add_keyseq("O6D", MKEY_EQUIV, 393); // Ctrl-Shift-Left |
|
232 |
|
233 // Xterm |
|
234 add_keyseq("[1;5A", MKEY_EQUIV, 521); // Ctrl-Up |
|
235 add_keyseq("[1;5B", MKEY_EQUIV, 514); // Ctrl-Down |
|
236 add_keyseq("[1;5C", MKEY_EQUIV, 518); // Ctrl-Right |
|
237 add_keyseq("[1;5D", MKEY_EQUIV, 516); // Ctrl-Left |
|
238 add_keyseq("[1;6A", MKEY_EQUIV, 520); // Ctrl-Shift-Up |
|
239 add_keyseq("[1;6B", MKEY_EQUIV, 513); // Ctrl-Shift-Down |
|
240 add_keyseq("[1;6C", MKEY_EQUIV, 402); // Ctrl-Shift-Right |
|
241 add_keyseq("[1;6D", MKEY_EQUIV, 393); // Ctrl-Shift-Left |
|
242 |
212 initscr(); |
243 initscr(); |
213 raw(); |
244 raw(); |
214 noecho(); |
245 noecho(); |
215 nonl(); |
246 nonl(); |
216 intrflush(stdscr, FALSE); |
247 intrflush(stdscr, FALSE); |
1861 scr_end_current_completion(); |
1892 scr_end_current_completion(); |
1862 check_offset(-1); |
1893 check_offset(-1); |
1863 refresh_inputline(); |
1894 refresh_inputline(); |
1864 } |
1895 } |
1865 |
1896 |
1866 int scr_Getch(void) |
1897 static void add_keyseq(char *seqstr, guint mkeycode, gint value) |
1867 { |
1898 { |
1868 return wgetch(inputWnd); |
1899 keyseq *ks; |
|
1900 |
|
1901 // Let's make sure the length is correct |
|
1902 if (strlen(seqstr) > MAX_KEYSEQ_LENGTH) { |
|
1903 scr_LogPrint(LPRINT_LOGNORM, "add_keyseq(): key sequence is too long!"); |
|
1904 return; |
|
1905 } |
|
1906 |
|
1907 ks = g_new0(keyseq, 1); |
|
1908 ks->seqstr = g_strdup(seqstr); |
|
1909 ks->mkeycode = mkeycode; |
|
1910 ks->value = value; |
|
1911 keyseqlist = g_slist_append(keyseqlist, ks); |
|
1912 } |
|
1913 |
|
1914 // match_keyseq(iseq, &ret) |
|
1915 // Check if "iseq" is a known key escape sequence. |
|
1916 // Return value: |
|
1917 // -1 if "seq" matches no known sequence |
|
1918 // 0 if "seq" could match 1 or more known sequences |
|
1919 // >0 if "seq" matches a key sequence; the mkey code is returned |
|
1920 // and *ret is set to the matching keyseq structure. |
|
1921 static inline guint match_keyseq(int *iseq, keyseq **ret) |
|
1922 { |
|
1923 GSList *ksl; |
|
1924 keyseq *ksp; |
|
1925 char *p, c; |
|
1926 int *i; |
|
1927 int needmore = FALSE; |
|
1928 |
|
1929 for (ksl = keyseqlist; ksl; ksl = g_slist_next(ksl)) { |
|
1930 ksp = ksl->data; |
|
1931 p = ksp->seqstr; |
|
1932 i = iseq; |
|
1933 while (1) { |
|
1934 c = (unsigned char)*i; |
|
1935 if (!*p && !c) { // Match |
|
1936 (*ret) = ksp; |
|
1937 return ksp->mkeycode; |
|
1938 } |
|
1939 if (!c) { |
|
1940 // iseq is too short |
|
1941 needmore = TRUE; |
|
1942 break; |
|
1943 } else if (!*p || c != *p) { |
|
1944 // This isn't a match |
|
1945 break; |
|
1946 } |
|
1947 p++; i++; |
|
1948 } |
|
1949 } |
|
1950 |
|
1951 if (needmore) |
|
1952 return 0; |
|
1953 return -1; |
|
1954 } |
|
1955 |
|
1956 void scr_Getch(keycode *kcode) |
|
1957 { |
|
1958 keyseq *mks; |
|
1959 int ks[MAX_KEYSEQ_LENGTH+1]; |
|
1960 int i; |
|
1961 |
|
1962 memset(kcode, 0, sizeof(keycode)); |
|
1963 memset(ks, 0, sizeof(ks)); |
|
1964 |
|
1965 kcode->value = wgetch(inputWnd); |
|
1966 if (kcode->value != 27) |
|
1967 return; |
|
1968 |
|
1969 // Check for escape key sequence |
|
1970 for (i=0; i < MAX_KEYSEQ_LENGTH; i++) { |
|
1971 int match; |
|
1972 ks[i] = wgetch(inputWnd); |
|
1973 if (ks[i] == ERR) break; |
|
1974 match = match_keyseq(ks, &mks); |
|
1975 if (match == -1) { |
|
1976 // No such key sequence. Let's increment i as it is a valid key. |
|
1977 i++; |
|
1978 break; |
|
1979 } |
|
1980 if (match > 0) { |
|
1981 // We have a matching sequence |
|
1982 kcode->mcode = mks->mkeycode; |
|
1983 kcode->value = mks->value; |
|
1984 return; |
|
1985 } |
|
1986 } |
|
1987 |
|
1988 // No match. Let's return a meta-key. |
|
1989 if (i > 0) { |
|
1990 kcode->mcode = MKEY_META; |
|
1991 kcode->value = ks[0]; |
|
1992 } |
|
1993 if (i > 1) { |
|
1994 // We need to push some keys back to the keyboard buffer |
|
1995 while (i-- > 1) |
|
1996 ungetch(ks[i]); |
|
1997 } |
|
1998 return; |
1869 } |
1999 } |
1870 |
2000 |
1871 // process_key(key) |
2001 // process_key(key) |
1872 // Handle the pressed key, in the command line (bottom). |
2002 // Handle the pressed key, in the command line (bottom). |
1873 int process_key(int key) |
2003 int process_key(keycode kcode) |
1874 { |
2004 { |
1875 if (key == 27) { |
2005 int key = kcode.value; |
1876 key = scr_Getch(); |
2006 |
1877 if (key == -1 || key == 27) { |
2007 switch (kcode.mcode) { |
1878 // This is a "real" escape... |
2008 case 0: |
1879 scr_CheckAutoAway(TRUE); |
2009 break; |
1880 currentWindow = NULL; |
2010 case MKEY_EQUIV: |
1881 chatmode = FALSE; |
2011 key = kcode.value; |
1882 if (current_buddy) |
2012 break; |
1883 buddy_setflags(BUDDATA(current_buddy), ROSTER_FLAG_LOCK, FALSE); |
2013 case MKEY_META: |
1884 scr_RosterVisibility(1); |
2014 key = ERR; |
1885 scr_UpdateChatStatus(FALSE); |
2015 switch (kcode.value) { |
1886 top_panel(chatPanel); |
2016 case 27: |
1887 top_panel(inputPanel); |
2017 key = 27; |
1888 update_panels(); |
2018 break; |
1889 } else { // Meta |
2019 default: |
1890 switch (key) { |
2020 scr_LogPrint(LPRINT_NORMAL, "Unknown key=M%d", kcode.value); |
1891 default: |
2021 } |
1892 scr_LogPrint(LPRINT_NORMAL, "Unknown key=M%d", key); |
2022 break; |
1893 } |
2023 default: |
1894 } |
2024 scr_LogPrint(LPRINT_NORMAL, "Unknown mkeycode! (%d)", kcode.mcode); |
1895 key = -1; |
2025 key = ERR; |
1896 } |
2026 } |
|
2027 |
1897 switch (key) { |
2028 switch (key) { |
1898 case -1: |
2029 case 0: |
|
2030 case ERR: |
1899 break; |
2031 break; |
1900 case 8: // Ctrl-h |
2032 case 8: // Ctrl-h |
1901 case 127: // Backspace too |
2033 case 127: // Backspace too |
1902 case KEY_BACKSPACE: |
2034 case KEY_BACKSPACE: |
1903 if (ptr_inputline != (char*)&inputLine) { |
2035 if (ptr_inputline != (char*)&inputLine) { |