summaryrefslogtreecommitdiff
path: root/src/sclient.c
blob: 25002472fd09b521a991491b0e87663b43b20fdc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/**
 * @file
 * @section AUTHORS
 *
 *  Authors:
 *       Eamon Walsh <ewalsh@tycho.nsa.gov>
 *
 * @section LICENSE
 *
 * This file is in the public domain.
 *
 * @section DESCRIPTION
 *
 * This is the "subclass" of display that implements the server help screen
 * (the default screen that has the instructions and allows pressing
 * Esc to exit the server).
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>

#include "common.h"
#include "sys-queue.h"
#include "client.h"
#include "display.h"

static struct display sd;
static unsigned char *background;

static int
sclient_key(struct display *d, bool down, int keycode)
{
    if (keycode == KEY_ESC)
	kill(getpid(), SIGINT);

    return 0;
}

static int
sclient_mouse(struct display *d, struct mouse_event *m)
{
    return 0;
}

void
sclient_read_background_image(const char *filename, unsigned char *buf,
			      const int dw, const int dh)
{
    uint32_t iw, ih, w, h, o;
    unsigned i;
    unsigned char bg, *ptr = buf;
    int fd = open(filename, O_RDONLY);

    if (fd < 0)
	goto err;

    if (read(fd, &iw, sizeof(iw)) != sizeof(iw))
	goto err2;
    if (read(fd, &ih, sizeof(ih)) != sizeof(ih))
	goto err2;
    if (read(fd, &bg, 1) != 1)
	goto err2;

    lseek(fd, -1, SEEK_CUR);
    memset(buf, bg, dw * dh);

    iw = ntohl(iw);
    ih = ntohl(ih);

    w = MIN(iw, dw);
    h = MIN(ih, dh);
    o = (dw - w) / 2;

    for (i = 0; i < h; i++) {
	read(fd, ptr + o, w);
	ptr += dw;
	lseek(fd, iw - w, SEEK_CUR);
    }

    close(fd);
    return;

err2:
    close(fd);
err:
    memset(buf, 0, dw * dh);
}

int
sclient_setup(void)
{
    DFBSurfaceDescription sdesc;
    struct buffer *b;
    int width = display_get_width();
    int height = display_get_height();

    background = malloc(width * height);
    if (!background)
	return -1;

    sclient_read_background_image(SERVER_BG_FILE, background, width, height);

    /* Set up preallocated DirectFB surface with the data */
    memset(&sdesc, 0, sizeof(sdesc));
    sdesc.flags  = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_CAPS | DSDESC_PIXELFORMAT | DSDESC_PREALLOCATED;
    sdesc.width  = width;
    sdesc.height = height;
    sdesc.pixelformat = DSPF_RGB332;
    sdesc.preallocated[0].data = background;
    sdesc.preallocated[0].pitch = width;

    b = buffer_new(sd.client, &sdesc, BUFFER_FLAG_SERVER_BG);
    if (b == NULL) {
	free(background);
	return -1;
    }

    return 0;
}

struct display *
sclient_new(void)
{
    struct client *c = client_add(-1, 1024, 1024);
    if (!c)
	return NULL;

    /* XXX Label the client */
    c->label.label = strdup("LINPICKER SERVER");
    c->label.shortlabel = strdup("S");
    c->label.fg = (struct sec_color){ 0xff, 0xff, 0 };
    c->label.bg = (struct sec_color){ 0xff, 0, 0 };

    /* Set up input methods */
    sd.send_key = sclient_key;
    sd.send_mouse = sclient_mouse;

    sd.type = DISPLAY_SERVER;
    sd.client = c;
    LIST_INIT(&sd.buffers);
    TAILQ_INIT(&sd.views);

    return &sd;
}