Ejemplo n.º 1
0
static void
ply_boot_client_process_pending_requests (ply_boot_client_t *client)
{
  ply_list_node_t *request_node;
  ply_boot_client_request_t *request;

  assert (ply_list_get_length (client->requests_to_send) != 0);
  assert (client->daemon_can_take_request_watch != NULL);

  request_node = ply_list_get_first_node (client->requests_to_send);
  assert (request_node != NULL);

  request = (ply_boot_client_request_t *) ply_list_node_get_data (request_node);
  assert (request != NULL);

  ply_list_remove_node (client->requests_to_send, request_node);

  if (ply_boot_client_send_request (client, request))
    ply_list_append_data (client->requests_waiting_for_replies, request);

  if (ply_list_get_length (client->requests_to_send) == 0)
    {
      if (client->daemon_has_reply_watch != NULL)
        {
          assert (client->loop != NULL);

          ply_event_loop_stop_watching_fd (client->loop,
                                           client->daemon_can_take_request_watch);
          client->daemon_can_take_request_watch = NULL;
        }
    }
}
Ejemplo n.º 2
0
static void
ply_boot_client_cancel_unsent_requests (ply_boot_client_t *client)
{
  ply_list_node_t *node;

  if (ply_list_get_length (client->requests_to_send) == 0)
      return;

  node = ply_list_get_first_node (client->requests_to_send);
  while (node != NULL)
    {
      ply_list_node_t *next_node;
      ply_boot_client_request_t *request;

      request = (ply_boot_client_request_t *) ply_list_node_get_data (node);
      next_node = ply_list_get_next_node (client->requests_to_send, node);

      ply_boot_client_cancel_request (client, request);
      ply_list_remove_node (client->requests_to_send, node);

      node = next_node;
    }

  if (client->daemon_can_take_request_watch != NULL)
    {
      assert (client->loop != NULL);

      ply_event_loop_stop_watching_fd (client->loop, 
                                       client->daemon_can_take_request_watch);
      client->daemon_can_take_request_watch = NULL;
    }
}
Ejemplo n.º 3
0
static void
unmap_from_device (ply_renderer_backend_t *backend)
{
  ply_list_node_t *node;
  bool should_set_to_black;

  /* We only copy what's on screen back to the fb console
   * if there's one head (since in multihead set ups the fb console
   * is cloned).
   */
  should_set_to_black = ply_list_get_length (backend->heads) > 1;

  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 (backend->is_active)
        {
          ply_trace ("scanning out %s directly to console",
                     should_set_to_black? "black" : "splash");
          ply_renderer_head_set_scan_out_buffer_to_console (backend, head,
                                                            should_set_to_black);
        }

      ply_renderer_head_unmap (backend, head);

      node = next_node;
    }
}
Ejemplo n.º 4
0
static bool
ply_boot_client_send_request (ply_boot_client_t         *client,
                              ply_boot_client_request_t *request)
{
  char *request_string;
  size_t request_size;

  assert (client != NULL);
  assert (request != NULL);

  request_string = ply_boot_client_get_request_string (client, request,
                                                       &request_size);
  if (!ply_write (client->socket_fd, request_string, request_size))
    {
      free (request_string);
      ply_boot_client_cancel_request (client, request);
      return false;
    }
  free (request_string);

  if (client->daemon_has_reply_watch == NULL)
    {
      assert (ply_list_get_length (client->requests_waiting_for_replies) == 0);
      client->daemon_has_reply_watch = 
          ply_event_loop_watch_fd (client->loop, client->socket_fd,
                                   PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
                                   (ply_event_handler_t)
                                   ply_boot_client_process_incoming_replies,
                                   NULL, client);
    }
  return true;
}
Ejemplo n.º 5
0
static void
add_pixel_displays (ply_seat_t *seat)
{
        ply_list_t *heads;
        ply_list_node_t *node;

        heads = ply_renderer_get_heads (seat->renderer);

        ply_trace ("Adding displays for %d heads",
                   ply_list_get_length (heads));

        node = ply_list_get_first_node (heads);
        while (node != NULL) {
                ply_list_node_t *next_node;
                ply_renderer_head_t *head;
                ply_pixel_display_t *display;

                head = ply_list_node_get_data (node);
                next_node = ply_list_get_next_node (heads, node);

                display = ply_pixel_display_new (seat->renderer, head);

                ply_list_append_data (seat->pixel_displays, display);

                node = next_node;
        }
}
Ejemplo n.º 6
0
static bool
show_splash_screen (ply_boot_splash_plugin_t *plugin,
                    ply_event_loop_t         *loop,
                    ply_buffer_t             *boot_buffer,
                    ply_boot_splash_mode_t    mode)
{
  assert (plugin != NULL);

  if (ply_list_get_length (plugin->displays) == 0)
    {
      ply_trace ("no pixel displays");
      return false;
    }

  plugin->loop = loop;
  plugin->mode = mode;

  ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
                                 detach_from_event_loop,
                                 plugin);

  ply_event_loop_watch_signal (plugin->loop,
                               SIGINT,
                               (ply_event_handler_t)
                               on_interrupt, plugin);

  ply_trace ("starting boot animation");
  return start_animation (plugin);
}
Ejemplo n.º 7
0
void
ply_boot_client_flush (ply_boot_client_t *client)
{
  assert (client != NULL);

  while (ply_list_get_length (client->requests_to_send) > 0)
    {
      ply_event_loop_process_pending_events (client->loop);
    }
}
Ejemplo n.º 8
0
static void
ply_boot_client_queue_request (ply_boot_client_t                  *client,
                               const char                         *request_command,
                               const char                         *request_argument,
                               ply_boot_client_response_handler_t  handler,
                               ply_boot_client_response_handler_t  failed_handler,
                               void                               *user_data)
{
  assert (client != NULL);
  assert (client->loop != NULL);
  assert (request_command != NULL);
  assert (request_argument == NULL || strlen (request_argument) <= UCHAR_MAX);
  assert (handler != NULL);

  if (client->daemon_can_take_request_watch == NULL &&
      client->socket_fd >= 0)
    {
      assert (ply_list_get_length (client->requests_to_send) == 0);
      client->daemon_can_take_request_watch = 
          ply_event_loop_watch_fd (client->loop, client->socket_fd,
                                   PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA,
                                   (ply_event_handler_t)
                                   ply_boot_client_process_pending_requests,
                                   NULL, client);
    }

  if (!client->is_connected)
    {
      if (failed_handler != NULL)
        {
          failed_handler (user_data, client);
        }
    }
  else
    {
      ply_boot_client_request_t *request;

      request = ply_boot_client_request_new (client, request_command,
                                             request_argument,
                                             handler, failed_handler, user_data);
      ply_list_append_data (client->requests_to_send, request);
    }
}
Ejemplo n.º 9
0
static void
free_text_displays (ply_seat_t *seat)
{
        ply_list_node_t *node;

        ply_trace ("freeing %d text displays", ply_list_get_length (seat->text_displays));
        node = ply_list_get_first_node (seat->text_displays);
        while (node != NULL) {
                ply_list_node_t *next_node;
                ply_text_display_t *display;

                next_node = ply_list_get_next_node (seat->text_displays, node);
                display = ply_list_node_get_data (node);
                ply_text_display_free (display);

                ply_list_remove_node (seat->text_displays, node);

                node = next_node;
        }
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
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;
        }
    }
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
static bool
create_heads_for_active_connectors (ply_renderer_backend_t *backend)
{
  int i;
  drmModeConnector *connector;

  for (i = 0; i < backend->resources->count_connectors; i++)
    {
      ply_renderer_head_t *head;
      drmModeEncoder *encoder;
      uint32_t controller_id;
      uint32_t encoder_id;
      uint32_t console_buffer_id;
      drmModeModeInfo *mode;

      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_id = find_controller_for_encoder (backend, encoder);
      drmModeFreeEncoder (encoder);

      if (controller_id == 0)
        {
          drmModeFreeConnector (connector);
          continue;
        }

      mode = get_active_mode_for_connector (backend, connector);

      console_buffer_id = get_console_buffer_id (backend, controller_id);

      head = ply_renderer_head_new (backend, connector, encoder_id,
                                    controller_id, console_buffer_id,
                                    mode);

      ply_list_append_data (backend->heads, head);
    }

#ifdef PLY_ENABLE_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_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;
}
Ejemplo n.º 14
0
bool
ply_seat_is_open (ply_seat_t *seat)
{
        return ply_list_get_length (seat->pixel_displays) > 0 ||
               ply_list_get_length (seat->text_displays) > 0;
}