File gsd-moblin-osd-enhance.patch of Package gnome-settings-daemon

diff --git a/configure.ac b/configure.ac
index 9e70f4c..08fcf9f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,6 +49,7 @@ GCONF_REQUIRED_VERSION=2.6.1
 GIO_REQUIRED_VERSION=2.17.3
 GNOME_DESKTOP_REQUIRED_VERSION=2.23.90
 LIBNOTIFY_REQUIRED_VERSION=0.4.3
+LIBNM_GLIB_REQUIRED_VERSION=0.7.0
 
 EXTRA_COMPILE_WARNINGS(yes)
 
@@ -68,6 +69,7 @@ PKG_CHECK_MODULES(SETTINGS_PLUGIN,
         gio-2.0 >= $GIO_REQUIRED_VERSION
         libglade-2.0 >= 2.0.0
         dbus-glib-1 >= $DBUS_GLIB_REQUIRED_VERSION
+	libnm_glib >= $LIBNM_GLIB_REQUIRED_VERSION
 )
 
 PKG_CHECK_MODULES(GNOME, libgnome-2.0)
diff --git a/data/apps_gnome_settings_daemon_keybindings.schemas.in b/data/apps_gnome_settings_daemon_keybindings.schemas.in
index 40e5577..24daca9 100644
--- a/data/apps_gnome_settings_daemon_keybindings.schemas.in
+++ b/data/apps_gnome_settings_daemon_keybindings.schemas.in
@@ -25,6 +25,138 @@
 	</schema>
 
         <schema>
+	    <key>/schemas/apps/gnome_settings_daemon/volume_step_icons</key>
+	    <applyto>/apps/gnome_settings_daemon/volume_step_icons</applyto>
+	    <type>bool</type>
+	    <default>FALSE</default>
+	    <locale name="C">
+	        <short>Volume step icons</short>
+		<long>Turn this switch on will hide the volume progress bar, and show volume icon by current level.</long>
+	    </locale>
+	</schema>
+
+        <schema>
+	    <key>/schemas/apps/gnome_settings_daemon/backlight_xrandr</key>
+	    <applyto>/apps/gnome_settings_daemon/backlight_xrandr</applyto>
+	    <type>bool</type>
+	    <default>FALSE</default>
+	    <locale name="C">
+	        <short>Use xrandr turn screen on/off when backlight power on/off</short>
+		<long>When backlight power(bl_power) on/off, set the LDVS screen on/off at the same time.</long>
+	    </locale>
+	</schema>
+
+        <schema>
+	    <key>/schemas/apps/gnome_settings_daemon/cpu_governor_powersave</key>
+	    <applyto>/apps/gnome_settings_daemon/cpu_governor_powersave</applyto>
+	    <type>bool</type>
+	    <default>FALSE</default>
+	    <locale name="C">
+	        <short>Enable/Disable the powersave selection for CPU governor function key</short>
+		<long>Turn this switch on will causes user can be select the CPU governor to powersave by using function key.</long>
+	    </locale>
+	</schema>
+
+	<schema>
+            <key>/schemas/apps/gnome_settings_daemon/wifi_hal_rfkill</key>
+            <applyto>/apps/gnome_settings_daemon/wifi_hal_rfkill</applyto>
+            <type>bool</type>
+            <default>FALSE</default>
+            <locale name="C">
+                <short>The function key will call hal to run killswitch function.</short>
+                <long>If this value is True, function key will call HAL to do rfkill.</long>
+            </locale>
+        </schema>
+
+        <schema>
+	    <key>/schemas/apps/gnome_settings_daemon/wifi_hal_bluetooth_rfkill</key>
+	    <applyto>/apps/gnome_settings_daemon/wifi_hal_bluetooth_rfkill</applyto>
+	    <type>bool</type>
+	    <default>FALSE</default>
+	    <locale name="C">
+	        <short>Enable/Disable bluetooth rfkill for wireless function key</short>
+		<long>Turn this switch on, wifi function key will call HAL to do bluetooth rfkill.</long>
+	    </locale>
+	</schema>
+
+        <schema>
+	    <key>/schemas/apps/gnome_settings_daemon/wifi_hal_wwan_rfkill</key>
+	    <applyto>/apps/gnome_settings_daemon/wifi_hal_wwan_rfkill</applyto>
+	    <type>bool</type>
+	    <default>FALSE</default>
+	    <locale name="C">
+	        <short>Enable/Disable wwan rfkill for wireless function key</short>
+		<long>Turn this switch on, wifi function key will call HAL to do wwan rfkill.</long>
+	    </locale>
+	</schema>
+
+	<schema>
+	    <key>/schemas/apps/gnome_settings_daemon/wifi_show_bluetooth</key>
+	    <applyto>/apps/gnome_settings_daemon/wifi_show_bluetooth</applyto>
+	    <type>bool</type>
+	    <default>FALSE</default>
+	    <locale name="C">
+	        <short>Enable/Disable show bluetooth state for wireless function key</short>
+		<long>Turn this switch on will causes wireless function key show bluetooth state.</long>
+	    </locale>
+	</schema>
+
+	<schema>
+	    <key>/schemas/apps/gnome_settings_daemon/wifi_show_wwan</key>
+	    <applyto>/apps/gnome_settings_daemon/wifi_show_wwan</applyto>
+	    <type>bool</type>
+	    <default>FALSE</default>
+	    <locale name="C">
+	        <short>Enable/Disable show wwan(3G) state for wireless function key</short>
+		<long>Turn this switch on will causes wireless function key show wwan(3G) state.</long>
+	    </locale>
+	</schema>
+
+        <schema>
+	    <key>/schemas/apps/gnome_settings_daemon/toggle_touchpad</key>
+	    <applyto>/apps/gnome_settings_daemon/toggle_touchpad</applyto>
+	    <type>bool</type>
+	    <default>TRUE</default>
+	    <locale name="C">
+	        <short>Toggle Touchpad</short>
+		<long>Toggle the touchpad on/off status when then touchpad Fn key is pressed.</long>
+	    </locale>
+	</schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/draw_osd_box</key>
+            <applyto>/apps/gnome_settings_daemon/draw_osd_box</applyto>
+            <type>bool</type>
+            <default>TRUE</default>
+            <locale name="C">
+                <short>Draw OSD background box</short>
+                <long>Draw a box on OSD's background.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/osd_window_size</key>
+            <applyto>/apps/gnome_settings_daemon/osd_window_size</applyto>
+            <type>int</type>
+            <default>130</default>
+            <locale name="C">
+                <short>OSD window size</short>
+                <long>Setup OSD window size.</long>
+            </locale>
+        </schema>
+
+	<schema>
+            <key>/schemas/apps/gnome_settings_daemon/cust_theme</key>
+            <applyto>/apps/gnome_settings_daemon/cust_theme</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Customer OSD theme</short>
+                <long>Setup customer OSD theme.</long>
+            </locale>
+        </schema>
+
+        <schema>
             <key>/schemas/apps/gnome_settings_daemon/keybindings/volume_mute</key>
             <applyto>/apps/gnome_settings_daemon/keybindings/volume_mute</applyto>
             <type>string</type>
@@ -248,5 +380,137 @@
             </locale>
         </schema>
 
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/num_lock</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/num_lock</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Number Lock</short>
+                <long>Binding to do something with Number Lock.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/scroll_lock</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/scroll_lock</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Scroll Lock</short>
+                <long>Binding to do something with Scroll Lock.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/wifi</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/wifi</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Wifi on/off</short>
+                <long>Binding to do something with Wifi on/off.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/touchpad_on</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/touchpad_on</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Touchpad on</short>
+                <long>Binding to do something with Touchpad on.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/touchpad_off</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/touchpad_off</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Touchpad off</short>
+                <long>Binding to do something with Touchpad off.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/xrandr</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/xrandr</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Xrandr</short>
+                <long>Use Xrandr to change screen status: LCD->CRT->CLONE->DUAL.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/cpu_governor</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/cpu_governor</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>CPU governor</short>
+                <long>Setup CPU governor by 3 different model.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/backlight</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/backlight</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Backlight power</short>
+                <long>Turn on/off or setup backlight power status.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/performance</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/performance</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Change the performance level</short>
+                <long>Use function key to change the performance level on this machine.HAL reference: 10-samsung-performance.fdi</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/esc</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/esc</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Interrupt when function key feature was launched</short>
+                <long>A bit function key feature is launched after OSD fade out and hide, this key can interrupt those keys.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/webcam</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/webcam</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>WebCam on/off</short>
+                <long>Binding to do something with WebCam on/off.</long>
+            </locale>
+        </schema>
+
+        <schema>
+            <key>/schemas/apps/gnome_settings_daemon/keybindings/bluetooth</key>
+            <applyto>/apps/gnome_settings_daemon/keybindings/bluetooth</applyto>
+            <type>string</type>
+            <default></default>
+            <locale name="C">
+                <short>Bluetooth on/off</short>
+                <long>Binding to do something with Bluetooth on/off.</long>
+            </locale>
+        </schema>
+
     </schemalist>
 </gconfschemafile>
diff --git a/plugins/media-keys/actions/acme.h b/plugins/media-keys/actions/acme.h
index eb5bc5e..b6bbe72 100644
--- a/plugins/media-keys/actions/acme.h
+++ b/plugins/media-keys/actions/acme.h
@@ -46,6 +46,18 @@ enum {
         STOP_KEY,
         PREVIOUS_KEY,
         NEXT_KEY,
+	NUM_LOCK_KEY,
+	SCROLL_LOCK_KEY,
+	WIFI_KEY,
+	TOUCHPAD_ON_KEY,
+	TOUCHPAD_OFF_KEY,
+	XRANDR_KEY,
+	CPU_GOVERNOR_KEY,
+	BACKLIGHT_KEY,
+	PERFORMANCE_KEY,
+	ESC_KEY,
+	WEBCAM_KEY,
+	BLUETOOTH_KEY,
         HANDLED_KEYS
 };
 
@@ -74,6 +86,18 @@ static struct {
         { STOP_KEY, GCONF_BINDING_DIR "/stop", NULL, NULL },
         { PREVIOUS_KEY, GCONF_BINDING_DIR "/previous", NULL, NULL },
         { NEXT_KEY, GCONF_BINDING_DIR "/next", NULL, NULL },
+        { NUM_LOCK_KEY, GCONF_BINDING_DIR "/num_lock", NULL, NULL },
+        { SCROLL_LOCK_KEY, GCONF_BINDING_DIR "/scroll_lock", NULL, NULL },
+        { WIFI_KEY, GCONF_BINDING_DIR "/wifi", NULL, NULL },
+        { TOUCHPAD_ON_KEY, GCONF_BINDING_DIR "/touchpad_on", NULL, NULL },
+        { TOUCHPAD_OFF_KEY, GCONF_BINDING_DIR "/touchpad_off", NULL, NULL },
+        { XRANDR_KEY, GCONF_BINDING_DIR "/xrandr", NULL, NULL },
+        { CPU_GOVERNOR_KEY, GCONF_BINDING_DIR "/cpu_governor", NULL, NULL },
+        { BACKLIGHT_KEY, GCONF_BINDING_DIR "/backlight", NULL, NULL },
+        { PERFORMANCE_KEY, GCONF_BINDING_DIR "/performance", NULL, NULL },
+        { ESC_KEY, GCONF_BINDING_DIR "/esc", NULL, NULL },
+        { WEBCAM_KEY, GCONF_BINDING_DIR "/webcam", NULL, NULL },
+        { BLUETOOTH_KEY, GCONF_BINDING_DIR "/bluetooth", NULL, NULL },
 };
 
 #endif /* __ACME_H__ */
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index a949116..e91bee6 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -44,6 +44,12 @@
 #include <libhal-glib/hal-manager.h>
 #include <libhal-glib/hal-device.h>
 
+#include <X11/XKBlib.h>
+#include <X11/extensions/Xrandr.h>
+
+#include <nm-client.h>
+#include <nm-device-wifi.h>
+
 #include "gnome-settings-profile.h"
 #include "gsd-marshal.h"
 #include "gsd-media-keys-manager.h"
@@ -73,7 +79,8 @@ struct GsdMediaKeysManagerPrivate
         AcmeVolume      *volume;
         GtkWidget       *dialog;
         GConfClient     *conf_client;
-        HalDevice 	*hk_device;
+	HalManager    	*manager;
+	GList         	*devices;
 
         /* Multihead stuff */
         GdkScreen       *current_screen;
@@ -82,7 +89,41 @@ struct GsdMediaKeysManagerPrivate
         GList           *media_players;
 
         DBusGConnection *connection;
+        DBusGConnection *sys_connection;
         guint            notify[HANDLED_KEYS];
+
+	/* variables for key post action  */
+	int 		 type_for_hide;
+	gboolean	 osd_window_showing;
+	gboolean	 esc_post_action;
+	Key 		*esc_key;
+
+	/* OSD window parameter */
+        gboolean 	 draw_osd_box;
+	int 		 osd_window_size;
+	gboolean 	 volume_step_icons;
+
+        /* customer OSD theme */
+        GtkIconTheme    *cust_theme;
+
+	/* hotkey properties */
+	GsdMediaKeysXrandr	xrandr;
+	GsdMediaKeysXrandr	last_xrandr;
+	gboolean		backlight_xrandr;
+	gboolean		cpu_governor_powersave;
+
+	GsdMediaKeysWifi	wifi_state;
+	gboolean		wifi_hal_rfkill;
+	gboolean		wifi_hal_bluetooth_rfkill;
+	gboolean		wifi_hal_wwan_rfkill;
+	gboolean		wifi_show_bluetooth;
+	gboolean		wifi_show_wwan;
+
+	gint			p_num_levels;
+	gint			p_level;
+
+	gboolean		toggle_touchpad;
+	gboolean		touchpad_enabled;
 };
 
 enum {
@@ -199,6 +240,7 @@ execute (GsdMediaKeysManager *manager,
 
         if (g_shell_parse_argv (exec, &argc, &argv, NULL)) {
                 if (sync != FALSE) {
+			gchar *output_str;
                         retval = g_spawn_sync (g_get_home_dir (),
                                                argv,
                                                NULL,
@@ -234,16 +276,257 @@ execute (GsdMediaKeysManager *manager,
         g_free (exec);
 }
 
+static gboolean
+is_lvds (XRROutputInfo *output_info)
+{
+        const char *output_name = output_info->name;
+
+        if (output_info->connection == RR_Connected &&
+	    output_name &&
+            (strstr (output_name, "lvds")       ||
+             strstr (output_name, "LVDS")       ||
+             strstr (output_name, "Lvds")))
+        {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+static gboolean
+is_crt_connected (gchar **lcd, gint *lcd_width, gint *lcd_height,
+                  gchar **crt, gint *crt_width, gint *crt_height)
+{
+    	Display  *dpy;
+	int	  i, screen;
+    	Window    root;
+        int	  minWidth, maxWidth, minHeight, maxHeight;
+    	XRRScreenResources  *res;
+	gboolean 	     crt_connected = FALSE;
+//	gboolean lcd_connected = FALSE;	TODO: lcd mode off?
+
+	dpy = XOpenDisplay (NULL);
+        screen = DefaultScreen (dpy);
+	root = RootWindow (dpy, screen);
+
+	XRRGetScreenSizeRange (dpy, root, &minWidth, &minHeight,
+                               &maxWidth, &maxHeight);
+    	res = XRRGetScreenResources (dpy, root);
+    	if (!res) {
+		g_warning ("could not get screen resources");
+		return FALSE;
+    	}
+
+	/* check it has right status to CRT mode */
+	for (i = 0; i < res->noutput; i++)
+    	{
+        	XRROutputInfo   *output_info = XRRGetOutputInfo (dpy, res, res->outputs[i]);
+                XRRModeInfo	*mode_info = NULL;
+                int             j, k;
+        	if (!output_info) {
+                	g_debug ("could not get output 0x%x information\n", res->outputs[i]);
+                	continue;
+        	}
+
+                for (j = 0; j < res->nmode; j++)
+                        if (res->modes[j].id == *(output_info->modes))
+                                mode_info = &res->modes[j];
+
+		/* check if is LVDS (LCD, internal monitor) */
+		if (is_lvds(output_info)) {
+			*lcd = g_strdup (output_info->name);
+                        if (mode_info) {
+                                if (lcd_width)
+                                        *lcd_width = mode_info->width;
+                                if (lcd_height)
+                                        *lcd_height = mode_info->height;
+                        } else {
+                                if (lcd_width)
+                                        *lcd_width = 800;
+                                if (lcd_height)
+                                        *lcd_height = 600;
+                        }
+			//TODO: lcd mode is on/off?
+		} else {
+			*crt = g_strdup (output_info->name);
+			crt_connected = (output_info->connection == RR_Connected);
+                        if (mode_info) {
+                                if (crt_width)
+                                        *crt_width = mode_info->width;
+                                if (crt_height)
+                                        *crt_height = mode_info->height;
+                        } else {
+                                if (crt_width)
+                                        *crt_width = 800;
+                                if (crt_height)
+                                        *crt_height = 600;
+                        }
+		}
+	}
+
+	return crt_connected;
+}
+
 static void
-do_sleep_action (char *cmd1,
-                 char *cmd2)
+do_xrandr_post_action (GsdMediaKeysManager *manager)
+{
+	gchar *lcd = NULL, *crt = NULL;
+        gint lcd_width = 0, lcd_height = 0, crt_width = 0, crt_height = 0;
+
+        sleep (1);
+	if (is_crt_connected (&lcd, &lcd_width, &lcd_height,
+                              &crt, &crt_width, &crt_height)) {
+		gchar	command1[255], command2[255];
+
+		/* change to next status when hotkey click*/
+		switch (manager->priv->xrandr) {
+		case GSD_MEDIA_KEYS_XRANDR_LCD_ONLY:
+			break;
+		case GSD_MEDIA_KEYS_XRANDR_LCD:
+			g_snprintf (command1, 255, "/usr/bin/xrandr --output %s --auto", lcd);
+			execute (manager, command1, FALSE, FALSE);
+			g_snprintf (command2, 255, "/usr/bin/xrandr --output %s --off", crt);
+			execute (manager, command2, FALSE, FALSE);
+			break;
+		case GSD_MEDIA_KEYS_XRANDR_CRT:
+			if (manager->priv->last_xrandr != GSD_MEDIA_KEYS_XRANDR_CRT) {
+                                g_snprintf (command1, 255, "/usr/bin/xrandr --output %s --off", crt);
+                                execute (manager, command1, FALSE, FALSE);
+                                sleep (1);
+                        }
+			g_snprintf (command1, 255, "/usr/bin/xrandr --output %s --auto", crt);
+			execute (manager, command1, FALSE, FALSE);
+			g_snprintf (command2, 255, "/usr/bin/xrandr --output %s --off", lcd);
+			execute (manager, command2, FALSE, FALSE);
+			break;
+		case GSD_MEDIA_KEYS_XRANDR_CLONE:
+			if (manager->priv->last_xrandr == GSD_MEDIA_KEYS_XRANDR_DUAL) {
+				g_snprintf (command1, 255, "/usr/bin/xrandr --output %s --off", crt);
+				execute (manager, command1, FALSE, FALSE);
+				sleep (1);
+			}
+			g_snprintf (command2, 255, "/usr/bin/xrandr --output %s --auto", lcd);
+			execute (manager, command2, FALSE, FALSE);
+			g_snprintf (command1, 255, "/usr/bin/xrandr --output %s --mode %dx%d --scale %fx%f", crt, crt_width, crt_height, (double) lcd_width / crt_width, (double) lcd_height / crt_height);
+			execute (manager, command1, FALSE, FALSE);
+			break;
+		case GSD_MEDIA_KEYS_XRANDR_DUAL:
+			/* TODO: virtual desktop can't large than 2048x2048? */
+			//TODO: capture the virtual desktop size and choice the best resolution
+                        if (manager->priv->last_xrandr != GSD_MEDIA_KEYS_XRANDR_DUAL) {
+                                g_snprintf (command2, 255, "/usr/bin/xrandr --output %s --off", crt);
+                                execute (manager, command2, FALSE, FALSE);
+                                sleep (1);
+                        }
+			g_snprintf (command1, 255, "/usr/bin/xrandr --output %s --auto", lcd);
+			execute (manager, command1, FALSE, FALSE);
+                        sleep (1);
+                        g_snprintf (command2, 255, "/usr/bin/xrandr --output %s --mode %dx%d --below %s --scale %fx%f", crt, crt_width, crt_height, lcd, (double) lcd_width / crt_width, (double) lcd_width / crt_width);
+			execute (manager, command2, FALSE, FALSE);
+			break;
+		}
+	} else {
+		if (manager->priv->xrandr != manager->priv->last_xrandr) {
+			gchar	command1[255], command2[255];
+
+			g_snprintf (command1, 255, "/usr/bin/xrandr --output %s --auto", lcd);
+			execute (manager, command1, FALSE, FALSE);
+			g_snprintf (command2, 255, "/usr/bin/xrandr --output %s --off", crt);
+			execute (manager, command2, FALSE, FALSE);
+		}
+		manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_LCD_ONLY;
+	}
+	manager->priv->last_xrandr = manager->priv->xrandr;
+
+	g_free (lcd);
+	g_free (crt);
+}
+
+static void
+do_xrandr_esc_post_action (GsdMediaKeysManager *manager)
 {
-        if (g_spawn_command_line_async (cmd1, NULL) == FALSE) {
-                if (g_spawn_command_line_async (cmd2, NULL) == FALSE) {
-                        acme_error (_("Couldn't put the machine to sleep.\n"
-                                        "Verify that the machine is correctly configured."));
+	/* change back to last status when hotkey click*/
+	manager->priv->xrandr = manager->priv->last_xrandr;
+/*
+	switch (manager->priv->xrandr) {
+	case GSD_MEDIA_KEYS_XRANDR_LCD_ONLY:
+		manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_LCD;
+		break;
+	case GSD_MEDIA_KEYS_XRANDR_LCD:
+		manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_CRT;
+		break;
+	case GSD_MEDIA_KEYS_XRANDR_CRT:
+		manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_CLONE;
+		break;
+	case GSD_MEDIA_KEYS_XRANDR_CLONE:
+		manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_DUAL;
+		break;
+	case GSD_MEDIA_KEYS_XRANDR_DUAL:
+		manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_LCD;
+		break;
+	}
+*/
+}
+
+static void
+do_performance_post_action (GsdMediaKeysManager *manager)
+{
+	if (manager->priv->p_level >= 0) {
+
+		DBusGProxy *proxy;
+		GError *error = NULL;
+
+		//set new performance level
+		proxy = dbus_g_proxy_new_for_name (manager->priv->sys_connection,
+						  "org.freedesktop.Hal",
+						   "/org/freedesktop/Hal/devices/performance",
+						   "org.freedesktop.Hal.Device.Performance");
+		if (!dbus_g_proxy_call (proxy, "SetPerformance", &error,
+						G_TYPE_INT, manager->priv->p_level ,
+						G_TYPE_INVALID, G_TYPE_INVALID)) {
+			g_print ("DBus method call failed\n");
+		}
+
+		if (proxy)
+			g_object_unref (proxy);
+	}
+}
+
+static void
+_dialog_hide_cb (GtkWidget   	     *dialog,
+                 GsdMediaKeysManager *manager)
+{
+	g_debug ("got dialog hide cb");
+
+	if (!manager->priv->esc_post_action) {
+		switch (manager->priv->type_for_hide) {
+		case XRANDR_KEY:
+			do_xrandr_post_action (manager);
+			break;
+        	case PERFORMANCE_KEY:
+                	do_performance_post_action (manager);
+                	break;
+		default:
+			break;
+		}
+	} else {
+                switch (manager->priv->type_for_hide) {
+                case XRANDR_KEY:
+                        do_xrandr_esc_post_action (manager);
+                        break;
+                default:
+                        break;
                 }
-        }
+	}
+
+	/* reset key type and variables for post action */
+	manager->priv->type_for_hide = -1;
+	manager->priv->esc_post_action = FALSE;
+	manager->priv->osd_window_showing = FALSE;
+
+	/* un-grab the esc key */
+	if (manager->priv->esc_key != NULL)
+		grab_key (manager->priv->esc_key, FALSE, manager->priv->screens);
 }
 
 static void
@@ -257,6 +540,19 @@ dialog_init (GsdMediaKeysManager *manager)
 
         if (manager->priv->dialog == NULL) {
                 manager->priv->dialog = gsd_media_keys_window_new ();
+        	gsd_media_keys_window_set_draw_osd_box (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+							manager->priv->draw_osd_box);
+                gsd_media_keys_window_set_osd_window_size (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                           manager->priv->osd_window_size);
+        	gsd_media_keys_window_set_volume_step_icons (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+							     manager->priv->volume_step_icons);
+		gsd_media_keys_window_set_cust_theme (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                      manager->priv->cust_theme);
+
+		g_signal_connect (manager->priv->dialog,
+      				  "hide",
+                        	  (GCallback)_dialog_hide_cb,
+                        	  manager);
         }
 }
 
@@ -283,6 +579,9 @@ update_kbd_cb (GConfClient         *client,
 
         g_return_if_fail (entry->key != NULL);
 
+	manager->priv->type_for_hide = -1;
+	manager->priv->esc_key = NULL;
+
         /* Find the key that was modified */
         for (i = 0; i < HANDLED_KEYS; i++) {
                 if (strcmp (entry->key, keys[i].gconf_key) == 0) {
@@ -327,6 +626,12 @@ update_kbd_cb (GConfClient         *client,
                                 break;
                         }
 
+			/* ESC key is only grab when OSD window showing  */
+			if (keys[i].key_type == ESC_KEY) {
+				manager->priv->esc_key = key;
+				continue;
+			}
+
                         grab_key (key, TRUE, manager->priv->screens);
                         keys[i].key = key;
 
@@ -342,6 +647,9 @@ init_kbd (GsdMediaKeysManager *manager)
 {
         int i;
 
+	manager->priv->type_for_hide = -1;
+	manager->priv->esc_key = NULL;
+
         gnome_settings_profile_start (NULL);
 
         for (i = 0; i < HANDLED_KEYS; i++) {
@@ -400,14 +708,20 @@ init_kbd (GsdMediaKeysManager *manager)
 
                 keys[i].key = key;
 
-                grab_key (key, TRUE, manager->priv->screens);
+		/* ESC key is only grab when OSD window showing  */
+		if (keys[i].key_type == ESC_KEY) {
+			manager->priv->esc_key = key;
+			continue;
+		}
+
+		grab_key (key, TRUE, manager->priv->screens);
         }
 
         gnome_settings_profile_end (NULL);
 }
 
 static void
-dialog_show (GsdMediaKeysManager *manager)
+dialog_show_m (GsdMediaKeysManager *manager, int w_m)
 {
         int            orig_w;
         int            orig_h;
@@ -431,6 +745,8 @@ dialog_show (GsdMediaKeysManager *manager)
          * know its true size, yet, so we need to jump through hoops
          */
         gtk_window_get_default_size (GTK_WINDOW (manager->priv->dialog), &orig_w, &orig_h);
+	gtk_window_resize (GTK_WINDOW(manager->priv->dialog), orig_w*w_m, orig_h);
+	orig_w = orig_w * w_m;
         gtk_widget_size_request (manager->priv->dialog, &win_req);
 
         if (win_req.width > orig_w) {
@@ -470,11 +786,22 @@ dialog_show (GsdMediaKeysManager *manager)
         gtk_window_move (GTK_WINDOW (manager->priv->dialog), x, y);
 
         gtk_widget_show (manager->priv->dialog);
+	manager->priv->osd_window_showing = TRUE;
+
+	/* grab the esc key */
+	if (manager->priv->esc_key != NULL)
+		grab_key (manager->priv->esc_key, TRUE, manager->priv->screens);
 
         gdk_display_sync (gdk_screen_get_display (manager->priv->current_screen));
 }
 
 static void
+dialog_show (GsdMediaKeysManager *manager)
+{
+	dialog_show_m (manager, 1);
+}
+
+static void
 do_unknown_action (GsdMediaKeysManager *manager,
                    const char          *url)
 {
@@ -691,11 +1018,626 @@ do_sound_action (GsdMediaKeysManager *manager,
                                                 muted);
         gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
                                                 vol);
+        gsd_media_keys_window_set_volume_step (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                vol_step);
+        gsd_media_keys_window_set_is_mute_key (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                               type == MUTE_KEY);
         gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
                                           GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME);
         dialog_show (manager);
 }
 
+static void
+do_sleep_action (GsdMediaKeysManager *manager,
+                 char *cmd1,
+                 char *cmd2)
+{
+	if (g_spawn_command_line_async (cmd1, NULL) == FALSE) {
+		if (g_spawn_command_line_async (cmd2, NULL) == FALSE) {
+			acme_error (_("Couldn't put the machine to sleep.\n"
+					"Verify that the machine is correctly configured."));
+		}
+	}
+}
+
+static void
+do_num_lock_action (GsdMediaKeysManager *manager)
+{
+	Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+        unsigned int state = 0;
+
+        dialog_init (manager);
+        XkbGetIndicatorState(display, XkbUseCoreKbd, &state);
+        gsd_media_keys_window_set_num_locked (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                              state & (1 << 1));
+        gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                          GSD_MEDIA_KEYS_WINDOW_ACTION_NUM_LOCK);
+        dialog_show (manager);
+}
+
+static void
+do_scroll_lock_action (GsdMediaKeysManager *manager)
+{
+        Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+        unsigned int state = 0;
+
+        dialog_init (manager);
+        XkbGetIndicatorState(display, XkbUseCoreKbd, &state);
+	g_debug ("scroll_lock: %d", state & (1 << 2));
+        gsd_media_keys_window_set_scroll_locked (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                 state & (1 << 2));
+        gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                          GSD_MEDIA_KEYS_WINDOW_ACTION_SCROLL_LOCK);
+        dialog_show (manager);
+}
+
+static void
+do_hal_rfkill (GsdMediaKeysManager *manager, gchar *rfkill_type, gboolean enable)
+{
+        gchar **names;
+        GError *error = NULL;
+        gchar *udi;
+        gint i;
+
+	hal_manager_find_device_string_match (manager->priv->manager,
+						"killswitch.type",
+						rfkill_type,
+						&names,
+						&error);
+        for (i = 0, udi = names[i]; udi != NULL; i++, udi = names[i]) {
+		DBusGProxy *proxy;
+		guint state = -1;
+
+		g_debug ("do_hal_rfkill udi: %s", udi);
+		proxy = dbus_g_proxy_new_for_name (manager->priv->sys_connection,
+						  "org.freedesktop.Hal",
+						   udi,
+						   "org.freedesktop.Hal.Device.KillSwitch");
+		//set new state
+		gboolean wifi_enabled = (state == 0)? FALSE:TRUE;
+		if (dbus_g_proxy_call (proxy, "SetPower", &error,
+					G_TYPE_BOOLEAN, enable,
+					G_TYPE_INVALID, G_TYPE_INVALID) < 0) {
+			g_print ("DBus SetPower method call failed\n");
+		}
+
+		if (proxy)
+			g_object_unref (proxy);
+	}
+}
+
+static gboolean
+is_wifi_enabled (GsdMediaKeysManager *manager)
+{
+        gboolean  wifi_enabled;
+
+	/* check current wifi status, priority:
+	   a. hardware device disappear?
+	   b. rfkill state */
+	/* check have available net.80211 */
+	gchar **names;
+	GError *error = NULL;
+	HalDevice *device;
+	gchar *udi;
+
+	hal_manager_find_capability (manager->priv->manager,
+					"net.80211",
+					&names,
+					&error);
+	wifi_enabled = FALSE;
+	udi = names[0];
+
+	/* just need check the first net.80211 device */
+	if (udi != NULL) {
+		gchar *parent_udi;
+		gchar **p_names;
+
+		device = hal_device_new ();
+		hal_device_set_udi (device, udi);
+		hal_device_get_string (device, "info.parent", &parent_udi, &error);
+
+		hal_manager_find_device_string_match (manager->priv->manager,
+							"info.udi",
+							parent_udi,
+							&p_names,
+							&error);
+		wifi_enabled = (p_names[0] != NULL)? TRUE:FALSE;
+		if (p_names[0] != NULL)
+			g_debug ("wifi parent: %s", p_names[0]);
+	}
+
+	return wifi_enabled;
+}
+
+static gboolean
+is_bluetooth_enabled (GsdMediaKeysManager *manager)
+{
+	gboolean bluetooth_enabled;
+	DBusGProxy *proxy;
+	gchar **names;
+	GError *error = NULL;
+
+	/* check current wifi status, priority:
+	   a. hardware device disappear?
+	   b. rfkill state */
+	/* TODO: check hardware device disappear */
+	/* check rfkill state */
+	hal_manager_find_device_string_match (manager->priv->manager,
+						"killswitch.type",
+						"bluetooth",
+						&names,
+						&error);
+	if (names[0] != NULL) {
+                guint state = -1;
+
+		g_debug ("bluetooth: %s", names[0]);
+                proxy = dbus_g_proxy_new_for_name (manager->priv->sys_connection,
+                                                  "org.freedesktop.Hal",
+                                                   names[0],
+                                                   "org.freedesktop.Hal.Device.KillSwitch");
+                if (!dbus_g_proxy_call (proxy, "GetPower", &error,
+                                        G_TYPE_INVALID,
+                                        G_TYPE_INT, &state, G_TYPE_INVALID)) {
+                        g_print ("DBus GetPower method call failed\n");
+			bluetooth_enabled = FALSE;
+                }
+
+                g_debug ("state: %d", state);
+		bluetooth_enabled = (state > 0)? TRUE:FALSE;
+
+                if (proxy)
+                        g_object_unref (proxy);
+
+	} else {
+		bluetooth_enabled = FALSE;
+	}
+
+	return bluetooth_enabled;
+}
+
+static gboolean
+is_wwan_enabled (GsdMediaKeysManager *manager)
+{
+	gboolean wwan_enabled;
+	DBusGProxy *proxy;
+	gchar **names;
+	GError *error = NULL;
+
+	/* check current wifi status, priority:
+	   a. hardware device disappear?
+	   b. rfkill state */
+	/* TODO: check hardware device disappear */
+		/* modem.command_sets = {'GSM-07.07', 'GSM-07.05'} (string list) */
+	/* check rfkill state */
+	hal_manager_find_device_string_match (manager->priv->manager,
+						"killswitch.type",
+						"wwan",
+						&names,
+						&error);
+	if (names[0] != NULL) {
+                guint state = -1;
+
+		g_debug ("wwan uid: %s", names[0]);
+                proxy = dbus_g_proxy_new_for_name (manager->priv->sys_connection,
+                                                  "org.freedesktop.Hal",
+                                                   names[0],
+                                                   "org.freedesktop.Hal.Device.KillSwitch");
+                if (!dbus_g_proxy_call (proxy, "GetPower", &error,
+                                        G_TYPE_INVALID,
+                                        G_TYPE_INT, &state, G_TYPE_INVALID)) {
+                        g_print ("DBus GetPower method call failed\n");
+			wwan_enabled = FALSE;
+                }
+
+                g_debug ("state: %d", state);
+		wwan_enabled = (state > 0)? TRUE:FALSE;
+
+                if (proxy)
+                        g_object_unref (proxy);
+
+	} else {
+		wwan_enabled = FALSE;
+	}
+
+	return wwan_enabled;
+}
+
+static gboolean
+is_rfkill_exists (GsdMediaKeysManager *manager, gchar *rfkill_type)
+{
+	DBusGProxy *proxy;
+	gchar **names;
+	GError *error = NULL;
+
+	hal_manager_find_device_string_match (manager->priv->manager,
+						"killswitch.type",
+						rfkill_type,
+						&names,
+						&error);
+
+	return (names[0] != NULL);
+}
+
+static void
+do_wifi_action (GsdMediaKeysManager *manager)
+{
+        gboolean	wlan_exists, bluetooth_exists, wwan_exists;
+        gboolean	wifi_enabled, bluetooth_enabled, wwan_enabled;
+        gboolean	wifi_rfkill, bluetooth_rfkill, wwan_rfkill;
+        gboolean	bluetooth_show, wwan_show;
+	int		rfkill_num = 0;
+	int		icon_num = 1;
+
+	/* get the current devices status */
+	wifi_rfkill = manager->priv->wifi_hal_rfkill;
+	bluetooth_rfkill = manager->priv->wifi_hal_bluetooth_rfkill;
+	wwan_rfkill = manager->priv->wifi_hal_wwan_rfkill;
+
+	wlan_exists  = is_rfkill_exists (manager, "wlan");
+	bluetooth_exists  = is_rfkill_exists (manager, "bluetooth");
+	wwan_exists  = is_rfkill_exists (manager, "wwan");
+
+	bluetooth_show = manager->priv->wifi_show_bluetooth && bluetooth_exists;
+	wwan_show = manager->priv->wifi_show_wwan && wwan_exists;
+
+	rfkill_num += (wlan_exists && wifi_rfkill)? 1:0;
+	rfkill_num += (bluetooth_exists && bluetooth_rfkill)? 1:0;
+	rfkill_num += (wwan_exists && wwan_rfkill)? 1:0;
+
+	/* change to next status when hotkey click*/
+	if (rfkill_num == 0)
+		goto show_wifi;
+
+	switch (manager->priv->wifi_state) {
+	case GSD_MEDIA_KEYS_WIFI_ENABLE_ALL:
+		if (wlan_exists && wifi_rfkill) {
+			manager->priv->wifi_state = GSD_MEDIA_KEYS_WIFI_ENABLE_WLAN;
+			do_hal_rfkill (manager, "wlan", TRUE);
+			if (bluetooth_exists && bluetooth_rfkill)
+				do_hal_rfkill (manager, "bluetooth", FALSE);
+			if (wwan_exists && wwan_rfkill)
+				do_hal_rfkill (manager, "wwan", FALSE);
+			break;
+		}
+	case GSD_MEDIA_KEYS_WIFI_ENABLE_WLAN:
+		if (bluetooth_exists && bluetooth_rfkill) {
+			manager->priv->wifi_state = GSD_MEDIA_KEYS_WIFI_ENABLE_BLUETOOTH;
+			do_hal_rfkill (manager, "bluetooth", TRUE);
+ 			if (wlan_exists && wifi_rfkill)
+				do_hal_rfkill (manager, "wlan", FALSE);
+			if (wwan_exists && wwan_rfkill)
+				do_hal_rfkill (manager, "wwan", FALSE);
+			break;
+		}
+	case GSD_MEDIA_KEYS_WIFI_ENABLE_BLUETOOTH:
+		if (wwan_exists && wwan_rfkill) {
+			manager->priv->wifi_state = GSD_MEDIA_KEYS_WIFI_ENABLE_WWAN;
+			do_hal_rfkill (manager, "wwan", TRUE);
+ 			if (wlan_exists && wifi_rfkill)
+				do_hal_rfkill (manager, "wlan", FALSE);
+			if (bluetooth_exists && bluetooth_rfkill)
+				do_hal_rfkill (manager, "bluetooth", FALSE);
+			break;
+		}
+	case GSD_MEDIA_KEYS_WIFI_ENABLE_WWAN:
+		manager->priv->wifi_state = GSD_MEDIA_KEYS_WIFI_DISABLE_ALL;
+		if (wlan_exists && wifi_rfkill)
+			do_hal_rfkill (manager, "wlan", FALSE);
+		if (bluetooth_exists && bluetooth_rfkill)
+			do_hal_rfkill (manager, "bluetooth", FALSE);
+		if (wwan_exists && wwan_rfkill)
+			do_hal_rfkill (manager, "wwan", FALSE);
+		if (rfkill_num == 1)
+			manager->priv->wifi_state = GSD_MEDIA_KEYS_WIFI_ENABLE_ALL;
+		break;
+	case GSD_MEDIA_KEYS_WIFI_DISABLE_ALL:
+		manager->priv->wifi_state = GSD_MEDIA_KEYS_WIFI_ENABLE_ALL;
+		if (wlan_exists && wifi_rfkill)
+			do_hal_rfkill (manager, "wlan", TRUE);
+		if (bluetooth_exists && bluetooth_rfkill)
+			do_hal_rfkill (manager, "bluetooth", TRUE);
+		if (wwan_exists && wwan_rfkill)
+			do_hal_rfkill (manager, "wwan", TRUE);
+		break;
+	}
+
+show_wifi:
+
+        /* check the wifi state */
+	if (manager->priv->wifi_show_bluetooth || manager->priv->wifi_show_wwan)
+		g_usleep (1000000);      // 1 second to wait USB H/W on/off
+	else
+		g_usleep (500000);      // 0.5 second to wait PCI H/W on/off
+
+	wifi_enabled = is_wifi_enabled (manager);
+
+	if (bluetooth_show) {
+		//TODO: check have no this device?
+		bluetooth_enabled = is_bluetooth_enabled (manager);	//TODO: check have rfkill interface
+		icon_num++;		//TODO: if have no rfkill interface, icon_num-- and set not show bluetooth
+	}
+	if (wwan_show) {
+		wwan_enabled = is_wwan_enabled (manager);	//TODO: check have rfkill interface
+		icon_num++;
+	}
+
+	dialog_init (manager);
+        gsd_media_keys_window_set_wifi_enabled (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                wifi_enabled);
+        gsd_media_keys_window_set_bluetooth_enabled (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+						bluetooth_enabled);
+        gsd_media_keys_window_set_wwan_enabled (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+						wwan_enabled);
+        gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                          GSD_MEDIA_KEYS_WINDOW_ACTION_WIFI);
+        gsd_media_keys_window_set_wifi_show_bluetooth (manager->priv->dialog,
+							bluetooth_show);
+	gsd_media_keys_window_set_wifi_show_wwan (manager->priv->dialog,
+							wwan_show);
+	dialog_show_m (manager, icon_num);
+}
+
+static void
+do_bluetooth_action (GsdMediaKeysManager *manager)
+{
+	gboolean bluetooth_enabled;
+
+	g_usleep (1000000);      // 1 second to wait USB H/W on/off
+	bluetooth_enabled = is_bluetooth_enabled (manager);
+
+        dialog_init (manager);
+        gsd_media_keys_window_set_bluetooth_enabled (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                  bluetooth_enabled);
+        gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                          GSD_MEDIA_KEYS_WINDOW_ACTION_BLUETOOTH);
+        dialog_show (manager);
+}
+
+static void
+do_touchpad_action (GsdMediaKeysManager *manager,
+		    int 		 type)
+{
+	if (manager->priv->toggle_touchpad) {
+		type = (manager->priv->touchpad_enabled)? TOUCHPAD_OFF_KEY:TOUCHPAD_ON_KEY;
+		manager->priv->touchpad_enabled	= (manager->priv->touchpad_enabled)? FALSE:TRUE;
+	}
+
+        switch (type) {
+        case TOUCHPAD_ON_KEY:
+        	dialog_init (manager);
+        	gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                          	  GSD_MEDIA_KEYS_WINDOW_ACTION_TOUCHPAD_ON);
+        	dialog_show (manager);
+                break;
+        case TOUCHPAD_OFF_KEY:
+                dialog_init (manager);
+                gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                  GSD_MEDIA_KEYS_WINDOW_ACTION_TOUCHPAD_OFF);
+                dialog_show (manager);
+		break;
+        }
+}
+
+static void
+do_webcam_action (GsdMediaKeysManager *manager)
+{
+	gboolean webcam_enabled;
+	gchar **names;
+	GError *error = NULL;
+
+	/* check have available video4linux.video_capture */
+	g_usleep (1000000);      // 1 second to wait USB H/W on/off
+	hal_manager_find_capability (manager->priv->manager,
+					"video4linux.video_capture",
+					&names,
+					&error);
+	webcam_enabled = (names[0] != NULL)? TRUE:FALSE;
+	if (names[0] != NULL)
+		g_debug ("webcam: %s", names[0]);
+
+        dialog_init (manager);
+        gsd_media_keys_window_set_webcam_enabled (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                                  webcam_enabled);
+        gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                          GSD_MEDIA_KEYS_WINDOW_ACTION_WEBCAM);
+        dialog_show (manager);
+}
+
+static void
+do_xrandr_action (GsdMediaKeysManager *manager)
+{
+	gchar	*lcd = NULL, *crt = NULL;
+
+	if (is_crt_connected (&lcd, NULL, NULL, &crt, NULL, NULL)) {
+		if (manager->priv->osd_window_showing) {
+			/* change to next status when hotkey click*/
+			switch (manager->priv->xrandr) {
+			case GSD_MEDIA_KEYS_XRANDR_LCD_ONLY:
+				manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_LCD;
+				break;
+			case GSD_MEDIA_KEYS_XRANDR_LCD:
+				manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_CRT;
+				break;
+			case GSD_MEDIA_KEYS_XRANDR_CRT:
+				manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_CLONE;
+				break;
+			case GSD_MEDIA_KEYS_XRANDR_CLONE:
+				manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_LCD;
+				break;
+			case GSD_MEDIA_KEYS_XRANDR_DUAL:
+				manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_LCD;
+				break;
+			}
+		} else if (manager->priv->xrandr == GSD_MEDIA_KEYS_XRANDR_LCD_ONLY) {
+			manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_LCD;
+		}
+	} else {
+		manager->priv->xrandr = GSD_MEDIA_KEYS_XRANDR_LCD_ONLY;
+	}
+	g_free(lcd);
+	g_free(crt);
+
+        dialog_init (manager);
+        gsd_media_keys_window_set_xrandr (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+         				  manager->priv->xrandr);
+        gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                          GSD_MEDIA_KEYS_WINDOW_ACTION_XRANDR);
+        dialog_show (manager);
+}
+
+static void
+do_cpu_governor_action (GsdMediaKeysManager *manager)
+{
+	//logic to get cpus governor
+        DBusGProxy *proxy;
+	gchar* cpu_governor = CPU_GOVERNOR_ONDEMAND;
+	gchar *current_governor;
+	gsize bytes;
+	GError *error = NULL;
+
+	if (!g_file_test (CPU0_FREQ_GOVERNOR, G_FILE_TEST_EXISTS)) {
+		g_warning ("Warning: /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor does not exist!");
+		return;
+	}
+
+	g_file_get_contents (CPU0_FREQ_GOVERNOR, &current_governor, &bytes, &error);
+
+	if (!g_ascii_strncasecmp (current_governor, CPU_GOVERNOR_PERFORMANCE, 11)) {
+		if (manager->priv->cpu_governor_powersave)
+			cpu_governor = CPU_GOVERNOR_POWERSAVE;
+	} else if (!g_ascii_strncasecmp (current_governor, CPU_GOVERNOR_POWERSAVE, 9)) {
+		cpu_governor = CPU_GOVERNOR_ONDEMAND;
+	} else if (!g_ascii_strncasecmp (current_governor, CPU_GOVERNOR_ONDEMAND, 8)) {
+		cpu_governor = CPU_GOVERNOR_PERFORMANCE;
+	}
+	g_free (current_governor);
+
+	g_debug ("cpu_governor: %s", cpu_governor);
+
+	//set new governor
+        proxy = dbus_g_proxy_new_for_name (manager->priv->sys_connection,
+                                          "org.freedesktop.Hal",
+                                           "/org/freedesktop/Hal/devices/computer",
+                                           "org.freedesktop.Hal.Device.CPUFreq");
+
+        if (!dbus_g_proxy_call (proxy, "SetCPUFreqGovernor", &error,
+                                G_TYPE_STRING, cpu_governor, G_TYPE_INVALID,
+                                G_TYPE_INVALID)) {
+                g_print ("DBus method call failed\n");
+        }
+
+	if (proxy)
+		g_object_unref (proxy);
+
+	dialog_init (manager);
+        gsd_media_keys_window_set_cpu_governor (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+         					cpu_governor);
+        gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+                                          GSD_MEDIA_KEYS_WINDOW_ACTION_CPU_GOVERNOR);
+        dialog_show (manager);
+}
+
+static void
+do_backlight_action (GsdMediaKeysManager *manager)
+{
+        DBusGProxy *proxy;
+	GError *error = NULL;
+	guint level = -1;
+
+	//get current backlight power state
+       	proxy = dbus_g_proxy_new_for_name (manager->priv->sys_connection,
+                                          "org.freedesktop.Hal",
+                                           "/org/freedesktop/Hal/devices/computer_backlight",
+                                           "org.freedesktop.Hal.Device.LaptopPanel");
+
+        if (!dbus_g_proxy_call (proxy, "GetPower", &error,
+                                G_TYPE_INVALID,
+				G_TYPE_INT, &level, G_TYPE_INVALID)) {
+                g_print ("DBus method call failed\n");
+        }
+
+	g_debug ("bl_power: %d", level);
+
+	if (level >= 0) {
+		/* turn on/off backlight */
+		if (!dbus_g_proxy_call (proxy, "SetPower", &error,
+					G_TYPE_INT, (level == 0)? 1:0 ,
+					G_TYPE_INVALID, G_TYPE_INVALID)) {
+			g_print ("DBus method call failed\n");
+		}
+
+		//show backlight on/off OSD
+		dialog_init (manager);
+		gsd_media_keys_window_set_backlight (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+						     (level == 0)? 1:0 );
+		gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+						  GSD_MEDIA_KEYS_WINDOW_ACTION_BACKLIGHT);
+		dialog_show (manager);
+	}
+
+	if (proxy)
+		g_object_unref (proxy);
+}
+
+static void
+do_performance_action (GsdMediaKeysManager *manager)
+{
+	if (manager->priv->p_num_levels <= 0)
+		return;
+
+	if (manager->priv->osd_window_showing) {
+
+		manager->priv->p_level++;
+		if (manager->priv->p_level >= manager->priv->p_num_levels)
+			manager->priv->p_level = 0;		//back to 0 level
+	} else {
+		DBusGProxy *proxy;
+		GError *error = NULL;
+		guint level = -1;
+
+		//get current performance level
+		proxy = dbus_g_proxy_new_for_name (manager->priv->sys_connection,
+						  "org.freedesktop.Hal",
+						   "/org/freedesktop/Hal/devices/performance",
+						   "org.freedesktop.Hal.Device.Performance");
+
+		if (!dbus_g_proxy_call (proxy, "GetPerformance", &error,
+					G_TYPE_INVALID,
+					G_TYPE_INT, &level, G_TYPE_INVALID)) {
+			g_print ("DBus method call failed\n");
+		}
+
+		manager->priv->p_level = level;
+
+		dialog_show (manager);
+
+		if (proxy)
+			g_object_unref (proxy);
+	}
+
+	//show OSD
+	dialog_init (manager);
+	gsd_media_keys_window_set_performance (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+					       manager->priv->p_level );
+	gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+					  GSD_MEDIA_KEYS_WINDOW_ACTION_PERFORMANCE);
+	dialog_show (manager);
+}
+
+static void
+do_esc_action (GsdMediaKeysManager *manager)
+{
+	/* interrupt osc window and post action */
+	if (manager->priv->osd_window_showing) {
+
+		manager->priv->esc_post_action = TRUE;
+
+		//TODO: interrupt OSD
+		//remove OSD icon
+	}
+}
+
+
 static gint
 find_by_application (gconstpointer a,
                      gconstpointer b)
@@ -797,6 +1739,9 @@ do_action (GsdMediaKeysManager *manager,
         char *cmd;
         char *path;
 
+	if (type != ESC_KEY)
+		manager->priv->type_for_hide = type;
+
         switch (type) {
         case MUTE_KEY:
         case VOLUME_DOWN_KEY:
@@ -831,7 +1776,7 @@ do_action (GsdMediaKeysManager *manager,
                 do_mail_action (manager);
                 break;
         case SLEEP_KEY:
-                do_sleep_action ("apm", "xset dpms force off");
+                do_sleep_action (manager, "apm", "xset dpms force off");
                 break;
         case SCREENSAVER_KEY:
                 if ((cmd = g_find_program_in_path ("gnome-screensaver-command"))) {
@@ -869,6 +1814,40 @@ do_action (GsdMediaKeysManager *manager,
         case NEXT_KEY:
                 return do_multimedia_player_action (manager, "Next");
                 break;
+        case NUM_LOCK_KEY:
+                do_num_lock_action (manager);
+                break;
+        case SCROLL_LOCK_KEY:
+                do_scroll_lock_action (manager);
+                break;
+        case WIFI_KEY:
+                do_wifi_action (manager);
+                break;
+        case TOUCHPAD_ON_KEY:
+        case TOUCHPAD_OFF_KEY:
+                do_touchpad_action (manager, type);
+                break;
+        case XRANDR_KEY:
+                do_xrandr_action (manager);
+                break;
+        case CPU_GOVERNOR_KEY:
+                do_cpu_governor_action (manager);
+                break;
+        case BACKLIGHT_KEY:
+                do_backlight_action (manager);
+                break;
+        case PERFORMANCE_KEY:
+                do_performance_action (manager);
+                break;
+        case ESC_KEY:
+                do_esc_action (manager);
+                break;
+        case WEBCAM_KEY:
+                do_webcam_action (manager);
+                break;
+        case BLUETOOTH_KEY:
+                do_bluetooth_action (manager);
+                break;
         default:
                 g_assert_not_reached ();
         }
@@ -963,11 +1942,53 @@ _hk_device_condition_cb (HalDevice   *device,
   }
 }
 
+void
+_setup_button_devices (GsdMediaKeysManager *self)
+{
+        //GsdMediaKeysManagerPrivate *priv = GET_PRIVATE (self);
+        gchar **names;
+        GError *error = NULL;
+        gchar *udi;
+        gint i;
+        HalDevice *device;
+        gchar *type;
+
+        if (!hal_manager_find_capability (self->priv->manager,
+                                        "button",
+                                        &names,
+                                        &error))
+        {
+                g_warning (G_STRLOC ": Unable to find devices with capability 'button': %s",
+               error->message);
+                g_clear_error (&error);
+                return;
+        }
+
+        for (i = 0, udi = names[i]; udi != NULL; i++, udi = names[i])
+        {
+                type = NULL;
+
+                device = hal_device_new ();
+                hal_device_set_udi (device, udi);
+
+                hal_device_watch_condition (device);
+                g_signal_connect (device,
+                                "device-condition",
+                                (GCallback)_hk_device_condition_cb,
+                                self);
+                self->priv->devices = g_list_append (self->priv->devices, device);
+        }
+
+        hal_manager_free_capability (names);
+}
+
 gboolean
 gsd_media_keys_manager_start (GsdMediaKeysManager *manager,
                               GError             **error)
 {
+	char   *cust_theme_name;
         GSList *l;
+        GError  *gconf_error = NULL;
 
         g_debug ("Starting media_keys manager");
         gnome_settings_profile_start (NULL);
@@ -981,6 +2002,127 @@ gsd_media_keys_manager_start (GsdMediaKeysManager *manager,
         init_screens (manager);
         init_kbd (manager);
 
+	/* Initial a bit variables */
+	manager->priv->osd_window_showing = FALSE;
+	manager->priv->esc_post_action = FALSE;
+
+	/* Load OSD window parameter */
+        manager->priv->draw_osd_box = gconf_client_get_bool (manager->priv->conf_client,
+                                             		   GCONF_MISC_DIR "/draw_osd_box",
+                                             		   &gconf_error);
+        if (gconf_error) {
+                manager->priv->draw_osd_box = TRUE;
+                g_error_free (gconf_error);
+        }
+
+        manager->priv->osd_window_size = gconf_client_get_int (manager->priv->conf_client,
+                                                           GCONF_MISC_DIR "/osd_window_size",
+                                                           &gconf_error);
+        if (gconf_error) {
+                manager->priv->osd_window_size = 130;
+                g_error_free (gconf_error);
+        }
+
+        manager->priv->volume_step_icons = gconf_client_get_bool (manager->priv->conf_client,
+                                                           GCONF_MISC_DIR "/volume_step_icons",
+                                                           &gconf_error);
+        if (gconf_error) {
+                manager->priv->volume_step_icons = FALSE;
+                g_error_free (gconf_error);
+        }
+
+	/* use xrandr turn screen on/off when backlight control enable */
+        manager->priv->backlight_xrandr = gconf_client_get_bool (manager->priv->conf_client,
+                                                           GCONF_MISC_DIR "/backlight_xrandr",
+                                                           &gconf_error);
+        if (gconf_error) {
+                manager->priv->backlight_xrandr = FALSE;
+                g_error_free (gconf_error);
+        }
+
+	/* setup cpu governor powersave switch  */
+        manager->priv->cpu_governor_powersave = gconf_client_get_bool (manager->priv->conf_client,
+                                                           GCONF_MISC_DIR "/cpu_governor_powersave",
+                                                           &gconf_error);
+        if (gconf_error) {
+                manager->priv->cpu_governor_powersave = FALSE;
+                g_error_free (gconf_error);
+        }
+
+	/* get wifi hal rfkill */
+        manager->priv->wifi_hal_rfkill = gconf_client_get_bool (manager->priv->conf_client,
+                                                           	  GCONF_MISC_DIR "/wifi_hal_rfkill",
+                                                           	  &gconf_error);
+        if (gconf_error) {
+                manager->priv->wifi_hal_rfkill = FALSE;
+                g_error_free (gconf_error);
+        }
+
+	manager->priv->wifi_hal_bluetooth_rfkill = gconf_client_get_bool (manager->priv->conf_client,
+                                                           GCONF_MISC_DIR "/wifi_hal_bluetooth_rfkill",
+                                                           &gconf_error);
+        if (gconf_error) {
+                manager->priv->wifi_hal_bluetooth_rfkill = FALSE;
+                g_error_free (gconf_error);
+        }
+
+	manager->priv->wifi_hal_wwan_rfkill = gconf_client_get_bool (manager->priv->conf_client,
+                                                           GCONF_MISC_DIR "/wifi_hal_wwan_rfkill",
+                                                           &gconf_error);
+        if (gconf_error) {
+                manager->priv->wifi_hal_wwan_rfkill = FALSE;
+                g_error_free (gconf_error);
+        }
+
+	/* get show bluetooth and wwan on wifi fn key */
+        manager->priv->wifi_show_bluetooth = gconf_client_get_bool (manager->priv->conf_client,
+                                                           GCONF_MISC_DIR "/wifi_show_bluetooth",
+                                                           &gconf_error);
+        if (gconf_error) {
+                manager->priv->wifi_show_bluetooth = FALSE;
+                g_error_free (gconf_error);
+        }
+
+	manager->priv->wifi_show_wwan = gconf_client_get_bool (manager->priv->conf_client,
+                                                           GCONF_MISC_DIR "/wifi_show_wwan",
+                                                           &gconf_error);
+        if (gconf_error) {
+                manager->priv->wifi_show_wwan = FALSE;
+                g_error_free (gconf_error);
+        }
+
+
+	/* use xrandr turn screen on/off when backlight control enable */
+	manager->priv->touchpad_enabled = TRUE;
+        manager->priv->toggle_touchpad = gconf_client_get_bool (manager->priv->conf_client,
+                                                           GCONF_MISC_DIR "/toggle_touchpad",
+                                                           &gconf_error);
+        if (gconf_error) {
+                manager->priv->toggle_touchpad = TRUE;
+                g_error_free (gconf_error);
+        }
+
+
+	/* get performance level  */
+	manager->priv->p_level = -1;
+	manager->priv->p_num_levels = -1;
+  	GError *error_per = NULL;
+        HalDevice *performance_device = hal_device_new ();
+        hal_device_set_udi (performance_device,
+                	    "/org/freedesktop/Hal/devices/performance");
+  	if (!hal_device_get_int (performance_device,
+                           	 "performance.num_levels",
+                           	 &manager->priv->p_num_levels,
+                           	 &error_per))
+  	{
+    		g_warning (G_STRLOC ": Error getting number of performance levels: %s",
+               		   error_per->message);
+    		g_error_free (error_per);
+	}
+	/* remove HalDevice */
+	if (performance_device)
+		g_object_unref (performance_device);
+
         /* initialise Volume handler */
         gnome_settings_profile_start ("acme_volume_new");
         manager->priv->volume = acme_volume_new ();
@@ -1002,18 +2144,47 @@ gsd_media_keys_manager_start (GsdMediaKeysManager *manager,
         gnome_settings_profile_end (NULL);
 
         /* Start monitor hal key event*/
-        manager->priv->hk_device = hal_device_new ();
-        hal_device_set_udi (manager->priv->hk_device,
-                "/org/freedesktop/Hal/devices/platform_i8042_i8042_KBD_port_logicaldev_input");
-        hal_device_watch_condition (manager->priv->hk_device);
-        g_signal_connect (manager->priv->hk_device,
-                        "device-condition",
-                        (GCallback)_hk_device_condition_cb,
-                        manager);
+	_setup_button_devices (manager);
+
+	/* Get customer OSD theme */
+        cust_theme_name = gconf_client_get_string (manager->priv->conf_client,
+                                                           	  GCONF_MISC_DIR "/cust_theme",
+                                                           	  &gconf_error);
+        if (gconf_error) {
+                cust_theme_name = NULL;
+                g_error_free (gconf_error);
+        }
+
+	if (cust_theme_name != NULL) {
+        	manager->priv->cust_theme = gtk_icon_theme_new ();
+        	gtk_icon_theme_set_custom_theme(manager->priv->cust_theme, cust_theme_name);
+	}
+
+	g_free(cust_theme_name);
+
 
         return TRUE;
 }
 
+static void
+_cleanup_button_devices (GsdMediaKeysManager *self)
+{
+  	GList *l = NULL;
+  	HalDevice *device = NULL;
+
+  	for (l = self->priv->devices; l; l = g_list_delete_link (l, l))
+  	{
+    		device = (HalDevice *)l->data;
+
+    		if (device)
+    		{
+      			g_object_unref (device);
+    		}
+  	}
+
+  	self->priv->devices = l;
+}
+
 void
 gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
 {
@@ -1025,8 +2196,7 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
 	g_debug ("Stopping media_keys manager");
 
 	/* remove HalDevice */
-	if (priv->hk_device)
-	  g_object_unref (priv->hk_device);
+  	_cleanup_button_devices (manager);
 
         for (ls = priv->screens; ls != NULL; ls = ls->next) {
                 gdk_window_remove_filter (gdk_screen_get_root_window (ls->data),
@@ -1058,6 +2228,11 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
                 priv->connection = NULL;
         }
 
+        if (priv->sys_connection != NULL) {
+                dbus_g_connection_unref (priv->sys_connection);
+                priv->sys_connection = NULL;
+        }
+
         for (i = 0; i < HANDLED_KEYS; ++i) {
                 g_free (keys[i].key);
                 keys[i].key = NULL;
@@ -1083,6 +2258,13 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
         }
         g_list_free (priv->media_players);
         priv->media_players = NULL;
+
+	//TODO: free draw_osd_box?
+	if (priv->cust_theme != NULL)
+	{
+		g_object_unref (priv->cust_theme);
+		priv->cust_theme = NULL;
+	}
 }
 
 static void
@@ -1179,7 +2361,7 @@ static void
 gsd_media_keys_manager_init (GsdMediaKeysManager *manager)
 {
         manager->priv = GSD_MEDIA_KEYS_MANAGER_GET_PRIVATE (manager);
-
+	manager->priv->manager = hal_manager_new ();
 }
 
 static void
@@ -1213,6 +2395,16 @@ register_manager (GsdMediaKeysManager *manager)
 
         dbus_g_connection_register_g_object (manager->priv->connection, GSD_MEDIA_KEYS_DBUS_PATH, G_OBJECT (manager));
 
+	//get system bus connection
+	manager->priv->sys_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+	if (manager->priv->sys_connection == NULL) {
+		if (error != NULL) {
+		    g_printerr ("Error getting system bus: %s\n", error->message);
+		    g_error_free (error);
+		}
+	    	return FALSE;
+	}
+
         return TRUE;
 }
 
diff --git a/plugins/media-keys/gsd-media-keys-manager.h b/plugins/media-keys/gsd-media-keys-manager.h
index f6449d2..27d3234 100644
--- a/plugins/media-keys/gsd-media-keys-manager.h
+++ b/plugins/media-keys/gsd-media-keys-manager.h
@@ -25,6 +25,8 @@
 
 G_BEGIN_DECLS
 
+#define CPU0_FREQ_GOVERNOR			"/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
+
 #define GSD_TYPE_MEDIA_KEYS_MANAGER         (gsd_media_keys_manager_get_type ())
 #define GSD_MEDIA_KEYS_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_MEDIA_KEYS_MANAGER, GsdMediaKeysManager))
 #define GSD_MEDIA_KEYS_MANAGER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_MEDIA_KEYS_MANAGER, GsdMediaKeysManagerClass))
diff --git a/plugins/media-keys/gsd-media-keys-window.c b/plugins/media-keys/gsd-media-keys-window.c
index 820cfaa..5178cab 100644
--- a/plugins/media-keys/gsd-media-keys-window.c
+++ b/plugins/media-keys/gsd-media-keys-window.c
@@ -53,9 +53,33 @@ struct GsdMediaKeysWindowPrivate
 
         guint                    volume_muted : 1;
         int                      volume_level;
+	/* volume per-step percentage */
+	int      		 vol_step;
+        guint                    is_mute_key : 1;
 
         GtkImage                *image;
         GtkWidget               *progress;
+
+	/* OSD parameter */
+        guint                    draw_osd_box : 1;
+	int			 osd_window_size;
+	guint 		 	 volume_step_icons : 1;
+
+	/* customer OSD theme */
+	GtkIconTheme 		 *cust_theme;
+
+	unsigned int		 num_locked;
+	unsigned int		 scroll_locked;
+	gchar*		 	 cpu_governor;
+	gboolean		 wifi_enabled;
+        gboolean                 wifi_show_bluetooth;
+        gboolean                 wifi_show_wwan;
+	GsdMediaKeysXrandr	 xrandr;
+	guint 		 	 backlight;
+	guint			 performance;
+	gboolean		 webcam_enabled;
+	gboolean		 bluetooth_enabled;
+	gboolean		 wwan_enabled;
 };
 
 G_DEFINE_TYPE (GsdMediaKeysWindow, gsd_media_keys_window, GTK_TYPE_WINDOW)
@@ -69,7 +93,6 @@ fade_timeout (GsdMediaKeysWindow *window)
                 /* Reset it for the next time */
                 window->priv->fade_out_alpha = 1.0;
                 window->priv->fade_timeout_id = 0;
-
                 return FALSE;
         } else {
                 GdkRectangle rect;
@@ -99,7 +122,6 @@ hide_timeout (GsdMediaKeysWindow *window)
         } else {
                 gtk_widget_hide (GTK_WIDGET (window));
         }
-
         return FALSE;
 }
 
@@ -198,6 +220,119 @@ action_changed (GsdMediaKeysWindow *window)
                         volume_controls_set_visible (window, FALSE);
                         window_set_icon_file (window, PIXMAPDIR "/acme-eject.png");
                         break;
+                case GSD_MEDIA_KEYS_WINDOW_ACTION_WIFI:
+                        volume_controls_set_visible (window, FALSE);
+
+			if (window->priv->wifi_enabled) {
+                        	window_set_icon_file (window, "wireless-on");
+			} else {
+                        	window_set_icon_file (window, "wireless-off");
+			}
+
+                        break;
+                case GSD_MEDIA_KEYS_WINDOW_ACTION_TOUCHPAD_ON:
+                        volume_controls_set_visible (window, FALSE);
+                        window_set_icon_file (window, "touchpad-on");
+                        break;
+                case GSD_MEDIA_KEYS_WINDOW_ACTION_TOUCHPAD_OFF:
+                        volume_controls_set_visible (window, FALSE);
+                        window_set_icon_file (window, "touchpad-off");
+                        break;
+                case GSD_MEDIA_KEYS_WINDOW_ACTION_XRANDR:
+                        volume_controls_set_visible (window, FALSE);
+			switch (window->priv->xrandr) {
+			case GSD_MEDIA_KEYS_XRANDR_LCD_ONLY:
+				window_set_icon_file (window, "display-internal-only");
+				break;
+			case GSD_MEDIA_KEYS_XRANDR_LCD:
+				window_set_icon_file (window, "display-internal");
+				break;
+			case GSD_MEDIA_KEYS_XRANDR_CRT:
+				window_set_icon_file (window, "display-external");
+				break;
+			case GSD_MEDIA_KEYS_XRANDR_CLONE:
+				window_set_icon_file (window, "display-mirror");
+				break;
+			case GSD_MEDIA_KEYS_XRANDR_DUAL:
+				window_set_icon_file (window, "display-extended-desktop");
+				break;
+			}
+                        break;
+		case GSD_MEDIA_KEYS_WINDOW_ACTION_CPU_GOVERNOR:
+                        volume_controls_set_visible (window, FALSE);
+
+	                if (!g_strcmp0(window->priv->cpu_governor, CPU_GOVERNOR_POWERSAVE)) {
+        	                window_set_icon_file (window, "cpu-governor-low");
+                	}
+                	else if (!g_strcmp0(window->priv->cpu_governor, CPU_GOVERNOR_ONDEMAND)) {
+                        	window_set_icon_file (window, "cpu-governor-normal");
+                	}
+                	else if (!g_strcmp0(window->priv->cpu_governor, CPU_GOVERNOR_PERFORMANCE)) {
+                        	window_set_icon_file (window, "cpu-governor-speed");
+                	}
+
+                        break;
+        	case GSD_MEDIA_KEYS_WINDOW_ACTION_NUM_LOCK:
+                        volume_controls_set_visible (window, FALSE);
+
+			if (window->priv->num_locked) {
+                            window_set_icon_file (window, "numlock-on");
+			} else {
+                            window_set_icon_file (window, "numlock-off");
+			}
+
+                	break;
+                case GSD_MEDIA_KEYS_WINDOW_ACTION_SCROLL_LOCK:
+                        volume_controls_set_visible (window, FALSE);
+
+                        if (window->priv->scroll_locked) {
+                            window_set_icon_file (window, "scrolllock-on");
+                        } else {
+                            window_set_icon_file (window, "scrolllock-off");
+                        }
+
+                        break;
+                case GSD_MEDIA_KEYS_WINDOW_ACTION_BACKLIGHT:
+                        volume_controls_set_visible (window, FALSE);
+
+                        if (window->priv->backlight) {
+                            window_set_icon_file (window, "lcd-backlight-1");
+                        } else {
+                            window_set_icon_file (window, "lcd-backlight-0");
+                        }
+
+                        break;
+                case GSD_MEDIA_KEYS_WINDOW_ACTION_PERFORMANCE:
+                        volume_controls_set_visible (window, FALSE);
+
+                        if (window->priv->performance >= 0) {
+			    gchar		   icon_name_tmp [25];
+                            g_snprintf (icon_name_tmp, 25, "performance-%01d",
+					window->priv->performance);
+                            window_set_icon_file (window, icon_name_tmp);
+                        }
+
+                        break;
+                case GSD_MEDIA_KEYS_WINDOW_ACTION_WEBCAM:
+                        volume_controls_set_visible (window, FALSE);
+
+			if (window->priv->webcam_enabled) {
+                        	window_set_icon_file (window, "camera-web-on");
+			} else {
+                        	window_set_icon_file (window, "camera-web-off");
+			}
+
+                        break;
+                case GSD_MEDIA_KEYS_WINDOW_ACTION_BLUETOOTH:
+                        volume_controls_set_visible (window, FALSE);
+
+			if (window->priv->bluetooth_enabled) {
+                        	window_set_icon_file (window, "bluetooth-on");
+			} else {
+                        	window_set_icon_file (window, "bluetooth-off");
+			}
+
+                        break;
                 default:
                         break;
                 }
@@ -222,6 +357,26 @@ volume_level_changed (GsdMediaKeysWindow *window)
 }
 
 static void
+vol_step_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (!window->priv->is_composited) {
+		;//TODO: change the icon
+        }
+}
+
+static void
+is_mute_key_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (!window->priv->is_composited) {
+                ;//TODO: change the icon
+        }
+}
+
+static void
 volume_muted_changed (GsdMediaKeysWindow *window)
 {
         update_window (window);
@@ -235,6 +390,152 @@ volume_muted_changed (GsdMediaKeysWindow *window)
         }
 }
 
+static void
+num_locked_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (! window->priv->is_composited) {
+                if (window->priv->num_locked) {
+                        window_set_icon_name (window, "numlock-on");
+                } else {
+                        window_set_icon_name (window, "numlock-off");
+                }
+        }
+}
+
+static void
+scroll_locked_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (! window->priv->is_composited) {
+                if (window->priv->scroll_locked) {
+                        window_set_icon_name (window, "scrolllock-on");
+                } else {
+                        window_set_icon_name (window, "scrolllock-off");
+                }
+        }
+}
+
+static void
+cpu_governor_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (! window->priv->is_composited) {
+		if (!g_strcmp0(window->priv->cpu_governor, CPU_GOVERNOR_POWERSAVE)) {
+                        window_set_icon_name (window, "cpu-governor-low");
+		}
+		else if (!g_strcmp0(window->priv->cpu_governor, CPU_GOVERNOR_ONDEMAND)) {
+                        window_set_icon_name (window, "cpu-governor-normal");
+		}
+		else if (!g_strcmp0(window->priv->cpu_governor, CPU_GOVERNOR_PERFORMANCE)) {
+                        window_set_icon_name (window, "cpu-governor-speed");
+		}
+        }
+}
+
+static void
+xrandr_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (! window->priv->is_composited) {
+		switch (window->priv->xrandr) {
+		case GSD_MEDIA_KEYS_XRANDR_LCD_ONLY:
+			window_set_icon_name (window, "display-internal-only");
+			break;
+		case GSD_MEDIA_KEYS_XRANDR_LCD:
+			window_set_icon_name (window, "display-internal");
+			break;
+		case GSD_MEDIA_KEYS_XRANDR_CRT:
+			window_set_icon_name (window, "display-external");
+			break;
+		case GSD_MEDIA_KEYS_XRANDR_CLONE:
+			window_set_icon_name (window, "display-mirror");
+			break;
+		case GSD_MEDIA_KEYS_XRANDR_DUAL:
+			window_set_icon_name (window, "display-extended-desktop");
+			break;
+		}
+	}
+}
+
+static void
+wifi_enabled_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (! window->priv->is_composited) {
+                if (window->priv->wifi_enabled) {
+                        window_set_icon_name (window, "wireless-on");
+                }
+                else {
+                        window_set_icon_name (window, "wireless-off");
+		}
+        }
+}
+
+static void
+webcam_enabled_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (! window->priv->is_composited) {
+                if (window->priv->webcam_enabled) {
+                        window_set_icon_name (window, "camera-web-on");
+                }
+                else {
+                        window_set_icon_name (window, "camera-web-off");
+		}
+        }
+}
+
+static void
+bluetooth_enabled_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (! window->priv->is_composited) {
+                if (window->priv->bluetooth_enabled) {
+                        window_set_icon_name (window, "bluetooth-on");
+                }
+                else {
+                        window_set_icon_name (window, "bluetooth-off");
+		}
+        }
+}
+
+static void
+backlight_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (! window->priv->is_composited) {
+		if (window->priv->backlight) {
+		    window_set_icon_file (window, "lcd-backlight-1");
+		} else {
+		    window_set_icon_file (window, "lcd-backlight-0");
+		}
+        }
+}
+
+static void
+performance_changed (GsdMediaKeysWindow *window)
+{
+        update_window (window);
+
+        if (! window->priv->is_composited) {
+		if (window->priv->performance >= 0) {
+			gchar		   icon_name_tmp [25];
+               		g_snprintf (icon_name_tmp, 25, "performance-%01d",
+			    		window->priv->performance);
+                	window_set_icon_file (window, icon_name_tmp);
+		}
+        }
+}
+
 void
 gsd_media_keys_window_set_action (GsdMediaKeysWindow      *window,
                                   GsdMediaKeysWindowAction action)
@@ -260,6 +561,203 @@ gsd_media_keys_window_set_volume_muted (GsdMediaKeysWindow *window,
 }
 
 void
+gsd_media_keys_window_set_draw_osd_box (GsdMediaKeysWindow *window,
+                                        gboolean            draw_osd_box_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->draw_osd_box != draw_osd_box_in) {
+                window->priv->draw_osd_box = draw_osd_box_in;
+        }
+}
+
+void
+gsd_media_keys_window_set_osd_window_size (GsdMediaKeysWindow *window,
+                                           int            osd_window_size_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        gint size;
+
+        window->priv->osd_window_size = osd_window_size_in;
+        size = window->priv->osd_window_size;
+
+        gtk_window_set_default_size (GTK_WINDOW (window), size, size);
+}
+
+void
+gsd_media_keys_window_set_volume_step_icons (GsdMediaKeysWindow *window,
+                                             gboolean            volume_step_icons_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->volume_step_icons != volume_step_icons_in) {
+                window->priv->volume_step_icons = volume_step_icons_in;
+        }
+}
+
+void
+gsd_media_keys_window_set_is_mute_key (GsdMediaKeysWindow *window,
+                                       gboolean            is_mute_key_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->is_mute_key != is_mute_key_in) {
+                window->priv->is_mute_key = is_mute_key_in;
+                is_mute_key_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_cust_theme (GsdMediaKeysWindow *window,
+                                      GtkIconTheme       *cust_theme_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        window->priv->cust_theme = cust_theme_in;
+}
+
+void
+gsd_media_keys_window_set_num_locked (GsdMediaKeysWindow *window,
+                                      unsigned int	  state)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->num_locked != state) {
+        	window->priv->num_locked = state;
+                num_locked_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_scroll_locked (GsdMediaKeysWindow *window,
+                                         unsigned int        state)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->scroll_locked != state) {
+                window->priv->scroll_locked = state;
+                scroll_locked_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_cpu_governor (GsdMediaKeysWindow *window,
+                                        gchar*         cpu_governor_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (g_strcmp0(window->priv->cpu_governor, cpu_governor_in)) {
+                window->priv->cpu_governor = cpu_governor_in;
+                cpu_governor_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_xrandr (GsdMediaKeysWindow *window,
+                                  GsdMediaKeysXrandr  xrandr_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->xrandr != xrandr_in) {
+                window->priv->xrandr = xrandr_in;
+                xrandr_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_wifi_enabled (GsdMediaKeysWindow *window,
+                                        gboolean	    wifi_enabled_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->wifi_enabled != wifi_enabled_in) {
+                window->priv->wifi_enabled = wifi_enabled_in;
+                wifi_enabled_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_wifi_show_bluetooth (GsdMediaKeysWindow *window,
+					gboolean	wifi_show_bluetooth_in)
+{
+	g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+	if (window->priv->wifi_show_bluetooth != wifi_show_bluetooth_in)
+		window->priv->wifi_show_bluetooth = wifi_show_bluetooth_in;
+}
+
+void
+gsd_media_keys_window_set_wifi_show_wwan (GsdMediaKeysWindow *window,
+                                        gboolean        wifi_show_wwan_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->wifi_show_wwan != wifi_show_wwan_in)
+                window->priv->wifi_show_wwan = wifi_show_wwan_in;
+}
+
+void
+gsd_media_keys_window_set_webcam_enabled (GsdMediaKeysWindow *window,
+                                          gboolean	     webcam_enabled_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->webcam_enabled != webcam_enabled_in) {
+                window->priv->webcam_enabled = webcam_enabled_in;
+                webcam_enabled_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_bluetooth_enabled (GsdMediaKeysWindow *window,
+                                          gboolean	     bluetooth_enabled_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->bluetooth_enabled != bluetooth_enabled_in) {
+                window->priv->bluetooth_enabled = bluetooth_enabled_in;
+                webcam_enabled_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_wwan_enabled (GsdMediaKeysWindow *window,
+					gboolean	wwan_enabled_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->wwan_enabled != wwan_enabled_in) {
+                window->priv->wwan_enabled = wwan_enabled_in;
+                webcam_enabled_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_backlight (GsdMediaKeysWindow *window,
+                                     guint	         backlight_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->backlight != backlight_in) {
+                window->priv->backlight = backlight_in;
+                backlight_changed (window);
+        }
+}
+
+void
+gsd_media_keys_window_set_performance (GsdMediaKeysWindow *window,
+                                       guint	           performance_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->performance != performance_in) {
+                window->priv->performance = performance_in;
+                performance_changed (window);
+        }
+}
+
+void
 gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window,
                                         int                 level)
 {
@@ -271,6 +769,18 @@ gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window,
         }
 }
 
+void
+gsd_media_keys_window_set_volume_step (GsdMediaKeysWindow *window,
+                                       int                 vol_step_in)
+{
+        g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+        if (window->priv->vol_step != vol_step_in) {
+                window->priv->vol_step = vol_step_in;
+                vol_step_changed (window);
+        }
+}
+
 static void
 curved_rectangle (cairo_t *cr,
                   double   x0,
@@ -336,13 +846,15 @@ load_pixbuf (GsdMediaKeysWindow *window,
         GtkIconTheme *theme;
         GdkPixbuf    *pixbuf;
 
-        if (window != NULL && gtk_widget_has_screen (GTK_WIDGET (window))) {
+	if ((window != NULL) && (window->priv->cust_theme != NULL)) {
+		theme = window->priv->cust_theme;
+	} else if (gtk_widget_has_screen (GTK_WIDGET (window))) {
                 theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
         } else {
                 theme = gtk_icon_theme_get_default ();
         }
 
-        pixbuf = gtk_icon_theme_load_icon (theme,
+	pixbuf = gtk_icon_theme_load_icon (theme,
                                            name,
                                            icon_size,
                                            GTK_ICON_LOOKUP_FORCE_SVG,
@@ -353,12 +865,40 @@ load_pixbuf (GsdMediaKeysWindow *window,
          * seems to be broken */
         if (pixbuf != NULL) {
                 int width;
+		int height;
 
                 width = gdk_pixbuf_get_width (pixbuf);
+        	height = gdk_pixbuf_get_height (pixbuf);
+
                 if (width < (float)icon_size * 0.75) {
                         g_object_unref (pixbuf);
                         pixbuf = NULL;
                 }
+
+		/* if pixbuf out of range, rescale it*/
+        	if (width > icon_size || height > icon_size)
+    		{
+			int new_width;
+			int new_height;
+
+			new_width = icon_size;
+			new_height = icon_size;
+			if (width > height)
+			{
+			    new_height = icon_size * height / width;
+			}
+			else
+			{
+			    new_width = icon_size * width / height;
+			}
+
+        		GdkPixbuf *temp = pixbuf;
+        		pixbuf = gdk_pixbuf_scale_simple (temp,
+                                      new_width,
+                                      new_height,
+                                      GDK_INTERP_HYPER);
+                	g_object_unref (temp);
+    		}
         }
 
         return pixbuf;
@@ -394,6 +934,34 @@ render_eject (GsdMediaKeysWindow *window,
         return TRUE;
 }
 
+static gboolean
+render_common (GsdMediaKeysWindow *window,
+              cairo_t            *cr,
+              double              x0,
+              double              y0,
+              double              width,
+              double              height,
+	      const char	  *icon_name)
+{
+        GdkPixbuf  *pixbuf;
+        int         icon_size;
+
+        icon_size = (int)width;
+
+        pixbuf = load_pixbuf (window, icon_name, icon_size);
+
+        if (pixbuf == NULL) {
+                return FALSE;
+        }
+
+        gdk_cairo_set_source_pixbuf (cr, pixbuf, x0, y0);
+        cairo_paint_with_alpha (cr, FG_ALPHA);
+
+        g_object_unref (pixbuf);
+
+        return TRUE;
+}
+
 static void
 draw_eject (cairo_t *cr,
             double   x0,
@@ -438,7 +1006,7 @@ draw_action_eject (GsdMediaKeysWindow *window,
 
         gtk_window_get_size (GTK_WINDOW (window), &window_width, &window_height);
 
-        width = window_width * 0.65;
+        width = window_width * 0.65;		//TODO: add gconf key for setup percent
         height = window_height * 0.65;
         x0 = (window_width - width) / 2;
         y0 = (window_height - height) / 2;
@@ -461,6 +1029,230 @@ draw_action_eject (GsdMediaKeysWindow *window,
         }
 }
 
+static gboolean
+draw_action_common (GsdMediaKeysWindow *window,
+                    cairo_t            *cr,
+		    const char 	       *icon_name)
+{
+        int      window_width;
+        int      window_height;
+        double   width;
+        double   height;
+        double   x0;
+        double   y0;
+        gboolean res;
+
+        gtk_window_get_size (GTK_WINDOW (window), &window_width, &window_height);
+
+        width = window_width * 0.65;
+        height = window_height * 0.65;
+        x0 = (window_width - width) / 2;
+        y0 = (window_height - height) / 2;
+
+        res = render_common (window,
+                            cr,
+                            x0, y0,
+                            width, height, icon_name);
+
+	return res;
+}
+
+static void
+draw_action_num_lock (GsdMediaKeysWindow *window,
+                      cairo_t            *cr)
+{
+	if (window->priv->num_locked) {
+        	draw_action_common (window, cr, "numlock-on");
+	} else {
+        	draw_action_common (window, cr, "numlock-off");
+	}
+}
+
+static void
+draw_action_webcam (GsdMediaKeysWindow *window,
+                      cairo_t            *cr)
+{
+	if (window->priv->webcam_enabled) {
+        	draw_action_common (window, cr, "camera-web-on");
+	} else {
+        	draw_action_common (window, cr, "camera-web-off");
+	}
+}
+
+static void
+draw_action_bluetooth (GsdMediaKeysWindow *window,
+                      cairo_t            *cr)
+{
+	if (window->priv->bluetooth_enabled) {
+        	draw_action_common (window, cr, "bluetooth-on");
+	} else {
+        	draw_action_common (window, cr, "bluetooth-off");
+	}
+}
+
+static void
+draw_action_scroll_lock (GsdMediaKeysWindow *window,
+                         cairo_t            *cr)
+{
+        if (window->priv->scroll_locked) {
+                draw_action_common (window, cr, "scrolllock-on");
+        } else {
+                draw_action_common (window, cr, "scrolllock-off");
+        }
+}
+
+static void
+draw_action_cpu_governor (GsdMediaKeysWindow *window,
+                          cairo_t            *cr)
+{
+	if (!g_strcmp0(window->priv->cpu_governor, CPU_GOVERNOR_POWERSAVE)) {
+        	draw_action_common (window, cr, "cpu-governor-low");
+        }
+        else if (!g_strcmp0(window->priv->cpu_governor, CPU_GOVERNOR_ONDEMAND)) {
+        	draw_action_common (window, cr, "cpu-governor-normal");
+       	}
+        else if (!g_strcmp0(window->priv->cpu_governor, CPU_GOVERNOR_PERFORMANCE)) {
+        	draw_action_common (window, cr, "cpu-governor-speed");
+        }
+}
+
+static void
+draw_action_xrandr (GsdMediaKeysWindow *window,
+                    cairo_t            *cr)
+{
+	switch (window->priv->xrandr) {
+	case GSD_MEDIA_KEYS_XRANDR_LCD_ONLY:
+		if (!draw_action_common (window, cr, "display-internal-only"))
+			draw_action_common (window, cr, "display-internal");
+		break;
+	case GSD_MEDIA_KEYS_XRANDR_LCD:
+		draw_action_common (window, cr, "display-internal");
+		break;
+	case GSD_MEDIA_KEYS_XRANDR_CRT:
+		draw_action_common (window, cr, "display-external");
+		break;
+	case GSD_MEDIA_KEYS_XRANDR_CLONE:
+		draw_action_common (window, cr, "display-mirror");
+		break;
+	case GSD_MEDIA_KEYS_XRANDR_DUAL:
+		draw_action_common (window, cr, "display-extended-desktop");
+		break;
+	}
+}
+
+static void
+draw_action_wifi (GsdMediaKeysWindow *window,
+			cairo_t            *cr)
+{
+        int	window_width;
+        int	window_height;
+	int	icon_num;
+        double	width;
+        double	height;
+        double	x0, x1, x2;
+        double	y0;
+        char    *icon_name;
+        gint	size;
+        GdkPixbuf  *pixbuf;
+        int         icon_size;
+
+        if (window->priv->wifi_enabled) {
+               icon_name = "wireless-on";
+        } else {
+               icon_name = "wireless-off";
+        }
+
+        size = window->priv->osd_window_size;
+        gtk_window_get_size (GTK_WINDOW (window), &window_width, &window_height);
+
+	icon_num = 1;
+	icon_num += (window->priv->wifi_show_bluetooth)? 1:0;
+	icon_num += (window->priv->wifi_show_wwan)? 1:0;
+
+        width = size * 0.65;
+        height = size * 0.65;
+	y0 = (window_height - height) / 2;
+	if (icon_num == 1) {
+	        x0 = (window_width - width) / 2;
+	} else if (icon_num == 2) {
+		x0 = (window_width/2 - width) / 2;
+		x1 = x0 + window_width/2 + x2;
+		x2 = x0;
+	} else {
+		x1 = (window_width - width) / 2;
+		x0 = (x1 - width) / 2;
+		x2 = x0 + width + x1;
+	}
+
+        icon_size = (int)width;
+
+        pixbuf = load_pixbuf (window, icon_name, icon_size);
+        if (pixbuf == NULL) {
+                return FALSE;
+        }
+        gdk_cairo_set_source_pixbuf (cr, pixbuf, x0, y0);
+        cairo_paint_with_alpha (cr, FG_ALPHA);
+        g_object_unref (pixbuf);
+
+	/* wifi_show_bluetooth */
+	if (window->priv->wifi_show_bluetooth) {
+		if (window->priv->bluetooth_enabled) {
+		       icon_name = "bluetooth-on";
+		} else {
+		       icon_name = "bluetooth-off";
+		}
+		pixbuf = load_pixbuf (window, icon_name, icon_size);
+		if (pixbuf == NULL) {
+			return FALSE;
+		}
+		gdk_cairo_set_source_pixbuf (cr, pixbuf, x1, y0);
+		cairo_paint_with_alpha (cr, FG_ALPHA);
+		g_object_unref (pixbuf);
+	}
+
+	/* wifi_show_wwan */
+	if (window->priv->wifi_show_wwan) {
+		if (window->priv->wwan_enabled) {
+		       icon_name = "wireless-on";	//TODO: use wwan icon
+		} else {
+		       icon_name = "wireless-off";
+		}
+		pixbuf = load_pixbuf (window, icon_name, icon_size);
+		if (pixbuf == NULL) {
+			return FALSE;
+        	}
+		gdk_cairo_set_source_pixbuf (cr, pixbuf, x2, y0);
+		cairo_paint_with_alpha (cr, FG_ALPHA);
+		g_object_unref (pixbuf);
+	}
+
+        return TRUE;
+}
+
+static void
+draw_action_backlight (GsdMediaKeysWindow *window,
+                       cairo_t            *cr)
+{
+        if (window->priv->backlight) {
+                draw_action_common (window, cr, "lcd-backlight-1");
+        }
+        else {
+                draw_action_common (window, cr, "lcd-backlight-0");
+        }
+}
+
+static void
+draw_action_performance (GsdMediaKeysWindow *window,
+                         cairo_t            *cr)
+{
+        if (window->priv->performance >= 0) {
+		gchar		   icon_name_tmp [25];
+                g_snprintf (icon_name_tmp, 25, "performance-%01d",
+			    window->priv->performance);
+        	draw_action_common (window, cr, icon_name_tmp);
+	}
+}
+
 static void
 draw_waves (cairo_t *cr,
             double   cx,
@@ -541,6 +1333,8 @@ render_speaker (GsdMediaKeysWindow *window,
         GdkPixbuf         *pixbuf;
         int                icon_size;
         int                n;
+	char		  *icon_name;
+	gchar		   icon_name_tmp [25];
         static const char *icon_names[] = {
                 "audio-volume-muted",
                 "audio-volume-low",
@@ -549,21 +1343,37 @@ render_speaker (GsdMediaKeysWindow *window,
                 NULL
         };
 
-        if (window->priv->volume_muted) {
-                n = 0;
-        } else {
-                /* select image */
-                n = 3 * window->priv->volume_level / 100 + 1;
-                if (n < 1) {
-                        n = 1;
-                } else if (n > 3) {
-                        n = 3;
+        if (window->priv->volume_step_icons) {
+                if (window->priv->is_mute_key) {
+                        if (window->priv->volume_muted) {
+                                icon_name = "audio-volume-muted";
+                        } else {
+                                icon_name = "audio-volume-unmuted";
+                        }
+                } else {
+                        n = window->priv->volume_level / window->priv->vol_step;
+			n = (n == 0 && window->priv->volume_level > 0)? 1:n;
+                        g_snprintf (icon_name_tmp, 25, "audio-volume-%02d", n);
+                        icon_name = icon_name_tmp;
                 }
-        }
+	} else {
+		if (window->priv->volume_muted) {
+			n = 0;
+		} else {
+			/* select image */
+			n = 3 * window->priv->volume_level / 100 + 1;
+			if (n < 1) {
+				n = 1;
+			} else if (n > 3) {
+				n = 3;
+			}
+		}
+		icon_name = icon_names[n];
+	}
 
         icon_size = (int)width;
 
-        pixbuf = load_pixbuf (window, icon_names[n], icon_size);
+        pixbuf = load_pixbuf (window, icon_name, icon_size);
 
         if (pixbuf == NULL) {
                 return FALSE;
@@ -645,7 +1455,12 @@ draw_action_volume (GsdMediaKeysWindow *window,
         volume_box_height = window_height * 0.05;
 
         icon_box_x0 = (window_width - icon_box_width) / 2;
-        icon_box_y0 = (window_height - icon_box_height - volume_box_height) / 2;
+        if (!window->priv->volume_step_icons)
+        {
+        	icon_box_y0 = (window_height - icon_box_height - volume_box_height) / 2;
+	} else {
+        	icon_box_y0 = (window_height - icon_box_height) / 2;
+	}
         volume_box_x0 = icon_box_x0;
         volume_box_y0 = icon_box_height + icon_box_y0;
 
@@ -701,13 +1516,16 @@ draw_action_volume (GsdMediaKeysWindow *window,
         }
 
         /* draw volume meter */
-        draw_volume_boxes (window,
-                           cr,
-                           (double)window->priv->volume_level / 100.0,
-                           volume_box_x0,
-                           volume_box_y0,
-                           volume_box_width,
-                           volume_box_height);
+        if (!window->priv->volume_step_icons)
+        {
+		draw_volume_boxes (window,
+				   cr,
+				   (double)window->priv->volume_level / 100.0,
+				   volume_box_x0,
+				   volume_box_y0,
+				   volume_box_width,
+				   volume_box_height);
+	}
 }
 
 static void
@@ -721,6 +1539,39 @@ draw_action (GsdMediaKeysWindow *window,
         case GSD_MEDIA_KEYS_WINDOW_ACTION_EJECT:
                 draw_action_eject (window, cr);
                 break;
+        case GSD_MEDIA_KEYS_WINDOW_ACTION_WIFI:
+		draw_action_wifi (window, cr);
+                break;
+        case GSD_MEDIA_KEYS_WINDOW_ACTION_TOUCHPAD_ON:
+                draw_action_common (window, cr, "touchpad-on");
+                break;
+        case GSD_MEDIA_KEYS_WINDOW_ACTION_TOUCHPAD_OFF:
+                draw_action_common (window, cr, "touchpad-off");
+                break;
+        case GSD_MEDIA_KEYS_WINDOW_ACTION_XRANDR:
+		draw_action_xrandr (window, cr);
+                break;
+        case GSD_MEDIA_KEYS_WINDOW_ACTION_CPU_GOVERNOR:
+		draw_action_cpu_governor (window, cr);
+                break;
+	case GSD_MEDIA_KEYS_WINDOW_ACTION_NUM_LOCK:
+		draw_action_num_lock (window, cr);
+		break;
+        case GSD_MEDIA_KEYS_WINDOW_ACTION_SCROLL_LOCK:
+                draw_action_scroll_lock (window, cr);
+                break;
+        case GSD_MEDIA_KEYS_WINDOW_ACTION_BACKLIGHT:
+                draw_action_backlight (window, cr);
+                break;
+        case GSD_MEDIA_KEYS_WINDOW_ACTION_PERFORMANCE:
+                draw_action_performance (window, cr);
+                break;
+	case GSD_MEDIA_KEYS_WINDOW_ACTION_WEBCAM:
+		draw_action_webcam (window, cr);
+		break;
+	case GSD_MEDIA_KEYS_WINDOW_ACTION_BLUETOOTH:
+		draw_action_bluetooth (window, cr);
+		break;
         default:
                 break;
         }
@@ -762,21 +1613,24 @@ on_expose_event (GtkWidget          *widget,
         cairo_paint (cr);
 
         /* draw a box */
-        curved_rectangle (cr, 0, 0, width, height, height / 10);
-        color = GTK_WIDGET (window)->style->bg [GTK_STATE_NORMAL];
-        r = (float)color.red / 65535.0;
-        g = (float)color.green / 65535.0;
-        b = (float)color.blue / 65535.0;
-        cairo_set_source_rgba (cr, r, g, b, BG_ALPHA);
-        cairo_fill_preserve (cr);
-
-        color = GTK_WIDGET (window)->style->fg [GTK_STATE_NORMAL];
-        r = (float)color.red / 65535.0;
-        g = (float)color.green / 65535.0;
-        b = (float)color.blue / 65535.0;
-        cairo_set_source_rgba (cr, r, g, b, BG_ALPHA);
-        cairo_set_line_width (cr, 1);
-        cairo_stroke (cr);
+	if (window->priv->draw_osd_box)
+	{
+        	curved_rectangle (cr, 0, 0, width, height, height / 10);
+        	color = GTK_WIDGET (window)->style->bg [GTK_STATE_NORMAL];
+        	r = (float)color.red / 65535.0;
+        	g = (float)color.green / 65535.0;
+        	b = (float)color.blue / 65535.0;
+        	cairo_set_source_rgba (cr, r, g, b, BG_ALPHA);
+        	cairo_fill_preserve (cr);
+
+        	color = GTK_WIDGET (window)->style->fg [GTK_STATE_NORMAL];
+        	r = (float)color.red / 65535.0;
+        	g = (float)color.green / 65535.0;
+        	b = (float)color.blue / 65535.0;
+        	cairo_set_source_rgba (cr, r, g, b, BG_ALPHA);
+        	cairo_set_line_width (cr, 1);
+        	cairo_stroke (cr);
+	}
 
         /* draw action */
         draw_action (window, cr);
@@ -823,7 +1677,7 @@ gsd_media_keys_window_real_hide (GtkWidget *widget)
                 GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->hide (widget);
         }
 
-        window = GSD_MEDIA_KEYS_WINDOW (widget);
+	window = GSD_MEDIA_KEYS_WINDOW (widget);
         remove_hide_timeout (window);
 }
 
diff --git a/plugins/media-keys/gsd-media-keys-window.h b/plugins/media-keys/gsd-media-keys-window.h
index ad75923..f3f7c5b 100644
--- a/plugins/media-keys/gsd-media-keys-window.h
+++ b/plugins/media-keys/gsd-media-keys-window.h
@@ -27,6 +27,10 @@
 
 G_BEGIN_DECLS
 
+#define CPU_GOVERNOR_ONDEMAND                   "ondemand"
+#define CPU_GOVERNOR_POWERSAVE                  "powersave"
+#define CPU_GOVERNOR_PERFORMANCE                "performance"
+
 #define GSD_TYPE_MEDIA_KEYS_WINDOW            (gsd_media_keys_window_get_type ())
 #define GSD_MEDIA_KEYS_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),  GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindow))
 #define GSD_MEDIA_KEYS_WINDOW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),   GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindowClass))
@@ -48,10 +52,38 @@ struct GsdMediaKeysWindowClass {
 };
 
 typedef enum {
-        GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME,
-        GSD_MEDIA_KEYS_WINDOW_ACTION_EJECT
+	GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_EJECT,
+        GSD_MEDIA_KEYS_WINDOW_ACTION_SLEEP,
+        GSD_MEDIA_KEYS_WINDOW_ACTION_NUM_LOCK,
+        GSD_MEDIA_KEYS_WINDOW_ACTION_SCROLL_LOCK,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_WIFI,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_TOUCHPAD_ON,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_TOUCHPAD_OFF,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_XRANDR,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_CPU_GOVERNOR,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_BACKLIGHT,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_PERFORMANCE,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_WEBCAM,
+	GSD_MEDIA_KEYS_WINDOW_ACTION_BLUETOOTH
 } GsdMediaKeysWindowAction;
 
+typedef enum {
+	GSD_MEDIA_KEYS_XRANDR_LCD_ONLY = 0,
+	GSD_MEDIA_KEYS_XRANDR_LCD,
+	GSD_MEDIA_KEYS_XRANDR_CRT,
+	GSD_MEDIA_KEYS_XRANDR_CLONE,
+	GSD_MEDIA_KEYS_XRANDR_DUAL
+} GsdMediaKeysXrandr;
+
+typedef enum {
+	GSD_MEDIA_KEYS_WIFI_ENABLE_ALL = 0,
+	GSD_MEDIA_KEYS_WIFI_ENABLE_WLAN,
+	GSD_MEDIA_KEYS_WIFI_ENABLE_BLUETOOTH,
+	GSD_MEDIA_KEYS_WIFI_ENABLE_WWAN,
+	GSD_MEDIA_KEYS_WIFI_DISABLE_ALL
+} GsdMediaKeysWifi;
+
 GType                 gsd_media_keys_window_get_type          (void);
 
 GtkWidget *           gsd_media_keys_window_new               (void);
@@ -62,7 +94,12 @@ void                  gsd_media_keys_window_set_volume_muted  (GsdMediaKeysWindo
 void                  gsd_media_keys_window_set_volume_level  (GsdMediaKeysWindow      *window,
                                                                int                      level);
 gboolean              gsd_media_keys_window_is_valid          (GsdMediaKeysWindow      *window);
-
+void		      gsd_media_keys_window_set_draw_osd_box  (GsdMediaKeysWindow      *window,
+                                        		       gboolean            draw_osd_box_in);
+void		      gsd_media_keys_window_set_osd_window_size (GsdMediaKeysWindow *window,
+                                           			 int               osd_window_size_in);
+void		      gsd_media_keys_window_set_cust_theme (GsdMediaKeysWindow *window,
+                                      			    GtkIconTheme       *cust_theme_in);
 G_END_DECLS
 
 #endif
openSUSE Build Service is sponsored by