v1.0.0
Stefan Schuermans authored 13 years ago
|
36) #include <intern/types.h>
37)
38) /**
39) * \brief process distributor from config file
40) *
41) * \param[in,out] p_ctx context information
42) * \param[in] p_setting_part2 second half of setting to process
43) * \param[in] p_value value of setting
44) * \return 0 in case of success, -1 in case of error
45) */
46) int flp_config_proc_distri(flp_config_ctx_t *p_ctx, char *p_setting_part2,
47) char *value)
48) {
49) char *ptr;
50) unsigned long val;
51) unsigned int distri, out, pix, i;
52) flp_distri_t *p_distri;
53)
54) /* get distributor number */
55) val = strtoul(p_setting_part2, &ptr, 0);
56) if (ptr == p_setting_part2 || *ptr != 0 || val >= FLP_DISTRI_MAX_CNT) {
57) if (p_ctx->p_msg_func)
58) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
59) "invalid distributor number \"%s\""
60) " in line %u of config file\n",
61) p_setting_part2, p_ctx->line_no);
62) return -1;
63) }
64) distri = (unsigned int)val;
65)
66) /* get number of outputs and pixels */
67) if (flp_parse_two_nos(value, &out, &pix, &ptr) || *ptr != 0) {
68) if (p_ctx->p_msg_func)
69) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
70) "invalid distributor size \"%s\""
71) " in line %u of config file\n",
72) value, p_ctx->line_no);
73) return -1;
74) }
75) if (out >= FLP_OUTPUT_MAX_CNT) {
76) if (p_ctx->p_msg_func)
77) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
78) "invalid number of outputs \"%u\""
79) " in line %u of config file\n",
80) out, p_ctx->line_no);
81) return -1;
82) }
83) if (pix >= FLP_PIXEL_MAX_CNT) {
84) if (p_ctx->p_msg_func)
85) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
86) "invalid number of pixels \"%u\""
87) " in line %u of config file\n",
88) pix, p_ctx->line_no);
89) return -1;
90) }
91)
92) /* check if distributor is already present */
93) if (p_ctx->p_display->distri_ptrs[distri]) {
94) if (p_ctx->p_msg_func)
95) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
96) "duplicate definition of distributor \"%u\""
97) " in line %u of config file\n",
98) distri, p_ctx->line_no);
99) return -1;
100) }
101)
102) /* create a new distributor */
103) p_distri = (flp_distri_t *)malloc(sizeof (flp_distri_t));
104) if (!p_distri) {
105) if (p_ctx->p_msg_func)
106) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err, "out of memory\n");
107) return -1;
108) }
109) p_distri->distri = distri;
110) p_distri->output_cnt = out;
111) p_distri->pixel_cnt = pix;
112) /* initialize mapping information */
113) for (i = 0; i < 3; i++) {
114) p_distri->mapping[i].base = 0.0;
115) p_distri->mapping[i].gamma = 1.0;
116) p_distri->mapping[i].factor = 1.0;
117) flp_mapping_precalc(&p_distri->mapping[i]);
118) }
119) /* create and initialize pixel array */
120) p_distri->p_pixels =
121) (flp_pixel_t *)malloc(out * pix * sizeof (flp_pixel_t));
122) if (!p_distri->p_pixels) {
123) free(p_distri);
124) if (p_ctx->p_msg_func)
125) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err, "out of memory\n");
126) return -1;
127) }
128) for (i = 0; i < out * pix; i++) {
129) p_distri->p_pixels[i].x = -1;
130) p_distri->p_pixels[i].y = -1;
131) }
132) /* create and initialize message buffer */
133) p_distri->msg_len = FLP_MCUF_HDR_LEN + out * pix * 3;
134) p_distri->p_msg_buf = (flp_u8_t *)malloc(p_distri->msg_len);
135) if (!p_distri->p_msg_buf) {
136) free(p_distri->p_pixels);
137) free(p_distri);
138) if (p_ctx->p_msg_func)
139) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err, "out of memory\n");
140) return -1;
141) }
142) memset(p_distri->p_msg_buf, 0, p_distri->msg_len);
143) memcpy(p_distri->p_msg_buf, flp_mcuf_hdr, FLP_MCUF_HDR_LEN);
144) p_distri->p_msg_buf[FLP_MCUF_HDR_OFS_OUTPUTS] = (flp_u8_t)out;
145) p_distri->p_msg_buf[FLP_MCUF_HDR_OFS_PIXELS] = (flp_u8_t)pix;
146) /* store pointer to distributor */
147) p_ctx->p_display->distri_ptrs[distri] = p_distri;
148)
149) /* count distributors */
150) p_ctx->p_display->distri_cnt++;
151)
152) return 0;
153) }
154)
155) /**
156) * \brief process mapping from config file
157) *
158) * \param[in,out] p_ctx context information
159) * \param[in] p_setting_part2 second half of setting to process
160) * \param[in] p_value value of setting
161) * \return 0 in case of success, -1 in case of error
162) */
163) int flp_config_proc_mapping(flp_config_ctx_t *p_ctx, char *p_setting_part2,
164) char *value)
165) {
166) char *ptr, *ptr2;
167) unsigned long val;
168) unsigned int distri, chan;
169) flp_distri_t *p_distri;
170) double base, factor, gamma;
171)
172) /* get distributor number */
173) val = strtoul(p_setting_part2, &ptr, 0);
174) if (ptr == p_setting_part2
175) || (*ptr != 0 && *ptr != ' ' && *ptr != '\t'
176) && *ptr != '\r' && *ptr != '\n')) {
177) if (p_ctx->p_msg_func)
178) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
179) "invalid mapping specifier \"%s\""
180) " in line %u of config file\n",
181) p_setting_part2, p_ctx->line_no);
182) return -1;
183) }
184) distri = (unsigned int)val;
185) if (distri >= FLP_DISTRI_MAX_CNT) {
186) if (p_ctx->p_msg_func)
187) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
188) "invalid distributor number \"%u\""
189) " in line %u of config file\n",
190) distri, p_ctx->line_no);
191) return -1;
192) }
193)
194) /* get channel */
195) while (*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n')
196) ptr++;
197) if (!strcmp(ptr, "red"))
198) chan = 0;
199) else if (!strcmp(ptr, "green"))
200) chan = 1;
201) else if (!strcmp(ptr, "blue"))
202) chan = 2;
203) else {
204) if (p_ctx->p_msg_func)
205) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
206) "invalid channel \"%s\""
207) " in line %u of config file\n", ptr,
208) p_ctx->line_no);
209) return -1;
210) }
211)
212) /* get distributor */
213) p_distri = p_ctx->p_display->distri_ptrs[distri];
214) if (!p_distri) {
215) if (p_ctx->p_msg_func)
216) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
217) "no distributor with number \"%u\""
218) " in line %u of config file\n",
219) distri, p_ctx->line_no);
220) return -1;
221) }
222)
223) /* get mapping parameters: base, factor, gamma */
|
v1.0.0
Stefan Schuermans authored 13 years ago
|
247) if (ptr == ptr2
248) || (*ptr != 0 && *ptr != ' ' && *ptr != '\t'
249) && *ptr != '\r' && *ptr != '\n')) {
250) if (p_ctx->p_msg_func)
251) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
252) "invalid mapping parameters \"%s\""
253) " in line %u of config file\n",
254) value, p_ctx->line_no);
255) return -1;
256) }
257) if (gamma <= 0.0) {
258) if (p_ctx->p_msg_func)
259) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
260) "invalid gamma value \"%f\""
261) " in line %u of config file\n",
262) gamma, p_ctx->line_no);
263) return -1;
264) }
265)
266) /* store new mapping parameters and re-calculate mapping table */
267) p_distri->mapping[chan].base = base;
268) p_distri->mapping[chan].factor = factor;
269) p_distri->mapping[chan].gamma = gamma;
270) flp_mapping_precalc(&p_distri->mapping[chan]);
271)
272) return 0;
273) }
274)
275) /**
276) * \brief process pixel from config file
277) *
278) * \param[in,out] p_ctx context information
279) * \param[in] sz_pixel text of pixel to process
280) * \param[in] distri number of distributor
281) * \param[in] out number of output
282) * \param[in] pix number of pixel
283) * \return 0 in case of success, -1 in case of error
284) */
285) int flp_config_proc_pixel(flp_config_ctx_t *p_ctx, char *sz_pixel,
286) unsigned int distri, unsigned int out,
287) unsigned int pix)
288) {
289) flp_distri_t *p_distri = p_ctx->p_display->distri_ptrs[distri];
290) char *ptr;
291) unsigned int x, y, idx;
292)
293) /* get coordinates of pixel */
294) if (flp_parse_two_nos(sz_pixel, &x, &y, &ptr) || *ptr != 0
295) || (int)x < 0 || (int)x >= p_ctx->p_display->size.x
296) || (int)y < 0 || (int)y >= p_ctx->p_display->size.y) {
297) if (p_ctx->p_msg_func)
298) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
299) "invalid pixel \"%s\""
300) " in line %u of config file\n",
301) sz_pixel, p_ctx->line_no);
302) return -1;
303) }
304)
305) /* check pixel number */
306) if (pix >= FLP_PIXEL_MAX_CNT || pix >= p_distri->pixel_cnt) {
307) if (p_ctx->p_msg_func)
308) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
309) "too many pixels (more than %u)"
310) " in line %u of config file\n",
311) p_distri->pixel_cnt, p_ctx->line_no);
312) return -1;
313) }
314)
315) /* check that pixel is not yet set */
316) idx = out * p_distri->pixel_cnt + pix;
317) if (p_distri->p_pixels[idx].x >= 0
318) && p_distri->p_pixels[idx].y >= 0) {
319) if (p_ctx->p_msg_func)
320) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
321) "pixel %u of output %u of distributor %u already set"
322) " to pixel %u,%u in line %u of config file\n",
323) pix, out, distri, p_distri->p_pixels[idx].x,
324) p_distri->p_pixels[idx].y, p_ctx->line_no);
325) return -1;
326) }
327)
328) /* set pixel coordinates */
329) p_distri->p_pixels[idx].x = x;
330) p_distri->p_pixels[idx].y = y;
331)
332) /* count pixels in total */
333) p_ctx->p_display->pixel_cnt++;
334)
335) return 0;
336) }
337)
338) /**
339) * \brief process output from config file
340) *
341) * \param[in,out] p_ctx context information
342) * \param[in] p_setting_part2 second half of setting to process
343) * \param[in] p_value value of setting
344) * \return 0 in case of success, -1 in case of error
345) */
346) int flp_config_proc_output(flp_config_ctx_t *p_ctx, char *p_setting_part2,
347) char *value)
348) {
349) char *ptr, *p_pos, *p_white, white;
350) unsigned int distri, out, pix;
351) flp_distri_t *p_distri;
352) int err;
353)
354) /* get number of distributor and output */
355) if (flp_parse_two_nos(p_setting_part2, &distri, &out, &ptr) || *ptr != 0) {
356) if (p_ctx->p_msg_func)
357) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
358) "invalid output specifier \"%s\""
359) " in line %u of config file\n",
360) p_setting_part2, p_ctx->line_no);
361) return -1;
362) }
363) if (distri >= FLP_DISTRI_MAX_CNT) {
364) if (p_ctx->p_msg_func)
365) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
366) "invalid distributor number \"%u\""
367) " in line %u of config file\n",
368) distri, p_ctx->line_no);
369) return -1;
370) }
371) if (out >= FLP_OUTPUT_MAX_CNT) {
372) if (p_ctx->p_msg_func)
373) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
374) "invalid output number \"%u\""
375) " in line %u of config file\n",
376) out, p_ctx->line_no);
377) return -1;
378) }
379)
380) /* get distributor */
381) p_distri = p_ctx->p_display->distri_ptrs[distri];
382) if (!p_distri) {
383) if (p_ctx->p_msg_func)
384) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
385) "no distributor with number \"%u\""
386) " in line %u of config file\n",
387) distri, p_ctx->line_no);
388) return -1;
389) }
390) /* check output number */
391) if (out >= p_distri->output_cnt) {
392) if (p_ctx->p_msg_func)
393) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
394) "no output with output number \"%u\""
395) " in line %u of config file\n",
396) out, p_ctx->line_no);
397) return -1;
398) }
399)
400) /* count outputs */
401) p_ctx->p_display->output_cnt++;
402)
403) /* process pixels */
404)
405) /* process all parts separated by whitespace */
406) p_pos = value;
407) err = 0;
408) pix = 0;
409) while (*p_pos != 0) {
410)
411) /* get end of item (first whitespace) */
412) for (p_white = p_pos;
413) *p_white && *p_white != ' ' && *p_white != '\t'
414) && *p_white != '\r' && *p_white != '\n'; p_white++);
415)
416) /* process item: a pixel */
417) white = *p_white; /* terminate item */
418) *p_white = 0;
419) if (flp_config_proc_pixel(p_ctx, p_pos, distri, out, pix)) /* process */
420) err = -1; /* remember errors */
421) pix++; /* count pixels */
422) *p_white = white; /* undo termination */
423)
424) /* skip whitespace and continue after it */
425) for (;
426) *p_white == ' ' || *p_white == '\t'
427) || *p_white == '\r' || *p_white == '\n'; p_white++);
428) p_pos = p_white;
429)
430) } /* while (*p_pos != 0) */
431)
432) return err;
433) }
434)
435) /**
436) * \brief process setting from config file
437) *
438) * \param[in,out] p_ctx context information
439) * \param[in] p_setting setting to process
440) * \param[in] p_value value of setting
441) * \return 0 in case of success, -1 in case of error
442) */
443) int flp_config_proc_setting(flp_config_ctx_t *p_ctx, char *p_setting,
444) char *p_value)
445) {
446) char *ptr;
447) unsigned int x, y;
448)
449) /* replace all whitespace with spaces in setting */
450) while ((ptr = strchr(p_setting, '\t')))
451) *ptr = ' ';
452) while ((ptr = strchr(p_setting, '\r')))
453) *ptr = ' ';
454) while ((ptr = strchr(p_setting, '\n')))
455) *ptr = ' ';
456)
457) /* bind address for UDP output */
458) if (!strcmp(p_setting, "bindAddr")) {
459) if (flp_parse_addr(p_value, &p_ctx->p_display->bind_addr)) {
460) if (p_ctx->p_msg_func)
461) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
462) "invalid address \"%s\" for \"%s\""
463) " in line %u of config file\n",
464) p_value, p_setting, p_ctx->line_no);
465) return -1;
466) }
467) if (p_ctx->p_msg_func)
468) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_info, "bind address: %s\n", p_value);
469) return 0;
470) }
471)
472) /* size of display */
473) if (!strcmp(p_setting, "size")) {
474) if (flp_parse_two_nos(p_value, &x, &y, &ptr)
475) || (int)x <= 0 || (int)y <= 0) {
476) if (p_ctx->p_msg_func)
477) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_err,
478) "invalid value \"%s\" for \"%s\""
479) " in line %u of config file\n",
480) p_value, p_setting, p_ctx->line_no);
481) return -1;
482) }
483) p_ctx->p_display->size.x = x;
484) p_ctx->p_display->size.y = y;
485) return 0;
486) }
487)
488) /* distributor */
489) if (!strncmp(p_setting, "distributor ", 12))
490) return flp_config_proc_distri(p_ctx, p_setting + 12, p_value);
491)
492) /* mapping */
493) if (!strncmp(p_setting, "mapping ", 8))
494) return flp_config_proc_mapping(p_ctx, p_setting + 8, p_value);
495)
496) /* output */
497) if (!strncmp(p_setting, "output ", 7))
498) return flp_config_proc_output(p_ctx, p_setting + 7, p_value);
499)
500) /* unknown setting */
501) if (p_ctx->p_msg_func)
502) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_warn,
503) "unknown setting \"%s\""
504) " in line %u of config file, ignored\n",
505) p_setting, p_ctx->line_no);
506) return 0;
507) }
508)
509) /**
510) * \brief process line from config file
511) *
512) * \param[in,out] p_ctx context information
513) * \param[in] p_line line to process
514) * \return 0 in case of success, -1 in case of error
515) */
516) int flp_config_proc_line(flp_config_ctx_t *p_ctx, char *p_line)
517) {
518) char *p_hash, *p_equal, *p_setting, *p_value;
519) int i;
520)
521) /* remove comment */
522) p_hash = strchr(p_line, '#');
523) if (p_hash)
524) *p_hash = 0;
525)
526) /* remove trailing whitespace */
527) for (i = strlen(p_line) - 1;
528) i >= 0 && (p_line[i] == ' ' || p_line[i] == '\t'
529) || p_line[i] == '\r' || p_line[i] == '\n'); i--)
530) p_line[i] = 0;
531)
532) /* remove leading whitespace */
533) for (; *p_line == ' ' || *p_line == '\t'
534) || *p_line == '\r' || *p_line == '\n'; p_line++);
535)
536) /* ignore empty line */
537) if (!p_line[0])
538) return 0;
539)
540) /* find equal sign */
541) p_equal = strchr(p_line, '=');
542) if (!p_equal) { /* no equal sign found */
543) if (p_ctx->p_msg_func)
544) p_ctx->p_msg_func(p_ctx->p_msg_ctx, flp_msg_type_warn,
545) "invalid line %u in config file, ignored\n",
546) p_ctx->line_no);
547) return 0;
548) }
549)
550) /* split string at equal sign */
551) *p_equal = 0;
552) p_setting = p_line;
553) p_value = p_equal + 1;
554)
555) /* remove trailing whitespaces in setting name */
556) for (i = strlen(p_setting) - 1;
557) i >= 0 && (p_setting[i] == ' ' || p_setting[i] == '\t'
558) || p_setting[i] == '\r' || p_setting[i] == '\n'); i--)
559) p_setting[i] = 0;
560)
561) /* remove leading whitespaces in value */
562) for (; *p_value == ' ' || *p_value == '\t'
563) || *p_value == '\r' || *p_value == '\n'; p_value++);
564)
565) /* process setting */
566) return flp_config_proc_setting(p_ctx, p_setting, p_value);
567) }
568)
569) /**
570) * \brief process config file
571) *
572) * \param[in,out] p_display display to configure
573) * \param[in] sz_config_file name of config file to read
574) * \param[in] p_msg_func message callback function or NULL
575) * \param[in] p_msg_ctx user context for message callback
576) * \return 0 in case of success, -1 in case of error
577) */
578) int flp_config_proc_file(flp_display_t *p_display,
579) const char *sz_config_file,
580) flp_msg_func_p_t p_msg_func, void *p_msg_ctx)
581) {
582) flp_config_ctx_t ctx;
583) FILE *file;
584)
585) /* set up context */
586) ctx.p_display = p_display;
587) ctx.p_msg_func = p_msg_func;
588) ctx.p_msg_ctx = p_msg_ctx;
589)
590) /* check if file is present */
591) if (!sz_config_file || !sz_config_file[0]) {
592) if (p_msg_func)
593) p_msg_func(p_msg_ctx, flp_msg_type_err,
594) "no config file specified\n");
595) return -1;
596) }
597)
598) if (p_msg_func)
599) p_msg_func(p_msg_ctx, flp_msg_type_info,
600) "using config file \"%s\"\n",
601) sz_config_file);
602)
603) /* open file */
604) file = fopen(sz_config_file, "rt");
605) if (!file) {
|