Browse Source

* Added a test app that swallows two console applications. Switch with C-a.

tags/v0.99.beta14
Sam Hocevar sam 18 years ago
parent
commit
81d9b86799
3 changed files with 218 additions and 2 deletions
  1. +3
    -1
      configure.ac
  2. +5
    -1
      test/Makefile.am
  3. +210
    -0
      test/term.c

+ 3
- 1
configure.ac View File

@@ -75,7 +75,7 @@ AC_ARG_ENABLE(plugins,
AC_ARG_ENABLE(doc,
[ --enable-doc build documentation (needs doxygen and LaTeX)])

AC_CHECK_HEADERS(stdio.h stdarg.h signal.h sys/ioctl.h sys/time.h inttypes.h endian.h unistd.h arpa/inet.h netinet/in.h winsock2.h errno.h locale.h getopt.h dlfcn.h)
AC_CHECK_HEADERS(stdio.h stdarg.h signal.h sys/ioctl.h sys/time.h inttypes.h endian.h unistd.h arpa/inet.h netinet/in.h winsock2.h errno.h locale.h getopt.h dlfcn.h pty.h)
AC_CHECK_FUNCS(signal ioctl vsnprintf getenv putenv strcasecmp htons)
AC_CHECK_FUNCS(usleep gettimeofday)

@@ -105,6 +105,7 @@ AC_TRY_COMPILE([],[asm("fldln2; fldln2; fxch; fyl2x");],
[AC_MSG_RESULT(no)])

AC_CHECK_LIB(m, sin, MATH_LIBS="${MATH_LIBS} -lm")
AC_CHECK_LIB(util, forkpty, UTIL_LIBS="${UTIL_LIBS} -lutil")

CACA_DRIVERS=""

@@ -277,6 +278,7 @@ fi


AC_SUBST(MATH_LIBS)
AC_SUBST(UTIL_LIBS)
AC_SUBST(GETOPT_LIBS)
AC_SUBST(CACA_LIBS)
AC_SUBST(X11_LIBS)


+ 5
- 1
test/Makefile.am View File

@@ -2,7 +2,7 @@

AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/cucul -I$(top_srcdir)/caca -DDATADIR=\"$(pkgdatadir)\"

noinst_PROGRAMS = blit colors cucul demo demo0 dithering event export font font2tga frames fullwidth gamma hsv input spritedit swallow text transform truecolor unicode import
noinst_PROGRAMS = blit colors cucul demo demo0 dithering event export font font2tga frames fullwidth gamma hsv input spritedit swallow term text transform truecolor unicode import

blit_SOURCES = blit.c
blit_LDADD = ../caca/libcaca.la ../cucul/libcucul.la
@@ -58,6 +58,10 @@ spritedit_LDADD = ../caca/libcaca.la ../cucul/libcucul.la
swallow_SOURCES = swallow.c
swallow_LDADD = ../caca/libcaca.la ../cucul/libcucul.la

term_SOURCES = term.c
term_LDADD = ../caca/libcaca.la ../cucul/libcucul.la
term_LDFLAGS = @UTIL_LIBS@

text_SOURCES = text.c
text_LDADD = ../cucul/libcucul.la



+ 210
- 0
test/term.c View File

@@ -0,0 +1,210 @@
/*
* term swallow a terminal-based application
* Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
* All Rights Reserved
*
* $Id$
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Do What The Fuck You Want To
* Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*/

#include "config.h"
#include "common.h"

#if !defined __KERNEL__
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <unistd.h>
# include <fcntl.h>
# if defined HAVE_PTY_H
# include <pty.h> /* for openpty and forkpty */
# endif
#endif

#include "cucul.h"
#include "caca.h"

static int run_in_pty(char *cmd);

int main(int argc, char **argv)
{
static cucul_canvas_t *cv, *app[2];
static caca_display_t *dp;
unsigned char *buf[2];
long int total[2];
int ptyfd[2], pty = 0;
int w, h, eof = 0;

if(argc < 3)
{
fprintf(stderr, "usage: %s <cmd1> <cmd2>\n", argv[0]);
fprintf(stderr, "eg. \"%s bash bash\"\n", argv[0]);
return 1;
}

cv = cucul_create_canvas(80 + 7, 24 + 7);
dp = caca_create_display(cv);
if(!dp)
return 1;

// w = cucul_get_canvas_width(cv) - 7;
// h = cucul_get_canvas_height(cv) - 7;
w = 80; h = 24;

if(w < 0 || h < 0)
return 1;

app[0] = cucul_create_canvas(w, h);
app[1] = cucul_create_canvas(w, h);

cucul_set_color_ansi(cv, CUCUL_LIGHTRED, CUCUL_BLACK);
cucul_draw_thin_box(cv, pty * 5, pty * 5,
80 + pty * 5 + 1, 24 + pty * 5 + 1);

caca_refresh_display(dp);

buf[0] = buf[1] = NULL;
total[0] = total[1] = 0;

ptyfd[0] = run_in_pty(argv[1]);
ptyfd[1] = run_in_pty(argv[2]);

if(ptyfd[0] < 0 || ptyfd[1] < 0)
return -1;

fcntl(ptyfd[0], F_SETFL, O_NDELAY);
fcntl(ptyfd[1], F_SETFL, O_NDELAY);

for(;;)
{
struct timeval tv;
fd_set fdset;
caca_event_t ev;
int i, ret, refresh = 0;

ret = caca_get_event(dp, CACA_EVENT_ANY, &ev, 0);
if(ret && ev.type & CACA_EVENT_KEY_PRESS)
{
switch(ev.data.key.ch)
{
case CACA_KEY_CTRL_A:
cucul_draw_box(cv, pty * 5, pty * 5,
80 + pty * 5 + 1, 24 + pty * 5 + 1, ' ');
pty = 1 - pty;
refresh = 1;
break;
case CACA_KEY_UP:
write(ptyfd[pty], "\x1b[A", 3); break;
case CACA_KEY_DOWN:
write(ptyfd[pty], "\x1b[B", 3); break;
case CACA_KEY_RIGHT:
write(ptyfd[pty], "\x1b[C", 3); break;
case CACA_KEY_LEFT:
write(ptyfd[pty], "\x1b[D", 3); break;
default:
write(ptyfd[pty], &ev.data.key.ch, 1); break;
}
}

/* Read data, if any */
FD_ZERO(&fdset);
FD_SET(ptyfd[0], &fdset);
FD_SET(ptyfd[1], &fdset);
tv.tv_sec = 0;
tv.tv_usec = 50000;
ret = select(ptyfd[0] + ptyfd[1] + 1, &fdset, NULL, NULL, &tv);

if(ret < 0)
{
if(!total[0] && !total[1])
break;
}
else if(ret) for(i = 0; i < 2; i++)
{
if(FD_ISSET(ptyfd[i], &fdset))
{
ssize_t n;

buf[i] = realloc(buf[i], total[i] + 4096);
n = read(ptyfd[i], buf[i] + total[i], 4096);

if(n > 0)
total[i] += n;
else if(n == 0 || errno != EWOULDBLOCK)
eof = 1;
}
}

for(i = 0; i < 2; i++) if(total[i])
{
unsigned long int bytes;

bytes = cucul_import_memory(app[i], buf[i], total[i], "utf8");

if(bytes > 0)
{
total[i] -= bytes;
memmove(buf[i], buf[i] + bytes, total[i]);
refresh = 1;
}
}

if(refresh)
{
cucul_blit(cv, 5 * !pty + 1, 5 * !pty + 1, app[!pty], NULL);
cucul_blit(cv, 5 * pty + 1, 5 * pty + 1, app[pty], NULL);
cucul_draw_thin_box(cv, pty * 5, pty * 5,
80 + pty * 5 + 1, 24 + pty * 5 + 1);
caca_refresh_display(dp);
}

if(eof && !total[0] && !total[1])
break;
}

caca_get_event(dp, CACA_EVENT_KEY_PRESS, NULL, -1);

/* Clean up */
caca_free_display(dp);
cucul_free_canvas(cv);
cucul_free_canvas(app[0]);
cucul_free_canvas(app[1]);

return 0;
}

static int run_in_pty(char *cmd)
{
#if defined HAVE_PTY_H
char **argv;
int fd;
pid_t pid;

pid = forkpty(&fd, NULL, NULL, NULL);
if(pid < 0)
{
fprintf(stderr, "forkpty() error\n");
return -1;
}
else if(pid == 0)
{
putenv("CACA_DRIVER=slang");
argv = malloc(2 * sizeof(char *));
argv[0] = cmd;
argv[1] = NULL;
execvp(cmd, argv);
fprintf(stderr, "execvp() error\n");
return -1;
}

return fd;
#else
fprintf(stderr, "forkpty() not available\n");
return -1;
#endif
}


Loading…
Cancel
Save