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