static int mp730_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) { int error, n; mp730_t *mp = (mp730_t *) s->subdriver; unsigned block_size, bytes_received; uint8_t header[16]; do { do { if (s->cancel) return PIXMA_ECANCELED; if (mp->last_block) /* end of image */ return 0; error = read_image_block (s, header, mp->imgbuf + mp->imgbuf_len); if (error < 0) return error; bytes_received = error; block_size = pixma_get_be16 (header + 4); mp->last_block = ((header[2] & 0x28) == 0x28); if (mp->last_block) { /* end of image */ mp->state = state_finished; } if ((header[2] & ~0x38) != 0) { PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n")); PDBG (pixma_hexdump (1, header, 16)); } PASSERT (bytes_received == block_size); if (block_size == 0) { /* no image data at this moment. */ /*pixma_sleep(100000); *//* FIXME: too short, too long? */ handle_interrupt (s, 100); } } while (block_size == 0); /* TODO: simplify! */ mp->imgbuf_len += bytes_received; n = mp->imgbuf_len / s->param->line_size; /* n = number of full lines (rows) we have in the buffer. */ if (n != 0) { if (s->param->channels != 1 && s->cfg->pid != MF5730_PID && s->cfg->pid != MF5750_PID && s->cfg->pid != MF5770_PID && s->cfg->pid != MF3110_PID && s->cfg->pid != IR1020_PID) { /* color, and not an MF57x0 nor MF3110 */ pack_rgb (mp->imgbuf, n, mp->raw_width, mp->lbuf); } else /* grayscale/lineart or MF57x0 or MF3110 */ memcpy (mp->lbuf, mp->imgbuf, n * s->param->line_size); block_size = n * s->param->line_size; mp->imgbuf_len -= block_size; memcpy (mp->imgbuf, mp->imgbuf + block_size, mp->imgbuf_len); } } while (n == 0); ib->rptr = mp->lbuf; ib->rend = mp->lbuf + block_size; return ib->rend - ib->rptr; }
/*********** set_color returns true if USB was inserted, false otherwise color is a pointer to the colour (in native format) to modify set banned_color to -1 to allow all ***********/ bool set_color(struct screen *display, char *title, unsigned *color, unsigned banned_color) { int exit = 0, slider = 0; struct rgb_pick rgb; rgb.color = *color; while (!exit) { int button; unpack_rgb(&rgb); if (display != NULL) { draw_screen(display, title, &rgb, slider); } else { FOR_NB_SCREENS(i) draw_screen(&screens[i], title, &rgb, slider); } button = get_action(CONTEXT_SETTINGS_COLOURCHOOSER, TIMEOUT_BLOCK); #ifdef HAVE_TOUCHSCREEN if (button == ACTION_TOUCHSCREEN && display->screen_type == SCREEN_MAIN) button = touchscreen_slider(display, &rgb, &slider); #endif switch (button) { case ACTION_STD_PREV: case ACTION_STD_PREVREPEAT: slider = (slider + 2) % 3; break; case ACTION_STD_NEXT: case ACTION_STD_NEXTREPEAT: slider = (slider + 1) % 3; break; case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INCREPEAT: if (rgb.rgb_val[slider] < rgb_max[slider]) rgb.rgb_val[slider]++; pack_rgb(&rgb); break; case ACTION_SETTINGS_DEC: case ACTION_SETTINGS_DECREPEAT: if (rgb.rgb_val[slider] > 0) rgb.rgb_val[slider]--; pack_rgb(&rgb); break; case ACTION_STD_OK: if (banned_color != (unsigned)-1 && banned_color == rgb.color) { splash(HZ*2, ID2P(LANG_COLOR_UNACCEPTABLE)); break; } *color = rgb.color; exit = 1; break; case ACTION_STD_CANCEL: exit = 1; break; default: if (default_event_handler(button) == SYS_USB_CONNECTED) return true; break; } } return false; }
static int iclass_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) { int error, n; iclass_t *mf = (iclass_t *) s->subdriver; unsigned block_size, lines_size, first_block_size; uint8_t info; /* * 1. send a block request cmd (d4 20 00... 04 00 06) * 2. examine the response for block size and/or end-of-scan flag * 3. read the block one chunk at a time * 4. repeat until have enough to process >=1 lines */ do { do { if (s->cancel) return PIXMA_ECANCELED; if (mf->last_block) { /* end of image */ mf->state = state_finished; return 0; } first_block_size = 0; error = request_image_block (s, 4, &info, &block_size, mf->blkptr + mf->blk_len, &first_block_size); /* add current block to remainder of previous */ mf->blk_len += first_block_size; if (error < 0) { /* NOTE: seen in traffic logs but don't know the meaning. */ read_error_info (s, NULL, 0); if (error == PIXMA_ECANCELED) return error; } /* info: 0x28 = end; 0x38 = end + ADF empty */ mf->last_block = info & 0x38; if ((info & ~0x38) != 0) { PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n")); PDBG (pixma_hexdump (1, &info, 1)); } if (block_size == 0) { /* no image data at this moment. */ /*pixma_sleep(100000); *//* FIXME: too short, too long? */ handle_interrupt (s, 100); } } while (block_size == 0 && first_block_size == 0); error = read_image_block (s, mf->blkptr + mf->blk_len, block_size); block_size = error; if (error < 0) return error; /* add current block to remainder of previous */ mf->blk_len += block_size; /* n = number of full lines (rows) we have in the buffer. */ n = mf->blk_len / s->param->line_size; if (n != 0) { if (s->param->channels != 1 && s->cfg->pid != MF3010_PID && s->cfg->pid != MF4410_PID && s->cfg->pid != MF4770_PID && s->cfg->pid != MF4550_PID && s->cfg->pid != MF4600_PID && s->cfg->pid != MF6500_PID && s->cfg->pid != MF8030_PID) { /* color and not MF46xx or MF65xx */ pack_rgb (mf->blkptr, n, mf->raw_width, mf->lineptr); } else { /* grayscale */ memcpy (mf->lineptr, mf->blkptr, n * s->param->line_size); } lines_size = n * s->param->line_size; /* cull remainder and shift left */ mf->blk_len -= lines_size; memcpy (mf->blkptr, mf->blkptr + lines_size, mf->blk_len); } } while (n == 0); /* output full lines, keep partial lines for next block */ ib->rptr = mf->lineptr; ib->rend = mf->lineptr + lines_size; return ib->rend - ib->rptr; }
static int touchscreen_slider(struct screen *display, struct rgb_pick *rgb, int *selected_slider) { short x, y; int char_height, line_height; int max_label_width; int text_top, slider_x, slider_width; bool display_three_rows; int button; int pressed_slider; struct viewport vp; viewport_set_defaults(&vp, display->screen_type); display->set_viewport(&vp); button = action_get_touchscreen_press_in_vp(&x, &y, &vp); if (button == ACTION_UNKNOWN || button == BUTTON_NONE) return ACTION_NONE; /* Get slider positions and top starting position * need vp.y here, because of the statusbar, since touchscreen * coordinates are absolute */ max_label_width = label_get_max_width(display); char_height = display->getcharheight(); text_top = MARGIN_TOP + char_height + TITLE_MARGIN_BOTTOM + SELECTOR_TB_MARGIN; slider_x = SELECTOR_WIDTH + max_label_width + SLIDER_TEXT_MARGIN; slider_width = vp.width - slider_x*2 - max_label_width; line_height = char_height + 2*SELECTOR_TB_MARGIN; /* same logic as in draw_screen */ /* Find out if there's enough room for three sliders or just enough to display the selected slider - calculate total height of display with three sliders present */ display_three_rows = vp.height >= text_top + line_height*3 + /* Title + 3 sliders */ SWATCH_TOP_MARGIN + /* at least 2 lines */ char_height*2 + /* + margins for bottom */ MARGIN_BOTTOM; /* colored rectangle */ display->set_viewport(NULL); if (y < text_top) { if (button == BUTTON_REL) return ACTION_STD_CANCEL; else return ACTION_NONE; } if (y >= text_top + line_height * (display_three_rows ? 3:1)) { /* touching the color area means accept */ if (button == BUTTON_REL) return ACTION_STD_OK; else return ACTION_NONE; } /* y is relative to the original viewport */ pressed_slider = (y - text_top)/line_height; if (pressed_slider != *selected_slider) *selected_slider = pressed_slider; /* add max_label_width to overcome integer division limits, * cap value later since that may lead to an overflow */ if (x < slider_x + (slider_width+max_label_width) && x > slider_x) { char computed_val; x -= slider_x; computed_val = (x*rgb_max[pressed_slider]/(slider_width)); rgb->rgb_val[pressed_slider] = MIN(computed_val,rgb_max[pressed_slider]); pack_rgb(rgb); } return ACTION_NONE; }