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
|
#include <string.h>
#include <malloc.h>
#include <syscall.h>
#include <debug.h>
#include <user_region.h>
#include <gip.h>
typedef struct {
framebuffer_info_t mode;
fd_t fd;
uint32_t features;
} giosrv_t;
void reset(gip_handler_t *s, gip_msg_header *p);
void enable_features(gip_handler_t *s, gip_msg_header *p);
void disable_features(gip_handler_t *s, gip_msg_header *p);
void query_mode(gip_handler_t *s, gip_msg_header *p);
void set_mode(gip_handler_t *s, gip_msg_header *p);
void unknown_msg(gip_handler_t *s, gip_msg_header *p);
void fd_error(gip_handler_t *s);
gip_handler_callbacks_t giosrv_cb = {
.reset = reset,
.initiate = 0,
.ok = 0,
.failure = 0,
.enable_features = enable_features,
.disable_features = disable_features,
.query_mode = query_mode,
.set_mode = set_mode,
.buffer_info = 0,
.mode_info = 0,
.buffer_damage = 0,
.unknown_msg = unknown_msg,
.fd_error = fd_error,
};
int main(int argc, char **argv) {
dbg_print("[giosrv] Starting up.\n");
giosrv_t srv;
srv.fd = open("io:/display/vesa", FM_IOCTL | FM_READ | FM_WRITE | FM_MMAP);
if (srv.fd == 0) PANIC("Could not open fbdev");
int r = ioctl(srv.fd, IOCTL_FB_GET_INFO, &srv.mode);
ASSERT(r == 1);
dbg_printf("[giosrv] Running on FB %dx%d\n", srv.mode.width, srv.mode.height);
gip_handler_t *h = new_gip_handler(&giosrv_cb, &srv);
ASSERT(h != 0);
h->mainloop_item.fd = 1;
mainloop_add_fd(&h->mainloop_item);
mainloop_run();
dbg_printf("[giosrv] Main loop exited, terminating.\n");
return 0;
}
void send_buffer_info(gip_handler_t *h, giosrv_t *s) {
gip_msg_header msg = {
.code = GIPN_BUFFER_INFO,
.arg = 0,
};
gip_buffer_info_msg msg_data;
msg_data.geom = s->mode;
if (!gen_token(s->fd, &msg_data.tok)) {
dbg_printf("Could not generate token for buffer_info_msg.\n");
} else {
dbg_printf("Token: %x %x\n", ((uint32_t*)&msg_data.tok)[0], ((uint32_t*)&msg_data.tok)[1]);
gip_notify(h, &msg, &msg_data);
}
}
void reset(gip_handler_t *h, gip_msg_header *p) {
giosrv_t *s = (giosrv_t*)h->data;
s->features = 0;
// ---- Send initiate message
gip_msg_header msg = {
.code = GIPR_INITIATE,
.arg = GIPF_MODESET
};
gip_reply(h, p, &msg, 0);
// ---- Send buffer information
send_buffer_info(h, s);
}
void enable_features(gip_handler_t *h, gip_msg_header *p) {
gip_reply_fail(h, p);
}
void disable_features(gip_handler_t *h, gip_msg_header *p) {
gip_reply_fail(h, p);
}
void query_mode(gip_handler_t *h, gip_msg_header *p) {
// TODO
}
void set_mode(gip_handler_t *h, gip_msg_header *p) {
// TODO
}
void unknown_msg(gip_handler_t *h, gip_msg_header *p) {
// TODO
}
void fd_error(gip_handler_t *h) {
// TODO
}
/* vim: set ts=4 sw=4 tw=0 noet :*/
|