Changing client resolution is a bad idea, and never took up. Remove some unmaintained experimental code. --- gtk/Makefile.am | 24 - gtk/display/display-name.c | 299 ------ gtk/display/edid-parse.c | 540 ---------- gtk/display/edid.h | 192 ---- gtk/display/gnome-rr-config.c | 2048 ------------------------------------ gtk/display/gnome-rr-config.h | 149 --- gtk/display/gnome-rr-generic.c | 218 ---- gtk/display/gnome-rr-generic.h | 53 - gtk/display/gnome-rr-output-info.c | 244 ----- gtk/display/gnome-rr-private.h | 204 ---- gtk/display/gnome-rr-windows.c | 453 -------- gtk/display/gnome-rr-windows.h | 53 - gtk/display/gnome-rr-x11.c | 1013 ------------------ gtk/display/gnome-rr-x11.h | 56 - gtk/display/gnome-rr.c | 1161 -------------------- gtk/display/gnome-rr.h | 200 ---- gtk/smartcard-manager.h | 1 - gtk/spicy.c | 214 ---- 18 files changed, 7122 deletions(-) delete mode 100644 gtk/display/display-name.c delete mode 100644 gtk/display/edid-parse.c delete mode 100644 gtk/display/edid.h delete mode 100644 gtk/display/gnome-rr-config.c delete mode 100644 gtk/display/gnome-rr-config.h delete mode 100644 gtk/display/gnome-rr-generic.c delete mode 100644 gtk/display/gnome-rr-generic.h delete mode 100644 gtk/display/gnome-rr-output-info.c delete mode 100644 gtk/display/gnome-rr-private.h delete mode 100644 gtk/display/gnome-rr-windows.c delete mode 100644 gtk/display/gnome-rr-windows.h delete mode 100644 gtk/display/gnome-rr-x11.c delete mode 100644 gtk/display/gnome-rr-x11.h delete mode 100644 gtk/display/gnome-rr.c delete mode 100644 gtk/display/gnome-rr.h diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 8d26132..e65d3e2 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -348,34 +348,10 @@ endif libspice_client_glib_2_0_la_LIBADD += -lws2_32 -lgdi32 endif -displaysrc = \ - glib-compat.h \ - display/edid.h \ - display/edid-parse.c \ - display/display-name.c \ - display/gnome-rr-config.c \ - display/gnome-rr-config.h \ - display/gnome-rr-output-info.c \ - display/gnome-rr-private.h \ - display/gnome-rr.c \ - display/gnome-rr.h \ - $(NULL) - -if WITH_DISPLAY_X11 - displaysrc += display/gnome-rr-x11.c display/gnome-rr-x11.h -else -if WITH_DISPLAY_WINDOWS - displaysrc += display/gnome-rr-windows.c display/gnome-rr-windows.h -else - displaysrc += display/gnome-rr-generic.c display/gnome-rr-generic.h -endif -endif - spicy_SOURCES = \ spicy.c \ spice-cmdline.h \ spice-cmdline.c \ - $(displaysrc) \ $(NULL) spicy_LDADD = \ diff --git a/gtk/display/display-name.c b/gtk/display/display-name.c deleted file mode 100644 index d38eb2f..0000000 --- a/gtk/display/display-name.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright 2007 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Author: Soren Sandmann <sandmann@xxxxxxxxxx> */ - -#include <config.h> -#include <glib/gi18n-lib.h> -#include <stdlib.h> -#include <math.h> -#include <stdio.h> -#include <string.h> -#include <glib.h> -#include "edid.h" - -typedef struct Vendor Vendor; -struct Vendor -{ - const char vendor_id[4]; - const char vendor_name[28]; -}; - -/* This list of vendor codes derived from lshw - * - * http://ezix.org/project/wiki/HardwareLiSter - * - * Note: we now prefer to use data coming from hwdata (and shipped with - * gnome-desktop). See - * http://git.fedorahosted.org/git/?p=hwdata.git;a=blob_plain;f=pnp.ids;hb=HEAD - * All contributions to the list of vendors should go there. - */ -static const struct Vendor vendors[] = -{ - { "AIC", "AG Neovo" }, - { "ACR", "Acer" }, - { "DEL", "DELL" }, - { "SAM", "SAMSUNG" }, - { "SNY", "SONY" }, - { "SEC", "Epson" }, - { "WAC", "Wacom" }, - { "NEC", "NEC" }, - { "CMO", "CMO" }, /* Chi Mei */ - { "BNQ", "BenQ" }, - - { "ABP", "Advansys" }, - { "ACC", "Accton" }, - { "ACE", "Accton" }, - { "ADP", "Adaptec" }, - { "ADV", "AMD" }, - { "AIR", "AIR" }, - { "AMI", "AMI" }, - { "ASU", "ASUS" }, - { "ATI", "ATI" }, - { "ATK", "Allied Telesyn" }, - { "AZT", "Aztech" }, - { "BAN", "Banya" }, - { "BRI", "Boca Research" }, - { "BUS", "Buslogic" }, - { "CCI", "Cache Computers Inc." }, - { "CHA", "Chase" }, - { "CMD", "CMD Technology, Inc." }, - { "COG", "Cogent" }, - { "CPQ", "Compaq" }, - { "CRS", "Crescendo" }, - { "CSC", "Crystal" }, - { "CSI", "CSI" }, - { "CTL", "Creative Labs" }, - { "DBI", "Digi" }, - { "DEC", "Digital Equipment" }, - { "DBK", "Databook" }, - { "EGL", "Eagle Technology" }, - { "ELS", "ELSA" }, - { "ESS", "ESS" }, - { "FAR", "Farallon" }, - { "FDC", "Future Domain" }, - { "HWP", "Hewlett-Packard" }, - { "IBM", "IBM" }, - { "INT", "Intel" }, - { "ISA", "Iomega" }, - { "LEN", "Lenovo" }, - { "MDG", "Madge" }, - { "MDY", "Microdyne" }, - { "MET", "Metheus" }, - { "MIC", "Micronics" }, - { "MLX", "Mylex" }, - { "NVL", "Novell" }, - { "OLC", "Olicom" }, - { "PRO", "Proteon" }, - { "RII", "Racal" }, - { "RTL", "Realtek" }, - { "SCM", "SCM" }, - { "SKD", "SysKonnect" }, - { "SGI", "SGI" }, - { "SMC", "SMC" }, - { "SNI", "Siemens Nixdorf" }, - { "STL", "Stallion Technologies" }, - { "SUN", "Sun" }, - { "SUP", "SupraExpress" }, - { "SVE", "SVEC" }, - { "TCC", "Thomas-Conrad" }, - { "TCI", "Tulip" }, - { "TCM", "3Com" }, - { "TCO", "Thomas-Conrad" }, - { "TEC", "Tecmar" }, - { "TRU", "Truevision" }, - { "TOS", "Toshiba" }, - { "TYN", "Tyan" }, - { "UBI", "Ungermann-Bass" }, - { "USC", "UltraStor" }, - { "VDM", "Vadem" }, - { "VMI", "Vermont" }, - { "WDC", "Western Digital" }, - { "ZDS", "Zeos" }, - - /* From http://faydoc.tripod.com/structures/01/0136.htm */ - { "ACT", "Targa" }, - { "ADI", "ADI" }, - { "AOC", "AOC Intl" }, - { "API", "Acer America" }, - { "APP", "Apple Computer" }, - { "ART", "ArtMedia" }, - { "AST", "AST Research" }, - { "CPL", "Compal" }, - { "CTX", "Chuntex Electronic Co." }, - { "DPC", "Delta Electronics" }, - { "DWE", "Daewoo" }, - { "ECS", "ELITEGROUP" }, - { "EIZ", "EIZO" }, - { "FCM", "Funai" }, - { "GSM", "LG Electronics" }, - { "GWY", "Gateway 2000" }, - { "HEI", "Hyundai" }, - { "HIT", "Hitachi" }, - { "HSL", "Hansol" }, - { "HTC", "Hitachi" }, - { "ICL", "Fujitsu ICL" }, - { "IVM", "Idek Iiyama" }, - { "KFC", "KFC Computek" }, - { "LKM", "ADLAS" }, - { "LNK", "LINK Tech" }, - { "LTN", "Lite-On" }, - { "MAG", "MAG InnoVision" }, - { "MAX", "Maxdata" }, - { "MEI", "Panasonic" }, - { "MEL", "Mitsubishi" }, - { "MIR", "miro" }, - { "MTC", "MITAC" }, - { "NAN", "NANAO" }, - { "NEC", "NEC Tech" }, - { "NOK", "Nokia" }, - { "OQI", "OPTIQUEST" }, - { "PBN", "Packard Bell" }, - { "PGS", "Princeton" }, - { "PHL", "Philips" }, - { "REL", "Relisys" }, - { "SDI", "Samtron" }, - { "SMI", "Smile" }, - { "SPT", "Sceptre" }, - { "SRC", "Shamrock Technology" }, - { "STP", "Sceptre" }, - { "TAT", "Tatung" }, - { "TRL", "Royal Information Company" }, - { "TSB", "Toshiba, Inc." }, - { "UNM", "Unisys" }, - { "VSC", "ViewSonic" }, - { "WTC", "Wen Tech" }, - { "ZCM", "Zenith Data Systems" }, - - { "???", "Unknown" }, -}; - -static GHashTable *pnp_ids = NULL; - -static void -read_pnp_ids (void) -{ - gchar *contents; - gchar **lines; - gchar *line; - gchar *code, *name; - gint i; - - if (pnp_ids) - return; - - pnp_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - - if (g_file_get_contents (PNP_IDS, &contents, NULL, NULL)) - { - lines = g_strsplit (contents, "\n", -1); - for (i = 0; lines[i]; i++) - { - line = lines[i]; - if (line[0] && line[1] && line[2] && line[3] == '\t' && line[4]) - { - code = line; - line[3] = '\0'; - name = line + 4; - g_hash_table_insert (pnp_ids, code, name); - } - } - g_free (lines); - g_free (contents); - } -} - - -static const char * -find_vendor (const char *code) -{ - const char *vendor_name; - int i; - - read_pnp_ids (); - - vendor_name = g_hash_table_lookup (pnp_ids, code); - - if (vendor_name) - return vendor_name; - - for (i = 0; i < sizeof (vendors) / sizeof (vendors[0]); ++i) - { - const Vendor *v = &(vendors[i]); - - if (strcmp (v->vendor_id, code) == 0) - return v->vendor_name; - } - - return code; -}; - -char * -make_display_name (const MonitorInfo *info) -{ - const char *vendor; - int width_mm, height_mm, inches; - - if (info) - { - vendor = find_vendor (info->manufacturer_code); - } - else - { - /* Translators: "Unknown" here is used to identify a monitor for which - * we don't know the vendor. When a vendor is known, the name of the - * vendor is used. */ - vendor = C_("Monitor vendor", "Unknown"); - } - - if (info && info->width_mm != -1 && info->height_mm) - { - width_mm = info->width_mm; - height_mm = info->height_mm; - } - else if (info && info->n_detailed_timings) - { - width_mm = info->detailed_timings[0].width_mm; - height_mm = info->detailed_timings[0].height_mm; - } - else - { - width_mm = -1; - height_mm = -1; - } - - if (width_mm != -1 && height_mm != -1) - { - double d = sqrt (width_mm * width_mm + height_mm * height_mm); - - inches = (int)(d / 25.4 + 0.5); - } - else - { - inches = -1; - } - - if (inches > 0) - return g_strdup_printf ("%s %d\"", vendor, inches); - else - return g_strdup (vendor); -} diff --git a/gtk/display/edid-parse.c b/gtk/display/edid-parse.c deleted file mode 100644 index 512c568..0000000 --- a/gtk/display/edid-parse.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright 2007 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Author: Soren Sandmann <sandmann@xxxxxxxxxx> */ - -#include "edid.h" -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <glib.h> - -static int -get_bit (int in, int bit) -{ - return (in & (1 << bit)) >> bit; -} - -static int -get_bits (int in, int begin, int end) -{ - int mask = (1 << (end - begin + 1)) - 1; - - return (in >> begin) & mask; -} - -static int -decode_header (const uchar *edid) -{ - if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0) - return TRUE; - return FALSE; -} - -static int -decode_vendor_and_product_identification (const uchar *edid, MonitorInfo *info) -{ - int is_model_year; - - /* Manufacturer Code */ - info->manufacturer_code[0] = get_bits (edid[0x08], 2, 6); - info->manufacturer_code[1] = get_bits (edid[0x08], 0, 1) << 3; - info->manufacturer_code[1] |= get_bits (edid[0x09], 5, 7); - info->manufacturer_code[2] = get_bits (edid[0x09], 0, 4); - info->manufacturer_code[3] = '\0'; - - info->manufacturer_code[0] += 'A' - 1; - info->manufacturer_code[1] += 'A' - 1; - info->manufacturer_code[2] += 'A' - 1; - - /* Product Code */ - info->product_code = edid[0x0b] << 8 | edid[0x0a]; - - /* Serial Number */ - info->serial_number = - edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | edid[0x0f] << 24; - - /* Week and Year */ - is_model_year = FALSE; - switch (edid[0x10]) - { - case 0x00: - info->production_week = -1; - break; - - case 0xff: - info->production_week = -1; - is_model_year = TRUE; - break; - - default: - info->production_week = edid[0x10]; - break; - } - - if (is_model_year) - { - info->production_year = -1; - info->model_year = 1990 + edid[0x11]; - } - else - { - info->production_year = 1990 + edid[0x11]; - info->model_year = -1; - } - - return TRUE; -} - -static int -decode_edid_version (const uchar *edid, MonitorInfo *info) -{ - info->major_version = edid[0x12]; - info->minor_version = edid[0x13]; - - return TRUE; -} - -static int -decode_display_parameters (const uchar *edid, MonitorInfo *info) -{ - /* Digital vs Analog */ - info->is_digital = get_bit (edid[0x14], 7); - - if (info->is_digital) - { - int bits; - - static const int bit_depth[8] = - { - -1, 6, 8, 10, 12, 14, 16, -1 - }; - - static const Interface interfaces[6] = - { - UNDEFINED, DVI, HDMI_A, HDMI_B, MDDI, DISPLAY_PORT - }; - - bits = get_bits (edid[0x14], 4, 6); - info->connector.digital.bits_per_primary = bit_depth[bits]; - - bits = get_bits (edid[0x14], 0, 3); - - if (bits <= 5) - info->connector.digital.interface = interfaces[bits]; - else - info->connector.digital.interface = UNDEFINED; - } - else - { - int bits = get_bits (edid[0x14], 5, 6); - - static const double levels[][3] = - { - { 0.7, 0.3, 1.0 }, - { 0.714, 0.286, 1.0 }, - { 1.0, 0.4, 1.4 }, - { 0.7, 0.0, 0.7 }, - }; - - info->connector.analog.video_signal_level = levels[bits][0]; - info->connector.analog.sync_signal_level = levels[bits][1]; - info->connector.analog.total_signal_level = levels[bits][2]; - - info->connector.analog.blank_to_black = get_bit (edid[0x14], 4); - - info->connector.analog.separate_hv_sync = get_bit (edid[0x14], 3); - info->connector.analog.composite_sync_on_h = get_bit (edid[0x14], 2); - info->connector.analog.composite_sync_on_green = get_bit (edid[0x14], 1); - - info->connector.analog.serration_on_vsync = get_bit (edid[0x14], 0); - } - - /* Screen Size / Aspect Ratio */ - if (edid[0x15] == 0 && edid[0x16] == 0) - { - info->width_mm = -1; - info->height_mm = -1; - info->aspect_ratio = -1.0; - } - else if (edid[0x16] == 0) - { - info->width_mm = -1; - info->height_mm = -1; - info->aspect_ratio = 100.0 / (edid[0x15] + 99); - } - else if (edid[0x15] == 0) - { - info->width_mm = -1; - info->height_mm = -1; - info->aspect_ratio = 100.0 / (edid[0x16] + 99); - info->aspect_ratio = 1/info->aspect_ratio; /* portrait */ - } - else - { - info->width_mm = 10 * edid[0x15]; - info->height_mm = 10 * edid[0x16]; - } - - /* Gamma */ - if (edid[0x17] == 0xFF) - info->gamma = -1.0; - else - info->gamma = (edid[0x17] + 100.0) / 100.0; - - /* Features */ - info->standby = get_bit (edid[0x18], 7); - info->suspend = get_bit (edid[0x18], 6); - info->active_off = get_bit (edid[0x18], 5); - - if (info->is_digital) - { - info->connector.digital.rgb444 = TRUE; - if (get_bit (edid[0x18], 3)) - info->connector.digital.ycrcb444 = 1; - if (get_bit (edid[0x18], 4)) - info->connector.digital.ycrcb422 = 1; - } - else - { - int bits = get_bits (edid[0x18], 3, 4); - ColorType color_type[4] = - { - MONOCHROME, RGB, OTHER_COLOR, UNDEFINED_COLOR - }; - - info->connector.analog.color_type = color_type[bits]; - } - - info->srgb_is_standard = get_bit (edid[0x18], 2); - - /* In 1.3 this is called "has preferred timing" */ - info->preferred_timing_includes_native = get_bit (edid[0x18], 1); - - /* FIXME: In 1.3 this indicates whether the monitor accepts GTF */ - info->continuous_frequency = get_bit (edid[0x18], 0); - return TRUE; -} - -static double -decode_fraction (int high, int low) -{ - double result = 0.0; - int i; - - high = (high << 2) | low; - - for (i = 0; i < 10; ++i) - result += get_bit (high, i) * pow (2, i - 10); - - return result; -} - -static int -decode_color_characteristics (const uchar *edid, MonitorInfo *info) -{ - info->red_x = decode_fraction (edid[0x1b], get_bits (edid[0x19], 6, 7)); - info->red_y = decode_fraction (edid[0x1c], get_bits (edid[0x19], 5, 4)); - info->green_x = decode_fraction (edid[0x1d], get_bits (edid[0x19], 2, 3)); - info->green_y = decode_fraction (edid[0x1e], get_bits (edid[0x19], 0, 1)); - info->blue_x = decode_fraction (edid[0x1f], get_bits (edid[0x1a], 6, 7)); - info->blue_y = decode_fraction (edid[0x20], get_bits (edid[0x1a], 4, 5)); - info->white_x = decode_fraction (edid[0x21], get_bits (edid[0x1a], 2, 3)); - info->white_y = decode_fraction (edid[0x22], get_bits (edid[0x1a], 0, 1)); - - return TRUE; -} - -static int -decode_established_timings (const uchar *edid, MonitorInfo *info) -{ - static const Timing established[][8] = - { - { - { 800, 600, 60 }, - { 800, 600, 56 }, - { 640, 480, 75 }, - { 640, 480, 72 }, - { 640, 480, 67 }, - { 640, 480, 60 }, - { 720, 400, 88 }, - { 720, 400, 70 } - }, - { - { 1280, 1024, 75 }, - { 1024, 768, 75 }, - { 1024, 768, 70 }, - { 1024, 768, 60 }, - { 1024, 768, 87 }, - { 832, 624, 75 }, - { 800, 600, 75 }, - { 800, 600, 72 } - }, - { - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, - { 1152, 870, 75 } - }, - }; - - int i, j, idx; - - idx = 0; - for (i = 0; i < 3; ++i) - { - for (j = 0; j < 8; ++j) - { - int byte = edid[0x23 + i]; - - if (get_bit (byte, j) && established[i][j].frequency != 0) - info->established[idx++] = established[i][j]; - } - } - return TRUE; -} - -static int -decode_standard_timings (const uchar *edid, MonitorInfo *info) -{ - int i; - - for (i = 0; i < 8; i++) - { - int first = edid[0x26 + 2 * i]; - int second = edid[0x27 + 2 * i]; - - if (first != 0x01 && second != 0x01) - { - int w = 8 * (first + 31); - int h = 0; - - switch (get_bits (second, 6, 7)) - { - case 0x00: h = (w / 16) * 10; break; - case 0x01: h = (w / 4) * 3; break; - case 0x02: h = (w / 5) * 4; break; - case 0x03: h = (w / 16) * 9; break; - } - - info->standard[i].width = w; - info->standard[i].height = h; - info->standard[i].frequency = get_bits (second, 0, 5) + 60; - } - } - - return TRUE; -} - -static void -decode_lf_string (const uchar *s, int n_chars, char *result) -{ - int i; - for (i = 0; i < n_chars; ++i) - { - if (s[i] == 0x0a) - { - *result++ = '\0'; - break; - } - else if (s[i] == 0x00) - { - /* Convert embedded 0's to spaces */ - *result++ = ' '; - } - else - { - *result++ = s[i]; - } - } -} - -static void -decode_display_descriptor (const uchar *desc, - MonitorInfo *info) -{ - switch (desc[0x03]) - { - case 0xFC: - decode_lf_string (desc + 5, 13, info->dsc_product_name); - break; - case 0xFF: - decode_lf_string (desc + 5, 13, info->dsc_serial_number); - break; - case 0xFE: - decode_lf_string (desc + 5, 13, info->dsc_string); - break; - case 0xFD: - /* Range Limits */ - break; - case 0xFB: - /* Color Point */ - break; - case 0xFA: - /* Timing Identifications */ - break; - case 0xF9: - /* Color Management */ - break; - case 0xF8: - /* Timing Codes */ - break; - case 0xF7: - /* Established Timings */ - break; - case 0x10: - break; - } -} - -static void -decode_detailed_timing (const uchar *timing, - DetailedTiming *detailed) -{ - int bits; - StereoType stereo[] = - { - NO_STEREO, NO_STEREO, FIELD_RIGHT, FIELD_LEFT, - TWO_WAY_RIGHT_ON_EVEN, TWO_WAY_LEFT_ON_EVEN, - FOUR_WAY_INTERLEAVED, SIDE_BY_SIDE - }; - - detailed->pixel_clock = (timing[0x00] | timing[0x01] << 8) * 10000; - detailed->h_addr = timing[0x02] | ((timing[0x04] & 0xf0) << 4); - detailed->h_blank = timing[0x03] | ((timing[0x04] & 0x0f) << 8); - detailed->v_addr = timing[0x05] | ((timing[0x07] & 0xf0) << 4); - detailed->v_blank = timing[0x06] | ((timing[0x07] & 0x0f) << 8); - detailed->h_front_porch = timing[0x08] | get_bits (timing[0x0b], 6, 7) << 8; - detailed->h_sync = timing[0x09] | get_bits (timing[0x0b], 4, 5) << 8; - detailed->v_front_porch = - get_bits (timing[0x0a], 4, 7) | get_bits (timing[0x0b], 2, 3) << 4; - detailed->v_sync = - get_bits (timing[0x0a], 0, 3) | get_bits (timing[0x0b], 0, 1) << 4; - detailed->width_mm = timing[0x0c] | get_bits (timing[0x0e], 4, 7) << 8; - detailed->height_mm = timing[0x0d] | get_bits (timing[0x0e], 0, 3) << 8; - detailed->right_border = timing[0x0f]; - detailed->top_border = timing[0x10]; - - detailed->interlaced = get_bit (timing[0x11], 7); - - /* Stereo */ - bits = get_bits (timing[0x11], 5, 6) << 1 | get_bit (timing[0x11], 0); - detailed->stereo = stereo[bits]; - - /* Sync */ - bits = timing[0x11]; - - detailed->digital_sync = get_bit (bits, 4); - if (detailed->digital_sync) - { - detailed->connector.digital.composite = !get_bit (bits, 3); - - if (detailed->connector.digital.composite) - { - detailed->connector.digital.serrations = get_bit (bits, 2); - detailed->connector.digital.negative_vsync = FALSE; - } - else - { - detailed->connector.digital.serrations = FALSE; - detailed->connector.digital.negative_vsync = !get_bit (bits, 2); - } - - detailed->connector.digital.negative_hsync = !get_bit (bits, 0); - } - else - { - detailed->connector.analog.bipolar = get_bit (bits, 3); - detailed->connector.analog.serrations = get_bit (bits, 2); - detailed->connector.analog.sync_on_green = !get_bit (bits, 1); - } -} - -static int -decode_descriptors (const uchar *edid, MonitorInfo *info) -{ - int i; - int timing_idx; - - timing_idx = 0; - - for (i = 0; i < 4; ++i) - { - int index = 0x36 + i * 18; - - if (edid[index + 0] == 0x00 && edid[index + 1] == 0x00) - { - decode_display_descriptor (edid + index, info); - } - else - { - decode_detailed_timing ( - edid + index, &(info->detailed_timings[timing_idx++])); - } - } - - info->n_detailed_timings = timing_idx; - - return TRUE; -} - -static void -decode_check_sum (const uchar *edid, - MonitorInfo *info) -{ - int i; - uchar check = 0; - - for (i = 0; i < 128; ++i) - check += edid[i]; - - info->checksum = check; -} - -MonitorInfo * -decode_edid (const uchar *edid) -{ - MonitorInfo *info = g_new0 (MonitorInfo, 1); - - decode_check_sum (edid, info); - - if (decode_header (edid) - && decode_vendor_and_product_identification (edid, info) - && decode_edid_version (edid, info) - && decode_display_parameters (edid, info) - && decode_color_characteristics (edid, info) - && decode_established_timings (edid, info) - && decode_standard_timings (edid, info) - && decode_descriptors (edid, info)) - { - return info; - } - else - { - g_free (info); - return NULL; - } -} diff --git a/gtk/display/edid.h b/gtk/display/edid.h deleted file mode 100644 index dc3daa3..0000000 --- a/gtk/display/edid.h +++ /dev/null @@ -1,192 +0,0 @@ -/* edid.h - * - * Copyright 2007, 2008, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Soren Sandmann <sandmann@xxxxxxxxxx> - */ - -#ifndef EDID_H -#define EDID_H - -typedef unsigned char uchar; -typedef struct MonitorInfo MonitorInfo; -typedef struct Timing Timing; -typedef struct DetailedTiming DetailedTiming; - -typedef enum -{ - UNDEFINED, - DVI, - HDMI_A, - HDMI_B, - MDDI, - DISPLAY_PORT -} Interface; - -typedef enum -{ - UNDEFINED_COLOR, - MONOCHROME, - RGB, - OTHER_COLOR -} ColorType; - -typedef enum -{ - NO_STEREO, - FIELD_RIGHT, - FIELD_LEFT, - TWO_WAY_RIGHT_ON_EVEN, - TWO_WAY_LEFT_ON_EVEN, - FOUR_WAY_INTERLEAVED, - SIDE_BY_SIDE -} StereoType; - -struct Timing -{ - int width; - int height; - int frequency; -}; - -struct DetailedTiming -{ - int pixel_clock; - int h_addr; - int h_blank; - int h_sync; - int h_front_porch; - int v_addr; - int v_blank; - int v_sync; - int v_front_porch; - int width_mm; - int height_mm; - int right_border; - int top_border; - int interlaced; - StereoType stereo; - - int digital_sync; - union - { - struct - { - int bipolar; - int serrations; - int sync_on_green; - } analog; - - struct - { - int composite; - int serrations; - int negative_vsync; - int negative_hsync; - } digital; - } connector; -}; - -struct MonitorInfo -{ - int checksum; - char manufacturer_code[4]; - int product_code; - unsigned int serial_number; - - int production_week; /* -1 if not specified */ - int production_year; /* -1 if not specified */ - int model_year; /* -1 if not specified */ - - int major_version; - int minor_version; - - int is_digital; - - union - { - struct - { - int bits_per_primary; - Interface interface; - int rgb444; - int ycrcb444; - int ycrcb422; - } digital; - - struct - { - double video_signal_level; - double sync_signal_level; - double total_signal_level; - - int blank_to_black; - - int separate_hv_sync; - int composite_sync_on_h; - int composite_sync_on_green; - int serration_on_vsync; - ColorType color_type; - } analog; - } connector; - - int width_mm; /* -1 if not specified */ - int height_mm; /* -1 if not specified */ - double aspect_ratio; /* -1.0 if not specififed */ - - double gamma; /* -1.0 if not specified */ - - int standby; - int suspend; - int active_off; - - int srgb_is_standard; - int preferred_timing_includes_native; - int continuous_frequency; - - double red_x; - double red_y; - double green_x; - double green_y; - double blue_x; - double blue_y; - double white_x; - double white_y; - - Timing established[24]; /* Terminated by 0x0x0 */ - Timing standard[8]; - - int n_detailed_timings; - DetailedTiming detailed_timings[4]; /* If monitor has a preferred - * mode, it is the first one - * (whether it has, is - * determined by the - * preferred_timing_includes - * bit. - */ - - /* Optional product description */ - char dsc_serial_number[14]; - char dsc_product_name[14]; - char dsc_string[14]; /* Unspecified ASCII data */ -}; - -MonitorInfo *decode_edid (const uchar *data); -char *make_display_name (const MonitorInfo *info); - -#endif diff --git a/gtk/display/gnome-rr-config.c b/gtk/display/gnome-rr-config.c deleted file mode 100644 index 82befb0..0000000 --- a/gtk/display/gnome-rr-config.c +++ /dev/null @@ -1,2048 +0,0 @@ -/* gnome-rr-config.c - * -*- c-basic-offset: 4 -*- - * - * Copyright 2007, 2008, Red Hat, Inc. - * Copyright 2010 Giovanni Campagna - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Soren Sandmann <sandmann@xxxxxxxxxx> - */ - -#define GNOME_DESKTOP_USE_UNSTABLE_API - -#include <config.h> -#include <glib/gi18n-lib.h> -#include <stdlib.h> -#include <string.h> -#include <glib.h> -#include <glib/gstdio.h> - -#ifdef HAVE_X11 -#include <X11/Xlib.h> -#include <gdk/gdkx.h> -#endif - -#include "gnome-rr-config.h" - -#include "edid.h" -#include "gnome-rr-private.h" - -#define CONFIG_INTENDED_BASENAME "monitors.xml" -#define CONFIG_BACKUP_BASENAME "monitors.xml.backup" - -/* In version 0 of the config file format, we had several <configuration> - * toplevel elements and no explicit version number. So, the filed looked - * like - * - * <configuration> - * ... - * </configuration> - * <configuration> - * ... - * </configuration> - * - * Since version 1 of the config file, the file has a toplevel <monitors> - * element to group all the configurations. That element has a "version" - * attribute which is an integer. So, the file looks like this: - * - * <monitors version="1"> - * <configuration> - * ... - * </configuration> - * <configuration> - * ... - * </configuration> - * </monitors> - */ - -/* A helper wrapper around the GMarkup parser stuff */ -static gboolean parse_file_gmarkup (const gchar *file, - const GMarkupParser *parser, - gpointer data, - GError **err); - -typedef struct CrtcAssignment CrtcAssignment; - -static gboolean crtc_assignment_apply (CrtcAssignment *assign, - guint32 timestamp, - GError **error); -static CrtcAssignment *crtc_assignment_new (GnomeRRScreen *screen, - GnomeRROutputInfo **outputs, - GError **error); -static void crtc_assignment_free (CrtcAssignment *assign); - -enum { - PROP_0, - PROP_SCREEN, - PROP_LAST -}; - -G_DEFINE_TYPE (GnomeRRConfig, gnome_rr_config, G_TYPE_OBJECT) - -typedef struct Parser Parser; - -/* Parser for monitor configurations */ -struct Parser -{ - int config_file_version; - GnomeRROutputInfo * output; - GnomeRRConfig * configuration; - GPtrArray * outputs; - GPtrArray * configurations; - GQueue * stack; -}; - -static int -parse_int (const char *text) -{ - return strtol (text, NULL, 0); -} - -static guint -parse_uint (const char *text) -{ - return strtoul (text, NULL, 0); -} - -static gboolean -stack_is (Parser *parser, - const char *s1, - ...) -{ - GList *stack = NULL; - const char *s; - GList *l1, *l2; - va_list args; - - stack = g_list_prepend (stack, (gpointer)s1); - - va_start (args, s1); - - s = va_arg (args, const char *); - while (s) - { - stack = g_list_prepend (stack, (gpointer)s); - s = va_arg (args, const char *); - } - - l1 = stack; - l2 = parser->stack->head; - - while (l1 && l2) - { - if (strcmp (l1->data, l2->data) != 0) - { - g_list_free (stack); - return FALSE; - } - - l1 = l1->next; - l2 = l2->next; - } - - g_list_free (stack); - - return (!l1 && !l2); -} - -static void -handle_start_element (GMarkupParseContext *context, - const gchar *name, - const gchar **attr_names, - const gchar **attr_values, - gpointer user_data, - GError **err) -{ - Parser *parser = user_data; - - if (strcmp (name, "output") == 0) - { - int i; - g_return_if_fail (parser->output == NULL); - - parser->output = g_object_new (GNOME_TYPE_RR_OUTPUT_INFO, NULL); - parser->output->priv->rotation = 0; - - for (i = 0; attr_names[i] != NULL; ++i) - { - if (strcmp (attr_names[i], "name") == 0) - { - parser->output->priv->name = g_strdup (attr_values[i]); - break; - } - } - - if (!parser->output->priv->name) - { - /* This really shouldn't happen, but it's better to make - * something up than to crash later. - */ - g_warning ("Malformed monitor configuration file"); - - parser->output->priv->name = g_strdup ("default"); - } - parser->output->priv->connected = FALSE; - parser->output->priv->on = FALSE; - parser->output->priv->primary = FALSE; - } - else if (strcmp (name, "configuration") == 0) - { - g_return_if_fail (parser->configuration == NULL); - - parser->configuration = g_object_new (GNOME_TYPE_RR_CONFIG, NULL); - parser->configuration->priv->clone = FALSE; - parser->configuration->priv->outputs = NULL; - } - else if (strcmp (name, "monitors") == 0) - { - int i; - - for (i = 0; attr_names[i] != NULL; i++) - { - if (strcmp (attr_names[i], "version") == 0) - { - parser->config_file_version = parse_int (attr_values[i]); - break; - } - } - } - - g_queue_push_tail (parser->stack, g_strdup (name)); -} - -static void -handle_end_element (GMarkupParseContext *context, - const gchar *name, - gpointer user_data, - GError **err) -{ - Parser *parser = user_data; - - if (strcmp (name, "output") == 0) - { - /* If no rotation properties were set, just use GNOME_RR_ROTATION_0 */ - if (parser->output->priv->rotation == 0) - parser->output->priv->rotation = GNOME_RR_ROTATION_0; - - g_ptr_array_add (parser->outputs, parser->output); - - parser->output = NULL; - } - else if (strcmp (name, "configuration") == 0) - { - g_ptr_array_add (parser->outputs, NULL); - parser->configuration->priv->outputs = - (GnomeRROutputInfo **)g_ptr_array_free (parser->outputs, FALSE); - parser->outputs = g_ptr_array_new (); - g_ptr_array_add (parser->configurations, parser->configuration); - parser->configuration = NULL; - } - - g_free (g_queue_pop_tail (parser->stack)); -} - -#define TOPLEVEL_ELEMENT (parser->config_file_version > 0 ? "monitors" : NULL) - -static void -handle_text (GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer user_data, - GError **err) -{ - Parser *parser = user_data; - - if (stack_is (parser, "vendor", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - parser->output->priv->connected = TRUE; - - strncpy ((gchar*) parser->output->priv->vendor, text, 3); - parser->output->priv->vendor[3] = 0; - } - else if (stack_is (parser, "clone", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - if (strcmp (text, "yes") == 0) - parser->configuration->priv->clone = TRUE; - } - else if (stack_is (parser, "product", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - parser->output->priv->connected = TRUE; - - parser->output->priv->product = parse_int (text); - } - else if (stack_is (parser, "serial", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - parser->output->priv->connected = TRUE; - - parser->output->priv->serial = parse_uint (text); - } - else if (stack_is (parser, "width", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - parser->output->priv->on = TRUE; - - parser->output->priv->width = parse_int (text); - } - else if (stack_is (parser, "x", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - parser->output->priv->on = TRUE; - - parser->output->priv->x = parse_int (text); - } - else if (stack_is (parser, "y", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - parser->output->priv->on = TRUE; - - parser->output->priv->y = parse_int (text); - } - else if (stack_is (parser, "height", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - parser->output->priv->on = TRUE; - - parser->output->priv->height = parse_int (text); - } - else if (stack_is (parser, "rate", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - parser->output->priv->on = TRUE; - - parser->output->priv->rate = parse_int (text); - } - else if (stack_is (parser, "rotation", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - if (strcmp (text, "normal") == 0) - { - parser->output->priv->rotation |= GNOME_RR_ROTATION_0; - } - else if (strcmp (text, "left") == 0) - { - parser->output->priv->rotation |= GNOME_RR_ROTATION_90; - } - else if (strcmp (text, "upside_down") == 0) - { - parser->output->priv->rotation |= GNOME_RR_ROTATION_180; - } - else if (strcmp (text, "right") == 0) - { - parser->output->priv->rotation |= GNOME_RR_ROTATION_270; - } - } - else if (stack_is (parser, "reflect_x", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - if (strcmp (text, "yes") == 0) - { - parser->output->priv->rotation |= GNOME_RR_REFLECT_X; - } - } - else if (stack_is (parser, "reflect_y", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - if (strcmp (text, "yes") == 0) - { - parser->output->priv->rotation |= GNOME_RR_REFLECT_Y; - } - } - else if (stack_is (parser, "primary", "output", "configuration", TOPLEVEL_ELEMENT, NULL)) - { - if (strcmp (text, "yes") == 0) - { - parser->output->priv->primary = TRUE; - } - } - else - { - /* Ignore other properties so we can expand the format in the future */ - } -} - -static void -parser_free (Parser *parser) -{ - int i; - GList *list; - - g_return_if_fail (parser != NULL); - - if (parser->output) - g_object_unref (parser->output); - - if (parser->configuration) - g_object_unref (parser->configuration); - - for (i = 0; i < parser->outputs->len; ++i) - { - GnomeRROutputInfo *output = parser->outputs->pdata[i]; - - g_object_unref (output); - } - - g_ptr_array_free (parser->outputs, TRUE); - - for (i = 0; i < parser->configurations->len; ++i) - { - GnomeRRConfig *config = parser->configurations->pdata[i]; - - g_object_unref (config); - } - - g_ptr_array_free (parser->configurations, TRUE); - - for (list = parser->stack->head; list; list = list->next) - g_free (list->data); - g_queue_free (parser->stack); - - g_free (parser); -} - -static GnomeRRConfig ** -configurations_read_from_file (const gchar *filename, GError **error) -{ - Parser *parser = g_new0 (Parser, 1); - GnomeRRConfig **result; - GMarkupParser callbacks = { - handle_start_element, - handle_end_element, - handle_text, - NULL, /* passthrough */ - NULL, /* error */ - }; - - parser->config_file_version = 0; - parser->configurations = g_ptr_array_new (); - parser->outputs = g_ptr_array_new (); - parser->stack = g_queue_new (); - - if (!parse_file_gmarkup (filename, &callbacks, parser, error)) - { - result = NULL; - - g_return_val_if_fail (parser->outputs, NULL); - goto out; - } - - g_return_val_if_fail (parser->outputs, NULL); - - g_ptr_array_add (parser->configurations, NULL); - result = (GnomeRRConfig **)g_ptr_array_free (parser->configurations, FALSE); - parser->configurations = g_ptr_array_new (); - - g_return_val_if_fail (parser->outputs, NULL); -out: - parser_free (parser); - - return result; -} - -static void -gnome_rr_config_init (GnomeRRConfig *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_RR_CONFIG, GnomeRRConfigPrivate); - - self->priv->clone = FALSE; - self->priv->screen = NULL; - self->priv->outputs = NULL; -} - -static void -gnome_rr_config_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *property) -{ - GnomeRRConfig *self = GNOME_RR_CONFIG (gobject); - - switch (property_id) { - case PROP_SCREEN: - self->priv->screen = g_value_dup_object (value); - return; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, property); - } -} - -static void -gnome_rr_config_finalize (GObject *gobject) -{ - GnomeRRConfig *self = GNOME_RR_CONFIG (gobject); - - if (self->priv->screen) - g_object_unref (self->priv->screen); - - if (self->priv->outputs) { - int i; - - for (i = 0; self->priv->outputs[i] != NULL; i++) { - GnomeRROutputInfo *output = self->priv->outputs[i]; - g_object_unref (output); - } - g_free (self->priv->outputs); - } - - G_OBJECT_CLASS (gnome_rr_config_parent_class)->finalize (gobject); -} - -gboolean -gnome_rr_config_load_current (GnomeRRConfig *config, GError **error) -{ - GPtrArray *a; - GnomeRROutput **rr_outputs; - int i; - int clone_width = -1; - int clone_height = -1; - int last_x; - - g_return_val_if_fail (GNOME_IS_RR_CONFIG (config), FALSE); - - a = g_ptr_array_new (); - rr_outputs = gnome_rr_screen_list_outputs (config->priv->screen); - - config->priv->clone = FALSE; - - for (i = 0; rr_outputs[i] != NULL; ++i) - { - GnomeRROutput *rr_output = rr_outputs[i]; - GnomeRROutputInfo *output = g_object_new (GNOME_TYPE_RR_OUTPUT_INFO, NULL); - GnomeRRMode *mode = NULL; - const guint8 *edid_data = gnome_rr_output_get_edid_data (rr_output); - GnomeRRCrtc *crtc; - - output->priv->name = g_strdup (gnome_rr_output_get_name (rr_output)); - output->priv->connected = gnome_rr_output_is_connected (rr_output); - - if (!output->priv->connected) - { - output->priv->x = -1; - output->priv->y = -1; - output->priv->width = -1; - output->priv->height = -1; - output->priv->rate = -1; - output->priv->rotation = GNOME_RR_ROTATION_0; - } - else - { - MonitorInfo *info = NULL; - - if (edid_data) - info = decode_edid (edid_data); - - if (info) - { - memcpy (output->priv->vendor, info->manufacturer_code, - sizeof (output->priv->vendor)); - - output->priv->product = info->product_code; - output->priv->serial = info->serial_number; - output->priv->aspect = info->aspect_ratio; - } - else - { - strcpy (output->priv->vendor, "???"); - output->priv->product = 0; - output->priv->serial = 0; - } - - if (gnome_rr_output_is_laptop (rr_output)) - output->priv->display_name = g_strdup (_("Laptop")); - else - output->priv->display_name = make_display_name (info); - - g_free (info); - - crtc = gnome_rr_output_get_crtc (rr_output); - mode = crtc? gnome_rr_crtc_get_current_mode (crtc) : NULL; - - if (crtc && mode) - { - output->priv->on = TRUE; - - gnome_rr_crtc_get_position (crtc, &output->priv->x, &output->priv->y); - output->priv->width = gnome_rr_mode_get_width (mode); - output->priv->height = gnome_rr_mode_get_height (mode); - output->priv->rate = gnome_rr_mode_get_freq (mode); - output->priv->rotation = gnome_rr_crtc_get_current_rotation (crtc); - - if (output->priv->x == 0 && output->priv->y == 0) { - if (clone_width == -1) { - clone_width = output->priv->width; - clone_height = output->priv->height; - } else if (clone_width == output->priv->width && - clone_height == output->priv->height) { - config->priv->clone = TRUE; - } - } - } - else - { - output->priv->on = FALSE; - config->priv->clone = FALSE; - } - - /* Get preferred size for the monitor */ - mode = gnome_rr_output_get_preferred_mode (rr_output); - - if (!mode) - { - GnomeRRMode **modes = gnome_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->priv->pref_width = gnome_rr_mode_get_width (mode); - output->priv->pref_height = gnome_rr_mode_get_height (mode); - } - else - { - /* Pick some random numbers. This should basically never happen */ - output->priv->pref_width = 1024; - output->priv->pref_height = 768; - } - } - - output->priv->primary = gnome_rr_output_get_is_primary (rr_output); - - g_ptr_array_add (a, output); - } - - g_ptr_array_add (a, NULL); - - config->priv->outputs = (GnomeRROutputInfo **)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->priv->outputs[i] != NULL; ++i) - { - GnomeRROutputInfo *output = config->priv->outputs[i]; - - if (output->priv->on) - { - last_x = MAX (last_x, output->priv->x + output->priv->width); - } - } - - /* Now position all off displays to the right of the - * on displays - */ - for (i = 0; config->priv->outputs[i] != NULL; ++i) - { - GnomeRROutputInfo *output = config->priv->outputs[i]; - - if (output->priv->connected && !output->priv->on) - { - output->priv->x = last_x; - last_x = output->priv->x + output->priv->width; - } - } - - g_return_val_if_fail (gnome_rr_config_match (config, config), FALSE); - - return TRUE; -} - -gboolean -gnome_rr_config_load_filename (GnomeRRConfig *result, const char *filename, GError **error) -{ - GnomeRRConfig *current; - GnomeRRConfig **configs; - gboolean found = FALSE; - - g_return_val_if_fail (GNOME_IS_RR_CONFIG (result), FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - current = gnome_rr_config_new_current (result->priv->screen, error); - - configs = configurations_read_from_file (filename, error); - - if (configs) - { - int i; - - for (i = 0; configs[i] != NULL; ++i) - { - if (gnome_rr_config_match (configs[i], current)) - { - int j; - GPtrArray *array; - result->priv->clone = configs[i]->priv->clone; - - array = g_ptr_array_new (); - for (j = 0; configs[i]->priv->outputs[j] != NULL; j++) { - g_object_ref (configs[i]->priv->outputs[j]); - g_ptr_array_add (array, configs[i]->priv->outputs[j]); - } - g_ptr_array_add (array, NULL); - result->priv->outputs = (GnomeRROutputInfo **) g_ptr_array_free (array, FALSE); - - found = TRUE; - break; - } - g_object_unref (configs[i]); - } - g_free (configs); - - if (!found) - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_MATCHING_CONFIG, - _("none of the saved display configurations matched the active configuration")); - } - - g_object_unref (current); - return found; -} - -static void -gnome_rr_config_class_init (GnomeRRConfigClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GnomeRROutputInfoPrivate)); - - gobject_class->set_property = gnome_rr_config_set_property; - gobject_class->finalize = gnome_rr_config_finalize; - - g_object_class_install_property (gobject_class, PROP_SCREEN, - g_param_spec_object ("screen", "Screen", "The GnomeRRScreen this config applies to", GNOME_TYPE_RR_SCREEN, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); -} - -GnomeRRConfig * -gnome_rr_config_new_current (GnomeRRScreen *screen, GError **error) -{ - GnomeRRConfig *self = g_object_new (GNOME_TYPE_RR_CONFIG, "screen", screen, NULL); - - if (gnome_rr_config_load_current (self, error)) - return self; - else - { - g_object_unref (self); - return NULL; - } -} - -GnomeRRConfig * -gnome_rr_config_new_stored (GnomeRRScreen *screen, GError **error) -{ - GnomeRRConfig *self = g_object_new (GNOME_TYPE_RR_CONFIG, "screen", screen, NULL); - char *filename; - gboolean success; - - filename = gnome_rr_config_get_intended_filename (); - - success = gnome_rr_config_load_filename (self, filename, error); - - g_free (filename); - - if (success) - return self; - else - { - g_object_unref (self); - return NULL; - } -} - -static gboolean -parse_file_gmarkup (const gchar *filename, - const GMarkupParser *parser, - gpointer data, - GError **err) -{ - GMarkupParseContext *context = NULL; - gchar *contents = NULL; - gboolean result = TRUE; - gsize len; - - if (!g_file_get_contents (filename, &contents, &len, err)) - { - result = FALSE; - goto out; - } - - context = g_markup_parse_context_new (parser, 0, data, NULL); - - if (!g_markup_parse_context_parse (context, contents, len, err)) - { - result = FALSE; - goto out; - } - - if (!g_markup_parse_context_end_parse (context, err)) - { - result = FALSE; - goto out; - } - -out: - if (contents) - g_free (contents); - - if (context) - g_markup_parse_context_free (context); - - return result; -} - -static gboolean -output_match (GnomeRROutputInfo *output1, GnomeRROutputInfo *output2) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (output1), FALSE); - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (output2), FALSE); - - if (strcmp (output1->priv->name, output2->priv->name) != 0) - return FALSE; - - if (strcmp (output1->priv->vendor, output2->priv->vendor) != 0) - return FALSE; - - if (output1->priv->product != output2->priv->product) - return FALSE; - - if (output1->priv->serial != output2->priv->serial) - return FALSE; - - if (output1->priv->connected != output2->priv->connected) - return FALSE; - - return TRUE; -} - -static gboolean -output_equal (GnomeRROutputInfo *output1, GnomeRROutputInfo *output2) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (output1), FALSE); - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (output2), FALSE); - - if (!output_match (output1, output2)) - return FALSE; - - if (output1->priv->on != output2->priv->on) - return FALSE; - - if (output1->priv->on) - { - if (output1->priv->width != output2->priv->width) - return FALSE; - - if (output1->priv->height != output2->priv->height) - return FALSE; - - if (output1->priv->rate != output2->priv->rate) - return FALSE; - - if (output1->priv->x != output2->priv->x) - return FALSE; - - if (output1->priv->y != output2->priv->y) - return FALSE; - - if (output1->priv->rotation != output2->priv->rotation) - return FALSE; - } - - return TRUE; -} - -static GnomeRROutputInfo * -find_output (GnomeRRConfig *config, const char *name) -{ - int i; - - for (i = 0; config->priv->outputs[i] != NULL; ++i) - { - GnomeRROutputInfo *output = config->priv->outputs[i]; - - if (strcmp (name, output->priv->name) == 0) - return output; - } - - return NULL; -} - -/* Match means "these configurations apply to the same hardware - * setups" - */ -gboolean -gnome_rr_config_match (GnomeRRConfig *c1, GnomeRRConfig *c2) -{ - int i; - g_return_val_if_fail (GNOME_IS_RR_CONFIG (c1), FALSE); - g_return_val_if_fail (GNOME_IS_RR_CONFIG (c2), FALSE); - - for (i = 0; c1->priv->outputs[i] != NULL; ++i) - { - GnomeRROutputInfo *output1 = c1->priv->outputs[i]; - GnomeRROutputInfo *output2; - - output2 = find_output (c2, output1->priv->name); - if (!output2 || !output_match (output1, output2)) - return FALSE; - } - - return TRUE; -} - -/* Equal means "the configurations will result in the same - * modes being set on the outputs" - */ -gboolean -gnome_rr_config_equal (GnomeRRConfig *c1, - GnomeRRConfig *c2) -{ - int i; - g_return_val_if_fail (GNOME_IS_RR_CONFIG (c1), FALSE); - g_return_val_if_fail (GNOME_IS_RR_CONFIG (c2), FALSE); - - for (i = 0; c1->priv->outputs[i] != NULL; ++i) - { - GnomeRROutputInfo *output1 = c1->priv->outputs[i]; - GnomeRROutputInfo *output2; - - output2 = find_output (c2, output1->priv->name); - if (!output2 || !output_equal (output1, output2)) - return FALSE; - } - - return TRUE; -} - -static GnomeRROutputInfo ** -make_outputs (GnomeRRConfig *config) -{ - GPtrArray *outputs; - GnomeRROutputInfo *first_on; - int i; - - outputs = g_ptr_array_new (); - - first_on = NULL; - - for (i = 0; config->priv->outputs[i] != NULL; ++i) - { - GnomeRROutputInfo *old = config->priv->outputs[i]; - GnomeRROutputInfo *new = g_object_new (GNOME_TYPE_RR_OUTPUT_INFO, NULL); - *(new->priv) = *(old->priv); - if (old->priv->name) - new->priv->name = g_strdup (old->priv->name); - if (old->priv->display_name) - new->priv->display_name = g_strdup (old->priv->display_name); - - if (old->priv->on && !first_on) - first_on = old; - - if (config->priv->clone && new->priv->on) - { - if (!first_on) { - g_warn_if_reached (); - goto end; - } - new->priv->width = first_on->priv->width; - new->priv->height = first_on->priv->height; - new->priv->rotation = first_on->priv->rotation; - new->priv->x = 0; - new->priv->y = 0; - } - - g_ptr_array_add (outputs, new); - } - -end: - g_ptr_array_add (outputs, NULL); - - return (GnomeRROutputInfo **)g_ptr_array_free (outputs, FALSE); -} - -gboolean -gnome_rr_config_applicable (GnomeRRConfig *configuration, - GnomeRRScreen *screen, - GError **error) -{ - GnomeRROutputInfo **outputs; - CrtcAssignment *assign; - gboolean result; - int i; - - g_return_val_if_fail (GNOME_IS_RR_CONFIG (configuration), FALSE); - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - outputs = make_outputs (configuration); - assign = crtc_assignment_new (screen, outputs, error); - - if (assign) - { - result = TRUE; - crtc_assignment_free (assign); - } - else - { - result = FALSE; - } - - for (i = 0; outputs[i] != NULL; i++) { - g_object_unref (outputs[i]); - } - - return result; -} - -/* Database management */ - -static void -ensure_config_directory (void) -{ - g_mkdir_with_parents (g_get_user_config_dir (), 0700); -} - -char * -gnome_rr_config_get_backup_filename (void) -{ - ensure_config_directory (); - return g_build_filename (g_get_user_config_dir (), CONFIG_BACKUP_BASENAME, NULL); -} - -char * -gnome_rr_config_get_intended_filename (void) -{ - ensure_config_directory (); - return g_build_filename (g_get_user_config_dir (), CONFIG_INTENDED_BASENAME, NULL); -} - -static const char * -get_rotation_name (GnomeRRRotation r) -{ - if (r & GNOME_RR_ROTATION_0) - return "normal"; - if (r & GNOME_RR_ROTATION_90) - return "left"; - if (r & GNOME_RR_ROTATION_180) - return "upside_down"; - if (r & GNOME_RR_ROTATION_270) - return "right"; - - return "normal"; -} - -static const char * -yes_no (int x) -{ - return x? "yes" : "no"; -} - -static const char * -get_reflect_x (GnomeRRRotation r) -{ - return yes_no (r & GNOME_RR_REFLECT_X); -} - -static const char * -get_reflect_y (GnomeRRRotation r) -{ - return yes_no (r & GNOME_RR_REFLECT_Y); -} - -static void -emit_configuration (GnomeRRConfig *config, - GString *string) -{ - int j; - - g_string_append_printf (string, " <configuration>\n"); - - g_string_append_printf (string, " <clone>%s</clone>\n", yes_no (config->priv->clone)); - - for (j = 0; config->priv->outputs[j] != NULL; ++j) - { - GnomeRROutputInfo *output = config->priv->outputs[j]; - - g_string_append_printf ( - string, " <output name=\"%s\">\n", output->priv->name); - - if (output->priv->connected && *output->priv->vendor != '\0') - { - g_string_append_printf ( - string, " <vendor>%s</vendor>\n", output->priv->vendor); - g_string_append_printf ( - string, " <product>0x%04x</product>\n", output->priv->product); - g_string_append_printf ( - string, " <serial>0x%08x</serial>\n", output->priv->serial); - } - - /* An unconnected output which is on does not make sense */ - if (output->priv->connected && output->priv->on) - { - g_string_append_printf ( - string, " <width>%d</width>\n", output->priv->width); - g_string_append_printf ( - string, " <height>%d</height>\n", output->priv->height); - g_string_append_printf ( - string, " <rate>%d</rate>\n", output->priv->rate); - g_string_append_printf ( - string, " <x>%d</x>\n", output->priv->x); - g_string_append_printf ( - string, " <y>%d</y>\n", output->priv->y); - g_string_append_printf ( - string, " <rotation>%s</rotation>\n", get_rotation_name (output->priv->rotation)); - g_string_append_printf ( - string, " <reflect_x>%s</reflect_x>\n", get_reflect_x (output->priv->rotation)); - g_string_append_printf ( - string, " <reflect_y>%s</reflect_y>\n", get_reflect_y (output->priv->rotation)); - g_string_append_printf ( - string, " <primary>%s</primary>\n", yes_no (output->priv->primary)); - } - - g_string_append_printf (string, " </output>\n"); - } - - g_string_append_printf (string, " </configuration>\n"); -} - -void -gnome_rr_config_sanitize (GnomeRRConfig *config) -{ - int i; - int x_offset, y_offset; - gboolean found; - - /* Offset everything by the top/left-most coordinate to - * make sure the configuration starts at (0, 0) - */ - x_offset = y_offset = G_MAXINT; - for (i = 0; config->priv->outputs[i]; ++i) - { - GnomeRROutputInfo *output = config->priv->outputs[i]; - - if (output->priv->on) - { - x_offset = MIN (x_offset, output->priv->x); - y_offset = MIN (y_offset, output->priv->y); - } - } - - for (i = 0; config->priv->outputs[i]; ++i) - { - GnomeRROutputInfo *output = config->priv->outputs[i]; - - if (output->priv->on) - { - output->priv->x -= x_offset; - output->priv->y -= y_offset; - } - } - - /* Only one primary, please */ - found = FALSE; - for (i = 0; config->priv->outputs[i]; ++i) - { - if (config->priv->outputs[i]->priv->primary) - { - if (found) - { - config->priv->outputs[i]->priv->primary = FALSE; - } - else - { - found = TRUE; - } - } - } -} - -static gboolean -output_info_is_laptop (GnomeRROutputInfo *info) -{ - if (info->priv->name - && (strstr (info->priv->name, "lvds") || /* Most drivers use an "LVDS" prefix... */ - strstr (info->priv->name, "LVDS") || - strstr (info->priv->name, "Lvds") || - strstr (info->priv->name, "LCD"))) /* ... but fglrx uses "LCD" in some versions. Shoot me now, kthxbye. */ - return TRUE; - - return FALSE; -} - -gboolean -gnome_rr_config_ensure_primary (GnomeRRConfig *configuration) -{ - int i; - GnomeRROutputInfo *laptop; - GnomeRROutputInfo *top_left; - gboolean found; - GnomeRRConfigPrivate *priv; - - g_return_val_if_fail (GNOME_IS_RR_CONFIG (configuration), FALSE); - - laptop = NULL; - top_left = NULL; - found = FALSE; - priv = configuration->priv; - - for (i = 0; priv->outputs[i] != NULL; ++i) { - GnomeRROutputInfo *info = priv->outputs[i]; - - if (!info->priv->on) { - info->priv->primary = FALSE; - continue; - } - - /* ensure only one */ - if (info->priv->primary) { - if (found) { - info->priv->primary = FALSE; - } else { - found = TRUE; - } - } - - if (top_left == NULL - || (info->priv->x < top_left->priv->x - && info->priv->y < top_left->priv->y)) { - top_left = info; - } - if (laptop == NULL - && output_info_is_laptop (info)) { - /* shame we can't find the connector type - as with gnome_rr_output_is_laptop */ - laptop = info; - } - } - - if (!found) { - if (laptop != NULL) { - laptop->priv->primary = TRUE; - } else if (top_left != NULL) { - top_left->priv->primary = TRUE; - } - } - - return !found; -} - -GString * -gnome_rr_config_dump (GnomeRRConfig *configuration) -{ - GString *output; - - output = g_string_new (""); - emit_configuration (configuration, output); - return output; -} - -gboolean -gnome_rr_config_save (GnomeRRConfig *configuration, GError **error) -{ - GnomeRRConfig **configurations; - GString *output; - int i; - gchar *intended_filename; - gchar *backup_filename; - gboolean result; - - g_return_val_if_fail (GNOME_IS_RR_CONFIG (configuration), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - output = g_string_new (""); - - backup_filename = gnome_rr_config_get_backup_filename (); - intended_filename = gnome_rr_config_get_intended_filename (); - - configurations = configurations_read_from_file (intended_filename, NULL); /* NULL-GError */ - - g_string_append_printf (output, "<monitors version=\"1\">\n"); - - if (configurations) - { - for (i = 0; configurations[i] != NULL; ++i) - { - if (!gnome_rr_config_match (configurations[i], configuration)) - emit_configuration (configurations[i], output); - g_object_unref (configurations[i]); - } - - g_free (configurations); - } - - emit_configuration (configuration, output); - - g_string_append_printf (output, "</monitors>\n"); - - /* backup the file first */ - rename (intended_filename, backup_filename); /* no error checking because the intended file may not even exist */ - - result = g_file_set_contents (intended_filename, output->str, -1, error); - - if (!result) - rename (backup_filename, intended_filename); /* no error checking because the backup may not even exist */ - - g_free (backup_filename); - g_free (intended_filename); - - return result; -} - -gboolean -gnome_rr_config_apply_with_time (GnomeRRConfig *config, - GnomeRRScreen *screen, - guint32 timestamp, - GError **error) -{ - CrtcAssignment *assignment; - GnomeRROutputInfo **outputs; - gboolean result = FALSE; - int i; - - g_return_val_if_fail (GNOME_IS_RR_CONFIG (config), FALSE); - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), FALSE); - - outputs = make_outputs (config); - - assignment = crtc_assignment_new (screen, outputs, error); - - for (i = 0; outputs[i] != NULL; i++) - g_object_unref (outputs[i]); - g_free (outputs); - - if (assignment) - { - if (crtc_assignment_apply (assignment, timestamp, error)) - result = TRUE; - - crtc_assignment_free (assignment); - - gdk_flush (); - } - - return result; -} - -/* gnome_rr_config_apply_from_filename_with_time: - * @screen: A #GnomeRRScreen - * @filename: Path of the file to look in for stored RANDR configurations. - * @timestamp: X server timestamp from the event that causes the screen configuration to change (a user's button press, for example) - * @error: Location to store error, or %NULL - * - * First, this function refreshes the @screen to match the current RANDR - * configuration from the X server. Then, it tries to load the file in - * @filename and looks for suitable matching RANDR configurations in the file; - * if one is found, that configuration will be applied to the current set of - * RANDR outputs. - * - * Typically, @filename is the result of gnome_rr_config_get_intended_filename() or - * gnome_rr_config_get_backup_filename(). - * - * Returns: TRUE if the RANDR configuration was loaded and applied from - * $(XDG_CONFIG_HOME)/monitors.xml, or FALSE otherwise: - * - * If the current RANDR configuration could not be refreshed, the @error will - * have a domain of #GNOME_RR_ERROR and a corresponding error code. - * - * If the file in question is loaded successfully but the configuration cannot - * be applied, the @error will have a domain of #GNOME_RR_ERROR. Note that an - * error code of #GNOME_RR_ERROR_NO_MATCHING_CONFIG is not a real error; it - * simply means that there were no stored configurations that match the current - * set of RANDR outputs. - * - * If the file in question cannot be loaded, the @error will have a domain of - * #G_FILE_ERROR. Note that an error code of G_FILE_ERROR_NOENT is not really - * an error, either; it means that there was no stored configuration file and so - * nothing is changed. - */ -gboolean -gnome_rr_config_apply_from_filename_with_time (GnomeRRScreen *screen, const char *filename, guint32 timestamp, GError **error) -{ - GnomeRRConfig *stored; - GError *my_error; - - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - my_error = NULL; - if (!gnome_rr_screen_refresh (screen, &my_error)) { - if (my_error) { - g_propagate_error (error, my_error); - return FALSE; /* This is a genuine error */ - } - - /* This means the screen didn't change, so just proceed */ - } - - stored = g_object_new (GNOME_TYPE_RR_CONFIG, "screen", screen, NULL); - - if (gnome_rr_config_load_filename (stored, filename, error)) - { - gboolean result; - - gnome_rr_config_ensure_primary (stored); - result = gnome_rr_config_apply_with_time (stored, screen, timestamp, error); - - g_object_unref (stored); - return result; - } - else - { - g_object_unref (stored); - return FALSE; - } -} - -/** - * gnome_rr_config_get_outputs: - * - * Returns: (array zero-terminated=1) (element-type GnomeDesktop.RROutputInfo) (transfer none): the output configuration for this #GnomeRRConfig - */ -GnomeRROutputInfo ** -gnome_rr_config_get_outputs (GnomeRRConfig *self) -{ - g_return_val_if_fail (GNOME_IS_RR_CONFIG (self), NULL); - - return self->priv->outputs; -} - -/** - * gnome_rr_config_get_clone: - * - * Returns: whether at least two outputs are at (0, 0) offset and they - * have the same width/height. Those outputs are of course connected and on - * (i.e. they have a CRTC assigned). - */ -gboolean -gnome_rr_config_get_clone (GnomeRRConfig *self) -{ - g_return_val_if_fail (GNOME_IS_RR_CONFIG (self), FALSE); - - return self->priv->clone; -} - -void -gnome_rr_config_set_clone (GnomeRRConfig *self, gboolean clone) -{ - g_return_if_fail (GNOME_IS_RR_CONFIG (self)); - - self->priv->clone = clone; -} - -/* - * CRTC assignment - */ -typedef struct CrtcInfo CrtcInfo; - -struct CrtcInfo -{ - GnomeRRMode *mode; - int x; - int y; - GnomeRRRotation rotation; - GPtrArray *outputs; -}; - -struct CrtcAssignment -{ - GnomeRRScreen *screen; - GHashTable *info; - GnomeRROutput *primary; -}; - -static gboolean -can_clone (CrtcInfo *info, - GnomeRROutput *output) -{ - int i; - - for (i = 0; i < info->outputs->len; ++i) - { - GnomeRROutput *clone = info->outputs->pdata[i]; - - if (!gnome_rr_output_can_clone (clone, output)) - return FALSE; - } - - return TRUE; -} - -static gboolean -crtc_assignment_assign (CrtcAssignment *assign, - GnomeRRCrtc *crtc, - GnomeRRMode *mode, - int x, - int y, - GnomeRRRotation rotation, - gboolean primary, - GnomeRROutput *output, - GError **error) -{ - CrtcInfo *info = g_hash_table_lookup (assign->info, crtc); - guint32 crtc_id; - const char *output_name; - - crtc_id = gnome_rr_crtc_get_id (crtc); - output_name = gnome_rr_output_get_name (output); - - if (!gnome_rr_crtc_can_drive_output (crtc, output)) - { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_CRTC_ASSIGNMENT, - _("CRTC %d cannot drive output %s"), crtc_id, output_name); - return FALSE; - } - - if (!gnome_rr_output_supports_mode (output, mode)) - { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_CRTC_ASSIGNMENT, - _("output %s does not support mode %dx%d@%dHz"), - output_name, - gnome_rr_mode_get_width (mode), - gnome_rr_mode_get_height (mode), - gnome_rr_mode_get_freq (mode)); - return FALSE; - } - - if (!gnome_rr_crtc_supports_rotation (crtc, rotation)) - { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_CRTC_ASSIGNMENT, - _("CRTC %d does not support rotation=%s"), - crtc_id, - get_rotation_name (rotation)); - return FALSE; - } - - if (info) - { - if (!(info->mode == mode && - info->x == x && - info->y == y && - info->rotation == rotation)) - { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_CRTC_ASSIGNMENT, - _("output %s does not have the same parameters as another cloned output:\n" - "existing mode = %d, new mode = %d\n" - "existing coordinates = (%d, %d), new coordinates = (%d, %d)\n" - "existing rotation = %s, new rotation = %s"), - output_name, - gnome_rr_mode_get_id (info->mode), gnome_rr_mode_get_id (mode), - info->x, info->y, - x, y, - get_rotation_name (info->rotation), get_rotation_name (rotation)); - return FALSE; - } - - if (!can_clone (info, output)) - { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_CRTC_ASSIGNMENT, - _("cannot clone to output %s"), - output_name); - return FALSE; - } - - g_ptr_array_add (info->outputs, output); - - if (primary && !assign->primary) - { - assign->primary = output; - } - - return TRUE; - } - else - { - CrtcInfo *info = g_new0 (CrtcInfo, 1); - - info->mode = mode; - info->x = x; - info->y = y; - info->rotation = rotation; - info->outputs = g_ptr_array_new (); - - g_ptr_array_add (info->outputs, output); - - g_hash_table_insert (assign->info, crtc, info); - - if (primary && !assign->primary) - { - assign->primary = output; - } - - return TRUE; - } -} - -static void -crtc_assignment_unassign (CrtcAssignment *assign, - GnomeRRCrtc *crtc, - GnomeRROutput *output) -{ - CrtcInfo *info = g_hash_table_lookup (assign->info, crtc); - - if (info) - { - g_ptr_array_remove (info->outputs, output); - - if (assign->primary == output) - { - assign->primary = NULL; - } - - if (info->outputs->len == 0) - g_hash_table_remove (assign->info, crtc); - } -} - -static void -crtc_assignment_free (CrtcAssignment *assign) -{ - g_hash_table_destroy (assign->info); - - g_free (assign); -} - -typedef struct { - guint32 timestamp; - gboolean has_error; - GError **error; -} ConfigureCrtcState; - -static void -configure_crtc (gpointer key, - gpointer value, - gpointer data) -{ - GnomeRRCrtc *crtc = key; - CrtcInfo *info = value; - ConfigureCrtcState *state = data; - - if (state->has_error) - return; - - if (!gnome_rr_crtc_set_config_with_time (crtc, - state->timestamp, - info->x, info->y, - info->mode, - info->rotation, - (GnomeRROutput **)info->outputs->pdata, - info->outputs->len, - state->error)) - state->has_error = TRUE; -} - -static gboolean -mode_is_rotated (CrtcInfo *info) -{ - if ((info->rotation & GNOME_RR_ROTATION_270) || - (info->rotation & GNOME_RR_ROTATION_90)) - { - return TRUE; - } - return FALSE; -} - -static gboolean -crtc_is_rotated (GnomeRRCrtc *crtc) -{ - GnomeRRRotation r = gnome_rr_crtc_get_current_rotation (crtc); - - if ((r & GNOME_RR_ROTATION_270) || - (r & GNOME_RR_ROTATION_90)) - { - return TRUE; - } - - return FALSE; -} - -static void -accumulate_error (GString *accumulated_error, GError *error) -{ - g_string_append_printf (accumulated_error, " %s\n", error->message); - g_error_free (error); -} - -/* Check whether the given set of settings can be used - * at the same time -- ie. whether there is an assignment - * of CRTC's to outputs. - * - * Brute force - the number of objects involved is small - * enough that it doesn't matter. - */ -static gboolean -real_assign_crtcs (GnomeRRScreen *screen, - GnomeRROutputInfo **outputs, - CrtcAssignment *assignment, - GError **error) -{ - GnomeRRCrtc **crtcs = gnome_rr_screen_list_crtcs (screen); - GnomeRROutputInfo *output; - int i; - gboolean tried_mode; - GError *my_error; - GString *accumulated_error; - gboolean success; - - output = *outputs; - if (!output) - return TRUE; - - /* It is always allowed for an output to be turned off */ - if (!output->priv->on) - { - return real_assign_crtcs (screen, outputs + 1, assignment, error); - } - - success = FALSE; - tried_mode = FALSE; - accumulated_error = g_string_new (NULL); - - for (i = 0; crtcs[i] != NULL; ++i) - { - GnomeRRCrtc *crtc = crtcs[i]; - int crtc_id = gnome_rr_crtc_get_id (crtc); - int pass; - - g_string_append_printf (accumulated_error, - _("Trying modes for CRTC %d\n"), - crtc_id); - - /* Make two passes, one where frequencies must match, then - * one where they don't have to - */ - for (pass = 0; pass < 2; ++pass) - { - GnomeRROutput *gnome_rr_output = gnome_rr_screen_get_output_by_name (screen, output->priv->name); - GnomeRRMode **modes = gnome_rr_output_list_modes (gnome_rr_output); - int j; - - for (j = 0; modes[j] != NULL; ++j) - { - GnomeRRMode *mode = modes[j]; - int mode_width; - int mode_height; - int mode_freq; - - mode_width = gnome_rr_mode_get_width (mode); - mode_height = gnome_rr_mode_get_height (mode); - mode_freq = gnome_rr_mode_get_freq (mode); - - g_string_append_printf (accumulated_error, - _("CRTC %d: trying mode %dx%d@%dHz with output at %dx%d@%dHz (pass %d)\n"), - crtc_id, - mode_width, mode_height, mode_freq, - output->priv->width, output->priv->height, output->priv->rate, - pass); - - if (mode_width == output->priv->width && - mode_height == output->priv->height && - (pass == 1 || mode_freq == output->priv->rate)) - { - tried_mode = TRUE; - - my_error = NULL; - if (crtc_assignment_assign ( - assignment, crtc, modes[j], - output->priv->x, output->priv->y, - output->priv->rotation, - output->priv->primary, - gnome_rr_output, - &my_error)) - { - my_error = NULL; - if (real_assign_crtcs (screen, outputs + 1, assignment, &my_error)) { - success = TRUE; - goto out; - } else - accumulate_error (accumulated_error, my_error); - - crtc_assignment_unassign (assignment, crtc, gnome_rr_output); - } else - accumulate_error (accumulated_error, my_error); - } - } - } - } - -out: - - if (success) - g_string_free (accumulated_error, TRUE); - else { - char *str; - - str = g_string_free (accumulated_error, FALSE); - - if (tried_mode) - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_CRTC_ASSIGNMENT, - _("could not assign CRTCs to outputs:\n%s"), - str); - else - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_CRTC_ASSIGNMENT, - _("none of the selected modes were compatible with the possible modes:\n%s"), - str); - - g_free (str); - } - - return success; -} - -static void -crtc_info_free (CrtcInfo *info) -{ - g_ptr_array_free (info->outputs, TRUE); - g_free (info); -} - -static void -get_required_virtual_size (CrtcAssignment *assign, int *width, int *height) -{ - GList *active_crtcs = g_hash_table_get_keys (assign->info); - GList *list; - int d; - - if (!width) - width = &d; - if (!height) - height = &d; - - /* Compute size of the screen */ - *width = *height = 1; - for (list = active_crtcs; list != NULL; list = list->next) - { - GnomeRRCrtc *crtc = list->data; - CrtcInfo *info = g_hash_table_lookup (assign->info, crtc); - int w, h; - - w = gnome_rr_mode_get_width (info->mode); - h = gnome_rr_mode_get_height (info->mode); - - if (mode_is_rotated (info)) - { - int tmp = h; - h = w; - w = tmp; - } - - *width = MAX (*width, info->x + w); - *height = MAX (*height, info->y + h); - } - - g_list_free (active_crtcs); -} - -static CrtcAssignment * -crtc_assignment_new (GnomeRRScreen *screen, GnomeRROutputInfo **outputs, GError **error) -{ - CrtcAssignment *assignment = g_new0 (CrtcAssignment, 1); - - assignment->info = g_hash_table_new_full ( - g_direct_hash, g_direct_equal, NULL, (GFreeFunc)crtc_info_free); - - if (real_assign_crtcs (screen, outputs, assignment, error)) - { - int width, height; - int min_width, max_width, min_height, max_height; - int required_pixels, min_pixels, max_pixels; - - get_required_virtual_size (assignment, &width, &height); - - gnome_rr_screen_get_ranges ( - screen, &min_width, &max_width, &min_height, &max_height); - - required_pixels = width * height; - min_pixels = min_width * min_height; - max_pixels = max_width * max_height; - - if (required_pixels < min_pixels || required_pixels > max_pixels) - { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_BOUNDS_ERROR, - /* Translators: the "requested", "minimum", and - * "maximum" words here are not keywords; please - * translate them as usual. */ - _("required virtual size does not fit available size: " - "requested=(%d, %d), minimum=(%d, %d), maximum=(%d, %d)"), - width, height, - min_width, min_height, - max_width, max_height); - goto fail; - } - - assignment->screen = screen; - - return assignment; - } - -fail: - crtc_assignment_free (assignment); - - return NULL; -} - -#ifdef HAVE_X11 -/* - * get_dpi_from_x_server copied from - * https://bugzilla.novell.com/show_bug.cgi?id=217790#c20 - */ -#define DPI_FALLBACK 96 -#define DPI_LOW_REASONABLE_VALUE 50 -#define DPI_HIGH_REASONABLE_VALUE 500 -static double -get_dpi_from_x_server (void) -{ - GdkScreen *screen; - double dpi; - - screen = gdk_screen_get_default (); - if (screen) - { - int width_pixels, width_mm; - int height_pixels, height_mm; - double width_dpi, height_dpi; - - width_pixels = gdk_screen_get_width (screen); - width_mm = gdk_screen_get_width_mm (screen); - - height_pixels = gdk_screen_get_height (screen); - height_mm = gdk_screen_get_height_mm (screen); - - width_dpi = width_pixels / (width_mm / 25.4); - height_dpi = height_pixels / (height_mm / 25.4); - - if (width_dpi < DPI_LOW_REASONABLE_VALUE || width_dpi > DPI_HIGH_REASONABLE_VALUE - || height_dpi < DPI_LOW_REASONABLE_VALUE || height_dpi > DPI_HIGH_REASONABLE_VALUE) - dpi = DPI_FALLBACK; - else - dpi = (width_dpi + height_dpi) / 2.0; - } - else - { - /* Huh!? No screen? */ - - dpi = DPI_FALLBACK; - } - - return dpi; -} -#endif - -static gboolean -crtc_assignment_apply (CrtcAssignment *assign, guint32 timestamp, GError **error) -{ - GnomeRRCrtc **all_crtcs = gnome_rr_screen_list_crtcs (assign->screen); - int width, height; - int i; - int min_width, max_width, min_height, max_height; - int width_mm, height_mm; - gboolean success = TRUE; - - /* Compute size of the screen */ - get_required_virtual_size (assign, &width, &height); - - gnome_rr_screen_get_ranges ( - assign->screen, &min_width, &max_width, &min_height, &max_height); - - /* We should never get here if the dimensions don't fit in the virtual size, - * but just in case we do, fix it up. - */ - width = MAX (min_width, width); - width = MIN (max_width, width); - height = MAX (min_height, height); - height = MIN (max_height, height); - - /* FMQ: do we need to check the sizes instead of clamping them? */ - - /* Grab the server while we fiddle with the CRTCs and the screen, so that - * apps that listen for RANDR notifications will only receive the final - * status. - */ -#ifdef HAVE_X11 - gdk_x11_display_grab (gdk_screen_get_display (assign->screen->priv->gdk_screen)); -#endif - - /* Turn off all crtcs that are currently displaying outside the new screen, - * or are not used in the new setup - */ - for (i = 0; all_crtcs[i] != NULL; ++i) - { - GnomeRRCrtc *crtc = all_crtcs[i]; - GnomeRRMode *mode = gnome_rr_crtc_get_current_mode (crtc); - int x, y; - - if (mode) - { - int w, h; - gnome_rr_crtc_get_position (crtc, &x, &y); - - w = gnome_rr_mode_get_width (mode); - h = gnome_rr_mode_get_height (mode); - - if (crtc_is_rotated (crtc)) - { - int tmp = h; - h = w; - w = tmp; - } - - if (x + w > width || y + h > height || !g_hash_table_lookup (assign->info, crtc)) - { - if (!gnome_rr_crtc_set_config_with_time (crtc, timestamp, 0, 0, NULL, GNOME_RR_ROTATION_0, NULL, 0, error)) - { - success = FALSE; - break; - } - - } - } - } - - /* The 'physical size' of an X screen is meaningless if that screen - * can consist of many monitors. So just pick a size that make the - * dpi 96. - * - * Firefox and Evince apparently believe what X tells them. - */ - double dpi = 96.0; -#ifdef HAVE_X11 - dpi = get_dpi_from_x_server(); -#endif - width_mm = (width / dpi) * 25.4 + 0.5; - height_mm = (height / dpi) * 25.4 + 0.5; - - if (success) - { - ConfigureCrtcState state; - - gnome_rr_screen_set_size (assign->screen, width, height, width_mm, height_mm); - - state.timestamp = timestamp; - state.has_error = FALSE; - state.error = error; - - g_hash_table_foreach (assign->info, configure_crtc, &state); - - success = !state.has_error; - } - - gnome_rr_screen_set_primary_output (assign->screen, assign->primary); - -#ifdef HAVE_X11 - gdk_x11_display_ungrab (gdk_screen_get_display (assign->screen->priv->gdk_screen)); -#endif - return success; -} diff --git a/gtk/display/gnome-rr-config.h b/gtk/display/gnome-rr-config.h deleted file mode 100644 index b1b6c15..0000000 --- a/gtk/display/gnome-rr-config.h +++ /dev/null @@ -1,149 +0,0 @@ -/* gnome-rr-config.h - * -*- c-basic-offset: 4 -*- - * - * Copyright 2007, 2008, Red Hat, Inc. - * Copyright 2010 Giovanni Campagna - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Soren Sandmann <sandmann@xxxxxxxxxx> - */ -#ifndef GNOME_RR_CONFIG_H -#define GNOME_RR_CONFIG_H - -#ifndef GNOME_DESKTOP_USE_UNSTABLE_API -#error gnome-rr-config.h is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnome-rr-config.h -#endif - -#include <glib.h> -#include <glib-object.h> -#include "gnome-rr.h" - -typedef struct GnomeRROutputInfoPrivate GnomeRROutputInfoPrivate; -typedef struct GnomeRRConfigPrivate GnomeRRConfigPrivate; - -typedef struct -{ - GObject parent; - - /*< private >*/ - GnomeRROutputInfoPrivate *priv; -} GnomeRROutputInfo; - -typedef struct -{ - GObjectClass parent_class; -} GnomeRROutputInfoClass; - -#define GNOME_TYPE_RR_OUTPUT_INFO (gnome_rr_output_info_get_type()) -#define GNOME_RR_OUTPUT_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_OUTPUT_INFO, GnomeRROutputInfo)) -#define GNOME_IS_RR_OUTPUT_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_OUTPUT_INFO)) -#define GNOME_RR_OUTPUT_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RR_OUTPUT_INFO, GnomeRROutputInfoClass)) -#define GNOME_IS_RR_OUTPUT_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RR_OUTPUT_INFO)) -#define GNOME_RR_OUTPUT_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_RR_OUTPUT_INFO, GnomeRROutputInfoClass)) - -GType gnome_rr_output_info_get_type (void); - -char *gnome_rr_output_info_get_name (GnomeRROutputInfo *self); - -gboolean gnome_rr_output_info_is_active (GnomeRROutputInfo *self); -void gnome_rr_output_info_set_active (GnomeRROutputInfo *self, gboolean active); - -void gnome_rr_output_info_get_geometry (GnomeRROutputInfo *self, int *x, int *y, int *width, int *height); -void gnome_rr_output_info_set_geometry (GnomeRROutputInfo *self, int x, int y, int width, int height); - -int gnome_rr_output_info_get_refresh_rate (GnomeRROutputInfo *self); -void gnome_rr_output_info_set_refresh_rate (GnomeRROutputInfo *self, int rate); - -GnomeRRRotation gnome_rr_output_info_get_rotation (GnomeRROutputInfo *self); -void gnome_rr_output_info_set_rotation (GnomeRROutputInfo *self, GnomeRRRotation rotation); - -gboolean gnome_rr_output_info_is_connected (GnomeRROutputInfo *self); -void gnome_rr_output_info_get_vendor (GnomeRROutputInfo *self, gchar* vendor); -guint gnome_rr_output_info_get_product (GnomeRROutputInfo *self); -guint gnome_rr_output_info_get_serial (GnomeRROutputInfo *self); -double gnome_rr_output_info_get_aspect_ratio (GnomeRROutputInfo *self); -char *gnome_rr_output_info_get_display_name (GnomeRROutputInfo *self); - -gboolean gnome_rr_output_info_get_primary (GnomeRROutputInfo *self); -void gnome_rr_output_info_set_primary (GnomeRROutputInfo *self, gboolean primary); - -int gnome_rr_output_info_get_preferred_width (GnomeRROutputInfo *self); -int gnome_rr_output_info_get_preferred_height (GnomeRROutputInfo *self); - -typedef struct -{ - GObject parent; - - /*< private >*/ - GnomeRRConfigPrivate *priv; -} GnomeRRConfig; - -typedef struct -{ - GObjectClass parent_class; -} GnomeRRConfigClass; - -#define GNOME_TYPE_RR_CONFIG (gnome_rr_config_get_type()) -#define GNOME_RR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_CONFIG, GnomeRRConfig)) -#define GNOME_IS_RR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_CONFIG)) -#define GNOME_RR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RR_CONFIG, GnomeRRConfigClass)) -#define GNOME_IS_RR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RR_CONFIG)) -#define GNOME_RR_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_RR_CONFIG, GnomeRRConfigClass)) - -GType gnome_rr_config_get_type (void); - -GnomeRRConfig *gnome_rr_config_new_current (GnomeRRScreen *screen, - GError **error); -GnomeRRConfig *gnome_rr_config_new_stored (GnomeRRScreen *screen, - GError **error); -gboolean gnome_rr_config_load_current (GnomeRRConfig *self, - GError **error); -gboolean gnome_rr_config_load_filename (GnomeRRConfig *self, - const gchar *filename, - GError **error); -gboolean gnome_rr_config_match (GnomeRRConfig *config1, - GnomeRRConfig *config2); -gboolean gnome_rr_config_equal (GnomeRRConfig *config1, - GnomeRRConfig *config2); -gboolean gnome_rr_config_save (GnomeRRConfig *configuration, - GError **error); -void gnome_rr_config_sanitize (GnomeRRConfig *configuration); -gboolean gnome_rr_config_ensure_primary (GnomeRRConfig *configuration); - -gboolean gnome_rr_config_apply_with_time (GnomeRRConfig *configuration, - GnomeRRScreen *screen, - guint32 timestamp, - GError **error); - -gboolean gnome_rr_config_apply_from_filename_with_time (GnomeRRScreen *screen, - const char *filename, - guint32 timestamp, - GError **error); - -gboolean gnome_rr_config_applicable (GnomeRRConfig *configuration, - GnomeRRScreen *screen, - GError **error); - -gboolean gnome_rr_config_get_clone (GnomeRRConfig *configuration); -void gnome_rr_config_set_clone (GnomeRRConfig *configuration, gboolean clone); -GnomeRROutputInfo **gnome_rr_config_get_outputs (GnomeRRConfig *configuration); -GString *gnome_rr_config_dump (GnomeRRConfig *configuration); - -char *gnome_rr_config_get_backup_filename (void); -char *gnome_rr_config_get_intended_filename (void); - -#endif diff --git a/gtk/display/gnome-rr-generic.c b/gtk/display/gnome-rr-generic.c deleted file mode 100644 index 90c4055..0000000 --- a/gtk/display/gnome-rr-generic.c +++ /dev/null @@ -1,218 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* gnome-rr.c - * - * Copyright 2011, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> - */ - -#define GNOME_DESKTOP_USE_UNSTABLE_API - -#include <config.h> -#include <glib/gi18n-lib.h> -#include <string.h> - -#include <gtk/gtk.h> - -#undef GNOME_DISABLE_DEPRECATED -#include "gnome-rr.h" -#include "gnome-rr-config.h" -#include "gnome-rr-private.h" -#include "gnome-rr-generic.h" - -struct GnomeRRGenericScreenPrivate -{ - RRMode rrmode_id; -}; - -static void gnome_rr_generic_screen_initable_iface_init (GInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (GnomeRRGenericScreen, gnome_rr_generic_screen, GNOME_TYPE_RR_SCREEN, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gnome_rr_generic_screen_initable_iface_init)) - -static gboolean -gnome_rr_generic_screen_initable_init (GInitable *initable, GCancellable *canc, GError **error) -{ - GInitableIface *iface, *parent_iface; - - iface = G_TYPE_INSTANCE_GET_INTERFACE(initable, G_TYPE_INITABLE, GInitableIface); - parent_iface = g_type_interface_peek_parent(iface); - - if (!parent_iface->init (initable, canc, error)) - return FALSE; - - return TRUE; -} - -static void -gnome_rr_generic_screen_initable_iface_init (GInitableIface *iface) -{ - iface->init = gnome_rr_generic_screen_initable_init; -} - -static void -gnome_rr_generic_screen_finalize (GObject *gobject) -{ - G_OBJECT_CLASS (gnome_rr_generic_screen_parent_class)->finalize (gobject); -} - -static void -gnome_rr_generic_screen_class_init (GnomeRRGenericScreenClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GnomeRRGenericScreenPrivate)); - - gobject_class->finalize = gnome_rr_generic_screen_finalize; -} - -static void -gnome_rr_generic_screen_init (GnomeRRGenericScreen *self) -{ - GnomeRRGenericScreenPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - GNOME_TYPE_RR_GENERIC_SCREEN, GnomeRRGenericScreenPrivate); - - self->priv = priv; -} - -gboolean -fill_out_screen_info (GnomeRRScreen *screen, ScreenInfo *info, - gboolean needs_reprobe, GError **error) -{ - GdkScreen *gdk_screen; - GPtrArray *crtcs, *outputs, *modes; - guint i; - - g_object_get(G_OBJECT(screen), "gdk-screen", &gdk_screen, NULL); - - crtcs = g_ptr_array_new (); - outputs = g_ptr_array_new (); - modes = g_ptr_array_new (); - - for (i = 0; i < gdk_screen_get_n_monitors(gdk_screen); i++) { - GdkRectangle monitor_geometry; - GnomeRRCrtc *crtc; - GnomeRROutput *output; - - crtc = crtc_new(info, i); - crtc->rotations = GNOME_RR_ROTATION_0; - g_ptr_array_add(crtcs, crtc); - - gdk_screen_get_monitor_geometry(gdk_screen, i, &monitor_geometry); - crtc->x = monitor_geometry.x; - crtc->y = monitor_geometry.y; - crtc->current_rotation = GNOME_RR_ROTATION_0; - - output = output_new(info, i); - output->name = gdk_screen_get_monitor_plug_name(gdk_screen, i); - output->current_crtc = crtc; - output->possible_crtcs = g_new0 (GnomeRRCrtc*, 2); - output->possible_crtcs[0] = crtc; - output->connected = TRUE; - output->width_mm = gdk_screen_get_monitor_width_mm(gdk_screen, i); - output->height_mm = gdk_screen_get_monitor_height_mm(gdk_screen, i); - - crtc->current_mode = mode_new(info, i); - crtc->current_mode->width = monitor_geometry.x; - crtc->current_mode->height = monitor_geometry.y; - output->modes = g_new0(GnomeRRMode*, 2); - output->modes[0] = crtc->current_mode; - g_ptr_array_add(modes, crtc->current_mode); - - crtc->current_outputs = g_new0(GnomeRROutput*, 2); - crtc->current_outputs[0] = output; - crtc->possible_outputs = g_new0(GnomeRROutput*, 2); - crtc->possible_outputs[0] = output; - } - - info->min_width = 0; - info->min_height = 0; - info->max_width = gdk_screen_get_width(gdk_screen); - info->max_height = gdk_screen_get_height(gdk_screen); - - g_ptr_array_add (modes, NULL); - info->modes = (GnomeRRMode **)g_ptr_array_free (modes, FALSE); - - g_ptr_array_add (crtcs, NULL); - info->crtcs = (GnomeRRCrtc **)g_ptr_array_free (crtcs, FALSE); - - g_ptr_array_add (outputs, NULL); - info->outputs = (GnomeRROutput **)g_ptr_array_free (outputs, FALSE); - - g_object_unref(G_OBJECT(gdk_screen)); - - return TRUE; -} - -gboolean -gnome_rr_crtc_set_config_with_time (GnomeRRCrtc *crtc, - guint32 timestamp, - int x, - int y, - GnomeRRMode *mode, - GnomeRRRotation rotation, - GnomeRROutput **outputs, - int n_outputs, - GError **error) -{ - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_UNKNOWN, - /* Translators: a CRTC is a CRT Controller (this is X terminology). */ - _("could not set the output configuration")); - - return FALSE; -} - -void -gnome_rr_screen_set_size (GnomeRRScreen *self, - int width, - int height, - int mm_width, - int mm_height) -{ - g_warning ("Unimplemented on MacOS X"); -} - -void -gnome_rr_crtc_set_gamma (GnomeRRCrtc *crtc, int size, - unsigned short *red, - unsigned short *green, - unsigned short *blue) -{ - g_return_if_fail (crtc != NULL); - g_return_if_fail (red != NULL); - g_return_if_fail (green != NULL); - g_return_if_fail (blue != NULL); - - g_warning ("Unimplemented on MacOS X"); -} - -gboolean -gnome_rr_crtc_get_gamma (GnomeRRCrtc *crtc, int *size, - unsigned short **red, unsigned short **green, - unsigned short **blue) -{ - g_return_val_if_fail (crtc != NULL, FALSE); - - g_warning ("Unimplemented on MacOS X"); - return FALSE; -} - -void -screen_set_primary_output (GnomeRRScreen *screen, GnomeRROutput *output) -{ - g_warning ("Unimplemented on MacOS X"); -} diff --git a/gtk/display/gnome-rr-generic.h b/gtk/display/gnome-rr-generic.h deleted file mode 100644 index 6694cd7..0000000 --- a/gtk/display/gnome-rr-generic.h +++ /dev/null @@ -1,53 +0,0 @@ -/* gnome-rr-generic.h - * - * Copyright 2011, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Authors: Soren Sandmann <sandmann@xxxxxxxxxx> - * Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> - */ - -#ifndef GNOME_RR_GENERIC_H -#define GNOME_RR_GENERIC_H - -#include <glib.h> -#include "gnome-rr.h" - -#define GNOME_TYPE_RR_GENERIC_SCREEN (gnome_rr_generic_screen_get_type()) -#define GNOME_RR_GENERIC_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_GENERIC_SCREEN, GnomeRRGenericScreen)) -#define GNOME_IS_RR_GENERIC_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_GENERIC_SCREEN)) -#define GNOME_RR_GENERIC_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RR_GENERIC_SCREEN, GnomeRRGenericScreenClass)) -#define GNOME_IS_RR_GENERIC_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RR_GENERIC_SCREEN)) -#define GNOME_RR_GENERIC_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_RR_GENERIC_SCREEN, GnomeRRGenericScreenClass)) - -typedef struct GnomeRRGenericScreenPrivate GnomeRRGenericScreenPrivate; - -typedef struct { - GnomeRRScreen parent; - - GnomeRRGenericScreenPrivate* priv; -} GnomeRRGenericScreen; - -typedef struct { - GnomeRRScreenClass parent_class; - - void (* changed) (void); -} GnomeRRGenericScreenClass; - -GType gnome_rr_generic_screen_get_type (void); - -#endif /* GNOME_RR_GENERIC_H */ diff --git a/gtk/display/gnome-rr-output-info.c b/gtk/display/gnome-rr-output-info.c deleted file mode 100644 index d9c1658..0000000 --- a/gtk/display/gnome-rr-output-info.c +++ /dev/null @@ -1,244 +0,0 @@ -/* gnome-rr-output-info.c - * -*- c-basic-offset: 4 -*- - * - * Copyright 2010 Giovanni Campagna - * - * This file is part of the Gnome Desktop Library. - * - * The Gnome Desktop Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#define GNOME_DESKTOP_USE_UNSTABLE_API - -#include <config.h> - -#include "gnome-rr-config.h" - -#include "edid.h" -#include "gnome-rr-private.h" - -G_DEFINE_TYPE (GnomeRROutputInfo, gnome_rr_output_info, G_TYPE_OBJECT) - -static void -gnome_rr_output_info_init (GnomeRROutputInfo *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_RR_OUTPUT_INFO, GnomeRROutputInfoPrivate); - - self->priv->name = NULL; - self->priv->on = FALSE; - self->priv->display_name = NULL; -} - -static void -gnome_rr_output_info_finalize (GObject *gobject) -{ - GnomeRROutputInfo *self = GNOME_RR_OUTPUT_INFO (gobject); - - g_free (self->priv->name); - g_free (self->priv->display_name); - - G_OBJECT_CLASS (gnome_rr_output_info_parent_class)->finalize (gobject); -} - -static void -gnome_rr_output_info_class_init (GnomeRROutputInfoClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GnomeRROutputInfoPrivate)); - - gobject_class->finalize = gnome_rr_output_info_finalize; -} - -/** - * gnome_rr_output_info_get_name: - * - * Returns: (transfer none): the output name - */ -char *gnome_rr_output_info_get_name (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), NULL); - - return self->priv->name; -} - -/** - * gnome_rr_output_info_is_active: - * - * Returns: whether there is a CRTC assigned to this output (i.e. a signal is being sent to it) - */ -gboolean gnome_rr_output_info_is_active (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), FALSE); - - return self->priv->on; -} - -void gnome_rr_output_info_set_active (GnomeRROutputInfo *self, gboolean active) -{ - g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self)); - - self->priv->on = active; -} - -/** - * gnome_rr_output_info_get_geometry: - * - * @self: a #GnomeRROutputInfo - * @x: (out) (allow-none): - * @y: (out) (allow-none): - * @width: (out) (allow-none): - * @height: (out) (allow-none): - */ -void gnome_rr_output_info_get_geometry (GnomeRROutputInfo *self, int *x, int *y, int *width, int *height) -{ - g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self)); - - if (x) - *x = self->priv->x; - if (y) - *y = self->priv->y; - if (width) - *width = self->priv->width; - if (height) - *height = self->priv->height; -} - -void gnome_rr_output_info_set_geometry (GnomeRROutputInfo *self, int x, int y, int width, int height) -{ - g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self)); - - self->priv->x = x; - self->priv->y = y; - self->priv->width = width; - self->priv->height = height; -} - -int gnome_rr_output_info_get_refresh_rate (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0); - - return self->priv->rate; -} - -void gnome_rr_output_info_set_refresh_rate (GnomeRROutputInfo *self, int rate) -{ - g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self)); - - self->priv->rate = rate; -} - -GnomeRRRotation gnome_rr_output_info_get_rotation (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), GNOME_RR_ROTATION_0); - - return self->priv->rotation; -} - -void gnome_rr_output_info_set_rotation (GnomeRROutputInfo *self, GnomeRRRotation rotation) -{ - g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self)); - - self->priv->rotation = rotation; -} - -/** - * gnome_rr_output_info_is_connected: - * - * Returns: whether the output is physically connected to a monitor - */ -gboolean gnome_rr_output_info_is_connected (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), FALSE); - - return self->priv->connected; -} - -/** - * gnome_rr_output_info_get_vendor: - * - * @self: a #GnomeRROutputInfo - * @vendor: (out caller-allocates) (array fixed-size=4): - */ -void gnome_rr_output_info_get_vendor (GnomeRROutputInfo *self, gchar* vendor) -{ - g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self)); - g_return_if_fail (vendor != NULL); - - vendor[0] = self->priv->vendor[0]; - vendor[1] = self->priv->vendor[1]; - vendor[2] = self->priv->vendor[2]; - vendor[3] = self->priv->vendor[3]; -} - -guint gnome_rr_output_info_get_product (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0); - - return self->priv->product; -} - -guint gnome_rr_output_info_get_serial (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0); - - return self->priv->serial; -} - -double gnome_rr_output_info_get_aspect_ratio (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0); - - return self->priv->aspect; -} - -/** - * gnome_rr_output_info_get_display_name: - * - * Returns: (transfer none): the display name of this output - */ -char *gnome_rr_output_info_get_display_name (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), NULL); - - return self->priv->display_name; -} - -gboolean gnome_rr_output_info_get_primary (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), FALSE); - - return self->priv->primary; -} - -void gnome_rr_output_info_set_primary (GnomeRROutputInfo *self, gboolean primary) -{ - g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self)); - - self->priv->primary = primary; -} - -int gnome_rr_output_info_get_preferred_width (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0); - - return self->priv->pref_width; -} - -int gnome_rr_output_info_get_preferred_height (GnomeRROutputInfo *self) -{ - g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0); - - return self->priv->pref_height; -} diff --git a/gtk/display/gnome-rr-private.h b/gtk/display/gnome-rr-private.h deleted file mode 100644 index 0e06b5e..0000000 --- a/gtk/display/gnome-rr-private.h +++ /dev/null @@ -1,204 +0,0 @@ -/* gnome-rr-private.h - * - * Copyright 2007, 2008, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Soren Sandmann <sandmann@xxxxxxxxxx> - */ - -#ifndef GNOME_RR_PRIVATE_H -#define GNOME_RR_PRIVATE_H - -#include <config.h> -#include <gtk/gtk.h> - -#ifdef HAVE_RANDR -#include <X11/extensions/Xrandr.h> -#endif - -#ifdef WIN32 -#include <windows.h> -#include <winuser.h> -#endif - -#ifndef HAVE_RANDR -/* This is to avoid a ton of ifdefs wherever we use a type from libXrandr */ -typedef int RROutput; -typedef int RRCrtc; -typedef int RRMode; -typedef int Rotation; -#define RR_Rotate_0 1 -#define RR_Rotate_90 2 -#define RR_Rotate_180 4 -#define RR_Rotate_270 8 -#define RR_Reflect_X 16 -#define RR_Reflect_Y 32 -#endif - -typedef struct ScreenInfo ScreenInfo; - -struct ScreenInfo -{ - int min_width; - int max_width; - int min_height; - int max_height; - - GnomeRROutput ** outputs; - GnomeRRCrtc ** crtcs; - GnomeRRMode ** modes; - - GnomeRRScreen * screen; - - GnomeRRMode ** clone_modes; - -#ifdef HAVE_RANDR - XRRScreenResources *resources; - RROutput primary; -#endif -}; - -struct GnomeRRScreenPrivate -{ - GdkScreen * gdk_screen; - ScreenInfo * info; -}; - -struct GnomeRROutputInfoPrivate -{ - char * name; - - gboolean on; - int width; - int height; - int rate; - int x; - int y; - GnomeRRRotation rotation; - - gboolean connected; - gchar vendor[4]; - guint product; - guint serial; - double aspect; - int pref_width; - int pref_height; - char * display_name; - gboolean primary; -}; - -struct GnomeRRConfigPrivate -{ - gboolean clone; - GnomeRRScreen * screen; - GnomeRROutputInfo ** outputs; -}; - -struct GnomeRROutput -{ - ScreenInfo * info; - RROutput id; - - char * name; - GnomeRRCrtc * current_crtc; - gboolean connected; - gulong width_mm; - gulong height_mm; - GnomeRRCrtc ** possible_crtcs; - GnomeRROutput ** clones; - GnomeRRMode ** modes; - int n_preferred; - guint8 * edid_data; - int edid_size; - char * connector_type; -}; - -struct GnomeRROutputWrap -{ - RROutput id; -}; - -struct GnomeRRCrtc -{ - ScreenInfo * info; - RRCrtc id; - - GnomeRRMode * current_mode; - GnomeRROutput ** current_outputs; - GnomeRROutput ** possible_outputs; - int x; - int y; - - GnomeRRRotation current_rotation; - GnomeRRRotation rotations; - int gamma_size; -}; - -struct GnomeRRMode -{ - ScreenInfo * info; - RRMode id; - char * name; - int width; - int height; - int freq; /* in mHz */ -#ifdef WIN32 - DEVMODE mode; -#endif -}; - -#if !GTK_CHECK_VERSION (2, 91, 0) -#define gdk_x11_window_get_xid gdk_x11_drawable_get_xid -#define gdk_error_trap_pop_ignored gdk_error_trap_pop -#endif - -G_GNUC_INTERNAL -GdkScreen * gnome_rr_screen_get_gdk_screen (GnomeRRScreen *self); -G_GNUC_INTERNAL -GnomeRROutput * gnome_rr_output_by_id (ScreenInfo *info, RROutput id); -G_GNUC_INTERNAL -GnomeRRCrtc * crtc_by_id (ScreenInfo *info, RRCrtc id); -G_GNUC_INTERNAL -GnomeRRMode * mode_by_id (ScreenInfo *info, RRMode id); - -G_GNUC_INTERNAL -ScreenInfo * screen_info_new (GnomeRRScreen *screen, gboolean needs_reprobe, - GError **error); -G_GNUC_INTERNAL -gboolean screen_update (GnomeRRScreen *screen, gboolean force_callback, - gboolean needs_reprobe, GError **error); -G_GNUC_INTERNAL -gboolean fill_out_screen_info (GnomeRRScreen *screen, ScreenInfo *info, - gboolean needs_reprobe, GError **error); -G_GNUC_INTERNAL -void screen_set_primary_output (GnomeRRScreen *screen, GnomeRROutput *output); -G_GNUC_INTERNAL -GnomeRRCrtc * crtc_new (ScreenInfo *info, RRCrtc id); - -/* GnomeRROutput */ -G_GNUC_INTERNAL -GnomeRROutput * output_new (ScreenInfo *info, RROutput id); -G_GNUC_INTERNAL -GnomeRRMode * mode_new (ScreenInfo *info, RRMode id); -G_GNUC_INTERNAL -void screen_info_free (ScreenInfo *info); -G_GNUC_INTERNAL -void gather_clone_modes (ScreenInfo *info); - - - -#endif diff --git a/gtk/display/gnome-rr-windows.c b/gtk/display/gnome-rr-windows.c deleted file mode 100644 index 86a2055..0000000 --- a/gtk/display/gnome-rr-windows.c +++ /dev/null @@ -1,453 +0,0 @@ -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -/* gnome-rr.c - * - * Copyright 2011, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> - */ - -#define GNOME_DESKTOP_USE_UNSTABLE_API - -#include <config.h> -#include <glib/gi18n-lib.h> -#include <string.h> - -#include <gtk/gtk.h> - -#include <windef.h> -#include <wingdi.h> - -#undef GNOME_DISABLE_DEPRECATED -#include "gnome-rr.h" -#include "gnome-rr-config.h" -#include "gnome-rr-private.h" -#include "gnome-rr-windows.h" - -struct GnomeRRWindowsScreenPrivate -{ - RRMode rrmode_id; - DISPLAY_DEVICE device; -}; - -static void gnome_rr_windows_screen_initable_iface_init (GInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (GnomeRRWindowsScreen, gnome_rr_windows_screen, GNOME_TYPE_RR_SCREEN, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gnome_rr_windows_screen_initable_iface_init)) - -static gboolean -gnome_rr_windows_screen_initable_init (GInitable *initable, GCancellable *canc, GError **error) -{ - GInitableIface *iface, *parent_iface; - - iface = G_TYPE_INSTANCE_GET_INTERFACE(initable, G_TYPE_INITABLE, GInitableIface); - parent_iface = g_type_interface_peek_parent(iface); - - if (!parent_iface->init (initable, canc, error)) - return FALSE; - - return TRUE; -} - -static void -gnome_rr_windows_screen_initable_iface_init (GInitableIface *iface) -{ - iface->init = gnome_rr_windows_screen_initable_init; -} - -static void -gnome_rr_windows_screen_finalize (GObject *gobject) -{ - G_OBJECT_CLASS (gnome_rr_windows_screen_parent_class)->finalize (gobject); -} - -static void -gnome_rr_windows_screen_class_init (GnomeRRWindowsScreenClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GnomeRRWindowsScreenPrivate)); - - gobject_class->finalize = gnome_rr_windows_screen_finalize; -} - -static void -gnome_rr_windows_screen_init (GnomeRRWindowsScreen *self) -{ - GnomeRRWindowsScreenPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - GNOME_TYPE_RR_WINDOWS_SCREEN, GnomeRRWindowsScreenPrivate); - - self->priv = priv; -} - -static int -display_frequency_to_freq (DWORD f) -{ - return ((f <= 1 ? 60 : f) * 1000); -} - -GnomeRRMode * -lookup_mode (GPtrArray *a, DEVMODE *mode, int flags) -{ - guint len = a->len; - GnomeRRMode **modes = (GnomeRRMode **)a->pdata; - - for (len = a->len; len > 0; len--) { - GnomeRRMode *m = modes[len - 1]; - - if (m->width != mode->dmPelsWidth) - continue; - if (m->height != mode->dmPelsHeight) - continue; - if (m->freq != display_frequency_to_freq (mode->dmDisplayFrequency)) - continue; - return m; - } - - return NULL; -} - -#if(WINVER >= 0x0501) -typedef struct -{ - DWORD o; - GnomeRRRotation rot; -} RotationMap; - -static const RotationMap rotation_map[] = -{ - { DMDO_DEFAULT, GNOME_RR_ROTATION_0 }, - { DMDO_90, GNOME_RR_ROTATION_90 }, - { DMDO_180, GNOME_RR_ROTATION_180 }, - { DMDO_270, GNOME_RR_ROTATION_270 }, -}; - -static GnomeRRRotation -gnome_rr_rotation_from_orientation (DWORD o) -{ - int i; - GnomeRRRotation result = 0; - - for (i = 0; i < G_N_ELEMENTS (rotation_map); ++i) - { - if (o == rotation_map[i].o) - result |= rotation_map[i].rot; - } - - return result; -} - -static DWORD -orientation_from_rotation (GnomeRRRotation r) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (rotation_map); ++i) - { - if (r & rotation_map[i].rot) - return rotation_map[i].o; - } - - g_return_val_if_reached (DMDO_DEFAULT); -} -#endif - - -GnomeRRMode* -screen_mode_new (GnomeRRScreen *screen, ScreenInfo *info, DEVMODE *m) -{ - GnomeRRWindowsScreen *self = GNOME_RR_WINDOWS_SCREEN (screen); - GnomeRRWindowsScreenPrivate *priv = self->priv; - GnomeRRMode *mode; - - g_return_val_if_fail (m != NULL, NULL); - - mode = mode_new (info, priv->rrmode_id++); - mode->mode = *m; - mode->width = m->dmPelsWidth; - mode->height = m->dmPelsHeight; - mode->freq = display_frequency_to_freq (m->dmDisplayFrequency); - - return mode; -} - -gboolean -fill_out_screen_info (GnomeRRScreen *screen, ScreenInfo *info, - gboolean needs_reprobe, GError **error) -{ - DWORD device_id; - DISPLAY_DEVICE device; - GPtrArray *crtcs, *outputs, *modes, *omodes;; - - device.cb = sizeof(device); - - crtcs = g_ptr_array_new (); - outputs = g_ptr_array_new (); - modes = g_ptr_array_new (); - - for (device_id = 0; ; device_id++) { - GnomeRRCrtc *crtc; - GnomeRRMode *rrmode; - GnomeRROutput *output; - DEVMODE mode = { {0, }, }; - DWORD iModeNum; - - mode.dmSize = sizeof (DEVMODE); - - if (!EnumDisplayDevices (NULL, device_id, &device, 0)) - break; - -#if DEBUG - g_debug ("%s - %s, primary: %s", device.DeviceName, device.DeviceString, - device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE ? "yes" : "no"); -#endif - if (device.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) /* FIXME: == clone output? */ - continue; - - crtc = crtc_new (info, device_id); - crtc->rotations = GNOME_RR_ROTATION_0; - g_ptr_array_add (crtcs, crtc); - - output = output_new (info, device_id); - g_ptr_array_add (outputs, output); - omodes = g_ptr_array_new (); - - output->name = g_strdup (device.DeviceName); - output->current_crtc = crtc; - output->possible_crtcs = g_new0 (GnomeRRCrtc*, 2); - output->possible_crtcs[0] = crtc; - output->clones = g_new0 (GnomeRROutput*, 1); /* FIXME */ - /* FIXME: could be a seperate active display? */ - output->connected = - device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP; - - /* Populate modes for this display/crtc */ - for (iModeNum = 0; ; iModeNum++) { -#if (_WIN32_WINNT >= 0x0500 || _WIN32_WINDOWS >= 0x0410) && defined(EDS_ROTATEDMODE) - if (!EnumDisplaySettingsEx (device.DeviceName, iModeNum, &mode, EDS_ROTATEDMODE)) -#else - if (!EnumDisplaySettings (device.DeviceName, iModeNum, &mode)) -#endif - break; - -#if DEBUG - g_debug ("pos: %ldx%ld, size: %ldx%ld, rot: %ld depth: %ld freq: %ld", - mode.dmPosition.x, mode.dmPosition.y, - mode.dmPelsWidth, mode.dmPelsHeight, - mode.dmDisplayOrientation, mode.dmBitsPerPel, - mode.dmDisplayFrequency); -#endif - - rrmode = screen_mode_new (screen, info, &mode); - g_ptr_array_add (modes, rrmode); - g_ptr_array_add (omodes, rrmode); -#if (_WIN32_WINNT >= 0x0500 || _WIN32_WINDOWS >= 0x0410) - /* NOTE: windows does rotation at mode level... */ - crtc->rotations |= gnome_rr_rotation_from_orientation (mode.dmDisplayOrientation); -#endif - } - - { - /* Current mode settings for this display/crtc */ -#if (_WIN32_WINNT >= 0x0500 || _WIN32_WINDOWS >= 0x0410) && defined(EDS_ROTATEDMODE) - if (!EnumDisplaySettingsEx (device.DeviceName, ENUM_CURRENT_SETTINGS, &mode, EDS_ROTATEDMODE)) -#else - if (!EnumDisplaySettings (device.DeviceName, ENUM_CURRENT_SETTINGS, &mode)) -#endif - { - g_warn_if_reached (); - continue; - } - - crtc->current_mode = lookup_mode (omodes, &mode, 0); - if (!crtc->current_mode) { - g_warn_if_reached (); - - rrmode = screen_mode_new (screen, info, &mode); - g_ptr_array_add (modes, rrmode); - g_ptr_array_add (omodes, rrmode); - crtc->current_mode = lookup_mode (outputs, &mode, 0); - } - g_return_val_if_fail (crtc->current_mode != NULL, FALSE); - - crtc->x = mode.dmPosition.x; - crtc->y = mode.dmPosition.y; - -#if(WINVER >= 0x0501) - crtc->current_rotation = gnome_rr_rotation_from_orientation (mode.dmDisplayOrientation); -#else - crtc->current_rotation = GNOME_RR_ROTATION_0; -#endif - - crtc->current_outputs = g_new0 (GnomeRROutput*, 2); - crtc->current_outputs[0] = output; - crtc->possible_outputs = g_new0 (GnomeRROutput*, 2); - crtc->possible_outputs[0] = output; - } - - /* FIXME: vista has GetMonitorDisplayAreaSize, not mingw */ - /* see also EDID hack on stackoverflow if necessary */ - output->width_mm = 0; - output->height_mm = 0; - g_ptr_array_add (omodes, NULL); - output->modes = (GnomeRRMode **)g_ptr_array_free (omodes, FALSE); - } - - g_ptr_array_add (modes, NULL); - info->modes = (GnomeRRMode **)g_ptr_array_free (modes, FALSE); - - g_ptr_array_add (crtcs, NULL); - info->crtcs = (GnomeRRCrtc **)g_ptr_array_free (crtcs, FALSE); - - g_ptr_array_add (outputs, NULL); - info->outputs = (GnomeRROutput **)g_ptr_array_free (outputs, FALSE); - - if (needs_reprobe) { - /* FIXME: all wrong.. perhaps size of primary monitor & sum of monitor sizes*/ - info->min_width = 0; - info->min_height = 0; - info->max_width = MAX(GetSystemMetrics (SM_CXVIRTUALSCREEN), 8192); - info->max_height = MAX(GetSystemMetrics (SM_CYVIRTUALSCREEN), 8192); - } else { - gnome_rr_screen_get_ranges (info->screen, - &(info->min_width), - &(info->max_width), - &(info->min_height), - &(info->max_height)); - } - - gather_clone_modes (info); /* FIXME: or do it diffently? */ - - return TRUE; -} - -static const gchar* -get_display_change_error (LONG ret) -{ - switch (ret) { - case DISP_CHANGE_SUCCESSFUL: - return "The settings change was successful."; - case DISP_CHANGE_BADDUALVIEW: - return "The settings change was unsuccessful because the system is DualView capable."; - case DISP_CHANGE_BADFLAGS: - return "An invalid set of flags was passed in."; - case DISP_CHANGE_BADMODE: - return "The graphics mode is not supported."; - case DISP_CHANGE_BADPARAM: - return "An invalid parameter was passed in. This can include an invalid flag or combination of flags."; - case DISP_CHANGE_FAILED: - return "The display driver failed the specified graphics mode."; - case DISP_CHANGE_NOTUPDATED: - return "Unable to write settings to the registry."; - case DISP_CHANGE_RESTART: - return "The computer must be restarted for the graphics mode to work."; - } - - g_return_val_if_reached ("unknown display change error"); -} - -gboolean -gnome_rr_crtc_set_config_with_time (GnomeRRCrtc *crtc, - guint32 timestamp, - int x, - int y, - GnomeRRMode *mode, - GnomeRRRotation rotation, - GnomeRROutput **outputs, - int n_outputs, - GError **error) -{ - int n; - DEVMODE m; - LONG ret; - - g_return_val_if_fail (n_outputs <= 1, FALSE); /* FIXME */ - g_return_val_if_fail (crtc != NULL, FALSE); - g_return_val_if_fail (mode != NULL || outputs == NULL || n_outputs == 0, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - if (mode == NULL) /* FIXME: turn off crtc? */ - return TRUE; - - m = mode->mode; - - m.dmFields |= DM_POSITION; - m.dmPosition.x = x; - m.dmPosition.y = y; -#if(WINVER >= 0x0501) - m.dmFields |= DM_DISPLAYORIENTATION; - m.dmDisplayOrientation = orientation_from_rotation (rotation); -#endif - /* TODO: deal with removed outputs and refresh stucts */ - - for (n = 0; n < n_outputs; ++n) { - GnomeRROutput *o = outputs[n]; - - ret = ChangeDisplaySettingsEx(o->name, &m, NULL, CDS_FULLSCREEN, NULL); - if (ret != DISP_CHANGE_SUCCESSFUL) { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_UNKNOWN, - /* Translators: a CRTC is a CRT Controller (this is X terminology). */ - _("could not set the output configuration %s"), - get_display_change_error (ret)); - return FALSE; - } - } - - return TRUE; -} - -void -gnome_rr_screen_set_size (GnomeRRScreen *self, - int width, - int height, - int mm_width, - int mm_height) -{ - g_return_if_fail (GNOME_IS_RR_WINDOWS_SCREEN (self)); - - /* there is nothing we can do here, windows seems to compute - virtual screen size itself */ -} - -void -gnome_rr_crtc_set_gamma (GnomeRRCrtc *crtc, int size, - unsigned short *red, - unsigned short *green, - unsigned short *blue) -{ - g_return_if_fail (crtc != NULL); - g_return_if_fail (red != NULL); - g_return_if_fail (green != NULL); - g_return_if_fail (blue != NULL); - - g_warning ("Unimplemented on Windows"); -} - -gboolean -gnome_rr_crtc_get_gamma (GnomeRRCrtc *crtc, int *size, - unsigned short **red, unsigned short **green, - unsigned short **blue) -{ - g_return_val_if_fail (crtc != NULL, FALSE); - - g_warning ("Unimplemented on Windows"); - return FALSE; -} - -void -screen_set_primary_output (GnomeRRScreen *screen, GnomeRROutput *output) -{ -} diff --git a/gtk/display/gnome-rr-windows.h b/gtk/display/gnome-rr-windows.h deleted file mode 100644 index 337bd50..0000000 --- a/gtk/display/gnome-rr-windows.h +++ /dev/null @@ -1,53 +0,0 @@ -/* gnome-rr-windows.h - * - * Copyright 2011, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Authors: Soren Sandmann <sandmann@xxxxxxxxxx> - * Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> - */ - -#ifndef GNOME_RR_WINDOWS_H -#define GNOME_RR_WINDOWS_H - -#include <glib.h> -#include "gnome-rr.h" - -#define GNOME_TYPE_RR_WINDOWS_SCREEN (gnome_rr_windows_screen_get_type()) -#define GNOME_RR_WINDOWS_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_WINDOWS_SCREEN, GnomeRRWindowsScreen)) -#define GNOME_IS_RR_WINDOWS_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_WINDOWS_SCREEN)) -#define GNOME_RR_WINDOWS_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RR_WINDOWS_SCREEN, GnomeRRWindowsScreenClass)) -#define GNOME_IS_RR_WINDOWS_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RR_WINDOWS_SCREEN)) -#define GNOME_RR_WINDOWS_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_RR_WINDOWS_SCREEN, GnomeRRWindowsScreenClass)) - -typedef struct GnomeRRWindowsScreenPrivate GnomeRRWindowsScreenPrivate; - -typedef struct { - GnomeRRScreen parent; - - GnomeRRWindowsScreenPrivate* priv; -} GnomeRRWindowsScreen; - -typedef struct { - GnomeRRScreenClass parent_class; - - void (* changed) (void); -} GnomeRRWindowsScreenClass; - -GType gnome_rr_windows_screen_get_type (void); - -#endif /* GNOME_RR_WINDOWS_H */ diff --git a/gtk/display/gnome-rr-x11.c b/gtk/display/gnome-rr-x11.c deleted file mode 100644 index e37a668..0000000 --- a/gtk/display/gnome-rr-x11.c +++ /dev/null @@ -1,1013 +0,0 @@ -/* gnome-rr-x11.c - * - * Copyright 2007, 2008, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Soren Sandmann <sandmann@xxxxxxxxxx> - */ - -#define GNOME_DESKTOP_USE_UNSTABLE_API - -#include <config.h> -#include <glib/gi18n-lib.h> -#include <string.h> - -#ifdef HAVE_RANDR -#include <X11/extensions/Xrandr.h> -#endif - -#include <gtk/gtk.h> - -#ifdef HAVE_X11 -#include <X11/Xlib.h> -#include <gdk/gdkx.h> -#include <X11/Xatom.h> -#endif - -#undef GNOME_DISABLE_DEPRECATED -#include "gnome-rr.h" -#include "gnome-rr-x11.h" -#include "gnome-rr-config.h" - -#include "gnome-rr-private.h" - -struct GnomeRRX11ScreenPrivate -{ - Display * xdisplay; - Screen * xscreen; - Window xroot; - - int randr_event_base; - int rr_major_version; - int rr_minor_version; - Atom connector_type_atom; -}; - -#define DISPLAY(o) (GNOME_RR_X11_SCREEN((o)->info->screen)->priv->xdisplay) - -#ifdef HAVE_RANDR -#define RANDR_LIBRARY_IS_AT_LEAST_1_3 (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) -#else -#define RANDR_LIBRARY_IS_AT_LEAST_1_3 0 -#endif - -#define SERVERS_RANDR_IS_AT_LEAST_1_3(priv) (priv->rr_major_version > 1 || (priv->rr_major_version == 1 && priv->rr_minor_version >= 3)) - -static gboolean output_initialize (GnomeRROutput *output, XRRScreenResources *res, GError **error); -static void gnome_rr_x11_screen_initable_iface_init (GInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (GnomeRRX11Screen, gnome_rr_x11_screen, GNOME_TYPE_RR_SCREEN, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gnome_rr_x11_screen_initable_iface_init)) - -static GdkFilterReturn -screen_on_event (GdkXEvent *xevent, - GdkEvent *event, - gpointer data) -{ -#ifdef HAVE_RANDR - GnomeRRX11Screen *screen = data; - GnomeRRX11ScreenPrivate *priv = screen->priv; - XEvent *e = xevent; - int event_num; - - if (!e) - return GDK_FILTER_CONTINUE; - - event_num = e->type - priv->randr_event_base; - - if (event_num == RRScreenChangeNotify) { - /* We don't reprobe the hardware; we just fetch the X server's latest - * state. The server already knows the new state of the outputs; that's - * why it sent us an event! - */ - screen_update (GNOME_RR_SCREEN (screen), TRUE, FALSE, NULL); /* NULL-GError */ -#if 0 - /* Enable this code to get a dialog showing the RANDR timestamps, for debugging purposes */ - { - GtkWidget *dialog; - XRRScreenChangeNotifyEvent *rr_event; - static int dialog_num; - - rr_event = (XRRScreenChangeNotifyEvent *) e; - - dialog = gtk_message_dialog_new (NULL, - 0, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, - "RRScreenChangeNotify timestamps (%d):\n" - "event change: %u\n" - "event config: %u\n" - "event serial: %lu\n" - "----------------------" - "screen change: %u\n" - "screen config: %u\n", - dialog_num++, - (guint32) rr_event->timestamp, - (guint32) rr_event->config_timestamp, - rr_event->serial, - (guint32) priv->info->resources->timestamp, - (guint32) priv->info->resources->configTimestamp); - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - gtk_widget_show (dialog); - } -#endif - } -#if 0 - /* WHY THIS CODE IS DISABLED: - * - * Note that in gnome_rr_screen_new(), we only select for - * RRScreenChangeNotifyMask. We used to select for other values in - * RR*NotifyMask, but we weren't really doing anything useful with those - * events. We only care about "the screens changed in some way or another" - * for now. - * - * If we ever run into a situtation that could benefit from processing more - * detailed events, we can enable this code again. - * - * Note that the X server sends RRScreenChangeNotify in conjunction with the - * more detailed events from RANDR 1.2 - see xserver/randr/randr.c:TellChanged(). - */ - else if (event_num == RRNotify) - { - /* Other RandR events */ - - XRRNotifyEvent *event = (XRRNotifyEvent *)e; - - /* Here we can distinguish between RRNotify events supported - * since RandR 1.2 such as RRNotify_OutputProperty. For now, we - * don't have anything special to do for particular subevent types, so - * we leave this as an empty switch(). - */ - switch (event->subtype) - { - default: - break; - } - - /* No need to reprobe hardware here */ - screen_update (GNOME_RR_SCREEN (screen), TRUE, FALSE, NULL); /* NULL-GError */ - } -#endif - -#endif /* HAVE_RANDR */ - - /* Pass the event on to GTK+ */ - return GDK_FILTER_CONTINUE; -} - -static gboolean -gnome_rr_x11_screen_initable_init (GInitable *initable, GCancellable *canc, GError **error) -{ - GInitableIface *iface, *parent_iface; - - iface = G_TYPE_INSTANCE_GET_INTERFACE(initable, G_TYPE_INITABLE, GInitableIface); - parent_iface = g_type_interface_peek_parent(iface); - -#ifdef HAVE_RANDR - GnomeRRX11Screen *self = GNOME_RR_X11_SCREEN (initable); - GnomeRRX11ScreenPrivate *priv = self->priv; - Display *dpy = GDK_SCREEN_XDISPLAY (gnome_rr_screen_get_gdk_screen (GNOME_RR_SCREEN (self))); - int event_base; - int ignore; - GdkWindow *root; - - root = gdk_screen_get_root_window (gnome_rr_screen_get_gdk_screen (GNOME_RR_SCREEN (self))); - priv->connector_type_atom = XInternAtom (dpy, "ConnectorType", FALSE); - - if (XRRQueryExtension (dpy, &event_base, &ignore)) - { - priv->randr_event_base = event_base; - - XRRQueryVersion (dpy, &priv->rr_major_version, &priv->rr_minor_version); - if (priv->rr_major_version < 1 || (priv->rr_major_version == 1 && priv->rr_minor_version < 2)) { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_RANDR_EXTENSION, - "RANDR extension is too old (must be at least 1.2)"); - return FALSE; - } - - if (!parent_iface->init (initable, canc, error)) - return FALSE; - - XRRSelectInput (priv->xdisplay, - priv->xroot, - RRScreenChangeNotifyMask); - gdk_x11_register_standard_event_type ( - gdk_screen_get_display (gnome_rr_screen_get_gdk_screen (GNOME_RR_SCREEN (self))), - event_base, - RRNotify + 1); - gdk_window_add_filter (root, screen_on_event, self); - - return TRUE; - } - else - { -#endif /* HAVE_RANDR */ - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_RANDR_EXTENSION, - _("RANDR extension is not present")); - - return FALSE; -#ifdef HAVE_RANDR - } -#endif -} - -static void -gnome_rr_x11_screen_initable_iface_init (GInitableIface *iface) -{ - iface->init = gnome_rr_x11_screen_initable_init; -} - -static void -gnome_rr_x11_screen_finalize (GObject *gobject) -{ - GnomeRRX11Screen *screen = GNOME_RR_X11_SCREEN (gobject); - GdkWindow *root; - - root = gdk_screen_get_root_window (gnome_rr_screen_get_gdk_screen (GNOME_RR_SCREEN (screen))); - gdk_window_remove_filter (root, screen_on_event, screen); - - G_OBJECT_CLASS (gnome_rr_x11_screen_parent_class)->finalize (gobject); -} - -static void -gnome_rr_x11_screen_class_init (GnomeRRX11ScreenClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GnomeRRX11ScreenPrivate)); - - gobject_class->finalize = gnome_rr_x11_screen_finalize; -} - -static void -on_gdk_screen_changed (GnomeRRX11Screen *self, G_GNUC_UNUSED gpointer data) -{ - GnomeRRX11ScreenPrivate *priv = self->priv; - GdkScreen *gdk_screen; - GdkWindow *root; - - gdk_screen = gnome_rr_screen_get_gdk_screen (GNOME_RR_SCREEN (self)); - root = gdk_screen_get_root_window (gdk_screen); - - priv->xroot = gdk_x11_window_get_xid (root); - priv->xdisplay = GDK_SCREEN_XDISPLAY (gdk_screen); - priv->xscreen = gdk_x11_screen_get_xscreen (gdk_screen); -} - -static void -gnome_rr_x11_screen_init (GnomeRRX11Screen *self) -{ - GnomeRRX11ScreenPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_RR_X11_SCREEN, GnomeRRX11ScreenPrivate); - - self->priv = priv; - priv->xdisplay = NULL; - priv->xroot = None; - priv->xscreen = NULL; - priv->rr_major_version = 0; - priv->rr_minor_version = 0; - - /* no need to unregister this handler: it's self - instead of notify signal, we could override the prop */ - g_signal_connect (self, "notify::gdk-screen", G_CALLBACK (on_gdk_screen_changed), NULL); -} - -void -gnome_rr_screen_set_size (GnomeRRScreen *self, - int width, - int height, - int mm_width, - int mm_height) -{ - g_return_if_fail (GNOME_IS_RR_X11_SCREEN (self)); - -#ifdef HAVE_RANDR - GnomeRRX11ScreenPrivate *priv = GNOME_RR_X11_SCREEN (self)->priv; - - gdk_error_trap_push (); - XRRSetScreenSize (priv->xdisplay, priv->xroot, - width, height, mm_width, mm_height); - gdk_error_trap_pop_ignored (); -#endif -} - -#ifdef HAVE_RANDR -/* GnomeRRCrtc */ -typedef struct -{ - Rotation xrot; - GnomeRRRotation rot; -} RotationMap; - -static const RotationMap rotation_map[] = -{ - { RR_Rotate_0, GNOME_RR_ROTATION_0 }, - { RR_Rotate_90, GNOME_RR_ROTATION_90 }, - { RR_Rotate_180, GNOME_RR_ROTATION_180 }, - { RR_Rotate_270, GNOME_RR_ROTATION_270 }, - { RR_Reflect_X, GNOME_RR_REFLECT_X }, - { RR_Reflect_Y, GNOME_RR_REFLECT_Y }, -}; - -static GnomeRRRotation -gnome_rr_rotation_from_xrotation (Rotation r) -{ - int i; - GnomeRRRotation result = 0; - - for (i = 0; i < G_N_ELEMENTS (rotation_map); ++i) - { - if (r & rotation_map[i].xrot) - result |= rotation_map[i].rot; - } - - return result; -} - -static Rotation -xrotation_from_rotation (GnomeRRRotation r) -{ - int i; - Rotation result = 0; - - for (i = 0; i < G_N_ELEMENTS (rotation_map); ++i) - { - if (r & rotation_map[i].rot) - result |= rotation_map[i].xrot; - } - - return result; -} - -static gboolean -crtc_initialize (GnomeRRCrtc *crtc, - XRRScreenResources *res, - GError **error) -{ - XRRCrtcInfo *info = XRRGetCrtcInfo (DISPLAY (crtc), res, crtc->id); - GPtrArray *a; - int i; - -#if 0 - g_print ("CRTC %lx Timestamp: %u\n", crtc->id, (guint32)info->timestamp); -#endif - - if (!info) - { - /* FIXME: We need to reaquire the screen resources */ - /* FIXME: can we actually catch BadRRCrtc, and does it make sense to emit that? */ - - /* Translators: CRTC is a CRT Controller (this is X terminology). - * It is *very* unlikely that you'll ever get this error, so it is - * only listed for completeness. */ - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR, - _("could not get information about CRTC %d"), - (int) crtc->id); - return FALSE; - } - - /* GnomeRRMode */ - crtc->current_mode = mode_by_id (crtc->info, info->mode); - - crtc->x = info->x; - crtc->y = info->y; - - /* Current outputs */ - a = g_ptr_array_new (); - for (i = 0; i < info->noutput; ++i) - { - GnomeRROutput *output = gnome_rr_output_by_id (crtc->info, info->outputs[i]); - - if (output) - g_ptr_array_add (a, output); - } - g_ptr_array_add (a, NULL); - crtc->current_outputs = (GnomeRROutput **)g_ptr_array_free (a, FALSE); - - /* Possible outputs */ - a = g_ptr_array_new (); - for (i = 0; i < info->npossible; ++i) - { - GnomeRROutput *output = gnome_rr_output_by_id (crtc->info, info->possible[i]); - - if (output) - g_ptr_array_add (a, output); - } - g_ptr_array_add (a, NULL); - crtc->possible_outputs = (GnomeRROutput **)g_ptr_array_free (a, FALSE); - - /* Rotations */ - crtc->current_rotation = gnome_rr_rotation_from_xrotation (info->rotation); - crtc->rotations = gnome_rr_rotation_from_xrotation (info->rotations); - - XRRFreeCrtcInfo (info); - - /* get an store gamma size */ - crtc->gamma_size = XRRGetCrtcGammaSize (DISPLAY (crtc), crtc->id); - - return TRUE; -} - -static void -mode_initialize (GnomeRRMode *mode, XRRModeInfo *info) -{ - g_return_if_fail (mode != NULL); - g_return_if_fail (info != NULL); - - mode->name = g_strdup (info->name); - mode->width = info->width; - mode->height = info->height; - mode->freq = ((info->dotClock / (double)info->hTotal) / info->vTotal + 0.5) * 1000; -} - -static gboolean -fill_screen_info_from_resources (ScreenInfo *info, - XRRScreenResources *resources, - GError **error) -{ - int i; - GPtrArray *a; - GnomeRRCrtc **crtc; - GnomeRROutput **output; - - info->resources = resources; - - /* We create all the structures before initializing them, so - * that they can refer to each other. - */ - a = g_ptr_array_new (); - for (i = 0; i < resources->ncrtc; ++i) - { - GnomeRRCrtc *crtc = crtc_new (info, resources->crtcs[i]); - - g_ptr_array_add (a, crtc); - } - g_ptr_array_add (a, NULL); - info->crtcs = (GnomeRRCrtc **)g_ptr_array_free (a, FALSE); - - a = g_ptr_array_new (); - for (i = 0; i < resources->noutput; ++i) - { - GnomeRROutput *output = output_new (info, resources->outputs[i]); - - g_ptr_array_add (a, output); - } - g_ptr_array_add (a, NULL); - info->outputs = (GnomeRROutput **)g_ptr_array_free (a, FALSE); - - a = g_ptr_array_new (); - for (i = 0; i < resources->nmode; ++i) - { - GnomeRRMode *mode = mode_new (info, resources->modes[i].id); - - g_ptr_array_add (a, mode); - } - g_ptr_array_add (a, NULL); - info->modes = (GnomeRRMode **)g_ptr_array_free (a, FALSE); - - /* Initialize */ - for (crtc = info->crtcs; *crtc; ++crtc) - { - if (!crtc_initialize (*crtc, resources, error)) - return FALSE; - } - - for (output = info->outputs; *output; ++output) - { - if (!output_initialize (*output, resources, error)) - return FALSE; - } - - for (i = 0; i < resources->nmode; ++i) - { - GnomeRRMode *mode = mode_by_id (info, resources->modes[i].id); - - mode_initialize (mode, &(resources->modes[i])); - } - - gather_clone_modes (info); - - return TRUE; -} -#endif /* HAVE_RANDR */ - -gboolean -fill_out_screen_info (GnomeRRScreen *screen, - ScreenInfo *info, - gboolean needs_reprobe, - GError **error) -{ - GnomeRRX11ScreenPrivate *priv = GNOME_RR_X11_SCREEN (screen)->priv; - Display *xdisplay = priv->xdisplay; - Window xroot = priv->xroot; -#ifdef HAVE_RANDR - XRRScreenResources *resources; - - g_return_val_if_fail (xdisplay != NULL, FALSE); - g_return_val_if_fail (info != NULL, FALSE); - - /* First update the screen resources */ - - if (needs_reprobe) - resources = XRRGetScreenResources (xdisplay, xroot); - else - { - /* XRRGetScreenResourcesCurrent is less expensive than - * XRRGetScreenResources, however it is available only - * in RandR 1.3 or higher - */ -#if RANDR_LIBRARY_IS_AT_LEAST_1_3 - if (SERVERS_RANDR_IS_AT_LEAST_1_3 (priv)) - resources = XRRGetScreenResourcesCurrent (xdisplay, xroot); - else - resources = XRRGetScreenResources (xdisplay, xroot); -#else - resources = XRRGetScreenResources (xdisplay, xroot); -#endif - } - - if (resources) - { - if (!fill_screen_info_from_resources (info, resources, error)) - return FALSE; - } - else - { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR, - /* Translators: a CRTC is a CRT Controller (this is X terminology). */ - _("could not get the screen resources (CRTCs, outputs, modes)")); - return FALSE; - } - - /* Then update the screen size range. We do this after XRRGetScreenResources() so that - * the X server will already have an updated view of the outputs. - */ - - if (needs_reprobe) { - gboolean success; - - gdk_error_trap_push (); - success = XRRGetScreenSizeRange (xdisplay, xroot, - &(info->min_width), - &(info->min_height), - &(info->max_width), - &(info->max_height)); - gdk_flush (); - if (gdk_error_trap_pop ()) { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_UNKNOWN, - _("unhandled X error while getting the range of screen sizes")); - return FALSE; - } - - if (!success) { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR, - _("could not get the range of screen sizes")); - return FALSE; - } - } - else - { - gnome_rr_screen_get_ranges (info->screen, - &(info->min_width), - &(info->max_width), - &(info->min_height), - &(info->max_height)); - } - - info->primary = None; -#if RANDR_LIBRARY_IS_AT_LEAST_1_3 - if (SERVERS_RANDR_IS_AT_LEAST_1_3 (priv)) { - gdk_error_trap_push (); - info->primary = XRRGetOutputPrimary (xdisplay, xroot); - gdk_error_trap_pop_ignored (); - } -#endif - - return TRUE; -#else - return FALSE; -#endif /* HAVE_RANDR */ -} - -static guint8 * -get_property (Display *dpy, - RROutput output, - Atom atom, - int *len) -{ -#ifdef HAVE_RANDR - unsigned char *prop; - int actual_format; - unsigned long nitems, bytes_after; - Atom actual_type; - guint8 *result; - - XRRGetOutputProperty (dpy, output, atom, - 0, 100, False, False, - AnyPropertyType, - &actual_type, &actual_format, - &nitems, &bytes_after, &prop); - - if (actual_type == XA_INTEGER && actual_format == 8) - { - result = g_memdup (prop, nitems); - if (len) - *len = nitems; - } - else - { - result = NULL; - } - - XFree (prop); - - return result; -#else - return NULL; -#endif /* HAVE_RANDR */ -} - -static guint8 * -read_edid_data (GnomeRROutput *output, int *len) -{ - Atom edid_atom; - guint8 *result; - - edid_atom = XInternAtom (DISPLAY (output), "EDID", FALSE); - result = get_property (DISPLAY (output), - output->id, edid_atom, len); - - if (!result) - { - edid_atom = XInternAtom (DISPLAY (output), "EDID_DATA", FALSE); - result = get_property (DISPLAY (output), - output->id, edid_atom, len); - } - - if (result) - { - if (*len % 128 == 0) - return result; - else - g_free (result); - } - - return NULL; -} - -static char * -x11_get_connector_type_string (GnomeRROutput *output) -{ -#ifdef HAVE_RANDR - char *result; - unsigned char *prop; - int actual_format; - unsigned long nitems, bytes_after; - Atom actual_type; - Atom connector_type; - char *connector_type_str; - GnomeRRX11ScreenPrivate *priv = GNOME_RR_X11_SCREEN (output->info->screen)->priv; - - result = NULL; - - if (XRRGetOutputProperty (DISPLAY (output), output->id, priv->connector_type_atom, - 0, 100, False, False, - AnyPropertyType, - &actual_type, &actual_format, - &nitems, &bytes_after, &prop) != Success) - return NULL; - - if (!(actual_type == XA_ATOM && actual_format == 32 && nitems == 1)) - goto out; - - connector_type = *((Atom *) prop); - - connector_type_str = XGetAtomName (DISPLAY (output), connector_type); - if (connector_type_str) { - result = g_strdup (connector_type_str); /* so the caller can g_free() it */ - XFree (connector_type_str); - } - -out: - - XFree (prop); - - return result; -#else - return NULL; -#endif -} - -static gboolean -output_initialize (GnomeRROutput *output, XRRScreenResources *res, GError **error) -{ - XRROutputInfo *info = XRRGetOutputInfo ( - DISPLAY (output), res, output->id); - GPtrArray *a; - int i; - -#if 0 - g_print ("Output %lx Timestamp: %u\n", output->id, (guint32)info->timestamp); -#endif - - if (!info || !output->info) - { - /* FIXME: see the comment in crtc_initialize() */ - /* Translators: here, an "output" is a video output */ - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR, - _("could not get information about output %d"), - (int) output->id); - return FALSE; - } - - output->name = g_strdup (info->name); /* FIXME: what is nameLen used for? */ - output->current_crtc = crtc_by_id (output->info, info->crtc); - output->width_mm = info->mm_width; - output->height_mm = info->mm_height; - output->connected = (info->connection == RR_Connected); - output->connector_type = x11_get_connector_type_string (output); - - /* Possible crtcs */ - a = g_ptr_array_new (); - - for (i = 0; i < info->ncrtc; ++i) - { - GnomeRRCrtc *crtc = crtc_by_id (output->info, info->crtcs[i]); - - if (crtc) - g_ptr_array_add (a, crtc); - } - g_ptr_array_add (a, NULL); - output->possible_crtcs = (GnomeRRCrtc **)g_ptr_array_free (a, FALSE); - - /* Clones */ - a = g_ptr_array_new (); - for (i = 0; i < info->nclone; ++i) - { - GnomeRROutput *gnome_rr_output = gnome_rr_output_by_id (output->info, info->clones[i]); - - if (gnome_rr_output) - g_ptr_array_add (a, gnome_rr_output); - } - g_ptr_array_add (a, NULL); - output->clones = (GnomeRROutput **)g_ptr_array_free (a, FALSE); - - /* Modes */ - a = g_ptr_array_new (); - for (i = 0; i < info->nmode; ++i) - { - GnomeRRMode *mode = mode_by_id (output->info, info->modes[i]); - - if (mode) - g_ptr_array_add (a, mode); - } - g_ptr_array_add (a, NULL); - output->modes = (GnomeRRMode **)g_ptr_array_free (a, FALSE); - - output->n_preferred = info->npreferred; - - /* Edid data */ - output->edid_data = read_edid_data (output, &output->edid_size); - - XRRFreeOutputInfo (info); - - return TRUE; -} - -gboolean -gnome_rr_crtc_set_config_with_time (GnomeRRCrtc *crtc, - guint32 timestamp, - int x, - int y, - GnomeRRMode *mode, - GnomeRRRotation rotation, - GnomeRROutput **outputs, - int n_outputs, - GError **error) -{ -#ifdef HAVE_RANDR - ScreenInfo *info; - GArray *output_ids; - Status status; - gboolean result; - int i; - - g_return_val_if_fail (crtc != NULL, FALSE); - g_return_val_if_fail (mode != NULL || outputs == NULL || n_outputs == 0, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - info = crtc->info; - - if (mode) - { - if (x + mode->width > info->max_width - || y + mode->height > info->max_height) - { - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_BOUNDS_ERROR, - /* Translators: the "position", "size", and "maximum" - * words here are not keywords; please translate them - * as usual. A CRTC is a CRT Controller (this is X terminology) */ - _("requested position/size for CRTC %d is outside the allowed limit: " - "position=(%d, %d), size=(%d, %d), maximum=(%d, %d)"), - (int) crtc->id, - x, y, - mode->width, mode->height, - info->max_width, info->max_height); - return FALSE; - } - } - - output_ids = g_array_new (FALSE, FALSE, sizeof (RROutput)); - - if (outputs) - { - for (i = 0; i < n_outputs; ++i) - g_array_append_val (output_ids, outputs[i]->id); - } - - status = XRRSetCrtcConfig (DISPLAY (crtc), info->resources, crtc->id, - timestamp, - x, y, - mode ? mode->id : None, - xrotation_from_rotation (rotation), - (RROutput *)output_ids->data, - output_ids->len); - - g_array_free (output_ids, TRUE); - - if (status == RRSetConfigSuccess) - result = TRUE; - else { - result = FALSE; - /* Translators: CRTC is a CRT Controller (this is X terminology). - * It is *very* unlikely that you'll ever get this error, so it is - * only listed for completeness. */ - g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR, - _("could not set the configuration for CRTC %d"), - (int) crtc->id); - } - - return result; -#else - return FALSE; -#endif /* HAVE_RANDR */ -} - -void -gnome_rr_crtc_set_gamma (GnomeRRCrtc *crtc, int size, - unsigned short *red, - unsigned short *green, - unsigned short *blue) -{ - g_return_if_fail (crtc != NULL); - g_return_if_fail (red != NULL); - g_return_if_fail (green != NULL); - g_return_if_fail (blue != NULL); - -#ifdef HAVE_RANDR - int copy_size; - XRRCrtcGamma *gamma; - - if (size != crtc->gamma_size) - return; - - gamma = XRRAllocGamma (crtc->gamma_size); - - copy_size = crtc->gamma_size * sizeof (unsigned short); - memcpy (gamma->red, red, copy_size); - memcpy (gamma->green, green, copy_size); - memcpy (gamma->blue, blue, copy_size); - - XRRSetCrtcGamma (DISPLAY (crtc), crtc->id, gamma); - XRRFreeGamma (gamma); -#endif /* HAVE_RANDR */ -} - -gboolean -gnome_rr_crtc_get_gamma (GnomeRRCrtc *crtc, int *size, - unsigned short **red, unsigned short **green, - unsigned short **blue) -{ - g_return_val_if_fail (crtc != NULL, FALSE); - -#ifdef HAVE_RANDR - int copy_size; - unsigned short *r, *g, *b; - XRRCrtcGamma *gamma; - - gamma = XRRGetCrtcGamma (DISPLAY (crtc), crtc->id); - if (!gamma) - return FALSE; - - copy_size = crtc->gamma_size * sizeof (unsigned short); - - if (red) { - r = g_new0 (unsigned short, crtc->gamma_size); - memcpy (r, gamma->red, copy_size); - *red = r; - } - - if (green) { - g = g_new0 (unsigned short, crtc->gamma_size); - memcpy (g, gamma->green, copy_size); - *green = g; - } - - if (blue) { - b = g_new0 (unsigned short, crtc->gamma_size); - memcpy (b, gamma->blue, copy_size); - *blue = b; - } - - XRRFreeGamma (gamma); - - if (size) - *size = crtc->gamma_size; - - return TRUE; -#else - return FALSE; -#endif /* HAVE_RANDR */ -} - -gboolean -gnome_rr_x11_screen_force_timestamp_update (GnomeRRX11Screen *self) -{ -#ifdef HAVE_RANDR - GnomeRRX11ScreenPrivate *priv = self->priv; - GnomeRRCrtc *crtc; - XRRCrtcInfo *current_info; - Status status; - gboolean timestamp_updated; - ScreenInfo *info; - - timestamp_updated = FALSE; - - info = GNOME_RR_SCREEN(self)->priv->info; - crtc = info->crtcs[0]; - - if (crtc == NULL) - goto out; - - current_info = XRRGetCrtcInfo (priv->xdisplay, - info->resources, - crtc->id); - - if (current_info == NULL) - goto out; - - gdk_error_trap_push (); - status = XRRSetCrtcConfig (priv->xdisplay, - info->resources, - crtc->id, - current_info->timestamp, - current_info->x, - current_info->y, - current_info->mode, - current_info->rotation, - current_info->outputs, - current_info->noutput); - - XRRFreeCrtcInfo (current_info); - - gdk_flush (); - if (gdk_error_trap_pop ()) - goto out; - - if (status == RRSetConfigSuccess) - timestamp_updated = TRUE; -out: - return timestamp_updated; -#else - return FALSE; -#endif -} - -void -screen_set_primary_output (GnomeRRScreen *screen, GnomeRROutput *output) -{ -#if RANDR_LIBRARY_IS_AT_LEAST_1_3 - GnomeRRX11ScreenPrivate *priv = GNOME_RR_X11_SCREEN (screen)->priv; - RROutput id; - - if (output) - id = output->id; - else - id = None; - - if (SERVERS_RANDR_IS_AT_LEAST_1_3 (priv)) - XRRSetOutputPrimary (priv->xdisplay, priv->xroot, id); -#endif -} diff --git a/gtk/display/gnome-rr-x11.h b/gtk/display/gnome-rr-x11.h deleted file mode 100644 index af53365..0000000 --- a/gtk/display/gnome-rr-x11.h +++ /dev/null @@ -1,56 +0,0 @@ -/* gnome-rr-x11.h - * - * Copyright 2011, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Authors: Soren Sandmann <sandmann@xxxxxxxxxx> - * Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> - */ - -#ifndef GNOME_RR_X11_H -#define GNOME_RR_X11_H - -#include <glib.h> -#include "gnome-rr.h" - -#define GNOME_TYPE_RR_X11_SCREEN (gnome_rr_x11_screen_get_type()) -#define GNOME_RR_X11_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_X11_SCREEN, GnomeRRX11Screen)) -#define GNOME_IS_RR_X11_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_X11_SCREEN)) -#define GNOME_RR_X11_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RR_X11_SCREEN, GnomeRRX11ScreenClass)) -#define GNOME_IS_RR_X11_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RR_X11_SCREEN)) -#define GNOME_RR_X11_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_RR_X11_SCREEN, GnomeRRX11ScreenClass)) - -typedef struct GnomeRRX11ScreenPrivate GnomeRRX11ScreenPrivate; - -typedef struct { - GnomeRRScreen parent; - - GnomeRRX11ScreenPrivate* priv; -} GnomeRRX11Screen; - -typedef struct { - GnomeRRScreenClass parent_class; - - void (* changed) (void); -} GnomeRRX11ScreenClass; - -GType gnome_rr_x11_screen_get_type (void); - -G_GNUC_INTERNAL -gboolean gnome_rr_x11_screen_force_timestamp_update (GnomeRRX11Screen *screen); - -#endif /* GNOME_RR_X11_H */ diff --git a/gtk/display/gnome-rr.c b/gtk/display/gnome-rr.c deleted file mode 100644 index b1327bd..0000000 --- a/gtk/display/gnome-rr.c +++ /dev/null @@ -1,1161 +0,0 @@ -/* gnome-rr.c - * - * Copyright 2007, 2008, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Soren Sandmann <sandmann@xxxxxxxxxx> - */ - -#define GNOME_DESKTOP_USE_UNSTABLE_API - -#include <config.h> -#include <glib/gi18n-lib.h> -#include <string.h> - -#include <gtk/gtk.h> - -#include "../glib-compat.h" - -#if defined(HAVE_X11) -#include <X11/Xlib.h> -#include <gdk/gdkx.h> -#include <X11/Xatom.h> -#include "gnome-rr-x11.h" -#elif defined(HAVE_WINDOWS) -#include "gnome-rr-windows.h" -#else -#include "gnome-rr-generic.h" -#endif - -#undef GNOME_DISABLE_DEPRECATED -#include "gnome-rr.h" -#include "gnome-rr-config.h" - -#include "gnome-rr-private.h" - -enum { - SCREEN_PROP_0, - SCREEN_PROP_GDK_SCREEN, - SCREEN_PROP_LAST, -}; - -enum { - SCREEN_CHANGED, - SCREEN_SIGNAL_LAST, -}; - -static gint screen_signals[SCREEN_SIGNAL_LAST]; -static GParamSpec *screen_properties[SCREEN_PROP_LAST]; - -/* GnomeRRCrtc */ -static GnomeRRCrtc * crtc_copy (const GnomeRRCrtc *from); -static void crtc_free (GnomeRRCrtc *crtc); - -static GnomeRROutput *output_copy (const GnomeRROutput *from); -static void output_free (GnomeRROutput *output); - -static GnomeRRMode * mode_copy (const GnomeRRMode *from); -static void mode_free (GnomeRRMode *mode); - -static void gnome_rr_screen_set_property (GObject*, guint, const GValue*, GParamSpec*); -static void gnome_rr_screen_get_property (GObject*, guint, GValue*, GParamSpec*); -static void gnome_rr_screen_initable_iface_init (GInitableIface *iface); -G_DEFINE_TYPE_WITH_CODE (GnomeRRScreen, gnome_rr_screen, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gnome_rr_screen_initable_iface_init)) - -G_DEFINE_BOXED_TYPE (GnomeRRCrtc, gnome_rr_crtc, crtc_copy, crtc_free) -G_DEFINE_BOXED_TYPE (GnomeRROutput, gnome_rr_output, output_copy, output_free) -G_DEFINE_BOXED_TYPE (GnomeRRMode, gnome_rr_mode, mode_copy, mode_free) - -/* Errors */ - -/** - * gnome_rr_error_quark: - * - * Returns the #GQuark that will be used for #GError values returned by the - * GnomeRR API. - * - * Return value: a #GQuark used to identify errors coming from the GnomeRR API. - */ -GQuark -gnome_rr_error_quark (void) -{ - return g_quark_from_static_string ("gnome-rr-error-quark"); -} - -/* Screen */ -GnomeRROutput * -gnome_rr_output_by_id (ScreenInfo *info, RROutput id) -{ - GnomeRROutput **output; - - g_return_val_if_fail (info != NULL, NULL); - - for (output = info->outputs; *output; ++output) - { - if ((*output)->id == id) - return *output; - } - - return NULL; -} - -GnomeRRCrtc * -crtc_by_id (ScreenInfo *info, RRCrtc id) -{ - GnomeRRCrtc **crtc; - - if (!info) - return NULL; - - for (crtc = info->crtcs; *crtc; ++crtc) - { - if ((*crtc)->id == id) - return *crtc; - } - - return NULL; -} - -GnomeRRMode * -mode_by_id (ScreenInfo *info, RRMode id) -{ - GnomeRRMode **mode; - - g_return_val_if_fail (info != NULL, NULL); - - for (mode = info->modes; *mode; ++mode) - { - if ((*mode)->id == id) - return *mode; - } - - return NULL; -} - -void -screen_info_free (ScreenInfo *info) -{ - GnomeRROutput **output; - GnomeRRCrtc **crtc; - GnomeRRMode **mode; - - g_return_if_fail (info != NULL); - -#ifdef HAVE_RANDR - if (info->resources) - { - XRRFreeScreenResources (info->resources); - - info->resources = NULL; - } -#endif - - if (info->outputs) - { - for (output = info->outputs; *output; ++output) - output_free (*output); - g_free (info->outputs); - } - - if (info->crtcs) - { - for (crtc = info->crtcs; *crtc; ++crtc) - crtc_free (*crtc); - g_free (info->crtcs); - } - - if (info->modes) - { - for (mode = info->modes; *mode; ++mode) - mode_free (*mode); - g_free (info->modes); - } - - if (info->clone_modes) - { - /* The modes themselves were freed above */ - g_free (info->clone_modes); - } - - g_free (info); -} - -static gboolean -has_similar_mode (GnomeRROutput *output, GnomeRRMode *mode) -{ - int i; - GnomeRRMode **modes = gnome_rr_output_list_modes (output); - int width = gnome_rr_mode_get_width (mode); - int height = gnome_rr_mode_get_height (mode); - - for (i = 0; modes[i] != NULL; ++i) - { - GnomeRRMode *m = modes[i]; - - if (gnome_rr_mode_get_width (m) == width && - gnome_rr_mode_get_height (m) == height) - { - return TRUE; - } - } - - return FALSE; -} - -void -gather_clone_modes (ScreenInfo *info) -{ - int i; - GPtrArray *result = g_ptr_array_new (); - - for (i = 0; info->outputs[i] != NULL; ++i) - { - int j; - GnomeRROutput *output1, *output2; - - output1 = info->outputs[i]; - - if (!output1->connected) - continue; - - for (j = 0; output1->modes[j] != NULL; ++j) - { - GnomeRRMode *mode = output1->modes[j]; - gboolean valid; - int k; - - valid = TRUE; - for (k = 0; info->outputs[k] != NULL; ++k) - { - output2 = info->outputs[k]; - - if (!output2->connected) - continue; - - if (!has_similar_mode (output2, mode)) - { - valid = FALSE; - break; - } - } - - if (valid) - g_ptr_array_add (result, mode); - } - } - - g_ptr_array_add (result, NULL); - - info->clone_modes = (GnomeRRMode **)g_ptr_array_free (result, FALSE); -} - -ScreenInfo * -screen_info_new (GnomeRRScreen *screen, gboolean needs_reprobe, GError **error) -{ - ScreenInfo *info = g_new0 (ScreenInfo, 1); - - g_return_val_if_fail (screen != NULL, NULL); - - info->outputs = NULL; - info->crtcs = NULL; - info->modes = NULL; - info->screen = screen; - - if (fill_out_screen_info (screen, info, needs_reprobe, error)) - { - return info; - } - else - { - screen_info_free (info); - return NULL; - } -} - -gboolean -screen_update (GnomeRRScreen *screen, gboolean force_callback, gboolean needs_reprobe, GError **error) -{ - ScreenInfo *info; - gboolean changed = FALSE; - - g_return_val_if_fail (screen != NULL, FALSE); - - info = screen_info_new (screen, needs_reprobe, error); - if (!info) - return FALSE; - -#ifdef HAVE_RANDR - if (info->resources->configTimestamp != screen->priv->info->resources->configTimestamp) - changed = TRUE; -#endif - - screen_info_free (screen->priv->info); - - screen->priv->info = info; - - if (changed || force_callback) - g_signal_emit (G_OBJECT (screen), screen_signals[SCREEN_CHANGED], 0); - - return changed; -} - -static gboolean -gnome_rr_screen_initable_init (GInitable *initable, GCancellable *canc, GError **error) -{ - GnomeRRScreen *self = GNOME_RR_SCREEN (initable); - GnomeRRScreenPrivate *priv = self->priv; - - priv->info = screen_info_new (self, TRUE, error); - g_return_val_if_fail (priv->info != NULL, FALSE); - - return TRUE; -} - -static void -gnome_rr_screen_initable_iface_init (GInitableIface *iface) -{ - iface->init = gnome_rr_screen_initable_init; -} - -static void -gnome_rr_screen_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *property) -{ - GnomeRRScreen *self = GNOME_RR_SCREEN (gobject); - GnomeRRScreenPrivate *priv = self->priv; - - switch (property_id) - { - case SCREEN_PROP_GDK_SCREEN: - priv->gdk_screen = g_value_get_object (value); - g_object_notify (gobject, "gdk-screen"); - return; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, property); - return; - } -} - -static void -gnome_rr_screen_get_property (GObject *gobject, guint property_id, GValue *value, GParamSpec *property) -{ - GnomeRRScreen *self = GNOME_RR_SCREEN (gobject); - - switch (property_id) - { - case SCREEN_PROP_GDK_SCREEN: - g_value_set_object (value, gnome_rr_screen_get_gdk_screen (self)); - return; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, property); - return; - } -} - -static void -gnome_rr_screen_finalize (GObject *gobject) -{ - GnomeRRScreen *screen = GNOME_RR_SCREEN (gobject); - - if (screen->priv->info) - screen_info_free (screen->priv->info); - - G_OBJECT_CLASS (gnome_rr_screen_parent_class)->finalize (gobject); -} - -void -gnome_rr_screen_class_init (GnomeRRScreenClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (klass, sizeof (GnomeRRScreenPrivate)); - - gobject_class->set_property = gnome_rr_screen_set_property; - gobject_class->get_property = gnome_rr_screen_get_property; - gobject_class->finalize = gnome_rr_screen_finalize; - - screen_properties[SCREEN_PROP_GDK_SCREEN] = g_param_spec_object ( - "gdk-screen", - "GDK Screen", - "The GDK Screen represented by this GnomeRRScreen", - GDK_TYPE_SCREEN, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_property( - gobject_class, - SCREEN_PROP_GDK_SCREEN, - screen_properties[SCREEN_PROP_GDK_SCREEN]); - - screen_signals[SCREEN_CHANGED] = g_signal_new("changed", - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - G_STRUCT_OFFSET (GnomeRRScreenClass, changed), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} - -void -gnome_rr_screen_init (GnomeRRScreen *self) -{ - GnomeRRScreenPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_RR_SCREEN, GnomeRRScreenPrivate); - self->priv = priv; - - priv->gdk_screen = NULL; - priv->info = NULL; -} - -/** - * gnome_rr_screen_new: - * Creates a new #GnomeRRScreen instance - * - * @screen: the #GdkScreen on which to operate - * @error: will be set if screen could not be created - * - * Returns: a new #GnomeRRScreen instance or NULL if screen could not be created, - * for instance if the driver does not support Xrandr 1.2 - */ -GnomeRRScreen * -gnome_rr_screen_new (GdkScreen *screen, - GError **error) -{ - /* FIXME: _gnome_desktop_init_i18n (); */ - return g_initable_new ( -#if defined(HAVE_X11) - GNOME_TYPE_RR_X11_SCREEN, -#elif defined(HAVE_WINDOWS) - GNOME_TYPE_RR_WINDOWS_SCREEN, -#else - GNOME_TYPE_RR_GENERIC_SCREEN, -#endif - NULL, error, "gdk-screen", screen, NULL); -} - -/** - * gnome_rr_screen_get_ranges: - * - * Get the ranges of the screen - * @screen: a #GnomeRRScreen - * @min_width: (out): the minimum width - * @max_width: (out): the maximum width - * @min_height: (out): the minimum height - * @max_height: (out): the maximum height - */ -void -gnome_rr_screen_get_ranges (GnomeRRScreen *screen, - int *min_width, - int *max_width, - int *min_height, - int *max_height) -{ - GnomeRRScreenPrivate *priv; - - g_return_if_fail (GNOME_IS_RR_SCREEN (screen)); - - priv = screen->priv; - - if (min_width) - *min_width = priv->info->min_width; - - if (max_width) - *max_width = priv->info->max_width; - - if (min_height) - *min_height = priv->info->min_height; - - if (max_height) - *max_height = priv->info->max_height; -} - -/** - * gnome_rr_screen_get_timestamps: - * @screen: a #GnomeRRScreen - * @change_timestamp_ret: (out): Location in which to store the timestamp at which the RANDR configuration was last changed - * @config_timestamp_ret: (out): Location in which to store the timestamp at which the RANDR configuration was last obtained - * - * Queries the two timestamps that the X RANDR extension maintains. The X - * server will prevent change requests for stale configurations, those whose - * timestamp is not equal to that of the latest request for configuration. The - * X server will also prevent change requests that have an older timestamp to - * the latest change request. - */ -void -gnome_rr_screen_get_timestamps (GnomeRRScreen *screen, - guint32 *change_timestamp_ret, - guint32 *config_timestamp_ret) -{ - GnomeRRScreenPrivate *priv G_GNUC_UNUSED; - - g_return_if_fail (GNOME_IS_RR_SCREEN (screen)); - - priv = screen->priv; - -#ifdef HAVE_RANDR - if (change_timestamp_ret) - *change_timestamp_ret = priv->info->resources->timestamp; - - if (config_timestamp_ret) - *config_timestamp_ret = priv->info->resources->configTimestamp; -#endif -} - -/** - * gnome_rr_screen_refresh: - * @screen: a #GnomeRRScreen - * @error: location to store error, or %NULL - * - * Refreshes the screen configuration, and calls the screen's callback if it - * exists and if the screen's configuration changed. - * - * Return value: TRUE if the screen's configuration changed; otherwise, the - * function returns FALSE and a NULL error if the configuration didn't change, - * or FALSE and a non-NULL error if there was an error while refreshing the - * configuration. - */ -gboolean -gnome_rr_screen_refresh (GnomeRRScreen *screen, - GError **error) -{ - gboolean refreshed; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - -#ifdef HAVE_X11 - gdk_x11_display_grab (gdk_screen_get_display (screen->priv->gdk_screen)); -#endif - - refreshed = screen_update (screen, FALSE, TRUE, error); - -#ifdef HAVE_X11 - gnome_rr_x11_screen_force_timestamp_update (GNOME_RR_X11_SCREEN (screen)); /* this is to keep other clients from thinking that the X server re-detected things by itself - bgo#621046 */ - gdk_x11_display_ungrab (gdk_screen_get_display (screen->priv->gdk_screen)); -#endif - - return refreshed; -} - -/** - * gnome_rr_screen_list_modes: - * - * List available XRandR modes - * - * Returns: (array zero-terminated=1) (transfer none): - */ -GnomeRRMode ** -gnome_rr_screen_list_modes (GnomeRRScreen *screen) -{ - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL); - g_return_val_if_fail (screen->priv->info != NULL, NULL); - - return screen->priv->info->modes; -} - -/** - * gnome_rr_screen_list_clone_modes: - * - * List available XRandR clone modes - * - * Returns: (array zero-terminated=1) (transfer none): - */ -GnomeRRMode ** -gnome_rr_screen_list_clone_modes (GnomeRRScreen *screen) -{ - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL); - g_return_val_if_fail (screen->priv->info != NULL, NULL); - - return screen->priv->info->clone_modes; -} - -/** - * gnome_rr_screen_list_crtcs: - * - * List all CRTCs - * - * Returns: (array zero-terminated=1) (transfer none): - */ -GnomeRRCrtc ** -gnome_rr_screen_list_crtcs (GnomeRRScreen *screen) -{ - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL); - g_return_val_if_fail (screen->priv->info != NULL, NULL); - - return screen->priv->info->crtcs; -} - -/** - * gnome_rr_screen_list_outputs: - * - * List all outputs - * - * Returns: (array zero-terminated=1) (transfer none): - */ -GnomeRROutput ** -gnome_rr_screen_list_outputs (GnomeRRScreen *screen) -{ - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL); - g_return_val_if_fail (screen->priv->info != NULL, NULL); - - return screen->priv->info->outputs; -} - -/** - * gnome_rr_screen_get_crtc_by_id: - * - * Returns: (transfer none): the CRTC identified by @id - */ -GnomeRRCrtc * -gnome_rr_screen_get_crtc_by_id (GnomeRRScreen *screen, - guint32 id) -{ - GnomeRRCrtc **crtcs; - int i; - - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL); - g_return_val_if_fail (screen->priv->info != NULL, NULL); - - crtcs = screen->priv->info->crtcs; - - for (i = 0; crtcs[i] != NULL; ++i) - { - if (crtcs[i]->id == id) - return crtcs[i]; - } - - return NULL; -} - -/** - * gnome_rr_screen_get_output_by_id: - * - * Returns: (transfer none): the output identified by @id - */ -GnomeRROutput * -gnome_rr_screen_get_output_by_id (GnomeRRScreen *screen, - guint32 id) -{ - GnomeRROutput **outputs; - int i; - - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL); - g_return_val_if_fail (screen->priv->info != NULL, NULL); - - outputs = screen->priv->info->outputs; - - for (i = 0; outputs[i] != NULL; ++i) - { - if (outputs[i]->id == id) - return outputs[i]; - } - - return NULL; -} - -/* GnomeRROutput */ -GnomeRROutput * -output_new (ScreenInfo *info, RROutput id) -{ - GnomeRROutput *output = g_slice_new0 (GnomeRROutput); - - output->id = id; - output->info = info; - - return output; -} - -static GnomeRROutput* -output_copy (const GnomeRROutput *from) -{ - GPtrArray *array; - GnomeRRCrtc **p_crtc; - GnomeRROutput **p_output; - GnomeRRMode **p_mode; - GnomeRROutput *output = g_slice_new0 (GnomeRROutput); - - output->id = from->id; - output->info = from->info; - output->name = g_strdup (from->name); - output->current_crtc = from->current_crtc; - output->width_mm = from->width_mm; - output->height_mm = from->height_mm; - output->connected = from->connected; - output->n_preferred = from->n_preferred; - output->connector_type = g_strdup (from->connector_type); - - array = g_ptr_array_new (); - for (p_crtc = from->possible_crtcs; *p_crtc != NULL; p_crtc++) - { - g_ptr_array_add (array, *p_crtc); - } - output->possible_crtcs = (GnomeRRCrtc**) g_ptr_array_free (array, FALSE); - - array = g_ptr_array_new (); - for (p_output = from->clones; *p_output != NULL; p_output++) - { - g_ptr_array_add (array, *p_output); - } - output->clones = (GnomeRROutput**) g_ptr_array_free (array, FALSE); - - array = g_ptr_array_new (); - for (p_mode = from->modes; *p_mode != NULL; p_mode++) - { - g_ptr_array_add (array, *p_mode); - } - output->modes = (GnomeRRMode**) g_ptr_array_free (array, FALSE); - - output->edid_size = from->edid_size; - output->edid_data = g_memdup (from->edid_data, from->edid_size); - - return output; -} - -static void -output_free (GnomeRROutput *output) -{ - g_free (output->clones); - g_free (output->modes); - g_free (output->possible_crtcs); - g_free (output->edid_data); - g_free (output->name); - g_free (output->connector_type); - g_slice_free (GnomeRROutput, output); -} - -guint32 -gnome_rr_output_get_id (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, 0); - - return output->id; -} - -const guint8 * -gnome_rr_output_get_edid_data (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, NULL); - - return output->edid_data; -} - -/** - * gnome_rr_screen_get_output_by_id: - * - * Returns: (transfer none): the output identified by @name - */ -GnomeRROutput * -gnome_rr_screen_get_output_by_name (GnomeRRScreen *screen, - const char *name) -{ - int i; - - g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL); - g_return_val_if_fail (screen->priv->info != NULL, NULL); - - for (i = 0; screen->priv->info->outputs[i] != NULL; ++i) - { - GnomeRROutput *output = screen->priv->info->outputs[i]; - - if (strcmp (output->name, name) == 0) - return output; - } - - return NULL; -} - -GnomeRRCrtc * -gnome_rr_output_get_crtc (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, NULL); - - return output->current_crtc; -} - -/* Returns NULL if the ConnectorType property is not available */ -const char * -gnome_rr_output_get_connector_type (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, NULL); - - return output->connector_type; -} - -gboolean -gnome_rr_output_is_laptop (GnomeRROutput *output) -{ - const char *connector_type; - - g_return_val_if_fail (output != NULL, FALSE); - - if (!output->connected) - return FALSE; - - /* The ConnectorType property is present in RANDR 1.3 and greater */ - - connector_type = gnome_rr_output_get_connector_type (output); - if (connector_type && strcmp (connector_type, GNOME_RR_CONNECTOR_TYPE_PANEL) == 0) - return TRUE; - - /* Older versions of RANDR - this is a best guess, as @#$% RANDR doesn't have standard output names, - * so drivers can use whatever they like. - */ - - if (output->name - && (strstr (output->name, "lvds") || /* Most drivers use an "LVDS" prefix... */ - strstr (output->name, "LVDS") || - strstr (output->name, "Lvds") || - strstr (output->name, "LCD"))) /* ... but fglrx uses "LCD" in some versions. Shoot me now, kthxbye. */ - return TRUE; - - return FALSE; -} - -GnomeRRMode * -gnome_rr_output_get_current_mode (GnomeRROutput *output) -{ - GnomeRRCrtc *crtc; - - g_return_val_if_fail (output != NULL, NULL); - - if ((crtc = gnome_rr_output_get_crtc (output))) - return gnome_rr_crtc_get_current_mode (crtc); - - return NULL; -} - -void -gnome_rr_output_get_position (GnomeRROutput *output, - int *x, - int *y) -{ - GnomeRRCrtc *crtc; - - g_return_if_fail (output != NULL); - - if ((crtc = gnome_rr_output_get_crtc (output))) - gnome_rr_crtc_get_position (crtc, x, y); -} - -const char * -gnome_rr_output_get_name (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, ""); - return output->name; -} - -int -gnome_rr_output_get_width_mm (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, -1); - return output->width_mm; -} - -int -gnome_rr_output_get_height_mm (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, -1); - return output->height_mm; -} - -GnomeRRMode * -gnome_rr_output_get_preferred_mode (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, NULL); - if (output->n_preferred) - return output->modes[0]; - - return NULL; -} - -GnomeRRMode ** -gnome_rr_output_list_modes (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, NULL); - return output->modes; -} - -gboolean -gnome_rr_output_is_connected (GnomeRROutput *output) -{ - g_return_val_if_fail (output != NULL, FALSE); - return output->connected; -} - -gboolean -gnome_rr_output_supports_mode (GnomeRROutput *output, - GnomeRRMode *mode) -{ - int i; - - g_return_val_if_fail (output != NULL, FALSE); - g_return_val_if_fail (mode != NULL, FALSE); - - for (i = 0; output->modes[i] != NULL; ++i) - { - if (output->modes[i] == mode) - return TRUE; - } - - return FALSE; -} - -gboolean -gnome_rr_output_can_clone (GnomeRROutput *output, - GnomeRROutput *clone) -{ - int i; - - g_return_val_if_fail (output != NULL, FALSE); - g_return_val_if_fail (clone != NULL, FALSE); - - for (i = 0; output->clones[i] != NULL; ++i) - { - if (output->clones[i] == clone) - return TRUE; - } - - return FALSE; -} - -gboolean -gnome_rr_output_get_is_primary (GnomeRROutput *output) -{ -#ifdef HAVE_RANDR - return output->info->primary == output->id; -#else - return FALSE; -#endif -} - -void -gnome_rr_screen_set_primary_output (GnomeRRScreen *screen, - GnomeRROutput *output) -{ - g_return_if_fail (GNOME_IS_RR_SCREEN (screen)); - - screen_set_primary_output (screen, output); -} - -#ifndef GNOME_DISABLE_DEPRECATED_SOURCE -gboolean -gnome_rr_crtc_set_config (GnomeRRCrtc *crtc, - int x, - int y, - GnomeRRMode *mode, - GnomeRRRotation rotation, - GnomeRROutput **outputs, - int n_outputs, - GError **error) -{ - return gnome_rr_crtc_set_config_with_time (crtc, GDK_CURRENT_TIME, x, y, mode, rotation, outputs, n_outputs, error); -} -#endif - -GnomeRRMode * -gnome_rr_crtc_get_current_mode (GnomeRRCrtc *crtc) -{ - g_return_val_if_fail (crtc != NULL, NULL); - - return crtc->current_mode; -} - -guint32 -gnome_rr_crtc_get_id (GnomeRRCrtc *crtc) -{ - g_return_val_if_fail (crtc != NULL, 0); - - return crtc->id; -} - -gboolean -gnome_rr_crtc_can_drive_output (GnomeRRCrtc *crtc, - GnomeRROutput *output) -{ - int i; - - g_return_val_if_fail (crtc != NULL, FALSE); - g_return_val_if_fail (output != NULL, FALSE); - - for (i = 0; crtc->possible_outputs[i] != NULL; ++i) - { - if (crtc->possible_outputs[i] == output) - return TRUE; - } - - return FALSE; -} - -/* FIXME: merge with get_mode()? */ -void -gnome_rr_crtc_get_position (GnomeRRCrtc *crtc, - int *x, - int *y) -{ - g_return_if_fail (crtc != NULL); - - if (x) - *x = crtc->x; - - if (y) - *y = crtc->y; -} - -/* FIXME: merge with get_mode()? */ -GnomeRRRotation -gnome_rr_crtc_get_current_rotation (GnomeRRCrtc *crtc) -{ - g_return_val_if_fail (crtc != NULL, GNOME_RR_ROTATION_0); - return crtc->current_rotation; -} - -GnomeRRRotation -gnome_rr_crtc_get_rotations (GnomeRRCrtc *crtc) -{ - g_return_val_if_fail (crtc != NULL, GNOME_RR_ROTATION_0); - return crtc->rotations; -} - -gboolean -gnome_rr_crtc_supports_rotation (GnomeRRCrtc * crtc, - GnomeRRRotation rotation) -{ - g_return_val_if_fail (crtc != NULL, FALSE); - return (crtc->rotations & rotation); -} - -GnomeRRCrtc * -crtc_new (ScreenInfo *info, RROutput id) -{ - GnomeRRCrtc *crtc = g_slice_new0 (GnomeRRCrtc); - - crtc->id = id; - crtc->info = info; - - return crtc; -} - -static GnomeRRCrtc * -crtc_copy (const GnomeRRCrtc *from) -{ - GnomeRROutput **p_output; - GPtrArray *array; - GnomeRRCrtc *to = g_slice_new0 (GnomeRRCrtc); - - to->info = from->info; - to->id = from->id; - to->current_mode = from->current_mode; - to->x = from->x; - to->y = from->y; - to->current_rotation = from->current_rotation; - to->rotations = from->rotations; - to->gamma_size = from->gamma_size; - - array = g_ptr_array_new (); - for (p_output = from->current_outputs; *p_output != NULL; p_output++) - { - g_ptr_array_add (array, *p_output); - } - to->current_outputs = (GnomeRROutput**) g_ptr_array_free (array, FALSE); - - array = g_ptr_array_new (); - for (p_output = from->possible_outputs; *p_output != NULL; p_output++) - { - g_ptr_array_add (array, *p_output); - } - to->possible_outputs = (GnomeRROutput**) g_ptr_array_free (array, FALSE); - - return to; -} - -static void -crtc_free (GnomeRRCrtc *crtc) -{ - g_free (crtc->current_outputs); - g_free (crtc->possible_outputs); - g_slice_free (GnomeRRCrtc, crtc); -} - -/* GnomeRRMode */ -GnomeRRMode * -mode_new (ScreenInfo *info, RRMode id) -{ - GnomeRRMode *mode = g_slice_new0 (GnomeRRMode); - - mode->id = id; - mode->info = info; - - return mode; -} - -guint32 -gnome_rr_mode_get_id (GnomeRRMode *mode) -{ - g_return_val_if_fail (mode != NULL, 0); - return mode->id; -} - -guint -gnome_rr_mode_get_width (GnomeRRMode *mode) -{ - g_return_val_if_fail (mode != NULL, 0); - return mode->width; -} - -int -gnome_rr_mode_get_freq (GnomeRRMode *mode) -{ - g_return_val_if_fail (mode != NULL, 0); - return (mode->freq) / 1000; -} - -guint -gnome_rr_mode_get_height (GnomeRRMode *mode) -{ - g_return_val_if_fail (mode != NULL, 0); - return mode->height; -} - -static GnomeRRMode * -mode_copy (const GnomeRRMode *from) -{ - GnomeRRMode *to = g_slice_new0 (GnomeRRMode); - - to->id = from->id; - to->info = from->info; - to->name = g_strdup (from->name); - to->width = from->width; - to->height = from->height; - to->freq = from->freq; - - return to; -} - -static void -mode_free (GnomeRRMode *mode) -{ - g_free (mode->name); - g_slice_free (GnomeRRMode, mode); -} - -GdkScreen * -gnome_rr_screen_get_gdk_screen (GnomeRRScreen *self) -{ - g_return_val_if_fail (self != NULL, NULL); - - return self->priv->gdk_screen; -} diff --git a/gtk/display/gnome-rr.h b/gtk/display/gnome-rr.h deleted file mode 100644 index d32d2f6..0000000 --- a/gtk/display/gnome-rr.h +++ /dev/null @@ -1,200 +0,0 @@ -/* gnome-rr.h - * - * Copyright 2007, 2008, Red Hat, Inc. - * - * This file is part of the Gnome Library. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Soren Sandmann <sandmann@xxxxxxxxxx> - */ -#ifndef GNOME_RR_H -#define GNOME_RR_H - -#ifndef GNOME_DESKTOP_USE_UNSTABLE_API -#error GnomeRR is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnomerr.h -#endif - -#include <glib.h> -#include <gdk/gdk.h> - -typedef struct GnomeRRScreenPrivate GnomeRRScreenPrivate; -typedef struct GnomeRROutput GnomeRROutput; -typedef struct GnomeRRCrtc GnomeRRCrtc; -typedef struct GnomeRRMode GnomeRRMode; - -typedef struct { - GObject parent; - - GnomeRRScreenPrivate* priv; -} GnomeRRScreen; - -typedef struct { - GObjectClass parent_class; - - void (* changed) (void); -} GnomeRRScreenClass; - -typedef enum -{ - GNOME_RR_ROTATION_0 = (1 << 0), - GNOME_RR_ROTATION_90 = (1 << 1), - GNOME_RR_ROTATION_180 = (1 << 2), - GNOME_RR_ROTATION_270 = (1 << 3), - GNOME_RR_REFLECT_X = (1 << 4), - GNOME_RR_REFLECT_Y = (1 << 5) -} GnomeRRRotation; - -/* Error codes */ - -#define GNOME_RR_ERROR (gnome_rr_error_quark ()) - -GQuark gnome_rr_error_quark (void); - -typedef enum { - GNOME_RR_ERROR_UNKNOWN, /* generic "fail" */ - GNOME_RR_ERROR_NO_RANDR_EXTENSION, /* RANDR extension is not present */ - GNOME_RR_ERROR_RANDR_ERROR, /* generic/undescribed error from the underlying XRR API */ - GNOME_RR_ERROR_BOUNDS_ERROR, /* requested bounds of a CRTC are outside the maximum size */ - GNOME_RR_ERROR_CRTC_ASSIGNMENT, /* could not assign CRTCs to outputs */ - GNOME_RR_ERROR_NO_MATCHING_CONFIG, /* none of the saved configurations matched the current configuration */ -} GnomeRRError; - -#define GNOME_RR_CONNECTOR_TYPE_PANEL "Panel" /* This is a laptop's built-in LCD */ - -#define GNOME_TYPE_RR_SCREEN (gnome_rr_screen_get_type()) -#define GNOME_RR_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_SCREEN, GnomeRRScreen)) -#define GNOME_IS_RR_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_SCREEN)) -#define GNOME_RR_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RR_SCREEN, GnomeRRScreenClass)) -#define GNOME_IS_RR_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RR_SCREEN)) -#define GNOME_RR_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_RR_SCREEN, GnomeRRScreenClass)) - -#define GNOME_TYPE_RR_OUTPUT (gnome_rr_output_get_type()) -#define GNOME_TYPE_RR_CRTC (gnome_rr_crtc_get_type()) -#define GNOME_TYPE_RR_MODE (gnome_rr_mode_get_type()) - -GType gnome_rr_screen_get_type (void); -GType gnome_rr_output_get_type (void); -GType gnome_rr_crtc_get_type (void); -GType gnome_rr_mode_get_type (void); - -/* GnomeRRScreen */ -GnomeRRScreen * gnome_rr_screen_new (GdkScreen *screen, - GError **error); -GnomeRROutput **gnome_rr_screen_list_outputs (GnomeRRScreen *screen); -GnomeRRCrtc ** gnome_rr_screen_list_crtcs (GnomeRRScreen *screen); -GnomeRRMode ** gnome_rr_screen_list_modes (GnomeRRScreen *screen); -GnomeRRMode ** gnome_rr_screen_list_clone_modes (GnomeRRScreen *screen); -void gnome_rr_screen_set_size (GnomeRRScreen *screen, - int width, - int height, - int mm_width, - int mm_height); -GnomeRRCrtc * gnome_rr_screen_get_crtc_by_id (GnomeRRScreen *screen, - guint32 id); -gboolean gnome_rr_screen_refresh (GnomeRRScreen *screen, - GError **error); -GnomeRROutput * gnome_rr_screen_get_output_by_id (GnomeRRScreen *screen, - guint32 id); -GnomeRROutput * gnome_rr_screen_get_output_by_name (GnomeRRScreen *screen, - const char *name); -void gnome_rr_screen_get_ranges (GnomeRRScreen *screen, - int *min_width, - int *max_width, - int *min_height, - int *max_height); -void gnome_rr_screen_get_timestamps (GnomeRRScreen *screen, - guint32 *change_timestamp_ret, - guint32 *config_timestamp_ret); - -void gnome_rr_screen_set_primary_output (GnomeRRScreen *screen, - GnomeRROutput *output); - -GnomeRRMode **gnome_rr_screen_create_clone_modes (GnomeRRScreen *screen); - -/* GnomeRROutput */ -guint32 gnome_rr_output_get_id (GnomeRROutput *output); -const char * gnome_rr_output_get_name (GnomeRROutput *output); -gboolean gnome_rr_output_is_connected (GnomeRROutput *output); -int gnome_rr_output_get_size_inches (GnomeRROutput *output); -int gnome_rr_output_get_width_mm (GnomeRROutput *outout); -int gnome_rr_output_get_height_mm (GnomeRROutput *output); -const guint8 * gnome_rr_output_get_edid_data (GnomeRROutput *output); -GnomeRRCrtc ** gnome_rr_output_get_possible_crtcs (GnomeRROutput *output); -GnomeRRMode * gnome_rr_output_get_current_mode (GnomeRROutput *output); -GnomeRRCrtc * gnome_rr_output_get_crtc (GnomeRROutput *output); -const char * gnome_rr_output_get_connector_type (GnomeRROutput *output); -gboolean gnome_rr_output_is_laptop (GnomeRROutput *output); -void gnome_rr_output_get_position (GnomeRROutput *output, - int *x, - int *y); -gboolean gnome_rr_output_can_clone (GnomeRROutput *output, - GnomeRROutput *clone); -GnomeRRMode ** gnome_rr_output_list_modes (GnomeRROutput *output); -GnomeRRMode * gnome_rr_output_get_preferred_mode (GnomeRROutput *output); -gboolean gnome_rr_output_supports_mode (GnomeRROutput *output, - GnomeRRMode *mode); -gboolean gnome_rr_output_get_is_primary (GnomeRROutput *output); - -/* GnomeRRMode */ -guint32 gnome_rr_mode_get_id (GnomeRRMode *mode); -guint gnome_rr_mode_get_width (GnomeRRMode *mode); -guint gnome_rr_mode_get_height (GnomeRRMode *mode); -int gnome_rr_mode_get_freq (GnomeRRMode *mode); - -/* GnomeRRCrtc */ -guint32 gnome_rr_crtc_get_id (GnomeRRCrtc *crtc); - -#ifndef GNOME_DISABLE_DEPRECATED -gboolean gnome_rr_crtc_set_config (GnomeRRCrtc *crtc, - int x, - int y, - GnomeRRMode *mode, - GnomeRRRotation rotation, - GnomeRROutput **outputs, - int n_outputs, - GError **error); -#endif - -gboolean gnome_rr_crtc_set_config_with_time (GnomeRRCrtc *crtc, - guint32 timestamp, - int x, - int y, - GnomeRRMode *mode, - GnomeRRRotation rotation, - GnomeRROutput **outputs, - int n_outputs, - GError **error); -gboolean gnome_rr_crtc_can_drive_output (GnomeRRCrtc *crtc, - GnomeRROutput *output); -GnomeRRMode * gnome_rr_crtc_get_current_mode (GnomeRRCrtc *crtc); -void gnome_rr_crtc_get_position (GnomeRRCrtc *crtc, - int *x, - int *y); -GnomeRRRotation gnome_rr_crtc_get_current_rotation (GnomeRRCrtc *crtc); -GnomeRRRotation gnome_rr_crtc_get_rotations (GnomeRRCrtc *crtc); -gboolean gnome_rr_crtc_supports_rotation (GnomeRRCrtc *crtc, - GnomeRRRotation rotation); - -gboolean gnome_rr_crtc_get_gamma (GnomeRRCrtc *crtc, - int *size, - unsigned short **red, - unsigned short **green, - unsigned short **blue); -void gnome_rr_crtc_set_gamma (GnomeRRCrtc *crtc, - int size, - unsigned short *red, - unsigned short *green, - unsigned short *blue); -#endif /* GNOME_RR_H */ diff --git a/gtk/smartcard-manager.h b/gtk/smartcard-manager.h index 24d9f92..65c6934 100644 --- a/gtk/smartcard-manager.h +++ b/gtk/smartcard-manager.h @@ -21,7 +21,6 @@ G_BEGIN_DECLS #include "spice-types.h" -#include "spice-glib-enums.h" #include "spice-util.h" #define SPICE_TYPE_SMARTCARD_MANAGER (spice_smartcard_manager_get_type ()) diff --git a/gtk/spicy.c b/gtk/spicy.c index 3d9085f..dff9d44 100644 --- a/gtk/spicy.c +++ b/gtk/spicy.c @@ -26,10 +26,6 @@ #include <termios.h> #endif -#define GNOME_DESKTOP_USE_UNSTABLE_API 2 -#include "display/gnome-rr.h" -#include "display/gnome-rr-config.h" - #ifdef USE_SMARTCARD #include <vreader.h> #include "smartcard-manager.h" @@ -114,8 +110,6 @@ static spice_connection *connection_new(void); static void connection_connect(spice_connection *conn); static void connection_disconnect(spice_connection *conn); static void connection_destroy(spice_connection *conn); -static void resolution_fullscreen(SpiceWindow *win); -static void resolution_restore(SpiceWindow *win); static void usb_connect_failed(GObject *object, SpiceUsbDevice *device, GError *error, @@ -132,9 +126,6 @@ static GMainLoop *mainloop = NULL; static int connections = 0; static GKeyFile *keyfile = NULL; static SpicePortChannel*stdin_port = NULL; -static GnomeRRScreen *rrscreen = NULL; -static GnomeRRConfig *rrsaved = NULL; -static GnomeRRConfig *rrcurrent = NULL; /* ------------------------------------------------------------------ */ @@ -961,198 +952,6 @@ static void recent_item_activated_cb(GtkRecentChooser *chooser, gpointer data) } #endif -static GnomeRROutputInfo * -get_nearest_output (GnomeRRConfig *configuration, int x, int y) -{ - int i; - int nearest_index; - int nearest_dist; - GnomeRROutputInfo **outputs; - - nearest_index = -1; - nearest_dist = G_MAXINT; - - outputs = gnome_rr_config_get_outputs (configuration); - for (i = 0; outputs[i] != NULL; i++) - { - int dist_x, dist_y; - int output_x, output_y, output_width, output_height; - - if (!(gnome_rr_output_info_is_connected (outputs[i]) && gnome_rr_output_info_is_active (outputs[i]))) - continue; - - gnome_rr_output_info_get_geometry (outputs[i], &output_x, &output_y, &output_width, &output_height); - - if (x < output_x) - dist_x = output_x - x; - else if (x >= output_x + output_width) - dist_x = x - (output_x + output_width) + 1; - else - dist_x = 0; - - if (y < output_y) - dist_y = output_y - y; - else if (y >= output_y + output_height) - dist_y = y - (output_y + output_height) + 1; - else - dist_y = 0; - - if (MIN (dist_x, dist_y) < nearest_dist) - { - nearest_dist = MIN (dist_x, dist_y); - nearest_index = i; - } - } - - if (nearest_index != -1) - return outputs[nearest_index]; - else - return NULL; -} - -#if !GTK_CHECK_VERSION (2, 91, 0) -#define gdk_window_get_geometry(win,x,y,w,h) gdk_window_get_geometry(win,x,y,w,h,NULL) -#endif - -static GnomeRROutputInfo * -get_output_for_window(GnomeRRConfig *configuration, GdkWindow *window) -{ - GdkRectangle win_rect; - int i; - int largest_area; - int largest_index; - GnomeRROutputInfo **outputs; - - gdk_window_get_geometry (window, &win_rect.x, &win_rect.y, &win_rect.width, &win_rect.height); - gdk_window_get_origin (window, &win_rect.x, &win_rect.y); - - largest_area = 0; - largest_index = -1; - - outputs = gnome_rr_config_get_outputs (configuration); - for (i = 0; outputs[i] != NULL; i++) - { - GdkRectangle output_rect, intersection; - - gnome_rr_output_info_get_geometry (outputs[i], &output_rect.x, &output_rect.y, &output_rect.width, &output_rect.height); - - if (gnome_rr_output_info_is_connected (outputs[i]) && gdk_rectangle_intersect (&win_rect, &output_rect, &intersection)) - { - int area; - - area = intersection.width * intersection.height; - if (area > largest_area) - { - largest_area = area; - largest_index = i; - } - } - } - - if (largest_index != -1) - return outputs[largest_index]; - else - return get_nearest_output (configuration, - win_rect.x + win_rect.width / 2, - win_rect.y + win_rect.height / 2); -} - -static void -on_screen_changed(GnomeRRScreen *scr, gpointer data) -{ - GError *error = NULL; - GnomeRRConfig *current; - - current = gnome_rr_config_new_current(rrscreen, &error); - if (!current) { - g_warning("Can't get current display config: %s", error->message); - goto end; - } - - if (rrcurrent) - g_object_unref(rrcurrent); - rrcurrent = current; - -end: - g_clear_error(&error); -} - -static void resolution_fullscreen(SpiceWindow *win) -{ - GnomeRROutputInfo *output; - int x, y, width, height; - GError *error = NULL;; - - if (!rrsaved) { - rrsaved = gnome_rr_config_new_current(rrscreen, &error); - g_clear_error(&error); - } - - output = get_output_for_window(rrcurrent, gtk_widget_get_window(win->spice)); - g_return_if_fail(output != NULL); - - gnome_rr_output_info_get_geometry (output, &x, &y, &width, &height); - g_object_get(win->display_channel, "width", &width, "height", &height, NULL); - gnome_rr_output_info_set_geometry (output, x, y, width, height); - - if (!gnome_rr_config_apply_with_time(rrcurrent, rrscreen, - gtk_get_current_event_time (), &error)) { - g_warning("Can't set display config: %s", error->message); - } - g_clear_error(&error); - -#ifdef WIN32 - /* recenter the window on Windows */ - gtk_window_fullscreen(GTK_WINDOW(win->toplevel)); -#endif -} - -static void resolution_restore(SpiceWindow *win) -{ - GnomeRROutputInfo *output, *saved; - int x, y, width, height; - GError *error = NULL;; - - if (rrsaved == NULL) - return; - - output = get_output_for_window(rrcurrent, gtk_widget_get_window(win->spice)); - g_return_if_fail(output != NULL); - saved = get_output_for_window(rrsaved, gtk_widget_get_window(win->spice)); - g_return_if_fail(saved != NULL); - - gnome_rr_output_info_get_geometry (saved, &x, &y, &width, &height); - gnome_rr_output_info_set_geometry (output, x, y, width, height); - - if (!gnome_rr_config_apply_with_time(rrcurrent, rrscreen, - gtk_get_current_event_time (), &error)) { - g_warning("Can't set display config: %s", error->message); - } - g_clear_error(&error); - -#ifdef WIN32 - /* recenter the window on Windows */ - gtk_window_unfullscreen(GTK_WINDOW(win->toplevel)); -#endif -} - -static void resolution_restore_all(void) -{ - GError *error = NULL;; - - if (!rrsaved) - return; - - if (!gnome_rr_config_apply_with_time(rrsaved, rrscreen, - gtk_get_current_event_time (), &error)) { - g_warning("Can't restore display config: %s", error->message); - } - g_clear_error(&error); - - g_object_unref(rrsaved); - rrsaved = NULL; -} - static gboolean configure_event_cb(GtkWidget *widget, GdkEventConfigure *event, gpointer data) @@ -1167,11 +966,6 @@ static gboolean configure_event_cb(GtkWidget *widget, if (resize_guest && win->conn->agent_connected) return FALSE; - if (win->fullscreen) - resolution_fullscreen(win); - else - resolution_restore(win); - return FALSE; } @@ -2053,11 +1847,6 @@ int main(int argc, char *argv[]) g_type_init(); mainloop = g_main_loop_new(NULL, false); - rrscreen = gnome_rr_screen_new(gdk_screen_get_default (), &error); - g_warn_if_fail(rrscreen != NULL); - if (rrscreen) - g_signal_connect(rrscreen, "changed", G_CALLBACK(on_screen_changed), NULL); - on_screen_changed(rrscreen, NULL); conn = connection_new(); spice_set_session_option(conn->session); @@ -2094,9 +1883,6 @@ int main(int argc, char *argv[]) error = NULL; } - resolution_restore_all(); - - g_object_unref(rrscreen); g_free(conf_file); g_free(conf); g_key_file_free(keyfile); -- 1.8.2.1.342.gfa7285d _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel