static int Epdc_set_opt(Epdc *self, enum plep_update_opt opt, PyObject *value) { if (!PyBool_Check(value)) return -1; plep_set_opt(self->plep, opt, (value == Py_True) ? 1 : 0); return 0; }
int main(int argc, char **argv) { //static const char OPTIONS[] = "hvlpsjPr:g:f::A:Ww:m:d:e:b:T:t:o:a:c:O:i:"; static const char OPTIONS[] = "A:a:b:c:D:d:E:e:F:f:g:hi:jlm:no:O:Ppr:sT:t:vWw:x:y:"; __sighandler_t sigint_original; char * const *file_names = NULL; size_t n_files = 0; int dither_mode = 0; int keep_power_on = 0; const char *waveform_id_str = "2"; int waveform_id = 2; int do_enumerate_waveforms = 0; int do_log_info = 0; int do_wait_power_off = 0; int do_synchro = 0; int do_infinite_loop = 0; int cfa = -1; int display_enable = 0; int do_fill = 0; int fill_color = 0xFF; int do_auto_rotate = 0; int rotation_angle = -1; int do_partial_update = 0; int use_manual_temperature = 0; int manual_temperature = 25; unsigned long pause_ms = 2000; const char *mode = NULL; const char *fbdev = NULL; const char *epdev = NULL; const char *background = NULL; struct plep_point offset = { 0, 0 }; enum epdoc_align_h align_h = EPDOC_ALIGN_H_NONE; enum epdoc_align_v align_v = EPDOC_ALIGN_V_NONE; struct plep_rect crop = { { 0, 0 }, { INT_MAX, INT_MAX } }; const char *doc_type = NULL; const char *conf_file = NULL; struct plep *plep; struct pldraw *pldraw; int onoff = -1; int c; int ret; int use_alternative_vsource = 0; while ((c = getopt(argc, argv, OPTIONS)) != -1) { switch (c) { case 'A': if (!strcmp(optarg, "l")) { use_alternative_vsource = 1; }else if (!strcmp(optarg, "h")) { use_alternative_vsource = 2; }else if (!strcmp(optarg, "lh")) { use_alternative_vsource = 3; }else if (!strcmp(optarg, "hl")) { use_alternative_vsource = 3; }else{ LOG("invalid alternative VSOURCE selection"); print_usage(); exit(EXIT_FAILURE); } break; case 'h': print_usage(); exit(EXIT_SUCCESS); break; case 'v': printf("%s v%s - %s\n%s\n%s\n", APP_NAME, VERSION, DESCRIPTION, COPYRIGHT, LICENSE); exit(EXIT_SUCCESS); break; case 'l': do_log_info = 1; break; case 'P': do_partial_update = 1; break; case 'p': do_wait_power_off = 1; break; case 's': do_synchro = 1; break; case 'j': do_infinite_loop = 1; break; case 'r': if (!strcmp(optarg, "auto")) { do_auto_rotate = 1; } else { unsigned long raw_angle; if (str2ul(optarg, &raw_angle) < 0) { LOG("failed to parse rotation angle"); print_usage(); exit(EXIT_FAILURE); } if ((raw_angle > 270) || (raw_angle % 90)) { LOG("invalid rotation angle"); print_usage(); exit(EXIT_FAILURE); } rotation_angle = raw_angle; } break; case 'g': if (str2ul(optarg, &pause_ms) < 0) { LOG("failed to parse pause duration"); print_usage(); exit(EXIT_FAILURE); } break; case 'f': if (optarg == NULL) { cfa = PLDRAW_CFA_GR_BW; } else { cfa = pldraw_get_cfa_id(optarg); if (cfa < 0) { LOG("Invalid CFA identifier: %s", optarg); print_usage(); exit(EXIT_FAILURE); } } break; case 'F':{ char* str = optarg; if (optarg == NULL) { // set color to white (0xFF) do_fill = 1; } else { do_fill = 1; if(!strncmp(optarg, "0x", 2) || !strncmp(optarg, "0X", 2)){ fill_color = strtoul(optarg, NULL, 16); }else{ fill_color = atoi(optarg); } } break; } case 'T': manual_temperature = atoi(optarg); use_manual_temperature = 1; break; case 'W': do_enumerate_waveforms = 1; break; case 'i': waveform_id_str = NULL; waveform_id = atoi(optarg); break; case 'w': waveform_id_str = optarg; break; case 'm': mode = optarg; break; case 'd': fbdev = optarg; break; case 'e': epdev = optarg; break; case 'b': background = optarg; break; case 't': doc_type = optarg; break; case 'o': if (parse_offset(&offset, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'a': if (parse_alignment(&align_h, &align_v, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'c': if (parse_crop(&crop, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'O': conf_file = optarg; if (access(conf_file, F_OK)) { LOG_ERRNO("Configuration file"); exit(EXIT_FAILURE); } break; case 'x':{ onoff = atoi(optarg); break; } case 'E':{ //Enable Display N display_enable = atoi(optarg); if(display_enable > 3){ LOG("Invalid arguments"); exit(EXIT_FAILURE); } break; } case 'D':{ //disable Display N display_enable -= atoi(optarg); if(display_enable < -3){ LOG("Invalid arguments"); exit(EXIT_FAILURE); } break; } case 'y': dither_mode = atoi(optarg); LOG("dither_mode %i", dither_mode); if(display_enable < 0 || display_enable > 3){ LOG("Invalid arguments"); exit(EXIT_FAILURE); } break; case 'n':{ keep_power_on = 1; break; } case '?': default: LOG("Invalid arguments"); print_usage(); exit(EXIT_FAILURE); break; } } if (optind < argc) { file_names = &argv[optind]; n_files = argc - optind; } LOG("%s v%s", APP_NAME, VERSION); plep = plep_init(epdev, mode, conf_file); if (plep == NULL) { LOG("failed to initialise ePDC"); goto error_plep; } pldraw = pldraw_init(fbdev, conf_file); if (pldraw == NULL) { LOG("failed to initialise pldraw"); goto error_pldraw; } pldraw_set_plep(pldraw, plep); if(waveform_id_str){ waveform_id = plep_get_wfid(plep, waveform_id_str); if (waveform_id < 0) { LOG("Invalid waveform path: %s", waveform_id_str); goto error_pldraw; } } if (cfa >= 0) pldraw_set_cfa(pldraw, cfa); else cfa = pldraw_get_cfa(pldraw); if (cfa != PLDRAW_CFA_NONE) LOG("CFA: %s", pldraw_cfa_name[cfa]); if (rotation_angle < 0) rotation_angle = pldraw_get_rotation(pldraw); if (rotation_angle) LOG("rotation: %d", rotation_angle); if (do_log_info) pldraw_log_info(pldraw); sigint_original = signal(SIGINT, sigint_abort); if(onoff != -1){ LOG("POWER ONOFF:%i\n", onoff); if(onoff) plep_powerup(plep); else plep_powerdown(plep); exit(EXIT_SUCCESS); } if(display_enable != 0){ //LOG("DISPLAY ENABLE:%i\n", display_enable); if(display_enable>0){ plep_enable_display(plep, display_enable); }else{ plep_disable_display(plep, display_enable); } exit(EXIT_SUCCESS); } if (do_enumerate_waveforms) { ret = enumerate_waveforms(plep); } else { struct epdoc_opt opt; plep_set_opt(plep, PLEP_SYNC_UPDATE, do_synchro); if (do_wait_power_off) plep_set_opt(plep, PLEP_WAIT_POWER_OFF, 1); if(do_partial_update){ plep_set_opt(plep, PLEP_PARTIAL, 1); } if(use_manual_temperature){ plep_set_opt(plep, PLEP_TEMPERATURE, 1); plep_set_hw_opt(plep, PLEP_TEMPERATURE, manual_temperature); }else{ plep_set_opt(plep, PLEP_TEMPERATURE_AUTO, 1); } opt.dither_mode = dither_mode; opt.keep_power_on = keep_power_on; opt.do_auto_rotate = do_auto_rotate; opt.rotation_angle = rotation_angle; opt.wfid = waveform_id; opt.offset.x = offset.x; opt.offset.y = offset.y; opt.align_h = align_h; opt.align_v = align_v; memcpy(&opt.crop, &crop, sizeof opt.crop); opt.doc_type = doc_type; opt.use_alternative_vsource = use_alternative_vsource; if(do_fill){ pldraw_fill_rect(pldraw, pldraw_get_grey(pldraw, fill_color), &crop); plep_update_screen(plep, opt.wfid); }else{ ret = show_contents(pldraw, file_names, n_files, &opt, pause_ms, do_infinite_loop, background); } } signal(SIGINT, sigint_original); pldraw_free(pldraw); plep_free(plep); exit((ret < 0) ? EXIT_FAILURE : EXIT_SUCCESS); error_pldraw: plep_free(plep); error_plep: exit(EXIT_FAILURE); }
int test_palette(struct pldraw *pldraw, char * const *opts, int opts_n) { struct plep *plep; static const int greys = 256; struct plep_rect rect; struct plep_rect area; int ret = 0; int cur_rotation; int xres; int yres; float x_grid, y_grid; int width; int tmp; int i; assert(pldraw != NULL); assert(g_initialised); plep = pldraw_get_plep(pldraw); plep_set_opt(plep, PLEP_SYNC_UPDATE, 1); xres = pldraw_get_xres(pldraw); yres = pldraw_get_yres(pldraw); cur_rotation = pldraw_get_rotation(pldraw); if (yres > xres) { const int new_rotation = cur_rotation + ((cur_rotation % 180) ? -90 : 90); pldraw_set_rotation(pldraw, new_rotation); xres = pldraw_get_xres(pldraw); yres = pldraw_get_yres(pldraw); } x_grid = xres / 24.0; y_grid = yres / 18.0; LOG("greyscale palettes"); area.a.x = x_grid * 0.5; area.a.y = y_grid * 0.5; area.b.x = x_grid * 23.5; area.b.y = y_grid * 3.0; width = area.b.x - area.a.x; memcpy(&rect, &area, sizeof rect); rect.b.x = rect.a.x; --rect.b.y; for (i = 0; i < width; ++i) { const int grey = i * greys / width; const pldraw_color_t col = pldraw_get_grey(pldraw, grey); pldraw_draw_line(pldraw, col, &rect); ++rect.a.x; ++rect.b.x; } draw_border(pldraw, g_black, &area); area.a.y = y_grid * 3.5; area.b.y = y_grid * 6.0; memcpy(&rect, &area, sizeof rect); for (i = 0; i < 16; ++i) { const int grey = pldraw_grey_16[i]; const pldraw_color_t col = pldraw_get_grey(pldraw, grey); rect.b.x = area.a.x + (width * (i + 1)) / 16; pldraw_fill_rect(pldraw, col, &rect); rect.a.x = rect.b.x; } draw_border(pldraw, g_black, &area); if (plep_update_screen(plep, g_clear_wf) < 0) ret = -1; LOG("primary and secondary colours"); width = x_grid * 24; width /= 90; width /= 2; width += 1; width *= 90; tmp = (x_grid * 21.5 - width) / 2; rect.a.x = x_grid * 0.5; rect.a.y = y_grid * 6.5; rect.b.x = x_grid * 0.5 + tmp; rect.b.y = y_grid * 9.5; pldraw_fill_rect(pldraw, g_red, &rect); rect.a.y = y_grid * 10.5; rect.b.y = y_grid * 13.5; pldraw_fill_rect(pldraw, g_green, &rect); rect.a.y = y_grid * 14.5; rect.b.y = y_grid * 17.5; pldraw_fill_rect(pldraw, g_blue, &rect); rect.a.x = x_grid * 1.5 + tmp; rect.a.y = y_grid * 6.5; rect.b.x = x_grid * 1.5 + (2 * tmp); rect.b.y = y_grid * 9.5; pldraw_fill_rect(pldraw, g_cyan, &rect); rect.a.y = y_grid * 10.5; rect.b.y = y_grid * 13.5; pldraw_fill_rect(pldraw, g_magenta, &rect); rect.a.y = y_grid * 14.5; rect.b.y = y_grid * 17.5; pldraw_fill_rect(pldraw, g_yellow, &rect); area.a.x = x_grid * 0.5; area.a.y = y_grid * 6.5; area.b.x = rect.b.x; area.b.y = y_grid * 17.5; if (plep_update(plep, &area, g_clear_wf) < 0) ret = -1; LOG("colour shades"); area.a.x = x_grid * 23.5 - width; area.a.y = y_grid * 6.5; area.b.x = x_grid * 23.5; area.b.y = y_grid * 17.5; i = 0; rect.a.x = area.a.x; rect.a.y = area.a.y; rect.b.y = area.b.y; for (i = 1; i <= 90; ++i) { const int r = pldraw_grey_16[get_shade(0, i)]; const int g = pldraw_grey_16[get_shade(30, i)]; const int b = pldraw_grey_16[get_shade(60, i)]; const pldraw_color_t col = pldraw_get_color(pldraw, r, g, b); rect.b.x = area.a.x + (width * i / 90); pldraw_fill_rect(pldraw, col, &rect); rect.a.x = rect.b.x; } if (plep_update(plep, &area, g_clear_wf) < 0) ret = -1; pldraw_set_rotation(pldraw, cur_rotation); return ret; }
int test_text(struct pldraw *pldraw, char * const *opts, int opts_n) { struct plep *plep; struct pldraw_pen pen; struct plep_point pt; float grid; assert(pldraw != NULL); plep = pldraw_get_plep(pldraw); grid = pldraw_get_xres(pldraw) / 12.0; pen.font = pldraw_fonts[0]; if (opts_n > 0) { if (pldraw_str2col(pldraw, &pen.foreground, opts[0]) < 0) return -1; } else { pen.foreground = pldraw_get_grey(pldraw, 0); } if (opts_n > 1) { if (pldraw_str2col(pldraw, &pen.background, opts[1]) < 0) return -1; } else { pen.background = pldraw_get_grey(pldraw, 192); } if (opts_n > 2) { const char *msg = opts[2]; struct plep_rect area; pt.x = grid; pt.y = grid; pldraw_draw_text(pldraw, &pen, &pt, msg); area.a.x = pt.x; area.a.y = pt.y; area.b.x = pt.x + (strlen(msg) * pen.font->width); area.b.y = pt.y + pen.font->height; if (plep_update(plep, &area, g_quick_wf) < 0) return -1; return 0; } plep_set_opt(plep, PLEP_SYNC_UPDATE, 1); pt.x = grid; pt.y = grid * 4.0; pldraw_draw_text(pldraw, &pen, &pt, "This is a long text in the middle of the screen."); if (plep_update_screen(plep, g_clear_wf) < 0) return -1; pt.x = grid; pt.y = grid * 6.0; pldraw_draw_text(pldraw, &pen, &pt, "Symbols: !\"[]$%^&*()+=\\/<>"); if (plep_update_screen(plep, g_clear_wf) < 0) return -1; pt.x = pldraw_get_xres(pldraw) - 30; pt.y = grid * 2.0; pldraw_draw_text(pldraw, &pen, &pt, "Edge"); if (plep_update_screen(plep, g_clear_wf) < 0) return -1; pt.x = grid; pt.y = pldraw_get_yres(pldraw) - 10; pldraw_draw_text(pldraw, &pen, &pt, "Bottom of the screen"); if (plep_update_screen(plep, g_clear_wf) < 0) return -1; return 0; }
int test_highlight(struct pldraw *pldraw, char * const *opts, int opts_n) { struct plep_rect area; struct pldraw_pen pen; struct plep *plep; int xres; int yres; int wfid; int grey; assert(pldraw != NULL); plep = pldraw_get_plep(pldraw); assert(plep != NULL); wfid = plep_get_wfid(plep, PLEP_HIGHLIGHT); if (wfid < 0) { LOG("highlight waveform not available"); return -1; } xres = pldraw_get_xres(pldraw); yres = pldraw_get_yres(pldraw); area.a.x = 0; area.b.x = xres; for (grey = 0; grey < 4; ++grey) { const uint8_t grey4 = pldraw_grey_4[grey]; const pldraw_color_t col = pldraw_get_grey(pldraw, grey4); area.a.y = grey * yres / 4; area.b.y = (grey + 1) * yres / 4; pldraw_fill_rect(pldraw, col, &area); } plep_set_opt(plep, PLEP_SYNC_UPDATE, 1); if (plep_update_screen(plep, g_clear_wf)) return -1; plep_set_opt(plep, PLEP_SYNC_UPDATE, 0); area.a.y = 0; area.b.y = pldraw_get_yres(pldraw); for (grey = 0; grey < 0x100; ++grey) { const pldraw_color_t col = pldraw_get_grey(pldraw, grey); area.a.x = grey * xres / 0x100; area.b.x = (grey + 1) * xres / 0x100; pldraw_fill_rect(pldraw, col, &area); } plep_set_opt(plep, PLEP_SYNC_UPDATE, 1); if (plep_update_screen(plep, wfid)) return -1; pen.font = pldraw_fonts[0]; pen.foreground = g_black; pen.background = g_white; for (grey = 0; grey < 16; ++grey) { char txt[4]; area.a.x = 1 + grey * xres / 16; area.a.y = yres - 20; area.b.x = 1 + (grey + 1) * xres / 16; area.b.y = yres; snprintf(txt, 4, "%d", (grey * 16)); pldraw_draw_text(pldraw, &pen, &area.a, txt); area.a.x -= 1; area.a.y = yres - 50; area.b.x = area.a.x; pldraw_draw_line(pldraw, g_black, &area); } area.a.x = 0; area.a.y = yres - 50; area.b.x = xres; area.b.y = yres; plep_update(plep, &area, g_clear_wf); return 0; }
int test_radar(struct pldraw *pldraw, char * const *opts, int opts_n) { enum quadrant_id { EDGE_TOP, EDGE_RIGHT, EDGE_BOTTOM, EDGE_LEFT, }; static const int PITCH = 10; const pldraw_color_t col_rgbw[] = { g_red, g_green, g_blue, g_white }; const int col_rgbw_n = ARRAY_SIZE(col_rgbw); struct plep *plep; __sighandler_t prev_sigint; struct plep_rect rect; struct plep_rect ep_area; struct plep_rect line; enum quadrant_id quad; pldraw_color_t draw_col = g_black; pldraw_color_t col; int col_rgbw_index = -1; unsigned long sleep_us; int wfid; int xres; int yres; int width; int height; int ret = 0; assert(pldraw != NULL); assert(g_initialised); if (opts_n > 0) { unsigned long sleep_ms; if (str2ul(&sleep_ms, opts[0]) < 0) { LOG("Invalid sleep value: %s", opts[0]); return -1; } sleep_us = sleep_ms * 1000; } else { sleep_us = 10000; } if (opts_n > 1) { const char *col_str = opts[1]; if (!strcmp(col_str, "rgbw")) { col_rgbw_index = 0; } else if (pldraw_str2col(pldraw, &draw_col, col_str) < 0) { return -1; } } if (!pldraw_colcmp(pldraw, col, g_black) && (pldraw_get_cfa(pldraw) == PLDRAW_CFA_NONE)) { wfid = g_clear_wf; } else { wfid = g_quick_wf; } plep = pldraw_get_plep(pldraw); xres = pldraw_get_xres(pldraw); yres = pldraw_get_yres(pldraw); width = ((xres / PITCH) - 2) * PITCH; height = ((yres / PITCH) - 2) * PITCH; rect.a.x = (xres - width) / 2; rect.a.y = (yres - height) / 2; rect.b.x = rect.a.x + width; rect.b.y = rect.a.y + height; LOG("rectangle: (%i, %i, %i, %i)", rect.a.x, rect.a.y, rect.b.x, rect.b.y); draw_border(pldraw, draw_col, &rect); if (plep_update(plep, &rect, g_clear_wf) < 0) ret = -1; plep_set_opt(plep, PLEP_SYNC_UPDATE, 0); plep_set_opt(plep, PLEP_PARTIAL, 1); ++rect.a.x; ++rect.a.y; --rect.b.x; --rect.b.y; memcpy(&ep_area, &rect, sizeof ep_area); --rect.b.x; --rect.b.y; line.a.x = (rect.a.x + rect.b.x) / 2; line.a.y = (rect.a.y + rect.b.y) / 2; line.b.x = rect.a.x; line.b.y = rect.a.y; if (col_rgbw_index < 0) col = draw_col; else col = col_rgbw[0]; prev_sigint = signal(SIGINT, sigint_stop); quad = EDGE_TOP; g_run = 1; LOG("Press Ctrl-C to stop"); while (!ret && g_run) { pldraw_draw_line(pldraw, col, &line); if (plep_update(plep, &ep_area, wfid) < 0) { ret = -1; break; } switch (quad) { case EDGE_TOP: line.b.x += PITCH; if (line.b.x >= rect.b.x) { line.b.x = rect.b.x; quad = EDGE_RIGHT; } break; case EDGE_RIGHT: line.b.y += PITCH; if (line.b.y >= rect.b.y) { line.b.y = rect.b.y; quad = EDGE_BOTTOM; } break; case EDGE_BOTTOM: line.b.x -= PITCH; if (line.b.x <= rect.a.x) { line.b.x = rect.a.x; quad = EDGE_LEFT; } break; case EDGE_LEFT: line.b.y -= PITCH; if (line.b.y <= rect.a.y) { line.b.y = rect.a.y; quad = EDGE_TOP; if (col_rgbw_index < 0) { col = pldraw_colcmp( pldraw, col, draw_col) ? draw_col : g_white; } else { if (++col_rgbw_index == col_rgbw_n) col_rgbw_index = 0; col = col_rgbw[col_rgbw_index]; } } break; } usleep(sleep_us); } signal(SIGINT, prev_sigint); plep_set_opt(plep, PLEP_PARTIAL, 0); return ret; }
int test_regions(struct pldraw *pldraw, char * const *opts, int opts_n) { struct plep *plep; struct plep_rect rect; int delta_wf; pldraw_color_t col; int ret = 0; assert(pldraw != NULL); assert(g_initialised); plep = pldraw_get_plep(pldraw); if (plep == NULL) { delta_wf = 0; } else { delta_wf = plep_get_wfid(plep, PLEP_DELTA); if (delta_wf < 0) delta_wf = g_clear_wf; } plep_set_opt(plep, PLEP_SYNC_UPDATE, 0); LOG("black frame"); rect.a.x = 50; rect.a.y = 350; rect.b.x = 100; rect.b.y = 550; pldraw_fill_rect(pldraw, g_black, &rect); if (plep_update(plep, &rect, g_quick_wf) < 0) ret = -1; rect.a.x += 300; rect.b.x += 300; pldraw_fill_rect(pldraw, g_black, &rect); if (plep_update(plep, &rect, g_quick_wf) < 0) ret = -1; rect.a.x = 100; rect.a.y = 350; rect.b.x = 350; rect.b.y = 400; pldraw_fill_rect(pldraw, g_black, &rect); if (plep_update(plep, &rect, g_quick_wf) < 0) ret = -1; rect.a.y += 150; rect.b.y += 150; pldraw_fill_rect(pldraw, g_black, &rect); if (plep_update(plep, &rect, g_quick_wf) < 0) ret = -1; LOG("grey rectangles"); col = pldraw_get_grey(pldraw, 0x80); rect.a.x = 50; rect.a.y = 50; rect.b.x = 200; rect.b.y = 100; pldraw_fill_rect(pldraw, col, &rect); if (plep_update(plep, &rect, delta_wf) < 0) ret = -1; rect.a.y += 100; rect.b.y += 100; pldraw_fill_rect(pldraw, col, &rect); if (plep_update(plep, &rect, delta_wf) < 0) ret = -1; rect.a.y += 100; rect.b.y += 100; pldraw_fill_rect(pldraw, col, &rect); if (plep_update(plep, &rect, delta_wf) < 0) ret = -1; rect.a.x += 200; rect.b.x += 200; pldraw_fill_rect(pldraw, col, &rect); if (plep_update(plep, &rect, delta_wf) < 0) ret = -1; rect.a.y -= 100; rect.b.y -= 100; pldraw_fill_rect(pldraw, col, &rect); if (plep_update(plep, &rect, delta_wf) < 0) ret = -1; rect.a.y -= 100; rect.b.y -= 100; pldraw_fill_rect(pldraw, col, &rect); if (plep_update(plep, &rect, delta_wf) < 0) ret = -1; return ret; }
static void draw_checkerboard(struct pldraw *pldraw, const struct plep_point *origin, size_t dim, int vertical, int n, int m, pldraw_color_t icolor) { struct plep_rect square; int i, j; pldraw_color_t color = icolor; square.a.x = origin->x; square.a.y = origin->y; square.b.x = origin->x + dim; square.b.y = origin->y + dim; for (j = 0; j < m; ++j) { const struct plep_point line = { .x = square.a.x, .y = square.a.y }; const pldraw_color_t line_color = color; for (i = 0; i < n; ++i) { pldraw_fill_rect(pldraw, color, &square); color = pldraw_colcmp(pldraw, color, icolor) ? icolor : g_white; if (vertical) { square.a.y += dim; square.b.y += dim; } else { square.a.x += dim; square.b.x += dim; } } color = pldraw_colcmp(pldraw, line_color, icolor) ? icolor : g_white; if (vertical) { square.a.x = line.x + dim; square.a.y = line.y; } else { square.a.x = line.x; square.a.y = line.y + dim; } square.b.x = square.a.x + dim; square.b.y = square.a.y + dim; } } static void draw_stripes(struct pldraw *pldraw, pldraw_color_t col, unsigned long width) { struct plep_rect coords; const int yres = pldraw_get_yres(pldraw); int y; coords.a.x = 0; coords.b.x = pldraw_get_xres(pldraw); for (y = 0; y < yres; ++y) { coords.a.y = coords.b.y = y; pldraw_draw_line(pldraw, col, &coords); if (!(y % width)) { col = pldraw_colcmp(pldraw, col, g_black) ? g_black : g_white; } } } static void draw_border(struct pldraw *pldraw, pldraw_color_t col, const struct plep_rect *rect) { struct plep_rect line; /* top */ line.a.x = rect->a.x; line.a.y = rect->a.y; line.b.x = rect->b.x - 1; line.b.y = rect->a.y; pldraw_draw_line(pldraw, col, &line); /* bottom */ line.a.y = rect->b.y - 1; line.b.y = rect->b.y - 1; pldraw_draw_line(pldraw, col, &line); /* left */ line.b.x = rect->a.x; line.b.y = rect->a.y; pldraw_draw_line(pldraw, col, &line); /* right */ line.a.x = rect->b.x - 1; line.b.x = rect->b.x - 1; pldraw_draw_line(pldraw, col, &line); } static int slide_square(struct pldraw *pldraw, const char *wf_type, const char *wf_opt) { const int xres = pldraw_get_xres(pldraw); const int yres = pldraw_get_yres(pldraw); struct plep *plep = pldraw_get_plep(pldraw); struct plep_rect square; int wfid; int dim; wfid = plep_get_wfid_split(plep, wf_type, PLEP_MONO, wf_opt); if (wfid < 0) { LOG("Waveform not found: %s/mono/%s", wf_type, wf_opt); return -1; } plep_set_opt(plep, PLEP_SYNC_UPDATE, 1); pldraw_fill_screen(pldraw, g_white); plep_update_screen(plep, g_clear_wf); plep_set_opt(plep, PLEP_SYNC_UPDATE, 0); usleep(500000); dim = xres / 8; square.a.x = 0; square.a.y = 0; square.b.x = dim; square.b.y = dim; while (square.b.x <= xres) { pldraw_fill_rect(pldraw, g_black, &square); plep_update(plep, &square, wfid); square.a.x += dim; square.b.x += dim; usleep(80000); } dim = yres / 8; square.a.x = 0; square.a.y = 0; square.b.x = dim; square.b.y = dim; while (square.b.y <= yres) { pldraw_fill_rect(pldraw, g_black, &square); plep_update(plep, &square, wfid); square.a.y += dim; square.b.y += dim; usleep(80000); } usleep(500000); return 0; } static void sigint_stop(int signum) { if (signum == SIGINT) { LOG("STOP"); g_run = 0; } } static int str2ul(unsigned long *out, const char *str) { errno = 0; *out = strtoul(str, NULL, 10); return errno ? -1 : 0; }
int main(int argc, char **argv) { static const char OPTIONS[] = "hvlpsjr:g:f::Ww:m:d:e:b:t:o:a:c:O:"; __sighandler_t sigint_original; char * const *file_names = NULL; size_t n_files = 0; const char *waveform_id_str = NULL; int waveform_id; int do_enumerate_waveforms = 0; int do_log_info = 0; int do_wait_power_off = 0; int do_synchro = 0; int do_infinite_loop = 0; int cfa = -1; int do_auto_rotate = 0; int rotation_angle = -1; unsigned long pause_ms = 2000; const char *mode = NULL; const char *fbdev = NULL; const char *epdev = NULL; const char *background = NULL; struct plep_point offset = { 0, 0 }; enum epdoc_align_h align_h = EPDOC_ALIGN_H_NONE; enum epdoc_align_v align_v = EPDOC_ALIGN_V_NONE; struct plep_rect crop = { { 0, 0 }, { INT_MAX, INT_MAX } }; const char *doc_type = NULL; const char *conf_file = NULL; struct plep *plep; struct pldraw *pldraw; int c; int ret; while ((c = getopt(argc, argv, OPTIONS)) != -1) { switch (c) { case 'h': print_usage(); exit(EXIT_SUCCESS); break; case 'v': printf("%s v%s - %s\n%s\n%s\n", APP_NAME, VERSION, DESCRIPTION, COPYRIGHT, LICENSE); exit(EXIT_SUCCESS); break; case 'l': do_log_info = 1; break; case 'p': do_wait_power_off = 1; break; case 's': do_synchro = 1; break; case 'j': do_infinite_loop = 1; break; case 'r': if (!strcmp(optarg, "auto")) { do_auto_rotate = 1; } else { unsigned long raw_angle; if (str2ul(optarg, &raw_angle) < 0) { LOG("failed to parse rotation angle"); print_usage(); exit(EXIT_FAILURE); } if ((raw_angle > 270) || (raw_angle % 90)) { LOG("invalid rotation angle"); print_usage(); exit(EXIT_FAILURE); } rotation_angle = raw_angle; } break; case 'g': if (str2ul(optarg, &pause_ms) < 0) { LOG("failed to parse pause duration"); print_usage(); exit(EXIT_FAILURE); } break; case 'f': if (optarg == NULL) { cfa = PLDRAW_CFA_GR_BW; } else { cfa = pldraw_get_cfa_id(optarg); if (cfa < 0) { LOG("Invalid CFA identifier: %s", optarg); print_usage(); exit(EXIT_FAILURE); } } break; case 'W': do_enumerate_waveforms = 1; break; case 'w': waveform_id_str = optarg; break; case 'm': mode = optarg; break; case 'd': fbdev = optarg; break; case 'e': epdev = optarg; break; case 'b': background = optarg; break; case 't': doc_type = optarg; break; case 'o': if (parse_offset(&offset, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'a': if (parse_alignment(&align_h, &align_v, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'c': if (parse_crop(&crop, optarg) < 0) { print_usage(); exit(EXIT_FAILURE); } break; case 'O': conf_file = optarg; if (access(conf_file, F_OK)) { LOG_ERRNO("Configuration file"); exit(EXIT_FAILURE); } break; case '?': default: LOG("Invalid arguments"); print_usage(); exit(EXIT_FAILURE); break; } } if (optind < argc) { file_names = &argv[optind]; n_files = argc - optind; } LOG("%s v%s", APP_NAME, VERSION); plep = plep_init(epdev, mode, conf_file); if (plep == NULL) { LOG("failed to initialise ePDC"); goto error_plep; } pldraw = pldraw_init(fbdev, conf_file); if (pldraw == NULL) { LOG("failed to initialise pldraw"); goto error_pldraw; } pldraw_set_plep(pldraw, plep); waveform_id = plep_get_wfid(plep, waveform_id_str); if (waveform_id < 0) { LOG("Invalid waveform path: %s", waveform_id_str); goto error_pldraw; } if (cfa >= 0) pldraw_set_cfa(pldraw, cfa); else cfa = pldraw_get_cfa(pldraw); if (cfa != PLDRAW_CFA_NONE) LOG("CFA: %s", pldraw_cfa_name[cfa]); if (rotation_angle < 0) rotation_angle = pldraw_get_rotation(pldraw); if (rotation_angle) LOG("rotation: %d", rotation_angle); if (do_log_info) pldraw_log_info(pldraw); sigint_original = signal(SIGINT, sigint_abort); if (do_enumerate_waveforms) { ret = enumerate_waveforms(plep); } else { struct epdoc_opt opt; plep_set_opt(plep, PLEP_SYNC_UPDATE, do_synchro); if (do_wait_power_off) plep_set_opt(plep, PLEP_WAIT_POWER_OFF, 1); opt.do_auto_rotate = do_auto_rotate; opt.rotation_angle = rotation_angle; opt.wfid = waveform_id; opt.offset.x = offset.x; opt.offset.y = offset.y; opt.align_h = align_h; opt.align_v = align_v; memcpy(&opt.crop, &crop, sizeof opt.crop); opt.doc_type = doc_type; ret = show_contents(pldraw, file_names, n_files, &opt, pause_ms, do_infinite_loop, background); } signal(SIGINT, sigint_original); pldraw_free(pldraw); plep_free(plep); exit((ret < 0) ? EXIT_FAILURE : EXIT_SUCCESS); error_pldraw: plep_free(plep); error_plep: exit(EXIT_FAILURE); }