From fd331c15043f249576b820522b3d78d2b0e33a58 Mon Sep 17 00:00:00 2001 From: Jean-Yves Lamoureux Date: Wed, 8 Mar 2006 20:03:24 +0000 Subject: [PATCH] * Added very preliminary network driver --- caca/Makefile.am | 1 + caca/caca.c | 9 ++ caca/caca_internals.h | 7 +- caca/driver_network.c | 222 ++++++++++++++++++++++++++++++++++++++++++ configure.ac | 13 +++ 5 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 caca/driver_network.c diff --git a/caca/Makefile.am b/caca/Makefile.am index 841a089..672c2e6 100644 --- a/caca/Makefile.am +++ b/caca/Makefile.am @@ -17,6 +17,7 @@ libcaca_la_SOURCES = \ driver_slang.c \ driver_win32.c \ driver_x11.c \ + driver_network.c \ $(NULL) libcaca_la_CPPFLAGS = -I$(top_srcdir)/cucul libcaca_la_LDFLAGS = -no-undefined diff --git a/caca/caca.c b/caca/caca.c index 005faef..ff4226b 100644 --- a/caca/caca.c +++ b/caca/caca.c @@ -145,6 +145,11 @@ static int caca_init_driver(caca_t *kk) if(!strcasecmp(var, "ncurses")) ncurses_init_driver(kk); else +#endif +#if defined(USE_NETWORK) + if(!strcasecmp(var, "network")) + network_init_driver(kk); + else #endif return -1; @@ -186,6 +191,10 @@ static int caca_init_driver(caca_t *kk) slang_init_driver(kk); return 0; #endif +#if defined(USE_NETWORK) + network_init_driver(kk); + return 0; +#endif return -1; } diff --git a/caca/caca_internals.h b/caca/caca_internals.h index 6e11ef8..2f35c3b 100644 --- a/caca/caca_internals.h +++ b/caca/caca_internals.h @@ -53,6 +53,9 @@ enum caca_driver #endif #if defined(USE_GL) CACA_DRIVER_GL = 6, +#endif +#if defined(USE_NETWORK) + CACA_DRIVER_NETWORK = 7, #endif CACA_DRIVER_NONE = 0 }; @@ -76,7 +79,9 @@ void win32_init_driver(caca_t *); #if defined(USE_X11) void x11_init_driver(caca_t *); #endif - +#if defined(USE_NETWORK) +void network_init_driver(caca_t *); +#endif /* Timer structure */ struct caca_timer { diff --git a/caca/driver_network.c b/caca/driver_network.c new file mode 100644 index 0000000..4807ee6 --- /dev/null +++ b/caca/driver_network.c @@ -0,0 +1,222 @@ +/* + * libcaca ASCII-Art library + * Copyright (c) 2002-2006 Sam Hocevar + * All Rights Reserved + * + * This library 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. + */ + +/** \file driver_network.c + * \version \$Id: driver_gl.c 330 2006-03-07 09:17:35Z sam $ + * \author Jean-Yves Lamoureux + * \brief Network driver + * + * This file contains the libcaca network input and output driver + */ + +#include "config.h" + +#if defined(USE_NETWORK) +#include +#include +#include +#include +#include +#include + +#if defined(HAVE_UNISTD_H) +# include +#endif +#include + +#include "caca.h" +#include "caca_internals.h" +#include "cucul.h" +#include "cucul_internals.h" + + + +struct driver_private +{ + unsigned int width, height; + unsigned int port; + int sockfd, new_fd; + struct sockaddr_in my_addr; // my address information + struct sockaddr_in remote_addr; + socklen_t sin_size; + int clilen; + char buffer[256]; +}; + + + +#define BACKLOG 1337 /* Number of pending connections */ + + + +/* Following vars are static */ +static char codes[] = {0xff, 0xfb, 0x01, // WILL ECHO + 0xff, 0xfb, 0x03, // WILL SUPPRESS GO AHEAD + 0xff, 253, 31, // DO NAWS + 0xff, 254, 31, // DON'T NAWS + 0xff, 31, 250, 0, 30, 0, 0xFF, // to be replaced + 0xff, 240}; + + +static int network_init_graphics(caca_t *kk) +{ + int yes=1; + printf("Initing network stack.\n"); + + kk->drv.p = malloc(sizeof(struct driver_private)); + + + kk->drv.p->width = 80; + kk->drv.p->height = 25; + kk->drv.p->port = 7575; // 75 75 decimal ASCII -> KK // FIXME, sadly + + + cucul_set_size(kk->qq, kk->drv.p->width, kk->drv.p->height); + + + printf("socket\n"); + if ((kk->drv.p->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + return -1; + } + printf("setsockopt\n"); + if (setsockopt(kk->drv.p->sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { + perror("setsockopt"); + return -1; + } + + + kk->drv.p->my_addr.sin_family = AF_INET; + kk->drv.p-> my_addr.sin_port = htons(kk->drv.p->port); + kk->drv.p->my_addr.sin_addr.s_addr = INADDR_ANY; + memset(&(kk->drv.p->my_addr.sin_zero), '\0', 8); + + printf("bind\n"); + if (bind(kk->drv.p->sockfd, (struct sockaddr *)&kk->drv.p->my_addr, sizeof(struct sockaddr)) + == -1) { + perror("bind"); + return -1; + } + printf("listen\n"); + if (listen(kk->drv.p->sockfd, BACKLOG) == -1) { + perror("listen"); + return -1; + } + + printf("accept\n"); + kk->drv.p->clilen = sizeof(kk->drv.p->remote_addr); + kk->drv.p->new_fd = accept(kk->drv.p->sockfd, (struct sockaddr *) &kk->drv.p->remote_addr, &kk->drv.p->clilen); + if (kk->drv.p->new_fd < 0) { + perror("ERROR on accept"); + return -1; + } + + + printf("Got connexion from %d.%d.%d.%d\n", + (unsigned int)((kk->drv.p->remote_addr.sin_addr.s_addr)&0x000000FF), + (unsigned int)((kk->drv.p->remote_addr.sin_addr.s_addr)&0x0000FF00)>>8, + (unsigned int)((kk->drv.p->remote_addr.sin_addr.s_addr)&0x00FF0000)>>16, + (unsigned int)((kk->drv.p->remote_addr.sin_addr.s_addr)&0xFF000000)>>24); + + codes[16] = (unsigned char) kk->drv.p->width&0xff; + codes[18] = (unsigned char) kk->drv.p->height&0xff; + + /* Send basic telnet codes */ + if (send(kk->drv.p->new_fd, codes,sizeof(codes) , 0) == -1) { + perror("send"); + return -1; + } + + printf("network ok.\n"); + + return 0; +} + +static int network_end_graphics(caca_t *kk) +{ + printf("network end graphics\n"); + return 0; +} + +static int network_set_window_title(caca_t *kk, char const *title) +{ + printf("network_set_window_title(%s) not implemented yet.\n", title); + return 0; +} + +static unsigned int network_get_window_width(caca_t *kk) +{ + return kk->drv.p->width * 6; +} + +static unsigned int network_get_window_height(caca_t *kk) +{ + return kk->drv.p->height * 10; +} + +static void network_display(caca_t *kk) +{ + /* Clear screen */ + /* if (send(kk->drv.p->new_fd, "\033?75l\033[2J\033[H", 12, 0) == -1) { + perror("send"); + return; + } + */ + + char *to_send = cucul_get_ansi(kk->qq, 0);; + to_send = realloc(to_send, kk->qq->width * kk->qq->height * 15 * 3); + + + if (send(kk->drv.p->new_fd, "\033[s", 4, 0) == -1) { + perror("send"); + return; + } + if (send(kk->drv.p->new_fd, to_send, kk->qq->width * kk->qq->height * 15, 0) == -1) { + perror("send"); + return; + } + if (send(kk->drv.p->new_fd, "\033?75l\033[2J\033[H", 12, 0) == -1) { + perror("send"); + return; + } + +} +static void network_handle_resize(caca_t *kk) +{ + printf("Resize\n"); + +} + +static unsigned int network_get_event(caca_t *kk) +{ + return 0; +} + + +/* + * Driver initialisation + */ + +void network_init_driver(caca_t *kk) +{ + kk->drv.driver = CACA_DRIVER_NETWORK; + + kk->drv.init_graphics = network_init_graphics; + kk->drv.end_graphics = network_end_graphics; + kk->drv.set_window_title = network_set_window_title; + kk->drv.get_window_width = network_get_window_width; + kk->drv.get_window_height = network_get_window_height; + kk->drv.display = network_display; + kk->drv.handle_resize = network_handle_resize; + kk->drv.get_event = network_get_event; +} + +#endif // USE_NETWORK diff --git a/configure.ac b/configure.ac index 17bede6..fe589b7 100644 --- a/configure.ac +++ b/configure.ac @@ -36,6 +36,8 @@ AC_ARG_ENABLE(x11, [ --enable-x11 X11 support (autodetected)]) AC_ARG_ENABLE(gl, [ --enable-gl OpenGL support (autodetected)]) +AC_ARG_ENABLE(network, + [ --enable-network Network support (autodetected)]) dnl example programs features AC_ARG_ENABLE(imlib2, @@ -137,6 +139,17 @@ if test "${enable_gl}" != "no"; then fi fi +if test "${enable_network}" != "no"; then + ac_cv_my_have_network="no" + AC_CHECK_HEADERS(sys/socket.h, + [ac_cv_my_have_network="yes" + AC_DEFINE(USE_NETWORK, 1, Define to activate the network backend driver) + CACA_DRIVERS="${CACA_DRIVERS} network"]) + if test "${ac_cv_my_have_network}" = "no" -a "${enable_network}" = "yes"; then + AC_MSG_ERROR([cannot find standard networking socket files]) + fi +fi + if test "${enable_ncurses}" != "no"; then ac_cv_my_have_ncurses="no" AC_CHECK_HEADERS(curses.h ncurses.h,