#!/usr/bin/env python
# Scrape colors from Gnome and import them into Wine through the registry
#
# endolith@gmail.com 2008-09-30
#
# Based on script by KillerKiwi [Ubuntu Forums] October 29th, 2007
# http://ubuntuforums.org/showthread.php?t=55286&page=3#23
#
# which is based on patch by Johannes Roith [Mono-winforms-list] Wed, 27 Aug 2003
# http://lists.ximian.com/pipermail/mono-winforms-list/2003-August/000469.html
import pygtk
import gtk
import os
from tempfile import NamedTemporaryFile
from gconf import Client
def format_color_string(Color):
""" Convert 48-bit gdk.Color to 24-bit "RRR GGG BBB" triple. """
return "%s %s %s" % (Color.red/256, Color.green/256, Color.blue/256)
def format_hex_color(color):
""" Convert from #rrrrggggbbbb string to decimal "RRR GGG BBB" triple. """
r, g, b = color[1:3], color[5:7], color[9:11]
return "%s %s %s" % (int(r,16), int(g,16), int(b,16))
# Get some colors from GTK
# gtk.Style object:
# http://www.moeraki.com/pygtkreference/pygtk2reference/class-gtkstyle.html
# Create a window to scrape colors from
window = gtk.Window()
button = gtk.Button()
vbox = gtk.VBox()
vbox.add(button)
scrollbar = gtk.VScrollbar()
vbox.add(scrollbar)
menubar = gtk.MenuBar()
menuitem = gtk.MenuItem()
menubar.add(menuitem)
vbox.add(menubar)
window.add(vbox)
# On show_all(), these are all converted from gtk.Style objects with wrong
# colors into __main__.EngineStyle objects with correct colors.
window.show_all()
# Tooltips
# http://www.daa.com.au/pipermail/pygtk/2005-November/011353.html
tooltip = gtk.Window()
tooltip.set_name('gtk-tooltips')
tooltip.show_all()
# All of Wine's 31 possible user.reg color values
# Asterisk * next to comment if I've found a value that works for most themes
# Question mark ? next to comment if not sure or can't find anywhere to scrape from
# Some descriptions:
# http://www.quimp.net/gamemaker/system-colors
# http://www.endolith.com/wordpress/2008/08/03/wine-colors/
# http://support.microsoft.com/kb/58336
# http://msdn.microsoft.com/en-us/library/system.drawing.systemcolors_properties(VS.80).aspx
gtk_colors = {
# Doesn't seem to be anything to scrape for these.
'TitleText': window.style.white , #? Active title bar text - white since we're guessing on dark selection color for titlebar
'ActiveTitle': window.style.dark[gtk.STATE_SELECTED] , #? Left end of active title bar - guess on selection color like Clearlooks
'GradientActiveTitle': window.style.light[gtk.STATE_SELECTED] , #? Right end of active title bar - lighter version for gradient
'ActiveBorder': button.style.bg[gtk.STATE_INSENSITIVE] , #? Active window border - same as ButtonFace like Clearlooks
'InactiveTitleText': window.style.white , #? Inactive title bar text - white since we're guessing on dark color for titlebar
'InactiveTitle': window.style.dark[gtk.STATE_NORMAL] , #? Left end of inactive title bar - darker color for gradient
'GradientInactiveTitle': window.style.base[gtk.STATE_NORMAL] , #? Right end of inactive title bar - guess on base color
'InactiveBorder': button.style.bg[gtk.STATE_INSENSITIVE] , #? Inactive window border - same as ButtonFace
'AppWorkSpace': window.style.base[gtk.STATE_NORMAL] , #? BG color of MDI, which aren't used in GTK: use same color as Window, like Glade
'Background': None , #* Scraped from gconf below
'ButtonText': button.style.fg[gtk.STATE_NORMAL] , #* Button/tab text and glyphs
'ButtonHilight': button.style.light[gtk.STATE_INSENSITIVE] , #* Outermost button higlight / Grayed-out button text shadow
'ButtonLight': button.style.bg[gtk.STATE_INSENSITIVE] , #* Inner button highlight, usually same as ButtonFace
'ButtonFace': button.style.bg[gtk.STATE_INSENSITIVE] , #* Background for buttons and all 3D objects
'ButtonAlternateFace': button.style.bg[gtk.STATE_INSENSITIVE] , #* No idea what this does - Set to same as ButtonFace for now
'ButtonShadow': button.style.dark[gtk.STATE_INSENSITIVE] , #* Shadows of buttons / Grayed-out button text
'ButtonDkShadow': button.style.black , #* Outermost shadow of buttons
'GrayText': window.style.fg[gtk.STATE_INSENSITIVE] , # Grayed out text in windows, like labels for unavailable widgets
'Hilight': window.style.base[gtk.STATE_SELECTED] , # Background of selected text
'HilightText': window.style.fg[gtk.STATE_SELECTED] , # Selected text
'HotTrackingColor': window.style.light[gtk.STATE_NORMAL] , # Single-click navigation hover color, doesn't seem to exist in GTK; use lighter ButtonFace color, like CompizConfig Settings Manager
'InfoText': tooltip.style.fg[gtk.STATE_NORMAL] , #* ToolTip text
'InfoWindow': tooltip.style.bg[gtk.STATE_NORMAL] , #* ToolTip background
'Menu': menuitem.style.light[gtk.STATE_ACTIVE] , # Background for menus, also background for menu bars in 3D mode
'MenuBar': menubar.style.bg[gtk.STATE_NORMAL] , # Background for menu bars - rarely seen due to 3D menus
'MenuHilight': menuitem.style.bg[gtk.STATE_PRELIGHT] , # Highlight for flat menus - in 3D mode, Hilight is used instead
'MenuText': menuitem.style.fg[gtk.STATE_NORMAL] , # Menu text
'Scrollbar': scrollbar.style.bg[gtk.STATE_ACTIVE] , # Background color of scrollbar, but only in some apps.
'Window': window.style.base[gtk.STATE_NORMAL] , # Background color of notepad, for instance
'WindowFrame': button.style.mid[gtk.STATE_SELECTED] , # Glow around focused widget
'WindowText': window.style.text[gtk.STATE_NORMAL] , # Text in notepad, for instance
}
# Create list of formatted color value pair strings
# Windows registry values are in the form "name"="data" with no spaces
color_pairs = []
for name, data in gtk_colors.iteritems():
if data:
color_pairs.append('"%s"="%s"' % (name, format_color_string(data)))
# Get desktop background color from gconf, append to color pair list
c = Client()
desktop_color = c.get_value("/desktop/gnome/background/primary_color")
color_pairs.append('"Background"="%s"' % format_hex_color(desktop_color))
# Create a temporary Windows .reg registry file with the new values
# I'm not sure of the meaning of S-1-5-4. This may not work on all systems?
# I do know it is the same number under multiple accounts.
f = NamedTemporaryFile(prefix = "winecolors", suffix = ".reg")
f.write("""REGEDIT4
[HKEY_USERS\S-1-5-4\Control Panel]
[HKEY_USERS\S-1-5-4\Control Panel\Colors]
""")
# Alphabetize list (purely so that user.reg is easy to read; Wine doesn't care)
color_pairs = sorted(color_pairs)
# Append list to file, with newlines
f.writelines(line + '\n' for line in color_pairs)
f.flush()
# Import values into Wine registry using regedit command
print "Using regedit to import colors into registry...\n"
os.system("regedit " + f.name)
# Delete temporary file
f.close()