source: neercs/trunk/src/wm.c @ 3921

Last change on this file since 3921 was 3921, checked in by Pascal Terjan, 13 years ago
  • Remove unused variable
  • Property svn:keywords set to Id
File size: 23.9 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: wm.c 3921 2009-11-17 20:54:00Z pterjan $
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 <stdio.h>
17#include <caca.h>
18#include <caca.h>
19#include <stdlib.h>
20#include <math.h>
21
22#include "neercs.h"
23
24
25void resize_screen(struct screen *s, int w, int h)
26{
27    caca_canvas_t *old, *new;
28
29    if(w==s->w && h==s->h) return;
30    if(w <= 0 || h <= 0) return;
31
32    s->changed = 1;
33
34    s->w = w;
35    s->h = h;
36
37    /* caca_set_canvas_boundaries() is bugged as hell,
38     * so let's resize it by hands */
39    old = s->cv;
40    new = caca_create_canvas(w, h);
41    caca_blit(new, 0, 0, old, NULL);
42    s->cv = new;
43    caca_gotoxy(new, caca_get_cursor_x(old), caca_get_cursor_y(old));
44    caca_free_canvas(old);
45    set_tty_size(s->fd, w, h);
46
47    s->orig_w = s->w;
48    s->orig_h = s->h;
49    s->orig_x = s->x;
50    s->orig_y = s->y;
51}
52
53void update_windows_props(struct screen_list *screen_list)
54{
55    debug("%s, %d screens, type %d\n", __FUNCTION__, screen_list->count, screen_list->wm_type);
56   
57    if(!screen_list->count) return;
58
59    switch(screen_list->wm_type)
60    {
61    case WM_CARD:
62        update_windows_props_cards(screen_list);
63        break;
64    case WM_HSPLIT:
65        update_windows_props_hsplit(screen_list);
66        break;
67    case WM_VSPLIT:
68        update_windows_props_vsplit(screen_list);
69        break;
70    case WM_CUBE:
71        update_windows_props_cube(screen_list);
72        break;
73    case WM_FULL:
74    default:
75        update_windows_props_full(screen_list);
76        break;
77    }
78}
79
80void update_windows_props_hsplit(struct screen_list *screen_list)
81{
82    int i;
83    int w = (screen_list->width / screen_list->count) - 1;
84    int h = screen_list->height - 2;
85
86    for(i = 0; i < screen_list->count; i++)
87    {
88        screen_list->screen[i]->x = (i*w)+1;
89        screen_list->screen[i]->y = 1;
90        screen_list->screen[i]->visible = 1;
91        if(i != screen_list->count -1)
92        {
93            resize_screen(screen_list->screen[i],
94                          w - 1, h);
95        } else {
96            resize_screen(screen_list->screen[i],
97                          screen_list->width - i*w - 2,
98                          h);
99        }
100    }
101}
102
103void update_windows_props_vsplit(struct screen_list *screen_list)
104{
105    int i;
106    int w = screen_list->width - 2;
107    int h = (screen_list->height) / screen_list->count;
108
109    for(i = 0; i < screen_list->count; i++)
110    {
111        screen_list->screen[i]->x = 1;
112        screen_list->screen[i]->y = (i*h) + 1;
113        screen_list->screen[i]->visible = 1;
114        if(i != screen_list->count -1)
115        {
116            resize_screen(screen_list->screen[i],
117                          w, h - 2);
118        } else {
119            resize_screen(screen_list->screen[i],
120                          w,
121                          screen_list->height - i*h - 2);
122        }
123    }
124}
125
126
127void update_windows_props_full(struct screen_list *screen_list)
128{
129    int i;
130    int w = screen_list->width - 2;
131    int h = screen_list->height - 2;
132
133    for(i = 0; i < screen_list->count; i++)
134    {
135        screen_list->screen[i]->visible = 0;
136        screen_list->screen[i]->x = 1;
137        screen_list->screen[i]->y = 1;
138
139        resize_screen(screen_list->screen[i],
140                      w, h);
141    }
142    screen_list->screen[screen_list->pty]->visible = 1;
143}
144
145
146void update_windows_props_cards(struct screen_list *screen_list)
147{
148    int i;
149    int w = (screen_list->width  - screen_list->count*3) + 1;
150    int h = (screen_list->height - screen_list->count) - 1;
151    int x = 1;
152    int y = screen_list->count;
153
154    for(i = 0; i < screen_list->count; i++)
155    {
156        screen_list->screen[i]->visible = 1;
157        screen_list->screen[i]->x = x;
158        screen_list->screen[i]->y = y;
159
160        resize_screen(screen_list->screen[i],
161                      w, h);
162        x += 3;
163        y--;
164    }
165}
166
167void update_windows_props_cube(struct screen_list *screen_list)
168{
169    int i;
170    int w = screen_list->width - 2;
171    int h = screen_list->height - 2;
172   
173    for(i = 0; i < screen_list->count; i++)
174    {
175        screen_list->screen[i]->visible = 0;
176        screen_list->screen[i]->x = 1;
177        screen_list->screen[i]->y = 1;
178       
179        resize_screen(screen_list->screen[i],
180                      w, h);
181    }
182    screen_list->screen[screen_list->pty]->visible = 1;
183}
184
185/* Window managers refresh */
186
187void wm_refresh(struct screen_list *screen_list)
188{
189    switch (screen_list->wm_type) {
190        case WM_CARD:
191            wm_refresh_card(screen_list);
192            break;
193        case WM_FULL:
194            wm_refresh_full(screen_list);
195            break;
196        case WM_HSPLIT:
197            wm_refresh_hsplit(screen_list);
198            break;
199        case WM_VSPLIT:
200            wm_refresh_hsplit(screen_list);
201            break;
202        case WM_CUBE:
203            wm_refresh_cube(screen_list);
204            break;
205        default:
206            wm_refresh_full(screen_list);
207            break;
208    }
209}
210
211void wm_refresh_card(struct screen_list *screen_list)
212{
213    int i;
214   
215    for(i = screen_list->count - 1; i >=0; i--)
216    {
217        if(i!=screen_list->pty && screen_list->screen[i]->visible &&
218           (screen_list->screen[i]->changed || screen_list->changed))
219        {
220            caca_blit(screen_list->cv,
221                      screen_list->screen[i]->x,
222                      screen_list->screen[i]->y,
223                      screen_list->screen[i]->cv, NULL);
224           
225            caca_draw_cp437_box(screen_list->cv,
226                                screen_list->screen[i]->x - 1,
227                                screen_list->screen[i]->y - 1,
228                                screen_list->screen[i]->w + 2,
229                                screen_list->screen[i]->h + 2);
230            if(screen_list->screen[i]->title)
231                caca_printf(screen_list->cv,
232                            screen_list->screen[i]->x,
233                            screen_list->screen[i]->y - 1,
234                            " %.*s ",
235                            screen_list->screen[i]->w - 3,
236                            screen_list->screen[i]->title);
237        }
238    }
239   
240    if(screen_list->screen[screen_list->pty]->changed || screen_list->changed)
241        caca_blit(screen_list->cv,
242                  screen_list->screen[screen_list->pty]->x,
243                  screen_list->screen[screen_list->pty]->y,
244                  screen_list->screen[screen_list->pty]->cv, NULL);
245   
246    if(screen_list->screen[screen_list->pty]->bell)
247    {
248        caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
249        screen_list->screen[screen_list->pty]->bell = 0;
250        screen_list->in_bell--;
251    }
252    else
253    {
254        caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
255    }
256   
257    caca_draw_cp437_box(screen_list->cv,
258                        screen_list->screen[screen_list->pty]->x - 1,
259                        screen_list->screen[screen_list->pty]->y - 1,
260                        screen_list->screen[screen_list->pty]->w + 2,
261                        screen_list->screen[screen_list->pty]->h + 2);
262   
263    if(screen_list->screen[screen_list->pty]->title)
264    {
265        caca_printf(screen_list->cv,
266                    screen_list->screen[screen_list->pty]->x,
267                    screen_list->screen[screen_list->pty]->y - 1,
268                    " %.*s ",
269                    screen_list->screen[screen_list->pty]->w - 3,
270                    screen_list->screen[screen_list->pty]->title);
271    }
272   
273   
274}
275
276
277void wm_refresh_full(struct screen_list *screen_list)
278{
279    if(screen_list->screen[screen_list->pty]->changed || screen_list->changed)
280        caca_blit(screen_list->cv,
281                  screen_list->screen[screen_list->pty]->x,
282                  screen_list->screen[screen_list->pty]->y,
283                  screen_list->screen[screen_list->pty]->cv, NULL);
284   
285    if(screen_list->screen[screen_list->pty]->bell)
286    {
287        caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
288        screen_list->screen[screen_list->pty]->bell = 0;
289        screen_list->in_bell--;
290    }
291    else
292    {
293        caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
294    }
295   
296    caca_draw_cp437_box(screen_list->cv,
297                        screen_list->screen[screen_list->pty]->x - 1,
298                        screen_list->screen[screen_list->pty]->y - 1,
299                        screen_list->screen[screen_list->pty]->w + 2,
300                        screen_list->screen[screen_list->pty]->h + 2);
301   
302    if(screen_list->screen[screen_list->pty]->title)
303    {
304        caca_printf(screen_list->cv,
305                    screen_list->screen[screen_list->pty]->x,
306                    screen_list->screen[screen_list->pty]->y - 1,
307                    " %.*s ",
308                    screen_list->screen[screen_list->pty]->w - 3,
309                    screen_list->screen[screen_list->pty]->title);
310    }
311   
312   
313}
314
315void wm_refresh_vsplit(struct screen_list *screen_list)
316{
317    int i;
318   
319    for(i = screen_list->count - 1; i >=0; i--)
320    {
321        if(i!=screen_list->pty && screen_list->screen[i]->visible &&
322           (screen_list->screen[i]->changed || screen_list->changed))
323        {
324            caca_blit(screen_list->cv,
325                      screen_list->screen[i]->x,
326                      screen_list->screen[i]->y,
327                      screen_list->screen[i]->cv, NULL);
328           
329            caca_draw_cp437_box(screen_list->cv,
330                                screen_list->screen[i]->x - 1,
331                                screen_list->screen[i]->y - 1,
332                                screen_list->screen[i]->w + 2,
333                                screen_list->screen[i]->h + 2);
334            if(screen_list->screen[i]->title)
335                caca_printf(screen_list->cv,
336                            screen_list->screen[i]->x,
337                            screen_list->screen[i]->y - 1,
338                            " %.*s ",
339                            screen_list->screen[i]->w - 3,
340                            screen_list->screen[i]->title);
341        }
342    }
343   
344    if(screen_list->screen[screen_list->pty]->changed || screen_list->changed)
345        caca_blit(screen_list->cv,
346                  screen_list->screen[screen_list->pty]->x,
347                  screen_list->screen[screen_list->pty]->y,
348                  screen_list->screen[screen_list->pty]->cv, NULL);
349   
350    if(screen_list->screen[screen_list->pty]->bell)
351    {
352        caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
353        screen_list->screen[screen_list->pty]->bell = 0;
354        screen_list->in_bell--;
355    }
356    else
357    {
358        caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
359    }
360   
361    caca_draw_cp437_box(screen_list->cv,
362                        screen_list->screen[screen_list->pty]->x - 1,
363                        screen_list->screen[screen_list->pty]->y - 1,
364                        screen_list->screen[screen_list->pty]->w + 2,
365                        screen_list->screen[screen_list->pty]->h + 2);
366   
367    if(screen_list->screen[screen_list->pty]->title)
368    {
369        caca_printf(screen_list->cv,
370                    screen_list->screen[screen_list->pty]->x,
371                    screen_list->screen[screen_list->pty]->y - 1,
372                    " %.*s ",
373                    screen_list->screen[screen_list->pty]->w - 3,
374                    screen_list->screen[screen_list->pty]->title);
375    }
376   
377   
378}
379
380void wm_refresh_hsplit(struct screen_list *screen_list)
381{
382    int i;
383   
384    for(i = screen_list->count - 1; i >=0; i--)
385    {
386        if(i!=screen_list->pty && screen_list->screen[i]->visible &&
387           (screen_list->screen[i]->changed || screen_list->changed))
388        {
389            caca_blit(screen_list->cv,
390                      screen_list->screen[i]->x,
391                      screen_list->screen[i]->y,
392                      screen_list->screen[i]->cv, NULL);
393           
394            caca_draw_cp437_box(screen_list->cv,
395                                screen_list->screen[i]->x - 1,
396                                screen_list->screen[i]->y - 1,
397                                screen_list->screen[i]->w + 2,
398                                screen_list->screen[i]->h + 2);
399            if(screen_list->screen[i]->title)
400                caca_printf(screen_list->cv,
401                            screen_list->screen[i]->x,
402                            screen_list->screen[i]->y - 1,
403                            " %.*s ",
404                            screen_list->screen[i]->w - 3,
405                            screen_list->screen[i]->title);
406        }
407    }
408   
409    if(screen_list->screen[screen_list->pty]->changed || screen_list->changed)
410        caca_blit(screen_list->cv,
411                  screen_list->screen[screen_list->pty]->x,
412                  screen_list->screen[screen_list->pty]->y,
413                  screen_list->screen[screen_list->pty]->cv, NULL);
414   
415    if(screen_list->screen[screen_list->pty]->bell)
416    {
417        caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
418        screen_list->screen[screen_list->pty]->bell = 0;
419        screen_list->in_bell--;
420    }
421    else
422    {
423        caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
424    }
425   
426    caca_draw_cp437_box(screen_list->cv,
427                        screen_list->screen[screen_list->pty]->x - 1,
428                        screen_list->screen[screen_list->pty]->y - 1,
429                        screen_list->screen[screen_list->pty]->w + 2,
430                        screen_list->screen[screen_list->pty]->h + 2);
431   
432    if(screen_list->screen[screen_list->pty]->title)
433    {
434        caca_printf(screen_list->cv,
435                    screen_list->screen[screen_list->pty]->x,
436                    screen_list->screen[screen_list->pty]->y - 1,
437                    " %.*s ",
438                    screen_list->screen[screen_list->pty]->w - 3,
439                    screen_list->screen[screen_list->pty]->title);
440    }
441   
442   
443}
444
445#if defined HAVE_CACA_TRIANGLE_TEXTURING
446static float get_direction(float p1x, float p1y, float p2x, float p2y, float p3x, float p3y)
447{
448    float d1x, d1y, d2x, d2y;
449   
450        d1x = p3x - p1x;
451        d1y = p3y - p1y;
452        d2x = p3x - p2x;
453        d2y = p3y - p2y;
454    return (d1x * d2y) - (d1y * d2x);
455}
456#endif
457
458/* 3D Cube. Yeah I know, it's a mess. Just look anywhere else. */
459void wm_refresh_cube(struct screen_list *screen_list)
460{
461    int i;
462       
463    if(!screen_list->cube.in_switch) {
464        wm_refresh_full(screen_list);
465        screen_list->force_refresh = 0;
466    } else {
467       
468#define CUBE_TIME 1000000
469
470       
471       
472        long long unsigned int cur_time = get_us() - screen_list->last_switch;
473       
474        if(cur_time >= CUBE_TIME || screen_list->count==1) {
475            screen_list->changed = 1 ;     
476            screen_list->force_refresh = 1;
477            screen_list->cube.in_switch = 0;
478        } else {
479           
480            float cube[12][3] = {
481                {-1, -1,  1}, 
482                {1,  -1,  1}, 
483                {1,   1,  1},
484                {-1,  1,  1},
485               
486                {1,  -1,  1},
487                {1,  -1,  -1},
488                {1,   1,  -1},
489                {1,   1,  1},
490               
491                {-1,  -1,  1},
492                {-1,  -1,  -1},
493                {-1,   1,  -1},
494                {-1,   1,  1},
495            };
496            float cube_transformed[12][3];
497            float cube_projected[12][2];
498            float fov = 0.5f;
499            float angle = 90.0f * ((float)cur_time / (float)CUBE_TIME);
500            angle*= (M_PI/180.0f);
501           
502            if(screen_list->cube.side==1)
503                angle = -angle;
504           
505           
506            for(i = 0; i < 12; i++) {
507           
508                cube_transformed[i][2] = cube[i][2]*cos(angle) - cube[i][0]*sin(angle);
509                cube_transformed[i][0] = cube[i][2]*sin(angle) + cube[i][0]*cos(angle);
510                cube_transformed[i][1] = cube[i][1];
511               
512                cube_transformed[i][2] -= 3;
513               
514                cube_projected[i][0] = cube_transformed[i][0] / (cube_transformed[i][2] * fov);   
515                cube_projected[i][1] = cube_transformed[i][1] / (cube_transformed[i][2] * fov); 
516               
517                cube_projected[i][0] /=2.0f; cube_projected[i][1] /=2.0f;
518                cube_projected[i][0] +=0.5f; cube_projected[i][1] +=0.5f;
519               
520                cube_projected[i][0] *= screen_list->width;
521                cube_projected[i][1] *= screen_list->height;
522               
523
524            }
525            caca_clear_canvas(screen_list->cv);
526           
527#if defined HAVE_CACA_TRIANGLE_TEXTURING
528            caca_canvas_t *first =  screen_list->screen[screen_list->prevpty]->cv;
529            caca_canvas_t *second = screen_list->screen[screen_list->pty]->cv;
530
531            if(get_direction(cube_projected[0][0], cube_projected[0][1],
532                             cube_projected[1][0], cube_projected[1][1],
533                             cube_projected[2][0], cube_projected[2][1]) >=0) {
534                caca_fill_triangle_textured(screen_list->cv,
535                                            cube_projected[0][0], cube_projected[0][1],
536                                            cube_projected[1][0], cube_projected[1][1],
537                                            cube_projected[2][0], cube_projected[2][1],
538                                            1, 1,
539                                            0, 1,
540                                            0, 0,
541                                            first);
542                caca_fill_triangle_textured(screen_list->cv,
543                                            cube_projected[0][0], cube_projected[0][1],
544                                            cube_projected[2][0], cube_projected[2][1],
545                                            cube_projected[3][0], cube_projected[3][1],
546                                            1, 1,
547                                            0, 0,
548                                            1, 0,
549                                            first);
550               
551               
552                caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
553                caca_draw_thin_line(screen_list->cv,
554                                    cube_projected[0][0], cube_projected[0][1],
555                                    cube_projected[1][0], cube_projected[1][1]);
556                caca_draw_thin_line(screen_list->cv,
557                                    cube_projected[1][0], cube_projected[1][1],
558                                    cube_projected[2][0], cube_projected[2][1]);
559                caca_draw_thin_line(screen_list->cv,
560                                    cube_projected[2][0], cube_projected[2][1],
561                                    cube_projected[3][0], cube_projected[3][1]);
562                caca_draw_thin_line(screen_list->cv,
563                                    cube_projected[3][0], cube_projected[3][1],
564                                    cube_projected[0][0], cube_projected[0][1]);
565            }
566           
567           
568           
569            if(screen_list->cube.side)
570            {
571                if(get_direction(cube_projected[4][0], cube_projected[4][1],
572                                 cube_projected[5][0], cube_projected[5][1],
573                                 cube_projected[6][0], cube_projected[6][1]) >=0) {
574                caca_fill_triangle_textured(screen_list->cv,
575                                            cube_projected[4][0], cube_projected[4][1],
576                                            cube_projected[5][0], cube_projected[5][1],
577                                            cube_projected[6][0], cube_projected[6][1],
578                                            1, 1,
579                                            0, 1,
580                                            0, 0,
581                                            second);
582                caca_fill_triangle_textured(screen_list->cv,
583                                            cube_projected[4][0], cube_projected[4][1],
584                                            cube_projected[6][0], cube_projected[6][1],
585                                            cube_projected[7][0], cube_projected[7][1],
586                                            1, 1,
587                                            0, 0,
588                                            1, 0,
589                                            second);
590                caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
591
592                caca_draw_thin_line(screen_list->cv,
593                                    cube_projected[4][0], cube_projected[4][1],
594                                    cube_projected[5][0], cube_projected[5][1]);
595                caca_draw_thin_line(screen_list->cv,
596                                    cube_projected[5][0], cube_projected[5][1],
597                                    cube_projected[6][0], cube_projected[6][1]);
598                caca_draw_thin_line(screen_list->cv,
599                                    cube_projected[6][0], cube_projected[6][1],
600                                    cube_projected[7][0], cube_projected[7][1]);
601                caca_draw_thin_line(screen_list->cv,
602                                    cube_projected[7][0], cube_projected[7][1],
603                                    cube_projected[4][0], cube_projected[4][1]);
604                }
605               
606               
607            } else
608            {
609                if(get_direction(cube_projected[9][0], cube_projected[9][1],
610                                 cube_projected[8][0], cube_projected[8][1],
611                                 cube_projected[10][0], cube_projected[10][1])) {
612                caca_fill_triangle_textured(screen_list->cv,
613                                            cube_projected[9][0], cube_projected[9][1],
614                                            cube_projected[8][0], cube_projected[8][1],
615                                            cube_projected[10][0], cube_projected[10][1],
616                                            1, 1,
617                                            0, 1,
618                                            1, 0,
619                                            second);
620                caca_fill_triangle_textured(screen_list->cv,
621                                            cube_projected[8][0], cube_projected[8][1],
622                                            cube_projected[10][0], cube_projected[10][1],
623                                            cube_projected[11][0], cube_projected[11][1],
624                                            0, 1,
625                                            1, 0,
626                                            0, 0,
627                                            second);
628                caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
629                caca_draw_thin_line(screen_list->cv,
630                                    cube_projected[8][0], cube_projected[8][1],
631                                    cube_projected[9][0], cube_projected[9][1]);
632                caca_draw_thin_line(screen_list->cv,
633                                    cube_projected[9][0], cube_projected[9][1],
634                                    cube_projected[10][0], cube_projected[10][1]);
635                caca_draw_thin_line(screen_list->cv,
636                                    cube_projected[10][0], cube_projected[10][1],
637                                    cube_projected[11][0], cube_projected[11][1]);
638                caca_draw_thin_line(screen_list->cv,
639                                    cube_projected[11][0], cube_projected[11][1],
640                                    cube_projected[8][0], cube_projected[8][1]);
641                }
642            }
643#endif
644           
645            screen_list->changed =1 ;     
646            screen_list->force_refresh = 1;
647            screen_list->cube.in_switch = 1;
648        }
649       
650    }
651}
652
Note: See TracBrowser for help on using the repository browser.