keyboardselect_st.c (6209B)
1 void set_notifmode(int type, KeySym ksym) 2 { 3 static char *lib[] = { " MOVE ", " SEL "}; 4 static Glyph *g, *deb, *fin; 5 static int col, bot; 6 7 if (ksym == -1) { 8 free(g); 9 col = term.col, bot = term.bot; 10 g = xmalloc(col * sizeof(Glyph)); 11 memcpy(g, term.line[bot], col * sizeof(Glyph)); 12 13 } else if (ksym == -2) 14 memcpy(term.line[bot], g, col * sizeof(Glyph)); 15 16 if ( type < 2 ) { 17 char *z = lib[type]; 18 for (deb = &term.line[bot][col - 6], fin = &term.line[bot][col]; deb < fin; z++, deb++) 19 deb->mode = ATTR_REVERSE, 20 deb->u = *z, 21 deb->fg = defaultfg, deb->bg = defaultbg; 22 } else if (type < 5) 23 memcpy(term.line[bot], g, col * sizeof(Glyph)); 24 else { 25 for (deb = &term.line[bot][0], fin = &term.line[bot][col]; deb < fin; deb++) 26 deb->mode = ATTR_REVERSE, 27 deb->u = ' ', 28 deb->fg = defaultfg, deb->bg = defaultbg; 29 term.line[bot][0].u = ksym; 30 } 31 32 term.dirty[bot] = 1; 33 drawregion(0, bot, col, bot + 1); 34 } 35 36 #if SCROLLBACK_PATCH && KEYBOARDSELECT_PATCH 37 Glyph getglyph(Term term, int y, int x) 38 { 39 Glyph g; 40 int realy = y - term.scr; 41 if(realy >= 0) { 42 g = term.line[realy][x]; 43 } else { 44 realy = term.histi - term.scr + y + 1; 45 g = term.hist[realy][x]; 46 } 47 return g; 48 } 49 #endif 50 51 void select_or_drawcursor(int selectsearch_mode, int type) 52 { 53 int done = 0; 54 55 if (selectsearch_mode & 1) { 56 selextend(term.c.x, term.c.y, type, done); 57 xsetsel(getsel()); 58 } else { 59 #if LIGATURES_PATCH 60 xdrawcursor(term.c.x, term.c.y, term.line[term.c.y][term.c.x], 61 term.ocx, term.ocy, term.line[term.ocy][term.ocx], 62 term.line[term.ocy], term.col); 63 #elif SCROLLBACK_PATCH && KEYBOARDSELECT_PATCH 64 xdrawcursor(term.c.x, term.c.y, getglyph(term, term.c.y, term.c.x), 65 term.ocx, term.ocy, getglyph(term, term.ocy, term.ocx)); 66 #else 67 xdrawcursor(term.c.x, term.c.y, term.line[term.c.y][term.c.x], 68 term.ocx, term.ocy, term.line[term.ocy][term.ocx]); 69 #endif // LIGATURES_PATCH 70 } 71 } 72 73 void search(int selectsearch_mode, Rune *target, int ptarget, int incr, int type, TCursor *cu) 74 { 75 Rune *r; 76 int i, bound = (term.col * cu->y + cu->x) * (incr > 0) + incr; 77 78 for (i = term.col * term.c.y + term.c.x + incr; i != bound; i += incr) { 79 for (r = target; r - target < ptarget; r++) { 80 if (*r == term.line[(i + r - target) / term.col][(i + r - target) % term.col].u) { 81 if (r - target == ptarget - 1) 82 break; 83 } else { 84 r = NULL; 85 break; 86 } 87 } 88 if (r != NULL) 89 break; 90 } 91 92 if (i != bound) { 93 term.c.y = i / term.col, term.c.x = i % term.col; 94 select_or_drawcursor(selectsearch_mode, type); 95 } 96 } 97 98 int trt_kbdselect(KeySym ksym, char *buf, int len) 99 { 100 static TCursor cu; 101 static Rune target[64]; 102 static int type = 1, ptarget, in_use; 103 static int sens, quant; 104 static char selectsearch_mode; 105 int i, bound, *xy; 106 107 if (selectsearch_mode & 2) { 108 if (ksym == XK_Return) { 109 selectsearch_mode ^= 2; 110 set_notifmode(selectsearch_mode, -2); 111 if (ksym == XK_Escape) 112 ptarget = 0; 113 return 0; 114 } else if (ksym == XK_BackSpace) { 115 if (!ptarget) 116 return 0; 117 term.line[term.bot][ptarget--].u = ' '; 118 } else if (len < 1) { 119 return 0; 120 } else if (ptarget == term.col || ksym == XK_Escape) { 121 return 0; 122 } else { 123 utf8decode(buf, &target[ptarget++], len); 124 term.line[term.bot][ptarget].u = target[ptarget - 1]; 125 } 126 127 if (ksym != XK_BackSpace) 128 search(selectsearch_mode, &target[0], ptarget, sens, type, &cu); 129 130 term.dirty[term.bot] = 1; 131 drawregion(0, term.bot, term.col, term.bot + 1); 132 return 0; 133 } 134 135 switch (ksym) { 136 case -1: 137 in_use = 1; 138 cu.x = term.c.x, cu.y = term.c.y; 139 set_notifmode(0, ksym); 140 return MODE_KBDSELECT; 141 case XK_s: 142 if (selectsearch_mode & 1) 143 selclear(); 144 else 145 selstart(term.c.x, term.c.y, 0); 146 set_notifmode(selectsearch_mode ^= 1, ksym); 147 break; 148 case XK_t: 149 selextend(term.c.x, term.c.y, type ^= 3, i = 0); /* 2 fois */ 150 selextend(term.c.x, term.c.y, type, i = 0); 151 break; 152 case XK_slash: 153 case XK_KP_Divide: 154 case XK_question: 155 ksym &= XK_question; /* Divide to slash */ 156 sens = (ksym == XK_slash) ? -1 : 1; 157 ptarget = 0; 158 set_notifmode(15, ksym); 159 selectsearch_mode ^= 2; 160 break; 161 case XK_Escape: 162 if (!in_use) 163 break; 164 selclear(); 165 case XK_Return: 166 set_notifmode(4, ksym); 167 term.c.x = cu.x, term.c.y = cu.y; 168 select_or_drawcursor(selectsearch_mode = 0, type); 169 in_use = quant = 0; 170 return MODE_KBDSELECT; 171 case XK_n: 172 case XK_N: 173 if (ptarget) 174 search(selectsearch_mode, &target[0], ptarget, (ksym == XK_n) ? -1 : 1, type, &cu); 175 break; 176 case XK_BackSpace: 177 term.c.x = 0; 178 select_or_drawcursor(selectsearch_mode, type); 179 break; 180 case XK_dollar: 181 term.c.x = term.col - 1; 182 select_or_drawcursor(selectsearch_mode, type); 183 break; 184 case XK_Home: 185 term.c.x = 0, term.c.y = 0; 186 select_or_drawcursor(selectsearch_mode, type); 187 break; 188 case XK_End: 189 term.c.x = cu.x, term.c.y = cu.y; 190 select_or_drawcursor(selectsearch_mode, type); 191 break; 192 case XK_Page_Up: 193 case XK_Page_Down: 194 term.c.y = (ksym == XK_Prior ) ? 0 : cu.y; 195 select_or_drawcursor(selectsearch_mode, type); 196 break; 197 case XK_exclam: 198 term.c.x = term.col >> 1; 199 select_or_drawcursor(selectsearch_mode, type); 200 break; 201 case XK_asterisk: 202 case XK_KP_Multiply: 203 term.c.x = term.col >> 1; 204 case XK_underscore: 205 term.c.y = cu.y >> 1; 206 select_or_drawcursor(selectsearch_mode, type); 207 break; 208 default: 209 if (ksym >= XK_0 && ksym <= XK_9) { /* 0-9 keyboard */ 210 quant = (quant * 10) + (ksym ^ XK_0); 211 return 0; 212 } else if (ksym >= XK_KP_0 && ksym <= XK_KP_9) { /* 0-9 numpad */ 213 quant = (quant * 10) + (ksym ^ XK_KP_0); 214 return 0; 215 } else if (ksym == XK_k || ksym == XK_h) 216 i = ksym & 1; 217 else if (ksym == XK_l || ksym == XK_j) 218 i = ((ksym & 6) | 4) >> 1; 219 else if ((XK_Home & ksym) != XK_Home || (i = (ksym ^ XK_Home) - 1) > 3) 220 break; 221 222 xy = (i & 1) ? &term.c.y : &term.c.x; 223 sens = (i & 2) ? 1 : -1; 224 bound = (i >> 1 ^ 1) ? 0 : (i ^ 3) ? term.col - 1 : term.bot; 225 226 if (quant == 0) 227 quant++; 228 229 if (*xy == bound && ((sens < 0 && bound == 0) || (sens > 0 && bound > 0))) 230 break; 231 232 *xy += quant * sens; 233 if (*xy < 0 || ( bound > 0 && *xy > bound)) 234 *xy = bound; 235 236 select_or_drawcursor(selectsearch_mode, type); 237 } 238 quant = 0; 239 return 0; 240 }