Changeset 703 for libcaca/trunk/src


Ignore:
Timestamp:
Mar 27, 2006, 11:37:52 PM (15 years ago)
Author:
Sam Hocevar
Message:
  • Removed the network driver and replaced it with a cacaserver executable that has all the functionality, except it does not work yet (the stdin reading routine is missing).
Location:
libcaca/trunk/src
Files:
3 edited
1 moved

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/src

    • Property svn:ignore
      •  

        old new  
        99cacaplas
        1010cacaplay
         11cacaserver
        1112*.exe
  • libcaca/trunk/src/Makefile.am

    r702 r703  
    66AM_CPPFLAGS = -I$(top_srcdir)/cucul -I$(top_srcdir)/caca -DLIBCACA=1 -DX_DISPLAY_MISSING=1
    77
    8 bin_PROGRAMS = cacafire cacaball cacaplas cacaview cacamoir cacaplay
     8bin_PROGRAMS = cacafire cacaball cacaplas cacaserver cacaview cacamoir cacaplay
    99
    1010cacafire_SOURCES = aafire.c
     
    1919cacamoir_SOURCES = cacamoir.c
    2020cacamoir_LDADD = ../caca/libcaca.la ../cucul/libcucul.la @CACA_LIBS@ @MATH_LIBS@
     21
     22cacaplay_SOURCES = cacaplay.c
     23cacaplay_LDADD = ../caca/libcaca.la ../cucul/libcucul.la @CACA_LIBS@
    2124
    2225cacaview_SOURCES = cacaview.c
     
    3336cacaplay_LDADD = ../caca/libcaca.la ../cucul/libcucul.la @CACA_LIBS@
    3437
     38cacaserver_SOURCES = cacaserver.c
     39cacaserver_LDADD = ../caca/libcaca.la ../cucul/libcucul.la @CACA_LIBS@
     40
  • libcaca/trunk/src/cacaplas.c

    r681 r703  
    1616
    1717#if !defined(__KERNEL__)
     18#   include <stdio.h>
    1819#   include <math.h>
    1920#   ifndef M_PI
     
    4041int main (int argc, char **argv)
    4142{
    42     cucul_t *qq; caca_t *kk;
     43    cucul_t *qq, *qq2, *mask; caca_t *kk;
    4344    unsigned int red[256], green[256], blue[256], alpha[256];
    4445    double r[3], R[6];
     
    5455
    5556    caca_set_delay(kk, 20000);
     57
     58    qq2 = cucul_create(cucul_get_width(qq), cucul_get_height(qq));
     59    mask = cucul_create(cucul_get_width(qq), cucul_get_height(qq));
    5660
    5761    /* Fill various tables */
     
    119123                          cucul_get_width(qq) - 1, cucul_get_height(qq) - 1,
    120124                          bitmap, screen);
     125
     126        cucul_blit(qq2, 0, 0, qq, NULL);
     127        cucul_invert(qq2);
     128
     129        cucul_clear(mask);
     130        cucul_set_color(mask, CUCUL_COLOR_WHITE, CUCUL_COLOR_WHITE);
     131        cucul_fill_ellipse(mask, (1.0 + 0.7 * sin(0.05 * (float)frame))
     132                                   * 0.5 * cucul_get_width(mask),
     133                                 (1.0 + 0.7 * cos(0.05 * (float)frame))
     134                                   * 0.5 * cucul_get_height(mask),
     135                                 cucul_get_width(mask) / 3,
     136                                 cucul_get_height(mask) / 3, "#");
     137
     138        cucul_blit(qq, 0, 0, qq2, mask);
     139
    121140        cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
    122141        cucul_putstr(qq, cucul_get_width(qq) - 30, cucul_get_height(qq) - 2,
  • libcaca/trunk/src/cacaserver.c

    r698 r703  
    11/*
    2  *  libcaca       Colour ASCII-Art library
    3  *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
     2 *  cacaserver    Colour ASCII-Art library
     3 *  Copyright (c) 2006 Jean-Yves Lamoureux <jylam@lnxscene.org>
     4 *                2006 Sam Hocevar <sam@zoy.org>
    45 *                All Rights Reserved
    56 *
    6  *  This library is free software; you can redistribute it and/or
     7 *  This program is free software; you can redistribute it and/or
    78 *  modify it under the terms of the Do What The Fuck You Want To
    89 *  Public License, Version 2, as published by Sam Hocevar. See
     
    1011 */
    1112
    12 /** \file driver_network.c
    13  *  \version \$Id$
    14  *  \author Jean-Yves Lamoureux <jylam@lnxscene.org>
    15  *  \brief Network driver
    16  *
    17  *  This file contains the libcaca network input and output driver
    18  */
    19 
    2013#include "config.h"
    2114
    22 #if defined(USE_NETWORK)
    2315#include <stdio.h>
     16#include <string.h>
    2417#include <stdlib.h>
    2518#include <sys/types.h>
     
    2720#include <arpa/inet.h>
    2821#include <fcntl.h>
    29 #include <string.h>
    3022#include <signal.h>
    3123#include <errno.h>
     24
     25#include "cucul.h"
     26#include "caca.h"
     27
     28#include "config.h"
    3229
    3330#if defined(HAVE_UNISTD_H)
    3431#   include <unistd.h>
    3532#endif
     33
    3634#include <stdarg.h>
    3735
    3836#include "caca.h"
    39 #include "caca_internals.h"
    4037#include "cucul.h"
    41 #include "cucul_internals.h"
    4238
    4339#define BACKLOG 1337     /* Number of pending connections */
     
    6561    "\x1b[?1049h" /* Clear screen again */
    6662
    67 
    6863static char const telnet_commands[16][5] =
    69     {"SE  ", "NOP ", "DM  ", "BRK ", "IP  ", "AO  ", "AYT ", "EC  ",
    70      "EL  ", "GA  ", "SB  ", "WILL", "WONT", "DO  ", "DONT", "IAC "};
     64{
     65    "SE  ", "NOP ", "DM  ", "BRK ", "IP  ", "AO  ", "AYT ", "EC  ",
     66    "EL  ", "GA  ", "SB  ", "WILL", "WONT", "DO  ", "DONT", "IAC "
     67};
    7168
    7269static char const telnet_options[37][5] =
    73     {"????", "ECHO", "????", "SUGH", "????", "STTS", "TIMK", "????", "????", "????",
    74      "????", "????", "????", "????", "????", "????", "????", "????", "????", "????",
    75      "????", "????", "????", "????", "TTYP", "????", "????", "????", "????", "????",
    76      "????", "NAWS", "TRSP", "RMFC", "LIMO", "????", "EVAR"};
    77 
     70{
     71    "????", "ECHO", "????", "SUGH", "????", "STTS", "TIMK", "????",
     72    "????", "????", "????", "????", "????", "????", "????", "????",
     73    "????", "????", "????", "????", "????", "????", "????", "????",
     74    "TTYP", "????", "????", "????", "????", "????", "????", "NAWS",
     75    "TRSP", "RMFC", "LIMO", "????", "EVAR"
     76};
    7877
    7978#define COMMAND_NAME(x) (x>=240)?telnet_commands[x-240]:"????"
    8079#define OPTION_NAME(x) (x<=36)?telnet_options[x]:"????"
    81 
    8280
    8381struct client
     
    9189};
    9290
    93 struct driver_private
     91struct server
    9492{
    9593    unsigned int width, height;
     
    9997    socklen_t sin_size;
    10098
     99    /* Input buffer */
     100
    101101    char prefix[sizeof(INIT_PREFIX)];
    102102
     
    109109};
    110110
    111 static void manage_connections(caca_t *kk);
    112 static int send_data(caca_t *kk, struct client *c);
     111static void manage_connections(struct server *server);
     112static int send_data(struct server *server, struct client *c);
    113113ssize_t nonblock_write(int fd, void *buf, size_t len);
    114114
    115 static int network_init_graphics(caca_t *kk)
    116 {
    117     int yes = 1, flags;
    118     int port = 0xCACA; /* 51914 */
    119     unsigned int width = 0, height = 0;
     115int main(void)
     116{
     117    cucul_t *qq;
     118    int i, yes = 1, flags;
     119    struct server *server;
    120120    char *tmp;
    121121
    122     kk->drv.p = malloc(sizeof(struct driver_private));
    123     if(kk->drv.p == NULL)
    124         return -1;
    125 
    126 #if defined(HAVE_GETENV)
    127     tmp = getenv("CACA_PORT");
    128     if(tmp && *tmp)
    129     {
    130         int new_port = atoi(tmp);
    131         if(new_port)
    132             port = new_port;
    133     }
    134 
    135     tmp = getenv("CACA_GEOMETRY");
    136     if(tmp && *tmp)
    137         sscanf(tmp, "%ux%u", &width, &height);
    138 #endif
    139 
    140     if(width && height)
    141     {
    142         kk->drv.p->width = width;
    143         kk->drv.p->height = height;
    144     }
    145     else
    146     {
    147         kk->drv.p->width = 80;
    148         kk->drv.p->height = 24;
    149     }
    150 
    151     kk->drv.p->client_count = 0;
    152     kk->drv.p->clients = NULL;
    153     kk->drv.p->port = port;
    154 
    155     _cucul_set_size(kk->qq, kk->drv.p->width, kk->drv.p->height);
     122    server = malloc(sizeof(struct server));
     123
     124    server->client_count = 0;
     125    server->clients = NULL;
     126    server->port = 0xCACA; /* 51914 */
    156127
    157128    /* FIXME, handle >255 sizes */
    158     memcpy(kk->drv.p->prefix, INIT_PREFIX, sizeof(INIT_PREFIX));
    159     tmp = strstr(kk->drv.p->prefix, "____");
    160     tmp[0] = (unsigned char) (kk->drv.p->width & 0xff00) >> 8;
    161     tmp[1] = (unsigned char) kk->drv.p->width & 0xff;
    162     tmp[2] = (unsigned char) (kk->drv.p->height & 0xff00) >> 8;
    163     tmp[3] = (unsigned char) kk->drv.p->height & 0xff;
    164 
    165     if ((kk->drv.p->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
     129    memcpy(server->prefix, INIT_PREFIX, sizeof(INIT_PREFIX));
     130    tmp = strstr(server->prefix, "____");
     131    tmp[0] = (unsigned char) (server->width & 0xff00) >> 8;
     132    tmp[1] = (unsigned char) server->width & 0xff;
     133    tmp[2] = (unsigned char) (server->height & 0xff00) >> 8;
     134    tmp[3] = (unsigned char) server->height & 0xff;
     135
     136    if((server->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
    166137    {
    167138        perror("socket");
     
    169140    }
    170141
    171     if (setsockopt(kk->drv.p->sockfd, SOL_SOCKET,
    172                    SO_REUSEADDR, &yes, sizeof(int)) == -1)
     142    if(setsockopt(server->sockfd, SOL_SOCKET,
     143                  SO_REUSEADDR, &yes, sizeof(int)) == -1)
    173144    {
    174145        perror("setsockopt SO_REUSEADDR");
     
    176147    }
    177148
    178     kk->drv.p->my_addr.sin_family = AF_INET;
    179     kk->drv.p-> my_addr.sin_port = htons(kk->drv.p->port);
    180     kk->drv.p->my_addr.sin_addr.s_addr = INADDR_ANY;
    181     memset(&(kk->drv.p->my_addr.sin_zero), '\0', 8);
    182 
    183     if (bind(kk->drv.p->sockfd, (struct sockaddr *)&kk->drv.p->my_addr,
     149    server->my_addr.sin_family = AF_INET;
     150    server-> my_addr.sin_port = htons(server->port);
     151    server->my_addr.sin_addr.s_addr = INADDR_ANY;
     152    memset(&(server->my_addr.sin_zero), '\0', 8);
     153
     154    if(bind(server->sockfd, (struct sockaddr *)&server->my_addr,
    184155             sizeof(struct sockaddr)) == -1)
    185156    {
     
    189160
    190161    /* Non blocking socket */
    191     flags = fcntl(kk->drv.p->sockfd, F_GETFL, 0);
    192     fcntl(kk->drv.p->sockfd, F_SETFL, flags | O_NONBLOCK);
    193 
    194     if (listen(kk->drv.p->sockfd, BACKLOG) == -1)
     162    flags = fcntl(server->sockfd, F_GETFL, 0);
     163    fcntl(server->sockfd, F_SETFL, flags | O_NONBLOCK);
     164
     165    if(listen(server->sockfd, BACKLOG) == -1)
    195166    {
    196167        perror("listen");
     
    198169    }
    199170
    200     kk->drv.p->ex = NULL;
     171    server->ex = NULL;
    201172
    202173    /* Ignore SIGPIPE */
    203     kk->drv.p->sigpipe_handler = signal(SIGPIPE, SIG_IGN);
     174    server->sigpipe_handler = signal(SIGPIPE, SIG_IGN);
    204175
    205176    fprintf(stderr, "initialised network, listening on port %i\n",
    206                     kk->drv.p->port);
    207 
    208     return 0;
    209 }
    210 
    211 static int network_end_graphics(caca_t *kk)
    212 {
    213     int i;
    214 
    215     for(i = 0; i < kk->drv.p->client_count; i++)
    216     {
    217         close(kk->drv.p->clients[i].fd);
    218         kk->drv.p->clients[i].fd = -1;
    219     }
    220 
    221     if(kk->drv.p->ex)
    222         cucul_free_export(kk->drv.p->ex);
     177                    server->port);
     178
     179    /* Main loop */
     180    for(;;)
     181    {
     182        /* Manage new connections as this function will be called sometimes
     183         * more often than display */
     184        manage_connections(server);
     185
     186        /* Read data from stdin */
     187        /* FIXME: read data, then continue if there was a new image */
     188
     189        /* Free the previous export buffer, if any */
     190        if(server->ex)
     191        {
     192            cucul_free_export(server->ex);
     193            server->ex = NULL;
     194        }
     195
     196        /* Get ANSI representation of the image and skip the end-of buffer
     197         * linefeed ("\r\n\0", 3 bytes) */
     198        server->ex = cucul_create_export(qq, CUCUL_FORMAT_ANSI);
     199        server->ex->size -= 3;
     200
     201        for(i = 0; i < server->client_count; i++)
     202        {
     203            if(server->clients[i].fd == -1)
     204                continue;
     205
     206            if(send_data(server, &server->clients[i]))
     207            {
     208                fprintf(stderr, "client %i dropped connection\n",
     209                                server->clients[i].fd);
     210                close(server->clients[i].fd);
     211                server->clients[i].fd = -1;
     212            }
     213        }
     214    }
     215
     216    /* Kill all remaining clients */
     217    for(i = 0; i < server->client_count; i++)
     218    {
     219        if(server->clients[i].fd == -1)
     220            continue;
     221
     222        close(server->clients[i].fd);
     223        server->clients[i].fd = -1;
     224    }
     225
     226    if(server->ex)
     227        cucul_free_export(server->ex);
    223228
    224229    /* Restore SIGPIPE handler */
    225     signal(SIGPIPE, kk->drv.p->sigpipe_handler);
    226 
    227     free(kk->drv.p);
    228 
    229     return 0;
    230 }
    231 
    232 static int network_set_window_title(caca_t *kk, char const *title)
    233 {
    234     /* Not handled (yet) */
    235     return 0;
    236 }
    237 
    238 static unsigned int network_get_window_width(caca_t *kk)
    239 {
    240     return kk->drv.p->width * 6;
    241 }
    242 
    243 static unsigned int network_get_window_height(caca_t *kk)
    244 {
    245     return kk->drv.p->height * 10;
    246 }
    247 
    248 static void network_display(caca_t *kk)
    249 {
    250     int i;
    251 
    252     /* Free the previous export buffer, if any */
    253     if(kk->drv.p->ex)
    254     {
    255         cucul_free_export(kk->drv.p->ex);
    256         kk->drv.p->ex = NULL;
    257     }
    258 
    259     /* Get ANSI representation of the image and skip the end-of buffer
    260      * linefeed ("\r\n\0", 3 bytes) */
    261     kk->drv.p->ex = cucul_create_export(kk->qq, CUCUL_FORMAT_ANSI);
    262     kk->drv.p->ex->size -= 3;
    263 
    264     for(i = 0; i < kk->drv.p->client_count; i++)
    265     {
    266         if(kk->drv.p->clients[i].fd == -1)
    267             continue;
    268 
    269         if(send_data(kk, &kk->drv.p->clients[i]))
    270         {
    271             fprintf(stderr, "client %i dropped connection\n",
    272                             kk->drv.p->clients[i].fd);
    273             close(kk->drv.p->clients[i].fd);
    274             kk->drv.p->clients[i].fd = -1;
    275         }
    276     }
    277 
    278     manage_connections(kk);
    279 }
    280 
    281 static void network_handle_resize(caca_t *kk)
    282 {
    283     /* Not handled */
    284 }
    285 
    286 static int network_get_event(caca_t *kk, struct caca_event *ev)
    287 {
    288     /* Manage new connections as this function will be called sometimes
    289      * more often than display */
    290     manage_connections(kk);
    291 
    292     /* Event not handled */
     230    signal(SIGPIPE, server->sigpipe_handler);
     231
     232    free(server);
     233
    293234    return 0;
    294235}
     
    298239 */
    299240
    300 static void manage_connections(caca_t *kk)
     241static void manage_connections(struct server *server)
    301242{
    302243    int fd, flags;
     
    304245    socklen_t len = sizeof(struct sockaddr_in);
    305246
    306     fd = accept(kk->drv.p->sockfd, (struct sockaddr *)&remote_addr, &len);
     247    fd = accept(server->sockfd, (struct sockaddr *)&remote_addr, &len);
    307248    if(fd == -1)
    308249        return;
     
    315256    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    316257
    317     if(kk->drv.p->clients == NULL)
    318     {
    319         kk->drv.p->clients = malloc(sizeof(struct client));
    320         if(kk->drv.p->clients == NULL)
     258    if(server->clients == NULL)
     259    {
     260        server->clients = malloc(sizeof(struct client));
     261        if(server->clients == NULL)
    321262            return;
    322263    }
    323264    else
    324265    {
    325         kk->drv.p->clients = realloc(kk->drv.p->clients,
    326                                      (kk->drv.p->client_count+1) * sizeof(struct client));
    327     }
    328 
    329     kk->drv.p->clients[kk->drv.p->client_count].fd = fd;
    330     kk->drv.p->clients[kk->drv.p->client_count].ready = 0;
    331     kk->drv.p->clients[kk->drv.p->client_count].inbytes = 0;
    332     kk->drv.p->clients[kk->drv.p->client_count].start = 0;
    333     kk->drv.p->clients[kk->drv.p->client_count].stop = 0;
     266        server->clients = realloc(server->clients,
     267                            (server->client_count+1) * sizeof(struct client));
     268    }
     269
     270    server->clients[server->client_count].fd = fd;
     271    server->clients[server->client_count].ready = 0;
     272    server->clients[server->client_count].inbytes = 0;
     273    server->clients[server->client_count].start = 0;
     274    server->clients[server->client_count].stop = 0;
    334275
    335276    /* If we already have data to send, send it to the new client */
    336     if(send_data(kk, &kk->drv.p->clients[kk->drv.p->client_count]))
     277    if(send_data(server, &server->clients[server->client_count]))
    337278    {
    338279        fprintf(stderr, "client %i dropped connection\n", fd);
    339280        close(fd);
    340         kk->drv.p->clients[kk->drv.p->client_count].fd = -1;
     281        server->clients[server->client_count].fd = -1;
    341282        return;
    342283    }
    343284
    344     kk->drv.p->client_count++;
     285    server->client_count++;
    345286}
    346287
    347 static int send_data(caca_t *kk, struct client *c)
     288static int send_data(struct server *server, struct client *c)
    348289{
    349290    ssize_t ret;
     
    398339    if(!c->ready)
    399340    {
    400         ret = nonblock_write(c->fd, kk->drv.p->prefix, sizeof(INIT_PREFIX));
     341        ret = nonblock_write(c->fd, server->prefix, sizeof(INIT_PREFIX));
    401342        if(ret == -1)
    402343            return (errno == EAGAIN) ? 0 : -1;
     
    409350
    410351    /* No error, there's just nothing to send yet */
    411     if(!kk->drv.p->ex)
     352    if(!server->ex)
    412353        return 0;
    413354
     
    434375            c->start += ret;
    435376
    436             if(c->stop - c->start + strlen(ANSI_PREFIX) + kk->drv.p->ex->size
     377            if(c->stop - c->start + strlen(ANSI_PREFIX) + server->ex->size
    437378                > OUTBUFFER)
    438379            {
     
    445386
    446387            /* Need to move? */
    447             if(c->stop + strlen(ANSI_PREFIX) + kk->drv.p->ex->size > OUTBUFFER)
     388            if(c->stop + strlen(ANSI_PREFIX) + server->ex->size > OUTBUFFER)
    448389            {
    449390                memmove(c->outbuf, c->outbuf + c->start, c->stop - c->start);
     
    454395            memcpy(c->outbuf + c->stop, ANSI_PREFIX, strlen(ANSI_PREFIX));
    455396            c->stop += strlen(ANSI_PREFIX);
    456             memcpy(c->outbuf + c->stop, kk->drv.p->ex->buffer, kk->drv.p->ex->size);
    457             c->stop += kk->drv.p->ex->size;
     397            memcpy(c->outbuf + c->stop, server->ex->buffer, server->ex->size);
     398            c->stop += server->ex->size;
    458399
    459400            return 0;
     
    475416    if(ret < (ssize_t)strlen(ANSI_PREFIX))
    476417    {
    477         if(strlen(ANSI_PREFIX) + kk->drv.p->ex->size > OUTBUFFER)
     418        if(strlen(ANSI_PREFIX) + server->ex->size > OUTBUFFER)
    478419        {
    479420            /* Overflow! Empty buffer and start again */
     
    486427        memcpy(c->outbuf, ANSI_PREFIX, strlen(ANSI_PREFIX) - ret);
    487428        c->stop = strlen(ANSI_PREFIX) - ret;
    488         memcpy(c->outbuf + c->stop, kk->drv.p->ex->buffer, kk->drv.p->ex->size);
    489         c->stop += kk->drv.p->ex->size;
     429        memcpy(c->outbuf + c->stop, server->ex->buffer, server->ex->size);
     430        c->stop += server->ex->size;
    490431
    491432        return 0;
     
    493434
    494435    /* Send actual data */
    495     ret = nonblock_write(c->fd, kk->drv.p->ex->buffer, kk->drv.p->ex->size);
     436    ret = nonblock_write(c->fd, server->ex->buffer, server->ex->size);
    496437    if(ret == -1)
    497438    {
     
    502443    }
    503444
    504     if(ret < (int)kk->drv.p->ex->size)
    505     {
    506         if(kk->drv.p->ex->size > OUTBUFFER)
     445    if(ret < (int)server->ex->size)
     446    {
     447        if(server->ex->size > OUTBUFFER)
    507448        {
    508449            /* Overflow! Empty buffer and start again */
     
    513454        }
    514455
    515         memcpy(c->outbuf, kk->drv.p->ex->buffer, kk->drv.p->ex->size - ret);
    516         c->stop = kk->drv.p->ex->size - ret;
     456        memcpy(c->outbuf, server->ex->buffer, server->ex->size - ret);
     457        c->stop = server->ex->size - ret;
    517458
    518459        return 0;
     
    547488}
    548489
    549 /*
    550  * Driver initialisation
    551  */
    552 
    553 int network_install(caca_t *kk)
    554 {
    555     kk->drv.driver = CACA_DRIVER_NETWORK;
    556 
    557     kk->drv.init_graphics = network_init_graphics;
    558     kk->drv.end_graphics = network_end_graphics;
    559     kk->drv.set_window_title = network_set_window_title;
    560     kk->drv.get_window_width = network_get_window_width;
    561     kk->drv.get_window_height = network_get_window_height;
    562     kk->drv.display = network_display;
    563     kk->drv.handle_resize = network_handle_resize;
    564     kk->drv.get_event = network_get_event;
    565     kk->drv.set_mouse = NULL;
    566 
    567     return 0;
    568 }
    569 
    570 #endif /* USE_NETWORK */
    571 
Note: See TracChangeset for help on using the changeset viewer.