Changeset 2402 for neercs


Ignore:
Timestamp:
Jun 15, 2008, 3:11:19 PM (12 years ago)
Author:
Jean-Yves Lamoureux
Message:
  • main.c now contains only main()
Location:
neercs/trunk/src
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • neercs/trunk/src/Makefile.am

    r2362 r2402  
    22bin_PROGRAMS = neercs
    33
    4 neercs_SOURCES = main.c neercs.h term.c effects.c wm.c
     4neercs_SOURCES = neercs.h main.c screens.c term.c effects.c wm.c
    55neercs_CFLAGS = @CACA_CFLAGS@
    66neercs_LDADD = @CACA_LIBS@ @UTIL_LIBS@
  • neercs/trunk/src/main.c

    r2401 r2402  
    3636
    3737#include "neercs.h"
    38 
    39 
    40 static int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid);
    4138
    4239int main(int argc, char **argv)
     
    264261    return 0;
    265262}
    266 
    267 static int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid)
    268 {
    269     char **argv;
    270     int fd;
    271     pid_t pid;
    272 
    273     pid = forkpty(&fd, NULL, NULL, NULL);
    274     if(pid < 0)
    275     {
    276         fprintf(stderr, "forkpty() error\n");
    277         return -1;
    278     }
    279     else if(pid == 0)
    280     {
    281         set_tty_size(0, w, h);
    282         putenv("CACA_DRIVER=slang");
    283         putenv("TERM=xterm");
    284         argv = malloc(2 * sizeof(char *));
    285         if(!argv)
    286         {
    287             fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__, __LINE__);
    288             return -1;
    289         }
    290         argv[0] = cmd;
    291         argv[1] = NULL;
    292         execvp(cmd, argv);
    293         fprintf(stderr, "execvp() error\n");
    294         return -1;
    295     }
    296 
    297     *cpid = pid;
    298 
    299     fcntl(fd, F_SETFL, O_NDELAY);
    300     return fd;
    301 #if 0
    302     fprintf(stderr, "forkpty() not available\n");
    303     return -1;
    304 #endif
    305 }
    306 
    307 int set_tty_size(int fd, unsigned int w, unsigned int h)
    308 {
    309     struct winsize ws;
    310 
    311     memset(&ws, 0, sizeof(ws));
    312     ws.ws_row = h;
    313     ws.ws_col = w;
    314     ioctl(fd, TIOCSWINSZ, (char *)&ws);
    315 
    316     return 0;
    317 }
    318 
    319 
    320 
    321 int update_terms(struct screen_list* screen_list)
    322 {
    323     int i, refresh = 0;
    324     for(i = 0; i < screen_list->count; i++)
    325     {
    326         if(screen_list->screen[i]->total)
    327         {
    328             unsigned long int bytes;
    329 
    330             bytes = import_term(screen_list,
    331                                 screen_list->screen[i],
    332                                 screen_list->screen[i]->buf,
    333                                 screen_list->screen[i]->total);
    334 
    335             if(bytes > 0)
    336             {
    337                 screen_list->screen[i]->total -= bytes;
    338                 memmove(screen_list->screen[i]->buf,
    339                         screen_list->screen[i]->buf + bytes,
    340                         screen_list->screen[i]->total);
    341                 refresh = 1;
    342             }
    343         }
    344     }
    345     return refresh;
    346 }
    347 
    348 
    349 
    350 
    351 int update_screens_contents(struct screen_list* screen_list,
    352                              int *pty, int *prevpty)
    353 {
    354     int i, refresh = 0;
    355     int maxfd = 0;
    356     struct timeval tv;
    357     fd_set fdset;
    358     int ret;
    359 
    360     /* Read data, if any */
    361     FD_ZERO(&fdset);
    362     for(i = 0; i < screen_list->count; i++)
    363     {
    364         if(screen_list->screen[i]->fd >= 0)
    365             FD_SET(screen_list->screen[i]->fd, &fdset);
    366         if(screen_list->screen[i]->fd > maxfd)
    367             maxfd = screen_list->screen[i]->fd;
    368     }
    369     tv.tv_sec = 0;
    370     tv.tv_usec = 50000;
    371     ret = select(maxfd + 1, &fdset, NULL, NULL, &tv);
    372 
    373     if(ret < 0)
    374     {
    375         if(errno == EINTR)
    376             ; /* We probably got a SIGWINCH, ignore it */
    377         else
    378         {
    379             for(i = 0; i < screen_list->count; i++)
    380                 if(screen_list->screen[i]->total)
    381                     break;
    382             if(i == screen_list->count)
    383                 return 0;
    384         }
    385     }
    386     else if(ret)
    387     {
    388 
    389     for(i = 0; i < screen_list->count; i++)
    390     {
    391         /* FIXME: try a new strategy: read all filedescriptors until
    392          * each of them starved at least once. */
    393 
    394         if(screen_list->screen[i]->fd < 0 ||
    395            !FD_ISSET(screen_list->screen[i]->fd, &fdset))
    396             continue;
    397 
    398         for(;;)
    399         {
    400             ssize_t nr;
    401 
    402             screen_list->screen[i]->buf =
    403                 realloc(screen_list->screen[i]->buf,
    404                         screen_list->screen[i]->total + 1024);
    405             nr = read(screen_list->screen[i]->fd,
    406                       screen_list->screen[i]->buf +
    407                       screen_list->screen[i]->total, 1024);
    408 
    409             if(nr > 0)
    410             {
    411                 screen_list->screen[i]->total += nr;
    412                 continue;
    413             }
    414 
    415             if(nr == 0 || errno != EWOULDBLOCK) {
    416                 close(screen_list->screen[i]->fd);
    417                 screen_list->screen[i]->fd = -1;
    418                 destroy_screen(screen_list->screen[i]);
    419                 remove_screen(screen_list, i, 0);
    420                 if(i < (*prevpty)) (*prevpty)--;
    421                 if(i == *pty)
    422                 {
    423                     *pty = *prevpty;
    424                     *prevpty = 0;
    425                 }
    426                 if(i < (*pty)) (*pty)--;
    427                 refresh = 1;
    428             }
    429 
    430             break;
    431         }
    432     }
    433     }
    434     return refresh;
    435 }
    436 
    437 void refresh_screens(cucul_canvas_t *cv,
    438                      caca_display_t *dp,
    439                      struct screen_list *screen_list,
    440                      int pty)
    441 {
    442     int i;
    443 
    444     screen_list->width  = cucul_get_canvas_width(cv);
    445     screen_list->height = cucul_get_canvas_height(cv) - (screen_list->mini*6);
    446 
    447     update_windows_props(cv, screen_list, pty);
    448 
    449     if(screen_list->screen[pty]->title)
    450         caca_set_display_title(dp, screen_list->screen[pty]->title);
    451     else
    452         caca_set_display_title(dp, PACKAGE_STRING);
    453 
    454     cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_DEFAULT);
    455     cucul_clear_canvas(cv);
    456     cucul_set_color_ansi(cv, CUCUL_LIGHTRED, CUCUL_BLACK);
    457 
    458     for(i = screen_list->count - 1; i >=0; i--)
    459     {
    460         if(i!=pty)
    461         {
    462             cucul_blit(cv,
    463                        screen_list->screen[i]->x,
    464                        screen_list->screen[i]->y,
    465                        screen_list->screen[i]->cv, NULL);
    466             cucul_draw_cp437_box(cv,
    467                                  screen_list->screen[i]->x - 1,
    468                                  screen_list->screen[i]->y - 1,
    469                                  screen_list->screen[i]->w + 2,
    470                                  screen_list->screen[i]->h + 2);
    471             if(screen_list->screen[i]->title)
    472                 cucul_printf(cv,
    473                              screen_list->screen[i]->x,
    474                              screen_list->screen[i]->y - 1,
    475                              " %.*s ",
    476                              screen_list->screen[i]->w - 3,
    477                              screen_list->screen[i]->title);
    478         }
    479     }
    480 
    481     cucul_blit(cv,
    482                screen_list->screen[pty]->x,
    483                screen_list->screen[pty]->y,
    484                screen_list->screen[pty]->cv, NULL);
    485 
    486     if(screen_list->screen[pty]->bell)
    487     {
    488         cucul_set_color_ansi(cv, CUCUL_RED, CUCUL_BLACK);
    489         screen_list->screen[pty]->bell = 0;
    490         screen_list->in_bell--;
    491     }
    492     else
    493     {
    494         cucul_set_color_ansi(cv, CUCUL_LIGHTGREEN, CUCUL_BLACK);
    495     }
    496 
    497     cucul_draw_cp437_box(cv,
    498                          screen_list->screen[pty]->x - 1,
    499                          screen_list->screen[pty]->y - 1,
    500                          screen_list->screen[pty]->w + 2,
    501                          screen_list->screen[pty]->h + 2);
    502 
    503     if(screen_list->screen[pty]->title)
    504     {
    505         cucul_printf(cv,
    506                      screen_list->screen[pty]->x,
    507                      screen_list->screen[pty]->y - 1,
    508                      " %.*s ",
    509                      screen_list->screen[pty]->w - 3,
    510                      screen_list->screen[pty]->title);
    511     }
    512 
    513     cucul_gotoxy(cv,
    514                  screen_list->screen[pty]->x +
    515                  cucul_get_cursor_x(screen_list->screen[pty]->cv),
    516                  screen_list->screen[pty]->y +
    517                  cucul_get_cursor_y(screen_list->screen[pty]->cv));
    518 
    519 
    520     if(screen_list->mini)
    521     {
    522         draw_thumbnails(cv, screen_list, pty);
    523     }
    524     if(screen_list->status)
    525     {
    526         draw_status(cv, screen_list, pty);
    527     }
    528     if(screen_list->help)
    529     {
    530         draw_help(cv, screen_list, pty);
    531     }
    532 
    533     caca_refresh_display(dp);
    534 }
    535 
    536 
    537 
    538 struct screen* create_screen(int w, int h, char *command)
    539 {
    540     struct screen *s = (struct screen*) malloc(sizeof(struct screen));
    541 
    542     s->cv = cucul_create_canvas(w, h);
    543     cucul_set_color_ansi(s->cv, CUCUL_BLACK, CUCUL_BLACK);
    544     cucul_clear_canvas(s->cv);
    545     s->init = 0;
    546 
    547     s->buf = NULL;
    548     s->title = NULL;
    549     s->total = 0;
    550     s->w = w+1;
    551     s->h = h+1;
    552     s->bell = 0;
    553 
    554     s->fd = create_pty(command, w, h, &s->pid);
    555 
    556     if(s->fd < 0)
    557     {
    558         cucul_free_canvas(s->cv);
    559         free(s);
    560         return NULL;
    561     }
    562     return s;
    563 }
    564 
    565 int destroy_screen(struct screen *s)
    566 {
    567     if(s->fd>0)
    568         close(s->fd);
    569     if(s->buf)
    570         free(s->buf);
    571     if(s->title)
    572         free(s->title);
    573     s->buf = NULL;
    574     if(s->cv)
    575         cucul_free_canvas(s->cv);
    576     s->cv = NULL;
    577     if(s)
    578         free(s);
    579     s = NULL;
    580     return 1;
    581 }
    582 
    583 int add_screen(struct screen_list *list, struct screen *s)
    584 {
    585     if(list == NULL || s == NULL) return -1;
    586 
    587     else
    588     {
    589         list->screen = (struct screen**) realloc(list->screen,
    590                                                  sizeof(sizeof(struct screen*))
    591                                                  * (list->count+1));
    592         list->screen[list->count] = s;
    593         list->count++;
    594     }
    595 
    596     return list->count-1;
    597 }
    598 
    599 int remove_screen(struct screen_list *list, int n, int please_kill)
    600 {
    601     if(n>list->count) return -1;
    602 
    603     if(please_kill)
    604     {
    605         int status = 0;
    606         int ret = 0;
    607         /* FIXME */
    608         close(list->screen[n]->fd);
    609         list->screen[n]->fd = -1;
    610         kill(list->screen[n]->pid, SIGINT);
    611         ret = waitpid(list->screen[n]->pid, &status,
    612                       WNOHANG|WUNTRACED|WCONTINUED);
    613         if(!ret)
    614             kill(list->screen[n]->pid, SIGQUIT);
    615         ret = waitpid(list->screen[n]->pid, &status,
    616                       WNOHANG|WUNTRACED|WCONTINUED);
    617         if(!ret)
    618             kill(list->screen[n]->pid, SIGABRT);
    619         ret = waitpid(list->screen[n]->pid, &status,
    620                       WNOHANG|WUNTRACED|WCONTINUED);
    621         if(!ret)
    622             kill(list->screen[n]->pid, SIGKILL);
    623 
    624     }
    625 
    626     memmove(&list->screen[n],
    627             &list->screen[n+1],
    628             sizeof(struct screen*)*(list->count-(n+1)));
    629 
    630     list->screen = (struct screen**) realloc(list->screen,
    631                                              sizeof(sizeof(struct screen*))
    632                                              * (list->count));
    633 
    634     list->count--;
    635     return 1;
    636 }
    637 
  • neercs/trunk/src/neercs.h

    r2401 r2402  
    6565
    6666
     67int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid);
    6768
    6869long int import_term(struct screen_list *screen_list, struct screen *sc, void const *data, unsigned int size);
  • neercs/trunk/src/term.c

    r2396 r2402  
    1818#include <stdio.h>
    1919#include <string.h>
     20#include <pty.h>
     21#include <unistd.h>
     22#include <fcntl.h>
     23
    2024#include <cucul.h>
    2125#include <caca.h>
     
    535539}
    536540
     541int create_pty(char *cmd, unsigned int w, unsigned int h, int *cpid)
     542{
     543    char **argv;
     544    int fd;
     545    pid_t pid;
     546
     547    pid = forkpty(&fd, NULL, NULL, NULL);
     548    if(pid < 0)
     549    {
     550        fprintf(stderr, "forkpty() error\n");
     551        return -1;
     552    }
     553    else if(pid == 0)
     554    {
     555        set_tty_size(0, w, h);
     556        putenv("CACA_DRIVER=slang");
     557        putenv("TERM=xterm");
     558        argv = malloc(2 * sizeof(char *));
     559        if(!argv)
     560        {
     561            fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__, __LINE__);
     562            return -1;
     563        }
     564        argv[0] = cmd;
     565        argv[1] = NULL;
     566        execvp(cmd, argv);
     567        fprintf(stderr, "execvp() error\n");
     568        return -1;
     569    }
     570
     571    *cpid = pid;
     572
     573    fcntl(fd, F_SETFL, O_NDELAY);
     574    return fd;
     575}
     576
     577int set_tty_size(int fd, unsigned int w, unsigned int h)
     578{
     579    struct winsize ws;
     580
     581    memset(&ws, 0, sizeof(ws));
     582    ws.ws_row = h;
     583    ws.ws_col = w;
     584    ioctl(fd, TIOCSWINSZ, (char *)&ws);
     585
     586    return 0;
     587}
     588
     589
     590
     591int update_terms(struct screen_list* screen_list)
     592{
     593    int i, refresh = 0;
     594    for(i = 0; i < screen_list->count; i++)
     595    {
     596        if(screen_list->screen[i]->total)
     597        {
     598            unsigned long int bytes;
     599
     600            bytes = import_term(screen_list,
     601                                screen_list->screen[i],
     602                                screen_list->screen[i]->buf,
     603                                screen_list->screen[i]->total);
     604
     605            if(bytes > 0)
     606            {
     607                screen_list->screen[i]->total -= bytes;
     608                memmove(screen_list->screen[i]->buf,
     609                        screen_list->screen[i]->buf + bytes,
     610                        screen_list->screen[i]->total);
     611                refresh = 1;
     612            }
     613        }
     614    }
     615    return refresh;
     616}
     617
Note: See TracChangeset for help on using the changeset viewer.