Beispiel #1
0
/* Callback for mouse events */
static void panel_check_click(struct yutani_msg_window_mouse_event * evt) {
	if (evt->wid == panel->wid) {
		if (evt->command == YUTANI_MOUSE_EVENT_CLICK) {
			/* Up-down click */
			if (evt->new_x >= width - 24 ) {
				yutani_session_end(yctx);
				_continue = 0;
			} else if (evt->new_x < APP_OFFSET) {
				if (!appmenu) {
					appmenu = yutani_window_create(yctx, APPMENU_WIDTH + APPMENU_PAD_RIGHT, APPMENU_ITEM_HEIGHT * appmenu_items_count + APPMENU_PAD_BOTTOM);
					yutani_window_move(yctx, appmenu, 0, PANEL_HEIGHT);
					bctx = init_graphics_yutani_double_buffer(appmenu);
					redraw_appmenu(-1);
					yutani_focus_window(yctx, appmenu->wid);
				} else {
					/* ??? */
				}
			} else if (evt->new_x > WIDGET_POSITION(1) && evt->new_x < WIDGET_POSITION(0)) {
				/* TODO: More generic widget click handling */
				/* TODO: Show the volume manager */
			} else if (evt->new_x >= APP_OFFSET && evt->new_x < LEFT_BOUND) {
				for (int i = 0; i < MAX_WINDOW_COUNT; ++i) {
					if (ads_by_l[i] == NULL) break;
					if (evt->new_x >= ads_by_l[i]->left && evt->new_x < ads_by_l[i]->left + TOTAL_CELL_WIDTH) {
						yutani_focus_window(yctx, ads_by_l[i]->wid);
						break;
					}
				}
			}
		} else if (evt->command == YUTANI_MOUSE_EVENT_MOVE || evt->command == YUTANI_MOUSE_EVENT_ENTER) {
			/* Movement, or mouse entered window */
			if (evt->new_y < PANEL_HEIGHT) {
				for (int i = 0; i < MAX_WINDOW_COUNT; ++i) {
					if (ads_by_l[i] == NULL) {
						set_focused(-1);
						break;
					}
					if (evt->new_x >= ads_by_l[i]->left && evt->new_x < ads_by_l[i]->left + TOTAL_CELL_WIDTH) {
						set_focused(i);
						break;
					}
				}
			} else {
				set_focused(-1);
			}

			int scroll_direction = 0;
			if (evt->buttons & YUTANI_MOUSE_SCROLL_UP) scroll_direction = -1;
			else if (evt->buttons & YUTANI_MOUSE_SCROLL_DOWN) scroll_direction = 1;

			if (scroll_direction) {
				if (evt->new_x > WIDGET_POSITION(1) && evt->new_y < WIDGET_POSITION(0)) {
					if (scroll_direction == 1) {
						volume_lower();
					} else if (scroll_direction == -1) {
						volume_raise();
					}
				} else if (evt->new_x >= APP_OFFSET && evt->new_x < LEFT_BOUND) {
					if (scroll_direction != 0) {
						struct window_ad * last = window_list->tail ? window_list->tail->value : NULL;
						int focus_next = 0;
						foreach(node, window_list) {
							struct window_ad * ad = node->value;
							if (focus_next) {
								yutani_focus_window(yctx, ad->wid);
								return;
							}
							if (ad->flags & 1) {
								if (scroll_direction == -1) {
									yutani_focus_window(yctx, last->wid);
									return;
								}
								if (scroll_direction == 1) {
									focus_next = 1;
								}
							}
							last = ad;
						}
						if (focus_next && window_list->head) {
							struct window_ad * ad = window_list->head->value;
							yutani_focus_window(yctx, ad->wid);
							return;
						}
					}
				}
			}
		} else if (evt->command == YUTANI_MOUSE_EVENT_LEAVE) {
			/* Mouse left panel window */
			set_focused(-1);
		}
	} else {
Beispiel #2
0
int main (int argc, char ** argv) {
	init_shmemfonts();

	yutani_t * y = yutani_init();

	if (!y) {
		fprintf(stderr, "[glogin] Connection to server failed.\n");
		return 1;
	}

	/* Load config */
	{
		confreader_t * conf = confreader_load("/etc/glogin.conf");

		LOGO_FINAL_OFFSET = confreader_intd(conf, "style", "logo_padding", LOGO_FINAL_OFFSET);
		BOX_WIDTH = confreader_intd(conf, "style", "box_width", BOX_WIDTH);
		BOX_HEIGHT = confreader_intd(conf, "style", "box_height", BOX_HEIGHT);
		BOX_ROUNDNESS = confreader_intd(conf, "style", "box_roundness", BOX_ROUNDNESS);
		CENTER_BOX_X = confreader_intd(conf, "style", "center_box_x", CENTER_BOX_X);
		CENTER_BOX_Y = confreader_intd(conf, "style", "center_box_y", CENTER_BOX_Y);
		BOX_LEFT = confreader_intd(conf, "style", "box_left", BOX_LEFT);
		BOX_RIGHT = confreader_intd(conf, "style", "box_right", BOX_RIGHT);
		BOX_TOP = confreader_intd(conf, "style", "box_top", BOX_TOP);
		BOX_BOTTOM = confreader_intd(conf, "style", "box_bottom", BOX_BOTTOM);
		BOX_COLOR_R = confreader_intd(conf, "style", "box_color_r", BOX_COLOR_R);
		BOX_COLOR_G = confreader_intd(conf, "style", "box_color_g", BOX_COLOR_G);
		BOX_COLOR_B = confreader_intd(conf, "style", "box_color_b", BOX_COLOR_B);
		BOX_COLOR_A = confreader_intd(conf, "style", "box_color_a", BOX_COLOR_A);

		WALLPAPER = confreader_getd(conf, "image", "wallpaper", WALLPAPER);
		LOGO = confreader_getd(conf, "image", "logo", LOGO);

		confreader_free(conf);

		TRACE("Loading complete");
	}

	TRACE("Loading logo...");
	load_sprite_png(&logo, LOGO);
	TRACE("... done.");

	/* Generate surface for background */
	sprite_t * bg_sprite;

	int width  = y->display_width;
	int height = y->display_height;
	int skip_animation = 0;

	/* Do something with a window */
	TRACE("Connecting to window server...");
	yutani_window_t * wina = yutani_window_create(y, width, height);
	assert(wina);
	yutani_set_stack(y, wina, 0);
	ctx = init_graphics_yutani_double_buffer(wina);
	draw_fill(ctx, rgba(0,0,0,255));
	yutani_flip(y, wina);
	TRACE("... done.");


redo_everything:
	win_width = width;
	win_height = height;

	cairo_surface_t * cs = cairo_image_surface_create_for_data((void*)ctx->backbuffer, CAIRO_FORMAT_ARGB32, ctx->width, ctx->height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, ctx->width));
	cairo_t * cr = cairo_create(cs);


	TRACE("Loading wallpaper...");
	{
		sprite_t * wallpaper = malloc(sizeof(sprite_t));
		load_sprite_png(wallpaper, WALLPAPER);

		float x = (float)width  / (float)wallpaper->width;
		float y = (float)height / (float)wallpaper->height;

		int nh = (int)(x * (float)wallpaper->height);
		int nw = (int)(y * (float)wallpaper->width);;

		bg_sprite = create_sprite(width, height, ALPHA_OPAQUE);
		gfx_context_t * bg = init_graphics_sprite(bg_sprite);

		if (nw > width) {
			draw_sprite_scaled(bg, wallpaper, (width - nw) / 2, 0, nw, height);
		} else {
			draw_sprite_scaled(bg, wallpaper, 0, (height - nh) / 2, width, nh);
		}

		/* Three box blurs = good enough approximation of a guassian, but faster*/
		blur_context_box(bg, 20);
		blur_context_box(bg, 20);
		blur_context_box(bg, 20);

		free(bg);
		free(wallpaper);
	}
	TRACE("... done.");

	while (1) {

		yutani_set_stack(y, wina, 0);
		yutani_focus_window(y, wina->wid);

		draw_fill(ctx, rgb(0,0,0));
		draw_sprite(ctx, bg_sprite, center_x(width), center_y(height));
		flip(ctx);
		yutani_flip(y, wina);

		char * foo = malloc(sizeof(uint32_t) * width * height);
		memcpy(foo, ctx->backbuffer, sizeof(uint32_t) * width * height);

		TRACE("Begin animation.");
		if (!skip_animation) {
			struct timeval start;
			gettimeofday(&start, NULL);

			while (1) {
				uint32_t tick;
				struct timeval t;
				gettimeofday(&t, NULL);

				uint32_t sec_diff = t.tv_sec - start.tv_sec;
				uint32_t usec_diff = t.tv_usec - start.tv_usec;

				if (t.tv_usec < start.tv_usec) {
					sec_diff -= 1;
					usec_diff = (1000000 + t.tv_usec) - start.tv_usec;
				}

				tick = (uint32_t)(sec_diff * 1000 + usec_diff / 1000);
				int i = (float)LOGO_FINAL_OFFSET * (float)tick / 700.0f;
				if (i >= LOGO_FINAL_OFFSET) break;

				memcpy(ctx->backbuffer, foo, sizeof(uint32_t) * width * height);
				draw_sprite(ctx, &logo, center_x(logo.width), center_y(logo.height) - i);
				flip(ctx);
				yutani_flip_region(y, wina, center_x(logo.width), center_y(logo.height) - i, logo.width, logo.height + 5);
				usleep(10000);
			}
		}
		TRACE("End animation.");
		skip_animation = 0;

		size_t buf_size = wina->width * wina->height * sizeof(uint32_t);
		char * buf = malloc(buf_size);

		uint32_t i = 0;

		uint32_t black = rgb(0,0,0);
		uint32_t white = rgb(255,255,255);

		int x_offset = 65;
		int y_offset = 64;

		int fuzz = 3;

		char username[INPUT_SIZE] = {0};
		char password[INPUT_SIZE] = {0};
		char hostname[512];

		// we do it here to calculate the final string position
		get_updated_hostname_with_time_info(hostname);

		char kernel_v[512];

		{
			struct utsname u;
			uname(&u);
			/* UTF-8 Strings FTW! */
			uint8_t * os_name_ = "とあるOS";
			uint32_t l = snprintf(kernel_v, 512, "%s %s", os_name_, u.release);
		}

		uid = 0;

		int box_x, box_y;

		if (CENTER_BOX_X) {
			box_x = center_x(BOX_WIDTH);
		} else if (BOX_LEFT == -1) {
			box_x = win_width - BOX_RIGHT - BOX_WIDTH;
		} else {
			box_x = BOX_LEFT;
		}
		if (CENTER_BOX_Y) {
			box_y = center_y(0) + 8;
		} else if (BOX_TOP == -1) {
			box_y = win_width - BOX_BOTTOM - BOX_HEIGHT;
		} else {
			box_y = BOX_TOP;
		}

		int focus = 0;

		set_font_size(11);
		int hostname_label_left = width - 10 - draw_string_width(hostname);
		int kernel_v_label_left = 10;

		struct text_box username_box = { (BOX_WIDTH - 170) / 2, 30, 170, 20, rgb(0,0,0), NULL, 0, 0, 0, username, "Username" };
		struct text_box password_box = { (BOX_WIDTH - 170) / 2, 58, 170, 20, rgb(0,0,0), NULL, 0, 1, 0, password, "Password" };

		struct login_container lc = { box_x, box_y, BOX_WIDTH, BOX_HEIGHT, &username_box, &password_box, 0 };

		username_box.parent = &lc;
		password_box.parent = &lc;

		while (1) {
			focus = 0;
			memset(username, 0x0, INPUT_SIZE);
			memset(password, 0x0, INPUT_SIZE);

			while (1) {

				// update time info
				get_updated_hostname_with_time_info(hostname);

				memcpy(ctx->backbuffer, foo, sizeof(uint32_t) * width * height);
				draw_sprite(ctx, &logo, center_x(logo.width), center_y(logo.height) - LOGO_FINAL_OFFSET);

				set_font_size(11);
				draw_string_shadow(ctx, hostname_label_left, height - 12, white, hostname, rgb(0,0,0), 2, 1, 1, 3.0);
				draw_string_shadow(ctx, kernel_v_label_left, height - 12, white, kernel_v, rgb(0,0,0), 2, 1, 1, 3.0);

				if (focus == USERNAME_BOX) {
					username_box.is_focused = 1;
					password_box.is_focused = 0;
				} else if (focus == PASSWORD_BOX) {
					username_box.is_focused = 0;
					password_box.is_focused = 1;
				} else {
					username_box.is_focused = 0;
					password_box.is_focused = 0;
				}

				draw_login_container(cr, &lc);

				flip(ctx);
				yutani_flip(y, wina);

				struct yutani_msg_key_event kbd;
				struct yutani_msg_window_mouse_event mou;
				int msg_type = 0;
collect_events:
				do {
					yutani_msg_t * msg = yutani_poll(y);
					switch (msg->type) {
						case YUTANI_MSG_KEY_EVENT:
							{
								struct yutani_msg_key_event * ke = (void*)msg->data;
								if (ke->event.action == KEY_ACTION_DOWN) {
									memcpy(&kbd, ke, sizeof(struct yutani_msg_key_event));
									msg_type = 1;
								}
							}
							break;
						case YUTANI_MSG_WINDOW_MOUSE_EVENT:
							{
								struct yutani_msg_window_mouse_event * me = (void*)msg->data;
								memcpy(&mou, me, sizeof(struct yutani_msg_mouse_event));
								msg_type = 2;
							}
							break;
						case YUTANI_MSG_WELCOME:
							{
								struct yutani_msg_welcome * mw = (void*)msg->data;
								yutani_window_resize(y, wina, mw->display_width, mw->display_height);
							}
							break;
						case YUTANI_MSG_RESIZE_OFFER:
							{
								struct yutani_msg_window_resize * wr = (void*)msg->data;
								width = wr->width;
								height = wr->height;
								yutani_window_resize_accept(y, wina, width, height);
								reinit_graphics_yutani(ctx, wina);
								yutani_window_resize_done(y, wina);

								sprite_free(bg_sprite);
								cairo_destroy(cr);
								cairo_surface_destroy(cs);

								skip_animation = 1;
								goto redo_everything;
							}
							break;
					}
					free(msg);
				} while (!msg_type);

				if (msg_type == 1) {

					if (kbd.event.keycode == '\n') {
						if (focus == USERNAME_BOX) {
							focus = PASSWORD_BOX;
							continue;
						} else if (focus == PASSWORD_BOX) {
							break;
						} else {
							focus = USERNAME_BOX;
							continue;
						}
					}

					if (kbd.event.keycode == '\t') {
						if (focus == USERNAME_BOX) {
							focus = PASSWORD_BOX;
						} else {
							focus = USERNAME_BOX;
						}
						continue;
					}

					if (kbd.event.key) {

						if (!focus) {
							focus = USERNAME_BOX;
						}

						if (focus == USERNAME_BOX) {
							buffer_put(username, kbd.event.key);
						} else if (focus == PASSWORD_BOX) {
							buffer_put(password, kbd.event.key);
						}

					}

				} else if (msg_type == 2) {

					if ((mou.command == YUTANI_MOUSE_EVENT_DOWN
					     && mou.buttons & YUTANI_MOUSE_BUTTON_LEFT)
					    || (mou.command == YUTANI_MOUSE_EVENT_CLICK)) {
						/* Determine if we were inside of a text box */

						if (mou.new_x >= lc.x + username_box.x &&
						    mou.new_x <= lc.x + username_box.x + username_box.width &&
						    mou.new_y >= lc.y + username_box.y &&
						    mou.new_y <= lc.y + username_box.y + username_box.height) {
							/* Ensure this box is focused. */
							focus = USERNAME_BOX;
							continue;
						} else if (mou.new_x >= lc.x + password_box.x &&
						    mou.new_x <= lc.x + password_box.x + password_box.width &&
						    mou.new_y >= lc.y + password_box.y &&
						    mou.new_y <= lc.y + password_box.y + password_box.height) {
							/* Ensure this box is focused. */
							focus = PASSWORD_BOX;
							continue;
						} else {
							focus = 0;
							continue;
						}

					} else {
						goto collect_events;
					}
				}

			}

			uid = toaru_auth_check_pass(username, password);

			if (uid >= 0) {
				break;
			}
			lc.show_error = 1;
		}

		memcpy(ctx->backbuffer, foo, sizeof(uint32_t) * width * height);
		flip(ctx);
		yutani_flip(y, wina);
		syscall_yield();

		pid_t _session_pid = fork();
		if (!_session_pid) {
			setuid(uid);
			toaru_auth_set_vars();
			char * args[] = {"/bin/gsession", NULL};
			execvp(args[0], args);
		}

		free(foo);
		free(buf);

		waitpid(_session_pid, NULL, 0);
	}

	yutani_close(y, wina);


	return 0;
}
Beispiel #3
0
int main(int argc, char * argv[]) {

	if (argc < 2) {
		fprintf(stderr, "Usage: %s image_file\n", argv[0]);
		return 1;
	}

	file_name = argv[1];

	load_sprite_png(&image, argv[1]);

	yctx = yutani_init();

	init_decorations();

	win = yutani_window_create(yctx, image.width + decor_width(), image.height + decor_height());
	yutani_window_move(yctx, win, center_x(image.width + decor_width()), center_y(image.height + decor_height()));
	ctx = init_graphics_yutani_double_buffer(win);

	int stride;

	stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, win->width);
	surface_win = cairo_image_surface_create_for_data(ctx->backbuffer, CAIRO_FORMAT_ARGB32, win->width, win->height, stride);
	cr_win = cairo_create(surface_win);

	yutani_window_advertise_icon(yctx, win, "Image Viewer", "image-viewer");

	redraw();

	yutani_focus_window(yctx, win->wid);

	while (!should_exit) {
		yutani_msg_t * m = yutani_poll(yctx);

		if (m) {
			switch (m->type) {
				case YUTANI_MSG_KEY_EVENT:
					{
						struct yutani_msg_key_event * ke = (void*)m->data;
						if (ke->event.key == 'q' && ke->event.action == KEY_ACTION_DOWN) {
							should_exit = 1;
						}
					}
					break;
				case YUTANI_MSG_WINDOW_FOCUS_CHANGE:
					{
						struct yutani_msg_window_focus_change * wf = (void*)m->data;
						if (wf->wid == win->wid) {
							win->focused = wf->focused;
							redraw();
						}
					}
					break;
				case YUTANI_MSG_WINDOW_MOUSE_EVENT:
					{
						struct yutani_msg_window_mouse_event * me = (void*)m->data;
						if (me->wid != win->wid) break;
						int result = decor_handle_event(yctx, m);
						switch (result) {
							case DECOR_CLOSE:
								should_exit = 1;
								break;
							default:
								/* Other actions */
								break;
						}
					}
					break;
				case YUTANI_MSG_SESSION_END:
					should_exit = 1;
					break;
				default:
					break;
			}
			free(m);
		}
	}

	return 0;
}