st-flexipatch

My st-flexipatch configuration
git clone git://git.ethandl.dev/st-flexipatch
Log | Files | Refs | README | LICENSE

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 }