static void show_prompt (ply_boot_splash_plugin_t *plugin, const char *prompt, const char *entry_text) { ply_list_node_t *node; ply_trace ("showing prompt"); node = ply_list_get_first_node (plugin->views); while (node != NULL) { ply_list_node_t *next_node; view_t *view; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); view_show_prompt (view, prompt); ply_entry_set_text (view->entry, entry_text); node = next_node; } }
static void show_message (ply_boot_splash_plugin_t *plugin, const char *message) { ply_trace ("Showing message '%s'", message); ply_list_node_t *node; node = ply_list_get_first_node (plugin->views); while (node != NULL) { ply_list_node_t *next_node; view_t *view; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); ply_label_set_text (view->message_label, message); ply_label_show (view->message_label, view->display, 10, 10); ply_pixel_display_draw_area (view->display, 10, 10, ply_label_get_width (view->message_label), ply_label_get_height (view->message_label)); node = next_node; } }
static void show_password_prompt (ply_boot_splash_plugin_t *plugin, const char *text, int number_of_bullets) { ply_list_node_t *node; node = ply_list_get_first_node (plugin->views); while (node != NULL) { ply_list_node_t *next_node; view_t *view; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); view_show_prompt (view, text); ply_entry_set_bullet_count (view->entry, number_of_bullets); node = next_node; } }
static bool encoder_is_available (ply_renderer_backend_t *backend, uint32_t encoder_id) { ply_list_node_t *node; node = ply_list_get_first_node (backend->heads); while (node != NULL) { ply_list_node_t *next_node; ply_renderer_head_t *head; head = (ply_renderer_head_t *) ply_list_node_get_data (node); next_node = ply_list_get_next_node (backend->heads, node); if (head->encoder_id == encoder_id) return false; node = next_node; } return true; }
static void free_stars (view_t *view) { ply_list_node_t *node; assert (view != NULL); node = ply_list_get_first_node (view->stars); while (node != NULL) { ply_list_node_t *next_node; star_t *star; star = (star_t *) ply_list_node_get_data (node); next_node = ply_list_get_next_node (view->stars, node); star_free (star); node = next_node; } ply_list_free (view->stars); view->stars = NULL; }
static void free_views (ply_boot_splash_plugin_t *plugin) { ply_list_node_t *node; node = ply_list_get_first_node (plugin->views); while (node != NULL) { ply_list_node_t *next_node; view_t *view; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); view_free (view); ply_list_remove_node (plugin->views, node); node = next_node; } ply_list_free (plugin->views); plugin->views = NULL; }
static void start_animation (ply_boot_splash_plugin_t *plugin) { ply_list_node_t *node; assert (plugin != NULL); assert (plugin->loop != NULL); redraw_views (plugin); if (plugin->message != NULL) show_message (plugin); if (plugin->is_animating) return; node = ply_list_get_first_node (plugin->views); while (node != NULL) { ply_list_node_t *next_node; view_t *view; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); view_start_animation (view); node = next_node; } plugin->is_animating = true; animate_frame (plugin, 0); ply_event_loop_watch_for_timeout (plugin->loop, 1.0, (ply_event_loop_timeout_handler_t) on_timeout, plugin); }
static void start_animation (ply_boot_splash_plugin_t *plugin) { ply_list_node_t *node; if (plugin->is_animating) return; node = ply_list_get_first_node (plugin->views); while (node != NULL) { ply_list_node_t *next_node; view_t *view; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); view_start_animation (view); node = next_node; } plugin->is_animating = true; }
static void remove_pixel_display (ply_boot_splash_plugin_t *plugin, ply_pixel_display_t *display) { ply_list_node_t *node; node = ply_list_get_first_node (plugin->views); while (node != NULL) { view_t *view; ply_list_node_t *next_node; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); if (view->display == display) { ply_pixel_display_set_draw_handler (view->display, NULL, NULL); view_free (view); ply_list_remove_node (plugin->views, node); return; } node = next_node; } }
static void start_end_animation (ply_boot_splash_plugin_t *plugin, ply_trigger_t *trigger) { ply_list_node_t *node; node = ply_list_get_first_node (plugin->views); while (node != NULL) { ply_list_node_t *next_node; view_t *view; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); ply_progress_animation_hide (view->progress_animation); ply_trigger_ignore_next_pull (trigger); view_start_end_animation (view, trigger); node = next_node; } ply_trigger_pull (trigger, NULL); }
static bool load_views (ply_boot_splash_plugin_t *plugin) { ply_list_node_t *node; bool view_loaded; view_loaded = false; node = ply_list_get_first_node (plugin->views); while (node != NULL) { ply_list_node_t *next_node; view_t *view; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); if (view_load (view)) view_loaded = true; node = next_node; } return view_loaded; }
static void stop_animation (ply_boot_splash_plugin_t *plugin, ply_trigger_t *trigger) { ply_list_node_t *node; assert (plugin != NULL); assert (plugin->loop != NULL); if (!plugin->is_animating) return; ply_trace ("stopping animation%s", trigger != NULL ? " with trigger" : ""); plugin->is_animating = false; node = ply_list_get_first_node (plugin->views); while (node != NULL) { ply_list_node_t *next_node; view_t *view; view = ply_list_node_get_data (node); next_node = ply_list_get_next_node (plugin->views, node); ply_progress_bar_hide (view->progress_bar); if (trigger != NULL) ply_trigger_ignore_next_pull (trigger); ply_throbber_stop (view->throbber, trigger); node = next_node; } if (trigger != NULL) ply_trigger_pull (trigger, NULL); }
void ply_terminal_stop_watching_for_input (ply_terminal_t *terminal, ply_terminal_input_handler_t input_handler, void *user_data) { ply_list_node_t *node; node = ply_list_get_first_node (terminal->input_closures); while (node != NULL) { ply_terminal_input_closure_t *closure; ply_list_node_t *next_node; closure = ply_list_node_get_data (node); next_node = ply_list_get_next_node (terminal->input_closures, node); if (closure->handler == input_handler && closure->user_data == user_data) { free (closure); ply_list_remove_node (terminal->input_closures, node); } node = next_node; } }
void ply_progress_save_cache (ply_progress_t* progress, const char *filename) { FILE *fp; ply_list_node_t *node; double cur_time = ply_progress_get_time(progress); fp = fopen (filename,"w"); if (fp == NULL) return; node = ply_list_get_first_node (progress->current_message_list); while (node) { ply_progress_message_t *message = ply_list_node_get_data (node); double percentage = message->time / cur_time; if (!message->disabled) fprintf (fp, "%.3lf:%s\n", percentage, message->string); node = ply_list_get_next_node (progress->current_message_list, node); } fclose (fp); }
static int do_test (void) { ply_rectangle_t rectangle; char cover[COVER_SIZE][COVER_SIZE]; int i; unsigned long x, y; ply_region_t *region; ply_list_node_t *node; region = ply_region_new (); for (y = 0; y < COVER_SIZE; y++) { for (x = 0; x < COVER_SIZE; x++) { cover[y][x] = 0; } } for (i = 0; i < RECTANGLE_COUNT; i++) { rectangle.x = random() % COVER_SIZE-5; rectangle.y = random() % COVER_SIZE-5; rectangle.width = 1 + random() % 20; rectangle.height = 1 + random() % 20; printf("Adding X=%ld Y=%ld W=%ld H=%ld\n", rectangle.x, rectangle.y, rectangle.width, rectangle.height); cover_with_rect(cover, &rectangle, 100); /* 100 means covered by origial squares */ ply_region_add_rectangle (region, &rectangle); } printf("Converted to:\n"); int count = 0; ply_list_t *rectangle_list = ply_region_get_rectangle_list (region); for (node = ply_list_get_first_node (rectangle_list); node; node = ply_list_get_next_node (rectangle_list, node)) { ply_rectangle_t *small_rectangle = ply_list_node_get_data (node); printf("Processed X=%ld Y=%ld W=%ld H=%ld\n", small_rectangle->x, small_rectangle->y, small_rectangle->width, small_rectangle->height); cover_with_rect(cover, small_rectangle, 0); count++; } printf("Rectangles in:%d out:%d\n", RECTANGLE_COUNT, count); count=0; for (y = 0; y < COVER_SIZE; y++) { printf("%03ld ", y); for (x = 0; x < COVER_SIZE; x++) { if (cover[y][x] >= 100) { if (cover[y][x] == 100) { printf("-"); /* "-" means should have been covered but wasn't */ count++; } else { if (cover[y][x] == 101) printf("O"); /* "O" means correctly covered */ else { printf("%d", cover[y][x] - 101); count++; /* 1+ means covered multiple times*/ } } } else { if (cover[y][x] == 0) printf("o"); /* "o" means not involved*/ else { printf("%c", 'A' - 1 + cover[y][x]); count++; /* A+ means covered despite being not involved*/ } } } printf("\n"); } printf("errors:%d\n", count); return count; }
static void script_parse_exp_free (script_exp_t *exp) { if (!exp) return; switch (exp->type) { case SCRIPT_EXP_TYPE_PLUS: case SCRIPT_EXP_TYPE_MINUS: case SCRIPT_EXP_TYPE_MUL: case SCRIPT_EXP_TYPE_DIV: case SCRIPT_EXP_TYPE_MOD: case SCRIPT_EXP_TYPE_EQ: case SCRIPT_EXP_TYPE_NE: case SCRIPT_EXP_TYPE_GT: case SCRIPT_EXP_TYPE_GE: case SCRIPT_EXP_TYPE_LT: case SCRIPT_EXP_TYPE_LE: case SCRIPT_EXP_TYPE_AND: case SCRIPT_EXP_TYPE_OR: case SCRIPT_EXP_TYPE_EXTEND: case SCRIPT_EXP_TYPE_ASSIGN: case SCRIPT_EXP_TYPE_ASSIGN_PLUS: case SCRIPT_EXP_TYPE_ASSIGN_MINUS: case SCRIPT_EXP_TYPE_ASSIGN_MUL: case SCRIPT_EXP_TYPE_ASSIGN_DIV: case SCRIPT_EXP_TYPE_ASSIGN_MOD: case SCRIPT_EXP_TYPE_ASSIGN_EXTEND: case SCRIPT_EXP_TYPE_HASH: script_parse_exp_free (exp->data.dual.sub_a); script_parse_exp_free (exp->data.dual.sub_b); break; case SCRIPT_EXP_TYPE_NOT: case SCRIPT_EXP_TYPE_POS: case SCRIPT_EXP_TYPE_NEG: case SCRIPT_EXP_TYPE_PRE_INC: case SCRIPT_EXP_TYPE_PRE_DEC: case SCRIPT_EXP_TYPE_POST_INC: case SCRIPT_EXP_TYPE_POST_DEC: script_parse_exp_free (exp->data.sub); break; case SCRIPT_EXP_TYPE_TERM_NUMBER: case SCRIPT_EXP_TYPE_TERM_NULL: case SCRIPT_EXP_TYPE_TERM_LOCAL: case SCRIPT_EXP_TYPE_TERM_GLOBAL: case SCRIPT_EXP_TYPE_TERM_THIS: break; case SCRIPT_EXP_TYPE_TERM_SET: { ply_list_node_t *node; for (node = ply_list_get_first_node (exp->data.parameters); node; node = ply_list_get_next_node (exp->data.parameters, node)) { script_exp_t *sub = ply_list_node_get_data (node); script_parse_exp_free (sub); } ply_list_free (exp->data.parameters); break; } case SCRIPT_EXP_TYPE_FUNCTION_EXE: { ply_list_node_t *node; for (node = ply_list_get_first_node (exp->data.function_exe.parameters); node; node = ply_list_get_next_node (exp->data.function_exe.parameters, node)) { script_exp_t *sub = ply_list_node_get_data (node); script_parse_exp_free (sub); } ply_list_free (exp->data.function_exe.parameters); script_parse_exp_free (exp->data.function_exe.name); break; } case SCRIPT_EXP_TYPE_FUNCTION_DEF: /* FIXME merge the frees with one from op_free */ { if (exp->data.function_def->type == SCRIPT_FUNCTION_TYPE_SCRIPT) script_parse_op_free (exp->data.function_def->data.script); ply_list_node_t *node; for (node = ply_list_get_first_node (exp->data.function_def->parameters); node; node = ply_list_get_next_node (exp->data.function_def->parameters, node)) { char *arg = ply_list_node_get_data (node); free (arg); } ply_list_free (exp->data.function_def->parameters); free (exp->data.function_def); break; } case SCRIPT_EXP_TYPE_TERM_STRING: case SCRIPT_EXP_TYPE_TERM_VAR: free (exp->data.string); break; } script_debug_remove_element (exp); free (exp); }
static void ply_boot_connection_on_request (ply_boot_connection_t *connection) { ply_boot_server_t *server; char *command, *argument; assert (connection != NULL); assert (connection->fd >= 0); server = connection->server; assert (server != NULL); if (!ply_boot_connection_read_request (connection, &command, &argument)) { ply_trace ("could not read connection request"); return; } if (!ply_boot_connection_is_from_root (connection)) { ply_error ("request came from non-root user"); if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK))) ply_error ("could not write bytes: %m"); free (command); return; } if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_UPDATE) == 0) { ply_trace ("got update request"); if (server->update_handler != NULL) server->update_handler (server->user_data, argument, server); free (argument); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SYSTEM_INITIALIZED) == 0) { ply_trace ("got system initialized notification"); if (server->system_initialized_handler != NULL) server->system_initialized_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_ERROR) == 0) { ply_trace ("got error notification"); if (server->error_handler != NULL) server->error_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_SHOW_SPLASH) == 0) { ply_trace ("got show splash request"); if (server->show_splash_handler != NULL) server->show_splash_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HIDE_SPLASH) == 0) { ply_trace ("got hide splash request"); if (server->hide_splash_handler != NULL) server->hide_splash_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_DEACTIVATE) == 0) { ply_trigger_t *deactivate_trigger; ply_trace ("got deactivate request"); deactivate_trigger = ply_trigger_new (NULL); ply_trigger_add_handler (deactivate_trigger, (ply_trigger_handler_t) ply_boot_connection_on_deactivated, connection); if (server->deactivate_handler != NULL) server->deactivate_handler (server->user_data, deactivate_trigger, server); free (argument); free (command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_REACTIVATE) == 0) { ply_trace ("got reactivate request"); if (server->reactivate_handler != NULL) server->reactivate_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUIT) == 0) { bool retain_splash; ply_trigger_t *quit_trigger; retain_splash = (bool) argument[0]; ply_trace ("got quit %srequest", retain_splash? "--retain-splash " : ""); quit_trigger = ply_trigger_new (NULL); ply_trigger_add_handler (quit_trigger, (ply_trigger_handler_t) ply_boot_connection_on_quit_complete, connection); if (server->quit_handler != NULL) server->quit_handler (server->user_data, retain_splash, quit_trigger, server); free(argument); free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD) == 0) { ply_trigger_t *answer; ply_trace ("got password request"); answer = ply_trigger_new (NULL); ply_trigger_add_handler (answer, (ply_trigger_handler_t) ply_boot_connection_on_password_answer, connection); if (server->ask_for_password_handler != NULL) server->ask_for_password_handler (server->user_data, argument, answer, server); /* will reply later */ free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_CACHED_PASSWORD) == 0) { ply_list_node_t *node; ply_buffer_t *buffer; size_t buffer_size; uint32_t size; ply_trace ("got cached password request"); buffer = ply_buffer_new (); node = ply_list_get_first_node (server->cached_passwords); ply_trace ("There are %d cached passwords", ply_list_get_length (server->cached_passwords)); /* Add each answer separated by their NUL terminators into * a buffer that we write out to the client */ while (node != NULL) { ply_list_node_t *next_node; const char *password; next_node = ply_list_get_next_node (server->cached_passwords, node); password = (const char *) ply_list_node_get_data (node); ply_buffer_append_bytes (buffer, password, strlen (password) + 1); node = next_node; } buffer_size = ply_buffer_get_size (buffer); /* splash plugin doesn't have any cached passwords */ if (buffer_size == 0) { if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER))) ply_error ("could not write bytes: %m"); } else { size = buffer_size; ply_trace ("writing %d cached answers", ply_list_get_length (server->cached_passwords)); if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_MULTIPLE_ANSWERS, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_MULTIPLE_ANSWERS)) || !ply_write_uint32 (connection->fd, size) || !ply_write (connection->fd, ply_buffer_get_bytes (buffer), size)) ply_error ("could not write bytes: %m"); } ply_buffer_free (buffer); free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION) == 0) { ply_trigger_t *answer; ply_trace ("got question request"); answer = ply_trigger_new (NULL); ply_trigger_add_handler (answer, (ply_trigger_handler_t) ply_boot_connection_on_question_answer, connection); if (server->ask_question_handler != NULL) server->ask_question_handler (server->user_data, argument, answer, server); /* will reply later */ free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_MESSAGE) == 0) { ply_trace ("got message request"); if (server->display_message_handler != NULL) server->display_message_handler(server->user_data, argument, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE) == 0) { ply_trigger_t *answer; ply_trace ("got keystroke request"); answer = ply_trigger_new (NULL); ply_trigger_add_handler (answer, (ply_trigger_handler_t) ply_boot_connection_on_keystroke_answer, connection); if (server->watch_for_keystroke_handler != NULL) server->watch_for_keystroke_handler (server->user_data, argument, answer, server); /* will reply later */ free(command); return; } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE_REMOVE) == 0) { ply_trace ("got keystroke remove request"); if (server->ignore_keystroke_handler != NULL) server->ignore_keystroke_handler (server->user_data, argument, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PROGRESS_PAUSE) == 0) { ply_trace ("got progress pause request"); if (server->progress_pause_handler != NULL) server->progress_pause_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PROGRESS_UNPAUSE) == 0) { ply_trace ("got progress unpause request"); if (server->progress_unpause_handler != NULL) server->progress_unpause_handler (server->user_data, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_NEWROOT) == 0) { ply_trace ("got newroot request"); if (server->newroot_handler != NULL) server->newroot_handler(server->user_data, argument, server); } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_HAS_ACTIVE_VT) == 0) { bool answer = false; ply_trace ("got has_active vt? request"); if (server->has_active_vt_handler != NULL) answer = server->has_active_vt_handler(server->user_data, server); if (!answer) { if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK))) ply_error ("could not write bytes: %m"); free(command); return; } } else if (strcmp (command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PING) != 0) { ply_error ("received unknown command '%s' from client", command); if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NAK))) ply_error ("could not write bytes: %m"); free(command); return; } if (!ply_write (connection->fd, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, strlen (PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK))) { ply_error ("could not write bytes: %m"); } free(command); }
static void view_add_star (view_t *view) { ply_boot_splash_plugin_t *plugin; ply_rectangle_t logo_area; star_t *star; unsigned int x, y; unsigned int width, height; unsigned long screen_width, screen_height; ply_list_node_t *node; assert (view != NULL); plugin = view->plugin; screen_width = ply_pixel_display_get_width (view->display); screen_height = ply_pixel_display_get_height (view->display); width = ply_image_get_width (plugin->logo_image); height = ply_image_get_height (plugin->logo_image); logo_area.x = (screen_width / 2) - (width / 2); logo_area.y = (screen_height / 2) - (height / 2); logo_area.width = width; logo_area.height = height; width = ply_image_get_width (plugin->star_image); height = ply_image_get_height (plugin->star_image); node = NULL; do { x = rand () % screen_width; y = rand () % screen_height; if ((x <= logo_area.x + logo_area.width) && (x >= logo_area.x) && (y >= logo_area.y) && (y <= logo_area.y + logo_area.height)) continue; if ((x + width >= logo_area.x) && (x + width <= logo_area.x + logo_area.width) && (y + height >= logo_area.y) && (y + height <= logo_area.y + logo_area.height)) continue; node = ply_list_get_first_node (view->stars); while (node != NULL) { ply_list_node_t *next_node; star = (star_t *) ply_list_node_get_data (node); next_node = ply_list_get_next_node (view->stars, node); if ((x <= star->x + width) && (x >= star->x) && (y >= star->y) && (y <= star->y + height)) break; if ((x + width >= star->x) && (x + width <= star->x + width) && (y + height >= star->y) && (y + height <= star->y + height)) break; node = next_node; } } while (node != NULL); star = star_new (x, y, (double) ((rand () % 50) + 1)); ply_list_append_data (view->stars, star); }
static bool create_heads_for_active_connectors (ply_renderer_backend_t *backend) { int i; drmModeConnector *connector; ply_hashtable_t *heads_by_controller_id; heads_by_controller_id = ply_hashtable_new (NULL, NULL); for (i = 0; i < backend->resources->count_connectors; i++) { ply_renderer_head_t *head; drmModeEncoder *encoder; uint32_t encoder_id; drmModeCrtc *controller; uint32_t controller_id; uint32_t console_buffer_id; int connector_mode_index; connector = drmModeGetConnector (backend->device_fd, backend->resources->connectors[i]); if (connector == NULL) continue; if (connector->connection != DRM_MODE_CONNECTED) { drmModeFreeConnector (connector); continue; } if (connector->count_modes <= 0) { drmModeFreeConnector (connector); continue; } encoder = find_encoder_for_connector (backend, connector); if (encoder == NULL) { drmModeFreeConnector (connector); continue; } encoder_id = encoder->encoder_id; controller = find_controller_for_encoder (backend, encoder); drmModeFreeEncoder (encoder); if (controller == NULL) { drmModeFreeConnector (connector); continue; } controller_id = controller->crtc_id; connector_mode_index = get_index_of_active_mode (backend, controller, connector); /* If we couldn't find the current active mode, fall back to the first available. */ if (connector_mode_index < 0) { ply_trace ("falling back to first available mode"); connector_mode_index = 0; } console_buffer_id = controller->buffer_id; drmModeFreeCrtc (controller); head = ply_hashtable_lookup (heads_by_controller_id, (void *) (intptr_t) controller_id); if (head == NULL) { head = ply_renderer_head_new (backend, connector, connector_mode_index, encoder_id, controller_id, console_buffer_id); ply_list_append_data (backend->heads, head); ply_hashtable_insert (heads_by_controller_id, (void *) (intptr_t) controller_id, head); } else { if (!ply_renderer_head_add_connector (head, connector, connector_mode_index)) { ply_trace ("couldn't connect monitor to existing head"); } drmModeFreeConnector (connector); } } ply_hashtable_free (heads_by_controller_id); #ifdef PLY_ENABLE_DEPRECATED_GDM_TRANSITION /* If the driver doesn't support mapping the fb console * then we can't get a smooth crossfade transition to * the display manager unless we use the /dev/fb interface * or the plymouth deactivate interface. * * In multihead configurations, we'd rather have working * multihead, but otherwise bail now. */ if (!backend->driver_supports_mapping_console && ply_list_get_length (backend->heads) == 1) { ply_list_node_t *node; ply_renderer_head_t *head; node = ply_list_get_first_node (backend->heads); head = (ply_renderer_head_t *) ply_list_node_get_data (node); if (ply_array_get_size (head->connector_ids) == 1) { ply_trace ("Only one monitor configured, and driver doesn't " "support mapping console, so letting frame-buffer " "take over"); free_heads (backend); return false; } } #endif return ply_list_get_length (backend->heads) > 0; }
static void ply_boot_client_process_incoming_replies (ply_boot_client_t *client) { ply_list_node_t *request_node; ply_boot_client_request_t *request; bool processed_reply; uint8_t byte[2] = ""; uint32_t size; assert (client != NULL); processed_reply = false; if (ply_list_get_length (client->requests_waiting_for_replies) == 0) { ply_error ("received unexpected response from boot status daemon"); return; } if (!ply_read (client->socket_fd, byte, sizeof (uint8_t))) goto out; for (request_node = ply_list_get_first_node (client->requests_waiting_for_replies); request_node; request_node = ply_list_get_next_node (client->requests_waiting_for_replies, request_node)) { assert (request_node != NULL); request = (ply_boot_client_request_t *) ply_list_node_get_data (request_node); assert (request != NULL); if (! strcmp (request->command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_PASSWORD) || ! strcmp (request->command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_QUESTION) || ! strcmp (request->command, PLY_BOOT_PROTOCOL_REQUEST_TYPE_KEYSTROKE)) { if (! memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, sizeof (uint8_t)) || ! memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, sizeof (uint8_t))) break; } else { if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, sizeof (uint8_t)) && memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, sizeof (uint8_t))) break; } } if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ACK, sizeof (uint8_t)) == 0) request->handler (request->user_data, client); else if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_ANSWER, sizeof (uint8_t)) == 0) { char *answer; if (!ply_read_uint32 (client->socket_fd, &size)) goto out; answer = malloc ((size+1) * sizeof(char)); if (size > 0) { if (!ply_read (client->socket_fd, answer, size)) goto out; } answer[size] = '\0'; ((ply_boot_client_answer_handler_t) request->handler) (request->user_data, answer, client); free(answer); } else if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_MULTIPLE_ANSWERS, sizeof (uint8_t)) == 0) { ply_array_t *array; char **answers; char *answer; char *p; char *q; uint8_t i; array = NULL; answers = NULL; if (!ply_read_uint32 (client->socket_fd, &size)) goto out; assert (size > 0); answer = malloc (size); if (!ply_read (client->socket_fd, answer, size)) { free (answer); goto out; } array = ply_array_new (); p = answer; q = p; for (i = 0; i < size; i++, q++) { if (*q == '\0') { ply_array_add_element (array, strdup (p)); p = q + 1; } } free (answer); answers = (char **) ply_array_steal_elements (array); ply_array_free (array); ((ply_boot_client_multiple_answers_handler_t) request->handler) (request->user_data, (const char * const *) answers, client); ply_free_string_array (answers); } else if (memcmp (byte, PLY_BOOT_PROTOCOL_RESPONSE_TYPE_NO_ANSWER, sizeof (uint8_t)) == 0) { ((ply_boot_client_answer_handler_t) request->handler) (request->user_data, NULL, client); } else goto out; processed_reply = true; out: if (!processed_reply) { if (request->failed_handler != NULL) request->failed_handler (request->user_data, client); } ply_list_remove_node (client->requests_waiting_for_replies, request_node); if (ply_list_get_length (client->requests_waiting_for_replies) == 0) { if (client->daemon_has_reply_watch != NULL) { assert (client->loop != NULL); ply_event_loop_stop_watching_fd (client->loop, client->daemon_has_reply_watch); client->daemon_has_reply_watch = NULL; } } }