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

Last change on this file since 2433 was 2433, checked in by pterjan, 6 years ago
  • Fix behavior with no parameter
  • Property svn:keywords set to Id
File size: 8.3 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$
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, args;
46    int eof = 0, refresh = 1, command = 0;
47
48    default_shell = getenv("SHELL");
49
50    args = argc -1;
51    if(default_shell == NULL  && args <= 0)
52    {
53        fprintf(stderr, "Environment variable SHELL not set and no arguments given. kthxbye.\n");
54        return -1;
55    }
56
57    if(args==0)
58        args = 1;
59
60    /* Create main canvas and associated caca window */
61    cv = cucul_create_canvas(0, 0);
62    dp = caca_create_display(cv);
63    if(!dp)
64        return 1;
65    caca_set_cursor(dp, 1);
66
67
68    w = cucul_get_canvas_width(cv);
69    h = cucul_get_canvas_height(cv);
70
71
72
73    /* Create screen list */
74    screen_list = (struct screen_list*)     malloc(sizeof(struct screen_list));
75    if(!screen_list)
76    {
77        fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__, __LINE__);
78        return -1;
79    }
80    screen_list->screen = (struct screen**) malloc(sizeof(sizeof(struct screen*)));
81    if(!screen_list->screen)
82    {
83        fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__, __LINE__);
84        return -1;
85    }
86    screen_list->count = 0;
87    screen_list->width  = cucul_get_canvas_width(cv);
88    screen_list->mini = 1;
89    screen_list->help = 0;
90    screen_list->status = 1;
91    screen_list->height = cucul_get_canvas_height(cv) - ((screen_list->mini*6) + (screen_list->status));
92    screen_list->wm_type = WM_VSPLIT;
93    screen_list->in_bell = 0;
94    screen_list->pty = screen_list->prevpty = 0;
95
96    for(i = 0; i < args; i++)
97    {
98        struct screen *tmp;
99        if(argc < 2)
100            tmp = create_screen(w, h, default_shell);
101        else
102        {
103            if(!strcmp(argv[i + 1], "-P"))
104            {
105#ifdef USE_GRAB
106                if(i + 2 > argc)
107                {
108                    fprintf(stderr, "-P needs a parameter !\n");
109                    exit(1);
110                }
111                tmp = create_screen_grab(w, h, atoi(argv[i + 2]));
112                i++;
113#else
114                fprintf(stderr, "Grabbing process is not supported, sorry\n");
115                exit(1);
116#endif
117            }
118            else
119                tmp = create_screen(w, h, argv[i + 1]);
120        }
121
122        if(tmp)
123        {
124            if(add_screen(screen_list, tmp) < 0)
125            {
126                fprintf(stderr, "Can't add %p to %p\n", tmp, screen_list);
127            }
128        }
129        else
130        {
131            fprintf(stderr, "Can't create screen\n");
132        }
133    }
134
135    /* Windows are in a temporary state, resize them to the right dimensions */
136    update_windows_props(cv, screen_list);
137    caca_refresh_display(dp);
138
139
140    for(;;)
141    {
142        caca_event_t ev;
143        int ret;
144
145        refresh |= update_screens_contents(screen_list);
146
147        /* No more screens, exit */
148        if(!screen_list->count) break;
149
150        /* Update each screen canvas  */
151        refresh |= update_terms(screen_list);
152
153        /* Get events, if any */
154        ret = caca_get_event(dp, CACA_EVENT_ANY, &ev, 0);
155        if(ret && (caca_get_event_type(&ev) & CACA_EVENT_KEY_PRESS))
156        {
157            unsigned int c = caca_get_event_key_ch(&ev);
158
159            if(command)
160            {
161                command = 0;
162
163                switch(c)
164                {
165                case 0x01: //CACA_KEY_CTRL_A:
166                    screen_list->pty ^= screen_list->prevpty;
167                    screen_list->prevpty ^= screen_list->pty;
168                    screen_list->pty ^= screen_list->prevpty;
169                    refresh = 1;
170                    break;
171                case 'm':
172                case 0x0d: //CACA_KEY_CTRL_M:
173                    screen_list->mini = !screen_list->mini;
174                    refresh = 1;
175                    break;
176                case 'n':
177                case ' ':
178                case '\0':
179                case 0x0e: //CACA_KEY_CTRL_N:
180                    screen_list->prevpty = screen_list->pty;
181                    screen_list->pty = (screen_list->pty + 1) % screen_list->count;
182                    refresh = 1;
183                    break;
184                case 'p':
185                case 0x10: //CACA_KEY_CTRL_P:
186                    screen_list->prevpty = screen_list->pty;
187                    screen_list->pty = (screen_list->pty + screen_list->count - 1) % screen_list->count;
188                    refresh = 1;
189                    break;
190                case 'c':
191                case 0x03: //CACA_KEY_CTRL_C:
192                    screen_list->prevpty = screen_list->pty;
193                    screen_list->pty =
194                        add_screen(screen_list, create_screen(w, h, default_shell));
195                    refresh = 1;
196                    break;
197                case 'w':
198                case 0x17: //CACA_KEY_CTRL_W:
199                    screen_list->wm_type = (screen_list->wm_type==(WM_MAX-1)?
200                                            screen_list->wm_type=0:
201                                            screen_list->wm_type+1);
202                    refresh = 1;
203                    break;
204                case 0x0b: //CACA_KEY_CTRL_K:
205                    remove_screen(screen_list, screen_list->pty, 1);
206                    screen_list->pty = screen_list->prevpty;
207                    screen_list->prevpty = 0;
208                    refresh = 1;
209                    break;
210                case 'h':
211                case 0x08: //CACA_KEY_CTRL_H:
212                    screen_list->help = !screen_list->help;
213                    refresh = 1;
214                    break;
215                }
216            }
217            else
218            {
219                switch(c)
220                {
221                case 0x01: //CACA_KEY_CTRL_A:
222                    command = 1; break;
223                case CACA_KEY_UP:
224                    write(screen_list->screen[screen_list->pty]->fd, "\x1b[A", 3); break;
225                case CACA_KEY_DOWN:
226                    write(screen_list->screen[screen_list->pty]->fd, "\x1b[B", 3); break;
227                case CACA_KEY_RIGHT:
228                    write(screen_list->screen[screen_list->pty]->fd, "\x1b[C", 3); break;
229                case CACA_KEY_LEFT:
230                    write(screen_list->screen[screen_list->pty]->fd, "\x1b[D", 3); break;
231                case CACA_KEY_ESCAPE:
232                    if(screen_list->help) screen_list->help = 0;
233                default:
234                    write(screen_list->screen[screen_list->pty]->fd, &c, 1); break;
235                }
236            }
237        }
238        else if(ret && (caca_get_event_type(&ev) & CACA_EVENT_RESIZE))
239        {
240            update_windows_props(cv, screen_list);
241            cucul_clear_canvas(cv);
242            refresh = 1;
243        }
244        else if(ret && (caca_get_event_type(&ev) & CACA_EVENT_QUIT))
245        {
246            break;
247        }
248
249        /* Resfresh screen */
250        if(refresh || screen_list->in_bell)
251        {
252            refresh = 0;
253            refresh_screens(cv, dp, screen_list);
254        }
255
256        eof = 1;
257        for(i = 0; i < screen_list->count; i++)
258            if(screen_list->screen[i]->fd >= 0)
259                eof = 0;
260        if(eof)
261            break;
262    }
263
264    /* Clean up */
265    caca_free_display(dp);
266    cucul_free_canvas(cv);
267    for(i = 0; i < screen_list->count; i++)
268    {
269        destroy_screen(screen_list->screen[i]);
270    }
271    free(screen_list->screen);
272    free(screen_list);
273
274
275    return 0;
276}
Note: See TracBrowser for help on using the repository browser.