#!/usr/bin/env python # Scrape colors from Gnome and import them into Wine through the registry # # endolith@gmail.com 2008-08-19 # # 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 import gconf 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) #TODO: tooltips window.add(vbox) # On show_all, these are all converted from gtk.Style objects to __main__.EngineStyle objects window.show_all() # Later destroy window? # All of Wine's 31 possible user.reg color values # Filled in with None if I can't figure out where 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 = { 'ActiveBorder': None , # Active window border - Defined only by window manager? 'ActiveTitle': None , # Left end of active title bar - Defined only by window manager? 'GradientActiveTitle': None , # Right end of active title bar - Defined only by window manager? 'GradientInactiveTitle': None , # Right end of inactive title bar - Defined only by window manager? 'InactiveBorder': None , # Inactive window border - Defined only by window manager? 'InactiveTitle': None , # Left end of inactive title bar - Defined only by window manager? 'InactiveTitleText': None , # Inactive title bar text - Defined only by window manager? 'TitleText': None , # Active title bar text - Defined only by window manager? 'AppWorkSpace': window.style.base[gtk.STATE_NORMAL] , # Background color of multiple-document interface, which really aren't used in GTK; use same color as Window, like Glade 'Background': None , # Scraped from gconf below 'ButtonAlternateFace': button.style.bg[gtk.STATE_INSENSITIVE] , # ??? Set to same as ButtonFace for now 'ButtonDkShadow': button.style.black , # Outermost shadow of buttons 'ButtonFace': button.style.bg[gtk.STATE_INSENSITIVE] , # Button background 'ButtonHilight': button.style.light[gtk.STATE_INSENSITIVE] , # Outermost button higlight, grayed-out button text shadow 'ButtonLight': button.style.bg[gtk.STATE_INSENSITIVE] , # Inner lit up edges of buttons, usually same color as ButtonFace 'ButtonShadow': button.style.dark[gtk.STATE_INSENSITIVE] , # Shadows of buttons, grayed-out button text 'ButtonText': button.style.fg[gtk.STATE_NORMAL] , # Button/tab text and glyphs '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': None , # ToolTip text 'InfoWindow': None , # 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.light[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 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. user_reg = """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) # Turn list into string with newlines between, append to .reg file user_reg += "\n".join(color_pairs) # Debugging # print user_reg # Write the values to a temporary .reg file f=NamedTemporaryFile(prefix="winecolors",suffix=".reg") f.write(user_reg) f.flush() # TODO: This works, but is it proper? # TODO: Just write directly to temp file instead of user_reg variable. # Import values into Wine registry using regedit command print "Using regedit to import colors into registry...\n" os.system("regedit " + f.name) f.close()