int jd11_select_image(GPPort *port,int nr) { /* select image <nr> */ unsigned short xcmd; _send_cmd(port,0xffa1); _send_cmd(port,0xff00|nr); _read_cmd(port,&xcmd); if (xcmd != 0xff01) return GP_ERROR_IO; return GP_OK; }
int jd11_set_bulb_exposure(GPPort *port,int i) { unsigned short xcmd; if ((i<1) || (i>9)) return GP_ERROR_BAD_PARAMETERS; _send_cmd(port,0xffa9); _send_cmd(port,0xff00|i); _read_cmd(port,&xcmd); return GP_OK; }
static void cmd_TestDRAM(GPPort *port) { unsigned short xcmd; _send_cmd(port,0xff72); _read_cmd(port,&xcmd); fprintf(stderr,"TestDRAM: done.\n"); }
/* doesn't actually flash */ static void cmd_TestFLASH(GPPort *port) { unsigned short xcmd; _send_cmd(port,0xff73); _read_cmd(port,&xcmd); fprintf(stderr,"TestFLASH: xcmd = %x.\n",xcmd); }
/* some kind of selftest ... shuts the shutters, beeps... only stops by * powercycle. */ static void cmd_79(GPPort *port) { unsigned short xcmd; _send_cmd(port,0xff79); _read_cmd(port,&xcmd); fprintf(stderr,"79: done, xcmd =%x\n",xcmd); }
static void _event_cb(const struct libvlc_event_t *ev, void *data) { struct _App *app = data; int thread_event; switch (ev->type) { case libvlc_MediaPlayerTimeChanged: _send_time_changed(app, ev); break; case libvlc_MediaPlayerPositionChanged: thread_event = EM_THREAD_POSITION_CHANGED; write(app->fd_write, &thread_event, sizeof(thread_event)); break; case libvlc_MediaPlayerLengthChanged: _send_length_changed(app, ev); break; case libvlc_MediaPlayerSeekableChanged: _send_seekable_changed(app, ev); break; case libvlc_MediaPlayerPlaying: _send_resize(app, app->w, app->h); break; case libvlc_MediaPlayerStopped: _send_file_set(app); break; case libvlc_MediaPlayerEndReached: _send_cmd(app, EM_RESULT_PLAYBACK_STOPPED); break; } }
static void _send_file_closed(struct _App *app) { app->closing = 0; emotion_generic_shm_free(app->vs); _send_cmd(app, EM_RESULT_FILE_CLOSE); }
static void jd11_TestADC(GPPort *port) { unsigned short xcmd; _send_cmd(port,0xff75); _read_cmd(port,&xcmd); fprintf(stderr,"TestADC: done, xcmd=%x\n",xcmd); }
static void _send_file_set(struct _App *app) { if (app->opening) _send_cmd(app, EM_RESULT_FILE_SET); if (app->closing) _send_file_closed(app); }
static int serial_image_reader(Camera *camera,CameraFile *file,int nr,unsigned char ***imagebufs,int *sizes, GPContext *context) { int picnum,curread,ret=0; GPPort *port = camera->port; unsigned int id; jd11_select_image(port,nr); *imagebufs = (unsigned char**)malloc(3*sizeof(char**)); for (picnum=0;picnum<3;picnum++) { curread=0; sizes[picnum] = jd11_imgsize(port); (*imagebufs)[picnum]=(unsigned char*)malloc(sizes[picnum]+400); _send_cmd(port,0xfff1); id = gp_context_progress_start (context, sizes[picnum], _("Downloading data...")); while (curread<sizes[picnum]) { int readsize = sizes[picnum]-curread; if (readsize > 200) readsize = 200; ret=getpacket(port,(*imagebufs)[picnum]+curread,readsize); if (ret==0) break; curread+=ret; if (ret<200) break; gp_context_progress_update (context, id, curread); if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) { int j; /* What to do ... Just free the stuff we allocated for now. */ for (j=0;j<picnum;j++) free((*imagebufs)[picnum]); free(*imagebufs); return GP_ERROR_CANCEL; } _send_cmd(port,0xfff1); } gp_context_progress_stop (context, id); } return GP_OK; }
static int getpacket(GPPort *port,unsigned char *buf, int expect) { int curread = 0, csum = 0; int tries = 0; if (expect == 200) expect++; while (tries++<5) { int i=0,ret; do { ret=READ(port,buf+curread,expect-curread); if (ret>0) { curread+=ret; i=0; continue; } usleep(100); } while ((i++<2) && (curread<expect)); if (curread!=expect) { if (!curread) return 0; _send_cmd(port,0xfff3); curread = csum = 0; continue; } /*printf("curread is %d\n",curread);*/ /*printf("PACKET:");_dump_buf(buf,curread);*/ for (i=0;i<curread-1;i++) csum+=buf[i]; if (buf[curread-1]==(csum&0xff) || (curread!=201)) return curread-1; fprintf(stderr,"BAD CHECKSUM %x vs %x, trying resend...\n",buf[curread-1],csum&0xff); _send_cmd(port,0xfff3); curread = csum = 0; /*return curread-1;*/ } fprintf(stderr,"Giving up after 5 tries.\n"); return 0; }
static void _display(void *data, void *id) { struct _App *app = data; if (!app->playing) return; sem_wait(&app->vs->lock); app->vs->frame.last = app->vs->frame.player; app->vs->frame.player = app->vs->frame.next; app->vs->frame.next = app->vs->frame.last; if (!app->vs->frame_drop++) _send_cmd(app, EM_RESULT_FRAME_NEW); sem_post(&app->vs->lock); }
int jd11_set_rgb(GPPort *port,float red, float green, float blue) { unsigned char buf[20]; _send_cmd(port,0xffa7); buf[0] = 0xff; buf[1] = (int)green; buf[2] = ((int)(green*10))%10; buf[3] = ((int)(green*100))%10; buf[4] = (int)red; buf[5] = ((int)(red*10))%10; buf[6] = ((int)(red*100))%10; buf[7] = (int)blue; buf[8] = ((int)(blue*10))%10; buf[9] = ((int)(blue*100))%10; /*_dump_buf(buf,10);*/ return WRITE(port,buf,10); }
static int jd11_imgsize(GPPort *port) { char buf[20]; int ret; int i=0,curread=0; _send_cmd(port,0xfff0); do { ret=READ(port,&buf[curread],10-curread); if (ret>0) curread+=ret; usleep(1000); } while ((i++<20) && (curread<10)); /*_dump_buf(buf,curread);*/ if (!curread) /* We get 0 bytes return for 0 images. */ return 0; ret=strtol(&buf[2],NULL,16); return ret; }
int jd11_get_rgb(GPPort *port,float *red, float *green, float *blue) { char buf[10]; int ret=GP_OK,tries=0,curread=0; _send_cmd(port,0xffa7); while ((curread<10) && (tries++<30)) { ret=READ(port,buf+curread,sizeof(buf)-curread); if (ret < 0) continue; if (ret == 0) break; curread+=ret; } if(curread<10) { fprintf(stderr,"%d returned bytes on float query.\n",ret); return GP_ERROR_IO; } /*_dump_buf(buf,10);*/ *green = buf[1]+buf[2]*0.1+buf[3]*0.01; *red = buf[4]+buf[5]*0.1+buf[6]*0.01; *blue = buf[7]+buf[8]*0.1+buf[9]*0.01; return GP_OK; }
//! The public send command method void COMMAND_INTERPRETER::send_cmd(byte packet_id, void *buf){ //! Process String _send_cmd(packet_id, buf); }
/* This function reads all thumbnails at once and initializes the whole * camera filesystem. This can be done, because finding out how much * pictures are on the camera is done by reading the whole preview picture * stream anyway. * And since the file infos are static mostly, why not just set them too at * the same time. */ int jd11_index_reader(GPPort *port, CameraFilesystem *fs, GPContext *context) { int i, id, count, xsize, curread=0, ret=0; unsigned char *indexbuf; ret = jd11_select_index(port); if (ret != GP_OK) return ret; xsize = jd11_imgsize(port); if (!xsize) { /* shortcut, no reading needed */ return GP_OK; } count = xsize/(64*48); xsize = count * (64*48); indexbuf = malloc(xsize); if (!indexbuf) return GP_ERROR_NO_MEMORY; id = gp_context_progress_start (context, xsize, _("Downloading thumbnail...")); _send_cmd(port,0xfff1); while (curread < xsize) { int readsize = xsize-curread; if (readsize>200) readsize = 200; ret=getpacket(port,indexbuf+curread,readsize); if (ret==0) break; curread+=ret; if (ret<200) break; gp_context_progress_update (context, id, curread); if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) { /* What to do...Just free the stuff we allocated for now.*/ free(indexbuf); return GP_ERROR_CANCEL; } _send_cmd(port,0xfff1); } gp_context_progress_stop (context, id); for (i=0;i<count;i++) { CameraFile *file; char fn[20]; unsigned char *src; unsigned char thumb[64*48]; int y; CameraFileInfo info; ret = gp_file_new(&file); if (ret!=GP_OK) { free(indexbuf); return ret; } sprintf(fn,"image%02i.pgm",i); gp_file_set_mime_type(file, GP_MIME_PGM); gp_file_append(file, THUMBHEADER, strlen(THUMBHEADER)); src = indexbuf+(i*64*48); for (y=0;y<48;y++) { int x,off = 64*y; for (x=0;x<64;x++) thumb[47*64-off+(63-x)] = src[off+x]; } ret = gp_file_append(file,(char*)thumb,sizeof(thumb)); if (ret != GP_OK) { gp_file_free (file); return ret; } ret = gp_filesystem_append(fs, "/", fn, context); if (ret != GP_OK) { /* should perhaps remove the entry again */ gp_file_free (file); return ret; } ret = gp_filesystem_set_file_noop(fs, "/", fn, GP_FILE_TYPE_PREVIEW, file, context); if (ret != GP_OK) return ret; /* we also get the fs info for free, so just set it */ info.file.fields = GP_FILE_INFO_TYPE | GP_FILE_INFO_WIDTH | GP_FILE_INFO_HEIGHT | GP_FILE_INFO_SIZE; strcpy(info.file.type,GP_MIME_PNM); info.file.width = 640; info.file.height = 480; info.file.size = 640*480*3+strlen(IMGHEADER); info.preview.fields = GP_FILE_INFO_TYPE | GP_FILE_INFO_WIDTH | GP_FILE_INFO_HEIGHT | GP_FILE_INFO_SIZE; strcpy(info.preview.type,GP_MIME_PGM); info.preview.width = 64; info.preview.height = 48; info.preview.size = 64*48+strlen(THUMBHEADER); ret = gp_filesystem_set_info_noop(fs, "/", fn, info, context); } free(indexbuf); return GP_OK; }
int jd11_erase_all(GPPort *port) { return _send_cmd(port,0xffa6); }
int main(int argc, const char *argv[]) { struct _App app; struct pollfd fds[3]; int tpipe[2]; // pipe for comunicating events from threads char cwidth[64], cheight[64], cpitch[64], chroma[64]; char buf[64]; const char *vlc_argv[] = { "--quiet", "--vout", "vmem", "--vmem-width", cwidth, "--vmem-height", cheight, "--vmem-pitch", cpitch, "--vmem-chroma", chroma }; if (argc < 3) { fprintf(stderr, "player: missing paramters.\n"); fprintf(stderr, "syntax:\n\t%s <fd read> <fd write>\n", argv[0]); return -1; } app.em_read = atoi(argv[1]); app.em_write = atoi(argv[2]); fprintf(stderr, "reading commands from fd: %d, writing on fd: %d\n", app.em_read, app.em_write); int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); snprintf(cwidth, sizeof(cwidth), "%d", DEFAULTWIDTH); snprintf(cheight, sizeof(cheight), "%d", DEFAULTHEIGHT); snprintf(cpitch, sizeof(cpitch), "%d", DEFAULTWIDTH * 4); snprintf(chroma, sizeof(chroma), "RV32"); /* * Naughty xattr in emotion uses ecore_thread to run its thing, this * may leave emotion's reference count high and it won't kill us... * letting us play the video in the background. not good. * * prctl(PR_SET_PDEATHSIG) is a linux only thing. Need to find ways * to do it on other platforms. Until then leave it breaking on * such platforms so people port it instead of ignoring. */ prctl(PR_SET_PDEATHSIG, SIGHUP); app.libvlc = libvlc_new(vlc_argc, vlc_argv); app.mp = NULL; app.filename = NULL; app.w = 0; app.h = 0; app.size_sent = 0; app.opening = 0; app.playing = 0; app.closing = 0; if (_em_cmd_read(&app) != EM_CMD_INIT) { fprintf(stderr, "player: wrong init command!\n"); return -1; } int size; _em_read_safe(app.em_read, &size, sizeof(size)); _em_read_safe(app.em_read, buf, size); app.shmname = strdup(buf); _send_cmd(&app, EM_RESULT_INIT); pipe(tpipe); app.fd_read = tpipe[0]; app.fd_write = tpipe[1]; fds[0].fd = app.em_read; fds[0].events = POLLIN; fds[1].fd = app.fd_read; fds[1].events = POLLIN; fds[2].fd = STDERR_FILENO; fds[2].events = 0; while (1) { int r; r = poll(fds, 3, -1); if (r == 0) continue; else if (r < 0) { fprintf(stderr, "emotion_generic_vlc: an error ocurred on poll(): %s\n", strerror(errno)); break; } if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { fputs("emotion_generic_vlc: error communicating with stdin\n", stderr); break; } if (fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) { fputs("emotion_generic_vlc: error communicating with thread\n", stderr); break; } if (fds[0].revents & POLLIN) _process_emotion_commands(&app); if (fds[1].revents & POLLIN) _process_thread_events(&app); if (fds[2].revents & (POLLERR | POLLHUP | POLLNVAL)) break; } libvlc_release(app.libvlc); return 0; }