mcabber/src/screen.c
changeset 761 4532a9fe0e8c
parent 760 715952c2f37f
child 762 96d46e00524a
equal deleted inserted replaced
760:715952c2f37f 761:4532a9fe0e8c
    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) {
  2028         scr_Resize();
  2160         scr_Resize();
  2029         redrawwin(stdscr);
  2161         redrawwin(stdscr);
  2030         break;
  2162         break;
  2031     case KEY_RESIZE:
  2163     case KEY_RESIZE:
  2032         scr_Resize();
  2164         scr_Resize();
       
  2165         break;
       
  2166     case 27:    // ESC
       
  2167         scr_CheckAutoAway(TRUE);
       
  2168         currentWindow = NULL;
       
  2169         chatmode = FALSE;
       
  2170         if (current_buddy)
       
  2171           buddy_setflags(BUDDATA(current_buddy), ROSTER_FLAG_LOCK, FALSE);
       
  2172         scr_RosterVisibility(1);
       
  2173         scr_UpdateChatStatus(FALSE);
       
  2174         top_panel(chatPanel);
       
  2175         top_panel(inputPanel);
       
  2176         update_panels();
  2033         break;
  2177         break;
  2034     default:
  2178     default:
  2035         if (isprint(key)) {
  2179         if (isprint(key)) {
  2036           char tmpLine[INPUTLINE_LENGTH+1];
  2180           char tmpLine[INPUTLINE_LENGTH+1];
  2037 
  2181