summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Lebl <jirka@5z.com>2003-12-30 23:39:21 +0000
committerGeorge Lebl <jirka@src.gnome.org>2003-12-30 23:39:21 +0000
commit669245886f2437c8efb3adf73f7245e57cb6e818 (patch)
treea9aee98535bd3fe498c2e440ef07c9499fef7a26
parentafa6a5a8099360422eb1f18e1f729872796d8de8 (diff)
downloadgdm-669245886f2437c8efb3adf73f7245e57cb6e818.tar.gz
Complain on some more errors
Tue Dec 30 15:34:59 2003 George Lebl <jirka@5z.com> * daemon/gdm.c, daemon/auth.c: Complain on some more errors * gui/gdmlogin.c, gui/gdmcommon.[ch], gui/gdmsetup.(c|glade), gui/greeter/greeter.c, gui/greeter/greeter_configuration.h, daemon/gdm.[ch], daemon/slave.c: Make the login sound thingie configurable and make it possible to play an arbitrary sound with /usr/bin/play (or whatever else is configured). Add accessibility section to gdmsetup which configures the accessibility modules and the sound. Fixes #125487 * config/gdm.conf.in, docs/C/gdm.xml: Update docs for the accessibility/sound stuff
-rw-r--r--ChangeLog15
-rw-r--r--acconfig.h1
-rw-r--r--config/gdm.conf.in10
-rw-r--r--configure.in5
-rw-r--r--daemon/auth.c8
-rw-r--r--daemon/gdm.c61
-rw-r--r--daemon/gdm.h17
-rw-r--r--daemon/slave.c55
-rw-r--r--docs/C/gdm.xml49
-rw-r--r--gui/gdmcommon.c20
-rw-r--r--gui/gdmcommon.h2
-rw-r--r--gui/gdmlogin.c14
-rw-r--r--gui/gdmsetup-strings.c12
-rw-r--r--gui/gdmsetup.c240
-rw-r--r--gui/gdmsetup.glade372
-rw-r--r--gui/greeter/greeter.c17
-rw-r--r--gui/greeter/greeter_configuration.h3
17 files changed, 861 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index 04433953..c319ddd1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Tue Dec 30 15:34:59 2003 George Lebl <jirka@5z.com>
+
+ * daemon/gdm.c, daemon/auth.c: Complain on some more errors
+
+ * gui/gdmlogin.c, gui/gdmcommon.[ch], gui/gdmsetup.(c|glade),
+ gui/greeter/greeter.c, gui/greeter/greeter_configuration.h,
+ daemon/gdm.[ch], daemon/slave.c: Make the login sound thingie
+ configurable and make it possible to play an arbitrary sound with
+ /usr/bin/play (or whatever else is configured). Add accessibility
+ section to gdmsetup which configures the accessibility modules
+ and the sound. Fixes #125487
+
+ * config/gdm.conf.in, docs/C/gdm.xml: Update docs for the
+ accessibility/sound stuff
+
Mon Dec 29 16:52:32 2003 George Lebl <jirka@5z.com>
* daemon/gdm.[ch]: add SET_SAFE_LOGOUT_ACTION which is like schedule
diff --git a/acconfig.h b/acconfig.h
index a5af232a..df818876 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -25,6 +25,7 @@
#undef EXPANDED_BINDIR
#undef EXPANDED_SBINDIR
#undef EXPANDED_LIBEXECDIR
+#undef EXPANDED_LIBDIR
#undef EXPANDED_GDMCONFIGDIR
#undef EXPANDED_LOCALEDIR
#undef EXPANDED_AUTHDIR
diff --git a/config/gdm.conf.in b/config/gdm.conf.in
index cf68ffea..36cb79a1 100644
--- a/config/gdm.conf.in
+++ b/config/gdm.conf.in
@@ -137,6 +137,10 @@ Xnest=@X_SERVER_PATH@/Xnest -audit 0 -name Xnest
# vts on linux systems for console logins)
#DoubleLoginWarning=true
+# Program used to play sounds. Should not require any 'daemon' or anything
+# like that as it will be run when no one is logged in yet.
+#SoundProgram=/usr/bin/play
+
[security]
# If any distributions ship with this one off, they should be shot
# this is only local, so it's only for say kiosk use, when you
@@ -317,6 +321,12 @@ GraphicalThemeDir=@EXPANDED_DATADIR@/gdm/themes/
# If InfoMsgFile is present then InfoMsgFont can be used to specify the font
# to be used when displaying the contents of the file.
#InfoMsgFont=Sans 24
+# If SoundOnLogin is true, then the greeter will beep when login is ready
+# for user input. If SoundOnLogin is a file and the greeter finds the
+# 'play' executable (see daemon/SoundProgram) it will play that file
+# instead of just beeping
+#SoundOnLogin=true
+#SoundOnLoginFile=
# The chooser is what's displayed when a user wants an indirect XDMCP
# session, or selects Run XDMCP chooser from the system menu
diff --git a/configure.in b/configure.in
index a688e2e5..05f476ab 100644
--- a/configure.in
+++ b/configure.in
@@ -557,6 +557,11 @@ EXPANDED_LIBEXECDIR=`eval echo $LIBEXECDIR_TMP`
AC_SUBST(EXPANDED_LIBEXECDIR)
AC_DEFINE_UNQUOTED(EXPANDED_LIBEXECDIR,"$EXPANDED_LIBEXECDIR")
+LIBDIR_TMP="$libdir"
+EXPANDED_LIBDIR=`eval echo $LIBDIR_TMP`
+AC_SUBST(EXPANDED_LIBDIR)
+AC_DEFINE_UNQUOTED(EXPANDED_LIBDIR,"$EXPANDED_LIBDIR")
+
dnl This is where the binary actually resides,
dnl not the console helper link
if test "x$enable_console_helper" = "xyes"; then
diff --git a/daemon/auth.c b/daemon/auth.c
index 543d6284..a6549235 100644
--- a/daemon/auth.c
+++ b/daemon/auth.c
@@ -881,9 +881,15 @@ gdm_auth_user_remove (GdmDisplay *d, uid_t user)
af = gdm_auth_purge (d, af, TRUE /* remove when empty */);
/* Close the file and unlock it */
- if (af != NULL)
+ if (af != NULL) {
/* FIXME: what about out of diskspace errors on errors close */
+ errno = 0;
VE_IGNORE_EINTR (fclose (af));
+ if G_UNLIKELY (errno != 0) {
+ gdm_error (_("Can't write to %s: %s"), d->userauth,
+ strerror (errno));
+ }
+ }
XauUnlockAuth (d->userauth);
diff --git a/daemon/gdm.c b/daemon/gdm.c
index d563adfb..bee7b5f7 100644
--- a/daemon/gdm.c
+++ b/daemon/gdm.c
@@ -190,6 +190,8 @@ gchar *GdmXnest = NULL;
int GdmFirstVT = 7;
gboolean GdmVTAllocation = TRUE;
gboolean GdmDisallowTCP = TRUE;
+gchar *GdmSoundProgram = NULL;
+gchar *GdmSoundOnLoginFile = NULL;
/* set in the main function */
@@ -407,9 +409,12 @@ gdm_config_parse (void)
if (ve_string_empty (GdmXnest))
GdmXnest = NULL;
- GdmFirstVT = ve_config_get_int (cfg, GDM_KEY_FIRSTVT);
- GdmVTAllocation = ve_config_get_bool (cfg, GDM_KEY_VTALLOCATION);
- GdmDisallowTCP = ve_config_get_bool (cfg, GDM_KEY_DISALLOWTCP);
+ GdmFirstVT = ve_config_get_int (cfg, GDM_KEY_FIRSTVT);
+ GdmVTAllocation = ve_config_get_bool (cfg, GDM_KEY_VTALLOCATION);
+ GdmDisallowTCP = ve_config_get_bool (cfg, GDM_KEY_DISALLOWTCP);
+
+ GdmSoundProgram = ve_config_get_string (cfg, GDM_KEY_SOUND_PROGRAM);
+ GdmSoundOnLoginFile = ve_config_get_string (cfg, GDM_KEY_SOUND_ON_LOGIN_FILE);
GdmDebug = ve_config_get_bool (cfg, GDM_KEY_DEBUG);
@@ -1170,6 +1175,11 @@ suspend_machine (void)
if (GdmSuspendReal != NULL &&
fork () == 0) {
char **argv;
+
+ /* sync everything to disk, just in case something goes
+ * wrong with the suspend */
+ sync ();
+
if (GdmXdmcp)
gdm_xdmcp_close ();
/* In the child setup empty mask and set all signals to
@@ -1181,6 +1191,9 @@ suspend_machine (void)
VE_IGNORE_EINTR (chdir ("/"));
+ /* short sleep to give some processing time to master */
+ usleep (1000);
+
argv = ve_split (GdmSuspendReal);
if (argv != NULL && argv[0] != NULL)
VE_IGNORE_EINTR (execv (argv[0], argv));
@@ -2170,7 +2183,7 @@ write_x_servers (GdmDisplay *d)
fp = gdm_safe_fopen_w (file);
if G_UNLIKELY (fp == NULL) {
- gdm_error ("Can't open %s for writing", file);
+ gdm_error (_("Can't open %s for writing"), file);
g_free (file);
return;
}
@@ -2198,7 +2211,14 @@ write_x_servers (GdmDisplay *d)
}
/* FIXME: What about out of disk space errors? */
+ errno = 0;
VE_IGNORE_EINTR (fclose (fp));
+ if G_UNLIKELY (errno != 0) {
+ gdm_error (_("Can't write to %s: %s"), file,
+ strerror (errno));
+ }
+
+ g_free (file);
}
static void
@@ -3306,6 +3326,39 @@ update_config (const char *key)
if (gdm_xdmcp_init ())
gdm_xdmcp_run ();
}
+ } else if (is_key (key, GDM_KEY_SOUND_ON_LOGIN_FILE)) {
+ char *val = ve_config_get_string (cfg, GDM_KEY_SOUND_ON_LOGIN_FILE);
+ if (strcmp (ve_sure_string (val), ve_sure_string (GdmSoundOnLoginFile)) == 0) {
+ g_free (val);
+ goto update_config_ok;
+ }
+ g_free (GdmSoundOnLoginFile);
+ GdmSoundOnLoginFile = val;
+
+ notify_displays_string (GDM_NOTIFY_SOUND_ON_LOGIN_FILE, val);
+
+ goto update_config_ok;
+ } else if (is_key (key, GDM_KEY_GTK_MODULES_LIST)) {
+ char *val = ve_config_get_string (cfg, GDM_KEY_GTK_MODULES_LIST);
+ if (strcmp (ve_sure_string (val), ve_sure_string (GdmGtkModulesList)) == 0) {
+ g_free (val);
+ goto update_config_ok;
+ }
+ g_free (GdmGtkModulesList);
+ GdmGtkModulesList = val;
+
+ notify_displays_string (GDM_NOTIFY_GTK_MODULES_LIST, val);
+
+ goto update_config_ok;
+ } else if (is_key (key, GDM_KEY_ADD_GTK_MODULES)) {
+ gboolean val = ve_config_get_bool (cfg, GDM_KEY_ADD_GTK_MODULES);
+ if (ve_bool_equal (val, GdmAddGtkModules))
+ goto update_config_ok;
+ GdmAddGtkModules = val;
+
+ notify_displays_int (GDM_NOTIFY_ADD_GTK_MODULES, val);
+
+ goto update_config_ok;
}
ve_config_destroy (cfg);
diff --git a/daemon/gdm.h b/daemon/gdm.h
index 7fc88626..9353f194 100644
--- a/daemon/gdm.h
+++ b/daemon/gdm.h
@@ -113,6 +113,7 @@ enum {
#define GDM_INTERRUPT_CONFIGURE 'C'
#define GDM_INTERRUPT_SUSPEND 'S'
#define GDM_INTERRUPT_SELECT_USER 'U'
+#define GDM_INTERRUPT_LOGIN_SOUND 'L'
/* The dreaded miscellaneous category */
#define FIELD_SIZE 256
@@ -247,6 +248,10 @@ enum {
#define GDM_KEY_INFO_MSG_FILE "greeter/InfoMsgFile="
#define GDM_KEY_INFO_MSG_FONT "greeter/InfoMsgFont="
+#define GDM_KEY_SOUND_ON_LOGIN "greeter/SoundOnLogin=true"
+#define GDM_KEY_SOUND_ON_LOGIN_FILE "greeter/SoundOnLoginFile="
+#define GDM_KEY_SOUND_PROGRAM "daemon/SoundProgram=/usr/bin/play"
+
#define GDM_KEY_SCAN "chooser/ScanTime=4"
#define GDM_KEY_HOST "chooser/DefaultHostImg=" EXPANDED_PIXMAPDIR "/nohost.png"
#define GDM_KEY_HOSTDIR "chooser/HostImageDir=" EXPANDED_DATADIR "/hosts/"
@@ -553,6 +558,9 @@ void gdm_final_cleanup (void);
#define GDM_NOTIFY_TIMED_LOGIN "TimedLogin" /* <login> */
#define GDM_NOTIFY_TIMED_LOGIN_DELAY "TimedLoginDelay" /* <seconds> */
#define GDM_NOTIFY_DISALLOWTCP "DisallowTCP" /* <true/false as int> */
+#define GDM_NOTIFY_SOUND_ON_LOGIN_FILE "SoundOnLoginFile" /* <sound file> */
+#define GDM_NOTIFY_ADD_GTK_MODULES "AddGtkModules" /* <true/false as int> */
+#define GDM_NOTIFY_GTK_MODULES_LIST "GtkModulesList" /* <modules list> */
/* commands */
#define GDM_NOTIFY_DIRTY_SERVERS "DIRTY_SERVERS"
@@ -723,12 +731,15 @@ void gdm_final_cleanup (void);
* xdmcp/MaxPendingIndirect
* xdmcp/MaxWaitIndirect
* xdmcp/PingIntervalSeconds (only affects new connections)
- * xdmcp/TimedLogin (2.3.90.3)
- * xdmcp/TimedLoginEnable (2.3.90.3)
- * xdmcp/TimedLoginDelay (2.3.90.3)
+ * daemon/TimedLogin (2.3.90.3)
+ * daemon/TimedLoginEnable (2.3.90.3)
+ * daemon/TimedLoginDelay (2.3.90.3)
* greeter/SystemMenu (2.3.90.3)
* greeter/ConfigAvailable (2.3.90.3)
* greeter/ChooserButton (2.4.2.0)
+ * greeter/SoundOnLoginFile (2.5.90.0)
+ * daemon/AddGtkModules (2.5.90.0)
+ * daemon/GtkModulesList (2.5.90.0)
* Supported since: 2.3.90.2
* Arguments: <key>
* <key> is just the base part of the key such as "security/AllowRemoteRoot"
diff --git a/daemon/slave.c b/daemon/slave.c
index a5a09c4f..28d97978 100644
--- a/daemon/slave.c
+++ b/daemon/slave.c
@@ -174,6 +174,8 @@ extern gboolean GdmAllowRemoteRoot;
extern gchar *GdmGlobalFaceDir;
extern gboolean GdmDebug;
extern gboolean GdmDisallowTCP;
+extern gchar *GdmSoundProgram;
+extern gchar *GdmSoundOnLoginFile;
/* Local prototypes */
@@ -3625,13 +3627,9 @@ session_child_run (struct passwd *pwent,
if ( ! gdm_selinux_setup (pwent->pw_name)) {
/* 66 means no "session crashed" examine .xsession-errors
dialog */
- /* FIXME: do this when we get out of string freeze */
- /*
- gdm_error_box (d, GTK_MESSAGE_ERROR, _("Error! Unable to set executable context."));
+ gdm_error_box (d, GTK_MESSAGE_ERROR,
+ _("Error! Unable to set executable context."));
_exit (66);
- */
- /* errors have alredy been logged to .xsession-errors */
- _exit (1);
}
#endif
@@ -4646,6 +4644,37 @@ check_for_interruption (const char *msg)
/* Not interrupted, continue reading input,
* just proxy this to the master server */
return TRUE;
+ case GDM_INTERRUPT_LOGIN_SOUND:
+ if (d->console &&
+ ! ve_string_empty (GdmSoundProgram) &&
+ ! ve_string_empty (GdmSoundOnLoginFile) &&
+ access (GdmSoundProgram, X_OK) == 0 &&
+ access (GdmSoundOnLoginFile, F_OK) == 0) {
+ pid_t pid;
+
+ gdm_sigchld_block_push ();
+ gdm_sigterm_block_push ();
+ pid = fork ();
+ if (pid == 0)
+ gdm_unset_signals ();
+ gdm_sigterm_block_pop ();
+ gdm_sigchld_block_pop ();
+
+ if (pid == 0) {
+ setsid ();
+ seteuid (0);
+ setegid (0);
+ execl (GdmSoundProgram,
+ GdmSoundProgram,
+ GdmSoundOnLoginFile,
+ NULL);
+
+ _exit (0);
+ }
+ } else {
+ gdm_error (_("Login sound requested on non-local display or the play software cannot be run or the sound does not exist"));
+ }
+ return TRUE;
case GDM_INTERRUPT_SELECT_USER:
gdm_verify_select_user (&msg[2]);
break;
@@ -5248,6 +5277,20 @@ gdm_slave_handle_notify (const char *msg)
GdmTimedLoginDelay = val;
if (d->greetpid > 1)
kill (d->greetpid, SIGHUP);
+ } else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_FILE " ",
+ strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1) == 0) {
+ g_free (GdmSoundOnLoginFile);
+ GdmSoundOnLoginFile = g_strdup
+ (&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1]);
+ if (d->greetpid > 1)
+ kill (d->greetpid, SIGHUP);
+ } else if (strncmp (msg, GDM_NOTIFY_GTK_MODULES_LIST " ",
+ strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1) == 0) {
+ g_free (GdmGtkModulesList);
+ GdmGtkModulesList = g_strdup
+ (&msg[strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1]);
+ } else if (sscanf (msg, GDM_NOTIFY_ADD_GTK_MODULES " %d", &val) == 1) {
+ GdmAddGtkModules = val;
}
}
diff --git a/docs/C/gdm.xml b/docs/C/gdm.xml
index fb8eb439..7c4ad1c6 100644
--- a/docs/C/gdm.xml
+++ b/docs/C/gdm.xml
@@ -3,7 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY legal SYSTEM "legal.xml">
<!ENTITY version "2.5.90.0">
- <!ENTITY date "12/12/2003">
+ <!ENTITY date "12/30/2003">
]>
<article id="index" lang="en">
@@ -33,7 +33,7 @@
<year>1998</year> <year>1999</year> <holder>Martin K. Petersen</holder>
</copyright>
<copyright>
- <year>2001</year> <holder>George Lebl</holder>
+ <year>2001</year> <year>2003</year> <holder>George Lebl</holder>
</copyright>
<copyright>
<year>2003</year> <holder>Red Hat, Inc.</holder>
@@ -61,7 +61,7 @@
<para>
GDM - Gnome Display Manager. Used to describe the software
- package as a whole.
+ package as a whole. Sometimes also referred to as GDM2.
</para>
<para>
@@ -1461,6 +1461,19 @@
</varlistentry>
<varlistentry>
+ <term>SoundProgram</term>
+ <listitem>
+ <synopsis>SoundProgram=/usr/bin/play</synopsis>
+ <para>
+ Program to use when playing a sound. Currently used for
+ playing the login sound, see
+ the <filename>SoundOnLoginFile</filename> key.
+ Supported since 2.5.90.0.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>StandardXServer</term>
<listitem>
<synopsis>StandardXServer=/usr/X11R6/bin/X</synopsis>
@@ -2454,6 +2467,36 @@
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>SoundOnLogin</term>
+ <listitem>
+ <synopsis>SoundOnLogin=true</synopsis>
+ <para>
+ If true, the greeter will play a sound or beep when
+ it is ready for a login. See also the
+ <filename>SoundOnLoginFile</filename> key.
+ Supported since 2.5.90.0.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>SoundOnLoginFile</term>
+ <listitem>
+ <synopsis>SoundOnLogin=/path/to/sound.wav</synopsis>
+ <para>
+ The file that will be played using the specified
+ sound program (by default that is
+ <filename>/usr/bin/play</filename>) instead of a beep
+ when the greeter is ready for a login.
+ See also the
+ <filename>SoundOnLogin</filename> key and the
+ <filename>SoundProgram</filename> key.
+ Supported since 2.5.90.0.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>SystemMenu</term>
diff --git a/gui/gdmcommon.c b/gui/gdmcommon.c
index 04da5544..615ae43e 100644
--- a/gui/gdmcommon.c
+++ b/gui/gdmcommon.c
@@ -36,6 +36,9 @@
extern gchar *GdmInfoMsgFile;
extern gchar *GdmInfoMsgFont;
+extern gchar *GdmSoundProgram;
+extern gboolean GdmSoundOnLogin;
+extern gchar *GdmSoundOnLoginFile;
void
gdm_common_show_info_msg (void)
@@ -223,4 +226,21 @@ gdm_common_int_same (VeConfig *config, int cur, const char *key)
}
}
+void
+gdm_common_login_sound (void)
+{
+ if ( ! GdmSoundOnLogin)
+ return;
+ if (ve_string_empty (g_getenv ("GDM_IS_LOCAL")) ||
+ ve_string_empty (GdmSoundProgram) ||
+ ve_string_empty (GdmSoundOnLoginFile) ||
+ access (GdmSoundProgram, F_OK) != 0 ||
+ access (GdmSoundOnLoginFile, F_OK) != 0) {
+ gdk_beep ();
+ } else {
+ /* login sound interruption */
+ printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_LOGIN_SOUND);
+ fflush (stdout);
+ }
+}
diff --git a/gui/gdmcommon.h b/gui/gdmcommon.h
index c08a3d93..9d8cde49 100644
--- a/gui/gdmcommon.h
+++ b/gui/gdmcommon.h
@@ -40,6 +40,8 @@ gboolean gdm_common_bool_same (VeConfig *config,
gboolean gdm_common_int_same (VeConfig *config,
int cur, const char *key);
+void gdm_common_login_sound (void);
+
/* The greeter defines this, we just call it from here */
void gdm_kill_thingies (void);
diff --git a/gui/gdmlogin.c b/gui/gdmlogin.c
index 196ae820..feded984 100644
--- a/gui/gdmlogin.c
+++ b/gui/gdmlogin.c
@@ -124,6 +124,10 @@ static gint GdmPositionX;
static gint GdmPositionY;
static gboolean GdmTitleBar;
+gboolean GdmSoundOnLogin;
+gchar *GdmSoundOnLoginFile;
+gchar *GdmSoundProgram;
+
static gboolean GdmShowGnomeFailsafeSession;
static gboolean GdmShowXtermFailsafeSession;
static gboolean GdmShowLastSession;
@@ -716,6 +720,10 @@ gdm_login_parse_config (void)
GdmFlexiReapDelayMinutes = ve_config_get_int (config, GDM_KEY_FLEXI_REAP_DELAY_MINUTES);
GdmUse24Clock = ve_config_get_bool (config, GDM_KEY_USE_24_CLOCK);
+ GdmSoundOnLogin = ve_config_get_bool (config, GDM_KEY_SOUND_ON_LOGIN);
+ GdmSoundOnLoginFile = ve_config_get_string (config, GDM_KEY_SOUND_ON_LOGIN_FILE);
+ GdmSoundProgram = ve_config_get_string (config, GDM_KEY_SOUND_PROGRAM);
+
if (GdmIconMaxWidth < 0) GdmIconMaxWidth = 128;
if (GdmIconMaxHeight < 0) GdmIconMaxHeight = 128;
if (GdmXineramaScreen < 0) GdmXineramaScreen = 0;
@@ -1744,7 +1752,7 @@ gdm_login_ctrl_handler (GIOChannel *source, GIOCondition cond, gint fd)
tmp = ve_locale_to_utf8 (buf);
if (strcmp (tmp, _("Username:")) == 0) {
- gdk_beep ();
+ gdm_common_login_sound ();
gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _("_Username:"));
} else {
gtk_label_set_text (GTK_LABEL (label), tmp);
@@ -3506,6 +3514,10 @@ gdm_reread_config (int sig, gpointer data)
}
}
+ GdmSoundProgram = ve_config_get_string (config, GDM_KEY_SOUND_PROGRAM);
+ GdmSoundOnLogin = ve_config_get_bool (config, GDM_KEY_SOUND_ON_LOGIN);
+ GdmSoundOnLoginFile = ve_config_get_string (config, GDM_KEY_SOUND_ON_LOGIN_FILE);
+
GdmUse24Clock = ve_config_get_bool (config, GDM_KEY_USE_24_CLOCK);
update_clock (NULL);
diff --git a/gui/gdmsetup-strings.c b/gui/gdmsetup-strings.c
index 5412dc3e..38abc95b 100644
--- a/gui/gdmsetup-strings.c
+++ b/gui/gdmsetup-strings.c
@@ -68,11 +68,23 @@ gchar *s = N_("Allow root to login r_emotely with GDM");
gchar *s = N_("Allow remote _timed logins");
gchar *s = N_("Show the \"Actions\" menu (formerly known as the \"System\" menu). If not set, none of the system commands will be available (this includes reboot, shutdown, configure, chooser)");
gchar *s = N_("Show _actions menu");
+gchar *s = N_(" ");
gchar *s = N_("Allow c_onfiguration from the login screen");
+gchar *s = N_(" ");
gchar *s = N_("Allo_w running XDMCP chooser from the login screen");
gchar *s = N_("Always disallow TCP connections to _X server (disables all remote connections)");
gchar *s = N_("Retry _delay (seconds) :");
gchar *s = N_("Security");
+gchar *s = N_("Options");
+gchar *s = N_(" ");
+gchar *s = N_("Enable _accessibility modules");
+gchar *s = N_("Make a _sound when login window is ready");
+gchar *s = N_(" ");
+gchar *s = N_("acc_sound_file_box");
+gchar *s = N_("Sound _file:");
+gchar *s = N_("*");
+gchar *s = N_("_Test sound");
+gchar *s = N_("Accessibility");
gchar *s = N_("No XDMCP support in the binary. To enable XDMCP support you must recompile GDM with the XDMCP libraries.");
gchar *s = N_("Enable _XDMCP");
gchar *s = N_(" ");
diff --git a/gui/gdmsetup.c b/gui/gdmsetup.c
index 436342be..633592ac 100644
--- a/gui/gdmsetup.c
+++ b/gui/gdmsetup.c
@@ -51,6 +51,7 @@ static gboolean RUNNING_UNDER_GDM = FALSE;
static gboolean gdm_running = FALSE;
static int GdmMinimalUID = 100;
+static char *GdmSoundProgram = NULL;
static GladeXML *xml;
@@ -565,6 +566,27 @@ setup_intspin (const char *name,
G_CALLBACK (intspin_changed), NULL);
}
+static void
+setup_notify_entry (const char *name,
+ const char *key)
+{
+ GtkWidget *entry = glade_helper_get (xml, name, GTK_TYPE_ENTRY);
+ char *val;
+
+ val = ve_config_get_string (ve_config_get (GDM_CONFIG_FILE), key);
+
+ g_object_set_data_full (G_OBJECT (entry),
+ "key", g_strdup (key),
+ (GDestroyNotify) g_free);
+
+ gtk_entry_set_text (GTK_ENTRY (entry), ve_sure_string (val));
+
+ g_signal_connect (G_OBJECT (entry), "changed",
+ G_CALLBACK (entry_changed), NULL);
+
+ g_free (val);
+}
+
static gboolean
greeter_toggle_timeout (GtkWidget *toggle)
{
@@ -948,6 +970,204 @@ setup_xdmcp_support (void)
}
static void
+test_sound (GtkWidget *button, gpointer data)
+{
+ GtkEntry *entry = GTK_ENTRY (data);
+ const char *file = gtk_entry_get_text (GTK_ENTRY (entry));
+ const char *argv[3];
+
+ if (ve_string_empty (file) ||
+ access (file, R_OK) != 0 ||
+ ve_string_empty (GdmSoundProgram))
+ return;
+
+ argv[0] = GdmSoundProgram;
+ argv[1] = file;
+ argv[2] = NULL;
+
+ g_spawn_async ("/" /* working directory */,
+ (char **)argv,
+ NULL /* envp */,
+ 0 /* flags */,
+ NULL /* child setup */,
+ NULL /* user data */,
+ NULL /* child pid */,
+ NULL /* error */);
+}
+
+static gboolean
+module_compare (const char *mod1, const char *mod2)
+{
+ char *base1;
+ char *base2;
+ char *p;
+ gboolean ret;
+
+ /* first cannonify the names */
+ base1 = g_path_get_basename (mod1);
+ base2 = g_path_get_basename (mod2);
+ if (strncmp (base1, "lib", 3) == 0)
+ strcpy (base1, &base1[3]);
+ if (strncmp (base2, "lib", 3) == 0)
+ strcpy (base2, &base2[3]);
+ p = strstr (base1, ".so");
+ if (p != NULL)
+ *p = '\0';
+ p = strstr (base2, ".so");
+ if (p != NULL)
+ *p = '\0';
+
+ ret = (strcmp (base1, base2) == 0);
+
+ g_free (base1);
+ g_free (base2);
+
+ return ret;
+}
+
+static gboolean
+modules_list_contains (const char *modules_list, const char *module)
+{
+ char **vec;
+ int i;
+
+ if (ve_string_empty (modules_list))
+ return FALSE;
+
+ vec = g_strsplit (modules_list, ":", -1);
+ if (vec == NULL)
+ return FALSE;
+
+ for (i = 0; vec[i] != NULL; i++) {
+ if (module_compare (vec[i], module)) {
+ g_strfreev (vec);
+ return TRUE;
+ }
+ }
+
+ g_strfreev (vec);
+ return FALSE;
+}
+
+static char *
+modules_list_remove (char *modules_list, const char *module)
+{
+ char **vec;
+ GString *str;
+ char *sep = "";
+ int i;
+
+ if (ve_string_empty (modules_list))
+ return g_strdup ("");
+
+ vec = g_strsplit (modules_list, ":", -1);
+ if (vec == NULL)
+ return g_strdup ("");
+
+ str = g_string_new (NULL);
+
+ for (i = 0; vec[i] != NULL; i++) {
+ if ( ! module_compare (vec[i], module)) {
+ g_string_append (str, sep);
+ sep = ":";
+ g_string_append (str, vec[i]);
+ }
+ }
+
+ g_strfreev (vec);
+
+ return g_string_free (str, FALSE);
+}
+
+static char *
+modules_list_add (char *modules_list, const char *module)
+{
+ char *n;
+ if (ve_string_empty (modules_list))
+ n = g_strdup (module);
+ else
+ n = g_strconcat (modules_list, ":", module, NULL);
+ g_free (modules_list);
+ return n;
+}
+
+static void
+acc_modules_toggled (GtkWidget *toggle, gpointer data)
+{
+ gboolean add_gtk_modules = ve_config_get_bool (ve_config_get (GDM_CONFIG_FILE),
+ GDM_KEY_ADD_GTK_MODULES);
+ char *modules_list = ve_config_get_string (ve_config_get (GDM_CONFIG_FILE),
+ GDM_KEY_GTK_MODULES_LIST);
+
+ /* first whack the modules from the list */
+ modules_list = modules_list_remove (modules_list, "gail");
+ modules_list = modules_list_remove (modules_list, "atk-bridge");
+ modules_list = modules_list_remove (modules_list, "dwellmouselistener");
+ modules_list = modules_list_remove (modules_list, "keymouselistener");
+
+ if (GTK_TOGGLE_BUTTON (toggle)->active) {
+ if ( ! add_gtk_modules) {
+ g_free (modules_list);
+ modules_list = NULL;
+ }
+
+ modules_list = modules_list_add (modules_list, "gail");
+ modules_list = modules_list_add (modules_list, "atk-bridge");
+ modules_list = modules_list_add (modules_list, EXPANDED_LIBDIR "/gtk-2.0/modules/libkeymouselistener");
+ modules_list = modules_list_add (modules_list, EXPANDED_LIBDIR "/gtk-2.0/modules/libdwellmouselistener");
+
+ add_gtk_modules = TRUE;
+ }
+
+ if (ve_string_empty (modules_list))
+ add_gtk_modules = FALSE;
+
+ ve_config_set_string (ve_config_get (GDM_CONFIG_FILE),
+ GDM_KEY_GTK_MODULES_LIST,
+ ve_sure_string (modules_list));
+ ve_config_set_bool (ve_config_get (GDM_CONFIG_FILE),
+ GDM_KEY_ADD_GTK_MODULES,
+ add_gtk_modules);
+
+ g_free (modules_list);
+
+ update_key (GDM_KEY_GTK_MODULES_LIST);
+ update_key (GDM_KEY_ADD_GTK_MODULES);
+}
+
+static void
+setup_accessibility_support (void)
+{
+ GtkWidget *acc_modules = glade_helper_get (xml, "acc_modules", GTK_TYPE_TOGGLE_BUTTON);
+ GtkWidget *acc_sound_test = glade_helper_get (xml, "acc_sound_test", GTK_TYPE_BUTTON);
+ GtkWidget *acc_sound_file_entry = glade_helper_get (xml, "acc_sound_file_entry", GTK_TYPE_ENTRY);
+
+ gboolean add_gtk_modules = ve_config_get_bool (ve_config_get (GDM_CONFIG_FILE),
+ GDM_KEY_ADD_GTK_MODULES);
+ char *modules_list = ve_config_get_string (ve_config_get (GDM_CONFIG_FILE),
+ GDM_KEY_GTK_MODULES_LIST);
+
+ if (add_gtk_modules &&
+ modules_list_contains (modules_list, "gail") &&
+ modules_list_contains (modules_list, "atk-bridge") &&
+ modules_list_contains (modules_list, "dwellmouselistener") &&
+ modules_list_contains (modules_list, "keymouselistener")) {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (acc_modules),
+ TRUE);
+ } else {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (acc_modules),
+ FALSE);
+ }
+
+ g_signal_connect (G_OBJECT (acc_modules), "toggled",
+ G_CALLBACK (acc_modules_toggled),
+ NULL);
+ g_signal_connect (G_OBJECT (acc_sound_test), "clicked",
+ G_CALLBACK (test_sound),
+ acc_sound_file_entry);
+}
+
+static void
background_toggled (void)
{
GtkWidget *no_bg = glade_helper_get (xml, "sg_no_bg_rb", GTK_TYPE_TOGGLE_BUTTON);
@@ -2148,8 +2368,11 @@ setup_gui (void)
glade_helper_tagify_label (xml, "gg_desc_label", "b");
glade_helper_tagify_label (xml, "gg_copyright_label", "b");
+ glade_helper_tagify_label (xml, "acc_options_cat_label", "b");
+
glade_helper_tagify_label (xml, "enable_xdmcp", "b");
+ setup_accessibility_support ();
setup_xdmcp_support ();
setup_background_support ();
setup_greeter_backselect ();
@@ -2227,10 +2450,18 @@ setup_gui (void)
GDM_KEY_DISALLOWTCP,
GDM_KEY_DISALLOWTCP /* notify_key */);
- /* setup sensitivities */
+ /* security sensitivities */
setup_sensitivity_positive_toggle ("sysmenu", "config_available");
setup_sensitivity_positive_toggle ("sysmenu", "chooser_button");
+ setup_greeter_toggle ("acc_beep",
+ GDM_KEY_SOUND_ON_LOGIN);
+ setup_notify_entry ("acc_sound_file_entry",
+ GDM_KEY_SOUND_ON_LOGIN_FILE);
+
+ /* accesibility sensitivities */
+ setup_sensitivity_positive_toggle ("acc_beep", "acc_sound_file_box");
+
setup_notify_toggle ("enable_xdmcp",
GDM_KEY_XDMCP,
GDM_KEY_XDMCP /* notify_key */);
@@ -2485,6 +2716,13 @@ main (int argc, char *argv[])
* ui? Say it ain't so. Our config sections are SUCH A MESS */
GdmMinimalUID = ve_config_get_int (ve_config_get (GDM_CONFIG_FILE),
GDM_KEY_MINIMALUID);
+ GdmSoundProgram = ve_config_get_string (ve_config_get (GDM_CONFIG_FILE),
+ GDM_KEY_SOUND_PROGRAM);
+ if (ve_string_empty (GdmSoundProgram) ||
+ access (GdmSoundProgram, X_OK) != 0) {
+ g_free (GdmSoundProgram);
+ GdmSoundProgram = NULL;
+ }
setup_gui ();
diff --git a/gui/gdmsetup.glade b/gui/gdmsetup.glade
index c8f597f2..3ffbcb32 100644
--- a/gui/gdmsetup.glade
+++ b/gui/gdmsetup.glade
@@ -1918,33 +1918,101 @@ widget</property>
</child>
<child>
- <widget class="GtkCheckButton" id="config_available">
+ <widget class="GtkHBox" id="hbox17">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Allow c_onfiguration from the login screen</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label62">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"> </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="config_available">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Allow c_onfiguration from the login screen</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
</packing>
</child>
<child>
- <widget class="GtkCheckButton" id="chooser_button">
+ <widget class="GtkHBox" id="hbox18">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Allo_w running XDMCP chooser from the login screen</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label63">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"> </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="chooser_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Allo_w running XDMCP chooser from the login screen</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="padding">0</property>
@@ -2078,6 +2146,274 @@ widget</property>
</child>
<child>
+ <widget class="GtkVBox" id="vbox20">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">18</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox21">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkLabel" id="acc_options_cat_label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Options</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox16">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label61">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"> </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox22">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="acc_modules">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Enable _accessibility modules</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="acc_beep">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Make a _sound when login window is ready</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox19">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label64">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"> </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHBox" id="acc_sound_file_box">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+ <accessibility>
+ <atkproperty name="AtkObject::accessible_name" translatable="yes">acc_sound_file_box</atkproperty>
+ </accessibility>
+
+ <child>
+ <widget class="GtkLabel" id="label65">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Sound _file:</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">acc_sound_file_entry</property>
+ <accessibility>
+ <atkrelation target="acc_sound_test" type="label-for"/>
+ <atkrelation target="acc_sound_file_entry" type="label-for"/>
+ </accessibility>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GnomeFileEntry" id="acc_sound_file">
+ <property name="visible">True</property>
+ <property name="max_saved">10</property>
+ <property name="directory_entry">False</property>
+ <property name="modal">False</property>
+
+ <child internal-child="entry">
+ <widget class="GtkEntry" id="acc_sound_file_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="acc_sound_test">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Test sound</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label59">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Accessibility</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ </packing>
+ </child>
+
+ <child>
<widget class="GtkVBox" id="vbox1">
<property name="border_width">5</property>
<property name="visible">True</property>
diff --git a/gui/greeter/greeter.c b/gui/greeter/greeter.c
index 96222f52..8c00341a 100644
--- a/gui/greeter/greeter.c
+++ b/gui/greeter/greeter.c
@@ -73,6 +73,9 @@ gchar *GdmServAuthDir;
gchar *GdmInfoMsgFile;
gchar *GdmInfoMsgFont;
gint GdmFlexiReapDelayMinutes;
+gboolean GdmSoundOnLogin;
+gchar *GdmSoundOnLoginFile;
+gchar *GdmSoundProgram;
gboolean GdmUseCirclesInEntry = FALSE;
@@ -194,6 +197,10 @@ greeter_parse_config (void)
GdmGlobalFaceDir = ve_config_get_string (config, GDM_KEY_FACEDIR);
GdmDefaultFace = ve_config_get_string (config, GDM_KEY_FACE);
+ GdmSoundProgram = ve_config_get_string (config, GDM_KEY_SOUND_PROGRAM);
+ GdmSoundOnLogin = ve_config_get_bool (config, GDM_KEY_SOUND_ON_LOGIN);
+ GdmSoundOnLoginFile = ve_config_get_string (config, GDM_KEY_SOUND_ON_LOGIN_FILE);
+
if (GdmXineramaScreen < 0)
GdmXineramaScreen = 0;
if (GdmIconMaxWidth < 0) GdmIconMaxWidth = 128;
@@ -261,7 +268,7 @@ greeter_ctrl_handler (GIOChannel *source,
tmp = ve_locale_to_utf8 (buf);
if (tmp != NULL && strcmp (tmp, _("Username:")) == 0) {
- gdk_beep ();
+ gdm_common_login_sound ();
greeter_probably_login_prompt = TRUE;
} else {
greeter_probably_login_prompt = FALSE;
@@ -818,9 +825,13 @@ greeter_reread_config (int sig, gpointer data)
_exit (DISPLAY_RESTARTGREETER);
}
+ GdmSoundProgram = ve_config_get_string (config, GDM_KEY_SOUND_PROGRAM);
+ GdmSoundOnLogin = ve_config_get_bool (config, GDM_KEY_SOUND_ON_LOGIN);
+ GdmSoundOnLoginFile = ve_config_get_string (config, GDM_KEY_SOUND_ON_LOGIN_FILE);
+
if ( ! gdm_common_bool_same (config,
- GdmUse24Clock,
- GDM_KEY_USE_24_CLOCK)) {
+ GdmUse24Clock,
+ GDM_KEY_USE_24_CLOCK)) {
GdmUse24Clock = ve_config_get_bool (config,
GDM_KEY_USE_24_CLOCK);
greeter_item_clock_update ();
diff --git a/gui/greeter/greeter_configuration.h b/gui/greeter/greeter_configuration.h
index bb3c5198..79df729b 100644
--- a/gui/greeter/greeter_configuration.h
+++ b/gui/greeter/greeter_configuration.h
@@ -32,6 +32,9 @@ extern gchar *GdmWelcome;
extern gchar *GdmServAuthDir;
extern gchar *GdmInfoMsgFile;
extern gchar *GdmInfoMsgFont;
+extern gchar *GdmSoundProgram;
+extern gchar *GdmSoundOnLoginFile;
+extern gboolean GdmSoundOnLogin;
extern gboolean GDM_IS_LOCAL;
extern gboolean DOING_GDM_DEVELOPMENT;