view lcdemu/process.c @ 166:2e1be0fc150e

fc-tmsh: ETM_AUDIO commands are just aul/aus/aur/auw, not audio <subcmd>
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 19 Mar 2017 17:17:57 +0000
parents e7502631a0f9
children
line wrap: on
line source

/*
 * Processing of LCD output (input to us)
 */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#include "globals.h"

#define	MAX_WIDTH	176

static unsigned
hexdecode(str)
	char *str;
{
	unsigned accum = 0;
	int i, c, n;

	for (i = 0; i < 4; i++) {
		c = str[i];
		if (isdigit(c))
			n = c - '0';
		else if (isupper(c))
			n = c - 'A' + 10;
		else
			n = c - 'a' + 10;
		accum <<= 4;
		accum |= n;
	}
	return(accum);
}

process_input_line(line)
	char *line;
{
	int blitrow, blitcol, npix;
	uint16_t pix16[MAX_WIDTH];
	char *cp;
	XImage *xi;

	for (cp = line; isspace(*cp); cp++)
		;
	if (!isdigit(*cp)) {
inv:		fprintf(stderr, "fc-lcdemu: invalid input line\n");
		exit(1);
	}
	blitrow = atoi(cp);
	while (isdigit(*cp))
		cp++;
	if (!isspace(*cp))
		goto inv;
	while (isspace(*cp))
		cp++;
	if (!isdigit(*cp))
		goto inv;
	blitcol = atoi(cp);
	while (isdigit(*cp))
		cp++;
	if (!isspace(*cp))
		goto inv;
	while (isspace(*cp))
		cp++;
	if (!isxdigit(*cp))
		goto inv;
	for (npix = 0; *cp; ) {
		if (!isxdigit(cp[0]) || !isxdigit(cp[1]) ||
		    !isxdigit(cp[2]) || !isxdigit(cp[3]))
			goto inv;
		if (npix >= MAX_WIDTH) {
			fprintf(stderr,
		"fc-lcdemu error: input line exceeds MAX_WIDTH of %d pixels\n",
				MAX_WIDTH);
			exit(1);
		}
		pix16[npix++] = hexdecode(cp);
		cp += 4;
	}
	xi = convert_function(pix16, npix);
	XPutImage(mydisplay, mainwindow, mainwingc, xi, 0, 0, blitcol, blitrow,
		  npix, 1);
	XDestroyImage(xi);
}

input_on_stdin(inbuf, incount)
	char *inbuf;
{
	char *input_end = inbuf + incount;
	static char linebuf[1024];
	static int linesz;
	char *cp;

	for (cp = inbuf; cp < input_end; cp++) {
		if (*cp == '\n') {
			linebuf[linesz] = '\0';
			process_input_line(linebuf);
			linesz = 0;
			continue;
		}
		if (linesz < sizeof(linebuf) - 1)
			linebuf[linesz++] = *cp;
	}
}