[BACK]Return to fcons.c CVS log [TXT][DIR] Up to [local] / funnyos / dev / fcons

File: [local] / funnyos / dev / fcons / fcons.c (download)

Revision 1.5, Fri Jan 11 15:36:01 2008 UTC (16 years, 3 months ago) by nbrk
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +43 -1 lines

incomplete fcons_enqueue implementation;
all things is missing until i figure out how to deal with htese beaty
QUEUES

/*
 * $Id: fcons.c,v 1.5 2008/01/11 15:36:01 nbrk Exp $
 */
#include <sys/types.h>
#include <sys/device.h>
#include <dev/fcons/fconsvar.h>
#include <libkern/printf.h>
#include <libkern/queue.h>

/*
 * funnyOS console.
 * 80x25, monochrome.
 */

/* current console device */
struct fcons_dd *curcons;

extern void (*putchar)(char);

int 	fcons_attach(struct device *, uint32_t loc, uint8_t flags);
void 	fcons_putchar(void *ddp, char);
char 	fcons_getchar(void *ddp);
void 	fcons_dfltputchar(char);
int 	fcons_devctl(struct device *, uint8_t, void *);

struct driver fcons_dr = {
	sizeof(struct fcons_dd),
	fcons_attach,
	NULL,
	NULL
};

int
fcons_attach(struct device *self, uint32_t loc, uint8_t size)
{
	struct fcons_dd *ddp = self->dv_devdata;

	/* link our parent's dv_aux (fcons_handle) to us */
	ddp->fd_fh = self->dv_parent->dv_aux;

	ddp->fd_currow = 0;
	ddp->fd_curcol = 0;

	/* initialize iqueue */
//	ddp->fd_iqhead = SIMPLEQ_HEAD_INITIALIZER(ddp->fd_iqhead);
	SIMPLEQ_INIT(ddp->head);
	ddp->fd_iqlength = 0;

	/* make current console default */
	curcons = ddp;

	/* override early putchar */
	putchar = fcons_dfltputchar;

	printf("system console (80x25, monochrome, no video buffer)\n");

	return(0);
}


void
fcons_putchar(void *ddp, char ch)
{
	struct fcons_dd *fdp = ddp;
	struct fcons_handle *fhp = fdp->fd_fh;

	/* if we reach screen width */
	if (fdp->fd_curcol == (FCONS_WIDTH - 1)) {
		/* CRLF */
		fdp->fd_curcol = 0;
		fdp->fd_currow++;

		/* XXX pass \n to lower level (not all devices work this way) */
		fhp->putc(fhp->fh_ownerdd, '\n');
	}
	/* XXX do something if col == FCONS_HEIGHT; console buffer? */

	/* if we reach the bottom of the screen */
	if (fdp->fd_currow == FCONS_HEIGHT) {
		/* XXX tmp hack; should really follow clrscr */
		fdp->fd_currow = 0;
	}

	fhp->putc(fhp->fh_ownerdd, ch);
}


char
fcons_getchar(void *ddp)
{
	/* TODO */
	return ' ';
}


void
fcons_dfltputchar(char ch)
{
	/*
	 * Put a character into default (current) console.
	 */
	fcons_putchar(curcons, ch);

	return;
}


void
fcons_ienqueue(char ch)
{
	/*
	 * Enqueue character into the input data queue.
	 */
	struct fcons_dd *ddp;
	struct fcons_char *curfc;
	uint32_t i;

	/* XXX will use curcons devdata */
	ddp = curcons;

#if 0
	if (ddp->fd_iqueue == NULL) {
		/* first insertion */
		curfc = kmalloc(sizeof(struct fcons_char));

		if(curfc == NULL)
			panic("fcons_ienqueue: can't allocate memory for new element\n");
	} else {
		curfc = ddp->fd_iqueue;

		/* locate last element */
		for(i = 0; i < ddp->fd_iqlength - 1; i++)
			curfc = curfc->fc_next;
	}
#endif
	curfc = kmalloc(sizeof(struct fcons_char));
	if(curfc == NULL)
		panic("fcons_ienqueue: can't allocate memory for new element\n");

	SIMPLEQ_INSERT_TAIL(ddp->fd_iqhead, curfc, fc_next);
}

#if 0
int
fcons_devctl(struct device *devp, uint8_t ctl, void *data)
{
	/*
	 * Devctl support for fcons device.
	 */
	switch(ctl) {
		case DCFCONS_GETCURROW:
			/* return cursor's row  */
			data = &fcons_dd[devp->dv_minor].currow;
			return(0);
		case DCFCONS_GETCURCOL:
			/* return cursor's column */
			data = &fcons_dd[devp->dv_minor].curcol;
			return(0);
		case DCFCONS_PUTCHAR:
			/* put a character to the device */
			fcons_putchar(devp, *(char*)data);
			return(0);
		case DCFCONS_GETCHAR:
			/* get a character from the device */
			/* TODO */
			return(-1);
		default:
			/* unknown devctl */
			return(-1);
	}

}
#endif /* not 0 */