home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Shareware 1999 March
/
PCShareware-3-99.iso
/
IMPLE
/
DJGPP.RAR
/
DJGPP2
/
XLIB-SR0.ZIP
/
SRC
/
XLIBEMU
/
TERM.C
< prev
next >
Wrap
Text File
|
1994-01-11
|
8KB
|
399 lines
/* $Id: term.c 1.1 1994/01/12 04:38:25 ulrich Exp $ */
/*
* term.c
*
* Simple terminal window code.
*/
#include <stdio.h>
#include <malloc.h>
#include <stdarg.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
typedef struct _Term {
int rows;
int cols;
int curr;
int curc;
int fw, fh;
char *text;
int *update;
Window window;
long event_mask;
GC normal_GC;
GC cursor_GC;
Display *display;
XFontStruct *font;
char *buffer;
int bufcount;
int bufsize;
} _TermRec;
_TermRec *_xterm = NULL;
_TermRec*
TermCreate (Display *dpy)
{
int width, height;
int background, foreground;
_TermRec *t;
t = (_TermRec *) calloc (1, sizeof (_TermRec));
t->display = dpy;
t->font = XLoadQueryFont (dpy, "8x14");
t->cols = 80;
t->rows = 25;
t->text = (char *) malloc (t->cols * t->rows * sizeof(char));
memset (t->text, ' ', t->cols * t->rows);
t->update = (int *) malloc (t->rows * sizeof(int));
memset (t->update, 0, t->rows * sizeof(int));
t->fw = t->font->max_bounds.width;
t->fh = (t->font->max_bounds.ascent + t->font->max_bounds.descent);
width = t->cols * t->fw;
height = t->rows * t->fh;
background = WhitePixel (dpy, DefaultScreen (dpy));
foreground = BlackPixel (dpy, DefaultScreen (dpy));
t->window =
XCreateSimpleWindow (dpy,
DefaultRootWindow (dpy),
50, 50, width, height, 4,
foreground, background);
t->event_mask = EnterWindowMask
|LeaveWindowMask
|ButtonPressMask
|KeyPressMask
|ExposureMask;
XSelectInput (dpy, t->window, t->event_mask);
t->normal_GC = XCreateGC (dpy, (Drawable) t->window, 0, 0);
XSetFont (dpy, t->normal_GC, t->font->fid);
XSetBackground (dpy, t->normal_GC, background);
XSetForeground (dpy, t->normal_GC, foreground);
t->cursor_GC = XCreateGC (dpy, (Drawable) t->window, 0, 0);
XSetFont (dpy, t->cursor_GC, t->font->fid);
XSetBackground (dpy, t->cursor_GC, foreground);
XSetForeground (dpy, t->cursor_GC, background);
XStoreName (dpy, t->window, "xterm");
return t;
}
void
TermUpdate (_TermRec *t)
{
int i;
for (i = t->rows; --i >= 0;)
{
if (t->update[i])
{
XDrawImageString (t->display, t->window, t->normal_GC,
0, t->fh * (i + 1) - 1,
t->text + t->cols * i, t->cols);
if (t->curr == i) {
XDrawImageString (t->display, t->window, t->cursor_GC,
t->fw * t->curc, t->fh * (i + 1) - 1,
t->text + t->cols * i + t->curc,
1);
}
t->update[i] = 0;
}
}
}
void
TermScroll (_TermRec *t, int lines)
{
if (lines > 0) {
if (lines >= t->rows) {
memset (t->text, ' ', t->cols * t->rows);
t->curr = 0;
t->curr = 1;
}
else {
char *src, *dst;
dst = t->text;
src = t->text + t->cols * lines;
memcpy (dst, src, t->cols * (t->rows - lines));
dst += t->cols * (t->rows - lines);
memset (dst, ' ', t->cols * lines);
t->curr -= lines;
}
{
int i;
for (i = t->rows; --i >= 0;)
t->update[i] = 1;
}
return;
}
}
void
TermAddc (_TermRec *t, char c)
{
if (t->buffer == NULL) {
t->bufsize = 1024;
t->buffer = (char *) malloc (t->bufsize);
t->bufcount = 0;
}
if (t->bufcount < t->bufsize) {
t->buffer[t->bufcount++] = c;
}
}
void
TermPutc (_TermRec *t, char c)
{
switch (c) {
case '':
t->curc--;
if (t->curc < 0)
t->curc = 0;
t->update[t->curr] = 1;
break;
case '':
t->curc++;
if (t->curc >= t->cols)
t->curc = t->cols - 1;
t->update[t->curr] = 1;
break;
case '':
t->update[t->curr] = 1;
t->curr++;
if (t->curr >= t->rows)
t->curr = t->rows - 1;
t->update[t->curr] = 1;
break;
case '':
t->update[t->curr] = 1;
t->curr--;
if (t->curr < 0)
t->curr = 0;
t->update[t->curr] = 1;
break;
case '':
{
char *dst = t->text + t->cols * t->curr + t->curc;
memcpy (dst, dst + 1, t->cols - t->curc - 1);
dst[t->cols - t->curc - 1] = ' ';
}
t->update[t->curr] = 1;
break;
case '\b':
t->curc--;
if (t->curc < 0) {
t->curc = 0;
}
else {
char *dst = t->text + t->cols * t->curr + t->curc;
memcpy (dst, dst + 1, t->cols - t->curc - 1);
dst[t->cols - t->curc - 1] = ' ';
}
t->update[t->curr] = 1;
break;
case '\r':
t->curc = 0;
t->update[t->curr] = 1;
break;
case '\n':
t->update[t->curr] = 1;
t->curc = 0;
t->curr++;
if (t->curr >= t->rows) {
TermScroll (t, t->rows/2);
}
else {
t->update[t->curr] = 1;
}
break;
case '\t':
#if 1
do {
TermPutc (t, ' ');
} while ((t->curc % 8) != 0);
#else
t->curc = (t->curc + 8) % 8;
t->update[t->curr] = 1;
if (t->curc >= t->cols) {
t->curc = t->curc % 8;
t->curr++;
if (t->curr >= t->rows) {
TermScroll (t, t->rows/2);
}
else {
t->update[t->curr] = 1;
}
}
#endif
break;
default:
t->text[t->cols * t->curr + t->curc] = c;
t->update[t->curr] = 1;
t->curc++;
if (t->curc >= t->cols) {
t->curc = 0;
t->curr++;
if (t->curr >= t->rows) {
TermScroll (t, t->rows/2);
}
else {
t->update[t->curr] = 1;
}
}
}
}
void
TermProc (_TermRec *t)
{
char text[10];
KeySym keysym;
XComposeStatus cs;
int i, n, count;
XEvent ev;
XNextEvent (t->display, &ev);
switch (ev.type) {
case KeyPress:
count = XLookupString (&ev.xkey, text, 10, &keysym, &cs);
if (count == 1) {
if (text[0] == '\r') goto carrige_return;
TermPutc (t, text[0]);
}
else switch (keysym) {
case XK_Return:
carrige_return:
{
char *p;
p = t->text + t->cols * t->curr;
for (n = t->cols; --n >= 0; )
if (p[n] != ' ') break;
for (i = 1; i <= n; i++) {
TermAddc (t, p[i]);
}
TermAddc (t, '\n');
}
TermPutc (t, '\n');
break;
case XK_Tab:
TermPutc (t, '\t');
break;
case XK_BackSpace:
TermPutc (t, '\b');
break;
case XK_Delete:
TermPutc (t, '');
break;
case XK_Left:
TermPutc (t, '');
break;
case XK_Right:
TermPutc (t, '');
break;
case XK_Down:
TermPutc (t, '');
break;
case XK_Up:
TermPutc (t, '');
break;
}
TermUpdate (t);
break;
case Expose:
for (i = t->rows; --i >= 0;)
t->update[i] = 1;
TermUpdate (t);
break;
}
}
int
xread (char *buffer, int bufsize)
{
int count = 0;
if (_xterm->bufcount > 0)
{
count = _xterm->bufcount;
if (count > bufsize) count = bufsize;
memcpy (buffer, _xterm->buffer, count);
_xterm->bufcount -= count;
}
return count;
}
int
xavail ()
{
return _xterm->bufcount;
}
int
xputs (char *buffer)
{
int i, count;
count = strlen (buffer);
for (i = 0; i < count; i++)
TermPutc (_xterm, buffer[i]);
TermUpdate (_xterm);
return count;
}
int
xprintf (char *format, ...)
{
char buffer[1024];
va_list ap;
va_start (ap, format);
vsprintf (buffer, format, ap);
va_end (ap);
return xputs (buffer);
}
term()
{
int argc;
char *argv[2];
argc = 1;
argv[0] = "term";
argv[1] = NULL;
return term_main (argc, argv);
}
int
term_main (int argc, char *argv[])
{
Display *display;
if (_xterm == NULL) {
display = XOpenDisplay ("");
if (display == NULL) {
fprintf (stderr, "Cannot open display\n");
exit (1);
}
_xterm = TermCreate (display);
XMapWindow (display, _xterm->window);
}
if (XPending (_xterm->display))
TermProc (_xterm);
return 1;
}
#ifdef TEST
main()
{
while (term ());
}
#endif