source: neercs/trunk/src/main.c @ 2421

Last change on this file since 2421 was 2421, checked in by Jean-Yves Lamoureux, 14 years ago
  • Put pty and prevpty in screen_list structure
  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1/*
2 *  neercs        console-based window manager
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                2008 Jean-Yves Lamoureux <jylam@lnxscene.org>
5 *                All Rights Reserved
6 *
7 *  $Id: main.c 2421 2008-06-15 15:13:41Z jylam $
8 *
9 *  This program is free software. It comes without any warranty, to
10 *  the extent permitted by applicable law. You can redistribute it
11 *  and/or modify it under the terms of the Do What The Fuck You Want
12 *  To Public License, Version 2, as published by Sam Hocevar. See
13 *  http://sam.zoy.org/wtfpl/COPYING for more details.
14 */
15
16#include "config.h"
17
18#include <stdio.h>
19#include <string.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <fcntl.h>
23#include <signal.h>
24#include <sys/ioctl.h>
25#include <sys/types.h>
26#include <sys/wait.h>
27
28#if defined HAVE_PTY_H
29#   include <pty.h>  /* for openpty and forkpty */
30#else
31#   include <util.h> /* for OS X */
32#endif
33#include <errno.h>
34#include <cucul.h>
35#include <caca.h>
36
37#include "neercs.h"
38
39int main(int argc, char **argv)
40{
41    static cucul_canvas_t *cv;
42    static caca_display_t *dp;
43    struct screen_list *screen_list = NULL;
44    char *default_shell = NULL;
45    int i, w, h, nt, args = 0;
46    int eof = 0, refresh = 1, command = 0;
47
48
49    nt = argc - 1;
50    args = nt;
51
52    if(nt == 0)
53    {
54        nt = 1;
55    }
56
57    default_shell = getenv("SHELL");
58
59    if(default_shell == NULL  && !args)
60    {
61        fprintf(stderr, "Environment variable SHELL not set and no arguments given. kthxbye.\n");
62        return -1;
63    }
64
65    /* Create main canvas and associated caca window */
66    cv = cucul_create_canvas(0, 0);
67    dp = caca_create_display(cv);
68    if(!dp)
69        return 1;
70    caca_set_cursor(dp, 1);
71
72
73    w = cucul_get_canvas_width(cv);
74    h = cucul_get_canvas_height(cv);
75
76
77
78    /* Create screen list */
79    screen_list = (struct screen_list*)     malloc(sizeof(struct screen_list));
80    if(!screen_list)
81    {
82        fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__, __LINE__);
83        return -1;
84    }
85    screen_list->screen = (struct screen**) malloc(sizeof(sizeof(struct screen*)));
86    if(!screen_list->screen)
87    {
88        fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__, __LINE__);
89        return -1;
90    }
91    screen_list->count = 0;
92    screen_list->width  = cucul_get_canvas_width(cv);
93    screen_list->mini = 1;
94    screen_list->help = 0;
95    screen_list->status = 1;
96    screen_list->height = cucul_get_canvas_height(cv) - ((screen_list->mini*6) + (screen_list->status));
97    screen_list->wm_type = WM_VSPLIT;
98    screen_list->in_bell = 0;
99    screen_list->pty = screen_list->prevpty = 0;
100
101
102    for(i = 0; i < nt; i++)
103    {
104        struct screen *tmp;
105        if(args) tmp = create_screen(w, h, argv[i + 1]);
106        else     tmp = create_screen(w, h, default_shell);
107
108        if(tmp)
109        {
110            if(add_screen(screen_list, tmp) < 0)
111            {
112                fprintf(stderr, "Can't add %p to %p\n", tmp, screen_list);
113            }
114        }
115        else
116        {
117            fprintf(stderr, "Can't create screen\n");
118        }
119    }
120
121    /* Windows are in a temporary state, resize them to the right dimensions */
122    update_windows_props(cv, screen_list);
123    caca_refresh_display(dp);
124
125
126    for(;;)
127    {
128        caca_event_t ev;
129        int ret;
130
131        refresh |= update_screens_contents(screen_list);
132
133        /* No more screens, exit */
134        if(!screen_list->count) break;
135
136        /* Update each screen canvas  */
137        refresh |= update_terms(screen_list);
138
139        /* Get events, if any */
140        ret = caca_get_event(dp, CACA_EVENT_ANY, &ev, 0);
141        if(ret && (caca_get_event_type(&ev) & CACA_EVENT_KEY_PRESS))
142        {
143            unsigned int c = caca_get_event_key_ch(&ev);
144
145            if(command)
146            {
147                command = 0;
148
149                switch(c)
150                {
151                case 0x01: //CACA_KEY_CTRL_A:
152                    screen_list->pty ^= screen_list->prevpty;
153                    screen_list->prevpty ^= screen_list->pty;
154                    screen_list->pty ^= screen_list->prevpty;
155                    refresh = 1;
156                    break;
157                case 'm':
158                case 0x0d: //CACA_KEY_CTRL_M:
159                    screen_list->mini = !screen_list->mini;
160                    refresh = 1;
161                    break;
162                case 'n':
163                case ' ':
164                case '\0':
165                case 0x0e: //CACA_KEY_CTRL_N:
166                    screen_list->prevpty = screen_list->pty;
167                    screen_list->pty = (screen_list->pty + 1) % screen_list->count;
168                    refresh = 1;
169                    break;
170                case 'p':
171                case 0x10: //CACA_KEY_CTRL_P:
172                    screen_list->prevpty = screen_list->pty;
173                    screen_list->pty = (screen_list->pty + screen_list->count - 1) % screen_list->count;
174                    refresh = 1;
175                    break;
176                case 'c':
177                case 0x03: //CACA_KEY_CTRL_C:
178                    screen_list->prevpty = screen_list->pty;
179                    screen_list->pty =
180                        add_screen(screen_list, create_screen(w, h, default_shell));
181                    refresh = 1;
182                    break;
183                case 'w':
184                case 0x17: //CACA_KEY_CTRL_W:
185                    screen_list->wm_type = (screen_list->wm_type==(WM_MAX-1)?
186                                            screen_list->wm_type=0:
187                                            screen_list->wm_type+1);
188                    refresh = 1;
189                    break;
190                case 0x0b: //CACA_KEY_CTRL_K:
191                    remove_screen(screen_list, screen_list->pty, 1);
192                    screen_list->pty = screen_list->prevpty;
193                    screen_list->prevpty = 0;
194                    refresh = 1;
195                    break;
196                case 'h':
197                case 0x08: //CACA_KEY_CTRL_H:
198                    screen_list->help = !screen_list->help;
199                    refresh = 1;
200                    break;
201                }
202            }
203            else
204            {
205                switch(c)
206                {
207                case 0x01: //CACA_KEY_CTRL_A:
208                    command = 1; break;
209                case CACA_KEY_UP:
210                    write(screen_list->screen[screen_list->pty]->fd, "\x1b[A", 3); break;
211                case CACA_KEY_DOWN:
212                    write(screen_list->screen[screen_list->pty]->fd, "\x1b[B", 3); break;
213                case CACA_KEY_RIGHT:
214                    write(screen_list->screen[screen_list->pty]->fd, "\x1b[C", 3); break;
215                case CACA_KEY_LEFT:
216                    write(screen_list->screen[screen_list->pty]->fd, "\x1b[D", 3); break;
217                case CACA_KEY_ESCAPE:
218                    if(screen_list->help) screen_list->help = 0;
219                default:
220                    write(screen_list->screen[screen_list->pty]->fd, &c, 1); break;
221                }
222            }
223        }
224        else if(ret && (caca_get_event_type(&ev) & CACA_EVENT_RESIZE))
225        {
226            update_windows_props(cv, screen_list);
227            cucul_clear_canvas(cv);
228            refresh = 1;
229        }
230        else if(ret && (caca_get_event_type(&ev) & CACA_EVENT_QUIT))
231        {
232            break;
233        }
234
235        /* Resfresh screen */
236        if(refresh || screen_list->in_bell)
237        {
238            refresh = 0;
239            refresh_screens(cv, dp, screen_list);
240        }
241
242        eof = 1;
243        for(i = 0; i < screen_list->count; i++)
244            if(screen_list->screen[i]->fd >= 0)
245                eof = 0;
246        if(eof)
247            break;
248    }
249
250    /* Clean up */
251    caca_free_display(dp);
252    cucul_free_canvas(cv);
253    for(i = 0; i < screen_list->count; i++)
254    {
255        destroy_screen(screen_list->screen[i]);
256    }
257    free(screen_list->screen);
258    free(screen_list);
259
260
261    return 0;
262}
Note: See TracBrowser for help on using the repository browser.