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

Last change on this file since 3920 was 3920, checked in by Pascal Terjan, 14 years ago
  • Drop duplicate code, when not in_switch, cube is same as full
  • 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 3920 2009-11-17 20:52:53Z 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    int i;
280   
281    if(screen_list->screen[screen_list->pty]->changed || screen_list->changed)
282        caca_blit(screen_list->cv,
283                  screen_list->screen[screen_list->pty]->x,
284                  screen_list->screen[screen_list->pty]->y,
285                  screen_list->screen[screen_list->pty]->cv, NULL);
286   
287    if(screen_list->screen[screen_list->pty]->bell)
288    {
289        caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
290        screen_list->screen[screen_list->pty]->bell = 0;
291        screen_list->in_bell--;
292    }
293    else
294    {
295        caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
296    }
297   
298    caca_draw_cp437_box(screen_list->cv,
299                        screen_list->screen[screen_list->pty]->x - 1,
300                        screen_list->screen[screen_list->pty]->y - 1,
301                        screen_list->screen[screen_list->pty]->w + 2,
302                        screen_list->screen[screen_list->pty]->h + 2);
303   
304    if(screen_list->screen[screen_list->pty]->title)
305    {
306        caca_printf(screen_list->cv,
307                    screen_list->screen[screen_list->pty]->x,
308                    screen_list->screen[screen_list->pty]->y - 1,
309                    " %.*s ",
310                    screen_list->screen[screen_list->pty]->w - 3,
311                    screen_list->screen[screen_list->pty]->title);
312    }
313   
314   
315}
316
317void wm_refresh_vsplit(struct screen_list *screen_list)
318{
319    int i;
320   
321    for(i = screen_list->count - 1; i >=0; i--)
322    {
323        if(i!=screen_list->pty && screen_list->screen[i]->visible &&
324           (screen_list->screen[i]->changed || screen_list->changed))
325        {
326            caca_blit(screen_list->cv,
327                      screen_list->screen[i]->x,
328                      screen_list->screen[i]->y,
329                      screen_list->screen[i]->cv, NULL);
330           
331            caca_draw_cp437_box(screen_list->cv,
332                                screen_list->screen[i]->x - 1,
333                                screen_list->screen[i]->y - 1,
334                                screen_list->screen[i]->w + 2,
335                                screen_list->screen[i]->h + 2);
336            if(screen_list->screen[i]->title)
337                caca_printf(screen_list->cv,
338                            screen_list->screen[i]->x,
339                            screen_list->screen[i]->y - 1,
340                            " %.*s ",
341                            screen_list->screen[i]->w - 3,
342                            screen_list->screen[i]->title);
343        }
344    }
345   
346    if(screen_list->screen[screen_list->pty]->changed || screen_list->changed)
347        caca_blit(screen_list->cv,
348                  screen_list->screen[screen_list->pty]->x,
349                  screen_list->screen[screen_list->pty]->y,
350                  screen_list->screen[screen_list->pty]->cv, NULL);
351   
352    if(screen_list->screen[screen_list->pty]->bell)
353    {
354        caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
355        screen_list->screen[screen_list->pty]->bell = 0;
356        screen_list->in_bell--;
357    }
358    else
359    {
360        caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
361    }
362   
363    caca_draw_cp437_box(screen_list->cv,
364                        screen_list->screen[screen_list->pty]->x - 1,
365                        screen_list->screen[screen_list->pty]->y - 1,
366                        screen_list->screen[screen_list->pty]->w + 2,
367                        screen_list->screen[screen_list->pty]->h + 2);
368   
369    if(screen_list->screen[screen_list->pty]->title)
370    {
371        caca_printf(screen_list->cv,
372                    screen_list->screen[screen_list->pty]->x,
373                    screen_list->screen[screen_list->pty]->y - 1,
374                    " %.*s ",
375                    screen_list->screen[screen_list->pty]->w - 3,
376                    screen_list->screen[screen_list->pty]->title);
377    }
378   
379   
380}
381
382void wm_refresh_hsplit(struct screen_list *screen_list)
383{
384    int i;
385   
386    for(i = screen_list->count - 1; i >=0; i--)
387    {
388        if(i!=screen_list->pty && screen_list->screen[i]->visible &&
389           (screen_list->screen[i]->changed || screen_list->changed))
390        {
391            caca_blit(screen_list->cv,
392                      screen_list->screen[i]->x,
393                      screen_list->screen[i]->y,
394                      screen_list->screen[i]->cv, NULL);
395           
396            caca_draw_cp437_box(screen_list->cv,
397                                screen_list->screen[i]->x - 1,
398                                screen_list->screen[i]->y - 1,
399                                screen_list->screen[i]->w + 2,
400                                screen_list->screen[i]->h + 2);
401            if(screen_list->screen[i]->title)
402                caca_printf(screen_list->cv,
403                            screen_list->screen[i]->x,
404                            screen_list->screen[i]->y - 1,
405                            " %.*s ",
406                            screen_list->screen[i]->w - 3,
407                            screen_list->screen[i]->title);
408        }
409    }
410   
411    if(screen_list->screen[screen_list->pty]->changed || screen_list->changed)
412        caca_blit(screen_list->cv,
413                  screen_list->screen[screen_list->pty]->x,
414                  screen_list->screen[screen_list->pty]->y,
415                  screen_list->screen[screen_list->pty]->cv, NULL);
416   
417    if(screen_list->screen[screen_list->pty]->bell)
418    {
419        caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
420        screen_list->screen[screen_list->pty]->bell = 0;
421        screen_list->in_bell--;
422    }
423    else
424    {
425        caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
426    }
427   
428    caca_draw_cp437_box(screen_list->cv,
429                        screen_list->screen[screen_list->pty]->x - 1,
430                        screen_list->screen[screen_list->pty]->y - 1,
431                        screen_list->screen[screen_list->pty]->w + 2,
432                        screen_list->screen[screen_list->pty]->h + 2);
433   
434    if(screen_list->screen[screen_list->pty]->title)
435    {
436        caca_printf(screen_list->cv,
437                    screen_list->screen[screen_list->pty]->x,
438                    screen_list->screen[screen_list->pty]->y - 1,
439                    " %.*s ",
440                    screen_list->screen[screen_list->pty]->w - 3,
441                    screen_list->screen[screen_list->pty]->title);
442    }
443   
444   
445}
446
447#if defined HAVE_CACA_TRIANGLE_TEXTURING
448static float get_direction(float p1x, float p1y, float p2x, float p2y, float p3x, float p3y)
449{
450    float d1x, d1y, d2x, d2y;
451   
452        d1x = p3x - p1x;
453        d1y = p3y - p1y;
454        d2x = p3x - p2x;
455        d2y = p3y - p2y;
456    return (d1x * d2y) - (d1y * d2x);
457}
458#endif
459
460/* 3D Cube. Yeah I know, it's a mess. Just look anywhere else. */
461void wm_refresh_cube(struct screen_list *screen_list)
462{
463    int i;
464       
465    if(!screen_list->cube.in_switch) {
466        wm_refresh_full(screen_list);
467        screen_list->force_refresh = 0;
468    } else {
469       
470#define CUBE_TIME 1000000
471
472       
473       
474        long long unsigned int cur_time = get_us() - screen_list->last_switch;
475       
476        if(cur_time >= CUBE_TIME || screen_list->count==1) {
477            screen_list->changed = 1 ;     
478            screen_list->force_refresh = 1;
479            screen_list->cube.in_switch = 0;
480        } else {
481           
482            float cube[12][3] = {
483                {-1, -1,  1}, 
484                {1,  -1,  1}, 
485                {1,   1,  1},
486                {-1,  1,  1},
487               
488                {1,  -1,  1},
489                {1,  -1,  -1},
490                {1,   1,  -1},
491                {1,   1,  1},
492               
493                {-1,  -1,  1},
494                {-1,  -1,  -1},
495                {-1,   1,  -1},
496                {-1,   1,  1},
497            };
498            float cube_transformed[12][3];
499            float cube_projected[12][2];
500            float fov = 0.5f;
501            float angle = 90.0f * ((float)cur_time / (float)CUBE_TIME);
502            angle*= (M_PI/180.0f);
503           
504            if(screen_list->cube.side==1)
505                angle = -angle;
506           
507           
508            for(i = 0; i < 12; i++) {
509           
510                cube_transformed[i][2] = cube[i][2]*cos(angle) - cube[i][0]*sin(angle);
511                cube_transformed[i][0] = cube[i][2]*sin(angle) + cube[i][0]*cos(angle);
512                cube_transformed[i][1] = cube[i][1];
513               
514                cube_transformed[i][2] -= 3;
515               
516                cube_projected[i][0] = cube_transformed[i][0] / (cube_transformed[i][2] * fov);   
517                cube_projected[i][1] = cube_transformed[i][1] / (cube_transformed[i][2] * fov); 
518               
519                cube_projected[i][0] /=2.0f; cube_projected[i][1] /=2.0f;
520                cube_projected[i][0] +=0.5f; cube_projected[i][1] +=0.5f;
521               
522                cube_projected[i][0] *= screen_list->width;
523                cube_projected[i][1] *= screen_list->height;
524               
525
526            }
527            caca_clear_canvas(screen_list->cv);
528           
529#if defined HAVE_CACA_TRIANGLE_TEXTURING
530            caca_canvas_t *first =  screen_list->screen[screen_list->prevpty]->cv;
531            caca_canvas_t *second = screen_list->screen[screen_list->pty]->cv;
532
533            if(get_direction(cube_projected[0][0], cube_projected[0][1],
534                             cube_projected[1][0], cube_projected[1][1],
535                             cube_projected[2][0], cube_projected[2][1]) >=0) {
536                caca_fill_triangle_textured(screen_list->cv,
537                                            cube_projected[0][0], cube_projected[0][1],
538                                            cube_projected[1][0], cube_projected[1][1],
539                                            cube_projected[2][0], cube_projected[2][1],
540                                            1, 1,
541                                            0, 1,
542                                            0, 0,
543                                            first);
544                caca_fill_triangle_textured(screen_list->cv,
545                                            cube_projected[0][0], cube_projected[0][1],
546                                            cube_projected[2][0], cube_projected[2][1],
547                                            cube_projected[3][0], cube_projected[3][1],
548                                            1, 1,
549                                            0, 0,
550                                            1, 0,
551                                            first);
552               
553               
554                caca_set_color_ansi(screen_list->cv, CACA_LIGHTGREEN, CACA_BLACK);
555                caca_draw_thin_line(screen_list->cv,
556                                    cube_projected[0][0], cube_projected[0][1],
557                                    cube_projected[1][0], cube_projected[1][1]);
558                caca_draw_thin_line(screen_list->cv,
559                                    cube_projected[1][0], cube_projected[1][1],
560                                    cube_projected[2][0], cube_projected[2][1]);
561                caca_draw_thin_line(screen_list->cv,
562                                    cube_projected[2][0], cube_projected[2][1],
563                                    cube_projected[3][0], cube_projected[3][1]);
564                caca_draw_thin_line(screen_list->cv,
565                                    cube_projected[3][0], cube_projected[3][1],
566                                    cube_projected[0][0], cube_projected[0][1]);
567            }
568           
569           
570           
571            if(screen_list->cube.side)
572            {
573                if(get_direction(cube_projected[4][0], cube_projected[4][1],
574                                 cube_projected[5][0], cube_projected[5][1],
575                                 cube_projected[6][0], cube_projected[6][1]) >=0) {
576                caca_fill_triangle_textured(screen_list->cv,
577                                            cube_projected[4][0], cube_projected[4][1],
578                                            cube_projected[5][0], cube_projected[5][1],
579                                            cube_projected[6][0], cube_projected[6][1],
580                                            1, 1,
581                                            0, 1,
582                                            0, 0,
583                                            second);
584                caca_fill_triangle_textured(screen_list->cv,
585                                            cube_projected[4][0], cube_projected[4][1],
586                                            cube_projected[6][0], cube_projected[6][1],
587                                            cube_projected[7][0], cube_projected[7][1],
588                                            1, 1,
589                                            0, 0,
590                                            1, 0,
591                                            second);
592                caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
593
594                caca_draw_thin_line(screen_list->cv,
595                                    cube_projected[4][0], cube_projected[4][1],
596                                    cube_projected[5][0], cube_projected[5][1]);
597                caca_draw_thin_line(screen_list->cv,
598                                    cube_projected[5][0], cube_projected[5][1],
599                                    cube_projected[6][0], cube_projected[6][1]);
600                caca_draw_thin_line(screen_list->cv,
601                                    cube_projected[6][0], cube_projected[6][1],
602                                    cube_projected[7][0], cube_projected[7][1]);
603                caca_draw_thin_line(screen_list->cv,
604                                    cube_projected[7][0], cube_projected[7][1],
605                                    cube_projected[4][0], cube_projected[4][1]);
606                }
607               
608               
609            } else
610            {
611                if(get_direction(cube_projected[9][0], cube_projected[9][1],
612                                 cube_projected[8][0], cube_projected[8][1],
613                                 cube_projected[10][0], cube_projected[10][1])) {
614                caca_fill_triangle_textured(screen_list->cv,
615                                            cube_projected[9][0], cube_projected[9][1],
616                                            cube_projected[8][0], cube_projected[8][1],
617                                            cube_projected[10][0], cube_projected[10][1],
618                                            1, 1,
619                                            0, 1,
620                                            1, 0,
621                                            second);
622                caca_fill_triangle_textured(screen_list->cv,
623                                            cube_projected[8][0], cube_projected[8][1],
624                                            cube_projected[10][0], cube_projected[10][1],
625                                            cube_projected[11][0], cube_projected[11][1],
626                                            0, 1,
627                                            1, 0,
628                                            0, 0,
629                                            second);
630                caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLACK);
631                caca_draw_thin_line(screen_list->cv,
632                                    cube_projected[8][0], cube_projected[8][1],
633                                    cube_projected[9][0], cube_projected[9][1]);
634                caca_draw_thin_line(screen_list->cv,
635                                    cube_projected[9][0], cube_projected[9][1],
636                                    cube_projected[10][0], cube_projected[10][1]);
637                caca_draw_thin_line(screen_list->cv,
638                                    cube_projected[10][0], cube_projected[10][1],
639                                    cube_projected[11][0], cube_projected[11][1]);
640                caca_draw_thin_line(screen_list->cv,
641                                    cube_projected[11][0], cube_projected[11][1],
642                                    cube_projected[8][0], cube_projected[8][1]);
643                }
644            }
645#endif
646           
647            screen_list->changed =1 ;     
648            screen_list->force_refresh = 1;
649            screen_list->cube.in_switch = 1;
650        }
651       
652    }
653}
654
Note: See TracBrowser for help on using the repository browser.