Changeset 2357 for neercs


Ignore:
Timestamp:
Jun 11, 2008, 5:13:41 PM (12 years ago)
Author:
Jean-Yves Lamoureux
Message:
  • Reorganised screen management in a list
  • Minor cosmetic changes
  • Refresh screen when a window is destroyed
Location:
neercs/trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • neercs/trunk/src/main.c

    r2356 r2357  
    22 *  neercs        console-based window manager
    33 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
     4 *                2008 Jean-Yves Lamoureux <jylam@lnxscene.org>
    45 *                All Rights Reserved
    56 *
     
    4243    static cucul_canvas_t *cv;
    4344    static caca_display_t *dp;
    44     static struct screen *screen;
    45     int pty = 0, prevpty = 0, i, n, w, h;
     45    struct screen_list *screen_list = NULL;
     46    int pty = 0, prevpty = 0, i, w, h, nt;
    4647    int eof = 0, refresh = 1, command = 0, mini = 1;
    4748
     
    5354    }
    5455
     56    nt = argc - 1;
     57
     58    /* Create main canvas and associated caca window */
    5559    cv = cucul_create_canvas(0, 0);
    5660    dp = caca_create_display(cv);
     
    5963    caca_set_cursor(dp, 1);
    6064
    61     n = argc - 1;
    62     screen = malloc(n * sizeof(struct screen));
    6365
    6466    w = cucul_get_canvas_width(cv);
    6567    h = cucul_get_canvas_height(cv);
    6668
    67     w = w <= XTAB * n ? 1 : w - XTAB * (n - 1) - 2;
    68     h = h <= YTAB * n ? 1 : h - YTAB * (n - 1) - 2 - 6;
    69 
    70     for(i = 0; i < n; i++)
    71     {
    72         screen[i].cv = cucul_create_canvas(w, h);
    73         screen[i].init = 0;
     69    w = w <= XTAB * nt ? 1 : w - XTAB * (nt - 1) - 2;
     70    h = h <= YTAB * nt ? 1 : h - YTAB * (nt - 1) - 2 - 6;
     71
     72
     73    /* Create screen list */
     74    screen_list = (struct screen_list*)   malloc(sizeof(struct screen_list));
     75    screen_list->screen = (struct screen**) malloc(sizeof(sizeof(struct screen*)));
     76    screen_list->count = 0;
     77
     78    for(i = 0; i < nt; i++)
     79    {
     80        struct screen *tmp = create_screen(w, h, argv[i + 1]);
     81        if(tmp)
     82        {
     83            if(add_screen(screen_list, tmp) < 0)
     84            {
     85                fprintf(stderr, "Can't add %p to %p\n", tmp, screen_list);
     86            }
     87        }
     88        else
     89        {
     90            fprintf(stderr, "Can't create screen\n");
     91        }
    7492    }
    7593
    7694    cucul_set_color_ansi(cv, CUCUL_LIGHTRED, CUCUL_BLACK);
    77     cucul_draw_cp437_box(cv, (n - 1 - pty) * XTAB, pty * YTAB,
    78                          w + (n - 1 - pty) * XTAB + 1, h + pty * YTAB + 1);
     95    cucul_draw_cp437_box(cv, (screen_list->count - 1 - pty) * XTAB, pty * YTAB,
     96                         w + (screen_list->count - 1 - pty) * XTAB + 1, h + pty * YTAB + 1);
    7997
    8098    caca_refresh_display(dp);
    81 
    82     for(i = 0; i < n; i++)
    83     {
    84         screen[i].buf = NULL;
    85         screen[i].total = 0;
    86         screen[i].fd = create_pty(argv[i + 1], w, h);
    87         if(screen[i].fd < 0)
    88             return -1;
    89     }
    9099
    91100    for(;;)
     
    98107        /* Read data, if any */
    99108        FD_ZERO(&fdset);
    100         for(i = 0; i < n; i++)
    101         {
    102             if(screen[i].fd >= 0)
    103                 FD_SET(screen[i].fd, &fdset);
    104             if(screen[i].fd > maxfd)
    105                 maxfd = screen[i].fd;
     109        for(i = 0; i < screen_list->count; i++)
     110        {
     111            if(screen_list->screen[i]->fd >= 0)
     112                FD_SET(screen_list->screen[i]->fd, &fdset);
     113            if(screen_list->screen[i]->fd > maxfd)
     114                maxfd = screen_list->screen[i]->fd;
    106115        }
    107116        tv.tv_sec = 0;
     
    115124            else
    116125            {
    117                 for(i = 0; i < n; i++)
    118                     if(screen[i].total)
     126                for(i = 0; i < screen_list->count; i++)
     127                    if(screen_list->screen[i]->total)
    119128                        break;
    120                 if(i == n)
    121                     break;
    122             }
    123         }
    124         else if(ret) for(i = 0; i < n; i++)
    125         {
    126             /* FIXME: try a new strategy: read all filedescriptors until
    127              * each of them starved at least once. */
    128 
    129             if(screen[i].fd < 0 || !FD_ISSET(screen[i].fd, &fdset))
    130                 continue;
    131 
    132             for(;;)
    133             {
    134                 ssize_t nr;
    135 
    136                 screen[i].buf = realloc(screen[i].buf, screen[i].total + 1024);
    137                 nr = read(screen[i].fd, screen[i].buf + screen[i].total, 1024);
    138 
    139                 if(nr > 0)
     129                if(i == screen_list->count)
     130                    break;
     131            }
     132        }
     133        else if(ret)
     134            for(i = 0; i < screen_list->count; i++)
     135            {
     136                /* FIXME: try a new strategy: read all filedescriptors until
     137                 * each of them starved at least once. */
     138
     139                if(screen_list->screen[i]->fd < 0 || !FD_ISSET(screen_list->screen[i]->fd, &fdset))
     140                    continue;
     141
     142                for(;;)
    140143                {
    141                     screen[i].total += nr;
    142                     continue;
     144                    ssize_t nr;
     145
     146                    screen_list->screen[i]->buf = realloc(screen_list->screen[i]->buf,
     147                                                          screen_list->screen[i]->total + 1024);
     148                    nr = read(screen_list->screen[i]->fd,
     149                              screen_list->screen[i]->buf + screen_list->screen[i]->total, 1024);
     150
     151                    if(nr > 0)
     152                    {
     153                        screen_list->screen[i]->total += nr;
     154                        continue;
     155                    }
     156
     157                    if(nr == 0 || errno != EWOULDBLOCK) {
     158                        close(screen_list->screen[i]->fd);
     159                        screen_list->screen[i]->fd = -1;
     160                        destroy_screen(screen_list->screen[i]);
     161                        remove_screen(screen_list, i);
     162                        refresh = 1;
     163                    }
     164
     165                    break;
    143166                }
    144 
    145                 if(nr == 0 || errno != EWOULDBLOCK) {
    146                     close(screen[i].fd);                       
    147                     screen[i].fd = -1;
    148                 }
    149 
    150                 break;
    151             }
    152         }
    153 
    154         for(i = 0; i < n; i++) if(screen[i].total)
     167            }
     168
     169        for(i = 0; i < screen_list->count; i++) if(screen_list->screen[i]->total)
    155170        {
    156171            unsigned long int bytes;
    157172
    158             bytes = import_term(&screen[i], screen[i].buf, screen[i].total);
     173            bytes = import_term(screen_list->screen[i], screen_list->screen[i]->buf, screen_list->screen[i]->total);
    159174
    160175            if(bytes > 0)
    161176            {
    162                 screen[i].total -= bytes;
    163                 memmove(screen[i].buf, screen[i].buf + bytes, screen[i].total);
     177                screen_list->screen[i]->total -= bytes;
     178                memmove(screen_list->screen[i]->buf, screen_list->screen[i]->buf + bytes, screen_list->screen[i]->total);
    164179                refresh = 1;
    165180            }
     
    193208                case 0x0e: //CACA_KEY_CTRL_N:
    194209                    prevpty = pty;
    195                     pty = (pty + 1) % n;
     210                    pty = (pty + 1) % screen_list->count;
    196211                    refresh = 1;
    197212                    break;
     
    199214                case 0x10: //CACA_KEY_CTRL_P:
    200215                    prevpty = pty;
    201                     pty = (pty + n - 1) % n;
     216                    pty = (pty + screen_list->count - 1) % screen_list->count;
    202217                    refresh = 1;
    203218                    break;
     
    211226                    command = 1; break;
    212227                case CACA_KEY_UP:
    213                     write(screen[pty].fd, "\x1b[A", 3); break;
     228                    write(screen_list->screen[pty]->fd, "\x1b[A", 3); break;
    214229                case CACA_KEY_DOWN:
    215                     write(screen[pty].fd, "\x1b[B", 3); break;
     230                    write(screen_list->screen[pty]->fd, "\x1b[B", 3); break;
    216231                case CACA_KEY_RIGHT:
    217                     write(screen[pty].fd, "\x1b[C", 3); break;
     232                    write(screen_list->screen[pty]->fd, "\x1b[C", 3); break;
    218233                case CACA_KEY_LEFT:
    219                     write(screen[pty].fd, "\x1b[D", 3); break;
     234                    write(screen_list->screen[pty]->fd, "\x1b[D", 3); break;
    220235                default:
    221                     write(screen[pty].fd, &c, 1); break;
     236                    write(screen_list->screen[pty]->fd, &c, 1); break;
    222237                }
    223238            }
     
    227242            w = cucul_get_canvas_width(cv);
    228243            h = cucul_get_canvas_height(cv);
    229             w = w <= XTAB * n ? 1 : w - XTAB * (n - 1) - 2;
    230             h = h <= YTAB * n ? 1 : h - YTAB * (n - 1) - 2;
    231             for(i = 0; i < n; i++)
    232             {
    233                 cucul_set_canvas_size(screen[i].cv, w, h);
    234                 if(screen[i].fd >= 0)
    235                     set_tty_size(screen[i].fd, w, h);
     244            w = w <= XTAB * screen_list->count ? 1 : w - XTAB * (screen_list->count - 1) - 2;
     245            h = h <= YTAB * screen_list->count ? 1 : h - YTAB * (screen_list->count - 1) - 2;
     246            for(i = 0; i < screen_list->count; i++)
     247            {
     248                cucul_set_canvas_size(screen_list->screen[i]->cv, w, h);
     249                if(screen_list->screen[i]->fd >= 0)
     250                    set_tty_size(screen_list->screen[i]->fd, w, h);
    236251            }
    237252            cucul_clear_canvas(cv);
     
    248263            refresh = 0;
    249264
     265            cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_DEFAULT);
     266            cucul_clear_canvas(cv);
    250267            cucul_set_color_ansi(cv, CUCUL_LIGHTRED, CUCUL_BLACK);
    251268
    252             for(i = 0; i < n; i++)
    253             {
    254                 if(screen[i].fd < 0)
     269            for(i = 0; i < screen_list->count; i++)
     270            {
     271                int n = screen_list->count;
     272                if(screen_list->screen[i]->fd < 0)
    255273                    continue;
    256274                int j = (pty + n - 1 - i) % n;
    257275                cucul_blit(cv, (n - 1 - j) * XTAB + 1,
    258                                j * YTAB + 1, screen[j].cv, NULL);
     276                           j * YTAB + 1, screen_list->screen[j]->cv, NULL);
    259277                cucul_draw_cp437_box(cv, (n - 1 - j) * XTAB, j * YTAB,
    260278                                     w + (n - 1 - j) * XTAB + 1, h + j * YTAB + 1);
     
    262280                if(i == n - 1)
    263281                    cucul_gotoxy(cv, (n - 1 - j) * XTAB + 1
    264                                         + cucul_get_cursor_x(screen[j].cv),
    265                                      j * YTAB + 1
    266                                         + cucul_get_cursor_y(screen[j].cv));
     282                                 + cucul_get_cursor_x(screen_list->screen[j]->cv),
     283                                 j * YTAB + 1
     284                                 + cucul_get_cursor_y(screen_list->screen[j]->cv));
    267285            }
    268286
     
    275293                int miniw, minih;
    276294
    277                 fonts = cucul_get_font_list();
    278                 f = cucul_load_font(fonts[0], 0);
    279 
    280                 miniw = cucul_get_canvas_width(screen[0].cv)
    281                          * cucul_get_font_width(f);
    282                 minih = cucul_get_canvas_height(screen[0].cv)
    283                          * cucul_get_font_height(f);
    284                 buf = malloc(4 * miniw * minih);
     295                if(screen_list->count)
     296                {
     297                    fonts = cucul_get_font_list();
     298                    f = cucul_load_font(fonts[0], 0);
     299
     300                    miniw = cucul_get_canvas_width(screen_list->screen[0]->cv)
     301                        * cucul_get_font_width(f);
     302                    minih = cucul_get_canvas_height(screen_list->screen[0]->cv)
     303                        * cucul_get_font_height(f);
     304                    buf = malloc(4 * miniw * minih);
    285305
    286306#if defined(HAVE_ENDIAN_H)
    287                 if(__BYTE_ORDER == __BIG_ENDIAN)
     307                    if(__BYTE_ORDER == __BIG_ENDIAN)
    288308#else
    289                 /* This is compile-time optimised with at least -O1 or -Os */
    290                 uint32_t const tmp = 0x12345678;
    291                 if(*(uint8_t const *)&tmp == 0x12)
     309                        /* This is compile-time optimised with at least -O1 or -Os */
     310                        uint32_t const tmp = 0x12345678;
     311                    if(*(uint8_t const *)&tmp == 0x12)
    292312#endif
    293                     d = cucul_create_dither(32, miniw, minih, 4 * miniw,
    294                                             0xff0000, 0xff00, 0xff, 0x0);
    295                 else
    296                     d = cucul_create_dither(32, miniw, minih, 4 * miniw,
    297                                             0xff00, 0xff0000, 0xff000000, 0x0);
    298 
    299                 for(i = 0; i < n; i++)
    300                 {
    301                     cucul_render_canvas(screen[i].cv, f, buf,
    302                                         miniw, minih, miniw * 4);
    303                     cucul_dither_bitmap(cv, 20 * i,
    304                               cucul_get_canvas_height(cv) - 6, 19, 6, d, buf);
    305                     cucul_set_color_ansi(cv, CUCUL_WHITE, CUCUL_BLUE);
    306                     cucul_printf(cv, 20 * i,
    307                                  cucul_get_canvas_height(cv) - 6, "(%i)", i);
     313                        d = cucul_create_dither(32, miniw, minih, 4 * miniw,
     314                                                0xff0000, 0xff00, 0xff, 0x0);
     315                    else
     316                        d = cucul_create_dither(32, miniw, minih, 4 * miniw,
     317                                                0xff00, 0xff0000, 0xff000000, 0x0);
     318
     319                    for(i = 0; i < screen_list->count; i++)
     320                    {
     321                        cucul_render_canvas(screen_list->screen[i]->cv, f, buf,
     322                                            miniw, minih, miniw * 4);
     323                        cucul_dither_bitmap(cv, 20 * i,
     324                                            cucul_get_canvas_height(cv) - 6, 19, 6, d, buf);
     325                        cucul_set_color_ansi(cv, CUCUL_WHITE, CUCUL_BLUE);
     326                        cucul_printf(cv, 20 * i,
     327                                     cucul_get_canvas_height(cv) - 6, "(%i)", i);
     328                    }
     329
     330                    cucul_free_dither(d);
     331                    cucul_free_font(f);
     332
     333                    free(buf);
    308334                }
    309 
    310                 cucul_free_dither(d);
    311                 cucul_free_font(f);
    312 
    313                 free(buf);
    314335            }
    315336
     
    318339
    319340        eof = 1;
    320         for(i = 0; i < n; i++)
    321             if(screen[i].fd >= 0)
     341        for(i = 0; i < screen_list->count; i++)
     342            if(screen_list->screen[i]->fd >= 0)
    322343                eof = 0;
    323344        if(eof)
     
    328349    caca_free_display(dp);
    329350    cucul_free_canvas(cv);
    330     for(i = 0; i < n; i++)
    331     {
    332         free(screen[i].buf);
    333         cucul_free_canvas(screen[i].cv);
    334     }
     351    for(i = 0; i < screen_list->count; i++)
     352    {
     353        destroy_screen(screen_list->screen[i]);
     354    }
     355    free(screen_list->screen);
     356    free(screen_list);
     357
    335358
    336359    return 0;
     
    382405}
    383406
     407
     408
     409
     410struct screen* create_screen(int w, int h, char *command)
     411{
     412    struct screen *s = (struct screen*) malloc(sizeof(struct screen));
     413
     414    s->cv = cucul_create_canvas(w, h);
     415    s->init = 0;
     416
     417    s->buf = NULL;
     418    s->total = 0;
     419    s->fd = create_pty(command, w, h);
     420    if(s->fd < 0)
     421    {
     422        cucul_free_canvas(s->cv);
     423        free(s);
     424        return NULL;
     425    }
     426    return s;
     427}
     428
     429
     430int add_screen(struct screen_list *list, struct screen *s)
     431{
     432    if(list == NULL || s == NULL)
     433    {
     434        return -1;
     435    }
     436    else
     437    {
     438        list->screen = (struct screen**) realloc(list->screen,
     439                                                 sizeof(sizeof(struct screen*))
     440                                                 * (list->count+1));
     441        list->screen[list->count] = s;
     442        list->count++;
     443    }
     444
     445    return list->count-1;
     446}
     447
     448
     449int remove_screen(struct screen_list *list, int n)
     450{
     451    if(n>list->count) return -1;
     452
     453    memmove(&list->screen[n],
     454            &list->screen[n+1],
     455            sizeof(struct screen*)*(list->count-(n+1)));
     456
     457    list->screen = (struct screen**) realloc(list->screen,
     458                                             sizeof(sizeof(struct screen*))
     459                                             * (list->count));
     460
     461    list->count--;
     462    return 1;
     463}
     464
     465int destroy_screen(struct screen *s)
     466{
     467    free(s->buf);
     468    cucul_free_canvas(s->cv);
     469    free(s);
     470    return 1;
     471}
  • neercs/trunk/src/neercs.h

    r1459 r2357  
    22 *  neercs        console-based window manager
    33 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
     4 *                2008 Jean-Yves Lamoureux <jylam@lnxscene.org>
    45 *                All Rights Reserved
    56 *
     
    1516#include <stdint.h>
    1617#include <cucul.h>
     18
     19
    1720
    1821struct screen
     
    3437};
    3538
     39struct screen_list
     40{
     41  int count;
     42  struct screen **screen;
     43};
     44
     45
     46
    3647long int import_term(struct screen *sc, void const *data, unsigned int size);
     48
     49/* Screens management */
     50struct screen* create_screen(int w, int h, char *command);
     51int destroy_screen(struct screen *s);
     52int add_screen(struct screen_list *list, struct screen *s);
     53int remove_screen(struct screen_list *list, int n);
     54
     55
    3756
    3857#if 0
Note: See TracChangeset for help on using the changeset viewer.