source: neercs/trunk/src/effects.c @ 2474

Last change on this file since 2474 was 2474, checked in by Pascal Terjan, 13 years ago
  • First more or less working version of attach
File size: 11.6 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: effects.c 2360 2008-06-11 16:23:46Z 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 <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <cucul.h>
20#include <caca.h>
21#include <config.h>
22#include <time.h>
23#include <sys/wait.h>
24#include <sys/types.h>
25#include <security/pam_appl.h>
26#include <security/pam_misc.h>
27#include <pwd.h>
28
29#include "neercs.h"
30
31static int convpam(int num_msg, const struct pam_message **msg,
32        struct pam_response **resp, void *appdata_ptr);
33
34void draw_thumbnails(cucul_canvas_t *cv, struct screen_list *screen_list)
35{
36                char const * const *fonts;
37                cucul_dither_t *d;
38                cucul_font_t *f;
39                uint8_t *buf;
40                int i;
41                int miniw, minih;
42
43                if(screen_list->count)
44                {
45                    fonts = cucul_get_font_list();
46                    f = cucul_load_font(fonts[0], 0);
47
48                    miniw = cucul_get_canvas_width(screen_list->screen[0]->cv)
49                        * cucul_get_font_width(f);
50                    minih = cucul_get_canvas_height(screen_list->screen[0]->cv)
51                        * cucul_get_font_height(f);
52                    buf = malloc(4 * miniw * minih);
53
54#if defined(HAVE_ENDIAN_H)
55                    if(__BYTE_ORDER == __BIG_ENDIAN)
56#else
57                        /* This is compile-time optimised with at least -O1 or -Os */
58                        uint32_t const tmp = 0x12345678;
59                    if(*(uint8_t const *)&tmp == 0x12)
60#endif
61                        d = cucul_create_dither(32, miniw, minih, 4 * miniw,
62                                                0xff0000, 0xff00, 0xff, 0x0);
63                    else
64                        d = cucul_create_dither(32, miniw, minih, 4 * miniw,
65                                                0xff00, 0xff0000, 0xff000000, 0x0);
66
67                    for(i = 0; i < screen_list->count; i++)
68                    {
69                        cucul_render_canvas(screen_list->screen[i]->cv, f, buf,
70                                            miniw, minih, miniw * 4);
71                        cucul_dither_bitmap(cv, 20 * i,
72                                            cucul_get_canvas_height(cv) - 6, 19, 6, d, buf);
73                        cucul_set_color_ansi(cv, CUCUL_WHITE, CUCUL_BLUE);
74
75                        if(screen_list->pty == i)
76                            cucul_draw_cp437_box(cv,20 * i,
77                                                 cucul_get_canvas_height(cv) - 6, 19, 6);
78                        cucul_printf(cv, 20 * i,
79                                     cucul_get_canvas_height(cv) - 6, "(%i)", i+1);
80                    }
81
82                    cucul_free_dither(d);
83                    cucul_free_font(f);
84
85                    free(buf);
86                }
87
88}
89
90/* FIXME, make this stuff more configurable */
91void draw_status(cucul_canvas_t *cv, struct screen_list *screen_list)
92{
93    int x = 0, y = cucul_get_canvas_height(cv) - 1;
94
95
96        cucul_set_color_ansi(cv, CUCUL_BLUE, CUCUL_BLUE);
97        cucul_fill_box(cv,
98                       x, y,
99                       cucul_get_canvas_width(cv), 1, '#');
100
101/* Hour */
102    {
103        time_t now = time ((time_t *) 0);
104        struct tm *t = localtime(&now);
105        char hour[256];
106        sprintf(hour, "%02d:%02d", t->tm_hour, t->tm_min);
107
108        cucul_set_color_ansi(cv, CUCUL_LIGHTBLUE, CUCUL_BLUE);
109        cucul_printf(cv, x, y,
110                     "[");
111
112        cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_BLUE);
113        cucul_printf(cv, x+1, y,
114                     hour);
115        cucul_set_color_ansi(cv, CUCUL_LIGHTBLUE, CUCUL_BLUE);
116        cucul_printf(cv, x + strlen(hour) + 1, y,
117                     "]");
118        x += 7;
119
120    }
121
122/* Window */
123    {
124        char text[256];
125        sprintf(text, "%d/%d", screen_list->pty+1, screen_list->count);
126        x++;
127        cucul_set_color_ansi(cv, CUCUL_LIGHTBLUE, CUCUL_BLUE);
128        cucul_printf(cv, x, y, "Window:");
129        cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_BLUE);
130        cucul_printf(cv, x+8, y, text);
131        x+= 8+strlen(text);
132    }
133
134/* Window Manager */
135    {
136        char text[256];
137
138        switch(screen_list->wm_type)
139        {
140        case WM_CARD:
141            strcpy(text, "card");
142            break;
143        case WM_HSPLIT:
144            strcpy(text, "hsplit");
145            break;
146        case WM_VSPLIT:
147            strcpy(text, "vsplit");
148            break;
149        case WM_FULL:
150        default:
151            strcpy(text, "full");
152            break;
153
154        }
155
156        x++;
157        cucul_set_color_ansi(cv, CUCUL_LIGHTBLUE, CUCUL_BLUE);
158        cucul_printf(cv, x, y, "WM:");
159        cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_BLUE);
160        cucul_printf(cv, x+4, y, text);
161        x+= 4+strlen(text);
162    }
163
164/* Help (must be the last one )*/
165    {
166        char text[256];
167        sprintf(text, "Help: ctrl-a-h");
168        x = cucul_get_canvas_width(cv) - strlen(text);
169
170        cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_BLUE);
171        cucul_printf(cv, x, y, text);
172    }
173
174
175}
176
177
178void draw_help(cucul_canvas_t *cv, struct screen_list *screen_list)
179{
180    int w = 65, h = 20;
181    int x = (cucul_get_canvas_width(cv) - w) / 2;
182    int y = (cucul_get_canvas_height(cv) - h) / 2;
183
184
185    cucul_set_color_ansi(cv, CUCUL_BLUE, CUCUL_BLUE);
186    cucul_fill_box(cv,
187                   x, y,
188                   w, h, '#');
189    cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_BLUE);
190    cucul_draw_cp437_box(cv,
191                         x, y,
192                         w, h);
193
194    x+=2;
195    y++;
196    cucul_printf(cv,
197                 (cucul_get_canvas_width(cv) - strlen(PACKAGE_STRING)) / 2,
198                 y-1,
199                 PACKAGE_STRING);
200    cucul_printf(cv, x, y++, "Copyright (c) 2006-2008 ");
201    cucul_printf(cv, x, y++, "              Sam Hocevar <sam@zoy.org>");
202    cucul_printf(cv, x, y++, "              Jean-Yves Lamoureux <jylam@lnxscene.org>");
203    cucul_printf(cv, x, y++, "              Pascal Terjan <pterjan@linuxfr.org>");
204    cucul_printf(cv, x, y++, "");
205    cucul_printf(cv, x, y++, "");
206    cucul_printf(cv, x, y++, "All shortcuts are in format 'ctrl-a-X' where X is :");
207    cucul_printf(cv, x, y++, "n:\t Next window");
208    cucul_printf(cv, x, y++, "p:\t Previous window");
209    cucul_printf(cv, x, y++, "w:\t Switch window manager");
210    cucul_printf(cv, x, y++, "c:\t Create new window");
211    cucul_printf(cv, x, y++, "m:\t Thumbnails");
212    cucul_printf(cv, x, y++, "d:\t Detach");
213    cucul_printf(cv, x, y++, "k:\t Close window and kill associated process");
214    cucul_printf(cv, x, y++, "h:\t This help");
215    cucul_printf(cv, x, y++, "");
216    cucul_printf(cv, x, y++, "");
217    cucul_printf(cv, x, y++, "See http://libcaca.zoy.org/wiki/neercs for more informations");
218}
219
220
221void draw_lock(cucul_canvas_t *cv, struct screen_list *screen_list)
222{
223    unsigned int i;
224    char buffer[1024];
225    gethostname(buffer, sizeof(buffer)-1);
226
227    int w = 65, h = 20;
228    int x = (cucul_get_canvas_width(cv) - w) / 2;
229    int y = (cucul_get_canvas_height(cv) - h) / 2;
230
231
232    cucul_set_color_ansi(cv, CUCUL_BLUE, CUCUL_BLUE);
233    cucul_fill_box(cv,
234                   x, y,
235                   w, h, '#');
236    cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_BLUE);
237    cucul_draw_cp437_box(cv,
238                         x, y,
239                         w, h);
240
241    x+=2;
242    y++;
243    cucul_printf(cv,
244                 (cucul_get_canvas_width(cv) - strlen(PACKAGE_STRING " locked")) / 2,
245                 y-1,
246                 PACKAGE_STRING " locked");
247
248    cucul_printf(cv, x, y++, "Please type in your password for %s@%s :", getenv("USER"), buffer);
249    y+=2;
250
251    x = (cucul_get_canvas_width(cv)/2) - ((strlen(screen_list->lockpass) / 2) + strlen("Password : "));
252    cucul_printf(cv, x, y, "Password : ");
253    x+=strlen("Password : ");
254    for(i=0; i<strlen(screen_list->lockpass); i++)
255    {
256        cucul_put_str(cv, x, y, "*");
257        x++;
258    }
259
260
261    if(strlen(screen_list->lockmsg))
262    {
263        x = ((cucul_get_canvas_width(cv) - w) / 2) + (strlen(screen_list->lockmsg));
264        y+=2;
265        cucul_set_color_ansi(cv, CUCUL_RED, CUCUL_BLUE);
266        cucul_printf(cv, x, y, "Error : %s", screen_list->lockmsg);
267    }
268}
269
270
271
272/* FIXME, handle this without assuming this is a password auth */
273static int convpam(int num_msg, const struct pam_message **msg,
274                struct pam_response **resp, void *appdata_ptr)
275{
276
277    struct pam_response *aresp;
278    int i;
279    aresp = calloc(num_msg, sizeof(*aresp));
280
281    for (i = 0; i < num_msg; ++i)
282    {
283        switch(msg[i]->msg_style)
284        {
285        case PAM_PROMPT_ECHO_ON:
286        case PAM_PROMPT_ECHO_OFF:
287            aresp[i].resp = strdup(appdata_ptr);
288            aresp[i].resp_retcode = 0;
289            break;
290        case PAM_ERROR_MSG:
291            break;
292        default :
293            printf("Unknow message type from PAM\n");
294            break;
295        }
296    }
297
298    *resp = aresp;
299    return (PAM_SUCCESS);
300}
301
302
303int validate_lock(struct screen_list *screen_list, char *user, char *pass)
304{
305    int ret;
306    pam_handle_t *pamh=NULL;
307    char buffer[100];
308    const char *service="neercs";
309    struct pam_conv conv = {
310        convpam,
311        pass,
312    };
313
314    ret = pam_start(service, user, &conv, &pamh);
315    if(ret!=PAM_SUCCESS)
316        return 0;
317    pam_set_item(pamh, PAM_RUSER, user);
318
319    ret = gethostname(buffer, sizeof(buffer)-1);
320    if (ret)
321    {
322        perror("failed to look up hostname");
323        ret = pam_end(pamh, PAM_ABORT);
324        sprintf(screen_list->lockmsg, "Can't get hostname");
325        pam_end(pamh, PAM_SUCCESS);
326        return 0;
327    }
328
329    ret = pam_set_item(pamh, PAM_RHOST, buffer);
330    if(ret!=PAM_SUCCESS)
331    {
332        sprintf(screen_list->lockmsg, "Can't set hostname");
333        pam_end(pamh, PAM_SUCCESS);
334        return 0;
335    }
336
337    ret = pam_authenticate(pamh, 0);
338    if(ret!=PAM_SUCCESS)
339    {
340        sprintf(screen_list->lockmsg, "Can't authenticate");
341        pam_end(pamh, PAM_SUCCESS);
342        return 0;
343    }
344
345    ret = pam_end(pamh, PAM_SUCCESS);
346    return 1;
347}
348
349
350/* Close a window by animating it collapsing */
351/* Total close time */
352#define DELAY 500000.0f
353int close_screen_recurrent(struct screen_list* screen_list, struct recurrent* rec, void *user, long long unsigned int t)
354{
355    long long unsigned int delta = t - rec->start_time;
356
357    screen_list->dont_update_coords = 1;
358    rec->kill_me = 0;
359    if(delta>=DELAY)
360    {
361        rec->kill_me = 1;
362        remove_screen(screen_list, screen_list->pty, 1);
363        screen_list->pty = screen_list->prevpty;
364        screen_list->prevpty = 0;
365        screen_list->dont_update_coords = 0;
366    }
367    else
368    {
369        float r = 1 - ((DELAY - (DELAY - delta)) / DELAY);
370        cucul_canvas_t *old, *new;
371        struct screen *s = screen_list->screen[screen_list->pty];
372        int w = s->orig_w * r;
373        int h = s->orig_h * r;
374
375        /* libcucul canvas resize function is bugged, do it by hand  */
376        old = s->cv;
377        new = cucul_create_canvas(w, h);
378        cucul_blit(new, 0, 0, old, NULL);
379        s->cv = new;
380        cucul_free_canvas(old);
381        set_tty_size(s->fd, w, h);
382
383        s->w = w;
384        s->h = h;
385
386        s->x =
387            (s->orig_x * r) +
388            ((s->orig_w/2) - s->w/2);
389        s->y =
390            (s->orig_y * r) +
391            ((s->orig_h/2) - s->h/2);
392    }
393
394    return 1;
395}
Note: See TracBrowser for help on using the repository browser.