int ShellCmdArgInt::operator()(const char * & arg, CmdLine & cmd) { CmdArgInt int_arg(*this); const char * save_arg = arg; int badval = int_arg(arg, cmd); if (save_arg && !badval) set(save_arg); return badval; }
/* * ESC * r <code> U * * Simple color space command. Note that all the simple color spaces are * variations of the RGB/CMY device-specific color space. */ static int pcl_simple_color_space(pcl_args_t * pargs, pcl_state_t * pcs) { if (pcs->personality == pcl5e || pcs->raster_state.graphics_mode) return 0; return set_simple_color_mode(int_arg(pargs), pcs); }
/* * ESC % <enum> B */ static int rtl_enter_hpgl_mode( pcl_args_t * pargs, pcl_state_t * pcs ) { int i = int_arg(pargs); /* Note: -1..3 for PCL5c, 0..1 for PCL5 */ if (i < 0) i = -1; else if (i > 3) return 0; hpgl_call_mem(pcs->memory, hpgl_clear_current_path(pcs)); pcs->parse_other = ( int (*)( void *, pcl_state_t *, stream_cursor_read * ) ) hpgl_process; /* add the pcl cap to hpgl/2's path */ if (i == 1) { gs_point pcl_pt; pcl_pt.x = (hpgl_real_t)pcs->cap.x; pcl_pt.y = (hpgl_real_t)pcs->cap.y; hpgl_add_pcl_point_to_path(pcs, &pcl_pt); hpgl_update_carriage_return_pos(pcs); } hpgl_call_mem(pcs->memory, hpgl_set_ctm(pcs)); return 0; }
static int /* ESC & u <upi> B */ pcl_set_unit_of_measure(pcl_args_t *pargs, pcl_state_t *pcs) { int num = int_arg(pargs); if ( num <= 96 ) num = 96; else if ( num >= 7200 ) num = 7200; else if ( 7200 % num != 0 ) { /* Pick the exact divisor of 7200 with the smallest */ /* relative error. */ static const int values[] = { 96, 100, 120, 144, 150, 160, 180, 200, 225, 240, 288, 300, 360, 400, 450, 480, 600, 720, 800, 900, 1200, 1440, 1800, 2400, 3600, 7200 }; const int *p = values; while ( num > p[1] ) p++; /* Now *p < num < p[1]. */ if ( (p[1] - (float)num) / p[1] < ((float)num - *p) / *p ) p++; num = *p; } pcs->uom_cp = pcl_coord_scale / num; return 0; }
static int /* ESC & l <num_copies> X */ pcl_number_of_copies(pcl_args_t *pargs, pcl_state_t *pcs) { int i = int_arg(pargs); if ( i < 1 ) return 0; pcs->num_copies = i; return put_param1_int(pcs, "NumCopies", i); }
static int /* ESC % -12345 X */ pcl_exit_language(pcl_args_t *pargs, pcl_state_t *pcs) { if ( int_arg(pargs) != -12345 ) return e_Range; { int code = pcl_printer_reset(pargs, pcs); return (code < 0 ? code : e_ExitLanguage); } }
static int /* ESC & l 1 T */ pcl_job_separation(pcl_args_t *pargs, pcl_state_t *pcs) { int i = int_arg(pargs); if ( i != 1 ) return 0; /**** NEED A DRIVER PROCEDURE FOR END-OF-JOB ****/ return 0; }
static int /* ESC & l <sd_enum> S */ pcl_simplex_duplex_print(pcl_args_t *pargs, pcl_state_t *pcs) { int code; bool reopen = false; /* oddly the command goes to the next page irrespective of arguments */ code = pcl_end_page_if_marked(pcs); if ( code < 0 ) return code; pcl_home_cursor(pcs); switch ( int_arg(pargs) ) { case 0: pcs->duplex = false; break; case 1: pcs->duplex = true; pcs->bind_short_edge = false; break; case 2: pcs->duplex = true; pcs->bind_short_edge = true; break; default: return 0; } code = put_param1_bool(pcs, "Duplex", pcs->duplex); switch ( code ) { case 1: /* reopen device */ reopen = true; case 0: break; case gs_error_undefined: return 0; default: /* error */ if ( code < 0 ) return code; } code = put_param1_bool(pcs, "BindShortEdge", pcs->bind_short_edge); switch ( code ) { case 1: /* reopen device */ reopen = true; case 0: case gs_error_undefined: break; default: /* error */ if ( code < 0 ) return code; } return (reopen ? gs_setdevice_no_erase(pcs->pgs, gs_currentdevice(pcs->pgs)) : 0); }
/* * (From PCL5 Comparison Guide, p. 1-99) * * ESC * o <quality> Q * * Set print quality. */ static int pcl_print_quality(pcl_args_t * pargs, pcl_state_t * pcs) { int quality = int_arg(pargs); if ((quality >= -1) && (quality <= 1)) { int code = pcl_end_page_if_marked(pcs); if (code >= 0) pcl_home_cursor(pcs); return (code < 0 ? code : 0); } else return e_Range; }
/* * ESC & a <bool> N */ static int pcl_negative_motion( pcl_args_t * pargs, pcl_state_t * pcs ) { int motion = int_arg(pargs); if (motion > 1) return e_Range; /* Currently we can't take any advantage of this.... */ return 0; }
FILE *open_file(NODE *arg, char *access) { char *fnstr; FILE *tstrm; char *old_stringptr = print_stringptr; int old_stringlen = print_stringlen; if (is_list(arg)) { /* print to string */ if (*access != 'w') { err_logo(BAD_DATA_UNREC, arg); return NULL; } else { FIXNUM i = int_arg(cdr(arg)); if (NOT_THROWING && i > 0 && cddr(arg) == NIL) { char *tmp = (char *)malloc(i); *tmp = '\0'; return (FILE *)tmp; } err_logo(BAD_DATA_UNREC, car(arg)); return NULL; } } arg = cnv_node_to_strnode(arg); if (arg == UNBOUND) return(NULL); if (file_prefix != NIL) { print_stringlen = getstrlen(file_prefix) + getstrlen(arg) + 2; fnstr = (char *)malloc((size_t)print_stringlen + 1); } else fnstr = (char *) malloc((size_t)getstrlen(arg) + 1); if (fnstr == NULL) { err_logo(FILE_ERROR, make_static_strnode(message_texts[MEM_LOW])); print_stringptr = old_stringptr; print_stringlen = old_stringlen; return NULL; } if (file_prefix != NIL) { print_stringptr = fnstr; ndprintf((FILE *)NULL, "%p%t%p", file_prefix, separator, arg); *print_stringptr = '\0'; print_stringptr = old_stringptr; print_stringlen = old_stringlen; } else noparity_strnzcpy(fnstr, getstrptr(arg), getstrlen(arg)); tstrm = fopen(fnstr, access); free(fnstr); return(tstrm); }
NODE *lsetwrite(NODE *arg) { FILE *tmp; NODE *margs; if (writestream == NULL) { /* Any setwrite finishes earlier write to string */ *print_stringptr = '\0'; writestream = stdout; if (find_file(writer_name, FALSE) == NULL) { /* pre-5.4 compatibility mode, implicitly close string */ margs = cons(car(writer_name), cons(make_strnode(write_buf, NULL, strlen(write_buf), STRING, strnzcpy), NIL)); lmake(margs); free(write_buf); } writer_name = NIL; } if (car(arg) == NIL) { writestream = stdout; writer_name = NIL; } else if (is_list(car(arg))) { /* print to string */ FIXNUM i = int_arg(cdar(arg)); if ((tmp = find_file(car(arg), FALSE)) != NULL) { writestream = NULL; writer_name = car(arg); print_stringptr = (char *)tmp + strlen((char *)tmp); print_stringlen = i - strlen((char *)tmp); } else if (NOT_THROWING && i > 0 && cddr(car(arg)) == NIL) { writestream = NULL; writer_name = copy_list(car(arg)); print_stringptr = write_buf = (char *)malloc(i); print_stringlen = i; } else err_logo(BAD_DATA_UNREC, car(arg)); } else if ((tmp = find_file(car(arg), FALSE)) != NULL) { writestream = tmp; writer_name = car(arg); } else err_logo(NOT_OPEN_ERROR, car(arg)); return(UNBOUND); }
/* * We export this so we can call it from HP-GL/2 configurations. * Note that it returns 1 iff it changed the PCL CAP. * * ESC % <enum> A */ int rtl_enter_pcl_mode( pcl_args_t * pargs, pcl_state_t * pcs ) { int b = int_arg(pargs) & 1; if ( pcs->parse_other == (int(*)(void *, pcl_state_t *, stream_cursor_read *))hpgl_process ) { /* * We were in HP-GL/2 mode. Destroy the gl/2 polygon path * and conditionally copy back the cursor position. */ if (b != 0) { /* the usual user -> device -> user dance. */ gs_point pt, dev_pt; hpgl_call_mem(pcs->memory, hpgl_set_ctm(pcs)); hpgl_call_mem(pcs->memory, hpgl_get_current_position(pcs, &pt)); hpgl_call_mem(pcs->memory, gs_transform(pcs->pgs, pt.x, pt.y, &dev_pt)); hpgl_call_mem(pcs->memory, pcl_set_ctm(pcs, true)); hpgl_call_mem(pcs->memory, gs_itransform(pcs->pgs, dev_pt.x, dev_pt.y, &pt)); /* HPGL/2 uses floats for coordinates */ #define round(x) (((x) < 0.0) ? (ceil ((x) - 0.5)) : (floor ((x) + 0.5))) pcs->cap.x = round(pt.x); pcs->cap.y = round(pt.y); #undef round } } else b = 0; pcs->parse_other = 0; return b; /* not 0, see comment above */ }
int main(int argc, char *argv[]) { if (eval_flag(argc,argv,"-h\0")) { printf("Usage: lold [-p PORT] [-D DELAY] [-d DEVICE]\n\n"); return EXIT_FAILURE; } delay = int_arg(eval_arg(argc, argv, "-D\0", NULL), DEF_DELAY); port = int_arg(eval_arg(argc, argv, "-p\0", NULL), DEF_LOLD_PORT); device = eval_arg(argc, argv, "-d\0", NULL); to_stdout = eval_flag(argc, argv, "--stdout\0"); if (!to_stdout && device==NULL) //no device provided? device = autodetect(); if (!device && !to_stdout) //no device found by autodetect? fprintf(stderr, "No serial USB device found! (Try -d flag?) Output to stdout.\n"); pthread_mutex_init(&imutex, NULL); //init mutex for interrupted flag pthread_mutex_init(&qmutex, NULL); //init mutex for queue //Start web server thread listening for clients sending stuff pthread_t serverThread; pthread_create(&serverThread, NULL, server_thread, NULL); pthread_detach(serverThread); //trap INT signal(SIGINT, sig_handler); LolTask *currtask = NULL; //task currently being executed //clean lolshield render_frame(device, EMPTY_FRAME); //loop outputting animation frames to device while (!shutting_down) { //do nothing if some client is streaming if (streaming) { sleep_ms(100); continue; } //New task arrived -> check stuff pthread_mutex_lock(&imutex); if (interrupted) { interrupted = 0; if (DEBUG) fprintf(stderr, "New task inserted!\n"); if (queue==NULL) exit(EXIT_FAILURE); //can not happen! pthread_mutex_lock(&qmutex); LolTask *first = (LolTask*)(queue->value); pthread_mutex_unlock(&qmutex); //new arrived has higher priority? cancel current ani if (currtask != NULL && first->pri > currtask->pri) { loltask_free(currtask); currtask = NULL; if (DEBUG) fprintf(stderr, "Ani cancelled\n"); } } pthread_mutex_unlock(&imutex); //load new task if neccessary if (currtask == NULL) { pthread_mutex_lock(&qmutex); currtask = lollist_shift(&queue); pthread_mutex_unlock(&qmutex); if (DEBUG) if (currtask != NULL) fprintf(stderr, "Ani start\n"); } //nothing in queue -> just wait if (currtask == NULL) { sleep_ms(delay); continue; } //animation delay sleep_ms(currtask->delay); //get next frame char *frame = lollist_shift(&(currtask->frames)); //current animation done? if (frame == NULL) { currtask = NULL; clean_tasks(); //remove aged tasks //render empty frame to clean lolshield -> breaks hardware text message //render_frame(device, EMPTY_FRAME); sleep_ms(delay); if (DEBUG) fprintf(stderr, "Ani done\n"); continue; } //render next frame render_frame(device, frame); free(frame); } if (DEBUG) fprintf(stderr, "Shutting down\n"); //shutting down render_frame(device, EMPTY_FRAME); //clean lolshield serialport_close(port); //close port pthread_cancel(serverThread); //kill server pthread_mutex_destroy(&qmutex); //uninit mutex pthread_mutex_destroy(&imutex); //uninit mutex close(svr_sock); //close server listening socket pthread_exit(NULL); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { if (argc==1) { printf("Usage: lolplay OPTIONS [-A|-P] [FILE (if not stdin)]\n"); printf(" lolplay OPTIONS [-m|-M] \"message\"\n"); printf(" lolplay OPTIONS -b VALUE\n"); printf(" lolplay OPTIONS -t\n"); printf("FLAGS:\n"); printf(" -h: lold host, default: %s\n", DEF_LOLD_HOST); printf(" -p: lold port, default: %i\n", DEF_LOLD_PORT); printf("\n"); printf(" -D: Frame delay (20-1000), default: %i\n", DEF_DELAY); printf(" -T: TTL in sec (0-600), default: %i\n", DEF_TTL); printf(" -C: Channel/Priority (>=0), default: %i\n", DEF_PRI); printf("\n"); printf(" -A: File is in AsciiFrame format (monochrome)\n"); printf(" -P: File is PDE sketch file from Lol Shield Theatre Homepage\n"); printf(" -R: File is raw animation data (as sent to sketch)\n"); printf("\n"); printf(" -m: Send scrolling text message (pre-rendered)\n"); printf(" -M: Send scrolling text message (rendered on Lol Shield)\n"); printf("\n"); printf(" -b: Set maximum brightness (1-7)\n"); printf(" -t: Toggle Lolshield mode (loop ROM or pass through mode)\n"); printf("\n"); printf(" -B: with '-[mAPR]' - burn this animation to Lolshield ROM\n"); printf(" -g: with '-A' - render in grayscale (not with '-B' !)\n"); printf(" -o: added to any command - output raw frames to stdout, no sending\n"); printf("\n"); exit(EXIT_FAILURE); } int del = int_arg(eval_arg(argc, argv, "-D\0", NULL), DEF_DELAY); int ttl = int_arg(eval_arg(argc, argv, "-T\0", NULL), DEF_TTL); int pri = int_arg(eval_arg(argc, argv, "-C\0", NULL), DEF_PRI); int port = int_arg(eval_arg(argc, argv, "-p\0", NULL), DEF_LOLD_PORT); char *host = eval_arg(argc, argv, "-h\0", DEF_LOLD_HOST); int bflag = eval_flag(argc, argv, "-b\0"); int gflag = eval_flag(argc, argv, "-g\0"); int oflag = eval_flag(argc, argv, "-o\0"); int tflag = eval_flag(argc, argv, "-t\0"); int burnFlag = eval_flag(argc, argv, "-B\0"); int mFlag = eval_flag(argc, argv, "-m\0"); int MFlag = eval_flag(argc, argv, "-M\0"); int aniType = 0; //Initialize loltask LolTask *task = loltask_new(); task->delay = burnFlag ? 100 : del; task->ttl = ttl; task->pri = pri; if (tflag) { //just toggle char *frame = malloc(100*sizeof(char)); frame[0] = '\0'; snprintf(frame, 100, "16384,0,0,0,0,0,0,0,0"); task->frames = lollist_add(task->frames, frame); goto send; } else if (bflag) { //just set brightness char *val = eval_arg(argc, argv, "-b\0", NULL); char *frame = malloc(100*sizeof(char)); frame[0] = '\0'; snprintf(frame, 100, "16387,%s",val); task->frames = lollist_add(task->frames, frame); goto send; } if (mFlag) { //software text message char *msg = eval_arg(argc, argv, "-m\0", NULL); if (msg == NULL) { printf("No message passed!\n"); exit(EXIT_FAILURE); } //create lolfactory, generate banner LolFactory *fac = lolfac_new(); int len = strlen(msg); lolfac_banner(fac, len, msg); //free lolfactory rescuing frames LolList *frames = fac->frames; fac->frames = NULL; lolfac_free(fac); //fill loltask with frames task->frames = frames; } else if (MFlag) { char *msg = eval_arg(argc, argv, "-M\0", NULL); char *frame = malloc(100*sizeof(char)); frame[0] = '\0'; snprintf(frame, BUFSIZE-1, "16385,%i,0,%s", del, msg); task->frames = lollist_add(task->frames, frame); } else { //animation file //open file char *filename = argv[argc-1]; FILE *fp = fopen(filename, "r"); if (fp == NULL) { // exit(EXIT_FAILURE); //failed opening file fp = stdin; //use standard input if no file given } char *line = NULL; size_t len = 0; ssize_t read; //read lines LolList *lines = NULL; while ((read = getline(&line, &len, fp)) != -1) { lines = lollist_add(lines, line); line = NULL; } if (eval_flag(argc, argv, "-R\0")) //raw data aniType = 1; if (eval_flag(argc, argv, "-A\0")) //ascii frames aniType = 2; else if (eval_flag(argc, argv, "-P\0")) //PDE sketch aniType = 3; if (aniType==1) { //raw LolList *curr = lines; while (curr!=NULL) { char *str = curr->value; len = strlen(str); if (str[len-1] == '\n') str[len-1] = '\0'; curr = curr->next; } task->frames = lines; } else if (aniType==2) { //ascii task->frames = ascii2frames(lines, gflag); } else if (aniType==3) { //pde task->delay = get_delay_from_pde(lines); task->frames = pde2frames(lines); } else { printf("No valid type selected!\n"); exit(EXIT_FAILURE); } } //burn flag set if (burnFlag) { if (gflag) { printf("Can not burn grayscale animation!\n"); exit(EXIT_FAILURE); } //check message length int cnt = 0; LolList *curr = task->frames; while (curr!=NULL) { curr = curr->next; cnt++; if (cnt>56) { printf("Message too long to store (max. frames: 56)!\n"); exit(EXIT_FAILURE); } } //TODO: check invalid stuff which can not be recorded (all non-regular frames) //prepend and append recording signal commands (start/stop recording) char *frame = malloc(100*sizeof(char)); snprintf(frame, 100, "16384,1,%i,0,0,0,0,0,0", del); lollist_insert(&task->frames, task->frames, frame); frame = malloc(100*sizeof(char)); snprintf(frame, 100, "16384,0,0,0,0,0,0,0,0"); lollist_add(task->frames, frame); } send: //append clearing frame if animation from file if (aniType) { char *frame = malloc(100*sizeof(char)); snprintf(frame, 100, "0,0,0,0,0,0,0,0,0"); lollist_add(task->frames, frame); } //output flag set - no sending, but output if (oflag) { LolList *curr = task->frames; while (curr!=NULL) { printf("%s\n", (char*)curr->value); curr = curr->next; } loltask_free(task); return EXIT_SUCCESS; } //try to send if (!loltask_send(host, port, task)) //error sending exit(EXIT_FAILURE); //done loltask_free(task); return EXIT_SUCCESS; }