Пример #1
0
static gchar *
xfce_randr_friendly_name (XfceRandr *randr,
                          guint      output,
                          guint      output_rr_id)
{
    Display        *xdisplay;
    MonitorInfo    *info = NULL;
    guint8         *edid_data;
    gchar          *friendly_name = NULL;
    const gchar *name = randr->priv->output_info[output]->name;

    /* special case, a laptop */
    if (g_str_has_prefix (name, "LVDS")
        || strcmp (name, "PANEL") == 0)
        return g_strdup (_("Laptop"));

    /* otherwise, get the vendor & size */
    xdisplay = gdk_x11_display_get_xdisplay (randr->priv->display);
    edid_data = xfce_randr_read_edid_data (xdisplay, randr->priv->resources->outputs[output_rr_id]);

    if (edid_data)
        info = decode_edid (edid_data);

    if (info)
        friendly_name = make_display_name (info, output);

    g_free (info);
    g_free (edid_data);

    if (friendly_name)
        return friendly_name;

    /* last attempt to return a better name */
    if (g_str_has_prefix (name, "VGA")
             || g_str_has_prefix (name, "Analog"))
        return g_strdup (_("Monitor"));
    else if (g_str_has_prefix (name, "TV")
             || strcmp (name, "S-video") == 0)
        return g_strdup (_("Television"));
    else if (g_str_has_prefix (name, "TMDS")
             || g_str_has_prefix (name, "DVI")
             || g_str_has_prefix (name, "Digital"))
        return g_strdup (_("Digital display"));

    /* everything failed, fallback */
    return g_strdup (name);
}
Пример #2
0
MateRRConfig *
mate_rr_config_new_current (MateRRScreen *screen)
{
    MateRRConfig *config = g_new0 (MateRRConfig, 1);
    GPtrArray *a = g_ptr_array_new ();
    MateRROutput **rr_outputs;
    int i;
    int clone_width = -1;
    int clone_height = -1;
    int last_x;

    g_return_val_if_fail (screen != NULL, NULL);

    rr_outputs = mate_rr_screen_list_outputs (screen);

    config->clone = FALSE;
    
    for (i = 0; rr_outputs[i] != NULL; ++i)
    {
	MateRROutput *rr_output = rr_outputs[i];
	MateOutputInfo *output = g_new0 (MateOutputInfo, 1);
	MateRRMode *mode = NULL;
	const guint8 *edid_data = mate_rr_output_get_edid_data (rr_output);
	MateRRCrtc *crtc;

	output->name = g_strdup (mate_rr_output_get_name (rr_output));
	output->connected = mate_rr_output_is_connected (rr_output);

	if (!output->connected)
	{
	    output->x = -1;
	    output->y = -1;
	    output->width = -1;
	    output->height = -1;
	    output->rate = -1;
	    output->rotation = MATE_RR_ROTATION_0;
	}
	else
	{
	    MonitorInfo *info = NULL;

	    if (edid_data)
		info = decode_edid (edid_data);

	    if (info)
	    {
		memcpy (output->vendor, info->manufacturer_code,
			sizeof (output->vendor));
		
		output->product = info->product_code;
		output->serial = info->serial_number;
		output->aspect = info->aspect_ratio;
	    }
	    else
	    {
		strcpy (output->vendor, "???");
		output->product = 0;
		output->serial = 0;
	    }

	    if (mate_rr_output_is_laptop (rr_output))
		output->display_name = g_strdup (_("Laptop"));
	    else
		output->display_name = make_display_name (info);
		
	    g_free (info);
		
	    crtc = mate_rr_output_get_crtc (rr_output);
	    mode = crtc? mate_rr_crtc_get_current_mode (crtc) : NULL;
	    
	    if (crtc && mode)
	    {
		output->on = TRUE;
		
		mate_rr_crtc_get_position (crtc, &output->x, &output->y);
		output->width = mate_rr_mode_get_width (mode);
		output->height = mate_rr_mode_get_height (mode);
		output->rate = mate_rr_mode_get_freq (mode);
		output->rotation = mate_rr_crtc_get_current_rotation (crtc);

		if (output->x == 0 && output->y == 0) {
			if (clone_width == -1) {
				clone_width = output->width;
				clone_height = output->height;
			} else if (clone_width == output->width &&
				   clone_height == output->height) {
				config->clone = TRUE;
			}
		}
	    }
	    else
	    {
		output->on = FALSE;
		config->clone = FALSE;
	    }

	    /* Get preferred size for the monitor */
	    mode = mate_rr_output_get_preferred_mode (rr_output);
	    
	    if (!mode)
	    {
		MateRRMode **modes = mate_rr_output_list_modes (rr_output);
		
		/* FIXME: we should pick the "best" mode here, where best is
		 * sorted wrt
		 *
		 * - closest aspect ratio
		 * - mode area
		 * - refresh rate
		 * - We may want to extend randrwrap so that get_preferred
		 *   returns that - although that could also depend on
		 *   the crtc.
		 */
		if (modes[0])
		    mode = modes[0];
	    }
	    
	    if (mode)
	    {
		output->pref_width = mate_rr_mode_get_width (mode);
		output->pref_height = mate_rr_mode_get_height (mode);
	    }
	    else
	    {
		/* Pick some random numbers. This should basically never happen */
		output->pref_width = 1024;
		output->pref_height = 768;
	    }
	}

        output->primary = mate_rr_output_get_is_primary (rr_output);
 
	g_ptr_array_add (a, output);
    }

    g_ptr_array_add (a, NULL);
    
    config->outputs = (MateOutputInfo **)g_ptr_array_free (a, FALSE);

    /* Walk the outputs computing the right-most edge of all
     * lit-up displays
     */
    last_x = 0;
    for (i = 0; config->outputs[i] != NULL; ++i)
    {
	MateOutputInfo *output = config->outputs[i];

	if (output->on)
	{
	    last_x = MAX (last_x, output->x + output->width);
	}
    }

    /* Now position all off displays to the right of the
     * on displays
     */
    for (i = 0; config->outputs[i] != NULL; ++i)
    {
	MateOutputInfo *output = config->outputs[i];

	if (output->connected && !output->on)
	{
	    output->x = last_x;
	    last_x = output->x + output->width;
	}
    }
    
    g_assert (mate_rr_config_match (config, config));
    
    return config;
}
Пример #3
0
static gboolean
meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
                                           GDBusMethodInvocation *invocation)
{
  MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
  MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (skeleton);
  GVariantBuilder crtc_builder, output_builder, mode_builder;
  unsigned int i, j;

  g_variant_builder_init (&crtc_builder, G_VARIANT_TYPE ("a(uxiiiiiuaua{sv})"));
  g_variant_builder_init (&output_builder, G_VARIANT_TYPE ("a(uxiausauaua{sv})"));
  g_variant_builder_init (&mode_builder, G_VARIANT_TYPE ("a(uxuud)"));

  for (i = 0; i < manager->n_crtcs; i++)
    {
      MetaCRTC *crtc = &manager->crtcs[i];
      GVariantBuilder transforms;

      g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
      for (j = 0; j <= WL_OUTPUT_TRANSFORM_FLIPPED_270; j++)
        if (crtc->all_transforms & (1 << j))
          g_variant_builder_add (&transforms, "u", j);

      g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
                             i, /* ID */
                             (gint64)crtc->crtc_id,
                             (int)crtc->rect.x,
                             (int)crtc->rect.y,
                             (int)crtc->rect.width,
                             (int)crtc->rect.height,
                             (int)(crtc->current_mode ? crtc->current_mode - manager->modes : -1),
                             (guint32)crtc->transform,
                             &transforms,
                             NULL /* properties */);
    }

  for (i = 0; i < manager->n_outputs; i++)
    {
      MetaOutput *output = &manager->outputs[i];
      GVariantBuilder crtcs, modes, clones, properties;
      GBytes *edid;
      char *edid_file;

      g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
      for (j = 0; j < output->n_possible_crtcs; j++)
        g_variant_builder_add (&crtcs, "u",
                               (unsigned)(output->possible_crtcs[j] - manager->crtcs));

      g_variant_builder_init (&modes, G_VARIANT_TYPE ("au"));
      for (j = 0; j < output->n_modes; j++)
        g_variant_builder_add (&modes, "u",
                               (unsigned)(output->modes[j] - manager->modes));

      g_variant_builder_init (&clones, G_VARIANT_TYPE ("au"));
      for (j = 0; j < output->n_possible_clones; j++)
        g_variant_builder_add (&clones, "u",
                               (unsigned)(output->possible_clones[j] - manager->outputs));

      g_variant_builder_init (&properties, G_VARIANT_TYPE ("a{sv}"));
      g_variant_builder_add (&properties, "{sv}", "vendor",
                             g_variant_new_string (output->vendor));
      g_variant_builder_add (&properties, "{sv}", "product",
                             g_variant_new_string (output->product));
      g_variant_builder_add (&properties, "{sv}", "serial",
                             g_variant_new_string (output->serial));
      g_variant_builder_add (&properties, "{sv}", "width-mm",
                             g_variant_new_int32 (output->width_mm));
      g_variant_builder_add (&properties, "{sv}", "height-mm",
                             g_variant_new_int32 (output->height_mm));
      g_variant_builder_add (&properties, "{sv}", "display-name",
                             g_variant_new_take_string (make_display_name (manager, output)));
      g_variant_builder_add (&properties, "{sv}", "backlight",
                             g_variant_new_int32 (output->backlight));
      g_variant_builder_add (&properties, "{sv}", "primary",
                             g_variant_new_boolean (output->is_primary));
      g_variant_builder_add (&properties, "{sv}", "presentation",
                             g_variant_new_boolean (output->is_presentation));

      edid_file = manager_class->get_edid_file (manager, output);
      if (edid_file)
        {
          g_variant_builder_add (&properties, "{sv}", "edid-file",
                                 g_variant_new_take_string (edid_file));
        }
      else
        {
          edid = manager_class->read_edid (manager, output);

          if (edid)
            {
              g_variant_builder_add (&properties, "{sv}", "edid",
                                     g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"),
                                                               edid, TRUE));
              g_bytes_unref (edid);
            }
        }

      g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
                             i, /* ID */
                             (gint64)output->output_id,
                             (int)(output->crtc ? output->crtc - manager->crtcs : -1),
                             &crtcs,
                             output->name,
                             &modes,
                             &clones,
                             &properties);
    }

  for (i = 0; i < manager->n_modes; i++)
    {
      MetaMonitorMode *mode = &manager->modes[i];

      g_variant_builder_add (&mode_builder, "(uxuud)",
                             i, /* ID */
                             (gint64)mode->mode_id,
                             (guint32)mode->width,
                             (guint32)mode->height,
                             (double)mode->refresh_rate);
    }

  meta_dbus_display_config_complete_get_resources (skeleton,
                                                   invocation,
                                                   manager->serial,
                                                   g_variant_builder_end (&crtc_builder),
                                                   g_variant_builder_end (&output_builder),
                                                   g_variant_builder_end (&mode_builder),
                                                   manager->max_screen_width,
                                                   manager->max_screen_height);
  return TRUE;
}
Пример #4
0
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:hiP:vVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "csv", 0, 0, 0 },
    { "domain", 1, 0, 'd' },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "human-readable", 0, 0, 'h' },
    { "inodes", 0, 0, 'i' },
    { "long-options", 0, 0, 0 },
    { "one-per-guest", 0, 0, 0 },
    { "short-options", 0, 0, 0 },
    { "uuid", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  bool format_consumed = true;
  int c;
  int option_index;
  size_t max_threads = 0;
  int err;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, _("guestfs_create: failed to create handle\n"));
    exit (EXIT_FAILURE);
  }

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "short-options"))
        display_short_options (options);
      else if (STREQ (long_options[option_index].name, "format")) {
        OPTION_format;
      } else if (STREQ (long_options[option_index].name, "csv")) {
        csv = 1;
      } else if (STREQ (long_options[option_index].name, "one-per-guest")) {
        /* nothing - left for backwards compatibility */
      } else if (STREQ (long_options[option_index].name, "uuid")) {
        uuid = 1;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'h':
      human = 1;
      break;

    case 'i':
      inodes = 1;
      break;

    case 'P':
      if (sscanf (optarg, "%zu", &max_threads) != 1) {
        fprintf (stderr, _("%s: -P option is not numeric\n"), program_name);
        exit (EXIT_FAILURE);
      }
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-df which is how we detect this.
   */
  if (drvs == NULL) {
    while (optind < argc) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = strdup (argv[optind]);
        if (!drv->a.filename) {
          perror ("strdup");
          exit (EXIT_FAILURE);
        }
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("malloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 0);
  assert (live == 0);

  /* Must be no extra arguments on the command line. */
  if (optind != argc)
    usage (EXIT_FAILURE);

  CHECK_OPTION_format_consumed;

  /* -h and --csv doesn't make sense.  Spreadsheets will corrupt these
   * fields.  (RHBZ#600977).
   */
  if (human && csv) {
    fprintf (stderr, _("%s: you cannot use -h and --csv options together.\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  /* virt-df has two modes.  If the user didn't specify any drives,
   * then we do the df on every libvirt guest.  That's the if-clause
   * below.  If the user specified domains/drives, then we assume they
   * belong to a single guest.  That's the else-clause below.
   */
  if (drvs == NULL) {
#if defined(HAVE_LIBVIRT)
    get_all_libvirt_domains (libvirt_uri);
    print_title ();
    err = start_threads (max_threads, g, df_work);
    free_domains ();
#else
    fprintf (stderr, _("%s: compiled without support for libvirt.\n"),
             program_name);
    exit (EXIT_FAILURE);
#endif
  }
  else {                        /* Single guest. */
    CLEANUP_FREE char *name = NULL;

    /* Add domains/drives from the command line (for a single guest). */
    add_drives (drvs, 'a');

    if (guestfs_launch (g) == -1)
      exit (EXIT_FAILURE);

    print_title ();

    /* Synthesize a display name. */
    name = make_display_name (drvs);

    /* XXX regression: in the Perl version we cached the UUID from the
     * libvirt domain handle so it was available to us here.  In this
     * version the libvirt domain handle is hidden inside
     * guestfs_add_domain so the UUID is not available easily for
     * single '-d' command-line options.
     */
    err = df_on_handle (g, name, NULL, stdout);

    /* Free up data structures, no longer needed after this point. */
    free_drives (drvs);
  }

  guestfs_close (g);

  exit (err == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}