gnome-desktop r5115 - in branches/randr-12: . desktop-docs gnome-about libgnome-desktop libgnome-desktop/libgnomeui po
- From: ssp svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-desktop r5115 - in branches/randr-12: . desktop-docs gnome-about libgnome-desktop libgnome-desktop/libgnomeui po
- Date: Mon, 16 Jun 2008 20:16:34 +0000 (UTC)
Author: ssp
Date: Mon Jun 16 20:16:33 2008
New Revision: 5115
URL: http://svn.gnome.org/viewvc/gnome-desktop?rev=5115&view=rev
Log:
Merge from trunk
Modified:
branches/randr-12/ChangeLog
branches/randr-12/NEWS
branches/randr-12/README
branches/randr-12/configure.in
branches/randr-12/desktop-docs/ChangeLog
branches/randr-12/gnome-about/ChangeLog
branches/randr-12/libgnome-desktop/ChangeLog
branches/randr-12/libgnome-desktop/Makefile.am
branches/randr-12/libgnome-desktop/display-name.c
branches/randr-12/libgnome-desktop/edid-parse.c
branches/randr-12/libgnome-desktop/edid.h
branches/randr-12/libgnome-desktop/gnome-bg.c
branches/randr-12/libgnome-desktop/gnome-rr-config.c
branches/randr-12/libgnome-desktop/gnome-rr.c
branches/randr-12/libgnome-desktop/libgnomeui/Makefile.am
branches/randr-12/libgnome-desktop/libgnomeui/gnome-bg.h
branches/randr-12/libgnome-desktop/libgnomeui/gnome-rr-config.h
branches/randr-12/libgnome-desktop/libgnomeui/gnome-rr.h
branches/randr-12/po/ChangeLog
branches/randr-12/po/ar.po
branches/randr-12/po/gu.po
Modified: branches/randr-12/NEWS
==============================================================================
--- branches/randr-12/NEWS (original)
+++ branches/randr-12/NEWS Mon Jun 16 20:16:33 2008
@@ -1,4 +1,29 @@
==============
+Version 2.23.3
+==============
+
+ libgnome-desktop
+
+ * GnomeBG: Fix some logic errors wrt to caching of slideshows that may
+ cause nautilus crashes (Matthias Clasen)
+ * GnomeBG: Support multi-resolution backgrounds (Matthias Clasen)
+ * GnomeBG: Falls back to the default image if the user's background
+ doesn't exist (Ray Strode)
+ * GnomeBG: Prevent loops caused by setting URI (SÃren Sandmann)
+ * GnomeBG: Fix leak (Kjartan Maraas)
+ * GnomeBG: Get rid of URIs and only use paths (SÃren Sandmann)
+ * GnomeBG: Make sure tiles are at least 24 pixels wide (SÃren Sandmann)
+ * GnomeBG: Some tweaks to the tile scaling heuristic (SÃren Sandmann)
+ * GnomeBG: Small fixes (SÃren Sandmann)
+ * GnomeBG: Add getters for the various properties (SÃren Sandmann)
+ * GnomeBG: Monitor the image file (SÃren Sandmann)
+
+ Translators
+
+ * Khaled Hosny (ar)
+ * Sweta Kothari (gu)
+
+==============
Version 2.23.2
==============
Modified: branches/randr-12/README
==============================================================================
--- branches/randr-12/README (original)
+++ branches/randr-12/README Mon Jun 16 20:16:33 2008
@@ -1,4 +1,4 @@
-gnome-desktop 2.23.2
+gnome-desktop 2.23.3
====================
This package is free software and is part of the
Modified: branches/randr-12/configure.in
==============================================================================
--- branches/randr-12/configure.in (original)
+++ branches/randr-12/configure.in Mon Jun 16 20:16:33 2008
@@ -1,4 +1,4 @@
-AC_INIT([gnome-desktop], [2.23.3],
+AC_INIT([gnome-desktop], [2.23.4],
[http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-desktop])
AC_CONFIG_SRCDIR([libgnome-desktop])
@@ -19,7 +19,7 @@
# change to C+1:0:0
# - If the interface is the same as the previous version, change to C:R+1:A
-LT_VERSION=6:8:4
+LT_VERSION=7:0:0
AC_SUBST(LT_VERSION)
AM_MAINTAINER_MODE
@@ -35,7 +35,7 @@
GNOME_PLATFORM=2
GNOME_MINOR=23
-GNOME_MICRO=2
+GNOME_MICRO=3
GNOME_DISTRIBUTOR="GNOME.Org"
GNOME_DATE=`date +"%Y-%m-%d"`
Modified: branches/randr-12/libgnome-desktop/Makefile.am
==============================================================================
--- branches/randr-12/libgnome-desktop/Makefile.am (original)
+++ branches/randr-12/libgnome-desktop/Makefile.am Mon Jun 16 20:16:33 2008
@@ -20,12 +20,7 @@
gnome-desktop-item.c \
gnome-ditem-edit.c \
gnome-hint.c \
- gnome-bg.c \
- display-name.c \
- gnome-rr.c \
- gnome-rr-config.c \
- edid-parse.c \
- edid.h
+ gnome-bg.c
libgnome_desktop_2_la_LIBADD = \
$(XLIB_LIBS) \
Modified: branches/randr-12/libgnome-desktop/display-name.c
==============================================================================
--- branches/randr-12/libgnome-desktop/display-name.c (original)
+++ branches/randr-12/libgnome-desktop/display-name.c Mon Jun 16 20:16:33 2008
@@ -1,252 +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 redhat com> */
-
-#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
- */
-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" },
- { "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 const char *
-find_vendor (const char *code)
-{
- int i;
-
- 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 char *output_name,
- const MonitorInfo *info)
-{
- const char *vendor;
- int width_mm, height_mm, inches;
-
- if (output_name &&
- (strstr ("lvds", output_name) ||
- strstr ("LVDS", output_name) ||
- strstr ("Lvds", output_name)))
- {
- vendor = "Laptop";
- }
- else if (info)
- {
- vendor = find_vendor (info->manufacturer_code);
- }
- else
- {
- 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_printf ("%s\n", vendor);
-}
Modified: branches/randr-12/libgnome-desktop/edid-parse.c
==============================================================================
--- branches/randr-12/libgnome-desktop/edid-parse.c (original)
+++ branches/randr-12/libgnome-desktop/edid-parse.c Mon Jun 16 20:16:33 2008
@@ -1,551 +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 redhat com> */
-
-#include "edid.h"
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#define TRUE 1
-#define FALSE 0
-
-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->digital.bits_per_primary = bit_depth[bits];
-
- bits = get_bits (edid[0x14], 0, 3);
-
- if (bits <= 5)
- info->digital.interface = interfaces[bits];
- else
- info->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->analog.video_signal_level = levels[bits][0];
- info->analog.sync_signal_level = levels[bits][1];
- info->analog.total_signal_level = levels[bits][2];
-
- info->analog.blank_to_black = get_bit (edid[0x14], 4);
-
- info->analog.separate_hv_sync = get_bit (edid[0x14], 3);
- info->analog.composite_sync_on_h = get_bit (edid[0x14], 2);
- info->analog.composite_sync_on_green = get_bit (edid[0x14], 1);
-
- info->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->digital.rgb444 = TRUE;
- if (get_bit (edid[0x18], 3))
- info->digital.ycrcb444 = 1;
- if (get_bit (edid[0x18], 4))
- info->digital.ycrcb422 = 1;
- }
- else
- {
- int bits = get_bits (edid[0x18], 3, 4);
- ColorType color_type[4] =
- {
- MONOCHROME, RGB, OTHER_COLOR, UNDEFINED_COLOR
- };
-
- info->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;
-
- 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->digital.composite = !get_bit (bits, 3);
-
- if (detailed->digital.composite)
- {
- detailed->digital.serrations = get_bit (bits, 2);
- detailed->digital.negative_vsync = FALSE;
- }
- else
- {
- detailed->digital.serrations = FALSE;
- detailed->digital.negative_vsync = !get_bit (bits, 2);
- }
-
- detailed->digital.negative_hsync = !get_bit (bits, 0);
- }
- else
- {
- detailed->analog.bipolar = get_bit (bits, 3);
- detailed->analog.serrations = get_bit (bits, 2);
- detailed->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 = calloc (1, sizeof (MonitorInfo));
-
- decode_check_sum (edid, info);
-
- if (!decode_header (edid))
- return NULL;
-
- if (!decode_vendor_and_product_identification (edid, info))
- return NULL;
-
- if (!decode_edid_version (edid, info))
- return NULL;
-
- if (!decode_display_parameters (edid, info))
- return NULL;
-
- if (!decode_color_characteristics (edid, info))
- return NULL;
-
- if (!decode_established_timings (edid, info))
- return NULL;
-
- if (!decode_standard_timings (edid, info))
- return NULL;
-
- if (!decode_descriptors (edid, info))
- return NULL;
-
- return info;
-}
Modified: branches/randr-12/libgnome-desktop/edid.h
==============================================================================
--- branches/randr-12/libgnome-desktop/edid.h (original)
+++ branches/randr-12/libgnome-desktop/edid.h Mon Jun 16 20:16:33 2008
@@ -1,199 +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 Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Soren Sandmann <sandmann redhat com>
- */
-
-#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 DisplayDescriptor
-{
-};
-
-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;
- };
-};
-
-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;
- };
-
- 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 char *output_name,
- const MonitorInfo *info);
-
-#endif
Modified: branches/randr-12/libgnome-desktop/gnome-bg.c
==============================================================================
--- branches/randr-12/libgnome-desktop/gnome-bg.c (original)
+++ branches/randr-12/libgnome-desktop/gnome-bg.c Mon Jun 16 20:16:33 2008
@@ -46,8 +46,8 @@
#define BG_KEY_DRAW_BACKGROUND GNOME_BG_KEY_DIR "/draw_background"
#define BG_KEY_PRIMARY_COLOR GNOME_BG_KEY_DIR "/primary_color"
#define BG_KEY_SECONDARY_COLOR GNOME_BG_KEY_DIR "/secondary_color"
-#define BG_KEY_COLOR_SHADING_TYPE GNOME_BG_KEY_DIR "/color_shading_type"
-#define BG_KEY_PICTURE_OPTIONS GNOME_BG_KEY_DIR "/picture_options"
+#define BG_KEY_COLOR_TYPE GNOME_BG_KEY_DIR "/color_shading_type"
+#define BG_KEY_PICTURE_PLACEMENT GNOME_BG_KEY_DIR "/picture_options"
#define BG_KEY_PICTURE_OPACITY GNOME_BG_KEY_DIR "/picture_opacity"
#define BG_KEY_PICTURE_FILENAME GNOME_BG_KEY_DIR "/picture_filename"
@@ -59,8 +59,17 @@
double duration; /* in seconds */
gboolean fixed;
- char *file1;
- char *file2; /* NULL if fixed is TRUE */
+ GSList *file1;
+ GSList *file2; /* NULL if fixed is TRUE */
+};
+
+typedef struct _FileSize FileSize;
+struct _FileSize
+{
+ gint width;
+ gint height;
+
+ char *file;
};
/* This is the size of the GdkRGB dither matrix, in order to avoid
@@ -77,21 +86,26 @@
struct _GnomeBG
{
GObject parent_instance;
- char * uri;
+ char * filename;
GnomeBGPlacement placement;
GnomeBGColorType color_type;
- GdkColor c1;
- GdkColor c2;
+ GdkColor primary;
+ GdkColor secondary;
+ gint last_pixmap_width;
+ gint last_pixmap_height;
+
+ GFileMonitor * file_monitor;
+
+ guint changed_id;
+
/* Cached information, only access through cache accessor functions */
SlideShow * slideshow;
- time_t uri_mtime;
+ time_t file_mtime;
GdkPixbuf * pixbuf_cache;
int timeout_id;
GList * file_cache;
-
- guint changed_id;
};
struct _GnomeBGClass
@@ -137,8 +151,8 @@
double alpha);
/* Thumbnail utilities */
-static GdkPixbuf *create_thumbnail_for_uri (GnomeThumbnailFactory *factory,
- const char *uri);
+static GdkPixbuf *create_thumbnail_for_filename (GnomeThumbnailFactory *factory,
+ const char *filename);
static gboolean get_thumb_annotations (GdkPixbuf *thumb,
int *orig_width,
int *orig_height);
@@ -147,66 +161,96 @@
static GdkPixbuf *get_pixbuf (GnomeBG *bg);
static void clear_cache (GnomeBG *bg);
static gboolean is_different (GnomeBG *bg,
- const char *uri);
-static time_t get_mtime (const char *uri);
+ const char *filename);
+static time_t get_mtime (const char *filename);
static GdkPixbuf *create_img_thumbnail (GnomeBG *bg,
GnomeThumbnailFactory *factory,
GdkScreen *screen,
int dest_width,
int dest_height);
static SlideShow * get_as_slideshow (GnomeBG *bg,
- const char *uri);
+ const char *filename);
static Slide * get_current_slide (SlideShow *show,
double *alpha);
+static gboolean slideshow_changes_with_size (SlideShow *show);
static void
-set_color_from_string (const char *string,
- GdkColor *colorp)
+color_from_string (const char *string,
+ GdkColor *colorp)
{
/* If all else fails use black */
- if (string == NULL || !gdk_color_parse (string, colorp)) {
- gdk_color_parse ("black", colorp);
- }
- gdk_rgb_find_color (gdk_rgb_get_colormap (), colorp);
+ gdk_color_parse ("black", colorp);
+
+ if (!string)
+ return;
+
+ if (!gdk_color_parse (string, colorp))
+ return;
+
+ gdk_rgb_find_color (gdk_rgb_get_colormap(), colorp);
+}
+
+static char *
+color_to_string (const GdkColor *color)
+{
+ return g_strdup_printf ("#%02x%02x%02x",
+ color->red >> 8,
+ color->green >> 8,
+ color->blue >> 8);
}
+static GConfEnumStringPair placement_lookup[] = {
+ { GNOME_BG_PLACEMENT_CENTERED, "centered" },
+ { GNOME_BG_PLACEMENT_FILL_SCREEN, "stretched" },
+ { GNOME_BG_PLACEMENT_SCALED, "scaled" },
+ { GNOME_BG_PLACEMENT_ZOOMED, "zoom" },
+ { GNOME_BG_PLACEMENT_TILED, "wallpaper" },
+ { 0, NULL }
+};
+
+static GConfEnumStringPair color_type_lookup[] = {
+ { GNOME_BG_COLOR_SOLID, "solid" },
+ { GNOME_BG_COLOR_H_GRADIENT, "horizontal-gradient" },
+ { GNOME_BG_COLOR_V_GRADIENT, "vertical-gradient" },
+ { 0, NULL }
+};
static void
-set_color_type_from_string (const char *string,
- GnomeBGColorType *color_type)
+color_type_from_string (const char *string,
+ GnomeBGColorType *color_type)
{
*color_type = GNOME_BG_COLOR_SOLID;
- if (string != NULL) {
- if (!strncmp (string, "vertical-gradient", sizeof ("vertical-gradient"))) {
- *color_type = GNOME_BG_COLOR_V_GRADIENT;
- } else if (!strncmp (string, "horizontal-gradient", sizeof ("horizontal-gradient"))) {
- *color_type = GNOME_BG_COLOR_H_GRADIENT;
- }
+ if (string) {
+ gconf_string_to_enum (color_type_lookup,
+ string, (int *)color_type);
}
}
+static const char *
+color_type_to_string (GnomeBGColorType color_type)
+{
+ return gconf_enum_to_string (color_type_lookup, color_type);
+}
+
static void
-set_placement_from_string (const char *string,
- GnomeBGPlacement *placement)
+placement_from_string (const char *string,
+ GnomeBGPlacement *placement)
{
*placement = GNOME_BG_PLACEMENT_ZOOMED;
- if (string != NULL) {
- if (!strncmp (string, "wallpaper", sizeof ("wallpaper"))) {
- *placement = GNOME_BG_PLACEMENT_TILED;
- } else if (!strncmp (string, "centered", sizeof ("centered"))) {
- *placement = GNOME_BG_PLACEMENT_CENTERED;
- } else if (!strncmp (string, "scaled", sizeof ("scaled"))) {
- *placement = GNOME_BG_PLACEMENT_SCALED;
- } else if (!strncmp (string, "stretched", sizeof ("stretched"))) {
- *placement = GNOME_BG_PLACEMENT_FILL_SCREEN;
- } else if (!strncmp (string, "zoom", sizeof ("zoom"))) {
- *placement = GNOME_BG_PLACEMENT_ZOOMED;
- }
+ if (string) {
+ gconf_string_to_enum (placement_lookup,
+ string, (int *)placement);
}
}
+static const char *
+placement_to_string (GnomeBGPlacement placement)
+{
+ return gconf_enum_to_string (placement_lookup, placement);
+}
+
static gboolean
do_changed (GnomeBG *bg)
{
@@ -235,48 +279,101 @@
GConfClient *client)
{
char *tmp;
- char *uri;
+ char *filename;
g_return_if_fail (GNOME_IS_BG (bg));
g_return_if_fail (client != NULL);
/* Filename */
- uri = NULL;
+ filename = NULL;
tmp = gconf_client_get_string (client, BG_KEY_PICTURE_FILENAME, NULL);
if (tmp != NULL) {
if (g_utf8_validate (tmp, -1, NULL) &&
g_file_test (tmp, G_FILE_TEST_EXISTS)) {
- uri = g_strdup (tmp);
+ filename = g_strdup (tmp);
} else {
- uri = g_filename_from_utf8 (tmp, -1, NULL, NULL, NULL);
+ filename = g_filename_from_utf8 (tmp, -1, NULL, NULL, NULL);
+ }
+
+ /* Fall back to default background if filename was set
+ but no longer exists */
+ if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ GConfValue *default_value;
+
+ g_free (filename);
+ filename = NULL;
+
+ default_value =
+ gconf_client_get_default_from_schema (client,
+ BG_KEY_PICTURE_FILENAME,
+ NULL);
+ if (default_value != NULL) {
+ filename = g_strdup (gconf_value_get_string (default_value));
+ gconf_value_free (default_value);
+ }
}
}
g_free (tmp);
/* Colors */
tmp = gconf_client_get_string (client, BG_KEY_PRIMARY_COLOR, NULL);
- set_color_from_string (tmp, &bg->c1);
+ color_from_string (tmp, &bg->primary);
g_free (tmp);
tmp = gconf_client_get_string (client, BG_KEY_SECONDARY_COLOR, NULL);
- set_color_from_string (tmp, &bg->c2);
+ color_from_string (tmp, &bg->secondary);
g_free (tmp);
/* Color type */
- tmp = gconf_client_get_string (client, BG_KEY_COLOR_SHADING_TYPE, NULL);
- set_color_type_from_string (tmp, &bg->color_type);
+ tmp = gconf_client_get_string (client, BG_KEY_COLOR_TYPE, NULL);
+ color_type_from_string (tmp, &bg->color_type);
g_free (tmp);
/* Placement */
- tmp = gconf_client_get_string (client, BG_KEY_PICTURE_OPTIONS, NULL);
- set_placement_from_string (tmp, &bg->placement);
+ tmp = gconf_client_get_string (client, BG_KEY_PICTURE_PLACEMENT, NULL);
+ placement_from_string (tmp, &bg->placement);
g_free (tmp);
- gnome_bg_set_uri (bg, uri);
+ gnome_bg_set_filename (bg, filename);
queue_changed (bg);
}
+void
+gnome_bg_save_to_preferences (GnomeBG *bg,
+ GConfClient *client)
+{
+ const char *color_type;
+ const char *placement;
+ const gchar *filename;
+ gchar *primary;
+ gchar *secondary;
+
+ primary = color_to_string (&bg->primary);
+ secondary = color_to_string (&bg->secondary);
+
+ color_type = color_type_to_string (bg->color_type);
+
+ if (bg->filename) {
+ filename = bg->filename;
+ placement = placement_to_string (bg->placement);
+ }
+ else {
+ filename = "(none)";
+ placement = "none";
+ }
+
+ gconf_client_set_string (client, BG_KEY_PICTURE_FILENAME, filename, NULL);
+ gconf_client_set_string (client, BG_KEY_PRIMARY_COLOR, primary, NULL);
+ gconf_client_set_string (client, BG_KEY_SECONDARY_COLOR, secondary, NULL);
+ gconf_client_set_string (client, BG_KEY_COLOR_TYPE, color_type, NULL);
+ gconf_client_set_string (client, BG_KEY_PICTURE_PLACEMENT, placement, NULL);
+
+ g_free (primary);
+ g_free (secondary);
+}
+
+
static void
gnome_bg_init (GnomeBG *bg)
{
@@ -320,29 +417,29 @@
}
static gboolean
-colors_equal (const GdkColor *c1, const GdkColor *c2)
+colors_equal (const GdkColor *primary, const GdkColor *secondary)
{
- return c1->red == c2->red &&
- c1->green == c2->green &&
- c1->blue == c2->blue;
+ return primary->red == secondary->red &&
+ primary->green == secondary->green &&
+ primary->blue == secondary->blue;
}
void
gnome_bg_set_color (GnomeBG *bg,
GnomeBGColorType type,
- GdkColor *c1,
- GdkColor *c2)
+ GdkColor *primary,
+ GdkColor *secondary)
{
g_return_if_fail (bg != NULL);
if (bg->color_type != type ||
- !colors_equal (&bg->c1, c1) ||
- (c2 && !colors_equal (&bg->c2, c2))) {
+ !colors_equal (&bg->primary, primary) ||
+ (secondary && !colors_equal (&bg->secondary, secondary))) {
bg->color_type = type;
- bg->c1 = *c1;
- if (c2) {
- bg->c2 = *c2;
+ bg->primary = *primary;
+ if (secondary) {
+ bg->secondary = *secondary;
}
queue_changed (bg);
@@ -362,26 +459,83 @@
}
}
+GnomeBGPlacement
+gnome_bg_get_placement (GnomeBG *bg)
+{
+ g_return_val_if_fail (bg != NULL, -1);
+
+ return bg->placement;
+}
+
+void
+gnome_bg_get_color (GnomeBG *bg,
+ GnomeBGColorType *type,
+ GdkColor *primary,
+ GdkColor *secondary)
+{
+ g_return_if_fail (bg != NULL);
+
+ if (type)
+ *type = bg->color_type;
+
+ if (primary)
+ *primary = bg->primary;
+
+ if (secondary)
+ *secondary = bg->secondary;
+}
+
+const gchar *
+gnome_bg_get_filename (GnomeBG *bg)
+{
+ g_return_val_if_fail (bg != NULL, NULL);
+
+ return bg->filename;
+}
+
+static void
+file_changed (GFileMonitor *file_monitor,
+ GFile *child,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ GnomeBG *bg = GNOME_BG (user_data);
+
+ clear_cache (bg);
+ queue_changed (bg);
+}
+
void
-gnome_bg_set_uri (GnomeBG *bg,
- const char *uri)
+gnome_bg_set_filename (GnomeBG *bg,
+ const char *filename)
{
char *free_me = NULL;
g_return_if_fail (bg != NULL);
- if (g_path_is_absolute (uri)) {
- uri = free_me = g_filename_to_uri (uri, NULL, NULL);
- }
-
- if (is_different (bg, uri)) {
- char *tmp = g_strdup (uri);
-
- /* FIXME: maybe check that it is local */
+ if (is_different (bg, filename)) {
+ char *tmp = g_strdup (filename);
- g_free (bg->uri);
+ g_free (bg->filename);
- bg->uri = tmp;
+ bg->filename = tmp;
+ bg->file_mtime = get_mtime (bg->filename);
+
+ if (bg->file_monitor) {
+ g_object_unref (bg->file_monitor);
+ bg->file_monitor = NULL;
+ }
+
+ if (bg->filename) {
+ GFile *f = g_file_new_for_path (bg->filename);
+
+ bg->file_monitor = g_file_monitor_file (f, 0, NULL, NULL);
+ g_signal_connect (bg->file_monitor, "changed",
+ G_CALLBACK (file_changed), bg);
+
+ g_object_unref (f);
+ }
clear_cache (bg);
@@ -399,20 +553,20 @@
switch (bg->color_type)
{
case GNOME_BG_COLOR_SOLID:
- pixel = ((bg->c1.red >> 8) << 24) |
- ((bg->c1.green >> 8) << 16) |
- ((bg->c1.blue >> 8) << 8) |
+ pixel = ((bg->primary.red >> 8) << 24) |
+ ((bg->primary.green >> 8) << 16) |
+ ((bg->primary.blue >> 8) << 8) |
(0xff);
gdk_pixbuf_fill (dest, pixel);
break;
case GNOME_BG_COLOR_H_GRADIENT:
- pixbuf_draw_gradient (dest, TRUE, &(bg->c1), &(bg->c2));
+ pixbuf_draw_gradient (dest, TRUE, &(bg->primary), &(bg->secondary));
break;
case GNOME_BG_COLOR_V_GRADIENT:
- pixbuf_draw_gradient (dest, FALSE, &(bg->c1), &(bg->c2));
+ pixbuf_draw_gradient (dest, FALSE, &(bg->primary), &(bg->secondary));
break;
default:
@@ -478,7 +632,7 @@
scaled = get_scaled_pixbuf (
placement, pixbuf, dest_width, dest_height, &x, &y, &w, &h);
-
+
switch (placement) {
case GNOME_BG_PLACEMENT_TILED:
pixbuf_tile (scaled, dest);
@@ -512,6 +666,10 @@
gnome_bg_changes_with_size (GnomeBG *bg)
{
g_return_val_if_fail (bg != NULL, FALSE);
+
+ SlideShow *show = get_as_slideshow (bg, bg->filename);
+ if (show)
+ return slideshow_changes_with_size (show);
if (bg->color_type != GNOME_BG_COLOR_SOLID) {
if (!get_pixbuf (bg))
@@ -622,7 +780,17 @@
g_return_val_if_fail (bg != NULL, NULL);
g_return_val_if_fail (window != NULL, NULL);
-
+
+ if (bg->last_pixmap_width != width ||
+ bg->last_pixmap_height != height) {
+ if (bg->pixbuf_cache) {
+ g_object_unref (bg->pixbuf_cache);
+ bg->pixbuf_cache = NULL;
+ }
+ }
+ bg->last_pixmap_width = width;
+ bg->last_pixmap_height = height;
+
gnome_bg_get_pixmap_size (bg, width, height, &pm_width, &pm_height);
if (root) {
@@ -635,7 +803,7 @@
if (!get_pixbuf (bg) && bg->color_type == GNOME_BG_COLOR_SOLID) {
GdkGC *gc = gdk_gc_new (pixmap);
- gdk_gc_set_rgb_fg_color (gc, &(bg->c1));
+ gdk_gc_set_rgb_fg_color (gc, &(bg->primary));
gdk_draw_point (pixmap, gc, 0, 0);
@@ -670,11 +838,11 @@
g_return_val_if_fail (bg != NULL, FALSE);
if (bg->color_type == GNOME_BG_COLOR_SOLID) {
- color = bg->c1;
+ color = bg->primary;
} else {
- color.red = (bg->c1.red + bg->c2.red) / 2;
- color.green = (bg->c1.green + bg->c2.green) / 2;
- color.blue = (bg->c1.blue + bg->c2.blue) / 2;
+ color.red = (bg->primary.red + bg->secondary.red) / 2;
+ color.green = (bg->primary.green + bg->secondary.green) / 2;
+ color.blue = (bg->primary.blue + bg->secondary.blue) / 2;
}
if (get_pixbuf (bg)) {
@@ -746,24 +914,16 @@
}
static gboolean
-get_original_size (const char *uri,
+get_original_size (const char *filename,
int *orig_width,
int *orig_height)
{
- char *filename;
gboolean result;
- if (g_str_has_prefix (uri, "file:"))
- filename = g_filename_from_uri (uri, NULL, NULL);
- else
- filename = g_strdup (uri);
-
if (gdk_pixbuf_get_file_info (filename, orig_width, orig_height))
result = TRUE;
else
result = FALSE;
-
- g_free (filename);
return result;
}
@@ -776,24 +936,26 @@
{
GdkPixbuf *thumb;
gboolean result = FALSE;
- const gchar *uri;
+ const gchar *filename;
g_return_val_if_fail (bg != NULL, FALSE);
g_return_val_if_fail (factory != NULL, FALSE);
- if (!bg->uri)
+ if (!bg->filename)
return FALSE;
- uri = bg->uri;
- thumb = create_thumbnail_for_uri (factory, uri);
+ filename = bg->filename;
+ thumb = create_thumbnail_for_filename (factory, filename);
if (!thumb) {
- SlideShow *show = get_as_slideshow (bg, bg->uri);
+ SlideShow *show = get_as_slideshow (bg, bg->filename);
if (show) {
double alpha;
+ FileSize *fs;
Slide *slide = get_current_slide (show, &alpha);
- uri = slide->file1;
- thumb = create_thumbnail_for_uri (factory, uri);
+ fs = slide->file1->data;
+ filename = fs->file;
+ thumb = create_thumbnail_for_filename (factory, filename);
}
}
@@ -805,7 +967,7 @@
}
if (!result) {
- if (get_original_size (uri, width, height))
+ if (get_original_size (filename, width, height))
result = TRUE;
}
@@ -918,11 +1080,14 @@
/* Implementation of the pixbuf cache */
struct _SlideShow
{
+ gint ref_count;
double start_time;
double total_duration;
GQueue *slides;
+ gboolean changes_with_size;
+
/* used during parsing */
struct tm start_tm;
GQueue *stack;
@@ -930,7 +1095,8 @@
static SlideShow *read_slideshow_file (const char *filename,
GError **err);
-static void slideshow_free (SlideShow *show);
+static void slideshow_ref (SlideShow *show);
+static void slideshow_unref (SlideShow *show);
static double
now (void)
@@ -983,14 +1149,16 @@
GdkPixbuf *tmp;
if (gdk_pixbuf_get_width (p2) != gdk_pixbuf_get_width (p1) ||
- gdk_pixbuf_get_height (p2) != gdk_pixbuf_get_height (p1))
- tmp = gdk_pixbuf_scale_simple (p2,
- gdk_pixbuf_get_width (p1),
- gdk_pixbuf_get_height (p1),
- GDK_INTERP_BILINEAR);
- else
- tmp = g_object_ref (p2);
-
+ gdk_pixbuf_get_height (p2) != gdk_pixbuf_get_height (p1)) {
+ tmp = gdk_pixbuf_scale_simple (p2,
+ gdk_pixbuf_get_width (p1),
+ gdk_pixbuf_get_height (p1),
+ GDK_INTERP_BILINEAR);
+ }
+ else {
+ tmp = g_object_ref (p2);
+ }
+
pixbuf_blend (tmp, result, 0, 0, -1, -1, 0, 0, alpha);
g_object_unref (tmp);
@@ -1007,7 +1175,7 @@
struct FileCacheEntry
{
FileType type;
- char *uri;
+ char *filename;
union {
GdkPixbuf *pixbuf;
SlideShow *slideshow;
@@ -1018,14 +1186,14 @@
static void
file_cache_entry_delete (FileCacheEntry *ent)
{
- g_free (ent->uri);
+ g_free (ent->filename);
switch (ent->type) {
case PIXBUF:
g_object_unref (ent->u.pixbuf);
break;
case SLIDESHOW:
- slideshow_free (ent->u.slideshow);
+ slideshow_unref (ent->u.slideshow);
break;
case THUMBNAIL:
g_object_unref (ent->u.thumbnail);
@@ -1049,15 +1217,17 @@
}
static const FileCacheEntry *
-file_cache_lookup (GnomeBG *bg, FileType type, const char *uri)
+file_cache_lookup (GnomeBG *bg, FileType type, const char *filename)
{
GList *list;
for (list = bg->file_cache; list != NULL; list = list->next) {
FileCacheEntry *ent = list->data;
- if (ent && ent->type == type && strcmp (ent->uri, uri) == 0)
+ if (ent && ent->type == type &&
+ strcmp (ent->filename, filename) == 0) {
return ent;
+ }
}
return NULL;
@@ -1066,14 +1236,14 @@
static FileCacheEntry *
file_cache_entry_new (GnomeBG *bg,
FileType type,
- const char *uri)
+ const char *filename)
{
FileCacheEntry *ent = g_new0 (FileCacheEntry, 1);
- g_assert (!file_cache_lookup (bg, type, uri));
+ g_assert (!file_cache_lookup (bg, type, filename));
ent->type = type;
- ent->uri = g_strdup (uri);
+ ent->filename = g_strdup (filename);
bg->file_cache = g_list_prepend (bg->file_cache, ent);
@@ -1084,77 +1254,77 @@
static void
file_cache_add_pixbuf (GnomeBG *bg,
- const char *uri,
+ const char *filename,
GdkPixbuf *pixbuf)
{
- FileCacheEntry *ent = file_cache_entry_new (bg, PIXBUF, uri);
+ FileCacheEntry *ent = file_cache_entry_new (bg, PIXBUF, filename);
ent->u.pixbuf = pixbuf;
}
static void
file_cache_add_thumbnail (GnomeBG *bg,
- const char *uri,
+ const char *filename,
GdkPixbuf *pixbuf)
{
- FileCacheEntry *ent = file_cache_entry_new (bg, THUMBNAIL, uri);
+ FileCacheEntry *ent = file_cache_entry_new (bg, THUMBNAIL, filename);
ent->u.thumbnail = pixbuf;
}
static void
file_cache_add_slide_show (GnomeBG *bg,
- const char *uri,
+ const char *filename,
SlideShow *show)
{
- FileCacheEntry *ent = file_cache_entry_new (bg, SLIDESHOW, uri);
+ FileCacheEntry *ent = file_cache_entry_new (bg, SLIDESHOW, filename);
ent->u.slideshow = show;
}
static GdkPixbuf *
-get_as_pixbuf (GnomeBG *bg, const char *uri)
+get_as_pixbuf (GnomeBG *bg, const char *filename)
{
const FileCacheEntry *ent;
- if ((ent = file_cache_lookup (bg, PIXBUF, uri))) {
+ if ((ent = file_cache_lookup (bg, PIXBUF, filename))) {
return ent->u.pixbuf;
}
else {
- GdkPixbuf *pixbuf = gnome_gdk_pixbuf_new_from_uri (uri);
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
if (pixbuf)
- file_cache_add_pixbuf (bg, uri, pixbuf);
+ file_cache_add_pixbuf (bg, filename, pixbuf);
return pixbuf;
}
}
static SlideShow *
-get_as_slideshow (GnomeBG *bg, const char *uri)
+get_as_slideshow (GnomeBG *bg, const char *filename)
{
const FileCacheEntry *ent;
- if ((ent = file_cache_lookup (bg, SLIDESHOW, uri))) {
+ if ((ent = file_cache_lookup (bg, SLIDESHOW, filename))) {
return ent->u.slideshow;
}
else {
- SlideShow *show = read_slideshow_file (uri, NULL);
+ SlideShow *show = read_slideshow_file (filename, NULL);
if (show)
- file_cache_add_slide_show (bg, uri, show);
+ file_cache_add_slide_show (bg, filename, show);
return show;
}
}
static GdkPixbuf *
-get_as_thumbnail (GnomeBG *bg, GnomeThumbnailFactory *factory, const char *uri)
+get_as_thumbnail (GnomeBG *bg, GnomeThumbnailFactory *factory, const char *filename)
{
const FileCacheEntry *ent;
- if ((ent = file_cache_lookup (bg, THUMBNAIL, uri))) {
+ if ((ent = file_cache_lookup (bg, THUMBNAIL, filename))) {
return ent->u.thumbnail;
}
else {
- GdkPixbuf *thumb = create_thumbnail_for_uri (factory, uri);
+ GdkPixbuf *thumb = create_thumbnail_for_filename (factory, filename);
if (thumb)
- file_cache_add_thumbnail (bg, uri, thumb);
+ file_cache_add_thumbnail (bg, filename, thumb);
return thumb;
}
@@ -1200,7 +1370,7 @@
}
static time_t
-get_mtime (const char *uri)
+get_mtime (const char *filename)
{
GFile *file;
GFileInfo *info;
@@ -1208,8 +1378,8 @@
mtime = (time_t)-1;
- if (uri) {
- file = g_file_new_for_uri (uri);
+ if (filename) {
+ file = g_file_new_for_path (filename);
info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_QUERY_INFO_NONE, NULL, NULL);
if (info) {
@@ -1225,7 +1395,7 @@
static GdkPixbuf *
scale_thumbnail (GnomeBGPlacement placement,
- const char *uri,
+ const char *filename,
GdkPixbuf *thumb,
GdkScreen *screen,
int dest_width,
@@ -1243,13 +1413,8 @@
return g_object_ref (thumb);
}
- /* FIXME: in case of tiled, we should probably scale the pixbuf to
- * be maybe dest_width/4 pixels tall. While strictly speaking incorrect,
- * it might give a better idea of what the background would actually look
- * like.
- */
if (get_thumb_annotations (thumb, &o_width, &o_height) ||
- (uri && get_original_size (uri, &o_width, &o_height))) {
+ (filename && get_original_size (filename, &o_width, &o_height))) {
int scr_height = gdk_screen_get_height (screen);
int scr_width = gdk_screen_get_width (screen);
@@ -1264,7 +1429,23 @@
new_width = floor (thumb_width * f + 0.5);
new_height = floor (thumb_height * f + 0.5);
-
+
+ if (placement == GNOME_BG_PLACEMENT_TILED) {
+ /* Heuristic to make sure tiles don't become so small that
+ * they turn into a blur.
+ *
+ * This is strictly speaking incorrect, but the resulting
+ * thumbnail gives a much better idea what the background
+ * will actually look like.
+ */
+
+ if ((new_width < 32 || new_height < 32) &&
+ (new_width < o_width / 4 || new_height < o_height / 4)) {
+ new_width = o_width / 4;
+ new_height = o_height / 4;
+ }
+ }
+
thumb = gdk_pixbuf_scale_simple (thumb, new_width, new_height,
GDK_INTERP_BILINEAR);
}
@@ -1281,42 +1462,57 @@
int dest_width,
int dest_height)
{
- if (bg->uri) {
- GdkPixbuf *thumb = get_as_thumbnail (bg, factory, bg->uri);
+ if (bg->filename) {
+ GdkPixbuf *thumb = get_as_thumbnail (bg, factory, bg->filename);
if (thumb) {
return scale_thumbnail (
- bg->placement, bg->uri,
+ bg->placement, bg->filename,
thumb, screen, dest_width, dest_height);
}
else {
- SlideShow *show = get_as_slideshow (bg, bg->uri);
+ SlideShow *show = get_as_slideshow (bg, bg->filename);
if (show) {
double alpha;
- Slide *slide = get_current_slide (show, &alpha);
+ Slide *slide;
+
+ slideshow_ref (show);
+
+ slide = get_current_slide (show, &alpha);
if (slide->fixed) {
GdkPixbuf *tmp;
+ FileSize *fs;
- tmp = get_as_thumbnail (bg, factory, slide->file1);
+ fs = slide->file1->data;
+ tmp = get_as_thumbnail (bg, factory, fs->file);
thumb = scale_thumbnail (
- bg->placement, bg->uri,
+ bg->placement, fs->file,
tmp, screen, dest_width, dest_height);
}
else {
- GdkPixbuf *p1 = get_as_thumbnail (bg, factory, slide->file1);
- GdkPixbuf *p2 = get_as_thumbnail (bg, factory, slide->file2);
+ FileSize *fs;
+ GdkPixbuf *p1, *p2;
+
+ fs = slide->file1->data;
+ p1 = get_as_thumbnail (bg, factory, fs->file);
+
+ fs = slide->file2->data;
+ p2 = get_as_thumbnail (bg, factory, fs->file);
if (p1 && p2) {
GdkPixbuf *thumb1, *thumb2;
+ fs = slide->file1->data;
thumb1 = scale_thumbnail (
- bg->placement, bg->uri,
+ bg->placement, fs->file,
p1, screen, dest_width, dest_height);
+
+ fs = slide->file2->data;
thumb2 = scale_thumbnail (
- bg->placement, bg->uri,
+ bg->placement, fs->file,
p2, screen, dest_width, dest_height);
thumb = blend (thumb1, thumb2, alpha);
@@ -1327,6 +1523,8 @@
}
ensure_timeout (bg, slide);
+
+ slideshow_unref (show);
}
}
@@ -1336,6 +1534,51 @@
return NULL;
}
+/*
+ * Find the FileSize that best matches the given size.
+ * Do two passes; the first pass only considers FileSizes
+ * that are larger than the given size.
+ * We are looking for the image that best matches the aspect ratio.
+ * When two images have the same aspect ratio, prefer the one whose
+ * width is closer to the given width.
+ */
+static FileSize *
+find_best_size (GSList *sizes, gint width, gint height)
+{
+ GSList *s;
+ gdouble a, d, distance;
+ FileSize *best = NULL;
+ gint pass;
+
+ a = width/(gdouble)height;
+ distance = 10000.0;
+
+ for (pass = 0; pass < 2; pass++) {
+ for (s = sizes; s; s = s->next) {
+ FileSize *size = s->data;
+
+ if (pass == 0 && (size->width < width || size->height < height))
+ continue;
+
+ d = fabs (a - size->width/(gdouble)size->height);
+ if (d < distance) {
+ distance = d;
+ best = size;
+ }
+ else if (d == distance) {
+ if (abs (size->width - width) < abs (best->width - width)) {
+ best = size;
+ }
+ }
+ }
+
+ if (best)
+ break;
+ }
+
+ return best;
+}
+
static GdkPixbuf *
get_pixbuf (GnomeBG *bg)
{
@@ -1343,24 +1586,35 @@
gboolean ref = FALSE;
- if (!bg->pixbuf_cache && bg->uri) {
+ if (!bg->pixbuf_cache && bg->filename) {
ref = TRUE;
- bg->uri_mtime = get_mtime (bg->uri);
+ bg->file_mtime = get_mtime (bg->filename);
- bg->pixbuf_cache = get_as_pixbuf (bg, bg->uri);
+ bg->pixbuf_cache = get_as_pixbuf (bg, bg->filename);
if (!bg->pixbuf_cache) {
- SlideShow *show = get_as_slideshow (bg, bg->uri);
+ SlideShow *show = get_as_slideshow (bg, bg->filename);
if (show) {
double alpha;
- Slide *slide = get_current_slide (show, &alpha);
+ Slide *slide;
+
+ slideshow_ref (show);
+
+ slide = get_current_slide (show, &alpha);
if (slide->fixed) {
- bg->pixbuf_cache = get_as_pixbuf (bg, slide->file1);
+ FileSize *size;
+ size = find_best_size (slide->file1, bg->last_pixmap_width, bg->last_pixmap_height);
+ bg->pixbuf_cache = get_as_pixbuf (bg, size->file);
}
else {
- GdkPixbuf *p1 = get_as_pixbuf (bg, slide->file1);
- GdkPixbuf *p2 = get_as_pixbuf (bg, slide->file2);
+ FileSize *size;
+ GdkPixbuf *p1, *p2;
+ size = find_best_size (slide->file1, bg->last_pixmap_width, bg->last_pixmap_height);
+ p1 = get_as_pixbuf (bg, size->file);
+ size = find_best_size (slide->file2, bg->last_pixmap_width, bg->last_pixmap_height);
+ p2 = get_as_pixbuf (bg, size->file);
+
if (p1 && p2) {
bg->pixbuf_cache = blend (p1, p2, alpha);
@@ -1369,6 +1623,8 @@
}
ensure_timeout (bg, slide);
+
+ slideshow_unref (show);
}
}
}
@@ -1381,24 +1637,24 @@
static gboolean
is_different (GnomeBG *bg,
- const char *uri)
+ const char *filename)
{
- if (!uri && bg->uri) {
+ if (!filename && bg->filename) {
return TRUE;
}
- else if (uri && !bg->uri) {
+ else if (filename && !bg->filename) {
return TRUE;
}
- else if (!uri && !bg->uri) {
+ else if (!filename && !bg->filename) {
return FALSE;
}
else {
- time_t mtime = get_mtime (uri);
+ time_t mtime = get_mtime (filename);
- if (mtime != bg->uri_mtime)
+ if (mtime != bg->file_mtime)
return TRUE;
- if (strcmp (uri, bg->uri) != 0)
+ if (strcmp (filename, bg->filename) != 0)
return TRUE;
return FALSE;
@@ -1533,8 +1789,8 @@
}
static guchar *
-create_gradient (const GdkColor *c1,
- const GdkColor *c2,
+create_gradient (const GdkColor *primary,
+ const GdkColor *secondary,
int n_pixels)
{
guchar *result = g_malloc (n_pixels * 3);
@@ -1543,9 +1799,9 @@
for (i = 0; i < n_pixels; ++i) {
double ratio = (i + 0.5) / n_pixels;
- result[3 * i + 0] = ((guint16) (c1->red * (1 - ratio) + c2->red * ratio)) >> 8;
- result[3 * i + 1] = ((guint16) (c1->green * (1 - ratio) + c2->green * ratio)) >> 8;
- result[3 * i + 2] = ((guint16) (c1->blue * (1 - ratio) + c2->blue * ratio)) >> 8;
+ result[3 * i + 0] = ((guint16) (primary->red * (1 - ratio) + secondary->red * ratio)) >> 8;
+ result[3 * i + 1] = ((guint16) (primary->green * (1 - ratio) + secondary->green * ratio)) >> 8;
+ result[3 * i + 2] = ((guint16) (primary->blue * (1 - ratio) + secondary->blue * ratio)) >> 8;
}
return result;
@@ -1554,8 +1810,8 @@
static void
pixbuf_draw_gradient (GdkPixbuf *pixbuf,
gboolean horizontal,
- GdkColor *c1,
- GdkColor *c2)
+ GdkColor *primary,
+ GdkColor *secondary)
{
int width = gdk_pixbuf_get_width (pixbuf);
int height = gdk_pixbuf_get_height (pixbuf);
@@ -1564,7 +1820,7 @@
guchar *dst_limit = dst + height * rowstride;
if (horizontal) {
- guchar *gradient = create_gradient (c1, c2, width);
+ guchar *gradient = create_gradient (primary, secondary, width);
int copy_bytes_per_row = width * 3;
while (dst < dst_limit) {
@@ -1575,7 +1831,7 @@
} else {
guchar *gb, *gradient;
- gb = gradient = create_gradient (c1, c2, height);
+ gb = gradient = create_gradient (primary, secondary, height);
while (dst < dst_limit) {
int i;
guchar *d = dst;
@@ -1656,6 +1912,7 @@
}
}
+static gboolean stack_is (SlideShow *parser, const char *s1, ...);
/* Parser for fading background */
static void
@@ -1667,6 +1924,7 @@
GError **err)
{
SlideShow *parser = user_data;
+ gint i;
if (strcmp (name, "static") == 0 || strcmp (name, "transition") == 0) {
Slide *slide = g_new0 (Slide, 1);
@@ -1676,7 +1934,25 @@
g_queue_push_tail (parser->slides, slide);
}
-
+ else if (strcmp (name, "size") == 0) {
+ Slide *slide = parser->slides->tail->data;
+ FileSize *size = g_new0 (FileSize, 1);
+ for (i = 0; attr_names[i]; i++) {
+ if (strcmp (attr_names[i], "width") == 0)
+ size->width = atoi (attr_values[i]);
+ else if (strcmp (attr_names[i], "height") == 0)
+ size->height = atoi (attr_values[i]);
+ }
+ if (parser->stack->tail &&
+ (strcmp (parser->stack->tail->data, "file") == 0 ||
+ strcmp (parser->stack->tail->data, "from") == 0)) {
+ slide->file1 = g_slist_prepend (slide->file1, size);
+ }
+ else if (parser->stack->tail &&
+ strcmp (parser->stack->tail->data, "to") == 0) {
+ slide->file2 = g_slist_prepend (slide->file2, size);
+ }
+ }
g_queue_push_tail (parser->stack, g_strdup (name));
}
@@ -1735,21 +2011,6 @@
return strtol (text, NULL, 0);
}
-static char *
-make_uri (char *file)
-{
- if (g_path_is_absolute (file)) {
- char *result = g_filename_to_uri (file, NULL, NULL);
-
- g_free (file);
-
- return result;
- }
- else {
- return file;
- }
-}
-
static void
handle_text (GMarkupParseContext *context,
const gchar *text,
@@ -1759,6 +2020,8 @@
{
SlideShow *parser = user_data;
Slide *slide = parser->slides->tail? parser->slides->tail->data : NULL;
+ FileSize *fs;
+ gint i;
if (stack_is (parser, "year", "starttime", "background", NULL)) {
parser->start_tm.tm_year = parse_int (text) - 1900;
@@ -1785,28 +2048,87 @@
}
else if (stack_is (parser, "file", "static", "background", NULL) ||
stack_is (parser, "from", "transition", "background", NULL)) {
- slide->file1 = g_strdup (text);
- slide->file1 = make_uri (slide->file1);
+ for (i = 0; text[i]; i++) {
+ if (!g_ascii_isspace (text[i]))
+ break;
+ }
+ if (text[i] == 0)
+ return;
+ fs = g_new (FileSize, 1);
+ fs->width = -1;
+ fs->height = -1;
+ fs->file = g_strdup (text);
+ slide->file1 = g_slist_prepend (slide->file1, fs);
+ if (slide->file1->next != NULL)
+ parser->changes_with_size = TRUE;
+ }
+ else if (stack_is (parser, "size", "file", "static", "background", NULL) ||
+ stack_is (parser, "size", "from", "transition", "background", NULL)) {
+ fs = slide->file1->data;
+ fs->file = g_strdup (text);
+ if (slide->file1->next != NULL)
+ parser->changes_with_size = TRUE;
}
else if (stack_is (parser, "to", "transition", "background", NULL)) {
- slide->file2 = g_strdup (text);
- slide->file2 = make_uri (slide->file2);
+ for (i = 0; text[i]; i++) {
+ if (!g_ascii_isspace (text[i]))
+ break;
+ }
+ if (text[i] == 0)
+ return;
+ fs = g_new (FileSize, 1);
+ fs->width = -1;
+ fs->height = -1;
+ fs->file = g_strdup (text);
+ slide->file2 = g_slist_prepend (slide->file2, fs);
+ if (slide->file2->next != NULL)
+ parser->changes_with_size = TRUE;
}
+ else if (stack_is (parser, "size", "to", "transition", "background", NULL)) {
+ fs = slide->file2->data;
+ fs->file = g_strdup (text);
+ if (slide->file2->next != NULL)
+ parser->changes_with_size = TRUE;
+ }
+}
+
+static void
+slideshow_ref (SlideShow *show)
+{
+ show->ref_count++;
}
static void
-slideshow_free (SlideShow *show)
+slideshow_unref (SlideShow *show)
{
GList *list;
-
+ GSList *slist;
+ FileSize *size;
+
+ show->ref_count--;
+ if (show->ref_count > 0)
+ return;
+
for (list = show->slides->head; list != NULL; list = list->next) {
Slide *slide = list->data;
-
- g_free (slide->file1);
- g_free (slide->file2);
+
+ for (slist = slide->file1; slist != NULL; slist = slist->next) {
+ size = slist->data;
+ g_free (size->file);
+ g_free (size);
+ }
+ g_slist_free (slide->file1);
+
+ for (slist = slide->file2; slist != NULL; slist = slist->next) {
+ size = slist->data;
+ g_free (size->file);
+ g_free (size);
+ }
+ g_slist_free (slide->file2);
+
g_free (slide);
}
-
+
g_queue_free (show->slides);
for (list = show->stack->head; list != NULL; list = list->next) {
@@ -1825,15 +2147,26 @@
{
#if 0
GList *list;
+ GSList *slist;
for (list = show->slides->head; list != NULL; list = list->next)
{
Slide *slide = list->data;
g_print ("\nSlide: %s\n", slide->fixed? "fixed" : "transition");
- g_print ("duration: %d\n", slide->duration);
- g_print ("file1: %p %s\n", slide, slide->file1);
- g_print ("file2: %s\n", slide->file2);
+ g_print ("duration: %f\n", slide->duration);
+ g_print ("File1:\n");
+ for (slist = slide->file1; slist != NULL; slist = slist->next) {
+ FileSize *size = slist->data;
+ g_print ("\t%s (%dx%d)\n",
+ size->file, size->width, size->height);
+ }
+ g_print ("File2:\n");
+ for (slist = slide->file2; slist != NULL; slist = slist->next) {
+ FileSize *size = slist->data;
+ g_print ("\t%s (%dx%d)\n",
+ size->file, size->width, size->height);
+ }
}
#endif
}
@@ -1856,7 +2189,7 @@
}
static SlideShow *
-read_slideshow_file (const char *uri,
+read_slideshow_file (const char *filename,
GError **err)
{
GMarkupParser parser = {
@@ -1874,10 +2207,10 @@
GMarkupParseContext *context = NULL;
time_t t;
- if (!uri)
+ if (!filename)
return NULL;
- file = g_file_new_for_uri (uri);
+ file = g_file_new_for_path (filename);
if (!g_file_load_contents (file, NULL, &contents, &len, NULL, NULL)) {
g_object_unref (file);
return NULL;
@@ -1885,6 +2218,7 @@
g_object_unref (file);
show = g_new0 (SlideShow, 1);
+ show->ref_count = 1;
threadsafe_localtime ((time_t)0, &show->start_tm);
show->stack = g_queue_new ();
show->slides = g_queue_new ();
@@ -1892,13 +2226,14 @@
context = g_markup_parse_context_new (&parser, 0, show, NULL);
if (!g_markup_parse_context_parse (context, contents, len, err)) {
- slideshow_free (show);
+ slideshow_unref (show);
show = NULL;
}
- if (!g_markup_parse_context_end_parse (context, err)) {
- if (show) {
- slideshow_free (show);
+
+ if (show) {
+ if (!g_markup_parse_context_end_parse (context, err)) {
+ slideshow_unref (show);
show = NULL;
}
}
@@ -1920,47 +2255,52 @@
/* Thumbnail utilities */
static GdkPixbuf *
-create_thumbnail_for_uri (GnomeThumbnailFactory *factory,
- const char *uri)
+create_thumbnail_for_filename (GnomeThumbnailFactory *factory,
+ const char *filename)
{
- char *filename;
+ char *thumb;
time_t mtime;
- GdkPixbuf *pixbuf, *orig;
+ GdkPixbuf *orig, *result = NULL;
+ char *uri;
- mtime = get_mtime (uri);
+ mtime = get_mtime (filename);
if (mtime == (time_t)-1)
return NULL;
- filename = gnome_thumbnail_factory_lookup (factory, uri, mtime);
+ uri = g_filename_to_uri (filename, NULL, NULL);
- if (filename) {
- pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
-
- return pixbuf;
- }
+ thumb = gnome_thumbnail_factory_lookup (factory, uri, mtime);
- orig = gnome_gdk_pixbuf_new_from_uri (uri);
- if (orig) {
- int orig_width = gdk_pixbuf_get_width (orig);
- int orig_height = gdk_pixbuf_get_height (orig);
-
- pixbuf = pixbuf_scale_to_fit (orig, 128, 128);
-
- g_object_set_data_full (G_OBJECT (pixbuf), "gnome-thumbnail-height",
- g_strdup_printf ("%d", orig_height), g_free);
- g_object_set_data_full (G_OBJECT (pixbuf), "gnome-thumbnail-width",
- g_strdup_printf ("%d", orig_width), g_free);
-
- g_object_unref (orig);
-
- gnome_thumbnail_factory_save_thumbnail (factory, pixbuf, uri, mtime);
-
- return pixbuf;
+ if (thumb) {
+ result = gdk_pixbuf_new_from_file (thumb, NULL);
+ g_free (thumb);
}
-
- gnome_thumbnail_factory_create_failed_thumbnail (factory, uri, mtime);
- return NULL;
+ else {
+ orig = gdk_pixbuf_new_from_file (filename, NULL);
+ if (orig) {
+ int orig_width = gdk_pixbuf_get_width (orig);
+ int orig_height = gdk_pixbuf_get_height (orig);
+
+ result = pixbuf_scale_to_fit (orig, 128, 128);
+
+ g_object_set_data_full (G_OBJECT (result), "gnome-thumbnail-height",
+ g_strdup_printf ("%d", orig_height), g_free);
+ g_object_set_data_full (G_OBJECT (result), "gnome-thumbnail-width",
+ g_strdup_printf ("%d", orig_width), g_free);
+
+ g_object_unref (orig);
+
+ gnome_thumbnail_factory_save_thumbnail (factory, result, uri, mtime);
+ }
+ else {
+ gnome_thumbnail_factory_create_failed_thumbnail (factory, uri, mtime);
+ }
+ }
+
+ g_free (uri);
+
+ return result;
}
static gboolean
@@ -1988,3 +2328,10 @@
return FALSE;
}
+
+static gboolean
+slideshow_changes_with_size (SlideShow *show)
+{
+ return show->changes_with_size;
+}
+
Modified: branches/randr-12/libgnome-desktop/gnome-rr-config.c
==============================================================================
--- branches/randr-12/libgnome-desktop/gnome-rr-config.c (original)
+++ branches/randr-12/libgnome-desktop/gnome-rr-config.c Mon Jun 16 20:16:33 2008
@@ -1,1407 +0,0 @@
-/* gnome-rr-config.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 Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Soren Sandmann <sandmann redhat com>
- */
-
-#define GNOME_DESKTOP_USE_UNSTABLE_API
-
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-#include "libgnomeui/gnome-rr-config.h"
-#include "edid.h"
-
-#define CONFIG_BASENAME "monitors.xml"
-
-/* 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 void crtc_assignment_apply (CrtcAssignment *assign);
-static CrtcAssignment *crtc_assignment_new (GnomeRRScreen *screen,
- GnomeOutputInfo **outputs);
-static void crtc_assignment_free (CrtcAssignment *assign);
-static void output_free (GnomeOutputInfo *output);
-static GnomeOutputInfo *output_copy (GnomeOutputInfo *output);
-
-static gchar *get_old_config_filename (void);
-static gchar *get_config_filename (void);
-
-typedef struct Parser Parser;
-
-/* Parser for monitor configurations */
-struct Parser
-{
- int config_file_version;
- GnomeOutputInfo * 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_assert (parser->output == NULL);
-
- parser->output = g_new0 (GnomeOutputInfo, 1);
- parser->output->rotation = 0;
-
- for (i = 0; attr_names[i] != NULL; ++i)
- {
- if (strcmp (attr_names[i], "name") == 0)
- {
- parser->output->name = g_strdup (attr_values[i]);
- break;
- }
- }
-
- if (!parser->output->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->name = g_strdup ("default");
- }
- parser->output->connected = FALSE;
- parser->output->on = FALSE;
- }
- else if (strcmp (name, "configuration") == 0)
- {
- g_assert (parser->configuration == NULL);
-
- parser->configuration = g_new0 (GnomeRRConfig, 1);
- parser->configuration->clone = FALSE;
- parser->configuration->outputs = g_new0 (GnomeOutputInfo *, 1);
- }
- 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->rotation == 0)
- parser->output->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->outputs =
- (GnomeOutputInfo **)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->connected = TRUE;
-
- strncpy (parser->output->vendor, text, 3);
- parser->output->vendor[3] = 0;
- }
- else if (stack_is (parser, "clone", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- if (strcmp (text, "yes") == 0)
- parser->configuration->clone = TRUE;
- }
- else if (stack_is (parser, "product", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->connected = TRUE;
-
- parser->output->product = parse_int (text);
- }
- else if (stack_is (parser, "serial", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->connected = TRUE;
-
- parser->output->serial = parse_uint (text);
- }
- else if (stack_is (parser, "width", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->on = TRUE;
-
- parser->output->width = parse_int (text);
- }
- else if (stack_is (parser, "x", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->on = TRUE;
-
- parser->output->x = parse_int (text);
- }
- else if (stack_is (parser, "y", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->on = TRUE;
-
- parser->output->y = parse_int (text);
- }
- else if (stack_is (parser, "height", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->on = TRUE;
-
- parser->output->height = parse_int (text);
- }
- else if (stack_is (parser, "rate", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->on = TRUE;
-
- parser->output->rate = parse_int (text);
- }
- else if (stack_is (parser, "rotation", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- if (strcmp (text, "normal") == 0)
- {
- parser->output->rotation |= GNOME_RR_ROTATION_0;
- }
- else if (strcmp (text, "left") == 0)
- {
- parser->output->rotation |= GNOME_RR_ROTATION_90;
- }
- else if (strcmp (text, "upside_down") == 0)
- {
- parser->output->rotation |= GNOME_RR_ROTATION_180;
- }
- else if (strcmp (text, "right") == 0)
- {
- parser->output->rotation |= GNOME_RR_ROTATION_270;
- }
- }
- else if (stack_is (parser, "reflect_x", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- if (strcmp (text, "yes") == 0)
- {
- parser->output->rotation |= GNOME_RR_REFLECT_X;
- }
- }
- else if (stack_is (parser, "reflect_y", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- if (strcmp (text, "yes") == 0)
- {
- parser->output->rotation |= GNOME_RR_REFLECT_Y;
- }
- }
- else
- {
- /* Ignore other properties so we can expand the format in the future */
- }
-}
-
-static void
-parser_free (Parser *parser)
-{
- int i;
- GList *list;
-
- g_assert (parser != NULL);
-
- if (parser->output)
- output_free (parser->output);
-
- if (parser->configuration)
- gnome_rr_config_free (parser->configuration);
-
- for (i = 0; i < parser->outputs->len; ++i)
- {
- GnomeOutputInfo *output = parser->outputs->pdata[i];
-
- output_free (output);
- }
-
- g_ptr_array_free (parser->outputs, TRUE);
-
- for (i = 0; i < parser->configurations->len; ++i)
- {
- GnomeRRConfig *config = parser->configurations->pdata[i];
-
- gnome_rr_config_free (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_assert (parser->outputs);
- goto out;
- }
-
- g_assert (parser->outputs);
-
- g_ptr_array_add (parser->configurations, NULL);
- result = (GnomeRRConfig **)g_ptr_array_free (parser->configurations, FALSE);
- parser->configurations = g_ptr_array_new ();
-
- g_assert (parser->outputs);
-out:
- parser_free (parser);
-
- return result;
-}
-
-static GnomeRRConfig **
-configurations_read (GError **error)
-{
- char *filename;
- GnomeRRConfig **configs;
- GError *err;
-
- /* Try the new configuration file... */
-
- filename = get_config_filename ();
-
- err = NULL;
- configs = configurations_read_from_file (filename, &err);
-
- g_free (filename);
-
- if (g_error_matches (err, G_FILE_ERROR, G_FILE_ERROR_NOENT))
- {
- g_error_free (err);
-
- /* Okay, so try the old configuration file */
- filename = get_old_config_filename ();
- configs = configurations_read_from_file (filename, error);
- g_free (filename);
-
- return configs;
- }
-
- g_propagate_error (error, err);
- return configs;
-}
-
-GnomeRRConfig *
-gnome_rr_config_new_current (GnomeRRScreen *screen)
-{
- GnomeRRConfig *config = g_new0 (GnomeRRConfig, 1);
- GPtrArray *a = g_ptr_array_new ();
- GnomeRROutput **rr_outputs;
- int i;
- int clone_width = -1;
- int clone_height = -1;
-
- g_return_val_if_fail (screen != NULL, NULL);
-
- rr_outputs = gnome_rr_screen_list_outputs (screen);
-
- config->clone = FALSE;
-
- for (i = 0; rr_outputs[i] != NULL; ++i)
- {
- GnomeRROutput *rr_output = rr_outputs[i];
- GnomeOutputInfo *output = g_new0 (GnomeOutputInfo, 1);
- GnomeRRMode *mode = NULL;
- const guint8 *edid_data = gnome_rr_output_get_edid_data (rr_output);
- GnomeRRCrtc *crtc;
-
- output->name = g_strdup (gnome_rr_output_get_name (rr_output));
- output->connected = gnome_rr_output_is_connected (rr_output);
-
- if (!output->connected)
- {
- output->x = -1;
- output->y = -1;
- output->width = -1;
- output->height = -1;
- output->rate = -1;
- output->rotation = GNOME_RR_ROTATION_0;
- }
- else
- {
- MonitorInfo *info = NULL;
-
- if (edid_data)
- info = decode_edid (edid_data);
-
- if (info)
- {
- memcpy (output->vendor, info->manufacturer_code,
- sizeof (output->vendor));
-
- output->product = info->product_code;
- output->serial = info->serial_number;
- output->aspect = info->aspect_ratio;
- }
- else
- {
- strcpy (output->vendor, "???");
- output->product = 0;
- output->serial = 0;
- }
-
- output->display_name = make_display_name (
- gnome_rr_output_get_name (rr_output), 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->on = TRUE;
-
- gnome_rr_crtc_get_position (crtc, &output->x, &output->y);
- output->width = gnome_rr_mode_get_width (mode);
- output->height = gnome_rr_mode_get_height (mode);
- output->rate = gnome_rr_mode_get_freq (mode);
- output->rotation = gnome_rr_crtc_get_current_rotation (crtc);
-
- if (output->x == 0 && output->y == 0) {
- if (clone_width == -1) {
- clone_width = output->width;
- clone_height = output->height;
- } else if (clone_width == output->width &&
- clone_height == output->height) {
- config->clone = TRUE;
- }
- }
- }
- else
- {
- output->on = FALSE;
- config->clone = FALSE;
- }
-
- /* Get preferred size for the monitor */
- mode = 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->pref_width = gnome_rr_mode_get_width (mode);
- output->pref_height = gnome_rr_mode_get_height (mode);
- }
- else
- {
- /* Pick some random numbers. This should basically never happen */
- output->pref_width = 1024;
- output->pref_height = 768;
- }
- }
-
- g_ptr_array_add (a, output);
- }
-
- g_ptr_array_add (a, NULL);
-
- config->outputs = (GnomeOutputInfo **)g_ptr_array_free (a, FALSE);
-
- g_assert (gnome_rr_config_match (config, config));
-
- return config;
-}
-
-static void
-output_free (GnomeOutputInfo *output)
-{
- if (output->display_name)
- g_free (output->display_name);
-
- if (output->name)
- g_free (output->name);
-
- g_free (output);
-}
-
-static GnomeOutputInfo *
-output_copy (GnomeOutputInfo *output)
-{
- GnomeOutputInfo *copy = g_new0 (GnomeOutputInfo, 1);
-
- *copy = *output;
-
- copy->name = g_strdup (output->name);
- copy->display_name = g_strdup (output->display_name);
-
- return copy;
-}
-
-static void
-outputs_free (GnomeOutputInfo **outputs)
-{
- int i;
-
- g_assert (outputs != NULL);
-
- for (i = 0; outputs[i] != NULL; ++i)
- output_free (outputs[i]);
-}
-
-void
-gnome_rr_config_free (GnomeRRConfig *config)
-{
- g_return_if_fail (config != NULL);
- outputs_free (config->outputs);
-
- g_free (config);
-}
-
-static void
-configurations_free (GnomeRRConfig **configurations)
-{
- int i;
-
- g_assert (configurations != NULL);
-
- for (i = 0; configurations[i] != NULL; ++i)
- gnome_rr_config_free (configurations[i]);
-
- g_free (configurations);
-}
-
-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 (GnomeOutputInfo *output1, GnomeOutputInfo *output2)
-{
- g_assert (output1 != NULL);
- g_assert (output2 != NULL);
-
- if (strcmp (output1->name, output2->name) != 0)
- return FALSE;
-
- if (strcmp (output1->vendor, output2->vendor) != 0)
- return FALSE;
-
- if (output1->product != output2->product)
- return FALSE;
-
- if (output1->serial != output2->serial)
- return FALSE;
-
- if (output1->connected != output2->connected)
- return FALSE;
-
- return TRUE;
-}
-
-static GnomeOutputInfo *
-find_output (GnomeRRConfig *config, const char *name)
-{
- int i;
-
- for (i = 0; config->outputs[i] != NULL; ++i)
- {
- GnomeOutputInfo *output = config->outputs[i];
-
- if (strcmp (name, output->name) == 0)
- return output;
- }
-
- return NULL;
-}
-
-gboolean
-gnome_rr_config_match (GnomeRRConfig *c1, GnomeRRConfig *c2)
-{
- int i;
-
- for (i = 0; c1->outputs[i] != NULL; ++i)
- {
- GnomeOutputInfo *output1 = c1->outputs[i];
- GnomeOutputInfo *output2;
-
- output2 = find_output (c2, output1->name);
- if (!output2 || !output_match (output1, output2))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static GnomeOutputInfo **
-make_outputs (GnomeRRConfig *config)
-{
- GPtrArray *outputs;
- GnomeOutputInfo *first_on;;
- int i;
-
- outputs = g_ptr_array_new ();
-
- first_on = NULL;
-
- for (i = 0; config->outputs[i] != NULL; ++i)
- {
- GnomeOutputInfo *old = config->outputs[i];
- GnomeOutputInfo *new = output_copy (old);
-
- if (old->on && !first_on)
- first_on = old;
-
- if (config->clone && new->on)
- {
- g_assert (first_on);
-
- new->width = first_on->width;
- new->height = first_on->height;
- new->rotation = first_on->rotation;
- new->x = 0;
- new->y = 0;
- }
-
- g_ptr_array_add (outputs, new);
- }
-
- g_ptr_array_add (outputs, NULL);
-
- return (GnomeOutputInfo **)g_ptr_array_free (outputs, FALSE);
-}
-
-gboolean
-gnome_rr_config_applicable (GnomeRRConfig *configuration,
- GnomeRRScreen *screen)
-{
- GnomeOutputInfo **outputs = make_outputs (configuration);
- CrtcAssignment *assign = crtc_assignment_new (screen, outputs);
- gboolean result;
-
- if (assign)
- {
- result = TRUE;
- crtc_assignment_free (assign);
- }
- else
- {
- result = FALSE;
- }
-
- outputs_free (outputs);
-
- return result;
-}
-
-static GnomeRRConfig *
-gnome_rr_config_find (GnomeRRConfig **haystack,
- GnomeRRConfig *needle)
-{
- int i;
-
- for (i = 0; haystack[i] != NULL; ++i)
- {
- if (gnome_rr_config_match (haystack[i], needle))
- return haystack[i];
- }
-
- return NULL;
-}
-
-/* Database management */
-
-static gchar *
-get_old_config_filename (void)
-{
- return g_build_filename (g_get_home_dir(), ".gnome2", CONFIG_BASENAME, NULL);
-}
-
-static gchar *
-get_config_filename (void)
-{
- return g_build_filename (g_get_user_config_dir (), CONFIG_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->clone));
-
- for (j = 0; config->outputs[j] != NULL; ++j)
- {
- GnomeOutputInfo *output = config->outputs[j];
-
- g_string_append_printf (
- string, " <output name=\"%s\">\n", output->name);
-
- if (output->connected && *output->vendor != '\0')
- {
- g_string_append_printf (
- string, " <vendor>%s</vendor>\n", output->vendor);
- g_string_append_printf (
- string, " <product>0x%04x</product>\n", output->product);
- g_string_append_printf (
- string, " <serial>0x%08x</serial>\n", output->serial);
- }
-
- /* An unconnected output which is on does not make sense */
- if (output->connected && output->on)
- {
- g_string_append_printf (
- string, " <width>%d</width>\n", output->width);
- g_string_append_printf (
- string, " <height>%d</height>\n", output->height);
- g_string_append_printf (
- string, " <rate>%d</rate>\n", output->rate);
- g_string_append_printf (
- string, " <x>%d</x>\n", output->x);
- g_string_append_printf (
- string, " <y>%d</y>\n", output->y);
- g_string_append_printf (
- string, " <rotation>%s</rotation>\n", get_rotation_name (output->rotation));
- g_string_append_printf (
- string, " <reflect_x>%s</reflect_x>\n", get_reflect_x (output->rotation));
- g_string_append_printf (
- string, " <reflect_y>%s</reflect_y>\n", get_reflect_y (output->rotation));
- }
-
- 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;
-
- /* 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->outputs[i]; ++i)
- {
- GnomeOutputInfo *output = config->outputs[i];
-
- if (output->on)
- {
- x_offset = MIN (x_offset, output->x);
- y_offset = MIN (y_offset, output->y);
- }
- }
-
- for (i = 0; config->outputs[i]; ++i)
- {
- GnomeOutputInfo *output = config->outputs[i];
-
- if (output->on)
- {
- output->x -= x_offset;
- output->y -= y_offset;
- }
- }
-}
-
-
-gboolean
-gnome_rr_config_save (GnomeRRConfig *configuration, GError **err)
-{
- GnomeRRConfig **configurations;
- GString *output = g_string_new("");
- int i;
- gchar *filename;
- gboolean result;
-
- configurations = configurations_read (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);
- }
-
- configurations_free (configurations);
- }
-
- emit_configuration (configuration, output);
-
- g_string_append_printf (output, "</monitors>\n");
-
- filename = get_config_filename ();
- result = g_file_set_contents (filename, output->str, -1, err);
- g_free (filename);
-
- if (result)
- {
- /* Only remove the old config file if we were successful in saving the new one */
-
- filename = get_old_config_filename ();
- if (g_file_test (filename, G_FILE_TEST_EXISTS))
- g_unlink (filename);
-
- g_free (filename);
- }
-
- return result;
-}
-
-static gboolean
-apply_configuration (GnomeRRConfig *conf, GnomeRRScreen *screen)
-{
- CrtcAssignment *assignment;
- GnomeOutputInfo **outputs;
-
- outputs = make_outputs (conf);
-
- assignment = crtc_assignment_new (screen, outputs);
-
- outputs_free (outputs);
-
- if (assignment)
- {
- crtc_assignment_apply (assignment);
-
- crtc_assignment_free (assignment);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-gboolean
-gnome_rr_config_apply_stored (GnomeRRScreen *screen)
-{
- GnomeRRConfig **configs = configurations_read (NULL); /* NULL-GError */
- GnomeRRConfig *current;
- GnomeRRConfig *found;
- gboolean result = TRUE;
-
- if (!screen)
- return FALSE;
-
- gnome_rr_screen_refresh (screen);
-
- current = gnome_rr_config_new_current (screen);
- if (configs)
- {
- if ((found = gnome_rr_config_find (configs, current)))
- {
- apply_configuration (found, screen);
- result = TRUE;
- }
- else
- {
- result = FALSE;
- }
-
- configurations_free (configs);
- }
-
- gnome_rr_config_free (current);
-
- return result;
-}
-
-
-/*
- * CRTC assignment
- */
-typedef struct CrtcInfo CrtcInfo;
-
-struct CrtcInfo
-{
- GnomeRRMode *mode;
- int x;
- int y;
- GnomeRRRotation rotation;
- GPtrArray *outputs;
-};
-
-struct CrtcAssignment
-{
- GnomeRRScreen *screen;
- GHashTable *info;
-};
-
-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,
- GnomeRROutput *output)
-{
- /* FIXME: We should reject stuff that is outside the screen ranges */
-
- CrtcInfo *info = g_hash_table_lookup (assign->info, crtc);
-
- if (!gnome_rr_crtc_can_drive_output (crtc, output) ||
- !gnome_rr_output_supports_mode (output, mode) ||
- !gnome_rr_crtc_supports_rotation (crtc, rotation))
- {
- return FALSE;
- }
-
- if (info)
- {
- if (info->mode == mode &&
- info->x == x &&
- info->y == y &&
- info->rotation == rotation &&
- can_clone (info, output))
- {
- g_ptr_array_add (info->outputs, 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);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-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 (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);
-}
-
-static void
-configure_crtc (gpointer key,
- gpointer value,
- gpointer data)
-{
- GnomeRRCrtc *crtc = key;
- CrtcInfo *info = value;
-
- gnome_rr_crtc_set_config (crtc,
- info->x, info->y,
- info->mode,
- info->rotation,
- (GnomeRROutput **)info->outputs->pdata,
- info->outputs->len);
-}
-
-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
-crtc_assignment_apply (CrtcAssignment *assign)
-{
- GList *active_crtcs = g_hash_table_get_keys (assign->info);
- GnomeRRCrtc **all_crtcs = gnome_rr_screen_list_crtcs (assign->screen);
- GList *list;
- int width, height;
- int i;
- int min_width, max_width, min_height, max_height;
- int width_mm, height_mm;
-
- /* 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);
-
- gnome_rr_screen_get_ranges (
- assign->screen, &min_width, &max_width, &min_height, &max_height);
-
- width = MAX (min_width, width);
- width = MIN (max_width, width);
- height = MAX (min_height, height);
- height = MIN (max_height, height);
-
- /* Turn off all crtcs currently displaying outside the new screen */
- 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)
- gnome_rr_crtc_set_config (crtc, 0, 0, NULL, GNOME_RR_ROTATION_0, NULL, 0);
- }
- }
-
- /* Turn off all CRTC's that are not in the assignment */
- for (i = 0; all_crtcs[i] != NULL; ++i)
- {
- GnomeRRCrtc *crtc = all_crtcs[i];
-
- if (!g_hash_table_lookup (assign->info, crtc))
- gnome_rr_crtc_set_config (crtc, 0, 0, NULL, GNOME_RR_ROTATION_0, NULL, 0);
- }
-
- /* 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.
- */
- width_mm = (width / 96.0) * 25.4 + 0.5;
- height_mm = (height / 96.0) * 25.4 + 0.5;
-
- gnome_rr_screen_set_size (assign->screen, width, height, width_mm, height_mm);
-
- g_hash_table_foreach (assign->info, configure_crtc, NULL);
-}
-
-/* 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,
- GnomeOutputInfo **outputs,
- CrtcAssignment *assignment)
-{
- GnomeRRCrtc **crtcs = gnome_rr_screen_list_crtcs (screen);
- GnomeOutputInfo *output;
- int i;
-
- output = *outputs;
- if (!output)
- return TRUE;
-
- /* It is always allowed for an output to be turned off */
- if (!output->on)
- {
- return real_assign_crtcs (screen, outputs + 1, assignment);
- }
-
- for (i = 0; crtcs[i] != NULL; ++i)
- {
- int pass;
-
- /* Make two passses, one where frequencies must match, then
- * one where they don't have to
- */
- for (pass = 0; pass < 2; ++pass)
- {
- GnomeRRCrtc *crtc = crtcs[i];
- GnomeRROutput *gnome_rr_output =
- gnome_rr_screen_get_output_by_name (screen, output->name);
- GnomeRRMode **modes = gnome_rr_output_list_modes (gnome_rr_output);
- int j;
-
- for (j = 0; modes[j] != NULL; ++j)
- {
- GnomeRRMode *mode = modes[j];
-
- if (gnome_rr_mode_get_width (mode) == output->width &&
- gnome_rr_mode_get_height (mode) == output->height &&
- (pass == 1 || gnome_rr_mode_get_freq (mode) == output->rate))
- {
- if (crtc_assignment_assign (
- assignment, crtc, modes[j],
- output->x, output->y,
- output->rotation,
- gnome_rr_output))
- {
- if (real_assign_crtcs (screen, outputs + 1, assignment))
- return TRUE;
-
- crtc_assignment_unassign (assignment, crtc, gnome_rr_output);
- }
- }
- }
- }
- }
-
- return FALSE;
-}
-
-static void
-crtc_info_free (CrtcInfo *info)
-{
- g_ptr_array_free (info->outputs, TRUE);
- g_free (info);
-}
-
-static CrtcAssignment *
-crtc_assignment_new (GnomeRRScreen *screen, GnomeOutputInfo **outputs)
-{
- 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))
- {
- assignment->screen = screen;
-
- return assignment;
- }
- else
- {
- crtc_assignment_free (assignment);
-
- return NULL;
- }
-}
Modified: branches/randr-12/libgnome-desktop/gnome-rr.c
==============================================================================
--- branches/randr-12/libgnome-desktop/gnome-rr.c (original)
+++ branches/randr-12/libgnome-desktop/gnome-rr.c Mon Jun 16 20:16:33 2008
@@ -1,1215 +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 Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Soren Sandmann <sandmann redhat com>
- */
-
-#define GNOME_DESKTOP_USE_UNSTABLE_API
-
-#include "libgnomeui/gnome-rr.h"
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/Xrandr.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include <X11/Xatom.h>
-
-#define DISPLAY(o) ((o)->info->screen->xdisplay)
-
-typedef struct ScreenInfo ScreenInfo;
-
-struct ScreenInfo
-{
- int min_width;
- int max_width;
- int min_height;
- int max_height;
-
- XRRScreenResources *resources;
-
- GnomeRROutput ** outputs;
- GnomeRRCrtc ** crtcs;
- GnomeRRMode ** modes;
-
- GnomeRRScreen * screen;
-};
-
-struct GnomeRRScreen
-{
- GdkScreen * gdk_screen;
- GdkWindow * gdk_root;
- Display * xdisplay;
- Screen * xscreen;
- Window xroot;
- ScreenInfo * info;
-
- int randr_event_base;
-
- GnomeRRScreenChanged callback;
- gpointer data;
-};
-
-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;
-};
-
-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;
-};
-
-struct GnomeRRMode
-{
- ScreenInfo * info;
- RRMode id;
- char * name;
- int width;
- int height;
- int freq; /* in mHz */
-};
-
-/* GnomeRRCrtc */
-static GnomeRRCrtc * crtc_new (ScreenInfo *info,
- RRCrtc id);
-static void crtc_free (GnomeRRCrtc *crtc);
-static void crtc_initialize (GnomeRRCrtc *crtc,
- XRRScreenResources *res);
-
-/* GnomeRROutput */
-static GnomeRROutput *output_new (ScreenInfo *info,
- RROutput id);
-static void output_initialize (GnomeRROutput *output,
- XRRScreenResources *res);
-static void output_free (GnomeRROutput *output);
-
-/* GnomeRRMode */
-static GnomeRRMode * mode_new (ScreenInfo *info,
- RRMode id);
-static void mode_initialize (GnomeRRMode *mode,
- XRRModeInfo *info);
-static void mode_free (GnomeRRMode *mode);
-
-
-/* Screen */
-static GnomeRROutput *
-gnome_rr_output_by_id (ScreenInfo *info, RROutput id)
-{
- GnomeRROutput **output;
-
- g_assert (info != NULL);
-
- for (output = info->outputs; *output; ++output)
- {
- if ((*output)->id == id)
- return *output;
- }
-
- return NULL;
-}
-
-static 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;
-}
-
-static GnomeRRMode *
-mode_by_id (ScreenInfo *info, RRMode id)
-{
- GnomeRRMode **mode;
-
- g_assert (info != NULL);
-
- for (mode = info->modes; *mode; ++mode)
- {
- if ((*mode)->id == id)
- return *mode;
- }
-
- return NULL;
-}
-
-static void
-screen_info_free (ScreenInfo *info)
-{
- GnomeRROutput **output;
- GnomeRRCrtc **crtc;
- GnomeRRMode **mode;
-
- g_assert (info != NULL);
-
- if (info->resources)
- {
- XRRFreeScreenResources (info->resources);
-
- info->resources = NULL;
- }
-
- 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);
- }
-
- g_free (info);
-}
-
-static gboolean
-fill_out_screen_info (Display *xdisplay,
- Window xroot,
- ScreenInfo *info)
-{
- XRRScreenResources *resources;
-
- g_assert (xdisplay != NULL);
- g_assert (info != NULL);
-
- gdk_error_trap_push ();
-
- if (!XRRGetScreenSizeRange (xdisplay, xroot,
- &(info->min_width),
- &(info->min_height),
- &(info->max_width),
- &(info->max_height))) {
- /* XRR caught an error */
- return False;
- }
-
- gdk_flush ();
- if (gdk_error_trap_pop ())
- {
- /* Unhandled X Error was generated */
- return False;
- }
-
-#if 0
- g_print ("ranges: %d - %d; %d - %d\n",
- screen->min_width, screen->max_width,
- screen->min_height, screen->max_height);
-#endif
-
- resources = XRRGetScreenResources (xdisplay, xroot);
-
- if (resources)
- {
- int i;
- GPtrArray *a;
- GnomeRRCrtc **crtc;
- GnomeRROutput **output;
-
-#if 0
- g_print ("Resource Timestamp: %u\n", (guint32)resources->timestamp);
- g_print ("Resource Configuration Timestamp: %u\n", (guint32)resources->configTimestamp);
-#endif
-
- 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)
- crtc_initialize (*crtc, resources);
-
- for (output = info->outputs; *output; ++output)
- output_initialize (*output, resources);
-
- for (i = 0; i < resources->nmode; ++i)
- {
- GnomeRRMode *mode = mode_by_id (info, resources->modes[i].id);
-
- mode_initialize (mode, &(resources->modes[i]));
- }
-
- return TRUE;
- }
- else
- {
- g_print ("Couldn't get screen resources\n");
-
- return FALSE;
- }
-}
-
-static ScreenInfo *
-screen_info_new (GnomeRRScreen *screen)
-{
- ScreenInfo *info = g_new0 (ScreenInfo, 1);
-
- g_assert (screen != NULL);
-
- info->outputs = NULL;
- info->crtcs = NULL;
- info->modes = NULL;
- info->screen = screen;
-
- if (fill_out_screen_info (screen->xdisplay, screen->xroot, info))
- {
- return info;
- }
- else
- {
- g_free (info);
- return NULL;
- }
-}
-
-static gboolean
-screen_update (GnomeRRScreen *screen, gboolean force_callback)
-{
- ScreenInfo *info;
- gboolean changed = FALSE;
-
- g_assert (screen != NULL);
-
- info = screen_info_new (screen);
- if (info)
- {
- if (info->resources->configTimestamp != screen->info->resources->configTimestamp)
- changed = TRUE;
-
- screen_info_free (screen->info);
-
- screen->info = info;
- }
-
- if ((changed || force_callback) && screen->callback)
- screen->callback (screen, screen->data);
-
- return changed;
-}
-
-static GdkFilterReturn
-screen_on_event (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
-{
- GnomeRRScreen *screen = data;
- XEvent *e = xevent;
-
- if (e && e->type - screen->randr_event_base == RRNotify)
- {
- XRRNotifyEvent *event = (XRRNotifyEvent *)e;
-
- switch (event->subtype)
- {
- default:
- break;
- }
-
- /* FIXME: we may need to be more discriminating in
- * what causes 'changed' events
- */
- screen_update (screen, TRUE);
- }
-
- /* Pass the event on to GTK+ */
- return GDK_FILTER_CONTINUE;
-}
-
-/* Returns NULL if screen could not be created. For instance, if
- * the driver does not support Xrandr 1.2.
- */
-GnomeRRScreen *
-gnome_rr_screen_new (GdkScreen *gdk_screen,
- GnomeRRScreenChanged callback,
- gpointer data)
-{
- Display *dpy = GDK_SCREEN_XDISPLAY (gdk_screen);
- int event_base;
- int ignore;
-
- if (XRRQueryExtension (dpy, &event_base, &ignore))
- {
- GnomeRRScreen *screen = g_new0 (GnomeRRScreen, 1);
-
- screen->gdk_screen = gdk_screen;
- screen->gdk_root = gdk_screen_get_root_window (gdk_screen);
- screen->xroot = gdk_x11_drawable_get_xid (screen->gdk_root);
- screen->xdisplay = dpy;
- screen->xscreen = gdk_x11_screen_get_xscreen (screen->gdk_screen);
-
- screen->callback = callback;
- screen->data = data;
-
- screen->randr_event_base = event_base;
-
- screen->info = screen_info_new (screen);
-
- if (!screen->info)
- return NULL;
-
- XRRSelectInput (screen->xdisplay,
- screen->xroot,
- RRScreenChangeNotifyMask |
- RRCrtcChangeNotifyMask |
- RROutputPropertyNotifyMask);
-
- gdk_x11_register_standard_event_type (
- gdk_screen_get_display (gdk_screen),
- event_base,
- RRNotify + 1);
-
- gdk_window_add_filter (screen->gdk_root, screen_on_event, screen);
- return screen;
- }
-
- return NULL;
-}
-
-void
-gnome_rr_screen_set_size (GnomeRRScreen *screen,
- int width,
- int height,
- int mm_width,
- int mm_height)
-{
- g_return_if_fail (screen != NULL);
-
- XRRSetScreenSize (screen->xdisplay, screen->xroot,
- width, height, mm_width, mm_height);
-}
-
-void
-gnome_rr_screen_get_ranges (GnomeRRScreen *screen,
- int *min_width,
- int *max_width,
- int *min_height,
- int *max_height)
-{
- g_return_if_fail (screen != NULL);
-
- if (min_width)
- *min_width = screen->info->min_width;
-
- if (max_width)
- *max_width = screen->info->max_width;
-
- if (min_height)
- *min_height = screen->info->min_height;
-
- if (max_height)
- *max_height = screen->info->max_height;
-}
-
-gboolean
-gnome_rr_screen_refresh (GnomeRRScreen *screen)
-{
- return screen_update (screen, FALSE);
-}
-
-GnomeRRMode **
-gnome_rr_screen_list_modes (GnomeRRScreen *screen)
-{
- g_return_val_if_fail (screen != NULL, NULL);
- g_return_val_if_fail (screen->info != NULL, NULL);
-
- return screen->info->modes;
-}
-
-GnomeRRCrtc **
-gnome_rr_screen_list_crtcs (GnomeRRScreen *screen)
-{
- g_return_val_if_fail (screen != NULL, NULL);
- g_return_val_if_fail (screen->info != NULL, NULL);
-
- return screen->info->crtcs;
-}
-
-GnomeRROutput **
-gnome_rr_screen_list_outputs (GnomeRRScreen *screen)
-{
- g_return_val_if_fail (screen != NULL, NULL);
- g_return_val_if_fail (screen->info != NULL, NULL);
-
- return screen->info->outputs;
-}
-
-GnomeRRCrtc *
-gnome_rr_screen_get_crtc_by_id (GnomeRRScreen *screen,
- guint32 id)
-{
- int i;
-
- g_return_val_if_fail (screen != NULL, NULL);
- g_return_val_if_fail (screen->info != NULL, NULL);
-
- for (i = 0; screen->info->crtcs[i] != NULL; ++i)
- {
- if (screen->info->crtcs[i]->id == id)
- return screen->info->crtcs[i];
- }
-
- return NULL;
-}
-
-GnomeRROutput *
-gnome_rr_screen_get_output_by_id (GnomeRRScreen *screen,
- guint32 id)
-{
- int i;
-
- g_return_val_if_fail (screen != NULL, NULL);
- g_return_val_if_fail (screen->info != NULL, NULL);
-
- for (i = 0; screen->info->outputs[i] != NULL; ++i)
- {
- if (screen->info->outputs[i]->id == id)
- return screen->info->outputs[i];
- }
-
- return NULL;
-}
-
-/* GnomeRROutput */
-static GnomeRROutput *
-output_new (ScreenInfo *info, RROutput id)
-{
- GnomeRROutput *output = g_new0 (GnomeRROutput, 1);
-
- output->id = id;
- output->info = info;
-
- return output;
-}
-
-static guint8 *
-get_property (Display *dpy,
- RROutput output,
- Atom atom,
- int *len)
-{
- 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;
-}
-
-static guint8 *
-read_edid_data (GnomeRROutput *output)
-{
- Atom edid_atom = XInternAtom (DISPLAY (output), "EDID_DATA", FALSE);
- guint8 *result;
- int len;
-
- result = get_property (DISPLAY (output),
- output->id, edid_atom, &len);
-
- if (result)
- {
- if (len == 128)
- return result;
- else
- g_free (result);
- }
-
- return NULL;
-}
-
-static void
-output_initialize (GnomeRROutput *output, XRRScreenResources *res)
-{
- XRROutputInfo *info = XRRGetOutputInfo (
- DISPLAY (output), res, output->id);
- GPtrArray *a;
- int i;
-
- g_print ("Output %lx Timestamp: %u\n", output->id, (guint32)info->timestamp);
-
- if (!info || !output->info)
- {
- /* FIXME */
- return;
- }
-
- 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);
-
- /* 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);
-
- XRRFreeOutputInfo (info);
-}
-
-static void
-output_free (GnomeRROutput *output)
-{
- g_free (output);
-}
-
-guint32
-gnome_rr_output_get_id (GnomeRROutput *output)
-{
- g_assert(output != NULL);
-
- 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;
-}
-
-GnomeRROutput *
-gnome_rr_screen_get_output_by_name (GnomeRRScreen *screen,
- const char *name)
-{
- int i;
-
- g_return_val_if_fail (screen != NULL, NULL);
- g_return_val_if_fail (screen->info != NULL, NULL);
-
- for (i = 0; screen->info->outputs[i] != NULL; ++i)
- {
- GnomeRROutput *output = screen->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;
-}
-
-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_assert (output != NULL);
- return output->name;
-}
-
-int
-gnome_rr_output_get_width_mm (GnomeRROutput *output)
-{
- g_assert (output != NULL);
- return output->width_mm;
-}
-
-int
-gnome_rr_output_get_height_mm (GnomeRROutput *output)
-{
- g_assert (output != NULL);
- 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;
-}
-
-/* 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;
-}
-
-gboolean
-gnome_rr_crtc_set_config (GnomeRRCrtc *crtc,
- int x,
- int y,
- GnomeRRMode *mode,
- GnomeRRRotation rotation,
- GnomeRROutput **outputs,
- int n_outputs)
-{
- ScreenInfo *info;
- GArray *output_ids;
- int i;
-
- g_return_val_if_fail (crtc != NULL, FALSE);
- g_return_val_if_fail (mode != NULL || outputs == NULL || n_outputs == 0, FALSE);
-
- info = crtc->info;
-
- if (mode)
- {
- g_return_val_if_fail (x + mode->width <= info->max_width, FALSE);
- g_return_val_if_fail (y + mode->height <= info->max_height, 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);
- }
-
- XRRSetCrtcConfig (DISPLAY (crtc), info->resources, crtc->id,
- CurrentTime,
- x, y,
- mode? mode->id : None,
- xrotation_from_rotation (rotation),
- (RROutput *)output_ids->data,
- output_ids->len);
-
- g_array_free (output_ids, TRUE);
-
- return TRUE;
-}
-
-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_assert(crtc != NULL);
- return crtc->current_rotation;
-}
-
-GnomeRRRotation
-gnome_rr_crtc_get_rotations (GnomeRRCrtc *crtc)
-{
- g_assert(crtc != NULL);
- 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);
-}
-
-static GnomeRRCrtc *
-crtc_new (ScreenInfo *info, RROutput id)
-{
- GnomeRRCrtc *crtc = g_new0 (GnomeRRCrtc, 1);
-
- crtc->id = id;
- crtc->info = info;
-
- return crtc;
-}
-
-static void
-crtc_initialize (GnomeRRCrtc *crtc,
- XRRScreenResources *res)
-{
- XRRCrtcInfo *info = XRRGetCrtcInfo (DISPLAY (crtc), res, crtc->id);
- GPtrArray *a;
- int i;
-
- g_print ("CRTC %lx Timestamp: %u\n", crtc->id, (guint32)info->timestamp);
-
- if (!info)
- {
- /* FIXME: We need to reaquire the screen resources */
- return;
- }
-
- /* 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);
-}
-
-static void
-crtc_free (GnomeRRCrtc *crtc)
-{
- g_free (crtc->current_outputs);
- g_free (crtc->possible_outputs);
- g_free (crtc);
-}
-
-/* GnomeRRMode */
-static GnomeRRMode *
-mode_new (ScreenInfo *info, RRMode id)
-{
- GnomeRRMode *mode = g_new0 (GnomeRRMode, 1);
-
- 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 void
-mode_initialize (GnomeRRMode *mode, XRRModeInfo *info)
-{
- g_assert (mode != NULL);
- g_assert (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 void
-mode_free (GnomeRRMode *mode)
-{
- g_free (mode->name);
- g_free (mode);
-}
-
-
-#ifdef INCLUDE_MAIN
-static void
-on_screen_changed (GnomeRRScreen *screen, gpointer data)
-{
- g_print ("Changed\n");
-}
-
-static gboolean
-do_refresh (gpointer data)
-{
- GnomeRRScreen *screen = data;
-
- gnome_rr_screen_refresh (screen);
-
- return TRUE;
-}
-
-int
-main (int argc, char **argv)
-{
- int i;
-
- gtk_init (&argc, &argv);
-
- GnomeRRScreen *screen = gnome_rr_screen_new (gdk_screen_get_default(),
- on_screen_changed,
- NULL);
-
- for (i = 0; screen->info->crtcs[i]; ++i)
- {
- GnomeRRCrtc *crtc = screen->info->crtcs[i];
-
- if (crtc->current_mode)
- {
- g_print ("CRTC %p: (%d %d %d %d)\n",
- crtc, crtc->x, crtc->y,
- crtc->current_mode->width, crtc->current_mode->height);
- }
- else
- {
- g_print ("CRTC %p: turned off\n", crtc);
- }
- }
-
- for (i = 0; screen->info->outputs[i]; ++i)
- {
- GnomeRROutput *output = screen->info->outputs[i];
-
- g_print ("Output %s currently", output->name);
-
- if (!output->current_crtc)
- g_print (" turned off\n");
- else
- g_print (" driven by CRTC %p\n", output->current_crtc);
- }
-
- g_timeout_add (500, do_refresh, screen);
-
- gtk_main ();
-
- return 0;
-}
-#endif
Modified: branches/randr-12/libgnome-desktop/libgnomeui/Makefile.am
==============================================================================
--- branches/randr-12/libgnome-desktop/libgnomeui/Makefile.am (original)
+++ branches/randr-12/libgnome-desktop/libgnomeui/Makefile.am Mon Jun 16 20:16:33 2008
@@ -1,7 +1,5 @@
libgnomeui_desktopdir = $(includedir)/gnome-desktop-2.0/libgnomeui
-libgnomeui_desktop_HEADERS = \
- gnome-ditem-edit.h \
- gnome-hint.h \
- gnome-bg.h \
- gnome-rr.h \
- gnome-rr-config.h
+libgnomeui_desktop_HEADERS = \
+ gnome-ditem-edit.h \
+ gnome-hint.h \
+ gnome-bg.h
Modified: branches/randr-12/libgnome-desktop/libgnomeui/gnome-bg.h
==============================================================================
--- branches/randr-12/libgnome-desktop/libgnomeui/gnome-bg.h (original)
+++ branches/randr-12/libgnome-desktop/libgnomeui/gnome-bg.h Mon Jun 16 20:16:33 2008
@@ -61,43 +61,54 @@
GNOME_BG_PLACEMENT_FILL_SCREEN
} GnomeBGPlacement;
-GType gnome_bg_get_type (void);
-GnomeBG * gnome_bg_new (void);
-
-void gnome_bg_load_from_preferences (GnomeBG *bg,
- GConfClient *client);
-
-void gnome_bg_set_placement (GnomeBG *img,
- GnomeBGPlacement placement);
-void gnome_bg_set_color (GnomeBG *img,
- GnomeBGColorType type,
- GdkColor *c1,
- GdkColor *c2);
-void gnome_bg_set_uri (GnomeBG *img,
- const char *uri);
-void gnome_bg_draw (GnomeBG *img,
- GdkPixbuf *dest);
-GdkPixmap *gnome_bg_create_pixmap (GnomeBG *img,
- GdkWindow *window,
- int width,
- int height,
- gboolean root);
-gboolean gnome_bg_get_image_size (GnomeBG *bg,
- GnomeThumbnailFactory *factory,
- int *width,
- int *height);
-GdkPixbuf *gnome_bg_create_thumbnail (GnomeBG *bg,
- GnomeThumbnailFactory *factory,
- GdkScreen *screen,
- int dest_width,
- int dest_height);
-gboolean gnome_bg_is_dark (GnomeBG *img);
-gboolean gnome_bg_changes_with_size (GnomeBG *img);
+GType gnome_bg_get_type (void);
+GnomeBG * gnome_bg_new (void);
+void gnome_bg_load_from_preferences (GnomeBG *bg,
+ GConfClient *client);
+void gnome_bg_save_to_preferences (GnomeBG *bg,
+ GConfClient *client);
+/* Setters */
+void gnome_bg_set_filename (GnomeBG *bg,
+ const char *filename);
+void gnome_bg_set_placement (GnomeBG *bg,
+ GnomeBGPlacement placement);
+void gnome_bg_set_color (GnomeBG *bg,
+ GnomeBGColorType type,
+ GdkColor *primary,
+ GdkColor *secondary);
+/* Getters */
+GnomeBGPlacement gnome_bg_get_placement (GnomeBG *bg);
+void gnome_bg_get_color (GnomeBG *bg,
+ GnomeBGColorType *type,
+ GdkColor *primary,
+ GdkColor *secondary);
+const gchar * gnome_bg_get_filename (GnomeBG *bg);
+
+/* Drawing and thumbnailing */
+void gnome_bg_draw (GnomeBG *bg,
+ GdkPixbuf *dest);
+GdkPixmap * gnome_bg_create_pixmap (GnomeBG *bg,
+ GdkWindow *window,
+ int width,
+ int height,
+ gboolean root);
+gboolean gnome_bg_get_image_size (GnomeBG *bg,
+ GnomeThumbnailFactory *factory,
+ int *width,
+ int *height);
+GdkPixbuf * gnome_bg_create_thumbnail (GnomeBG *bg,
+ GnomeThumbnailFactory *factory,
+ GdkScreen *screen,
+ int dest_width,
+ int dest_height);
+gboolean gnome_bg_is_dark (GnomeBG *bg);
+gboolean gnome_bg_changes_with_size (GnomeBG *bg);
/* Set a pixmap as root - not a GnomeBG method */
-void gnome_bg_set_pixmap_as_root (GdkScreen *screen,
- GdkPixmap *pixmap);
+void gnome_bg_set_pixmap_as_root (GdkScreen *screen,
+ GdkPixmap *pixmap);
+
G_END_DECLS
Modified: branches/randr-12/libgnome-desktop/libgnomeui/gnome-rr-config.h
==============================================================================
--- branches/randr-12/libgnome-desktop/libgnomeui/gnome-rr-config.h (original)
+++ branches/randr-12/libgnome-desktop/libgnomeui/gnome-rr-config.h Mon Jun 16 20:16:33 2008
@@ -1,79 +0,0 @@
-/* gnome-rr-config.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 Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Soren Sandmann <sandmann redhat com>
- */
-#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 <libgnomeui/gnome-rr.h>
-#include <glib.h>
-
-typedef struct GnomeOutputInfo GnomeOutputInfo;
-typedef struct GnomeRRConfig GnomeRRConfig;
-
-struct GnomeOutputInfo
-{
- char * name;
-
- gboolean on;
- int width;
- int height;
- int rate;
- int x;
- int y;
- GnomeRRRotation rotation;
-
- gboolean connected;
- char vendor[4];
- guint product;
- guint serial;
- double aspect;
- int pref_width;
- int pref_height;
- char * display_name;
-
- gpointer user_data;
-};
-
-struct GnomeRRConfig
-{
- gboolean clone;
-
- GnomeOutputInfo ** outputs;
-};
-
-GnomeRRConfig *gnome_rr_config_new_current (GnomeRRScreen *screen);
-void gnome_rr_config_free (GnomeRRConfig *configuration);
-gboolean gnome_rr_config_match (GnomeRRConfig *config1,
- GnomeRRConfig *config2);
-gboolean gnome_rr_config_save (GnomeRRConfig *configuration,
- GError **err);
-void gnome_rr_config_sanitize (GnomeRRConfig *configuration);
-gboolean gnome_rr_config_apply_stored (GnomeRRScreen *screen);
-gboolean gnome_rr_config_applicable (GnomeRRConfig *configuration,
- GnomeRRScreen *screen);
-
-#endif
Modified: branches/randr-12/libgnome-desktop/libgnomeui/gnome-rr.h
==============================================================================
--- branches/randr-12/libgnome-desktop/libgnomeui/gnome-rr.h (original)
+++ branches/randr-12/libgnome-desktop/libgnomeui/gnome-rr.h Mon Jun 16 20:16:33 2008
@@ -1,123 +0,0 @@
-/* randrwrap.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 Library General Public
- * License along with the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Soren Sandmann <sandmann redhat com>
- */
-#ifndef RANDR_WRAP_H
-#define RANDR_WRAP_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 GnomeRRScreen GnomeRRScreen;
-typedef struct GnomeRROutput GnomeRROutput;
-typedef struct GnomeRRCrtc GnomeRRCrtc;
-typedef struct GnomeRRMode GnomeRRMode;
-
-typedef void (* GnomeRRScreenChanged) (GnomeRRScreen *screen, gpointer data);
-
-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;
-
-/* GnomeRRScreen */
-GnomeRRScreen * gnome_rr_screen_new (GdkScreen *screen,
- GnomeRRScreenChanged callback,
- gpointer data);
-GnomeRROutput **gnome_rr_screen_list_outputs (GnomeRRScreen *screen);
-GnomeRRCrtc ** gnome_rr_screen_list_crtcs (GnomeRRScreen *screen);
-GnomeRRMode ** gnome_rr_screen_list_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);
-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);
-
-/* 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);
-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);
-
-/* 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);
-gboolean gnome_rr_crtc_set_config (GnomeRRCrtc *crtc,
- int x,
- int y,
- GnomeRRMode *mode,
- GnomeRRRotation rotation,
- GnomeRROutput **outputs,
- int n_outputs);
-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);
-
-#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]