Beispiel #1
0
static void
erase_chars(struct inpdata *inpdata, char *from, char *to, int x, int mv)
{
  int chng;
  ASSERT(from < to);
  if (inpdata->inp.len > to - inpdata->inp.buf)
    memmove(from, to, inpdata->inp.len - (to - inpdata->inp.buf));
  chng = to - from;
  if (mv)
    {
      x -= chng;
      inpdata->inp.pos -= chng;
    }
  inpdata->inp.len -= chng;
  if (!(inpdata->inpmode & INP_NOECHO))
    {
      struct mchar mc;
      char *s = from < to ? from : to;
      mc = mchar_so;
      while (s < inpdata->inp.buf+inpdata->inp.len)
	{
	  mc.image = *s++;
	  LPutChar(flayer, &mc, x++, INPUTLINE);
	}
      while (chng--)
	LPutChar(flayer, &mchar_blank, x++, INPUTLINE);
      x = inpdata->inpstringlen + inpdata->inp.pos;
      LGotoPos(flayer, x, INPUTLINE);
    }
}
Beispiel #2
0
Datei: mark.c Projekt: meh/screen
/* tx, ty: WINDOW,  line: DISPLAY */
void revto_line(int tx, int ty, int line)
{
	int fx, fy;
	int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0;
	int ystart = 0, yend = fore->w_height - 1;
	int i, ry;
	uint32_t *wi;
	struct mline *ml;
	struct mchar mc;

	if (tx < 0)
		tx = 0;
	else if (tx > fore->w_width - 1)
		tx = fore->w_width - 1;
	if (ty < 0)
		ty = 0;
	else if (ty > fore->w_histheight + fore->w_height - 1)
		ty = fore->w_histheight + fore->w_height - 1;

	fx = markdata->cx;
	fy = markdata->cy;

	/* don't just move inside of a kanji, the user wants to see something */
	ml = WIN(ty);
	if (ty == fy && fx + 1 == tx && dw_right(ml, tx, fore->w_encoding) && tx < D_width - 1)
		tx++;
	if (ty == fy && fx - 1 == tx && dw_right(ml, fx, fore->w_encoding) && tx)
		tx--;

	markdata->cx = tx;
	markdata->cy = ty;

	/*
	 * if we go to a position that is currently offscreen
	 * then scroll the screen
	 */
	i = 0;
	if (line >= 0 && line < fore->w_height)
		i = W2D(ty) - line;
	else if (ty < markdata->hist_offset)
		i = ty - markdata->hist_offset;
	else if (ty > markdata->hist_offset + (fore->w_height - 1))
		i = ty - markdata->hist_offset - (fore->w_height - 1);
	if (i > 0)
		yend -= MarkScrollUpDisplay(i);
	else if (i < 0)
		ystart += MarkScrollDownDisplay(-i);

	if (markdata->second == 0) {
		flayer->l_x = tx;
		flayer->l_y = W2D(ty);
		LGotoPos(flayer, tx, W2D(ty));
		return;
	}

	qq = markdata->x1 + markdata->y1 * fore->w_width;
	ff = fx + fy * fore->w_width;	/* "from" offset in WIN coords */
	tt = tx + ty * fore->w_width;	/* "to" offset  in WIN coords */

	if (ff > tt) {
		st = tt;
		en = ff;
		x = tx;
		y = ty;
	} else {
		st = ff;
		en = tt;
		x = fx;
		y = fy;
	}
	if (st > qq) {
		st++;
		x++;
	}
	if (en < qq)
		en--;
	if (tt > qq) {
		revst = qq;
		reven = tt;
	} else {
		revst = tt;
		reven = qq;
	}
	ry = y - markdata->hist_offset;
	if (ry < ystart) {
		y += (ystart - ry);
		x = 0;
		st = y * fore->w_width;
		ry = ystart;
	}
	ml = WIN(y);
	for (t = st; t <= en; t++, x++) {
		if (x >= fore->w_width) {
			x = 0;
			y++, ry++;
			ml = WIN(y);
		}
		if (ry > yend)
			break;
		if (t == st || x == 0) {
			wi = ml->image + fore->w_width;
			for (ce = fore->w_width; ce >= 0; ce--, wi--)
				if (*wi != ' ')
					break;
		}
		if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar) {
			if (dw_right(ml, x, fore->w_encoding)) {
				if (t == revst)
					revst--;
				t--;
				x--;
			}
			if (t >= revst && t <= reven) {
				mc = mchar_so;
				if (pastefont) {
					mc.font = ml->font[x];
					mc.fontx = ml->fontx[x];
				}
				mc.image = ml->image[x];
			} else
				copy_mline2mchar(&mc, ml, x);
			if (dw_left(ml, x, fore->w_encoding)) {
				mc.mbcs = ml->image[x + 1];
				LPutChar(flayer, &mc, x, W2D(y));
				t++;
			}
			LPutChar(flayer, &mc, x, W2D(y));
			if (dw_left(ml, x, fore->w_encoding))
				x++;
		}
	}
	flayer->l_x = tx;
	flayer->l_y = W2D(ty);
	LGotoPos(flayer, tx, W2D(ty));
}
Beispiel #3
0
Datei: mark.c Projekt: meh/screen
static void MarkRedisplayLine(int y, int xs, int xe, int isblank)
/* NOTE: y is in DISPLAY coords system! */
{
	int wy, x, i, rm;
	int sta, sto, cp;	/* NOTE: these 3 are in WINDOW coords system */
	uint32_t *wi;
	struct mline *ml;
	struct mchar mchar_marked;

	if (y < 0)		/* No special full page handling */
		return;

	markdata = (struct markdata *)flayer->l_data;
	fore = markdata->md_window;

	mchar_marked = mchar_so;

	wy = D2W(y);
	ml = WIN(wy);

	if (markdata->second == 0) {
		if (dw_right(ml, xs, fore->w_encoding) && xs > 0)
			xs--;
		if (dw_left(ml, xe, fore->w_encoding) && xe < fore->w_width - 1)
			xe++;
		if (xs == 0 && y > 0 && wy > 0 && WIN(wy - 1)->image[flayer->l_width] == 0)
			LCDisplayLineWrap(flayer, ml, y, xs, xe, isblank);
		else
			LCDisplayLine(flayer, ml, y, xs, xe, isblank);
		return;
	}

	sta = markdata->y1 * fore->w_width + markdata->x1;
	sto = markdata->cy * fore->w_width + markdata->cx;
	if (sta > sto) {
		i = sta;
		sta = sto;
		sto = i;
	}
	cp = wy * fore->w_width + xs;

	rm = markdata->right_mar;
	for (x = fore->w_width, wi = ml->image + fore->w_width; x >= 0; x--, wi--)
		if (*wi != ' ')
			break;
	if (x < rm)
		rm = x;

	for (x = xs; x <= xe; x++, cp++)
		if (cp >= sta && x >= markdata->left_mar)
			break;
	if (dw_right(ml, x, fore->w_encoding))
		x--;
	if (x > xs)
		LCDisplayLine(flayer, ml, y, xs, x - 1, isblank);
	for (; x <= xe; x++, cp++) {
		if (cp > sto || x > rm)
			break;
		if (pastefont) {
			mchar_marked.font = ml->font[x];
			mchar_marked.fontx = ml->fontx[x];
		}
		mchar_marked.image = ml->image[x];
		mchar_marked.mbcs = 0;
		if (dw_left(ml, x, fore->w_encoding)) {
			mchar_marked.mbcs = ml->image[x + 1];
			cp++;
		}
		LPutChar(flayer, &mchar_marked, x, y);
		if (dw_left(ml, x, fore->w_encoding))
			x++;
	}
	if (x <= xe)
		LCDisplayLine(flayer, ml, y, x, xe, isblank);
}
Beispiel #4
0
void LWrapChar(Layer *l, struct mchar *c, int y, int top, int bot, bool ins)
{
	Canvas *cvlist, *cvlnext;
	Viewport *vp, *evp, **vpp;
	int yy, y2, yy2, top2, bot2;
	int bce;

	if (l->l_pause.d)
		/* XXX: 'y'? */
		LayPauseUpdateRegion(l, 0, l->l_width - 1, top, bot);

	bce = c->colorbg;
	if (y != bot) {
		/* simple case: no scrolling */

		/* cursor after wrapping */
		yy = y == l->l_height - 1 ? y : y + 1;

		for (Canvas *cv = l->l_cvlist; cv; cv = cv->c_lnext) {
			if (l->l_pause.d && cv->c_slorient)
				continue;
			y2 = 0;	/* gcc -Wall */
			display = cv->c_display;
			if (D_blocked)
				continue;
			/* find the viewport of the wrapped character */
			for (vp = cv->c_vplist; vp; vp = vp->v_next) {
				y2 = y + vp->v_yoff;
				yy2 = yy + vp->v_yoff;
				if (yy2 >= vp->v_ys && yy2 <= vp->v_ye && vp->v_xoff >= vp->v_xs
				    && vp->v_xoff <= vp->v_xe)
					break;
			}
			if (vp == NULL)
				continue;	/* nothing to do, character not visible */
			/* find the viewport of the character at the end of the line */
			for (evp = cv->c_vplist; evp; evp = evp->v_next)
				if (y2 >= evp->v_ys && y2 <= evp->v_ye
				    && evp->v_xoff + l->l_width - 1 >= evp->v_xs
				    && evp->v_xoff + l->l_width - 1 <= evp->v_xe)
					break;	/* gotcha! */
			if (evp == NULL || (ins && vp->v_xoff + l->l_width - 1 > vp->v_ye)) {
				/* no wrapping possible */
				cvlist = l->l_cvlist;
				cvlnext = cv->c_lnext;
				l->l_cvlist = cv;
				cv->c_lnext = NULL;
				if (ins)
					LInsChar(l, c, 0, yy, NULL);
				else
					LPutChar(l, c, 0, yy);
				l->l_cvlist = cvlist;
				cv->c_lnext = cvlnext;
			} else {
				WrapChar(RECODE_MCHAR(c), vp->v_xoff + l->l_width, y2, vp->v_xoff, -1,
					 vp->v_xoff + l->l_width - 1, -1, ins);
			}
		}
	} else {
		/* hard case: scroll up */

		for (Canvas *cv = l->l_cvlist; cv; cv = cv->c_lnext) {
			if (l->l_pause.d && cv->c_slorient)
				continue;
			display = cv->c_display;
			if (D_blocked)
				continue;
			/* search for wrap viewport */
			for (vpp = &cv->c_vplist; (vp = *vpp); vpp = &vp->v_next) {
				yy2 = bot + vp->v_yoff;
				if (yy2 >= vp->v_ys && yy2 <= vp->v_ye && vp->v_xoff >= vp->v_xs
				    && vp->v_xoff + l->l_width - 1 <= vp->v_xe)
					break;
			}

			if (vp) {
				/* great, can use Wrap on the vp */
				/* temporarily remove vp from cvlist */
				*vpp = vp->v_next;
			}
			if (cv->c_vplist) {
				/* scroll all viewports != vp */
				cvlist = l->l_cvlist;
				cvlnext = cv->c_lnext;
				l->l_cvlist = cv;
				cv->c_lnext = NULL;
				LScrollV(l, 1, top, bot, bce);
				if (!vp) {
					if (ins)
						LInsChar(l, c, 0, bot, NULL);
					else
						LPutChar(l, c, 0, bot);
				}
				l->l_cvlist = cvlist;
				cv->c_lnext = cvlnext;
			}
			if (vp) {
				/* add vp back to cvlist */
				*vpp = vp;
				top2 = top + vp->v_yoff;
				bot2 = bot + vp->v_yoff;
				if (top2 < vp->v_ys)
					top2 = vp->v_ys;
				WrapChar(RECODE_MCHAR(c), vp->v_xoff + l->l_width, bot2, vp->v_xoff, top2,
					 vp->v_xoff + l->l_width - 1, bot2, ins);
			}
		}
	}
}
Beispiel #5
0
static void
InpProcess(char **ppbuf, int *plen)
{
  int len, x;
  char *pbuf;
  char ch;
  struct inpdata *inpdata;
  struct display *inpdisplay;
  int prev, next, search = 0;

  inpdata = (struct inpdata *)flayer->l_data;
  inpdisplay = display;

#define RESET_SEARCH { if (inpdata->search) Free(inpdata->search); }

  LGotoPos(flayer, inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos), INPUTLINE);
  if (ppbuf == 0)
    {
      InpAbort();
      return;
    }
  x = inpdata->inpstringlen + inpdata->inp.pos;
  len = *plen;
  pbuf = *ppbuf;
  while (len)
    {
      char *p = inpdata->inp.buf + inpdata->inp.pos;

      ch = *pbuf++;
      len--;
      if (inpdata->inpmode & INP_EVERY)
	{
	  inpdata->inp.buf[inpdata->inp.len] = ch;
	  if (ch)
	    {
	      display = inpdisplay;
	      (*inpdata->inpfinfunc)(inpdata->inp.buf, inpdata->inp.len, inpdata->priv);
	      ch = inpdata->inp.buf[inpdata->inp.len];
	    }
	}
      else if (inpdata->inpmode & INP_RAW)
	{
	  display = inpdisplay;
          (*inpdata->inpfinfunc)(&ch, 1, inpdata->priv);	/* raw */
	  if (ch)
	    continue;
	}
      if (((unsigned char)ch & 0177) >= ' ' && ch != 0177 && inpdata->inp.len < inpdata->inpmaxlen)
	{
	  if (inpdata->inp.len > inpdata->inp.pos)
	    memmove(p+1, p, inpdata->inp.len - inpdata->inp.pos);
	  inpdata->inp.buf[inpdata->inp.pos++] = ch;
	  inpdata->inp.len++;

	  if (!(inpdata->inpmode & INP_NOECHO))
	    {
	      struct mchar mc;
	      mc = mchar_so;
	      mc.image = *p++;
	      LPutChar(flayer, &mc, x, INPUTLINE);
	      x++;
	      if (p < inpdata->inp.buf+inpdata->inp.len)
		{
		  while (p < inpdata->inp.buf+inpdata->inp.len)
		    {
		      mc.image = *p++;
		      LPutChar(flayer, &mc, x++, INPUTLINE);
		    }
		  x = inpdata->inpstringlen + inpdata->inp.pos;
		  LGotoPos(flayer, x, INPUTLINE);
		}
	    }
	  RESET_SEARCH;
	}
      else if ((ch == '\b' || ch == 0177) && inpdata->inp.pos > 0)
	{
	  erase_chars(inpdata, p-1, p, x, 1);
	  RESET_SEARCH;
	}
      else if (ch == '\025')			/* CTRL-U */
	{
	  x = inpdata->inpstringlen;
	  if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO))
	    {
	      LClearArea(flayer, x, INPUTLINE, x + inpdata->inp.len - 1, INPUTLINE, 0, 0);
	      LGotoPos(flayer, x, INPUTLINE);
	    }
	  inpdata->inp.len = inpdata->inp.pos = 0;
	}
      else if (ch == '\013')			/* CTRL-K */
	{
	  x = inpdata->inpstringlen + inpdata->inp.pos;
	  if (inpdata->inp.len > inpdata->inp.pos && !(inpdata->inpmode & INP_NOECHO))
	    {
	      LClearArea(flayer, x, INPUTLINE, x + inpdata->inp.len - inpdata->inp.pos - 1, INPUTLINE, 0, 0);
	      LGotoPos(flayer, x, INPUTLINE);
	    }
	  inpdata->inp.len = inpdata->inp.pos;
	}
      else if (ch == '\027' && inpdata->inp.pos > 0)		/* CTRL-W */
	{
	  char *oldp = p--;
	  while (p > inpdata->inp.buf && *p == ' ')
	    p--;
	  while (p > inpdata->inp.buf && *(p - 1) != ' ')
	    p--;
	  erase_chars(inpdata, p, oldp, x, 1);
	  RESET_SEARCH;
	}
      else if (ch == '\004' && inpdata->inp.pos < inpdata->inp.len)	/* CTRL-D */
	{
	  erase_chars(inpdata, p, p+1, x, 0);
	  RESET_SEARCH;
	}
      else if (ch == '\001' || (unsigned char)ch == 0201)	/* CTRL-A */
	{
	  LGotoPos(flayer, x -= inpdata->inp.pos, INPUTLINE);
	  inpdata->inp.pos = 0;
	}
      else if ((ch == '\002' || (unsigned char)ch == 0202) && inpdata->inp.pos > 0)	/* CTRL-B */
	{
	  LGotoPos(flayer, --x, INPUTLINE);
	  inpdata->inp.pos--;
	}
      else if (ch == '\005' || (unsigned char)ch == 0205)	/* CTRL-E */
	{
	  LGotoPos(flayer, x += inpdata->inp.len - inpdata->inp.pos, INPUTLINE);
	  inpdata->inp.pos = inpdata->inp.len;
	}
      else if ((ch == '\006' || (unsigned char)ch == 0206) && inpdata->inp.pos < inpdata->inp.len)	/* CTRL-F */
	{
	  LGotoPos(flayer, ++x, INPUTLINE);
	  inpdata->inp.pos++;
	}
      else if ((prev = ((ch == '\020' || (unsigned char)ch == 0220) &&	/* CTRL-P */
	      inpdata->inp.prev)) ||
	  (next = ((ch == '\016' || (unsigned char)ch == 0216) &&  /* CTRL-N */
		   inpdata->inp.next)) ||
	  (search = ((ch == '\022' || (unsigned char)ch == 0222) && inpdata->inp.prev)))
	{
	  struct mchar mc;
	  struct inpline *sel;
	  int pos = -1;

	  mc = mchar_so;

	  if (prev)
	    sel = inpdata->inp.prev;
	  else if (next)
	    sel = inpdata->inp.next;
	  else
	    {
	      /* search */
	      inpdata->inp.buf[inpdata->inp.len] = 0;	/* Remove the ctrl-r from the end */
	      if (!inpdata->search)
		inpdata->search = SaveStr(inpdata->inp.buf);
	      for (sel = inpdata->inp.prev; sel; sel = sel->prev)
		{
		  char *f;
		  if ((f = strstr(sel->buf, inpdata->search)))
		    {
		      pos = f - sel->buf;
		      break;
		    }
		}
	      if (!sel)
		continue;	/* Did not find a match. Process the next input. */
	    }

	  if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO))
	    LClearArea(flayer, inpdata->inpstringlen, INPUTLINE, inpdata->inpstringlen + inpdata->inp.len - 1, INPUTLINE, 0, 0);

	  if ((prev || search) && !inpdata->inp.next)
	    inphist = inpdata->inp;
	  memcpy(&inpdata->inp, sel, sizeof(struct inpline));
	  if (pos != -1)
	    inpdata->inp.pos = pos;
	  if (inpdata->inp.len > inpdata->inpmaxlen)
	    inpdata->inp.len = inpdata->inpmaxlen;
	  if (inpdata->inp.pos > inpdata->inp.len)
	    inpdata->inp.pos = inpdata->inp.len;

	  x = inpdata->inpstringlen;
	  p = inpdata->inp.buf;

	  if (!(inpdata->inpmode & INP_NOECHO))
	    {
	      while (p < inpdata->inp.buf+inpdata->inp.len)
		{
		  mc.image = *p++;
		  LPutChar(flayer, &mc, x++, INPUTLINE);
		}
	    }
	  x = inpdata->inpstringlen + inpdata->inp.pos;
	  LGotoPos(flayer, x, INPUTLINE);
	}

      else if (ch == '\003' || ch == '\007' || ch == '\033' ||
	       ch == '\000' || ch == '\n' || ch == '\r')
	{
          if (ch != '\n' && ch != '\r')
	    inpdata->inp.len = 0;
	  inpdata->inp.buf[inpdata->inp.len] = 0;

	  if (inpdata->inp.len && !(inpdata->inpmode & (INP_NOECHO | INP_RAW)))
	    {
	      struct inpline *store;

	      /* Look for a duplicate first */
	      for (store = inphist.prev; store; store = store->prev)
		{
		  if (strcmp(store->buf, inpdata->inp.buf) == 0)
		    {
		      if (store->next)
			store->next->prev = store->prev;
		      if (store->prev)
			store->prev->next = store->next;
		      store->pos = inpdata->inp.pos;
		      break;
		    }
		}

	      if (!store)
		{
		  store = malloc(sizeof(struct inpline));
		  memcpy(store, &inpdata->inp, sizeof(struct inpline));
		}
	      store->next = &inphist;
	      store->prev = inphist.prev;
	      if (inphist.prev)
		inphist.prev->next = store;
	      inphist.prev = store;
	    }

	  flayer->l_data = 0;	/* so inpdata does not get freed */
          InpAbort();		/* redisplays... */
	  *ppbuf = pbuf;
	  *plen = len;
	  display = inpdisplay;
	  if ((inpdata->inpmode & INP_RAW) == 0)
            (*inpdata->inpfinfunc)(inpdata->inp.buf, inpdata->inp.len, inpdata->priv);
	  else
            (*inpdata->inpfinfunc)(pbuf - 1, 0, inpdata->priv);
	  if (inpdata->search)
	    free(inpdata->search);
	  free(inpdata);
	  return;
	}
      else
	{
	  /* The user was searching, and then pressed some non-control input. So reset
	   * the search string. */
	  RESET_SEARCH;
	}
    }
  if (!(inpdata->inpmode & INP_RAW))
    {
      flayer->l_x = inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos);
      flayer->l_y = INPUTLINE;
    }
  *ppbuf = pbuf;
  *plen = len;
}