259 lines
6.4 KiB
C
259 lines
6.4 KiB
C
|
/* Program to test the vga_waitevent function. */
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <unistd.h>
|
||
|
#include <sys/time.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <vga.h>
|
||
|
#include <vgagl.h>
|
||
|
#include <vgamouse.h>
|
||
|
#include <vgakeyboard.h>
|
||
|
|
||
|
#define USE_RAWKEYBOARD
|
||
|
|
||
|
static int newcolor(void)
|
||
|
{
|
||
|
if (BYTESPERPIXEL == 1)
|
||
|
return random() % 15 + 1;
|
||
|
return gl_rgbcolor(random() & 255, random() & 255, random() & 255);
|
||
|
}
|
||
|
|
||
|
static void ping(void)
|
||
|
{
|
||
|
putchar('\a');
|
||
|
fflush(stdout);
|
||
|
}
|
||
|
|
||
|
/* read data from fd. Write string if '\n' encountered */
|
||
|
void process_input(int fd)
|
||
|
{
|
||
|
static char textbuf[80], *data = textbuf;
|
||
|
char inbuf[80];
|
||
|
int len, i;
|
||
|
|
||
|
len = read(fd, inbuf, 80);
|
||
|
if (len <= 0)
|
||
|
return;
|
||
|
for (i = 0; i < len; i++) {
|
||
|
if (inbuf[i] == '\n') {
|
||
|
*data = 0;
|
||
|
gl_write(0, 10, textbuf);
|
||
|
ping();
|
||
|
data = textbuf;
|
||
|
} else {
|
||
|
*data++ = inbuf[i];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void child(int fd)
|
||
|
{
|
||
|
time_t last_time = 0, now;
|
||
|
FILE *output;
|
||
|
|
||
|
output = fdopen(fd, "w");
|
||
|
for (;;) { /* when parent dies we get killed by SIGPIPE */
|
||
|
now = time(NULL);
|
||
|
if (now / 5 > last_time) { /* a new minute started */
|
||
|
last_time = now / 5;
|
||
|
fputs(ctime(&now), output);
|
||
|
fputc('\n', output);
|
||
|
fflush(output);
|
||
|
}
|
||
|
sleep(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
struct timeval timeout;
|
||
|
fd_set inputs;
|
||
|
char bitmap[16 * 16 * 4]; /* big enough for 10x10 bitmap in any mode */
|
||
|
int vgamode, color, pipefd[2], x, y, button, event, cursorsize = 5;
|
||
|
char loop = 1, drawcursor = 1;
|
||
|
#ifdef USE_RAWKEYBOARD
|
||
|
char space_pressed = 0;
|
||
|
#endif
|
||
|
|
||
|
puts("This is a demo showing the abilities of the new vga_waitevent() function\n"
|
||
|
"If something goes wrong it might hang your machine. Thus hit <ctrl>-C now\n"
|
||
|
"to bailout if in doubt.\n"
|
||
|
"Use mouse to move cursor. 1-9,0 to set the cursor size. Space to change the\n"
|
||
|
"cursor color. Left button to draw. Right button or 'Q' to bailout.\n"
|
||
|
"The cursor goes on/off every half second by usage of a timeout passed to\n"
|
||
|
"vga_waitevent. Every 5 secs a string from a child process (the time) arrives\n"
|
||
|
"asynchronously and is displayed by the frontend.");
|
||
|
#ifdef USE_RAWKEYBOARD
|
||
|
puts("\nBEWARE! This has been compiled to use the raw keyboard. A crash might\n"
|
||
|
"render the console unusable. (but shouldn't).");
|
||
|
#endif
|
||
|
fputs("\nHit <Enter> if brave enough, else ^C to bailout: ", stdout);
|
||
|
fflush(stdout);
|
||
|
getchar();
|
||
|
fflush(stdin); /* clear I/O buffer */
|
||
|
|
||
|
pipe(pipefd);
|
||
|
if (fork() == 0) { /* fork off b4 touching graphix to avoid side effects */
|
||
|
close(pipefd[0]); /* Important: close reading side, else it remains */
|
||
|
/* opened by child when parent exits and we don't get */
|
||
|
/* a SIGPIPE! */
|
||
|
child(pipefd[1]);
|
||
|
}
|
||
|
vga_init();
|
||
|
vgamode = vga_getdefaultmode();
|
||
|
if (vgamode == -1)
|
||
|
vgamode = G320x200x256;
|
||
|
|
||
|
if (!vga_hasmode(vgamode)) {
|
||
|
printf("Mode not available.\n");
|
||
|
exit(-1);
|
||
|
}
|
||
|
/* Enable automatic mouse setup at mode set. */
|
||
|
vga_setmousesupport(1);
|
||
|
vga_setmode(vgamode);
|
||
|
/* Disable wrapping (default). */
|
||
|
/* mouse_setwrap(MOUSE_NOWRAP); */
|
||
|
gl_setcontextvga(vgamode);
|
||
|
gl_enableclipping();
|
||
|
|
||
|
/* There might be some scrap data in the serial buffer
|
||
|
from the mouse. It will make vga_waitevent block
|
||
|
because it thinks the mouse wants to send data but
|
||
|
then no mouse packet arrives. */
|
||
|
color = newcolor();
|
||
|
x = 0;
|
||
|
y = 0;
|
||
|
gl_setwritemode(WRITEMODE_OVERWRITE | FONT_COMPRESSED);
|
||
|
gl_setfont(8, 8, gl_font8x8);
|
||
|
gl_setfontcolors(0, newcolor());
|
||
|
|
||
|
#ifdef USE_RAWKEYBOARD
|
||
|
if (keyboard_init()) {
|
||
|
printf("Could not initialize keyboard.\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
while (loop) {
|
||
|
gl_getbox(x, y, 10, 10, bitmap);
|
||
|
if (drawcursor) {
|
||
|
gl_hline(x, y, x + cursorsize, color);
|
||
|
gl_hline(x, y + cursorsize, x + cursorsize, color);
|
||
|
gl_line(x, y, x, y + cursorsize, color);
|
||
|
gl_line(x + cursorsize, y, x + cursorsize, y + cursorsize, color);
|
||
|
}
|
||
|
FD_ZERO(&inputs);
|
||
|
FD_SET(pipefd[0], &inputs);
|
||
|
timeout.tv_sec = 0;
|
||
|
timeout.tv_usec = 500000; /* 0.5 second time out */
|
||
|
event = vga_waitevent(VGA_MOUSEEVENT | VGA_KEYEVENT,
|
||
|
&inputs, NULL, NULL, &timeout);
|
||
|
gl_putbox(x, y, 10, 10, bitmap);
|
||
|
if (timeout.tv_sec || timeout.tv_usec) {
|
||
|
/* No timeout. An actual event occured. Reset to visible
|
||
|
cursor. Note:
|
||
|
This is actually a bug as the cursor will get visible on time
|
||
|
updates. However, it's better this way for demo/test
|
||
|
purposes. */
|
||
|
drawcursor = 1;
|
||
|
} else {
|
||
|
drawcursor ^= 1;
|
||
|
}
|
||
|
if (FD_ISSET(pipefd[0], &inputs))
|
||
|
process_input(pipefd[0]);
|
||
|
if (event & VGA_MOUSEEVENT) {
|
||
|
x = mouse_getx();
|
||
|
y = mouse_gety();
|
||
|
button = mouse_getbutton();
|
||
|
if (button & MOUSE_LEFTBUTTON)
|
||
|
gl_fillbox(x, y, cursorsize + 1, cursorsize + 1, color);
|
||
|
if (button & MOUSE_RIGHTBUTTON)
|
||
|
loop = 0;
|
||
|
}
|
||
|
if (event & VGA_KEYEVENT) {
|
||
|
#ifdef USE_RAWKEYBOARD
|
||
|
if (keyboard_keypressed(SCANCODE_1))
|
||
|
cursorsize = 0;
|
||
|
if (keyboard_keypressed(SCANCODE_2))
|
||
|
cursorsize = 1;
|
||
|
if (keyboard_keypressed(SCANCODE_3))
|
||
|
cursorsize = 2;
|
||
|
if (keyboard_keypressed(SCANCODE_4))
|
||
|
cursorsize = 3;
|
||
|
if (keyboard_keypressed(SCANCODE_5))
|
||
|
cursorsize = 4;
|
||
|
if (keyboard_keypressed(SCANCODE_6))
|
||
|
cursorsize = 5;
|
||
|
if (keyboard_keypressed(SCANCODE_7))
|
||
|
cursorsize = 6;
|
||
|
if (keyboard_keypressed(SCANCODE_8))
|
||
|
cursorsize = 7;
|
||
|
if (keyboard_keypressed(SCANCODE_9))
|
||
|
cursorsize = 8;
|
||
|
if (keyboard_keypressed(SCANCODE_0))
|
||
|
cursorsize = 9;
|
||
|
if (keyboard_keypressed(SCANCODE_Q))
|
||
|
loop = 0;
|
||
|
if (keyboard_keypressed(SCANCODE_SPACE)) {
|
||
|
if (!space_pressed) {
|
||
|
color = newcolor();
|
||
|
space_pressed = 1;
|
||
|
}
|
||
|
} else {
|
||
|
space_pressed = 0;
|
||
|
}
|
||
|
#else
|
||
|
switch (vga_getch()) {
|
||
|
case '1':
|
||
|
cursorsize = 0;
|
||
|
break;
|
||
|
case '2':
|
||
|
cursorsize = 1;
|
||
|
break;
|
||
|
case '3':
|
||
|
cursorsize = 2;
|
||
|
break;
|
||
|
case '4':
|
||
|
cursorsize = 3;
|
||
|
break;
|
||
|
case '5':
|
||
|
cursorsize = 4;
|
||
|
break;
|
||
|
case '6':
|
||
|
cursorsize = 5;
|
||
|
break;
|
||
|
case '7':
|
||
|
cursorsize = 6;
|
||
|
break;
|
||
|
case '8':
|
||
|
cursorsize = 7;
|
||
|
break;
|
||
|
case '9':
|
||
|
cursorsize = 8;
|
||
|
break;
|
||
|
case '0':
|
||
|
cursorsize = 9;
|
||
|
break;
|
||
|
case ' ':
|
||
|
color = newcolor();
|
||
|
break;
|
||
|
case 'q':
|
||
|
case 'Q':
|
||
|
loop = 0;
|
||
|
break;
|
||
|
default:
|
||
|
ping();
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#ifdef USE_RAWKEYBOARD
|
||
|
keyboard_close(); /* Don't forget this! */
|
||
|
#endif
|
||
|
vga_setmode(TEXT);
|
||
|
exit(0);
|
||
|
}
|