void * draw_thread(void * garbage) { (void)garbage; double time = 0; /* Generate a palette */ uint32_t palette[256]; for (int x = 0; x < 256; ++x) { palette[x] = hsv_to_rgb(x,1.0,1.0); } while (!should_exit) { time += 1.0; int w = win_width; int h = win_height; spin_lock(&draw_lock); for (int x = 0; x < win_width; ++x) { for (int y = 0; y < win_height; ++y) { double value = sin(dist(x + time, y, 128.0, 128.0) / 8.0) + sin(dist(x, y, 64.0, 64.0) / 8.0) + sin(dist(x, y + time / 7, 192.0, 64) / 7.0) + sin(dist(x, y, 192.0, 100.0) / 8.0); GFX(ctx, x + off_x, y + off_y) = palette[(int)((value + 4) * 32)]; } } redraw_borders(); flip(ctx); yutani_flip(yctx, wina); spin_unlock(&draw_lock); syscall_yield(); } }
void * draw_thread(void * glctx) { while (!quit) { display(); flip(ctx); yutani_flip(yctx, wina); syscall_yield(); } pthread_exit(0); }
// Send val to whom. This function keeps trying until // it succeeds. It should panic() on any error other than // -E_IPC_NOT_RECV. // // Hint: use syscall_yield() to be CPU-friendly. void ipc_send(u_int whom, u_int val, u_int srcva, u_int perm) { int r; while ((r = syscall_ipc_can_send(whom, val, srcva, perm)) == -E_IPC_NOT_RECV) { syscall_yield(); //writef("QQ"); } if (r == 0) { return; } user_panic("error in ipc_send: %d", r); }
int main (int argc, char ** argv) { setup_windowing(); int width = wins_globals->server_width; int height = wins_globals->server_height; win_width = width; win_height = height; /* Do something with a window */ window_t * wina = window_create(0,0, width, height); assert(wina); window_reorder (wina, 0); ctx = init_graphics_window_double_buffer(wina); draw_fill(ctx, rgb(127,127,127)); flip(ctx); #if 1 printf("Loading background...\n"); init_sprite(0, "/usr/share/login-background.bmp", NULL); printf("Background loaded.\n"); draw_sprite_scaled(ctx, sprites[0], 0, 0, width, height); #endif #if 0 init_sprite(1, "/usr/share/bs.bmp", "/usr/share/bs-alpha.bmp"); draw_sprite_scaled(sprites[1], center_x(sprites[1]->width), center_y(sprites[1]->height), sprites[1]->width, sprites[1]->height); #endif flip(ctx); while (1) { syscall_yield(); //syscall_wait(wins_globals->server_pid); } #if 0 window_destroy(window); // (will close on exit) teardown_windowing(); #endif return 0; }
int main (int argc, char ** argv) { left = 100; top = 100; width = 500; height = 500; yctx = yutani_init(); wina = yutani_window_create(yctx, width, height); yutani_window_move(yctx, wina, left, top); ctx = init_graphics_yutani(wina); draw_fill(ctx, rgb(0,0,0)); pthread_t thread; pthread_create(&thread, NULL, draw_thread, NULL); 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.action == KEY_ACTION_DOWN && ke->event.keycode == 'q') { should_exit = 1; syscall_yield(); } } break; case YUTANI_MSG_SESSION_END: should_exit = 1; break; default: break; } } free(m); } yutani_close(yctx, wina); return 0; }
int cons_read(struct Fd *fd, void *vbuf, u_int n, u_int offset) { int c; USED(offset); // printf("got into cons_read"); if (n == 0) return 0; while ((c = syscall_cgetc()) == 0) syscall_yield(); if (c!='\r') writef("%c",c); else writef("\n"); if (c < 0) return c; if (c == 0x04) // ctl-d is eof return 0; *(char*)vbuf = c; return 1; }
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; }
static void spin_lock(int volatile * lock) { while(__sync_lock_test_and_set(lock, 0x01)) { syscall_yield(); } }
int main (int argc, char ** argv) { yutani_t * yctx; yutani_window_t * wina; gfx_context_t * ctx; int should_exit = 0; int blur = 0; int stopped = 0; int left = 30; int top = 30; int width = 500; int height = 500; yctx = yutani_init(); wina = yutani_window_create(yctx, width, height); yutani_window_move(yctx, wina, left, top); ctx = init_graphics_yutani_double_buffer(wina); draw_fill(ctx, rgb(0,0,0)); yutani_window_update_shape(yctx, wina, YUTANI_SHAPE_THRESHOLD_HALF); yutani_window_advertise_icon(yctx, wina, "Mesa Gears", "gears"); OSMesaContext gl_ctx = OSMesaCreateContext(OSMESA_BGRA, NULL); if (resize(ctx, gl_ctx)) { fprintf(stderr, "%s: Something bad happened.\n", argv[0]); goto finish; } init(); while (!should_exit) { yutani_msg_t * m = yutani_poll_async(yctx); if (m) { switch (m->type) { case YUTANI_MSG_KEY_EVENT: { struct yutani_msg_key_event * ke = (void*)m->data; if (ke->event.action == KEY_ACTION_DOWN) { switch (ke->event.keycode) { case 'q': should_exit = 1; free(m); goto finish; case 'b': blur = (1-blur); break; case 's': stopped = (1-stopped); break; case KEY_ARROW_LEFT: view_roty += 5.0; break; case KEY_ARROW_RIGHT: view_roty -= 5.0; break; case KEY_ARROW_UP: view_rotx += 5.0; break; case KEY_ARROW_DOWN: view_rotx -= 5.0; break; default: break; } } } break; case YUTANI_MSG_WINDOW_MOUSE_EVENT: { struct yutani_msg_window_mouse_event * me = (void*)m->data; if (me->command == YUTANI_MOUSE_EVENT_DOWN && me->buttons & YUTANI_MOUSE_BUTTON_LEFT) { yutani_window_drag_start(yctx, wina); } } break; case YUTANI_MSG_SESSION_END: should_exit = 1; break; case YUTANI_MSG_RESIZE_OFFER: { struct yutani_msg_window_resize * wr = (void*)m->data; yutani_window_resize_accept(yctx, wina, wr->width, wr->height); reinit_graphics_yutani(ctx, wina); resize(ctx, gl_ctx); draw(); yutani_window_resize_done(yctx, wina); flip(ctx); yutani_flip(yctx, wina); yutani_window_update_shape(yctx, wina, 1); /* Reset statistics */ frames = 0; start_time = 0; } default: break; } free(m); } fps(); if (!stopped) { angle += 0.2; } draw(); if (blur) { blur_context_box(ctx, 20); } flip(ctx); yutani_flip(yctx, wina); syscall_yield(); } finish: OSMesaDestroyContext(gl_ctx); yutani_close(yctx, wina); return 0; }
static void spin_lock(int volatile * lock, const char * caller) { while(__sync_lock_test_and_set(lock, 0x01)) { syscall_yield(); } _lock_holder = caller; }