void rtext_key(t_rtext *x, int keynum, t_symbol *keysym) { int w = 0, h = 0, indx, i, newsize, ndel; char *s1, *s2; //fprintf(stderr,"rtext_key keysym=%s\n", keysym->s_name); if (keynum) { int n = keynum; if (n == '\r') n = '\n'; if (n == '\b') /* backspace */ { /* LATER delete the box if all text is selected... this causes reentrancy problems now. */ /* if ((!x->x_selstart) && (x->x_selend == x->x_bufsize)) { .... } */ if (x->x_selstart && (x->x_selstart == x->x_selend)) { u8_dec(x->x_buf, &x->x_selstart); if (glist_isvisible(glist_getcanvas(x->x_glist))) sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)glist_getcanvas(x->x_glist)); } } else if (n == 127) /* delete */ { if (x->x_selend < x->x_bufsize && (x->x_selstart == x->x_selend)) u8_inc(x->x_buf, &x->x_selend); if (glist_isvisible(glist_getcanvas(x->x_glist))) sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)glist_getcanvas(x->x_glist)); } ndel = x->x_selend - x->x_selstart; for (i = x->x_selend; i < x->x_bufsize; i++) x->x_buf[i- ndel] = x->x_buf[i]; newsize = x->x_bufsize - ndel; x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); x->x_bufsize = newsize; /* at Guenter's suggestion, use 'n>31' to test wither a character might be printable in whatever 8-bit character set we find ourselves. */ /*-- moo: ... but test with "<" rather than "!=" in order to accomodate unicode codepoints for n (which we get since Tk is sending the "%A" substitution for bind <Key>), effectively reducing the coverage of this clause to 7 bits. Case n>127 is covered by the next clause. */ if (n == '\n' || (n > 31 && n < 127)) { //fprintf(stderr,"return or 31-127\n"); newsize = x->x_bufsize+1; x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); for (i = x->x_bufsize; i > x->x_selstart; i--) x->x_buf[i] = x->x_buf[i-1]; x->x_buf[x->x_selstart] = n; x->x_bufsize = newsize; x->x_selstart = x->x_selstart + 1; if (glist_isvisible(glist_getcanvas(x->x_glist))) sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)glist_getcanvas(x->x_glist)); } /*--moo: check for unicode codepoints beyond 7-bit ASCII --*/ else if (n > 127) { //fprintf(stderr,">127\n"); int ch_nbytes = u8_wc_nbytes(n); newsize = x->x_bufsize + ch_nbytes; x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); for (i = x->x_bufsize; i > x->x_selstart; i--) x->x_buf[i] = x->x_buf[i-1]; x->x_bufsize = newsize; /*-- moo: assume canvas_key() has encoded keysym as UTF-8 */ strncpy(x->x_buf+x->x_selstart, keysym->s_name, ch_nbytes); x->x_selstart = x->x_selstart + ch_nbytes; } x->x_selend = x->x_selstart; x->x_glist->gl_editor->e_textdirty = 1; } else if (!strcmp(keysym->s_name, "Right")) { if (x->x_selend == x->x_selstart && x->x_selstart < x->x_bufsize) { u8_inc(x->x_buf, &x->x_selstart); x->x_selend = x->x_selstart; } else x->x_selstart = x->x_selend; last_sel = 0; } else if (!strcmp(keysym->s_name, "Left")) { if (x->x_selend == x->x_selstart && x->x_selstart > 0) { u8_dec(x->x_buf, &x->x_selstart); x->x_selend = x->x_selstart; } else x->x_selend = x->x_selstart; last_sel = 0; } else if (!strcmp(keysym->s_name, "ShiftRight")) { if (!last_sel) last_sel = 2; if (last_sel == 1 && x->x_selstart < x->x_selend) { if (x->x_selstart < x->x_bufsize) u8_inc(x->x_buf, &x->x_selstart); } else { last_sel = 2; if (x->x_selend < x->x_bufsize) u8_inc(x->x_buf, &x->x_selend); } } else if (!strcmp(keysym->s_name, "ShiftLeft")) { if (!last_sel) last_sel = 1; if (last_sel == 2 && x->x_selend > x->x_selstart) { x->x_selend = x->x_selend - 1; } else { last_sel = 1; if (x->x_selstart > 0) u8_dec(x->x_buf, &x->x_selstart); } } else if (!strcmp(keysym->s_name, "Up")) { if (x->x_selstart) u8_dec(x->x_buf, &x->x_selstart); while (x->x_selstart > 0 && (x->x_buf[x->x_selstart] != '\n' && x->x_buf[x->x_selstart] != '\v')) u8_dec(x->x_buf, &x->x_selstart); x->x_selend = x->x_selstart; last_sel = 0; } else if (!strcmp(keysym->s_name, "Down")) { while (x->x_selend < x->x_bufsize && (x->x_buf[x->x_selend] != '\n' && x->x_buf[x->x_selend] != '\v')) u8_inc(x->x_buf, &x->x_selend); if (x->x_selend < x->x_bufsize) u8_inc(x->x_buf, &x->x_selend); x->x_selstart = x->x_selend; last_sel = 0; } else if (!strcmp(keysym->s_name, "Home")) { if (x->x_selstart) u8_dec(x->x_buf, &x->x_selstart); while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n') u8_dec(x->x_buf, &x->x_selstart); x->x_selend = x->x_selstart; last_sel = 0; } else if (!strcmp(keysym->s_name, "End")) { while (x->x_selend < x->x_bufsize && x->x_buf[x->x_selend] != '\n') u8_inc(x->x_buf, &x->x_selend); if (x->x_selend < x->x_bufsize) u8_inc(x->x_buf, &x->x_selend); x->x_selstart = x->x_selend; last_sel = 0; } else if (!strcmp(keysym->s_name, "CtrlLeft")) { //fprintf(stderr,"ctrleft\n"); /* first find first non-space char going back */ while (x->x_selstart > 0 && rtext_compare_special_chars(x->x_buf[x->x_selstart-1])) { //fprintf(stderr,"while 1 <%c>\n", x->x_buf[x->x_selstart-1]); u8_dec(x->x_buf, &x->x_selstart); } /* now go back until you find another space or the beginning of the buffer */ while (x->x_selstart > 0 && !rtext_compare_special_chars(x->x_buf[x->x_selstart-1])) { //fprintf(stderr,"while 2 <%c>\n", x->x_buf[x->x_selstart-1]); u8_dec(x->x_buf, &x->x_selstart); } if (x->x_buf[x->x_selstart+1] == ' ' && x->x_buf[x->x_selstart] == ' ') { //fprintf(stderr,"go forward\n"); u8_inc(x->x_buf, &x->x_selstart); } x->x_selend = x->x_selstart; } else if (!strcmp(keysym->s_name, "CtrlRight")) { /* now go forward until you find another space or the end of the buffer */ if (x->x_selend < x->x_bufsize - 1) u8_inc(x->x_buf, &x->x_selend); while (x->x_selend < x->x_bufsize && !rtext_compare_special_chars(x->x_buf[x->x_selend])) u8_inc(x->x_buf, &x->x_selend); /* now skip all the spaces and land before next word */ /*while (x->x_selend < x->x_bufsize && x->x_buf[x->x_selend] == ' ') u8_inc(x->x_buf, &x->x_selend); if (x->x_selend > 0 && x->x_buf[x->x_selend-1] == ' ') u8_dec(x->x_buf, &x->x_selend);*/ x->x_selstart = x->x_selend; } else if (!strcmp(keysym->s_name, "CtrlShiftLeft")) { //fprintf(stderr,"ctrlshiftleft %d %d %d\n", // last_sel, x->x_selstart, x->x_selend); int swap = 0; int *target; if (!last_sel) last_sel = 1; if (last_sel == 2 && x->x_selend > x->x_selstart) target = &x->x_selend; else { last_sel = 1; target = &x->x_selstart; } /* first find first non-space char going back */ while (*target > 0 && rtext_compare_special_chars(x->x_buf[*target-1])) { u8_dec(x->x_buf, target); //(*target)--; } //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend); /* now go back until you find another space or the beginning of the buffer */ while (*target > 0 && !rtext_compare_special_chars(x->x_buf[*target-1])) { u8_dec(x->x_buf, target); //(*target)--; } //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend); if (x->x_buf[*target+1] == ' ' && x->x_buf[x->x_selstart] == ' ') { u8_inc(x->x_buf, target); //(*target)++; } //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend); if (x->x_selstart > x->x_selend) { swap = x->x_selend; x->x_selend = x->x_selstart; x->x_selstart = swap; last_sel = 1; } } else if (!strcmp(keysym->s_name, "CtrlShiftRight")) { //fprintf(stderr,"ctrlshiftright %d %d %d\n", // last_sel, x->x_selstart, x->x_selend); int swap = 0; int *target; if (!last_sel) last_sel = 2; if (last_sel == 1 && x->x_selstart < x->x_selend) target = &x->x_selstart; else { last_sel = 2; target = &x->x_selend; } //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend); /* now go forward until you find another space or the end of the buffer */ if (*target < x->x_bufsize - 1) { //fprintf(stderr,"while 1 <%c>\n", x->x_buf[*target]); u8_inc(x->x_buf, target); //(*target)++; } //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend); while (*target < x->x_bufsize && !rtext_compare_special_chars(x->x_buf[*target])) { //fprintf(stderr,"while 2 <%c>\n", x->x_buf[*target]); u8_inc(x->x_buf, target); //(*target)++; } /* now skip all the spaces and land before next word */ /*while (*target < x->x_bufsize && x->x_buf[*target] == ' ') { u8_inc(x->x_buf, target); //(*target)++; } if (*target > 0 && x->x_buf[*target-1] == ' ') { u8_dec(x->x_buf, target); //(*target)--; }*/ //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend); if (x->x_selstart > x->x_selend) { swap = x->x_selend; x->x_selend = x->x_selstart; x->x_selstart = swap; last_sel = 2; } //fprintf(stderr,"%d %d\n", x->x_selstart, x->x_selend); } rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); }
void rtext_key(t_rtext *x, int keynum, t_symbol *keysym) { //fprintf(stderr,"rtext_key %d %s\n", keynum, keysym->s_name); int w = 0, h = 0, indx, i, newsize, ndel; if (keynum) { int n = keynum; if (n == '\r' || n == '\v') n = '\n'; if (n == '\b') /* backspace */ { if (x->x_selstart && (x->x_selstart == x->x_selend)) { u8_dec(x->x_buf, &x->x_selstart); if (glist_isvisible(glist_getcanvas(x->x_glist))) canvas_getscroll(glist_getcanvas(x->x_glist)); } } else if (n == 127) /* delete */ { if (x->x_selend < x->x_bufsize && (x->x_selstart == x->x_selend)) u8_inc(x->x_buf, &x->x_selend); if (glist_isvisible(glist_getcanvas(x->x_glist))) canvas_getscroll(glist_getcanvas(x->x_glist)); } ndel = x->x_selend - x->x_selstart; if (ndel) { for (i = x->x_selend; i < x->x_bufsize; i++) x->x_buf[i- ndel] = x->x_buf[i]; newsize = x->x_bufsize - ndel; x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); x->x_bufsize = newsize; } /* at Guenter's suggestion, use 'n>31' to test wither a character might be printable in whatever 8-bit character set we find ourselves. */ /*-- moo: ... but test with "<" rather than "!=" in order to accomodate unicode codepoints for n (which we get since Tk is sending the "%A" substitution for bind <Key>), effectively reducing the coverage of this clause to 7 bits. Case n>127 is covered by the next clause. */ if (n == '\n' || (n > 31 && n < 127)) { newsize = x->x_bufsize+1; x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); for (i = x->x_bufsize; i > x->x_selstart; i--) x->x_buf[i] = x->x_buf[i-1]; x->x_buf[x->x_selstart] = n; x->x_bufsize = newsize; x->x_selstart = x->x_selstart + 1; if (glist_isvisible(glist_getcanvas(x->x_glist))) canvas_getscroll(glist_getcanvas(x->x_glist)); } /*--moo: check for unicode codepoints beyond 7-bit ASCII --*/ else if (n > 127) { int ch_nbytes = u8_wc_nbytes(n); newsize = x->x_bufsize + ch_nbytes; x->x_buf = resizebytes(x->x_buf, x->x_bufsize, newsize); //fprintf(stderr,"x->x_bufsize=%d newsize=%d\n", x->x_bufsize, newsize); //for (i = newsize-1; i >= x->x_selstart; i--) //{ //fprintf(stderr,"%d-%d <%d>\n", i, i-ch_nbytes, x->x_buf[i-ch_nbytes]); //x->x_buf[i] = '\0'; //} x->x_bufsize = newsize; /*-- moo: assume canvas_key() has encoded keysym as UTF-8 */ strncpy(x->x_buf+x->x_selstart, keysym->s_name, ch_nbytes); x->x_selstart = x->x_selstart + ch_nbytes; } x->x_selend = x->x_selstart; x->x_glist->gl_editor->e_textdirty = 1; } else if (!strcmp(keysym->s_name, "Right")) { if (x->x_selend == x->x_selstart && x->x_selstart < x->x_bufsize) { u8_inc(x->x_buf, &x->x_selstart); x->x_selend = x->x_selstart; } else x->x_selstart = x->x_selend; last_sel = 0; } else if (!strcmp(keysym->s_name, "Left")) { if (x->x_selend == x->x_selstart && x->x_selstart > 0) { u8_dec(x->x_buf, &x->x_selstart); x->x_selend = x->x_selstart; } else x->x_selend = x->x_selstart; last_sel = 0; } else if (!strcmp(keysym->s_name, "ShiftRight")) { if (!last_sel) last_sel = 2; if (last_sel == 1 && x->x_selstart < x->x_selend) { if (x->x_selstart < x->x_bufsize) u8_inc(x->x_buf, &x->x_selstart); } else { last_sel = 2; if (x->x_selend < x->x_bufsize) u8_inc(x->x_buf, &x->x_selend); } } else if (!strcmp(keysym->s_name, "ShiftLeft")) { if (!last_sel) last_sel = 1; if (last_sel == 2 && x->x_selend > x->x_selstart) { x->x_selend = x->x_selend - 1; } else { last_sel = 1; if (x->x_selstart > 0) u8_dec(x->x_buf, &x->x_selstart); } } else if (!strcmp(keysym->s_name, "Up")) { if (x->x_selstart != x->x_selend) { x->x_selend = x->x_selstart; last_sel = 0; } else { // we do this twice and then move to the right // as many spots as we had before, this will // allow us to go visually above where we used // to be in multiline situations (e.g. comments) int right = 0; //printf("start: selstart=%d x->x_bufsize=%d\n", x->x_selstart, x->x_bufsize); if (x->x_selstart > 0 && (x->x_selstart == x->x_bufsize || x->x_buf[x->x_selstart] == '\n' || x->x_buf[x->x_selstart] == '\v')) { //printf("found break\n"); u8_dec(x->x_buf, &x->x_selstart); right++; } while (x->x_selstart > 0 && (x->x_buf[x->x_selstart-1] != '\n' && x->x_buf[x->x_selstart-1] != '\v')) { u8_dec(x->x_buf, &x->x_selstart); right++; } if (x->x_selstart == 0) right = 0; //printf("first linebreak: right=%d selstart=%d\n", right, x->x_selstart); if (x->x_selstart > 0) u8_dec(x->x_buf, &x->x_selstart); //printf("decrease by 1: selstart=%d\n", x->x_selstart); while (x->x_selstart > 0 && (x->x_buf[x->x_selstart-1] != '\n' && x->x_buf[x->x_selstart-1] != '\v')) u8_dec(x->x_buf, &x->x_selstart); //printf("second linebreak: selstart=%d\n", x->x_selstart); if (x->x_selstart < x->x_bufsize && right > 0) { u8_inc(x->x_buf, &x->x_selstart); right--; } //printf("increase by 1: selstart=%d\n", x->x_selstart); while (right > 0 && (x->x_buf[x->x_selstart] != '\n' && x->x_buf[x->x_selstart] != '\v')) { u8_inc(x->x_buf, &x->x_selstart); right--; } //printf("final: selstart=%d\n", x->x_selstart); x->x_selend = x->x_selstart; last_sel = 0; } } else if (!strcmp(keysym->s_name, "Down")) { if (x->x_selstart != x->x_selend) { x->x_selstart = x->x_selend; last_sel = 0; } else { // we do this twice and then move to the right // as many spots as we had before, this will // allow us to go visually below where we used // to be in multiline situations (e.g. comments) int right = 0; if (x->x_selstart > 0 && (x->x_buf[x->x_selstart] != '\n' || x->x_buf[x->x_selstart] != '\v')) { while (x->x_selstart > 0 && (x->x_buf[x->x_selstart-1] != '\n' && x->x_buf[x->x_selstart-1] != '\v')) { x->x_selstart--; right++; } } //printf("start: right=%d selstart=%d selend=%d\n", right, x->x_selstart, x->x_selend); if (x->x_selend < x->x_bufsize && (x->x_buf[x->x_selend] == '\n' || x->x_buf[x->x_selend] == '\v')) { //printf("found break\n"); u8_inc(x->x_buf, &x->x_selend); right--; } else while (x->x_selend < x->x_bufsize && (x->x_buf[x->x_selend] != '\n' && x->x_buf[x->x_selend] != '\v')) { u8_inc(x->x_buf, &x->x_selend); } //printf("first linebreak: selend=%d\n", x->x_selend); if (x->x_selend+1 < x->x_bufsize) { u8_inc(x->x_buf, &x->x_selend); } //printf("increase by 1: selend=%d\n", x->x_selend); while (right > 0 && x->x_selend < x->x_bufsize && (x->x_buf[x->x_selend] != '\n' && x->x_buf[x->x_selend] != '\v')) { u8_inc(x->x_buf, &x->x_selend); right--; } //printf("final: selend=%d\n", x->x_selend); x->x_selstart = x->x_selend; last_sel = 0; } } else if (!strcmp(keysym->s_name, "Home")) { if (x->x_selstart) u8_dec(x->x_buf, &x->x_selstart); while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n') u8_dec(x->x_buf, &x->x_selstart); x->x_selend = x->x_selstart; last_sel = 0; } else if (!strcmp(keysym->s_name, "ShiftHome")) { if (x->x_selstart) { if (last_sel == 2) x->x_selend = x->x_selstart; u8_dec(x->x_buf, &x->x_selstart); last_sel = 1; } while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n') u8_dec(x->x_buf, &x->x_selstart); //x->x_selend = x->x_selstart; //last_sel = 1; } else if (!strcmp(keysym->s_name, "End")) { while (x->x_selend < x->x_bufsize && x->x_buf[x->x_selend] != '\n') u8_inc(x->x_buf, &x->x_selend); if (x->x_selend < x->x_bufsize) u8_inc(x->x_buf, &x->x_selend); x->x_selstart = x->x_selend; last_sel = 0; } else if (!strcmp(keysym->s_name, "ShiftEnd")) { if (last_sel == 1) x->x_selstart = x->x_selend; while (x->x_selend < x->x_bufsize && x->x_buf[x->x_selend] != '\n') u8_inc(x->x_buf, &x->x_selend); if (x->x_selend < x->x_bufsize) { u8_inc(x->x_buf, &x->x_selend); } //x->x_selstart = x->x_selend; last_sel = 2; } else if (!strcmp(keysym->s_name, "CtrlLeft")) { /* first find first non-space char going back */ while (x->x_selstart > 0 && rtext_compare_special_chars(x->x_buf[x->x_selstart-1])) { u8_dec(x->x_buf, &x->x_selstart); } /* now go back until you find another space or the beginning of the buffer */ while (x->x_selstart > 0 && !rtext_compare_special_chars(x->x_buf[x->x_selstart-1])) { u8_dec(x->x_buf, &x->x_selstart); } if (x->x_buf[x->x_selstart+1] == ' ' && x->x_buf[x->x_selstart] == ' ') { u8_inc(x->x_buf, &x->x_selstart); } x->x_selend = x->x_selstart; } else if (!strcmp(keysym->s_name, "CtrlRight")) { /* now go forward until you find another space or the end of the buffer */ if (x->x_selend < x->x_bufsize - 1) u8_inc(x->x_buf, &x->x_selend); while (x->x_selend < x->x_bufsize && !rtext_compare_special_chars(x->x_buf[x->x_selend])) u8_inc(x->x_buf, &x->x_selend); x->x_selstart = x->x_selend; } else if (!strcmp(keysym->s_name, "CtrlShiftLeft")) { int swap = 0; int *target; if (!last_sel) last_sel = 1; if (last_sel == 2 && x->x_selend > x->x_selstart) target = &x->x_selend; else { last_sel = 1; target = &x->x_selstart; } /* first find first non-space char going back */ while (*target > 0 && rtext_compare_special_chars(x->x_buf[*target-1])) { u8_dec(x->x_buf, target); } /* now go back until you find another space or the beginning of the buffer */ while (*target > 0 && !rtext_compare_special_chars(x->x_buf[*target-1])) { u8_dec(x->x_buf, target); } if (x->x_buf[*target+1] == ' ' && x->x_buf[x->x_selstart] == ' ') { u8_inc(x->x_buf, target); } if (x->x_selstart > x->x_selend) { swap = x->x_selend; x->x_selend = x->x_selstart; x->x_selstart = swap; last_sel = 1; } } else if (!strcmp(keysym->s_name, "CtrlShiftRight")) { int swap = 0; int *target; if (!last_sel) last_sel = 2; if (last_sel == 1 && x->x_selstart < x->x_selend) target = &x->x_selstart; else { last_sel = 2; target = &x->x_selend; } /* now go forward until you find another space or the end of the buffer */ if (*target < x->x_bufsize - 1) { u8_inc(x->x_buf, target); } while (*target < x->x_bufsize && !rtext_compare_special_chars(x->x_buf[*target])) { u8_inc(x->x_buf, target); } if (x->x_selstart > x->x_selend) { swap = x->x_selend; x->x_selend = x->x_selstart; x->x_selstart = swap; last_sel = 2; } } rtext_senditup(x, SEND_UPDATE, &w, &h, &indx); }