Пример #1
0
/**
 * \brief Updates the color pallet to the display
 *
 * This function should be called whenever a new color is selected
 * on the pallet. It will then move the selection box to the newly
 * chosen color.
 */
static void update_pallet_selection(void)
{
	/* Keep track of the last selected color */
	static uint8_t old_selected_color = 0;

	/* Delete old selection box */
	for (uint8_t i = 0; i < 3; i++) {
		gfx_draw_rect(
				(PALLET_COLOR_WIDTH * old_selected_color) + i,
				(gfx_get_height() - PALLET_HEIGHT) + i,
				PALLET_COLOR_WIDTH - (i * 2),
				PALLET_HEIGHT - (i * 2),
				pallet_colors[old_selected_color]);
	}

	/* Draw new selection box */
	for (uint8_t i = 0; i < 3; i++) {
		gfx_draw_rect(
				(PALLET_COLOR_WIDTH * selected_pallet_color) + i,
				(gfx_get_height() - PALLET_HEIGHT) + i,
				PALLET_COLOR_WIDTH - (i * 2),
				PALLET_HEIGHT - (i * 2),
				GFX_COLOR_GRAY);
	}

	old_selected_color = selected_pallet_color;
}
Пример #2
0
/**
 * This function stops an ongoing drag operation. Do not call this unless
 * dragging has been started with wtk_start_drag() first. This function erases
 * the drag handles and frees any allocated memory.
 *
 * \param last_pos Last position, as for wtk_continue_drag().
 */
static void wtk_stop_drag(struct win_point const *last_pos)
{
	/* Don't do any graphics if we did not get memory when drag started. */
	if (!wtk_drag_origin_pixmap || !wtk_drag_target_pixmap) {
		return;
	}

	/* Make sure we can draw on the entire screen, since dragging is not
	 * necessarily limited to within one window.
	 */
	gfx_set_clipping(0, 0, gfx_get_width() - 1, gfx_get_height() - 1);

	/* Restore screen underneath drag origin symbol. */
	gfx_put_pixmap(wtk_drag_origin_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			wtk_drag_origin.x - WTK_DRAG_HANDLE_RADIUS,
			wtk_drag_origin.y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	/* Restore screen underneath drag target symbol. */
	gfx_put_pixmap(wtk_drag_target_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			last_pos->x - WTK_DRAG_HANDLE_RADIUS,
			last_pos->y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	/* Free memory when not dragging. */
	membag_free(wtk_drag_origin_pixmap);
	membag_free(wtk_drag_target_pixmap);
}
Пример #3
0
/**
 * This function updated the drag target handle graphics. Call this function
 * from the MOVE event handler of the dragging widget. This function needs
 * both the current position and the last used position. The last position will
 * be either the position handed to wtk_start_drag() or the "pos" parameter of
 * the last call to wtk_continue_drag(). The pointer event struct will keep this
 * value for you. No need to store it yourself.
 *
 * \param last_pos Last position.
 * \param pos Current position.
 */
static void wtk_continue_drag(struct win_point const *last_pos,
		struct win_point const *pos)
{
	/* Don't do any graphics if we did not get memory when drag started. */
	if (!wtk_drag_origin_pixmap || !wtk_drag_target_pixmap) {
		return;
	}

	/* Make sure we can draw on the entire screen, since dragging is not
	 * necessarily limited to within one window.
	 */
	gfx_set_clipping(0, 0, gfx_get_width() - 1, gfx_get_height() - 1);

	/* Restore screen underneath drag target symbol. */
	gfx_put_pixmap(wtk_drag_target_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			last_pos->x - WTK_DRAG_HANDLE_RADIUS,
			last_pos->y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	/* Store screen underneath and draw new drag target symbol. */
	gfx_get_pixmap(wtk_drag_target_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			pos->x - WTK_DRAG_HANDLE_RADIUS,
			pos->y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	gfx_draw_filled_circle(pos->x, pos->y,
			WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_TARGET_COLOR, GFX_WHOLE);
}
/**
 * \brief Compute display coordinates for touch
 *
 * This function computes the display coordinates for a given touch event,
 * and stores it in the specified X- and Y-coordinate containers.
 *
 * \param touch_event Pointer to touch event
 * \param finger_data Pointer to finger struct
 */
static void get_finger_display_coordinates(const struct mxt_touch_event *touch_event,
		struct finger *finger_data)
{
	/* Display X-coordinate: rescale from 4k touch Y-coordinate to the
	 * display's width
	 */
	finger_data->x = ((uint32_t)touch_event->y * gfx_get_width()) / 4096;

	/* Display Y-coordinate: rescale from 4k touch X-coordinate to the
	 * display's height, and flip to get the right direction
	 */
	finger_data->y = gfx_get_height() - (((uint32_t)touch_event->x *
			gfx_get_height()) / 4096);

	/* Save the scaled size of the touch */
	finger_data->size = (touch_event->size * 4);
}
/**
 * \brief Set up calibration
 *
 * Allocates and initializes the application context; sets up the font, touch
 * event handler and calibration data; updates the display and then schedules
 * the calibration task.
 *
 * \param completed_task Task to schedule when calibration is complete
 */
void app_touch_calibrate_setup(struct workqueue_task *completed_task)
{
	calibrate_context =
			membag_alloc(sizeof(struct touch_calibrate_context));
	assert(calibrate_context != NULL);

	// Use twice as large font for this application.
	memcpy(&sysfont2x, &sysfont, sizeof(sysfont));
	sysfont2x.scale = 2;

	// Temporarily replace touch event handler.
	calibrate_context->old_handler = touch_get_event_handler();
	touch_set_event_handler(touch_calibrate_event_handler);

	// Clear the screen and draw the calibration guide text.
	gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height());
	gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(),
			CAL_BG_COLOR);
	gfx_draw_progmem_string((const char __progmem_arg *)
			&calibrate_help_text, 10, 80, &sysfont2x, CAL_FG_COLOR,
			GFX_COLOR_TRANSPARENT);

	// Set panel coordinates for all calibration points.
	calibrate_context->cal_points[0].panel_x =
			(gfx_get_width() - CAL_OFFSET - 1);
	calibrate_context->cal_points[0].panel_y =
			(gfx_get_height() - CAL_OFFSET - 1);
	calibrate_context->cal_points[1].panel_x = (CAL_OFFSET);
	calibrate_context->cal_points[1].panel_y =
			(gfx_get_height() - CAL_OFFSET - 1);
	calibrate_context->cal_points[2].panel_x = (CAL_OFFSET);
	calibrate_context->cal_points[2].panel_y = (CAL_OFFSET);

	// Draw circle for first calibration point.
	gfx_draw_circle(calibrate_context->cal_points[0].panel_x,
			calibrate_context->cal_points[0].panel_y,
			CAL_RADIUS, CAL_FG_COLOR, GFX_WHOLE);

	// Initialize the calibration state and tasks before scheduling it.
	calibrate_context->state = 0;
	calibrate_context->completed_task = completed_task;

	workqueue_task_init(&calibrate_context->task,
			touch_calibrate_task_handler);
	workqueue_add_task(&main_workqueue, &calibrate_context->task);
}
Пример #6
0
/**
 * \brief Draws the special function pallet entry text labels
 *
 * This function draws the special function pallet entry text labels to the
 * appropriate positions on the display.
 *
 * \param clearing_display   True if the display is currently being cleared
 */
static void draw_pallet_labels(const bool clearing_display)
{
	/* Draw multi-color mode text label to the appropriate pallet entry */
	gfx_draw_string_aligned("MUL",
			PALLET_COLOR_WIDTH / 2,
			gfx_get_height() - (PALLET_HEIGHT / 2), &sysfont,
			GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE,
			TEXT_POS_CENTER, TEXT_ALIGN_LEFT);

	/* Draw display clear text label to the appropriate pallet entry */
	gfx_draw_string_aligned("CLR",
			(PALLET_COLOR_WIDTH * NUM_PALLET_COLORS) - (PALLET_COLOR_WIDTH / 2),
			gfx_get_height() - (PALLET_HEIGHT / 2), &sysfont,
			GFX_COLOR_TRANSPARENT,
			clearing_display ? GFX_COLOR_RED : GFX_COLOR_WHITE,
			TEXT_POS_CENTER, TEXT_ALIGN_LEFT);
}
Пример #7
0
/**
 * \brief Main application function
 *
 * This function executes the necessary initialization calls and displays the
 * demo widgets before entering the main work loop of the application.
 *
 * The main work loop reads out the touch events from the mXT143E Xplained and
 * enqueues the corresponding touch events in the window system, before
 * processing the window system's event queue.
 */
int main(void)
{
	static struct mxt_device device;

	board_init();
	sysclk_init();
	membag_init();
	gfx_init();
	mxt_init(&device);
	win_init();

	setup_root_window();
	app_widget_launch();

	while (true) {
		/* Process received messages from the maXTouch device */
		while (mxt_is_message_pending(&device)) {
			struct mxt_touch_event touch_event;
			struct win_pointer_event win_touch_event;

			/* Get the first touch event in queue */
			if (mxt_read_touch_event(&device,
					&touch_event) != STATUS_OK) {
				continue;
			}

			/* Translate touch event type into a WTK event type */
			if (touch_event.status & MXT_PRESS_EVENT) {
				win_touch_event.type = WIN_POINTER_PRESS;
			} else if (touch_event.status & MXT_MOVE_EVENT) {
				win_touch_event.type = WIN_POINTER_MOVE;
			} else if (touch_event.status & MXT_RELEASE_EVENT) {
				win_touch_event.type = WIN_POINTER_RELEASE;
			} else {
				continue;
			}

			/* Indicate the touch event is a non-relative movement
			 * with the virtual touch button pressed
			 */
			win_touch_event.is_relative = false;
			win_touch_event.buttons = WIN_TOUCH_BUTTON;

			/* Translate the touch X and Y position into a screen
			 * coordinate
			 */
			win_touch_event.pos.x =
					((uint32_t)(4096 - touch_event.x) * gfx_get_width()) / 4096;
			win_touch_event.pos.y =
					((uint32_t)(4096 - touch_event.y) * gfx_get_height()) / 4096;
			win_queue_pointer_event(&win_touch_event);
		}

		/* Process queued events in the windowing system */
		win_process_events();
	}
}
Пример #8
0
/**
 * This function starts the drag operation. It will allocate memory to store
 * the screen behind the drag handles and draw the handles themselves.
 * Do not call this function unless wtk_prepare_drag() has been called first
 * with the drag origin position.
 * If there is not enough memory, this function will no draw anything, but it
 * is still safe to call wtk_continue_drag() and wtk_stop_drag().
 *
 * \param pos Current position of drag target.
 */
static void wtk_start_drag(struct win_point const *pos)
{
	/* Allocate memory for bitmaps. */
	wtk_drag_origin_pixmap = membag_alloc(
			(WTK_DRAG_PIXMAP_SIZE * WTK_DRAG_PIXMAP_SIZE) *
			sizeof(gfx_color_t)
			);
	if (!wtk_drag_origin_pixmap) {
		goto outofmem_origin;
	}

	wtk_drag_target_pixmap = membag_alloc(
			(WTK_DRAG_PIXMAP_SIZE * WTK_DRAG_PIXMAP_SIZE) *
			sizeof(gfx_color_t)
			);
	if (!wtk_drag_target_pixmap) {
		goto outofmem_target;
	}

	/* Make sure we can draw on the entire screen, since dragging is not
	 * necessarily limited to within one window.
	 */
	gfx_set_clipping(0, 0, gfx_get_width() - 1, gfx_get_height() - 1);

	/* Store screen underneath and draw drag origin symbol. */
	gfx_get_pixmap(wtk_drag_origin_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			wtk_drag_origin.x - WTK_DRAG_HANDLE_RADIUS,
			wtk_drag_origin.y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	gfx_draw_filled_circle(wtk_drag_origin.x, wtk_drag_origin.y,
			WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_ORIGIN_COLOR, GFX_WHOLE);

	/* Store screen underneath and draw drag target symbol. */
	gfx_get_pixmap(wtk_drag_target_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			pos->x - WTK_DRAG_HANDLE_RADIUS,
			pos->y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	gfx_draw_filled_circle(pos->x, pos->y,
			WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_TARGET_COLOR, GFX_WHOLE);

	return;

outofmem_target:
	membag_free(wtk_drag_origin_pixmap);
	wtk_drag_origin_pixmap = NULL;

outofmem_origin:
	return;
}
Пример #9
0
/**
 * \brief Draws the color pallet to the display
 *
 * This function draws the paint pallet to the display, including the special
 * function entries (such as display clear) and the selection box.
 */
static void draw_paint_pallet(void)
{
	/* Draw each color in the pallet to the display at the correct
	 * location */
	for (uint8_t i = 0; i < NUM_PALLET_COLORS; i++) {
		gfx_draw_filled_rect(
				PALLET_COLOR_WIDTH * i,
				gfx_get_height() - PALLET_HEIGHT,
				PALLET_COLOR_WIDTH,
				PALLET_HEIGHT, pallet_colors[i]);
	}

	/* Draw a dark gray line to separate the drawing area from the pallet */
	gfx_draw_horizontal_line(0,
			(gfx_get_height() - PALLET_HEIGHT - 1),
			gfx_get_width(), GFX_COLOR_GRAY);

	/* Draw special function labels */
	draw_pallet_labels(false);

	/* Draw selection box */
	update_pallet_selection();
}
Пример #10
0
Файл: ui.c Проект: kerichsen/asf
/** Initialize the user interface */
void ui_init(void)
{
	uint8_t n;

	LED_On(LED0_GPIO);
	LED_Off(LED1_GPIO);

	ui_new_touch_event = false;

	/* Initialize trace struct to all 0 */
	for (n = 0; n < NUM_TRACES; n++) {
		trace[n].x = trace[n].y = 0;
	}

	/* Get and keep display size */
	display_w = gfx_get_width();
	display_h = gfx_get_height();
}
Пример #11
0
/**
 * \brief Show an out of memory error on the display
 *
 * Shows a full screen error when called, signaling that the system
 * ran out of memory when initializing a WTK application.
 */
static void show_out_of_memory_error(void)
{
	const char memory_string[] = "OUT OF MEMORY";
	gfx_coord_t disp_width, disp_height;

	/* Get the display width and height */
	disp_width  = gfx_get_width();
	disp_height = gfx_get_height();

	/* Blank display */
	gfx_set_clipping(0, 0, disp_width, disp_height);
	gfx_draw_filled_rect(0, 0, disp_width, disp_height, GFX_COLOR_BLACK);

	/* Show centered out of memory error text */
	gfx_draw_string_aligned(memory_string,
		disp_width / 2, disp_height / 2,
		&sysfont,
		GFX_COLOR_TRANSPARENT, GFX_COLOR_RED,
		TEXT_POS_CENTER, TEXT_ALIGN_CENTER);
}
Пример #12
0
/**
 * \brief Convert touch events from the touchscreen into window pointer events
 *
 * Reads touch events in from the touchscreen and converts them into a
 * Window Manager pointer event, for enqueuing into the window event queue.
 *
 * \return Boolean true if a touch event was read, false if no touch event
 *         or a corrupt touch event was received
 */
static bool read_touch_event(struct mxt_device *device,
		struct win_pointer_event *win_touch_event)
{
	struct mxt_touch_event touch_event;

	/* Abort if no touch event is pending */
	if (!(mxt_is_message_pending(device))) {
		return false;
	}

	/* Get the first touch event in queue */
	if (mxt_read_touch_event(device, &touch_event) != STATUS_OK) {
		return false;
	}

	/* Translate touch event type into a WTK event type */
	if (touch_event.status & MXT_PRESS_EVENT) {
		win_touch_event->type = WIN_POINTER_PRESS;
	} else if (touch_event.status & MXT_MOVE_EVENT) {
		win_touch_event->type = WIN_POINTER_MOVE;
	} else if (touch_event.status & MXT_RELEASE_EVENT) {
		win_touch_event->type = WIN_POINTER_RELEASE;
	} else {
		return false;
	}

	/* Indicate the touch event is a non-relative movement with the virtual
	 * touch button pressed
	 */
	win_touch_event->is_relative = false;
	win_touch_event->buttons = WIN_TOUCH_BUTTON;

	/* Translate the touch X and Y position into a screen coordinate */
	win_touch_event->pos.x =
			((uint32_t)(4096 - touch_event.x) * gfx_get_width()) / 4096;
	win_touch_event->pos.y =
			((uint32_t)(4096 - touch_event.y) * gfx_get_height()) / 4096;

	return true;
}
/**
 * \brief Main application loop
 *
 * This is the main application function, which runs all the initialization
 * code, clears the display and enters a loop in which it continuously polls for
 * new messages from the maXTouch device. If one or more messages are pending,
 * the maXTouch message handler is invoked.
 */
int main(void)
{
	/* maXTouch data structure */
	static struct mxt_device device;

	/* Basic init routines */
	board_init();
	sysclk_init();
	gfx_init();
	mxt_init(&device);

	/* Clear the display */
	gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(),
			DISPLAY_COLOR);

	while (true) {
		/* Check for any pending messages and run message handler if any
		 * message is found in the queue */
		if (mxt_is_message_pending(&device)) {
			mxt_handler(&device);
		}
	}
}
/**
 * \brief Load file data directly to screen worker
 *
 * This worker function puts the data fetched from the file system directly to
 * the screen.
 *
 * \param task Pointer to the current work queue task
 */
static void load_to_screen_worker(struct workqueue_task *task)
{
	struct file_loader      *floader = &the_file_loader;
	enum status_code        result;

	gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height());

	gfx_put_pixmap((gfx_color_t *)floader->buffer,
			floader->load_size,
			0,
			0,
			floader->current_x + floader->offset_x,
			floader->current_y + floader->offset_y,
			floader->load_size,
			1);

	floader->current_x += floader->load_size;
	if (floader->current_x >= floader->width) {
		floader->current_y++;
		floader->current_x = 0;
	}

	floader->load_size = min_u((floader->width - floader->current_x),
			MAX_LOAD_PIXELS);

	result = tsfs_read(&myfs, &floader->file, &floader->buffer,
			floader->load_size * sizeof(gfx_color_t),
			&floader->task);

	// If file we are done, run the image done task
	if ((result != STATUS_OK) || (floader->current_y > floader->height)) {
		floader->busy = false;

		if (floader->done_task)
			workqueue_add_task(&main_workqueue, floader->done_task);
	}
}
Пример #15
0
/**
 * \brief Main application loop
 *
 * This is the main application function, which runs all the initialization
 * code, clears the display and enters a loop in which it continuously polls
 * for new messages from the maXTouch device. If one or more messages are
 *  pending, the maXTouch message handler is invoked.
 */
int main(void)
{
	/* maXTouch data structure */
	static struct mxt_device device;

	/* Basic init routines */
	board_init();
	sysclk_init();
	gfx_init();
	mxt_init(&device);

	/* Draw the paint pallet to the display */
	draw_paint_pallet();

	/* Draw instructions to the display */
	gfx_draw_string_aligned(
			"Select a color from the pallet below, and\n"
			"use your finger(s) to draw onto the display.\n\n"
			"Multiple simultaneous fingers are supported,\n"
			"and the drawing size varies according to the\n"
			"pressure of the touch.\n\n"
			"Select MUL to draw using multiple colors.\n\n"
			"Select CLR to clear the display.",
			gfx_get_width() / 2,
			(gfx_get_height() - PALLET_HEIGHT) / 2,
			&sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE,
			TEXT_POS_CENTER, TEXT_ALIGN_LEFT);

	while (true) {
		/* Check for any pending messages and run message handler if any
		 * message is found in the queue */
		if (mxt_is_message_pending(&device)) {
			mxt_handler(&device);
		}
	}
}
Пример #16
0
int main(int argc, char* argv[]){
	unsigned int size;/*Tamanho do triangulo*/
	unsigned int default_size;/*Tamanho padrão do triangulo*/
	unsigned int amount; /*Quantidade de triangulos*/
	int quit; /*Verifica se o programa deve ser encerrado*/
	char* msg; /*Auxiliar para colocar as informaçoes na tela*/
	SDL_Event event; /*guarda um evento ocorrido*/
	
	msg = (char*) malloc(sizeof(char) * 30); /*Aloca memoria para a string auxiliar*/
	if(!msg){/*Verifica se foi alocado*/
		printf("Erro ao alocar memoria.\n");
		exit (0);
	}

	amount = 0;/*Inicializa o contador de triangulos*/
	default_size = 100;/*Define o tamanho padrão do triangulo para caso o usuario não tenha definido*/

	if(argc != 1){/*Verifica se foi passado algum argumento na chamada do programa*/
		if(atoi(argv[1]) != 0){/*Se o argumento for um numero ele sera o tamanho padrão do triangulo*/
			default_size = atoi(argv[1]);
		}
	}
	
	size = default_size;/*Define o tamanho com o tamanho padrão*/
	
	gfx_init("Sierpinski");/*Seta o nome da janela*/
	
	sierpinski((gfx_get_width() / 2) - (size / 2), gfx_get_height() - (int)((size * 1.732050808) / 2), size, &amount);/*Desenha o triangulo com o tamanho incial*/
	sprintf(msg, "Lado: %d     Quantidade: %u", size, amount);
	gfx_text(10, 10, msg);/*Imprime as informacões do triangulo*/
	gfx_text(10, 30, "Atalhos: Zoom(i)n - Zoom(o)ut - (C)lear - (esc)ape");/*Imprime o menu*/
	gfx_paint();
	
	while(!quit){/*Loop principal*/
		while(SDL_PollEvent(&event)){/*Verifica se ocorreu algum evento*/
			switch(event.type){/*Seleciona o tipo de evento*/
				case SDL_QUIT:/*Clique no botão de fechar*/
					quit = 1;/*sair do loop principal*/
					break;
				case SDL_KEYDOWN:/*Tecla pressionada*/
					while(event.key.state == SDL_PRESSED && quit == 0){/*Tecla continua pressionada e não é o ESC*/
						switch (event.key.keysym.sym){/*Seleciona a tecla*/
							case SDLK_i:/*Caso seja 'i' os triangulos aumentam*/
								size += 5;/*Incrementa o tamanho do triangulo*/
								gfx_clear();/*Limpa a tela*/
								amount = 0;/*Zera o contador de triangulos*/
								sierpinski((gfx_get_width() / 2) - (size / 2), gfx_get_height() - (int)((size * 1.732050808) / 2), size, &amount);/*Desenha o triangulo de Sierpinski*/
								sprintf(msg, "Lado: %d     Quantidade: %u", size, amount);
								gfx_text(10, 10, msg);/*Imprime as informacões do triangulo*/
								gfx_text(10, 30, "Atalhos: Zoom(i)n - Zoom(o)ut - (C)lear - (esc)ape");/*Imprime o menu*/
								break;

							case SDLK_o:/*Caso seja 'o' os triangulos diminuem*/
								size -= 5;
								gfx_clear();
								amount = 0;
								sierpinski((gfx_get_width() / 2) - (size / 2), gfx_get_height() - (int)((size * 1.732050808) / 2), size, &amount);
								sprintf(msg, "Lado: %d     Quantidade: %u", size, amount);
								gfx_text(10, 10, msg);/*Imprime as informacões do triangulo*/
								gfx_text(10, 30, "Atalhos: Zoom(i)n - Zoom(o)ut - (C)lear - (esc)ape");/*Imprime o menu*/
								break;

							case SDLK_c: /*Caso seja 'c' o triangulo é resetado*/
								size = default_size;/*Define o tamanho com o tamanho padrão*/
								gfx_clear();/*Limpa tela*/
								amount = 0;/*Zera o contador de triangulos*/
								sierpinski((gfx_get_width() / 2) - (size / 2), gfx_get_height() - (int)((size * 1.732050808) / 2), size, &amount);/*Desenha o triangulo com o tamanho padrão*/
								sprintf(msg, "Lado: %d     Quantidade: %u", size, amount);
								gfx_text(10, 10, msg);/*Imprime as informacões do triangulo*/
								gfx_text(10, 30, "Atalhos: Zoom(i)n - Zoom(o)ut - (C)lear - (esc)ape");/*Imprime o menu*/
								break;

							case SDLK_ESCAPE: /*Caso seja 'ESC' encerra o programa*/
								quit = 1;
								break;
							
							default:/*Outra tecla nada é feito*/
								break;
						}
						gfx_refresh();/*Atualiza a tela*/
						usleep(120000);/*Delay para ler um novo evento*/
						SDL_PollEvent(&event);/*Le um novo evento*/
					}
					break;
			}
		}
	}

	gfx_quit();/*Fecha a janela*/
	free(msg);/*Libera a memoria alocada*/
	return 0;
}
/**
 * \brief Setup widget demo
 *
 * This function launches the widget demo.
 */
void app_widget_launch()
{
	struct win_window *win_root;
	struct win_window *parent;
	struct win_area area;
	struct wtk_label *lbl;
	struct wtk_button *btn;

	/* Get pointer to root window */
	win_root = win_get_root();

	/* Application frame */

	/* Create a background bitmap using a solid color. */
	frame_background.type = GFX_BITMAP_SOLID;
	frame_background.data.color = APP_BACKGROUND_COLOR;

	/* Set the area to fill the entire screen */
	area.pos.x = 0;
	area.pos.y = 0;
	area.size.x = gfx_get_width();
	area.size.y = gfx_get_height();

	/*
	 * Create a basic frame with a specified background and command event
	 * handler. Check the return value if an error occurred while creating
	 * the widget.
	 */
	main_frame = wtk_basic_frame_create(win_root, &area,
			&frame_background, NULL,
			widget_frame_command_handler, NULL);
	if (!main_frame) {
		goto error_frame;
	}

	/* Get a pointer to the widget's window for adding sub-widgets. */
	parent = wtk_basic_frame_as_child(main_frame);

	/*
	 * Draw the frame by showing the frame widget's window. Any
	 * child-widgets and windows will not be shown before the parent
	 * widget/window is shown.
	 */
	win_show(parent);

	/* Application label */
	area.pos.x = LABEL_POS_X;
	area.pos.y = LABEL_POS_Y;
	/* Find an optimal size for the widget. */
	wtk_label_size_hint(&area.size, demo_string);

	/*
	 * Create the label and check the return value if an error occurred
	 * while creating the label.
	 */
	lbl = wtk_label_create(parent, &area, demo_string,
			GFX_COLOR(255, 255, 255), NULL, false);
	if (!lbl) {
		goto error_widget;
	}

	/* Draw the label by showing the label widget's window. */
	win_show(wtk_label_as_child(lbl));

	/* Application slider */
	area.pos.x = SLIDER_POS_X;
	area.pos.y = SLIDER_POS_Y;
	area.size.x = SLIDER_SIZE_X;
	area.size.y = SLIDER_SIZE_Y;

	/*
	 * Create the slider and check the return value if an error occurred
	 * while creating the slider.
	 */
	slider = wtk_slider_create(parent, &area, SLIDER_MAX_VALUE,
			SLIDER_MAX_VALUE / 2,
			WTK_SLIDER_HORIZONTAL | WTK_SLIDER_CMD_RELEASE,
			(win_command_t)SLIDER_ID);
	if (!slider) {
		goto error_widget;
	}

	/* Draw the slider by showing the slider widget's window. */
	win_show(wtk_slider_as_child(slider));

	/* Application progress bar, placed right of the slider. */
	area.pos.x += area.size.x + SLIDER_PB_SPACING_X;
	area.size.x = PB_SIZE_X;
	area.size.y = PB_SIZE_Y;

	/*
	 * Create the progress bar and check the return value if an error
	 * occurred while creating the progress bar.
	 */
	progress_bar = wtk_progress_bar_create(parent, &area, SLIDER_MAX_VALUE,
			SLIDER_MAX_VALUE / 2, GFX_COLOR(255, 255, 0),
			GFX_COLOR(90, 90, 90), WTK_PROGRESS_BAR_HORIZONTAL);
	if (!progress_bar) {
		goto error_widget;
	}

	/* Draw the progress bar by showing the progress bar widget's window. */
	win_show(wtk_progress_bar_as_child(progress_bar));

	/** \todo Add code to set up button here. */

	/** \todo Add code to set up basic frame here. */

	return;

error_widget:
	/* Destroy widget and all sub-widgets. */
	win_destroy(wtk_basic_frame_as_child(main_frame));
error_frame:
	/* Wait forever if an error occurred during setup. */
	while (1) {
	}
}
/**
 * \brief Main application function
 *
 * This function ensures that the hardware and drivers are initialized before
 * entering an infinite work loop.
 *
 * In the work loop, the maXTouch device is polled for new touch events and any
 * new event is passed on to the user interface implementation for processing.
 * The loop then attempts to enter sleep.
 *
 * The user interface processing itself is not started by the work loop, but by
 * the USB callback function for start of frame.
 */
int main(void)
{
#ifdef USB_DEVICE_LOW_SPEED
	uint16_t virtual_sof_sub;
	uint16_t virtual_sof;
#endif

	/* maXTouch data structure */
	static struct mxt_device device;

	/* Initialize system clocks */
	sysclk_init();

	/* Initialize interrupt vectors */
	irq_initialize_vectors();

	/* Enable interrupts */
	cpu_irq_enable();

	/* Initialize the sleep manager */
	sleepmgr_init();

	/* Initialize the board */
	board_init();

	/* Initialize the mXT touch device */
	mxt_init(&device);

	/* Initialize the graphical library */
	gfx_init();

	/* Set correct landscape orientation */
	gfx_set_orientation(GFX_SWITCH_XY | GFX_FLIP_Y);

	/* Set background color */
	gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(),
			COLOR_BACKGROUND);

	/* Draw the help text */
	gfx_draw_string_aligned(
			"Middle finger to move cursor\n"
			"Index finger to left click\n"
			"Ring finger to right click",
			gfx_get_width() / 2, gfx_get_height() / 2,
			&sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE,
			TEXT_POS_CENTER, TEXT_ALIGN_CENTER);

	/* Initialize the user interface */
	ui_init();
	ui_powerdown();

	/* Start USB stack to authorize VBus monitoring */
	udc_start();

	/* Check if there are any new touch data pending */
	while (true) {
		if (mxt_is_message_pending(&device)) {
			if (mxt_read_touch_event(&device, &ui_touch_event) == STATUS_OK) {
				ui_flag_new_touch_event();
			}
		}

		/* Try to sleep */
		sleepmgr_enter_sleep();

#ifdef USB_DEVICE_LOW_SPEED
		/* No USB "Keep alive" interrupt available in low speed
		 * to scan mouse interface then use main loop */
		if (main_b_mouse_enable) {
			virtual_sof_sub = 0;
			virtual_sof = 0;
			if (virtual_sof_sub++ == 700) {
				virtual_sof_sub = 0;
				ui_process(virtual_sof++);
			}
		}
#endif
	}
}
Пример #19
0
/**
 * \brief Launch the water tank application.
 *
 * This function allocates memory, creates the application frame and widgets,
 * initializes the timer and initiates loading of the required bitmaps.
 *
 * One basic frame is created, along with four widgets: one slider, two progress
 * bars and a command button. These are not shown until the background image has
 * been loaded.
 *
 * If the alarm light bitmaps have already been loaded, i.e., the application
 * has already been run, the application will skip directly to loading of the
 * background image.
 *
 * If memory for the application context cannot be allocated or the frame or
 * widgets cannot be created, the application will exit immediately.
 *
 * \param task Workqueue task to use for the application's worker functions.
 */
void app_tank_launch(struct workqueue_task *task)
{
	struct win_attributes    attr;
	struct win_window        *win;
	struct gfx_bitmap        bitmap;
	struct wtk_basic_frame   *frame;
	struct wtk_slider        *slider;
	struct wtk_button        *button;
	struct wtk_progress_bar  *pbar;
	struct timer             *timer;
	timer_res_t              timer_res;
	uint32_t                 timer_clk;

	assert(task);

	// Clear the screen right away.
#ifdef CONFIG_GFX_USE_CLIPPING
	gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height());
#endif /* CONFIG_GFX_USE_CLIPPING */
	gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(),
			COLOR_WIN_BACKGROUND);

	// Allocate the application context first.
	tank_ctx = membag_alloc(sizeof(struct tank_context));
	if (!tank_ctx)
		goto exit_no_context;

	// Use larger sysfont for this app.
	memcpy(&tank_ctx->old_sysfont, &sysfont, sizeof(struct font));
	sysfont.scale = 2;

	// Create a basic frame to contain the widgets.
	attr.area.pos.x = 0;
	attr.area.pos.y = 0;
	attr.area.size.x = gfx_get_width();
	attr.area.size.y = gfx_get_height();

	frame = wtk_basic_frame_create(win_get_root(), &attr.area, NULL,
			NULL, tank_frame_handler, NULL);
	if (!frame) {
		goto exit_no_frame;
	}
	tank_ctx->frame = frame;

	// Get the frame's window to use as parent for widgets.
	win = wtk_basic_frame_as_child(frame);

	// Initialize the application timer.
	timer = &tank_ctx->timer;
	timer_init(CONFIG_TIMER_ID, timer, tank_timer_callback);
	timer_res = timer_set_resolution(CONFIG_TIMER_ID, timer,
			TICK_RATE);
	timer_write_resolution(CONFIG_TIMER_ID, timer, timer_res);

	// Get the timer alarm delay to use for the configured tick rate.
	timer_clk = timer_get_resolution(CONFIG_TIMER_ID, timer, timer_res);
	tank_ctx->timer_delay = timer_clk / TICK_RATE;

	// Initialize random variable and tick count.
	tank_ctx->rand = 1;
	tank_ctx->rand_ticks = TICKS_PER_RANDOM_UPDATE;

	// Create the supply slider.
	attr.area.pos.x = WIDGET_SUPPLY_POSITION_X;
	attr.area.pos.y = WIDGET_SUPPLY_POSITION_Y;
	attr.area.size.x = WIDGET_SUPPLY_SIZE_X;
	attr.area.size.y = WIDGET_SUPPLY_SIZE_Y;

	slider = wtk_slider_create(win, &attr.area, VALUE_SUPPLY_MAXIMUM,
			VALUE_SUPPLY_INITIAL, WTK_SLIDER_VERTICAL |
					WTK_SLIDER_INVERT, CMD_NONE);
	if (!slider) {
		goto exit_no_widget;
	}
	tank_ctx->supply = slider;
	win_show(wtk_slider_as_child(slider));

	// Create the tank level progress bar.
	attr.area.pos.x = WIDGET_LEVEL_POSITION_X;
	attr.area.pos.y = WIDGET_LEVEL_POSITION_Y;
	attr.area.size.x = WIDGET_LEVEL_SIZE_X;
	attr.area.size.y = WIDGET_LEVEL_SIZE_Y;

	pbar = wtk_progress_bar_create(win, &attr.area, VALUE_LEVEL_MAXIMUM,
			VALUE_LEVEL_INITIAL, COLOR_LEVEL_FILL,
			COLOR_LEVEL_BACKGROUND, WTK_PROGRESS_BAR_VERTICAL |
					WTK_PROGRESS_BAR_INVERT);
	if (!pbar) {
		goto exit_no_widget;
	}
	tank_ctx->level = pbar;
	win_show(wtk_progress_bar_as_child(pbar));

	// Create the demand progress bar.
	attr.area.pos.x = WIDGET_DEMAND_POSITION_X;
	attr.area.pos.y = WIDGET_DEMAND_POSITION_Y;
	attr.area.size.x = WIDGET_DEMAND_SIZE_X;
	attr.area.size.y = WIDGET_DEMAND_SIZE_Y;

	pbar = wtk_progress_bar_create(win, &attr.area, VALUE_DEMAND_MAXIMUM,
			VALUE_DEMAND_INITIAL, COLOR_DEMAND_NORMAL,
			COLOR_DEMAND_BACKGROUND, WTK_PROGRESS_BAR_VERTICAL |
					WTK_PROGRESS_BAR_INVERT);
	if (!pbar) {
		goto exit_no_widget;
	}
	tank_ctx->demand = pbar;
	win_show(wtk_progress_bar_as_child(pbar));

	// Create the exit button with the standard settings.
	attr.area.pos.x = APP_EXIT_BUTTON_POS_X;
	attr.area.pos.y = APP_EXIT_BUTTON_POS_Y;
	attr.area.size.x = APP_EXIT_BUTTON_SIZE_X;
	attr.area.size.y = APP_EXIT_BUTTON_SIZE_Y;

	button = wtk_button_create(win, &attr.area, APP_EXIT_BUTTON_TEXT,
			(win_command_t)CMD_EXIT);
	if (!button) {
		goto exit_no_widget;
	}
	win_show(wtk_button_as_child(button));

	// Set the tank alarm to trigger initial drawing of alarm light.
	tank_ctx->level_alarm = true;
	tank_ctx->flow_alarm = false;
	tank_ctx->task = task;

	/* Initialize bitmap data and set initial application loader state:
	 * If the alarm light bitmaps have already been loaded, skip right to
	 * loading of the application background bitmap.
	 */
	bitmap.width = BITMAP_LIGHT_SIZE_X;
	bitmap.height = BITMAP_LIGHT_SIZE_Y;
	bitmap.type = BITMAP_HUGEMEM;
	tank_ctx->bitmaps[BITMAP_RED_LIGHT] = bitmap;
	tank_ctx->bitmaps[BITMAP_GREEN_LIGHT] = bitmap;

	if (tank_bitmap_data[BITMAP_GREEN_LIGHT]) {
		tank_ctx->loader_state = LOAD_BACKGROUND;
		tank_ctx->bitmaps[BITMAP_RED_LIGHT].data.hugemem =
				tank_bitmap_data[BITMAP_RED_LIGHT];
		tank_ctx->bitmaps[BITMAP_GREEN_LIGHT].data.hugemem =
				tank_bitmap_data[BITMAP_GREEN_LIGHT];
	} else {
		tank_ctx->loader_state = LOAD_RED_LIGHT;
	}
	workqueue_task_set_work_func(task, tank_loader);
	workqueue_add_task(&main_workqueue, task);
	return;

	// Handle allocation errors.
exit_no_widget:
	win_destroy(wtk_basic_frame_as_child(tank_ctx->frame));
exit_no_frame:
	memcpy(&sysfont, &tank_ctx->old_sysfont, sizeof(struct font));
	membag_free(tank_ctx);
exit_no_context:
	app_desktop_restart();
	return;
}
Пример #20
0
/**
 * \brief Handle maXTouch messages
 *
 * This function handles the maXTouch messages, triggering the drawing of
 * squares around new or moved touches, and removing the squares around
 * released touches.
 *
 * \param device Pointer to mxt_device struct
 */
static void mxt_handler(struct mxt_device *device)
{
	struct mxt_touch_event touch_event;
	gfx_coord_t screen_touch_x, screen_touch_y, screen_touch_size;

	do {
		/* Get the first touch event in queue */
		if (mxt_read_touch_event(device, &touch_event) != STATUS_OK) {
			continue;
		}

		/* Discard non press, movement or release events */
		if (!(touch_event.status &
				(MXT_PRESS_EVENT | MXT_MOVE_EVENT | MXT_RELEASE_EVENT))) {
			continue;
		}

		/* Rescale from 4k touch X-coordinate to the display width */
		screen_touch_x = ((uint32_t)(4096 - touch_event.x) * gfx_get_width()) / 4096;

		/* Rescale from 4k touch Y-coordinate to the display height */
		screen_touch_y = ((uint32_t)(4096 - touch_event.y) * gfx_get_height()) / 4096;

		/* Scale the touch size to a value suitable for the target display */
		screen_touch_size = touch_event.size;

		/* Check if the touch is within the drawing area */
		if (screen_touch_y < (gfx_get_height() - PALLET_HEIGHT)) {
			/* Obtain the color to draw from the pallet colors */
			gfx_color_t draw_color = pallet_colors[selected_pallet_color];

			/* Color pallet index 0 selects multi-color mode */
			if (selected_pallet_color == 0) {
				draw_color = get_next_rainbow_color();
			}

			/* Set clipping area */
			gfx_set_clipping(0, 0, gfx_get_width(),
					(gfx_get_height() - PALLET_HEIGHT - 2));

			/* Draw touch point on the screen in the selected color */
			gfx_draw_filled_circle(screen_touch_x, screen_touch_y,
					screen_touch_size, draw_color, GFX_WHOLE);

			/* Reset clipping area */
			gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height());

		} else if (touch_event.status & MXT_PRESS_EVENT) {
			/* Calculate the pressed pallet entry */
			uint8_t pallete_index = (screen_touch_x / PALLET_COLOR_WIDTH);

			/* The last entry in the pallet clears the screen */
			if (pallete_index == (NUM_PALLET_COLORS - 1)) {
				/* Indicate display is being cleared */
				draw_pallet_labels(true);

				/* Clear the display */
				gfx_draw_filled_rect(0, 0, gfx_get_width(),
						(gfx_get_height() - PALLET_HEIGHT - 1),
						GFX_COLOR_BLACK);

				/* Indicate display has been cleared */
				draw_pallet_labels(false);
			} else {
				/* Change color selection based on the color chosen */
				selected_pallet_color = pallete_index;

				/* Draw new selection box around chosen color */
				update_pallet_selection();
			}
		}

	} while (mxt_is_message_pending(device));
}
Пример #21
0
/**
 * \brief Starts the calibration routines and displays user instructions on screen.
 *
 * \return 0 if calibration is successful, else 1.
 */
uint32_t rtouch_calibrate(void)
{
	uint32_t i;
	uint32_t x, y;
	/* Fill the whole screen with the background color */
	gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(), BGCOLOR);
	/* Print user instructions */
	/* Write center-aligned text string to the top of the display */
	gfx_draw_string_aligned(string_calib_name,
			gfx_get_width() / 2, 60, &sysfont,
			GFX_COLOR_WHITE, TXTCOLOR,
			TEXT_POS_CENTER, TEXT_ALIGN_LEFT);

	gfx_draw_string_aligned(string_calib_instruction,
		gfx_get_width() / 2, 190, &sysfont,
		GFX_COLOR_WHITE, TXTCOLOR,
		TEXT_POS_CENTER, TEXT_ALIGN_LEFT);

	/* Calibration points */
	for (i = 0; i < NUM_TOUCH_POINTS; i++) {
		draw_calibration_point(&gs_calibration_points[i].panel);

		/* Wait for touch & end of conversion */
		rtouch_wait_pressed();

		rtouch_get_raw_point(&x, &y);
		gs_calibration_points[i].raw.x = x;
		gs_calibration_points[i].raw.y = y;
		clear_calibration_point(&gs_calibration_points[i].panel);

		/* Wait for contact loss */
		rtouch_wait_released();
	}

	/* Check if the points acceptable */
	if (rtouch_compute_calibration((rtouch_calibration_point_t *) &gs_calibration_points) == 0) {

		for (i=0;i<NUM_TOUCH_POINTS;i++) {
			g_demo_parameters.calib_points[i].raw.x = gs_calibration_points[i].raw.x;
			g_demo_parameters.calib_points[i].raw.y = gs_calibration_points[i].raw.y;
		}

		/* Commit changes to the parameter area */
		demo_parameters_commit_changes();

		/* Display calibration done string */
		gfx_draw_string_aligned(string_calib_done,
				gfx_get_width() / 2, 130, &sysfont,
				GFX_COLOR_WHITE, TXTCOLOR,
				TEXT_POS_CENTER, TEXT_ALIGN_LEFT);

		return 0;

	} else {
		/* Clear instruction string first */
		gfx_draw_string_aligned(string_calib_instruction,
			gfx_get_width() / 2, 190, &sysfont,
			GFX_COLOR_WHITE, GFX_COLOR_WHITE,
			TEXT_POS_CENTER, TEXT_ALIGN_LEFT);

		/* Show up failed string */
		gfx_draw_string_aligned(string_calib_failed,
			gfx_get_width() / 2, 100, &sysfont,
			GFX_COLOR_WHITE, TXTCOLOR,
			TEXT_POS_CENTER, TEXT_ALIGN_LEFT);

		/* Display retry string */
		gfx_draw_string_aligned(string_calib_retry,
			gfx_get_width() / 2, 190, &sysfont,
			GFX_COLOR_WHITE, TXTCOLOR,
			TEXT_POS_CENTER, TEXT_ALIGN_LEFT);

		/* Wait for contact loss */
		rtouch_wait_released();
		return 1;
	}
}
Пример #22
0
void draw_button_hints() {
    gfx_draw_filled_triangle((gfx_get_width()/2) - 30, 225, (gfx_get_width()/2) - 10, 225, (gfx_get_width()/2) - 20, 225-10, GFX_COLOR_WHITE);
    gfx_draw_filled_triangle((gfx_get_width()/2) + 10, 215, (gfx_get_width()/2) + 30, 215, (gfx_get_width()/2) + 20, 215+10, GFX_COLOR_WHITE);
    gfx_draw_filled_triangle(20,  gfx_get_height() - 30, 20,  gfx_get_height() - 10, 10,  gfx_get_height()-20, GFX_COLOR_WHITE);
    gfx_draw_filled_triangle(300, gfx_get_height() - 30, 300, gfx_get_height() - 10, 310, gfx_get_height()-20, GFX_COLOR_WHITE);
}