/* ICAP_SUPPORTEDSIZES */ static TW_UINT16 SANE_ICAPSupportedSizes (pTW_CAPABILITY pCapability, TW_UINT16 action) { TW_UINT16 twCC = TWCC_BADCAP; #ifdef SONAME_LIBSANE static TW_UINT32 possible_values[SUPPORTED_SIZE_COUNT]; unsigned int i; TW_UINT32 val; TW_UINT16 default_size = get_default_paper_size(supported_sizes, SUPPORTED_SIZE_COUNT); TW_UINT16 current_size = get_current_paper_size(supported_sizes, SUPPORTED_SIZE_COUNT); TRACE("ICAP_SUPPORTEDSIZES\n"); switch (action) { case MSG_QUERYSUPPORT: twCC = set_onevalue(pCapability, TWTY_INT32, TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET ); break; case MSG_GET: for (i = 0; i < sizeof(supported_sizes) / sizeof(supported_sizes[0]); i++) possible_values[i] = supported_sizes[i].size; twCC = msg_get_enum(pCapability, possible_values, sizeof(possible_values) / sizeof(possible_values[0]), TWTY_UINT16, current_size, default_size); WARN("Partial Stub: our supported size selection is a bit thin.\n"); break; case MSG_SET: twCC = msg_set(pCapability, &val); if (twCC == TWCC_SUCCESS) for (i = 1; i < SUPPORTED_SIZE_COUNT; i++) if (supported_sizes[i].size == val) return set_width_height(supported_sizes[i].x, supported_sizes[i].y); ERR("Unsupported size %d\n", val); twCC = TWCC_BADCAP; break; case MSG_GETDEFAULT: twCC = set_onevalue(pCapability, TWTY_UINT16, default_size); break; case MSG_RESET: twCC = TWCC_BADCAP; for (i = 1; i < SUPPORTED_SIZE_COUNT; i++) if (supported_sizes[i].size == default_size) { twCC = set_width_height(supported_sizes[i].x, supported_sizes[i].y); break; } if (twCC != TWCC_SUCCESS) return twCC; /* .. fall through intentional .. */ case MSG_GETCURRENT: twCC = set_onevalue(pCapability, TWTY_UINT16, current_size); break; } #undef SUPPORTED_SIZE_COUNT #endif return twCC; }
int main(int argc, char **argv) { int shmid; int i,j; char in_str[16]; process_arguments(argc, argv); /* open the camera device */ if( (camera_fd = open(psz_video_dev, O_RDWR)) < 0 ) { char error_buf[256]; sprintf(error_buf, "open() %s", psz_video_dev); perror(error_buf); exit(-1); } get_caps(); get_format(); if( b_verbose ) printf("Device opened.\n"); if( b_verbose ) { printf("Video device:\t\t%s\n", psz_video_dev); print_caps(); print_format(); printf("Ouput directory:\t%s\n", psz_output_dir); printf("Image format:\t\t%s\n",str_formats[e_outfmt]); printf("\n"); printf("Opening device %s\n", psz_video_dev); if( b_named_filename ) { printf("Ouput filename:\t%s\n", psz_output_filename); } else if( b_named_pipe ) { printf("Using named pipe %s\n", psz_named_pipe); } if( b_shared_mem ) printf("Using shared memory. key = %i\n", shared_mem_key); } if( b_printinfo ) { printf("Device info:\n"); print_caps(); print_format(); close(camera_fd); exit(EXIT_SUCCESS); } (void)signal(SIGINT, exit_program); if( b_shared_mem && b_named_pipe ) { printf("WARNING: shared memory and named pipe can't be used together. Use more instances of camshot. Defaulting to named pipe.\n"); b_shared_mem = 0; } if( b_named_pipe ) { int ret_val = mkfifo(psz_named_pipe, 0666); if ((ret_val == -1) && (errno != EEXIST)) { perror("Error creating the named pipe"); exit(EXIT_FAILURE); } } if( req_width && req_height ) { if( b_verbose ) printf("Trying to set resolution to %ux%u.\n", req_width, req_height); if( set_width_height(req_width,req_height) == -1 ) printf("Unable to set the desired resolution.\n"); else if( b_verbose ) printf("Resolution set to %ux%u\n", req_width, req_height); } else { get_format(); req_width = camera_format.fmt.pix.width; req_height = camera_format.fmt.pix.height; } if( b_shared_mem ) { if((shmid = shmget(shared_mem_key, req_width*req_height*3, IPC_CREAT | 0666)) < 0) { perror("Error getting shared memory id"); exit(EXIT_FAILURE); } if((p_shm = (uint8_t *)shmat(shmid, NULL, 0)) == (void *) -1) { perror("Error getting shared memory ptr"); exit(EXIT_FAILURE); } shm_sem = semget((key_t)shared_mem_key, 1, IPC_CREAT | 0666); sem_set(&shm_sem); if( b_verbose ) printf("Shared memory ID: %i\nSemaphore ID: %i\n", shmid, shm_sem); } total_buffers = req_mmap_buffers(2); /* start the capture */ streaming_on(); /* let the camera self adjust by 'ignoring' 200 complete buffer queues */ printf("Letting the camera automaticaly adjust the picture:"); for(i=0; i<AUTO_ADJUST_TURNS; i++) { for(j=0; j<total_buffers; j++) { int ready_buf = dequeue_buffer(); /* don't queue the last buffers */ if( i<AUTO_ADJUST_TURNS-1 ) queue_buffer(ready_buf); } printf("."); fflush(stdout); } printf("Done.\n"); if( b_shared_mem || b_named_pipe ) { pthread_create(&stream_thread, NULL, &stream_func, NULL); while(1) { pthread_join(stream_thread, NULL); } } else { pthread_create(&capture_thread, NULL, &capture_func, NULL); } if( b_named_filename ) { usleep(200000); pthread_mutex_lock(&cond_mutex); pthread_cond_signal(&condition); pthread_mutex_unlock(&cond_mutex); usleep(200000); exit_program(SIGINT); fflush(stdout); return 0; } while( in_str[0] != 'q' ) { printf("Command (h for help): "); fflush(stdout); if( fgets(in_str, 16, stdin) == NULL ) { printf("Got NULL! Try again.\n"); continue; } switch(in_str[0]) { case 'x': pthread_mutex_lock(&cond_mutex); pthread_cond_signal(&condition); pthread_mutex_unlock(&cond_mutex); break; case 'h': printf("\nCommands:\n"); printf("\tx\tCapture a picture from camera.\n"); printf("\th\tPrints this help.\n"); printf("\tq\tQuits the program.\n"); printf("\n"); break; case 'q': case '\n': break; default: fprintf(stderr, "Unknown command %c\n", in_str[0]); break; } } /* Clean up */ exit_program(SIGINT); return 0; }