pynvidia
文件大小: unknow
源码售价: 5 个金币 积分规则     积分充值
资源说明:
===================
Python NVidia tools
===================

by Paul Wilson (paul@nagus-wilson.net)

Based on PHP5 tools by redmoskito (http://ubuntuforums.org/showthread.php?t=922956)

*Requires* NVidia-supplied nv-control-dpy tool.  See instructions at:
http://ubuntuforums.org/showthread.php?p=5809670

Motivation
----------

In fall 2010, 12 years since I had last relied on Linux as my primary
OS, I returned to Linux on my brand new HP 8440p Elitebook.  It was
equipped with an NVidia graphics card to enable some of the intensive
CAD manipulation I intended to do.

I quickly found, however, that while NVidia did a good job of
delivering high performance kernel modules to support their graphics
cards, they didn't integrate well into the normal display switching
tools of the Ubuntu 10.10 system I was using.  Since I have external
displays at both by office and my home office, and I occasionally use
projectors in common conference rooms, I wanted to be able to easily
switch between the different display options.  Some of those
configurations include:

- laptop LCD only (with resolution A)
- external office LCD only (with resolution B)
- external home office LCD only (with resolution C)
- clone to extnernal project (with resolution D)
- extended desktop across office/home office LCD

and so on. Moreover, in my ideal world, the computer would detect all
these changes at various time including booting, waking from suspend,
waking from hibernation, and even hot docking/undocking in a docking
station.

I scoured the net only to find a variety of convoluted-seeming
schemes, most based on the nv-control-dpy tool that NVidia distributes
with its settings tool source code.  At the time, it seemed as though
most of these relied on my learning more about video modes and
metamodes that really wanted to.  (Given my experience with these
developments here, it probably wasn't that much to learn, but still
more than I should have needed to!)

I managed to accomplish a solution that was about 65% of what I
wanted.  I added the metamodes for all the scenarios that I most
typically experience and then used xrandr to choose between them,
binding some particular options to special key combinations.  The main
problem with this solution was that I had no ability to easily adapt
to settings not identified a priori and was forced to use the
effective but tedious NVidia settings tool.

After the most recent OS upgrade (Ubunutu 12.04), I decided it was
time to tackle this for once and for all.  Available at that time, and
still available now in the archives, was a set of PHP5 tools that
invoked the nv-control-dpy tool and parsed its results to accomplish a
variety of tasks.  I decided to build a Python module that would
provide the basic functionality necessary for this mode switching and
use that to accomplish what I wanted.

One of the key goals here is not avoid the need for hard-coded screen
resolutions or options.  The goal is to discover the available
resolutions dynamically in order to generate a set of metamodes based
on some heuristics.


Python Module: pynvidia 
------------------------

This module provides a number of python functions that populate
dictionaries of information about the diplay devices, device
modelines, and NVidia metamodes, but calling the nv-control-dpy tool
and parsing the results.

A dictionary of display ports and devices is generated with
get_displays(), returning a dictionary in which each key is the name
of a port (e.g. DFP-1, CRT-0, etc) and the value is the name of the
device connected at that port.

A dictionary of fundamental display modes is generated with
build_modeDB(), returning a dictionary in which each key is the name
of a connected device and the value is another dictionary with the
following information:

::

   'port' => string describing the port to which this device is attached
   'mask' => hex string returned by NVidia tools
   'maxResMode' => string referring to the video mode with maximum # of pixels
   'maxW' => integer width of maxResMode
   'maxH' => integer heigher of maxResMode
   'modelist' =>
         string identifying mode => list of mode data
                                          modeData[2] = width
					  modeData[6] = height

A dictionary of metamodes is generated with get_all_metamodes(),
returning a dictionary in which each key is an integer mode ID, and
each value is a dictionary of the following data:

::

     =>  : a variety of key/value pairs are parsed as is and stored
    'details' =>
          string identifying port =>
                'enabled'    : Boolean indicating whether this port is active
                'mode'       : string resolution of viewable window
		'resolution' : string resolution of pannable mode
		'offset'     : string offset of this display


Sample Applets
--------------

With these dictionaries fully populated, and tools to add additional
metamodes to the previous set of modes, I was able to create brief
scripts that accomplish my particular aims and include them as
samples.

*build_dual_head_mode_list()*

Given my use cases, I am interested in first being able to dynamically
identify all the attached display devices (pynvidia.probe_displays())
and include them in my metamodes (pynvidia.dynamic_twinview()),
allowing me to detect the available devices at any time despite
changes since boot-time.  Once I have build the list of modelines for
these devices (pynvida.build_modeDB()), I can use that information at
a fairly high level to build the metamodes that are interesting to me.

Since I assume that I can only have 2 devices attached at a time (this
will need to be updated if/when I ever use the HDMI to make this an
invalid assumption), I have the following 7 modes that are of interest to me:

- internal LCD only
- external LCD only (discover resolution dynamically)
- clone internal/external (discover largest common resolution dynamically)
- dual desktop (dynamically discover resolution in all cases)
   - internal left of external
   - internal right of external
   - internal above external
   - internal below external

Using the information in the modeline database, I can generate the
metamode information that describes each of these.  I then add it to
the available metamodes, if not already present (pynvidia.find_or_add()).

*cylce_modes()*

Given a list of mode IDs, it is easy to cycle through them.  First I
search for the current mode in the list, and then find the next mode
(modulus the first 3 modes) and return that, to be invoked by
pynvidia.switch_mode().

*toggle_single_desktop_modes()*

With the list of available modes in a predictable order, it is
possible to write methods that will cycle through these modes in
predictable ways.  Most laptops have some hot-key combination that
cycles through the first three modes:

- internal LCD only
- external LCD only (discover resolution dynamically)
- clone internal/external (discover largest common resolution dynamically)

By passing this sub-list to cycle_modes(), I can replicate that.

*toggle_extended_desktop_modes()*

By passing a list to cycle_modes() that includes everything except the
cloned mode, I can cycle through the extended desktop modes also.

TODO
----

- Probably should determine if/how to clean up modes that are no longer valid.

- Having bound some of these to certain key combinations, the next step is to have them invoked automatically under certain state changing situations:

   - wake from suspend
   - hot docking
   - hot undocking


本源码包内暂不包含可直接显示的源代码文件,请下载源码包。