summaryrefslogtreecommitdiff
path: root/legacy/evas/src/bin/evas_cserve2_debug.c
diff options
context:
space:
mode:
authorIván Briano <sachieru@gmail.com>2012-06-22 22:39:16 +0000
committerIván Briano <sachieru@gmail.com>2012-06-22 22:39:16 +0000
commit309e29f9eeca36e48cdb31be7049dbd47c85e784 (patch)
tree14777e67827bffaaa1c0f5bf25e9c14cd1516883 /legacy/evas/src/bin/evas_cserve2_debug.c
parent74d8ed3c0160f8edf75f2977e6af230d6d43b385 (diff)
Add simple debug client for cserve2
SVN revision: 72708
Diffstat (limited to 'legacy/evas/src/bin/evas_cserve2_debug.c')
-rw-r--r--legacy/evas/src/bin/evas_cserve2_debug.c451
1 files changed, 451 insertions, 0 deletions
diff --git a/legacy/evas/src/bin/evas_cserve2_debug.c b/legacy/evas/src/bin/evas_cserve2_debug.c
new file mode 100644
index 0000000000..c86045c641
--- /dev/null
+++ b/legacy/evas/src/bin/evas_cserve2_debug.c
@@ -0,0 +1,451 @@
1#include "config.h"
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <errno.h>
6#include <string.h>
7#include <sys/types.h>
8#include <sys/socket.h>
9#include <sys/un.h>
10#include <unistd.h>
11#include <fcntl.h>
12
13#include <Eina.h>
14
15#include "evas_cs2.h"
16
17static int socketfd = -1;
18static unsigned int _rid_count = 1;
19static int _evas_cserve2_debug_log_dom = -1;
20
21static struct sockaddr_un socksize;
22#ifndef UNIX_PATH_MAX
23#define UNIX_PATH_MAX sizeof(socksize.sun_path)
24#endif
25
26#ifdef ERR
27#undef ERR
28#endif
29#define ERR(...) EINA_LOG_DOM_ERR(_evas_cserve2_debug_log_dom, __VA_ARGS__)
30#ifdef DBG
31#undef DBG
32#endif
33#define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_debug_log_dom, __VA_ARGS__)
34#ifdef WRN
35#undef WRN
36#endif
37#define WRN(...) EINA_LOG_DOM_WARN(_evas_cserve2_debug_log_dom, __VA_ARGS__)
38#ifdef INF
39#undef INF
40#endif
41#define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_debug_log_dom, __VA_ARGS__)
42
43static void
44_socket_path_set(char *path)
45{
46 char *env;
47 char buf[UNIX_PATH_MAX];
48
49 env = getenv("EVAS_CSERVE2_SOCKET");
50 if (env && env[0])
51 {
52 strncpy(path, env, UNIX_PATH_MAX - 1);
53 return;
54 }
55
56 snprintf(buf, sizeof(buf), "/tmp/.evas-cserve2-%x.socket", (int)getuid());
57 /* FIXME: check we can actually create this socket */
58 strcpy(path, buf);
59}
60
61static Eina_Bool
62_server_connect(void)
63{
64 int s, len;
65 struct sockaddr_un remote;
66
67 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
68 {
69 ERR("socket");
70 return EINA_FALSE;
71 }
72
73 remote.sun_family = AF_UNIX;
74 _socket_path_set(remote.sun_path);
75 len = strlen(remote.sun_path) + sizeof(remote.sun_family);
76 if (connect(s, (struct sockaddr *)&remote, len) == -1)
77 {
78 ERR("connect");
79 return EINA_FALSE;
80 }
81
82 fcntl(s, F_SETFL, O_NONBLOCK);
83
84 socketfd = s;
85
86 DBG("connected to cserve2 server.");
87 return EINA_TRUE;
88}
89
90static void
91_server_disconnect(void)
92{
93 close(socketfd);
94 socketfd = -1;
95}
96
97static Eina_Bool
98_server_send(const void *data, int size)
99{
100 int sent = 0;
101 ssize_t ret;
102 const char *msg = data;
103
104 while (sent < size)
105 {
106 ret = send(socketfd, msg + sent, size - sent, MSG_NOSIGNAL);
107 if (ret < 0)
108 {
109 if ((errno == EAGAIN) || (errno == EINTR))
110 continue;
111 return EINA_FALSE;
112 }
113 sent += ret;
114 }
115
116 return EINA_TRUE;
117}
118
119static int sr_size = 0;
120static int sr_got = 0;
121static char *sr_buf = NULL;
122
123static void *
124_server_read(int *size)
125{
126 int n;
127 void *ret;
128
129 if (sr_size)
130 goto get_data;
131
132 n = recv(socketfd, &sr_size, sizeof(sr_size), 0);
133 if (n < 0)
134 return NULL;
135
136 sr_buf = malloc(sr_size);
137
138get_data:
139 n = recv(socketfd, sr_buf + sr_got, sr_size - sr_got, 0);
140 if (n < 0)
141 return NULL;
142
143 sr_got += n;
144 if (sr_got < sr_size)
145 return NULL;
146
147 *size = sr_size;
148 sr_size = 0;
149 sr_got = 0;
150 ret = sr_buf;
151 sr_buf = NULL;
152
153 return ret;
154}
155
156static void
157_debug_msg_send(void)
158{
159 Msg_Base msg;
160 int size;
161
162 memset(&msg, 0, sizeof(msg));
163 msg.type = CSERVE2_FONT_DEBUG;
164 msg.rid = _rid_count++;
165
166 size = sizeof(msg);
167
168 if (!_server_send(&size, sizeof(size)))
169 {
170 ERR("Could not send usage msg size to server.");
171 return;
172 }
173 if (!_server_send(&msg, size))
174 {
175 ERR("Could not send usage msg body to server.");
176 return;
177 }
178}
179
180typedef struct _Font_Entry Font_Entry;
181typedef struct _Cache_Entry Cache_Entry;
182typedef struct _Glyph_Entry Glyph_Entry;
183
184struct _Font_Entry
185{
186 const char *file;
187 const char *name;
188 unsigned int rend_flags;
189 unsigned int size;
190 unsigned int dpi;
191 unsigned int unused;
192 Eina_List *caches;
193};
194
195struct _Cache_Entry
196{
197 const char *shmname;
198 unsigned int size;
199 unsigned int usage;
200 Eina_List *glyphs;
201};
202
203struct _Glyph_Entry
204{
205 unsigned int index;
206 unsigned int offset;
207 unsigned int size;
208 unsigned int rows;
209 unsigned int width;
210 unsigned int pitch;
211 unsigned int num_grays;
212 unsigned int pixel_mode;
213};
214
215#define READIT(_dst, _src) \
216 do { \
217 memcpy(&_dst, _src, sizeof(_dst)); \
218 _src += sizeof(_dst); \
219 } while(0)
220
221static Glyph_Entry *
222_parse_glyph_entry(char **msg)
223{
224 Glyph_Entry *ge;
225 char *buf = *msg;
226
227 ge = calloc(1, sizeof(*ge));
228
229 READIT(ge->index, buf);
230 READIT(ge->offset, buf);
231 READIT(ge->size, buf);
232 READIT(ge->rows, buf);
233 READIT(ge->width, buf);
234 READIT(ge->pitch, buf);
235 READIT(ge->num_grays, buf);
236 READIT(ge->pixel_mode, buf);
237
238 *msg = buf;
239
240 return ge;
241}
242
243static Cache_Entry *
244_parse_cache_entry(char **msg)
245{
246 Cache_Entry *ce;
247 char *buf = *msg;
248 unsigned int n;
249
250 ce = calloc(1, sizeof(*ce));
251
252 READIT(n, buf);
253 ce->shmname = eina_stringshare_add_length(buf, n);
254 buf += n;
255
256 READIT(ce->size, buf);
257 READIT(ce->usage, buf);
258
259 READIT(n, buf);
260 while (n--)
261 {
262 Glyph_Entry *ge;
263 ge = _parse_glyph_entry(&buf);
264 ce->glyphs = eina_list_append(ce->glyphs, ge);
265 }
266
267 *msg = buf;
268
269 return ce;
270}
271
272static Font_Entry *
273_parse_font_entry(char **msg)
274{
275 Font_Entry *fe;
276 char *buf = *msg;
277 unsigned int n;
278
279 fe = calloc(1, sizeof(*fe));
280
281 READIT(n, buf);
282 if (n)
283 fe->file = eina_stringshare_add_length(buf, n);
284 buf += n;
285 READIT(n, buf);
286 if (n)
287 fe->name = eina_stringshare_add_length(buf, n);
288 buf += n;
289
290 READIT(fe->rend_flags, buf);
291 READIT(fe->size, buf);
292 READIT(fe->dpi, buf);
293 READIT(fe->unused, buf);
294
295 READIT(n, buf);
296 while (n--)
297 {
298 Cache_Entry *ce;
299 ce = _parse_cache_entry(&buf);
300 fe->caches = eina_list_append(fe->caches, ce);
301 }
302
303 *msg = buf;
304
305 return fe;
306}
307
308static Eina_List *
309_debug_msg_read(void)
310{
311 Msg_Base *msg = NULL;
312 char *buf;
313 int size;
314 unsigned int nfonts;
315 Eina_List *fonts = NULL;
316
317 printf("Requesting server debug info.\n\n");
318 while (!msg)
319 msg = _server_read(&size);
320
321 if (msg->type != CSERVE2_FONT_DEBUG)
322 {
323 ERR("Invalid message received from server."
324 "Something went badly wrong.");
325 return NULL;
326 }
327
328 buf = (char *)msg + sizeof(*msg);
329
330 READIT(nfonts, buf);
331 while (nfonts--)
332 {
333 Font_Entry *fe;
334 fe = _parse_font_entry(&buf);
335 fonts = eina_list_append(fonts, fe);
336 }
337
338 return fonts;
339}
340
341static void
342_glyph_entry_free(Glyph_Entry *ge)
343{
344 free(ge);
345}
346
347static void
348_cache_entry_free(Cache_Entry *ce)
349{
350 Glyph_Entry *ge;
351
352 EINA_LIST_FREE(ce->glyphs, ge)
353 _glyph_entry_free(ge);
354
355 eina_stringshare_del(ce->shmname);
356 free(ce);
357}
358
359static void
360_font_entry_free(Font_Entry *fe)
361{
362 Cache_Entry *ce;
363
364 EINA_LIST_FREE(fe->caches, ce)
365 _cache_entry_free(ce);
366
367 eina_stringshare_del(fe->name);
368 eina_stringshare_del(fe->file);
369 free(fe);
370}
371
372static void
373_glyph_entry_print(Glyph_Entry *ge)
374{
375 const char *pxmode[] = {
376 "FT_PIXEL_MODE_NONE",
377 "FT_PIXEL_MODE_MONO",
378 "FT_PIXEL_MODE_GRAY",
379 "FT_PIXEL_MODE_GRAY2",
380 "FT_PIXEL_MODE_GRAY4",
381 "FT_PIXEL_MODE_LCD",
382 "FT_PIXEL_MODE_LCD_V"
383 };
384 printf("\t\tGLYPH %u offset: %u size: %u %ux%u pitch: %u grays: %u "
385 "pixel mode: %s\n",
386 ge->index, ge->offset, ge->size, ge->width, ge->rows, ge->pitch,
387 ge->num_grays, pxmode[ge->pixel_mode]);
388}
389
390static void
391_cache_entry_print(Cache_Entry *ce)
392{
393 Eina_List *l;
394 Glyph_Entry *ge;
395
396 printf("\tSHM %s used %u/%u\n", ce->shmname, ce->usage, ce->size);
397
398 EINA_LIST_FOREACH(ce->glyphs, l, ge)
399 _glyph_entry_print(ge);
400}
401
402static void
403_font_entry_print(Font_Entry *fe)
404{
405 Eina_List *l;
406 Cache_Entry *ce;
407
408 printf("FONT %s:%s size: %u dpi: %u %s%s%s %s\n",
409 fe->file, fe->name, fe->size, fe->dpi,
410 fe->rend_flags == 0 ? "REGULAR " : "",
411 fe->rend_flags & 1 ? "SLANT " : "",
412 fe->rend_flags & 2 ? "WEIGHT" : "",
413 fe->unused ? "(unused)" : "");
414
415 EINA_LIST_FOREACH(fe->caches, l, ce)
416 _cache_entry_print(ce);
417
418 putchar('\n');
419}
420
421int
422main(void)
423{
424 Eina_List *fonts;
425 Font_Entry *fe;
426
427 eina_init();
428
429 _evas_cserve2_debug_log_dom = eina_log_domain_register
430 ("evas_cserve2_debug", EINA_COLOR_BLUE);
431
432 if (!_server_connect())
433 {
434 ERR("Could not connect to server.");
435 return -1;
436 }
437
438 _debug_msg_send();
439
440 fonts = _debug_msg_read();
441
442 EINA_LIST_FREE(fonts, fe)
443 {
444 _font_entry_print(fe);
445 _font_entry_free(fe);
446 }
447
448 _server_disconnect();
449
450 eina_shutdown();
451}