+Tue Jun 17 19:51:03 2008 S�ren Sandmann <sandmann@redhat.com>
+ + * Merge randr-12 to trunk + +Tue Jun 17 18:29:46 2008 S�ren Sandmann <sandmann@redhat.com> + + * Port to changes in gnome-desktop + +2008-06-04 Federico Mena Quintero <federico@novell.com> + + * xrandr-capplet.c (driver_is_randr_10): New function, currently + unused, to detect whether the graphics driver used in the X server + only supports the RANDR 1.0 API. We may find this information + useful to tell the user that not all the features in the capplet + will work as intended, or to actually disable features that won't work. + +2008-05-29 Federico Mena Quintero <federico@novell.com> + + * xrandr-capplet.c (apply): Before applying the settings, check if + the X server supports the Virtual size we need. + (check_required_virtual_size): New function; does the checking + against what the X server supports. + This still needs to present a friendly dialog box. + (compute_virtual_size_for_configuration): New function. + +Wed May 14 18:16:10 2008 S�ren Sandmann <sandmann@redhat.com> + + * xrandr-capplet.c: Add GNOME_DESKTOP_USE_UNSTABLE_API define + + * scrollarea.[ch]: Add copyright statement + +2008-05-14 Soren Sandmann Pedersen <sandmann@redhat.com> + + * *: Check in new RandR 1.2 enabled capplet + svn path=/trunk/; revision=8762
This commit is contained in:
parent
29d0d29005
commit
324f02cea3
11 changed files with 5349 additions and 1 deletions
|
@ -901,6 +901,13 @@ wp_load_stuffs (void *user_data)
|
||||||
uri = gconf_client_get_string (data->client,
|
uri = gconf_client_get_string (data->client,
|
||||||
WP_FILE_KEY,
|
WP_FILE_KEY,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
if (uri && *uri == '\0')
|
||||||
|
{
|
||||||
|
g_free (uri);
|
||||||
|
uri = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (uri == NULL)
|
if (uri == NULL)
|
||||||
uri = g_strdup ("(none)");
|
uri = g_strdup ("(none)");
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,38 @@
|
||||||
|
Tue Jun 17 19:51:03 2008 Søren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* Merge randr-12 to trunk
|
||||||
|
|
||||||
|
Tue Jun 17 18:29:46 2008 Søren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* Port to changes in gnome-desktop
|
||||||
|
|
||||||
|
2008-06-04 Federico Mena Quintero <federico@novell.com>
|
||||||
|
|
||||||
|
* xrandr-capplet.c (driver_is_randr_10): New function, currently
|
||||||
|
unused, to detect whether the graphics driver used in the X server
|
||||||
|
only supports the RANDR 1.0 API. We may find this information
|
||||||
|
useful to tell the user that not all the features in the capplet
|
||||||
|
will work as intended, or to actually disable features that won't work.
|
||||||
|
|
||||||
|
2008-05-29 Federico Mena Quintero <federico@novell.com>
|
||||||
|
|
||||||
|
* xrandr-capplet.c (apply): Before applying the settings, check if
|
||||||
|
the X server supports the Virtual size we need.
|
||||||
|
(check_required_virtual_size): New function; does the checking
|
||||||
|
against what the X server supports.
|
||||||
|
This still needs to present a friendly dialog box.
|
||||||
|
(compute_virtual_size_for_configuration): New function.
|
||||||
|
|
||||||
|
Wed May 14 18:16:10 2008 Søren Sandmann <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* xrandr-capplet.c: Add GNOME_DESKTOP_USE_UNSTABLE_API define
|
||||||
|
|
||||||
|
* scrollarea.[ch]: Add copyright statement
|
||||||
|
|
||||||
|
2008-05-14 Soren Sandmann Pedersen <sandmann@redhat.com>
|
||||||
|
|
||||||
|
* *: Check in new RandR 1.2 enabled capplet
|
||||||
|
|
||||||
==================== 2.23.2 ====================
|
==================== 2.23.2 ====================
|
||||||
|
|
||||||
2008-02-19 Jens Granseuer <jensgr@gmx.net>
|
2008-02-19 Jens Granseuer <jensgr@gmx.net>
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
# This is used in GNOMECC_CAPPLETS_CFLAGS
|
# This is used in GNOMECC_CAPPLETS_CFLAGS
|
||||||
cappletname = display
|
cappletname = display
|
||||||
|
|
||||||
|
gladedir = $(pkgdatadir)/glade
|
||||||
|
dist_glade_DATA = display-capplet.glade
|
||||||
|
|
||||||
bin_PROGRAMS = gnome-display-properties
|
bin_PROGRAMS = gnome-display-properties
|
||||||
|
|
||||||
gnome_display_properties_SOURCES = main.c
|
gnome_display_properties_SOURCES = \
|
||||||
|
xrandr-capplet.c \
|
||||||
|
scrollarea.c \
|
||||||
|
foo-marshal.c \
|
||||||
|
scrollarea.h \
|
||||||
|
foo-marshal.h
|
||||||
|
|
||||||
gnome_display_properties_LDFLAGS = -export-dynamic
|
gnome_display_properties_LDFLAGS = -export-dynamic
|
||||||
gnome_display_properties_LDADD = \
|
gnome_display_properties_LDADD = \
|
||||||
$(DISPLAY_CAPPLET_LIBS) \
|
$(DISPLAY_CAPPLET_LIBS) \
|
||||||
|
|
815
capplets/display/TODO
Normal file
815
capplets/display/TODO
Normal file
|
@ -0,0 +1,815 @@
|
||||||
|
Highlevel overview:
|
||||||
|
|
||||||
|
- GTK+ work.
|
||||||
|
|
||||||
|
Allow applications to be notified whenever monitors are added
|
||||||
|
or removed. Allow applications to get more detailed
|
||||||
|
information about the connected monitors.
|
||||||
|
|
||||||
|
The main complication is that XRRGetScreenResources() is very
|
||||||
|
slow. We could call it only when the X server sends an event,
|
||||||
|
but it's not desirable to have every application freeze for
|
||||||
|
half a second. And certainly not desirable to have the X
|
||||||
|
server block for n * 0.5 seconds.
|
||||||
|
|
||||||
|
With the X server work below we should be fine just calling
|
||||||
|
XRRGetScreenResources on startup and in response to events.
|
||||||
|
|
||||||
|
- X server work:
|
||||||
|
|
||||||
|
X server needs to poll for whether a monitor is plugged
|
||||||
|
in. Whenever it detects a change, it should do an EDID query,
|
||||||
|
and cache the resulting information. That way XRRGetScreenResources()
|
||||||
|
can be the speed of a normal roundtrip. It's desirable that
|
||||||
|
normal client requests can still be processed during the EDID
|
||||||
|
querying, but only a nice-to-have.
|
||||||
|
|
||||||
|
Drivers need to work reliably. There could be substantial work
|
||||||
|
here. For F9, possibly only the Intel driver can be made to
|
||||||
|
work.
|
||||||
|
|
||||||
|
Interrupts and events must be generated whenever something changes
|
||||||
|
about the outputs, if necessary by polling.
|
||||||
|
|
||||||
|
Events must be emitted whenever something changes, including when
|
||||||
|
the reason for the change is a manual change.
|
||||||
|
|
||||||
|
The maximum framebuffer must be dynamically changable.
|
||||||
|
|
||||||
|
- Control panel work:
|
||||||
|
Capplet needs to be written. The main complications:
|
||||||
|
|
||||||
|
- It needs to pay attention to events from the X server
|
||||||
|
and update itself, ie., add show new monitors if they become
|
||||||
|
available when the applet is shown.
|
||||||
|
|
||||||
|
- It needs to store information under a key computed
|
||||||
|
from a monitor identifier. The complication here is that
|
||||||
|
it's not completely clear how to do this in GConf.
|
||||||
|
|
||||||
|
- Would probably be worthwhile to drop libgnome/libgnomeui from
|
||||||
|
the craplets.
|
||||||
|
|
||||||
|
- Metacity work:
|
||||||
|
- Metacity is already Xinerama aware, but it needs to update itself
|
||||||
|
when monitors come and go.
|
||||||
|
|
||||||
|
- GNOME panel work:
|
||||||
|
- Is already Xinerama aware, but needs to listen and update itself
|
||||||
|
when monitors change.
|
||||||
|
|
||||||
|
- Evince work:
|
||||||
|
- Make sure it deals sensibly with multiple monitors
|
||||||
|
|
||||||
|
- OpenOffice work:
|
||||||
|
- Make sure it deals sensibly with multiple monitors
|
||||||
|
|
||||||
|
- An Xlib call to just return all the available information would be
|
||||||
|
useful. At the moment we have to do a bunch of roundtrips to
|
||||||
|
get the information. This is a would-be-nice though.
|
||||||
|
|
||||||
|
- A dbus service could be written that pops up the applet whenever a
|
||||||
|
monitor. It should only pop up if the new monitor is unknown. This
|
||||||
|
is at best a nice-to-have, and low priority in my opinion.
|
||||||
|
|
||||||
|
|
||||||
|
******************* Metacity
|
||||||
|
|
||||||
|
Havoc:
|
||||||
|
|
||||||
|
> I was just talking to bryan about this and "helping" him design it ;-)
|
||||||
|
|
||||||
|
> But I wanted to be sure and lobby for a fix window managers
|
||||||
|
> need. Basically right now the WM can't tell "physical" from
|
||||||
|
> "logical" monitors.
|
||||||
|
|
||||||
|
> A "logical" monitor is a desktop; it has its own panel, windows
|
||||||
|
> maximize to it, etc.
|
||||||
|
|
||||||
|
> A "physical" monitor is a piece of hardware.
|
||||||
|
|
||||||
|
> Sometimes people want to combine physical monitors into a video wall
|
||||||
|
> or just two monitors treated as one. Or at least a couple of noisy
|
||||||
|
> people in bugzilla want to do this.
|
||||||
|
|
||||||
|
> When people talk about a "Xinerama aware" app or WM they usually
|
||||||
|
> mean that all physical monitors are treated as logical monitors,
|
||||||
|
> while lack of Xinerama-aware means treating the entire X screen (all
|
||||||
|
> physical monitors) as one logical monitor.
|
||||||
|
|
||||||
|
> The problem is that the setting for "ignore Xinerama" or "don't be
|
||||||
|
> Xinerama aware" should be global to the desktop (GTK, all apps, WM)
|
||||||
|
> and should not be a window manager setting.
|
||||||
|
|
||||||
|
> Bryan thought people who wanted non-Xinerama-aware should just use
|
||||||
|
> fvwm, which may be right, but what I'd say is that if there is any
|
||||||
|
> setting for this, it should be desktop-global and in this monitor
|
||||||
|
> config dialog.
|
||||||
|
|
||||||
|
> It should not be a metacity or Compiz option, but in some way an X
|
||||||
|
> option in short. The implementation could be either an X server
|
||||||
|
> feature or an EWMH hint or whatever, but it should be controlled by
|
||||||
|
> the monitor config dialog and used by apps, GTK, etc. in addition to
|
||||||
|
> used by the WM.
|
||||||
|
|
||||||
|
> People tend to insist this should be a WM option, but that's just
|
||||||
|
> busted, since GTK and apps also have Xinerama-awareness features.
|
||||||
|
|
||||||
|
|
||||||
|
******************* EDID
|
||||||
|
|
||||||
|
edid-decode enhancements:
|
||||||
|
|
||||||
|
- Rejects years <= 0x0f for all versions, but this should only be done
|
||||||
|
for monitors claiming conformance to 1.4 (since 1.4 was released in
|
||||||
|
2006). A monitor produced in 2005 should have 0x0f - it's the only
|
||||||
|
reasonable thing to do.
|
||||||
|
|
||||||
|
- Uses 0x80 as the conformance mask for 1.4, should be 0
|
||||||
|
|
||||||
|
- Should read from stdin
|
||||||
|
|
||||||
|
- Should parse xrandr -verbose output more robustly
|
||||||
|
|
||||||
|
- Color depth computation is wrong. It uses the formula
|
||||||
|
|
||||||
|
(edid[0x14] >> 3) + 2
|
||||||
|
|
||||||
|
The correct formula to use is
|
||||||
|
|
||||||
|
(edid[0x14] & 0x70) >> 3 + 4
|
||||||
|
|
||||||
|
-
|
||||||
|
|
||||||
|
-=-=-=-
|
||||||
|
Computing a display name from EDID information:
|
||||||
|
|
||||||
|
vendor = lookup_vendor (code);
|
||||||
|
|
||||||
|
if (dsc_product && !is_gobbledigook (dsc_product))
|
||||||
|
{
|
||||||
|
if (vendor && !fuzzy_string_search (vendor, dsc_product))
|
||||||
|
prepend (vendor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (vendor)
|
||||||
|
append (vendor);
|
||||||
|
else
|
||||||
|
append ("Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has size)
|
||||||
|
{
|
||||||
|
convert_to_inches()
|
||||||
|
|
||||||
|
append (" %d\"", inches)
|
||||||
|
}
|
||||||
|
|
||||||
|
(Does this internationalize at all)?
|
||||||
|
|
||||||
|
We also need the ability to get laptop names. The laptop panel may report
|
||||||
|
a manufacturer that has nothing to do with the laptop manufacturer.
|
||||||
|
|
||||||
|
Needed XRandr output properties:
|
||||||
|
|
||||||
|
- Modes that the monitor supports, or enough information that the
|
||||||
|
client can go throught the list of modes for the relevant
|
||||||
|
CRTC/Outputs and filter those out that the monitor can't support.
|
||||||
|
|
||||||
|
- The preferred mode, if any. Also useful if we could get a "strongly
|
||||||
|
preferred" indication if it's an LCD with a fixed resolution.
|
||||||
|
|
||||||
|
- Sufficient information that a fairly specific identifier can be
|
||||||
|
computed. The algorithm the client should use is:
|
||||||
|
|
||||||
|
1 Have we seen exactly this monitor before? If yes, use
|
||||||
|
settings for that.
|
||||||
|
|
||||||
|
2 Have we seen a monitor with similar specs before? If yes,
|
||||||
|
use settings for that. (But don't save, unless the user
|
||||||
|
changes the settings).
|
||||||
|
|
||||||
|
3 Otherwise, use some reasonable default for the monitor and
|
||||||
|
save it.
|
||||||
|
|
||||||
|
A setting should only be used if the CRTC/Output allows it. Ie,. if
|
||||||
|
a user has installed a new video card, then previously-used settings
|
||||||
|
may no longer apply, so this must be checked every time.
|
||||||
|
|
||||||
|
(1) Implies that we really need a globally unique identifier for
|
||||||
|
monitors. (2) is useful in an enterprise setting, but not absolutely
|
||||||
|
critical, since (3) would still handle the majority of cases.
|
||||||
|
|
||||||
|
There is a question here: Where are machine specific preferences
|
||||||
|
stored? Havoc mentions three possibilities here:
|
||||||
|
|
||||||
|
http://mail.gnome.org/archives/gnomecc-list/2001-October/msg00023.html
|
||||||
|
|
||||||
|
I'm not sure if any of them are implementable at this point. Also
|
||||||
|
(1) may mostly take care of the problem.
|
||||||
|
|
||||||
|
|
||||||
|
Usecases:
|
||||||
|
|
||||||
|
1. Fixed setup with some number of monitors.
|
||||||
|
- They should be set to the correct mode on login.
|
||||||
|
Note that this involves setting the right position in the
|
||||||
|
framebuffer too.
|
||||||
|
What if someone swaps two monitors? Users are going to expect
|
||||||
|
that the images will switch position.
|
||||||
|
|
||||||
|
2. Laptop being moved between home and work
|
||||||
|
- Setups should be detected and the correct mode set, at least on
|
||||||
|
login, but ideally when you put the laptop into the docking
|
||||||
|
station.
|
||||||
|
|
||||||
|
3. Laptop gets projector plugged in.
|
||||||
|
|
||||||
|
Note the same model monitor can be used in two different ways. Ie.,
|
||||||
|
at home, it's being used at one resolution, at work the same type of
|
||||||
|
monitor is used at a different resolution.
|
||||||
|
|
||||||
|
Simple solution:
|
||||||
|
|
||||||
|
- The on-disk database is just a list of monitors. Each monitor has an
|
||||||
|
associated mode. This has these problems:
|
||||||
|
- If someone uses the same monitor model in two different ways.
|
||||||
|
- If someone swaps the monitors around
|
||||||
|
|
||||||
|
Better solution
|
||||||
|
|
||||||
|
- The on-disk database is a list of configurations, where a
|
||||||
|
configuration is a list of monitors and what outputs they are
|
||||||
|
connected to, and the position in the framebuffer.
|
||||||
|
|
||||||
|
- Picking a default configuration is then a matter of selecting the
|
||||||
|
closest existing configuration from the database.
|
||||||
|
|
||||||
|
- If the stored configuration is a subset of the existing,
|
||||||
|
then use that - then pick the best mode available for the
|
||||||
|
rest of the monitors
|
||||||
|
|
||||||
|
- If the stored configuration is a superset of the existing,
|
||||||
|
then use the projection of the configuration onto the monitors.
|
||||||
|
|
||||||
|
- Pick the configuration with the most overlap in monitors.
|
||||||
|
Although, if a configuration differs only in what outputs
|
||||||
|
they are connected to, then those outputs should probably
|
||||||
|
get their original modes set.
|
||||||
|
|
||||||
|
- Or maybe simply:
|
||||||
|
|
||||||
|
- If there is an exact match, use it, if not, pick a default.
|
||||||
|
|
||||||
|
- Picking a new default must never change the mode of any existing
|
||||||
|
output.
|
||||||
|
|
||||||
|
******************* Capplet
|
||||||
|
|
||||||
|
Somehow the applet will find out that a new monitor is plugged in
|
||||||
|
(either through notification, or through a refresh button). When this
|
||||||
|
happens, this monitor is looked up in a database and if it is found,
|
||||||
|
some suitable mode is set.
|
||||||
|
|
||||||
|
Restrictions on the modes:
|
||||||
|
|
||||||
|
- Monitors that are already plugged in should not get their mode
|
||||||
|
changed just because a new monitor is plugged in.
|
||||||
|
|
||||||
|
- If the exact configuration of monitors is known, and all the old
|
||||||
|
monitors have the same mode as the known configuration, then just use
|
||||||
|
the known configuration. Also do this, if the configuration is a
|
||||||
|
subset of something known.
|
||||||
|
|
||||||
|
- Otherwise, if the configuration is a subset of a known configuration
|
||||||
|
where the only difference is that existing monitors have different
|
||||||
|
modes, then try and convert that mode to something we can know
|
||||||
|
about. Maybe configurations should be stored in terms of edges that
|
||||||
|
line up.
|
||||||
|
|
||||||
|
- Otherwise, just pick some good default for the mode, probably based
|
||||||
|
on the EDID prferred mode if possible. By default cloning is
|
||||||
|
probably best.
|
||||||
|
|
||||||
|
- How do virtual desktops interact with this?
|
||||||
|
|
||||||
|
|
||||||
|
g-s-d:
|
||||||
|
|
||||||
|
- On startup
|
||||||
|
|
||||||
|
- It reads the configuration file into memory
|
||||||
|
|
||||||
|
capplet --configure
|
||||||
|
|
||||||
|
- It gathers the existing configuration from randr
|
||||||
|
|
||||||
|
- If the existing config is in the file, set that mode
|
||||||
|
|
||||||
|
- On changes, including changes to the config file [this is crack]
|
||||||
|
|
||||||
|
- Reread configuration file
|
||||||
|
|
||||||
|
- Compare new configuration to database, if it is there, set the
|
||||||
|
mode as appropriate
|
||||||
|
|
||||||
|
- If a monitor was added, pop up a bubble
|
||||||
|
|
||||||
|
capplet --show-bubble
|
||||||
|
|
||||||
|
capplet --set-mode
|
||||||
|
|
||||||
|
capplet
|
||||||
|
|
||||||
|
- On changes
|
||||||
|
|
||||||
|
- Update GUI
|
||||||
|
|
||||||
|
- When user changes something,
|
||||||
|
|
||||||
|
- Write configuration to file
|
||||||
|
|
||||||
|
- Signal gsd somehow
|
||||||
|
|
||||||
|
Schemes:
|
||||||
|
- configuration file changes
|
||||||
|
- randr code will have to be shared between gcc and gsd
|
||||||
|
|
||||||
|
- binary installed by gcc
|
||||||
|
- something will still have to listen for changes to pop
|
||||||
|
up the notification bubble.
|
||||||
|
|
||||||
|
Structure of capplet:
|
||||||
|
|
||||||
|
- There is a database on disk with monitors and their corresponding
|
||||||
|
settings.
|
||||||
|
|
||||||
|
- On startup, this database is read into memory. When the user accepts
|
||||||
|
new settings, it is written back to disk.
|
||||||
|
|
||||||
|
- When something changes about the settings
|
||||||
|
|
||||||
|
- If new configuration is in the database, use that mode
|
||||||
|
|
||||||
|
- Else, find all outputs that are now connected but weren't before,
|
||||||
|
and set a default mode for them.
|
||||||
|
|
||||||
|
- If GUI is running, update graphics.
|
||||||
|
|
||||||
|
|
||||||
|
- Notification thing:
|
||||||
|
- if
|
||||||
|
|
||||||
|
- if the new configuration is found in the database, use it
|
||||||
|
|
||||||
|
and added if they are not already there. Initial settings are
|
||||||
|
1 what the output is already doing, if anything
|
||||||
|
2 based on an existing sufficiently similar monitor, if possible
|
||||||
|
3 some reasonable default.
|
||||||
|
|
||||||
|
- When the user changes settings in the GUI, the corresponding monitor
|
||||||
|
in the database is updated.
|
||||||
|
|
||||||
|
- Whenever the GUI settings change, for all displayed monitors the
|
||||||
|
possible modes are recomputed.
|
||||||
|
|
||||||
|
- Whenever a new monitor is selected in the GUI, it first gets all its
|
||||||
|
possible modes computed based on the selections on other
|
||||||
|
outputs. Then, if the possible modes include the existing choice of
|
||||||
|
resolution, that is selected.
|
||||||
|
|
||||||
|
Actually,
|
||||||
|
|
||||||
|
- initially, the settings are copied from the current settings
|
||||||
|
|
||||||
|
- whenever a gui setting changes for a monitor, all the other
|
||||||
|
monitors get their list of choices set to whatever is possible
|
||||||
|
given the chocie for the current monitor. A 'desired mode' is
|
||||||
|
maintained, and the closest choice to that is displayed. Whenever
|
||||||
|
the user actively selects something, that becomes the desired mode
|
||||||
|
for that monitor.
|
||||||
|
|
||||||
|
- Required
|
||||||
|
|
||||||
|
- Generate all outputs that are newly connected
|
||||||
|
|
||||||
|
foreach_newly_connected (Configuration *before, Configuration *after,
|
||||||
|
OutputFunc);
|
||||||
|
|
||||||
|
- A way to generate the best mode for a connected output
|
||||||
|
|
||||||
|
existing best_mode() can probably be used
|
||||||
|
|
||||||
|
- Given a list of modes, pick the one closest to a given mode.
|
||||||
|
|
||||||
|
(a possibility here is: pick an exact match, if that's impossible, then
|
||||||
|
pick the best one with the same width/height, if that's impossible, then
|
||||||
|
just pick the best mode on the list).
|
||||||
|
|
||||||
|
- For a configuation, fix the mode for a subset of the outputs, then list the
|
||||||
|
combinations for the rest of the outputs.
|
||||||
|
|
||||||
|
An obvious possibility here is to simply list all possibilities, then
|
||||||
|
weed out those that don't work. Is this too expensive? It might be.
|
||||||
|
|
||||||
|
Structure of login time program:
|
||||||
|
|
||||||
|
- The configuration database is read
|
||||||
|
|
||||||
|
- The current hardware configuration is generated
|
||||||
|
|
||||||
|
- If the current configuration is found in the database, that mode is set.
|
||||||
|
|
||||||
|
- If it isn't found, then nothing changes.
|
||||||
|
|
||||||
|
This could just be gnome-screen-resolution-capplet --reset
|
||||||
|
|
||||||
|
******************* Things that need to be done to the xrandr.patch:
|
||||||
|
|
||||||
|
===
|
||||||
|
|
||||||
|
XRRGetScreenResources() is a roundtrip and very slow (~0.5 s). GTK+
|
||||||
|
needs to keep information up-to-date by tracking events rather than
|
||||||
|
calling this function. In fact we probably can't call it at all unless
|
||||||
|
its performance improves significantly.
|
||||||
|
|
||||||
|
If EDID processing really has to be this slow, and we can't get
|
||||||
|
interrupts when monitors are plugged in, then we have a problem,
|
||||||
|
because we can't do anything this expensive once per second.
|
||||||
|
|
||||||
|
|
||||||
|
Detailed notes (but most of the patch should be rewritten):
|
||||||
|
|
||||||
|
|
||||||
|
=== FIXME in gdkscreen-x11.c in get_width_mm()
|
||||||
|
|
||||||
|
/* monitor pixel width / screen pixel width * screen_physical width */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== Check for 1.2 library
|
||||||
|
|
||||||
|
The patch should check that the 1.2 version of the XRandR library is
|
||||||
|
available before using the functions. A possibility is to not use any
|
||||||
|
RandR unless 1.2 is available, another is to conditionalize the code.
|
||||||
|
|
||||||
|
The most sane thing is probably to just require 1.2.
|
||||||
|
|
||||||
|
On the other hand, installing a newer gtk+ on a system with older X is
|
||||||
|
probably not that unusual, so maybe it's better to do the full 1.0,
|
||||||
|
vs. 1.1 vs 1.2 check.
|
||||||
|
|
||||||
|
For now it just requires 1.2.
|
||||||
|
|
||||||
|
Actually, this might be fine because the only place where we make use
|
||||||
|
of a 1.1 library is in the _gdk_x11_screen_size_changed() function,
|
||||||
|
but there we have a fallback that just updates the variables in the
|
||||||
|
Screen struct itself.
|
||||||
|
|
||||||
|
So, only defining HAVE_RANDR if we detect 1.2 should be ok.
|
||||||
|
|
||||||
|
=== Monitor information available
|
||||||
|
|
||||||
|
- Subpixel information. This should be set automatically for the fonts and
|
||||||
|
store under the name of the monitor. If the user changes the font
|
||||||
|
configuration, that change should also be stored under the monitor name.
|
||||||
|
|
||||||
|
- When a monitor we don't know about is plugged in, a configuration should
|
||||||
|
be generated:
|
||||||
|
|
||||||
|
- Screen size, computed based on the location of the screens
|
||||||
|
|
||||||
|
- RGBA information
|
||||||
|
|
||||||
|
- Whether the screen has a panel on it
|
||||||
|
|
||||||
|
- If there is a conflict between stored information and EDID,
|
||||||
|
the stored information wins
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
New API so far:
|
||||||
|
|
||||||
|
(* monitors_changed) signal
|
||||||
|
gdk_screen_get_monitor_width_mm()
|
||||||
|
gdk_screen_get_monitor_height_mm()
|
||||||
|
gdk_screen_get_monitor_name() => Note this is the output (eg. "DVI-0")
|
||||||
|
|
||||||
|
We should probably also have
|
||||||
|
get_manufacturer()
|
||||||
|
get_serial()
|
||||||
|
get_resolutions()
|
||||||
|
|
||||||
|
etc.
|
||||||
|
|
||||||
|
Should there be a GdkMonitor object that would correspond to an
|
||||||
|
output? Or maybe GdkOutput?
|
||||||
|
|
||||||
|
screen_list_monitors()
|
||||||
|
|
||||||
|
|
||||||
|
*************************** Issues XRandR/Xserver
|
||||||
|
|
||||||
|
- We need polling in the X server, whenever something changes, X must
|
||||||
|
recompute the information and cache it, then send an event. Note the
|
||||||
|
situation where the user disconnects and reconnects a monitor within
|
||||||
|
the polling interval. The event could missed in that case since the polling
|
||||||
|
cannot do a full EDID query. Difficult to see a way around this.
|
||||||
|
|
||||||
|
Actually, DDC allows random access, so it should be possible to just
|
||||||
|
read theq vendor id and manufacturer codes. This can be done once a
|
||||||
|
second without a problem. The polling should be turned off in power
|
||||||
|
saving mode anyway.
|
||||||
|
|
||||||
|
- Driver work:
|
||||||
|
|
||||||
|
- Intel driver:
|
||||||
|
|
||||||
|
- EDID information is not reported for VGA when the output is not
|
||||||
|
turned on (i945 laptop).
|
||||||
|
|
||||||
|
- Screen size must be dynamically changable. (No xorg.conf changes
|
||||||
|
should be required).
|
||||||
|
|
||||||
|
- Make use of ACPI information when possible.
|
||||||
|
|
||||||
|
Adam has code on his freedesktop page.
|
||||||
|
|
||||||
|
- i830 laptop can be put in a state where XRandr reports that no
|
||||||
|
outputs are connected to a CRTC, but the panel is on.
|
||||||
|
|
||||||
|
- Plug in VGA
|
||||||
|
- xrandr --auto
|
||||||
|
- xrandr --output VGA --off
|
||||||
|
- run chk
|
||||||
|
- xrandr --verbose will now not report any outputs as turned on
|
||||||
|
- run chk again - all screens will be turned off
|
||||||
|
|
||||||
|
- Small Sun monitor - an 1152x921 mode is generated, but the
|
||||||
|
monitor doesn't handle that. The monitor itself only claims to
|
||||||
|
handle 1152x920. It doesn't look to me like there is anything
|
||||||
|
in the EDID information that would indicate that it could handle
|
||||||
|
1152x921.
|
||||||
|
|
||||||
|
This happens with a radeon as wellso it may be a bug in the
|
||||||
|
generic X server EDID parsing. The X server apparently
|
||||||
|
interpretes the standard timing 1152x920 as 1152x921.
|
||||||
|
|
||||||
|
This happens because the X server uses
|
||||||
|
|
||||||
|
hsize * 4 / 5
|
||||||
|
|
||||||
|
which gives 921 for 1152. By using
|
||||||
|
|
||||||
|
(hsize / 5) * 4
|
||||||
|
|
||||||
|
you get 920. The 66 Hz version can bet set, the 76 Hz mode gets
|
||||||
|
sync out of range. (Would be interesting to find out whether the
|
||||||
|
1152x920 ModeLine would allow the 76 Hz version to be set).
|
||||||
|
|
||||||
|
This is for the ATI driver as shipped in F8:
|
||||||
|
|
||||||
|
- XRRGetScreenResources() takes half a second.
|
||||||
|
|
||||||
|
- Adam has now removed a workaround that caused some of the slowdown.
|
||||||
|
|
||||||
|
- If a DVI monitor is disconnected, you get "Unknown" for connection
|
||||||
|
status.
|
||||||
|
|
||||||
|
- If a VGA monitor is plugged in, then EDID information is not
|
||||||
|
available, even after running xrandr --verbose. The monitor has
|
||||||
|
to be plugged in at driver startup time, apparently.
|
||||||
|
|
||||||
|
- Logging out and logging back in often results in some random mode being
|
||||||
|
set. We need mode selection to not be completely screwed up.
|
||||||
|
Currently it is.
|
||||||
|
|
||||||
|
- The set up at server startup needs to be fixed. *If* randr actually works,
|
||||||
|
then we might be able to do something sensible.
|
||||||
|
|
||||||
|
- We need to revisit the idea that many monitors have broken EDID data.
|
||||||
|
This may be less widespread than previously believed.
|
||||||
|
|
||||||
|
- It may be useful to return the connector names as identifiers instead
|
||||||
|
of relying on UTF-8 strings. Ie., have an enum
|
||||||
|
|
||||||
|
{ UNKNOWN, OTHER, DVI, VGA, HDMI, ..., }
|
||||||
|
|
||||||
|
in addition to the string. The difference between UNKNOWN and OTHER is that
|
||||||
|
UNKNOWN means the driver doesn't know, whereas OTHER means it is something
|
||||||
|
not listed in the enum (which could be listed in a later version).
|
||||||
|
|
||||||
|
- Mouse cursor should be confined to the visible area. (It is already, I think)
|
||||||
|
|
||||||
|
- It looks like EDID information is only available for one output
|
||||||
|
even though it is actually read according to the log file.
|
||||||
|
(nv, intel drivers)
|
||||||
|
|
||||||
|
|
||||||
|
*********************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DONE:
|
||||||
|
|
||||||
|
Server work:
|
||||||
|
|
||||||
|
- i830 laptop incorrectly reports BadMatch when you configure the
|
||||||
|
CRTC to drive both VGA and LVDS with the 1024x768 mode that both
|
||||||
|
outputs can handle. (It should return 'failed' if it can't do
|
||||||
|
that). Same for i945 laptop. It seems as if the same CRTC can't
|
||||||
|
drive more than one output at the same time on Intel.
|
||||||
|
|
||||||
|
This was a client bug, but the documentation for SetCrtcConfig
|
||||||
|
should say that BadMatch will be returned if the outputs aren't
|
||||||
|
clones.
|
||||||
|
|
||||||
|
GTK+ patch is in now.
|
||||||
|
|
||||||
|
=== Add helper function
|
||||||
|
|
||||||
|
|
||||||
|
+ if (screen_x11->randr12)
|
||||||
|
+ {
|
||||||
|
+ XRRScreenResources *sr;
|
||||||
|
+ XRROutputInfo *output;
|
||||||
|
+ gchar *retval;
|
||||||
|
+
|
||||||
|
+ sr = XRRGetScreenResources ( screen_x11->xdisplay,
|
||||||
|
+ screen_x11->xroot_window );
|
||||||
|
+
|
||||||
|
+ output = XRRGetOutputInfo ( screen_x11->xdisplay,
|
||||||
|
+ sr,
|
||||||
|
+ (RROutput)screen_x11->act_outputs[monitor_num]
|
||||||
|
);
|
||||||
|
|
||||||
|
Might be worthwhile to factor this out into a
|
||||||
|
gdk_screen_get_output_info (screen, monitor_num)
|
||||||
|
helper function ?
|
||||||
|
|
||||||
|
Instead of cutting and pasting all over creation
|
||||||
|
|
||||||
|
* Calling XRRGetScreenResources all the time is not going to fly. It
|
||||||
|
takes hundreds of milliseconds ... Even if it didn't, it wouldn't
|
||||||
|
be acceptable to do all those roundtrips.
|
||||||
|
|
||||||
|
|
||||||
|
=== Some g_prints left
|
||||||
|
|
||||||
|
|
||||||
|
=== Version check
|
||||||
|
|
||||||
|
Should be (maj > 1) || (maj == 1 && min >= 2)
|
||||||
|
|
||||||
|
|
||||||
|
=== Grep for TODO
|
||||||
|
|
||||||
|
|
||||||
|
=== Setup XRRSelectInput()
|
||||||
|
|
||||||
|
You should call XRRSelectInput() at the same place where you are
|
||||||
|
calling XSelectInput() right now. The right place to handle the
|
||||||
|
XRandr events is the huge switch in gdkevents-x11.c:gdk_event_translate
|
||||||
|
Check out how other extension events are handled there, like
|
||||||
|
XKB, or XFixes.
|
||||||
|
|
||||||
|
|
||||||
|
=== Lots of variable naming issues, such as act_output and noutput
|
||||||
|
|
||||||
|
=== Needs to select the input, and hook it up to the signal
|
||||||
|
|
||||||
|
=== Add version markers to API
|
||||||
|
|
||||||
|
=== API to turn monitors on and off?
|
||||||
|
|
||||||
|
- DPMS not exposed through randr, maybe should be
|
||||||
|
|
||||||
|
- DPMS is presumably a property of either an
|
||||||
|
output or a CRTC. Logically it's an output.
|
||||||
|
|
||||||
|
- Need events when DPMS happens. Exposing the "screen saving on" on
|
||||||
|
dbus may not be good enough.
|
||||||
|
|
||||||
|
=== Why does init_multihead_support() start by freeing monitors and
|
||||||
|
outputs?
|
||||||
|
|
||||||
|
=== Do we disable Xinerama support entirely when 1.2 is in use?
|
||||||
|
|
||||||
|
=== We should expose information about what parts of the screen monitors
|
||||||
|
are viewing.
|
||||||
|
|
||||||
|
=== Make use of the EDID information?
|
||||||
|
|
||||||
|
|
||||||
|
-- details for X server --
|
||||||
|
|
||||||
|
In nv driver SorSetOutputProperty should return TRUE for unknown
|
||||||
|
properties. (Like the Intel driver does).
|
||||||
|
|
||||||
|
Detecting plugged in
|
||||||
|
|
||||||
|
- Periodically poll
|
||||||
|
-
|
||||||
|
|
||||||
|
- One ddc probe takes 5 ms, according to a comment in the intel
|
||||||
|
driver. Running this twice a second would mean spending 1% of
|
||||||
|
overall time doing ddc polling, which is almost certainly not
|
||||||
|
acceptable.
|
||||||
|
|
||||||
|
1) Async I2C:
|
||||||
|
|
||||||
|
void I2CProbeAsync(..., callback, data);
|
||||||
|
Bool I2CPending()
|
||||||
|
void I2CUpdate()
|
||||||
|
|
||||||
|
In Dispatch, call I2CUpdate()
|
||||||
|
Before going idle, do
|
||||||
|
|
||||||
|
while (I2CPending())
|
||||||
|
I2CUpdate()
|
||||||
|
|
||||||
|
Would need
|
||||||
|
RegisterDispatchFunction() (Is this called Wakeup?)
|
||||||
|
RegisterIdleFunction()
|
||||||
|
|
||||||
|
Note the idle function should have the option of saying:
|
||||||
|
"check if something else happened; if not, call me again" and
|
||||||
|
"ok, I'm done - go idle". Otherwise, we would be blocking for
|
||||||
|
5 ms whenever the X server went idle. So actually the idle
|
||||||
|
function should be
|
||||||
|
|
||||||
|
if (I2CPending())
|
||||||
|
{
|
||||||
|
I2CUpdate();
|
||||||
|
return TRUE; /* call me again */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FALSE; /* I'm done */
|
||||||
|
}
|
||||||
|
|
||||||
|
What happens if another I2C requests come in while an async one
|
||||||
|
is pending? Most likely we simply finish whatever is going on,
|
||||||
|
then process the new request.
|
||||||
|
|
||||||
|
What happens if an X request takes so long that we get timeouts on
|
||||||
|
the i2c bus? Good question. Need to read the VESA ddc spec.
|
||||||
|
|
||||||
|
2) Run the polling in a separate thread.
|
||||||
|
|
||||||
|
Probably crack.
|
||||||
|
|
||||||
|
3) Run the polling less, maybe once every three seconds.
|
||||||
|
|
||||||
|
-- details for control panel --
|
||||||
|
Screen changes
|
||||||
|
- Currently it is polling via rw_screen_refresh(), which will always emit
|
||||||
|
a screen-changed event. In reponse to this event the capplet currently
|
||||||
|
checks whether anything changed physically about the setup. This means
|
||||||
|
the capplet can't react to external changes to modes. On the other hand
|
||||||
|
if it didn't
|
||||||
|
Disallow combinations that would exceed the screen ranges.
|
||||||
|
- Note rotations
|
||||||
|
|
||||||
|
Give rw objects stable positions in memory so that they can be cached
|
||||||
|
across screen_changed events.
|
||||||
|
|
||||||
|
Add Clone Mode
|
||||||
|
|
||||||
|
Drag and drop for the monitors
|
||||||
|
- 2 dimensional layout
|
||||||
|
|
||||||
|
Store make and model in monitors.xml, then if serial numbers don't
|
||||||
|
match, fall back to a make and model match. Users with an nfs mounted
|
||||||
|
home directory should not have to reconfigure for each new system they
|
||||||
|
log in to.
|
||||||
|
|
||||||
|
Make sure text is scaled correctly
|
||||||
|
|
||||||
|
Need to sanitize naming
|
||||||
|
RWOutput vs Output - should probably be OutputInfo
|
||||||
|
rate vs. freq - decide on one
|
||||||
|
|
||||||
|
Should probably reconsider the use of null terminated arrays.
|
||||||
|
Maybe lists would be better.
|
||||||
|
|
||||||
|
Pick a fixed scale, so that two 1024x768 don't look like two 6x4.
|
||||||
|
- An alternative would be to draw a checkerboard pattern
|
||||||
|
below the monitors.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
Add rotation
|
||||||
|
|
||||||
|
Disable panel checkbox for now
|
||||||
|
|
||||||
|
Patch into gnome-desktop
|
||||||
|
|
||||||
|
Find out how to share code between gcc and gsd
|
||||||
|
|
||||||
|
Make it assign coordinates correctly
|
||||||
|
- including computing correct screen size
|
||||||
|
|
1
capplets/display/build.sh
Normal file
1
capplets/display/build.sh
Normal file
|
@ -0,0 +1 @@
|
||||||
|
gcc -g -Wall `pkg-config --cflags --libs gtk+-2.0 libglade-2.0` -I../ ../randrwrap.c ../monitor-db.c xrandr-capplet.c ../edid-parse.c ../display-name.c scrollarea.c foo-marshal.c -o capplet
|
387
capplets/display/display-capplet.glade
Normal file
387
capplets/display/display-capplet.glade
Normal file
|
@ -0,0 +1,387 @@
|
||||||
|
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||||
|
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||||
|
|
||||||
|
<glade-interface>
|
||||||
|
|
||||||
|
<widget class="GtkDialog" id="dialog">
|
||||||
|
<property name="border_width">18</property>
|
||||||
|
<property name="title" translatable="yes">Monitor Resolution Settings</property>
|
||||||
|
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||||
|
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||||
|
<property name="modal">False</property>
|
||||||
|
<property name="resizable">True</property>
|
||||||
|
<property name="destroy_with_parent">False</property>
|
||||||
|
<property name="decorated">True</property>
|
||||||
|
<property name="skip_taskbar_hint">False</property>
|
||||||
|
<property name="skip_pager_hint">False</property>
|
||||||
|
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||||
|
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||||
|
<property name="focus_on_map">True</property>
|
||||||
|
<property name="urgency_hint">False</property>
|
||||||
|
<property name="has_separator">False</property>
|
||||||
|
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<widget class="GtkVBox" id="dialog-vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="helpbutton1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_default">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label">gtk-help</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
<property name="response_id">-11</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="button1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_default">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label">gtk-apply</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
<property name="response_id">-10</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="button2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_default">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label">gtk-close</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
<property name="response_id">-7</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">GTK_PACK_END</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0.5</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xscale">1</property>
|
||||||
|
<property name="yscale">1</property>
|
||||||
|
<property name="top_padding">0</property>
|
||||||
|
<property name="bottom_padding">24</property>
|
||||||
|
<property name="left_padding">0</property>
|
||||||
|
<property name="right_padding">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">12</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkCheckButton" id="clone_checkbox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Mirror Screens</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
<property name="active">False</property>
|
||||||
|
<property name="inconsistent">False</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="align">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0.5</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xscale">1</property>
|
||||||
|
<property name="yscale">1</property>
|
||||||
|
<property name="top_padding">0</property>
|
||||||
|
<property name="bottom_padding">0</property>
|
||||||
|
<property name="left_padding">0</property>
|
||||||
|
<property name="right_padding">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkAlignment" id="alignment1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0.5</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xscale">1</property>
|
||||||
|
<property name="yscale">1</property>
|
||||||
|
<property name="top_padding">12</property>
|
||||||
|
<property name="bottom_padding">12</property>
|
||||||
|
<property name="left_padding">24</property>
|
||||||
|
<property name="right_padding">24</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkTable" id="table1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="n_rows">2</property>
|
||||||
|
<property name="n_columns">4</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="row_spacing">12</property>
|
||||||
|
<property name="column_spacing">12</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">_Resolution</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="use_markup">False</property>
|
||||||
|
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||||
|
<property name="wrap">False</property>
|
||||||
|
<property name="selectable">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xpad">0</property>
|
||||||
|
<property name="ypad">0</property>
|
||||||
|
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||||
|
<property name="width_chars">-1</property>
|
||||||
|
<property name="single_line_mode">False</property>
|
||||||
|
<property name="angle">0</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="right_attach">1</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
<property name="bottom_attach">1</property>
|
||||||
|
<property name="x_options">fill</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Re_fresh Rate:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="use_markup">False</property>
|
||||||
|
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||||
|
<property name="wrap">False</property>
|
||||||
|
<property name="selectable">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xpad">0</property>
|
||||||
|
<property name="ypad">0</property>
|
||||||
|
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||||
|
<property name="width_chars">-1</property>
|
||||||
|
<property name="single_line_mode">False</property>
|
||||||
|
<property name="angle">0</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="right_attach">1</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="x_options">fill</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkComboBox" id="resolution_combo">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="add_tearoffs">False</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
<property name="bottom_attach">1</property>
|
||||||
|
<property name="y_options">fill</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkComboBox" id="refresh_combo">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="add_tearoffs">False</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="x_options">fill</property>
|
||||||
|
<property name="y_options">fill</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="panel_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Include _Panel</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="use_markup">False</property>
|
||||||
|
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||||
|
<property name="wrap">False</property>
|
||||||
|
<property name="selectable">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xpad">0</property>
|
||||||
|
<property name="ypad">0</property>
|
||||||
|
<property name="mnemonic_widget">panel_checkbox</property>
|
||||||
|
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||||
|
<property name="width_chars">-1</property>
|
||||||
|
<property name="single_line_mode">False</property>
|
||||||
|
<property name="angle">0</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">2</property>
|
||||||
|
<property name="right_attach">3</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
<property name="bottom_attach">1</property>
|
||||||
|
<property name="x_options">fill</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label5">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">R_otation</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="use_markup">False</property>
|
||||||
|
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||||
|
<property name="wrap">False</property>
|
||||||
|
<property name="selectable">False</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xpad">0</property>
|
||||||
|
<property name="ypad">0</property>
|
||||||
|
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||||
|
<property name="width_chars">-1</property>
|
||||||
|
<property name="single_line_mode">False</property>
|
||||||
|
<property name="angle">0</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">2</property>
|
||||||
|
<property name="right_attach">3</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="x_options">fill</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkComboBox" id="rotation_combo">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="items" translatable="yes">Normal
|
||||||
|
Left
|
||||||
|
Right
|
||||||
|
Upside-down
|
||||||
|
</property>
|
||||||
|
<property name="add_tearoffs">False</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">3</property>
|
||||||
|
<property name="right_attach">4</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="y_options">fill</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkCheckButton" id="panel_checkbox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
<property name="active">False</property>
|
||||||
|
<property name="inconsistent">False</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">3</property>
|
||||||
|
<property name="right_attach">4</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
<property name="bottom_attach">1</property>
|
||||||
|
<property name="x_options">fill</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="detect_displays_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label" translatable="yes">_Detect Displays</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="focus_on_click">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
|
||||||
|
</glade-interface>
|
279
capplets/display/foo-marshal.c
Normal file
279
capplets/display/foo-marshal.c
Normal file
|
@ -0,0 +1,279 @@
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
|
||||||
|
#define g_marshal_value_peek_char(v) g_value_get_char (v)
|
||||||
|
#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
|
||||||
|
#define g_marshal_value_peek_int(v) g_value_get_int (v)
|
||||||
|
#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
|
||||||
|
#define g_marshal_value_peek_long(v) g_value_get_long (v)
|
||||||
|
#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
|
||||||
|
#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
|
||||||
|
#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
|
||||||
|
#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
|
||||||
|
#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
|
||||||
|
#define g_marshal_value_peek_float(v) g_value_get_float (v)
|
||||||
|
#define g_marshal_value_peek_double(v) g_value_get_double (v)
|
||||||
|
#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
|
||||||
|
#define g_marshal_value_peek_param(v) g_value_get_param (v)
|
||||||
|
#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
|
||||||
|
#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
|
||||||
|
#define g_marshal_value_peek_object(v) g_value_get_object (v)
|
||||||
|
#else /* !G_ENABLE_DEBUG */
|
||||||
|
/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
|
||||||
|
* Do not access GValues directly in your code. Instead, use the
|
||||||
|
* g_value_get_*() functions
|
||||||
|
*/
|
||||||
|
#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
|
||||||
|
#define g_marshal_value_peek_char(v) (v)->data[0].v_int
|
||||||
|
#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
|
||||||
|
#define g_marshal_value_peek_int(v) (v)->data[0].v_int
|
||||||
|
#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
|
||||||
|
#define g_marshal_value_peek_long(v) (v)->data[0].v_long
|
||||||
|
#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
|
||||||
|
#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
|
||||||
|
#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
|
||||||
|
#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
|
||||||
|
#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
|
||||||
|
#define g_marshal_value_peek_float(v) (v)->data[0].v_float
|
||||||
|
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
|
||||||
|
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
|
||||||
|
#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
|
||||||
|
#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
|
||||||
|
#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
|
||||||
|
#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
|
||||||
|
#endif /* !G_ENABLE_DEBUG */
|
||||||
|
|
||||||
|
|
||||||
|
/* VOID:OBJECT,OBJECT (marshal.list:1) */
|
||||||
|
void
|
||||||
|
foo_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
|
||||||
|
GValue *return_value G_GNUC_UNUSED,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint G_GNUC_UNUSED,
|
||||||
|
gpointer marshal_data)
|
||||||
|
{
|
||||||
|
typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1,
|
||||||
|
gpointer arg_1,
|
||||||
|
gpointer arg_2,
|
||||||
|
gpointer data2);
|
||||||
|
register GMarshalFunc_VOID__OBJECT_OBJECT callback;
|
||||||
|
register GCClosure *cc = (GCClosure*) closure;
|
||||||
|
register gpointer data1, data2;
|
||||||
|
|
||||||
|
g_return_if_fail (n_param_values == 3);
|
||||||
|
|
||||||
|
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||||
|
{
|
||||||
|
data1 = closure->data;
|
||||||
|
data2 = g_value_peek_pointer (param_values + 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data1 = g_value_peek_pointer (param_values + 0);
|
||||||
|
data2 = closure->data;
|
||||||
|
}
|
||||||
|
callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback);
|
||||||
|
|
||||||
|
callback (data1,
|
||||||
|
g_marshal_value_peek_object (param_values + 1),
|
||||||
|
g_marshal_value_peek_object (param_values + 2),
|
||||||
|
data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VOID:UINT,UINT,UINT,UINT (marshal.list:2) */
|
||||||
|
void
|
||||||
|
foo_marshal_VOID__UINT_UINT_UINT_UINT (GClosure *closure,
|
||||||
|
GValue *return_value G_GNUC_UNUSED,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint G_GNUC_UNUSED,
|
||||||
|
gpointer marshal_data)
|
||||||
|
{
|
||||||
|
typedef void (*GMarshalFunc_VOID__UINT_UINT_UINT_UINT) (gpointer data1,
|
||||||
|
guint arg_1,
|
||||||
|
guint arg_2,
|
||||||
|
guint arg_3,
|
||||||
|
guint arg_4,
|
||||||
|
gpointer data2);
|
||||||
|
register GMarshalFunc_VOID__UINT_UINT_UINT_UINT callback;
|
||||||
|
register GCClosure *cc = (GCClosure*) closure;
|
||||||
|
register gpointer data1, data2;
|
||||||
|
|
||||||
|
g_return_if_fail (n_param_values == 5);
|
||||||
|
|
||||||
|
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||||
|
{
|
||||||
|
data1 = closure->data;
|
||||||
|
data2 = g_value_peek_pointer (param_values + 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data1 = g_value_peek_pointer (param_values + 0);
|
||||||
|
data2 = closure->data;
|
||||||
|
}
|
||||||
|
callback = (GMarshalFunc_VOID__UINT_UINT_UINT_UINT) (marshal_data ? marshal_data : cc->callback);
|
||||||
|
|
||||||
|
callback (data1,
|
||||||
|
g_marshal_value_peek_uint (param_values + 1),
|
||||||
|
g_marshal_value_peek_uint (param_values + 2),
|
||||||
|
g_marshal_value_peek_uint (param_values + 3),
|
||||||
|
g_marshal_value_peek_uint (param_values + 4),
|
||||||
|
data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VOID:UINT,UINT (marshal.list:3) */
|
||||||
|
void
|
||||||
|
foo_marshal_VOID__UINT_UINT (GClosure *closure,
|
||||||
|
GValue *return_value G_GNUC_UNUSED,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint G_GNUC_UNUSED,
|
||||||
|
gpointer marshal_data)
|
||||||
|
{
|
||||||
|
typedef void (*GMarshalFunc_VOID__UINT_UINT) (gpointer data1,
|
||||||
|
guint arg_1,
|
||||||
|
guint arg_2,
|
||||||
|
gpointer data2);
|
||||||
|
register GMarshalFunc_VOID__UINT_UINT callback;
|
||||||
|
register GCClosure *cc = (GCClosure*) closure;
|
||||||
|
register gpointer data1, data2;
|
||||||
|
|
||||||
|
g_return_if_fail (n_param_values == 3);
|
||||||
|
|
||||||
|
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||||
|
{
|
||||||
|
data1 = closure->data;
|
||||||
|
data2 = g_value_peek_pointer (param_values + 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data1 = g_value_peek_pointer (param_values + 0);
|
||||||
|
data2 = closure->data;
|
||||||
|
}
|
||||||
|
callback = (GMarshalFunc_VOID__UINT_UINT) (marshal_data ? marshal_data : cc->callback);
|
||||||
|
|
||||||
|
callback (data1,
|
||||||
|
g_marshal_value_peek_uint (param_values + 1),
|
||||||
|
g_marshal_value_peek_uint (param_values + 2),
|
||||||
|
data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VOID:BOXED (marshal.list:4) */
|
||||||
|
|
||||||
|
/* VOID:BOXED,BOXED (marshal.list:5) */
|
||||||
|
void
|
||||||
|
foo_marshal_VOID__BOXED_BOXED (GClosure *closure,
|
||||||
|
GValue *return_value G_GNUC_UNUSED,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint G_GNUC_UNUSED,
|
||||||
|
gpointer marshal_data)
|
||||||
|
{
|
||||||
|
typedef void (*GMarshalFunc_VOID__BOXED_BOXED) (gpointer data1,
|
||||||
|
gpointer arg_1,
|
||||||
|
gpointer arg_2,
|
||||||
|
gpointer data2);
|
||||||
|
register GMarshalFunc_VOID__BOXED_BOXED callback;
|
||||||
|
register GCClosure *cc = (GCClosure*) closure;
|
||||||
|
register gpointer data1, data2;
|
||||||
|
|
||||||
|
g_return_if_fail (n_param_values == 3);
|
||||||
|
|
||||||
|
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||||
|
{
|
||||||
|
data1 = closure->data;
|
||||||
|
data2 = g_value_peek_pointer (param_values + 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data1 = g_value_peek_pointer (param_values + 0);
|
||||||
|
data2 = closure->data;
|
||||||
|
}
|
||||||
|
callback = (GMarshalFunc_VOID__BOXED_BOXED) (marshal_data ? marshal_data : cc->callback);
|
||||||
|
|
||||||
|
callback (data1,
|
||||||
|
g_marshal_value_peek_boxed (param_values + 1),
|
||||||
|
g_marshal_value_peek_boxed (param_values + 2),
|
||||||
|
data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VOID:POINTER,BOXED,POINTER (marshal.list:6) */
|
||||||
|
void
|
||||||
|
foo_marshal_VOID__POINTER_BOXED_POINTER (GClosure *closure,
|
||||||
|
GValue *return_value G_GNUC_UNUSED,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint G_GNUC_UNUSED,
|
||||||
|
gpointer marshal_data)
|
||||||
|
{
|
||||||
|
typedef void (*GMarshalFunc_VOID__POINTER_BOXED_POINTER) (gpointer data1,
|
||||||
|
gpointer arg_1,
|
||||||
|
gpointer arg_2,
|
||||||
|
gpointer arg_3,
|
||||||
|
gpointer data2);
|
||||||
|
register GMarshalFunc_VOID__POINTER_BOXED_POINTER callback;
|
||||||
|
register GCClosure *cc = (GCClosure*) closure;
|
||||||
|
register gpointer data1, data2;
|
||||||
|
|
||||||
|
g_return_if_fail (n_param_values == 4);
|
||||||
|
|
||||||
|
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||||
|
{
|
||||||
|
data1 = closure->data;
|
||||||
|
data2 = g_value_peek_pointer (param_values + 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data1 = g_value_peek_pointer (param_values + 0);
|
||||||
|
data2 = closure->data;
|
||||||
|
}
|
||||||
|
callback = (GMarshalFunc_VOID__POINTER_BOXED_POINTER) (marshal_data ? marshal_data : cc->callback);
|
||||||
|
|
||||||
|
callback (data1,
|
||||||
|
g_marshal_value_peek_pointer (param_values + 1),
|
||||||
|
g_marshal_value_peek_boxed (param_values + 2),
|
||||||
|
g_marshal_value_peek_pointer (param_values + 3),
|
||||||
|
data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VOID:POINTER,POINTER (marshal.list:7) */
|
||||||
|
void
|
||||||
|
foo_marshal_VOID__POINTER_POINTER (GClosure *closure,
|
||||||
|
GValue *return_value G_GNUC_UNUSED,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint G_GNUC_UNUSED,
|
||||||
|
gpointer marshal_data)
|
||||||
|
{
|
||||||
|
typedef void (*GMarshalFunc_VOID__POINTER_POINTER) (gpointer data1,
|
||||||
|
gpointer arg_1,
|
||||||
|
gpointer arg_2,
|
||||||
|
gpointer data2);
|
||||||
|
register GMarshalFunc_VOID__POINTER_POINTER callback;
|
||||||
|
register GCClosure *cc = (GCClosure*) closure;
|
||||||
|
register gpointer data1, data2;
|
||||||
|
|
||||||
|
g_return_if_fail (n_param_values == 3);
|
||||||
|
|
||||||
|
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||||
|
{
|
||||||
|
data1 = closure->data;
|
||||||
|
data2 = g_value_peek_pointer (param_values + 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data1 = g_value_peek_pointer (param_values + 0);
|
||||||
|
data2 = closure->data;
|
||||||
|
}
|
||||||
|
callback = (GMarshalFunc_VOID__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
|
||||||
|
|
||||||
|
callback (data1,
|
||||||
|
g_marshal_value_peek_pointer (param_values + 1),
|
||||||
|
g_marshal_value_peek_pointer (param_values + 2),
|
||||||
|
data2);
|
||||||
|
}
|
||||||
|
|
63
capplets/display/foo-marshal.h
Normal file
63
capplets/display/foo-marshal.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
|
||||||
|
#ifndef __foo_marshal_MARSHAL_H__
|
||||||
|
#define __foo_marshal_MARSHAL_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/* VOID:OBJECT,OBJECT (marshal.list:1) */
|
||||||
|
extern void foo_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
|
||||||
|
GValue *return_value,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
|
gpointer marshal_data);
|
||||||
|
|
||||||
|
/* VOID:UINT,UINT,UINT,UINT (marshal.list:2) */
|
||||||
|
extern void foo_marshal_VOID__UINT_UINT_UINT_UINT (GClosure *closure,
|
||||||
|
GValue *return_value,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
|
gpointer marshal_data);
|
||||||
|
|
||||||
|
/* VOID:UINT,UINT (marshal.list:3) */
|
||||||
|
extern void foo_marshal_VOID__UINT_UINT (GClosure *closure,
|
||||||
|
GValue *return_value,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
|
gpointer marshal_data);
|
||||||
|
|
||||||
|
/* VOID:BOXED (marshal.list:4) */
|
||||||
|
#define foo_marshal_VOID__BOXED g_cclosure_marshal_VOID__BOXED
|
||||||
|
|
||||||
|
/* VOID:BOXED,BOXED (marshal.list:5) */
|
||||||
|
extern void foo_marshal_VOID__BOXED_BOXED (GClosure *closure,
|
||||||
|
GValue *return_value,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
|
gpointer marshal_data);
|
||||||
|
|
||||||
|
/* VOID:POINTER,BOXED,POINTER (marshal.list:6) */
|
||||||
|
extern void foo_marshal_VOID__POINTER_BOXED_POINTER (GClosure *closure,
|
||||||
|
GValue *return_value,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
|
gpointer marshal_data);
|
||||||
|
|
||||||
|
/* VOID:POINTER,POINTER (marshal.list:7) */
|
||||||
|
extern void foo_marshal_VOID__POINTER_POINTER (GClosure *closure,
|
||||||
|
GValue *return_value,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint,
|
||||||
|
gpointer marshal_data);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __foo_marshal_MARSHAL_H__ */
|
||||||
|
|
1920
capplets/display/scrollarea.c
Normal file
1920
capplets/display/scrollarea.c
Normal file
File diff suppressed because it is too large
Load diff
124
capplets/display/scrollarea.h
Normal file
124
capplets/display/scrollarea.h
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/* Copyright 2006, 2007, 2008, Soren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
#include <cairo/cairo.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#define FOO_TYPE_SCROLL_AREA (foo_scroll_area_get_type ())
|
||||||
|
#define FOO_SCROLL_AREA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE_SCROLL_AREA, FooScrollArea))
|
||||||
|
#define FOO_SCROLL_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE_SCROLL_AREA, FooScrollAreaClass))
|
||||||
|
#define FOO_IS_SCROLL_AREA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE_SCROLL_AREA))
|
||||||
|
#define FOO_IS_SCROLL_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE_SCROLL_AREA))
|
||||||
|
#define FOO_SCROLL_AREA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE_SCROLL_AREA, FooScrollAreaClass))
|
||||||
|
|
||||||
|
typedef struct FooScrollArea FooScrollArea;
|
||||||
|
typedef struct FooScrollAreaClass FooScrollAreaClass;
|
||||||
|
typedef struct FooScrollAreaPrivate FooScrollAreaPrivate;
|
||||||
|
typedef struct FooScrollAreaEvent FooScrollAreaEvent;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
FOO_BUTTON_PRESS,
|
||||||
|
FOO_BUTTON_RELEASE,
|
||||||
|
FOO_MOTION
|
||||||
|
} FooScrollAreaEventType;
|
||||||
|
|
||||||
|
struct FooScrollAreaEvent
|
||||||
|
{
|
||||||
|
FooScrollAreaEventType type;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (* FooScrollAreaEventFunc) (FooScrollArea *area,
|
||||||
|
FooScrollAreaEvent *event,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
struct FooScrollArea
|
||||||
|
{
|
||||||
|
GtkContainer parent_instance;
|
||||||
|
|
||||||
|
FooScrollAreaPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FooScrollAreaClass
|
||||||
|
{
|
||||||
|
GtkContainerClass parent_class;
|
||||||
|
|
||||||
|
void (*set_scroll_adjustments) (FooScrollArea *scroll_area,
|
||||||
|
GtkAdjustment *hadjustment,
|
||||||
|
GtkAdjustment *vadjustment);
|
||||||
|
|
||||||
|
void (*viewport_changed) (FooScrollArea *scroll_area,
|
||||||
|
GdkRectangle *old_viewport,
|
||||||
|
GdkRectangle *new_viewport);
|
||||||
|
|
||||||
|
void (*paint) (FooScrollArea *scroll_area,
|
||||||
|
cairo_t *cr,
|
||||||
|
GdkRectangle *extents,
|
||||||
|
GdkRegion *region);
|
||||||
|
};
|
||||||
|
|
||||||
|
GType foo_scroll_area_get_type (void);
|
||||||
|
|
||||||
|
FooScrollArea *foo_scroll_area_new (void);
|
||||||
|
|
||||||
|
/* Set the requisition for the widget. */
|
||||||
|
void foo_scroll_area_set_min_size (FooScrollArea *scroll_area,
|
||||||
|
int min_width,
|
||||||
|
int min_height);
|
||||||
|
|
||||||
|
/* Set how much of the canvas can be scrolled into view */
|
||||||
|
void foo_scroll_area_set_size (FooScrollArea *scroll_area,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
void foo_scroll_area_set_size_fixed_y (FooScrollArea *scroll_area,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int old_y,
|
||||||
|
int new_y);
|
||||||
|
void foo_scroll_area_set_viewport_pos (FooScrollArea *scroll_area,
|
||||||
|
int x,
|
||||||
|
int y);
|
||||||
|
void foo_scroll_area_get_viewport (FooScrollArea *scroll_area,
|
||||||
|
GdkRectangle *viewport);
|
||||||
|
void foo_scroll_area_add_input_from_stroke (FooScrollArea *scroll_area,
|
||||||
|
cairo_t *cr,
|
||||||
|
FooScrollAreaEventFunc func,
|
||||||
|
gpointer data);
|
||||||
|
void foo_scroll_area_add_input_from_fill (FooScrollArea *scroll_area,
|
||||||
|
cairo_t *cr,
|
||||||
|
FooScrollAreaEventFunc func,
|
||||||
|
gpointer data);
|
||||||
|
void foo_scroll_area_invalidate_region (FooScrollArea *area,
|
||||||
|
GdkRegion *region);
|
||||||
|
void foo_scroll_area_invalidate (FooScrollArea *scroll_area);
|
||||||
|
void foo_scroll_area_invalidate_rect (FooScrollArea *scroll_area,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
void foo_scroll_area_begin_grab (FooScrollArea *scroll_area,
|
||||||
|
FooScrollAreaEventFunc func,
|
||||||
|
gpointer input_data);
|
||||||
|
void foo_scroll_area_end_grab (FooScrollArea *scroll_area);
|
||||||
|
gboolean foo_scroll_area_is_grabbed (FooScrollArea *scroll_area);
|
||||||
|
|
||||||
|
void foo_scroll_area_begin_auto_scroll (FooScrollArea *scroll_area);
|
||||||
|
void foo_scroll_area_auto_scroll (FooScrollArea *scroll_area,
|
||||||
|
FooScrollAreaEvent *event);
|
||||||
|
void foo_scroll_area_end_auto_scroll (FooScrollArea *scroll_area);
|
1708
capplets/display/xrandr-capplet.c
Normal file
1708
capplets/display/xrandr-capplet.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue