diff options
| -rw-r--r-- | boxes.c | 245 |
1 files changed, 141 insertions, 104 deletions
| @@ -1741,15 +1741,57 @@ void nop(box *box, event *event) | |||
| 1741 | } | 1741 | } |
| 1742 | 1742 | ||
| 1743 | 1743 | ||
| 1744 | static struct keyCommand *lineLoop(long extra) | ||
| 1745 | { | ||
| 1746 | struct _view *view = (struct _view *) extra; // Though we pretty much stomp on this straight away. | ||
| 1747 | int y, len; | ||
| 1748 | |||
| 1749 | // Coz things might change out from under us, find the current view. | ||
| 1750 | if (commandMode) view = commandLine; | ||
| 1751 | else view = currentBox->view; | ||
| 1752 | // Draw the prompt and the current line. | ||
| 1753 | y = view->Y + (view->cY - view->offsetY); | ||
| 1754 | len = strlen(view->prompt); | ||
| 1755 | drawLine(y, view->X, view->X + view->W, "", " ", view->prompt, "", 0); | ||
| 1756 | drawContentLine(view, y, view->X + len, view->X + view->W, "", " ", view->line->line, "", 1); | ||
| 1757 | // Move the cursor. | ||
| 1758 | printf("\x1B[%d;%dH", y + 1, view->X + len + (view->cX - view->offsetX) + 1); | ||
| 1759 | fflush(stdout); | ||
| 1760 | |||
| 1761 | // This is using the currentBox instead of view, coz the command line keys are part of the box context now, not separate. | ||
| 1762 | // More importantly, the currentBox may change due to a command. | ||
| 1763 | return currentBox->view->content->context->modes[currentBox->view->mode].keys; | ||
| 1764 | } | ||
| 1765 | |||
| 1766 | static void lineChar(long extra, char *buffer) | ||
| 1767 | { | ||
| 1768 | struct _view *view = (struct _view *) extra; // Though we pretty much stomp on this straight away. | ||
| 1769 | |||
| 1770 | // Coz things might change out from under us, find the current view. | ||
| 1771 | if (commandMode) view = commandLine; | ||
| 1772 | else view = currentBox->view; | ||
| 1773 | // TODO - Should check for tabs to, and insert them. | ||
| 1774 | // Though better off having a function for that? | ||
| 1775 | // TODO - see if I can get these out of here. Some sort of pushCharacter(buffer, blob) that is passed in. | ||
| 1776 | mooshStrings(view->line, buffer, view->iX, 0, !TT.overWriteMode); | ||
| 1777 | view->oW = formatLine(view, view->line->line, &(view->output)); | ||
| 1778 | moveCursorRelative(view, strlen(buffer), 0, 0, 0); | ||
| 1779 | } | ||
| 1780 | |||
| 1781 | static void lineCommand(long extra, char *command, event *event) | ||
| 1782 | { | ||
| 1783 | struct _view *view = (struct _view *) extra; // Though we pretty much stomp on this straight away. | ||
| 1784 | |||
| 1785 | // Coz things might change out from under us, find the current view. | ||
| 1786 | if (commandMode) view = commandLine; | ||
| 1787 | else view = currentBox->view; | ||
| 1788 | doCommand(view->content->context->commands, command, view, event); | ||
| 1789 | } | ||
| 1790 | |||
| 1744 | // Basically this is the main loop. | 1791 | // Basically this is the main loop. |
| 1745 | 1792 | ||
| 1746 | // X and Y are screen coords. | 1793 | void editLine(long extra, struct keyCommand *(*lineLoop)(long extra), void (*lineChar)(long extra, char *buffer), void (*lineCommand)(long extra, char *command, event *event)) |
| 1747 | // W and H are the size of the editLine. EditLine will start one line high, and grow to a maximum of H if needed, then start to scroll. | ||
| 1748 | // H more than one means the editLine can grow upwards, unless it's at the top of the box / screen, then it has to grow downwards. | ||
| 1749 | // X, Y, W, and H can be -1, which means to grab suitable numbers from the views box. | ||
| 1750 | void editLine(view *view, int16_t X, int16_t Y, int16_t W, int16_t H) | ||
| 1751 | { | 1794 | { |
| 1752 | struct termios termio, oldtermio; | ||
| 1753 | struct pollfd pollfds[1]; | 1795 | struct pollfd pollfds[1]; |
| 1754 | char buffer[20]; | 1796 | char buffer[20]; |
| 1755 | char command[20]; | 1797 | char command[20]; |
| @@ -1762,56 +1804,15 @@ void editLine(view *view, int16_t X, int16_t Y, int16_t W, int16_t H) | |||
| 1762 | buffer[0] = 0; | 1804 | buffer[0] = 0; |
| 1763 | command[0] = 0; | 1805 | command[0] = 0; |
| 1764 | 1806 | ||
| 1765 | if (view->box) | ||
| 1766 | sizeViewToBox(view->box, X, Y, W, H); | ||
| 1767 | // Assumes the view was already setup if it's not part of a box. | ||
| 1768 | |||
| 1769 | // All the mouse tracking methods suck one way or another. sigh | ||
| 1770 | // Enable mouse (VT200 normal tracking mode, UTF8 encoding). The limit is 2015. Seems to only be in later xterms. | ||
| 1771 | // printf("\x1B[?1005h"); | ||
| 1772 | // Enable mouse (DEC locator reporting mode). In theory has no limit. Wont actually work though. | ||
| 1773 | // On the other hand, only allows for four buttons, so only half a mouse wheel. | ||
| 1774 | // printf("\x1B[1;2'z\x1B[1;3'{"); | ||
| 1775 | // Enable mouse (VT200 normal tracking mode). Has a limit of 256 - 32 rows and columns. An xterm exclusive I think, but works in roxterm at least. | ||
| 1776 | printf("\x1B[?1000h"); | ||
| 1777 | fflush(stdout); | ||
| 1778 | // TODO - Should remember to turn off mouse reporting when we leave. | ||
| 1779 | |||
| 1780 | // Grab the old terminal settings and save it. | ||
| 1781 | tcgetattr(0, &oldtermio); | ||
| 1782 | tcflush(0, TCIFLUSH); | ||
| 1783 | termio = oldtermio; | ||
| 1784 | |||
| 1785 | // Mould the terminal to our will. | ||
| 1786 | termio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); | ||
| 1787 | termio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP|ICANON); | ||
| 1788 | termio.c_cc[VTIME]=0; // deciseconds. | ||
| 1789 | termio.c_cc[VMIN]=1; | ||
| 1790 | tcsetattr(0, TCSANOW, &termio); | ||
| 1791 | |||
| 1792 | calcBoxes(currentBox); | ||
| 1793 | drawBoxes(currentBox); | ||
| 1794 | |||
| 1795 | // TODO - OS buffered keys might be a problem, but we can't do the usual timestamp filter for now. | 1807 | // TODO - OS buffered keys might be a problem, but we can't do the usual timestamp filter for now. |
| 1808 | TT.stillRunning = 1; | ||
| 1796 | while (TT.stillRunning) | 1809 | while (TT.stillRunning) |
| 1797 | { | 1810 | { |
| 1798 | // TODO - We can reuse one or two of these to have less of them. | 1811 | int j, p; |
| 1799 | int j = 0, p, ret, y, len; | 1812 | char *found = NULL; |
| 1800 | 1813 | // We do this coz the command set might change out from under us in response to commands. | |
| 1801 | // This is using the currentBox instead of view, coz the command line keys are part of the box context now, not separate. | 1814 | // So lineLoop should return the current command set if nothing else. |
| 1802 | // More importantly, the currentBox may change due to a command. | 1815 | struct keyCommand *ourKeys = lineLoop(extra); |
| 1803 | struct keyCommand *ourKeys = currentBox->view->content->context->modes[currentBox->view->mode].keys; | ||
| 1804 | |||
| 1805 | // Coz things might change out from under us, find the current view. | ||
| 1806 | // TODO - see if I can get this lot out of here. | ||
| 1807 | if (commandMode) view = commandLine; | ||
| 1808 | else view = currentBox->view; | ||
| 1809 | y = view->Y + (view->cY - view->offsetY); | ||
| 1810 | len = strlen(view->prompt); | ||
| 1811 | drawLine(y, view->X, view->X + view->W, "\0", " ", view->prompt, '\0', 0); | ||
| 1812 | drawContentLine(view, y, view->X + len, view->X + view->W, "\0", " ", view->line->line, '\0', 1); | ||
| 1813 | printf("\x1B[%d;%dH", y + 1, view->X + len + (view->cX - view->offsetX) + 1); | ||
| 1814 | fflush(stdout); | ||
| 1815 | 1816 | ||
| 1816 | // Apparently it's more portable to reset this each time. | 1817 | // Apparently it's more portable to reset this each time. |
| 1817 | memset(pollfds, 0, pollcount * sizeof(struct pollfd)); | 1818 | memset(pollfds, 0, pollcount * sizeof(struct pollfd)); |
| @@ -1832,7 +1833,7 @@ void editLine(view *view, int16_t X, int16_t Y, int16_t W, int16_t H) | |||
| 1832 | index = 0; | 1833 | index = 0; |
| 1833 | buffer[0] = 0; | 1834 | buffer[0] = 0; |
| 1834 | } | 1835 | } |
| 1835 | // TODO - Send a timer event somewhere. This wont be a precise timed event, but don't think we need one. | 1836 | // TODO - Send a timer event to lineCommand(). This wont be a precise timed event, but don't think we need one. |
| 1836 | } | 1837 | } |
| 1837 | 1838 | ||
| 1838 | while (0 < p) | 1839 | while (0 < p) |
| @@ -1842,21 +1843,21 @@ void editLine(view *view, int16_t X, int16_t Y, int16_t W, int16_t H) | |||
| 1842 | { | 1843 | { |
| 1843 | // I am assuming that we get the input atomically, each multibyte key fits neatly into one read. | 1844 | // I am assuming that we get the input atomically, each multibyte key fits neatly into one read. |
| 1844 | // If that's not true (which is entirely likely), then we have to get complicated with circular buffers and stuff, or just one byte at a time. | 1845 | // If that's not true (which is entirely likely), then we have to get complicated with circular buffers and stuff, or just one byte at a time. |
| 1845 | ret = read(pollfds[p].fd, &buffer[index], sizeof(buffer) - (index + 1)); | 1846 | j = read(pollfds[p].fd, &buffer[index], sizeof(buffer) - (index + 1)); |
| 1846 | if (ret < 0) // An error happened. | 1847 | if (j < 0) // An error happened. |
| 1847 | { | 1848 | { |
| 1848 | // For now, just ignore errors. | 1849 | // For now, just ignore errors. |
| 1849 | fprintf(stderr, "input error on %d\n", p); | 1850 | fprintf(stderr, "input error on %d\n", p); |
| 1850 | fflush(stderr); | 1851 | fflush(stderr); |
| 1851 | } | 1852 | } |
| 1852 | else if (ret == 0) // End of file. | 1853 | else if (j == 0) // End of file. |
| 1853 | { | 1854 | { |
| 1854 | fprintf(stderr, "EOF\n"); | 1855 | fprintf(stderr, "EOF\n"); |
| 1855 | fflush(stderr); | 1856 | fflush(stderr); |
| 1856 | } | 1857 | } |
| 1857 | else | 1858 | else |
| 1858 | { | 1859 | { |
| 1859 | index += ret; | 1860 | index += j; |
| 1860 | if (sizeof(buffer) < (index + 1)) // Ran out of buffer. | 1861 | if (sizeof(buffer) < (index + 1)) // Ran out of buffer. |
| 1861 | { | 1862 | { |
| 1862 | fprintf(stderr, "Full buffer - %s -> %s\n", buffer, command); | 1863 | fprintf(stderr, "Full buffer - %s -> %s\n", buffer, command); |
| @@ -1873,7 +1874,7 @@ void editLine(view *view, int16_t X, int16_t Y, int16_t W, int16_t H) | |||
| 1873 | 1874 | ||
| 1874 | // For a real timeout checked Esc, buffer is now empty, so this for loop wont find it anyway. | 1875 | // For a real timeout checked Esc, buffer is now empty, so this for loop wont find it anyway. |
| 1875 | // While it's true we could avoid it by checking, the user already had to wait for a time out, and this loop wont take THAT long. | 1876 | // While it's true we could avoid it by checking, the user already had to wait for a time out, and this loop wont take THAT long. |
| 1876 | for (j = 0; keys[j].code; j++) // Search for multibyte keys and some control keys. | 1877 | for (j = 0; keys[j].code; j++) // Search for multibyte keys and control keys. |
| 1877 | { | 1878 | { |
| 1878 | if (strcmp(keys[j].code, buffer) == 0) | 1879 | if (strcmp(keys[j].code, buffer) == 0) |
| 1879 | { | 1880 | { |
| @@ -1887,42 +1888,26 @@ void editLine(view *view, int16_t X, int16_t Y, int16_t W, int16_t H) | |||
| 1887 | // See if it's an ordinary key, | 1888 | // See if it's an ordinary key, |
| 1888 | if ((1 == index) && isprint(buffer[0])) | 1889 | if ((1 == index) && isprint(buffer[0])) |
| 1889 | { | 1890 | { |
| 1890 | int visucks = 0; | 1891 | // Here we want to run it through the command finder first, and only "insert" it if it's not a command. |
| 1891 | |||
| 1892 | // Here we want to pass it to the command finder first, and only "insert" it if it's not a command. | ||
| 1893 | // Less and more have the "ZZ" command, but nothing else seems to have multi ordinary character commands. | ||
| 1894 | // Less and more also have some ordinary character commands, mostly vi like. | ||
| 1895 | for (j = 0; ourKeys[j].key; j++) | 1892 | for (j = 0; ourKeys[j].key; j++) |
| 1896 | { | 1893 | { |
| 1897 | // Yes, that's right, we are scanning ourKeys twice, coz vi. | ||
| 1898 | // TODO - We can wriggle out of this later by bumping visucks up a scope and storing a pointer to ourKeys[j].command. | ||
| 1899 | // In fact, visucks could be that pointer. | ||
| 1900 | if (strcmp(ourKeys[j].key, buffer) == 0) | 1894 | if (strcmp(ourKeys[j].key, buffer) == 0) |
| 1901 | { | 1895 | { |
| 1902 | strcpy(command, buffer); | 1896 | strcpy(command, buffer); |
| 1903 | visucks = 1; | 1897 | found = command; |
| 1904 | break; | 1898 | break; |
| 1905 | } | 1899 | } |
| 1906 | } | 1900 | } |
| 1907 | // If there's an outstanding command, add this to the end of it. | 1901 | if (NULL == found) |
| 1908 | if (!visucks) | ||
| 1909 | { | 1902 | { |
| 1903 | // If there's an outstanding command, add this to the end of it. | ||
| 1910 | if (command[0]) strcat(command, buffer); | 1904 | if (command[0]) strcat(command, buffer); |
| 1911 | else | 1905 | else lineChar(extra, buffer); |
| 1912 | { | ||
| 1913 | // TODO - Should check for tabs to, and insert them. | ||
| 1914 | // Though better off having a function for that? | ||
| 1915 | // TODO - see if I can get these out of here. Some sort of pushCharacter(buffer, blob) that is passed in. | ||
| 1916 | mooshStrings(view->line, buffer, view->iX, 0, !TT.overWriteMode); | ||
| 1917 | view->oW = formatLine(view, view->line->line, &(view->output)); | ||
| 1918 | moveCursorRelative(view, strlen(buffer), 0, 0, 0); | ||
| 1919 | } | ||
| 1920 | } | 1906 | } |
| 1921 | index = 0; | 1907 | index = 0; |
| 1922 | buffer[0] = 0; | 1908 | buffer[0] = 0; |
| 1923 | } | 1909 | } |
| 1924 | 1910 | ||
| 1925 | // TODO - If the view->context has an event handler, use it, otherwise look up the specific event handler in the context modes ourselves. | ||
| 1926 | if (command[0]) // Search for a bound key. | 1911 | if (command[0]) // Search for a bound key. |
| 1927 | { | 1912 | { |
| 1928 | if (sizeof(command) < (strlen(command) + 1)) | 1913 | if (sizeof(command) < (strlen(command) + 1)) |
| @@ -1932,21 +1917,25 @@ void editLine(view *view, int16_t X, int16_t Y, int16_t W, int16_t H) | |||
| 1932 | command[0] = 0; | 1917 | command[0] = 0; |
| 1933 | } | 1918 | } |
| 1934 | 1919 | ||
| 1935 | for (j = 0; ourKeys[j].key; j++) | 1920 | if (NULL == found) |
| 1936 | { | 1921 | { |
| 1937 | if (strcmp(ourKeys[j].key, command) == 0) | 1922 | for (j = 0; ourKeys[j].key; j++) |
| 1938 | { | 1923 | { |
| 1939 | doCommand(view->content->context->commands, ourKeys[j].command, view, NULL); | 1924 | if (strcmp(ourKeys[j].key, command) == 0) |
| 1940 | command[0] = 0; | 1925 | { |
| 1941 | break; | 1926 | found = ourKeys[j].command; |
| 1927 | break; | ||
| 1928 | } | ||
| 1942 | } | 1929 | } |
| 1943 | } | 1930 | } |
| 1931 | if (found) | ||
| 1932 | { | ||
| 1933 | // That last argument, an event pointer, should be the original raw keystrokes, though by this time that's been cleared. | ||
| 1934 | lineCommand(extra, found, NULL); | ||
| 1935 | command[0] = 0; | ||
| 1936 | } | ||
| 1944 | } | 1937 | } |
| 1945 | |||
| 1946 | } | 1938 | } |
| 1947 | |||
| 1948 | // Restore the old terminal settings. | ||
| 1949 | tcsetattr(0, TCSANOW, &oldtermio); | ||
| 1950 | } | 1939 | } |
| 1951 | 1940 | ||
| 1952 | 1941 | ||
| @@ -2591,22 +2580,10 @@ struct context simpleVi = | |||
| 2591 | void boxes_main(void) | 2580 | void boxes_main(void) |
| 2592 | { | 2581 | { |
| 2593 | struct context *context = &simpleMcedit; // The default is mcedit, coz that's what I use. | 2582 | struct context *context = &simpleMcedit; // The default is mcedit, coz that's what I use. |
| 2583 | struct termios termio, oldtermio; | ||
| 2594 | char *prompt = "Enter a command : "; | 2584 | char *prompt = "Enter a command : "; |
| 2595 | unsigned W = 80, H = 24; | 2585 | unsigned W = 80, H = 24; |
| 2596 | 2586 | ||
| 2597 | // TODO - Should do an isatty() here, though not sure about the usefullness of driving this from a script or redirected input, since it's supposed to be a UI for terminals. | ||
| 2598 | // It would STILL need the terminal size for output though. Perhaps just bitch and abort if it's not a tty? | ||
| 2599 | // On the other hand, sed don't need no stinkin' UI. And things like more or less should be usable on the end of a pipe. | ||
| 2600 | |||
| 2601 | // TODO - set up a handler for SIGWINCH to find out when the terminal has been resized. | ||
| 2602 | terminal_size(&W, &H); | ||
| 2603 | if (toys.optflags & FLAG_w) | ||
| 2604 | W = TT.w; | ||
| 2605 | if (toys.optflags & FLAG_h) | ||
| 2606 | H = TT.h; | ||
| 2607 | |||
| 2608 | TT.stillRunning = 1; | ||
| 2609 | |||
| 2610 | // For testing purposes, figure out which context we use. When this gets real, the toybox multiplexer will sort this out for us instead. | 2587 | // For testing purposes, figure out which context we use. When this gets real, the toybox multiplexer will sort this out for us instead. |
| 2611 | if (toys.optflags & FLAG_m) | 2588 | if (toys.optflags & FLAG_m) |
| 2612 | { | 2589 | { |
| @@ -2626,8 +2603,48 @@ void boxes_main(void) | |||
| 2626 | context = &simpleVi; | 2603 | context = &simpleVi; |
| 2627 | } | 2604 | } |
| 2628 | 2605 | ||
| 2606 | // TODO - Should do an isatty() here, though not sure about the usefullness of driving this from a script or redirected input, since it's supposed to be a UI for terminals. | ||
| 2607 | // It would STILL need the terminal size for output though. Perhaps just bitch and abort if it's not a tty? | ||
| 2608 | // On the other hand, sed don't need no stinkin' UI. And things like more or less should be usable on the end of a pipe. | ||
| 2609 | |||
| 2610 | // Grab the old terminal settings and save it. | ||
| 2611 | tcgetattr(0, &oldtermio); | ||
| 2612 | tcflush(0, TCIFLUSH); | ||
| 2613 | termio = oldtermio; | ||
| 2614 | |||
| 2615 | // Mould the terminal to our will. | ||
| 2616 | /* | ||
| 2617 | IUCLC (not in POSIX) Map uppercase characters to lowercase on input. | ||
| 2618 | IXON Enable XON/XOFF flow control on output. | ||
| 2619 | IXOFF Enable XON/XOFF flow control on input. | ||
| 2620 | IXANY (not in POSIX.1; XSI) Enable any character to restart output. | ||
| 2621 | |||
| 2622 | ECHO Echo input characters. | ||
| 2623 | ECHOE If ICANON is also set, the ERASE character erases the preceding input character, and WERASE erases the preceding word. | ||
| 2624 | ECHOK If ICANON is also set, the KILL character erases the current line. | ||
| 2625 | ECHONL If ICANON is also set, echo the NL character even if ECHO is not set. | ||
| 2626 | TOSTOP Send the SIGTTOU signal to the process group of a background process which tries to write to its controlling terminal. | ||
| 2627 | ICANON Enable canonical mode. This enables the special characters EOF, EOL, EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, and WERASE, and buffers by lines. | ||
| 2628 | |||
| 2629 | VTIME Timeout in deciseconds for non-canonical read. | ||
| 2630 | VMIN Minimum number of characters for non-canonical read. | ||
| 2631 | */ | ||
| 2632 | termio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); | ||
| 2633 | termio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP|ICANON); | ||
| 2634 | termio.c_cc[VTIME]=0; // deciseconds. | ||
| 2635 | termio.c_cc[VMIN]=1; | ||
| 2636 | tcsetattr(0, TCSANOW, &termio); | ||
| 2637 | |||
| 2638 | // TODO - set up a handler for SIGWINCH to find out when the terminal has been resized. | ||
| 2639 | terminal_size(&W, &H); | ||
| 2640 | if (toys.optflags & FLAG_w) | ||
| 2641 | W = TT.w; | ||
| 2642 | if (toys.optflags & FLAG_h) | ||
| 2643 | H = TT.h; | ||
| 2644 | |||
| 2629 | // Create the main box. Right now the system needs one for wrapping around while switching. The H - 1 bit is to leave room for our example command line. | 2645 | // Create the main box. Right now the system needs one for wrapping around while switching. The H - 1 bit is to leave room for our example command line. |
| 2630 | rootBox = addBox("root", context, toys.optargs[0], 0, 0, W, H - 1); | 2646 | rootBox = addBox("root", context, toys.optargs[0], 0, 0, W, H - 1); |
| 2647 | currentBox = rootBox; | ||
| 2631 | 2648 | ||
| 2632 | // Create the command line view, sharing the same context as the root. It will differentiate based on the view mode of the current box. | 2649 | // Create the command line view, sharing the same context as the root. It will differentiate based on the view mode of the current box. |
| 2633 | // Also load the command line history as it's file. | 2650 | // Also load the command line history as it's file. |
| @@ -2639,9 +2656,29 @@ void boxes_main(void) | |||
| 2639 | // Move to the end of the history. | 2656 | // Move to the end of the history. |
| 2640 | moveCursorAbsolute(commandLine, 0, commandLine->content->lines.length, 0, 0); | 2657 | moveCursorAbsolute(commandLine, 0, commandLine->content->lines.length, 0, 0); |
| 2641 | 2658 | ||
| 2659 | // All the mouse tracking methods suck one way or another. sigh | ||
| 2660 | // http://leonerds-code.blogspot.co.uk/2012/04/wide-mouse-support-in-libvterm.html is helpful. | ||
| 2661 | // Enable mouse (VT200 normal tracking mode, UTF8 encoding). The limit is 2015. Seems to only be in later xterms. | ||
| 2662 | // printf("\x1B[?1005h"); | ||
| 2663 | // Enable mouse (VT340 locator reporting mode). In theory has no limit. Wont actually work though. | ||
| 2664 | // On the other hand, only allows for four buttons, so only half a mouse wheel. | ||
| 2665 | // Responds with "\1B[e;p;r;c;p&w" where e is event type, p is a bitmap of buttons pressed, r and c are the mouse coords in decimal, and p is the "page number". | ||
| 2666 | // printf("\x1B[1;2'z\x1B[1;3'{"); | ||
| 2667 | // Enable mouse (VT200 normal tracking mode). Has a limit of 256 - 32 rows and columns. An xterm exclusive I think, but works in roxterm at least. No wheel reports. | ||
| 2668 | // Responds with "\x1B[Mbxy" where x and y are the mouse coords, and b is bit encoded buttons and modifiers - 0=MB1 pressed, 1=MB2 pressed, 2=MB3 pressed, 3=release, 4=Shift, 8=Meta, 16=Control | ||
| 2669 | printf("\x1B[?1000h"); | ||
| 2670 | fflush(stdout); | ||
| 2671 | |||
| 2672 | calcBoxes(currentBox); | ||
| 2673 | drawBoxes(currentBox); | ||
| 2674 | |||
| 2642 | // Run the main loop. | 2675 | // Run the main loop. |
| 2643 | currentBox = rootBox; | 2676 | editLine((long) currentBox->view, lineLoop, lineChar, lineCommand); |
| 2644 | editLine(currentBox->view, -1, -1, -1, -1); | 2677 | |
| 2678 | // TODO - Should remember to turn off mouse reporting when we leave. | ||
| 2679 | |||
| 2680 | // Restore the old terminal settings. | ||
| 2681 | tcsetattr(0, TCSANOW, &oldtermio); | ||
| 2645 | 2682 | ||
| 2646 | puts("\n"); | 2683 | puts("\n"); |
| 2647 | fflush(stdout); | 2684 | fflush(stdout); |
