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

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