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); }
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; }
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; }
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); }