*Background*
Patch 120094-22, may cause performance degradation of CPU and system 
become unresposive when Trusted Extension or  Accessibility is turned 
on. Fixes of CR 6769901 are not appropriate should be corrected with CR 
6839026, on all the x86 and SPARC machine .

When a machine is patched with 120094-22, Symptoms are as follows.

a) When screen is locked and Accessibility is turned on, popup window 
might make x86/SPARC machine unresponsive.
b) When screen is locked and Trusted Extension is turned on, may cause 
performance degradation of CPU. [tx] Xsun chews cpu and console appear 
to be hung.

*Questions*
Q:why we have not fixed it at WindowManager?
Ans: We got some success in fixing this bug at  metacity/WM, but with 
lots of code changes. Login helper interface is required at metacity

Q: Is it fixed completly .What is remaining?
Ans: Yes this bug is fixed completely.  But we should wait for final 
test results,  if any problem comes we will fix in CR6875930.
There are some special cases, where we need to do restacking of pop up 
windows in timer.c . Also  there are some existing bugs in a11y, we will 
address them separately.
We are fixing this bug in incremental mode, all the remaining problem 
will be fixed in CR6875930


*What we have fixied*
Xsun is consuming 100% cpu cycle with trusted path because of  CR6769901
Also we found, with accessibility, cpu consumption goes to 100%
Popup window should not come through screensaver.

*Testing *
a) Pop-ups will not come through screensaver  in case of dual head 
display with and without xinerama . Same is the case when a11y is turned on.
b)Pop-ups will not come through screensaver  with  twinview  display of 
Xorg. Also there will be no performance degradation with my fixes
c) Pop-ups will not come through screensaver  with trusted path
d) Pop-ups will not come through screensaver  with all  a11y cases
e) works fine with Xnewt,Xorg and Xsun
f) works fine with x86, x64, SPARC
g) The only pop-ups to get through are the ally pop-ups  which are 
allowed by design.  GOK and MAG  always on top of screensaver when we 
lock the screen.



I am including svn diff of repository trunk/vermillion.  For more detail 
please see the attached source file.

Index: ChangeLog
===================================================================
--- ChangeLog   (revision 19180)
+++ ChangeLog   (working copy)
@@ -1,3 +1,8 @@
+2009-09-10  Arvind Umrao  <arvind.umrao at sun.com>
+
+    * SUNWxscreensaver.spec, patches/xscreensaver-48-bug-6839026.diff:
+    * CR#6839026 Regression in screensaver may cause Performance 
Degradation and make lock ed screensaver unresponsive.
+
 2009-08-27  Abhijit Nath <abhijit.nath at sun.com>

        * SUNWTiff.spec: add patch libtiff-05-CVE-2009-2285.diff
Index: patches/xscreensaver-48-bug-6839026.diff
===================================================================
--- patches/xscreensaver-48-bug-6839026.diff    (revision 0)
+++ patches/xscreensaver-48-bug-6839026.diff    (revision 0)
@@ -0,0 +1,150 @@
+--- xscreensaver-5.01/driver/lock.c_org        2009-08-27 
16:40:31.474335000 +0530
++++ xscreensaver-5.01/driver/lock.c    2009-09-10 15:39:37.444268000 +0530
+@@ -109,8 +109,8 @@ extern Atom XA_UNLOCK_RATIO;
+
+
+ /* GOK bug */
+-Window at_win[4] = {0,0,0,0}; /* wIds for XRestackWindows() */
+-                              /* dialog, GOK, or MAG or screenSaver */
++Window at_win[5] = {0,0,0,0,0}; /* wIds for XRestackWindows() */
++                              /* dialog, GOK, or MAG or screenSaver or 
temporary popup wi ndow */
+
+ int no_atserv = 0;            /* GOK or MAG or Both on def. screen 0 */
+
+@@ -2139,36 +2139,6 @@ passwd_event_loop (saver_info *si)
+           }
+       }
+
+-      //bugid 6769901: popup windows appearing through xscreensaver
+-        //code to stop popup windows while screen is locked
+-        //Raise the screen saver window and then the password dialog 
window
+-        if (event.xany.type == VisibilityNotify || event.xany.type == 
ConfigureNotify || event.xany.type == CreateNotify)
+-        {
+-              int screen;
+-                for (screen = 0; screen < si->nscreens; screen++)
+-                {
+-                      if(si->passwd_dialog)for
+-                        {
+-                              saver_screen_info *ssi = 
&si->screens[screen];
+-                                if(screen==0)
+-                                {
+-                                      Window screen_win[2] = {
+-                                              si->passwd_dialog,
+-                                                ssi->screensaver_window
+-                                      };
+-                                        XRestackWindows(si->dpy, 
screen_win, 2);
+-                                        
XMapRaised(si->dpy,si->passwd_dialog);
+-                                        XFlush(si->dpy);
+-                              }
+-                                else
+-                                {
+-                                      
XMapRaised(si->dpy,ssi->screensaver_window);
+-                                        XFlush(si->dpy);
+-                                }
+-                      }
+-              }
+-        }
+-
+ #else /* !HAVE_XSCREENSAVER_LOCK */
+       if (event.xany.window == si->passwd_dialog && event.xany.type == 
Expose)
+       draw_passwd_window (si);
+@@ -2219,24 +2189,87 @@ passwd_event_loop (saver_info *si)
+      Now, GOK only supports 2nd USB/mouse/Dwell, corepointer is supposed
+      not to be used, and GOK cannot disable it
+ */
+-        else if (((event.type == UnmapNotify)
+-                || (event.type == MapNotify )
+-                || (event.type == ConfigureNotify)
+-                || (event.type == PropertyNotify )
+-                || (event.type == ReparentNotify ))*dfdf


*
+-                && (si->passwd_dialog) && (no_atserv))
+-        {
++/*
++     bugid 6769901,6839026: popup windows appearing through xscreensaver
++     Also this routine is to stop the popup window when a11y is on 
also when a11y is not on.
++     Note: when a11y is on no_atserv > 0for
++*/
++
++else if (((event.type == UnmapNotify)
++              || (event.type == MapNotify )
++              || (event.type == VisibilityNotify)
++              || (event.type == ConfigureNotify)
++              || (event.type == PropertyNotify )
++              || (event.type == CreateNotify)
++              || (event.type == ReparentNotify ))
++              && (si->passwd_dialog) )
++      {
+ /* AT_LOCK_DEBUG
+ fprintf (stderr, "client window(0x%x) %s\n", 
event.xclient.window,blurb());
+ fprintf (stderr, "dialog window 0x%x:\n", si->passwd_dialog);
+ fprintf(stderr, "** no_atserv: %d \n", no_atserv);
+ for (ii = 0; ii < 4;  ii++)
+-         fprintf(stderr, "** win : 0x%x \n", at_win[ii]);
++       fprintf(stderr, "** win : 0x%x \n", at_win[ii]);
+ */
+-          at_win[no_atserv+1] = si->screens[0].screensaver_window;
+-/* 2 => screensaver and dialog Wids */
+-         XRestackWindows(si->dpy, at_win, no_atserv+2);
+-          XFlush(si->dpy);
++
++       /* this if case is for safety,it prevent screensaver stuck in 
loop of ConfigureNot ify */
++       if(event.xany.window && (event.xany.window != 
si->screens[0].screensaver_window) & & (event.xany.window != 
si->passwd_dialog
++))
++       {
++            /* find the handle of popup window */
++            /* Note: we can not get handle of popup window with 
event.xany.window, thats why we have switch cases. */
++             Window wPopWin =0;
++             switch(event.type)
++             {
++                case ConfigureNotify:
++                wPopWin = event.xconfigure.window;
++                break;
++                case CreateNotify:
++                wPopWin = event.xcreatewindow.window;
Need to update about SUBCR of  Nevada #6839026

My new fixes are very  stable now. Barun and I have tested it very 
thoroughly with a11y on.  Today I will raise it for JDS-Review, if no 
objection from Jeremy and Alan.

*Background*
Patch 120094-22, may cause performance degradation of CPU and system 
become unresposive when Trusted Extension or  Accessibility is turned 
on. Fixes of CR 6769901 are not appropriate should be corrected with CR 
6839026, on all the x86 and SPARC machine .

When a machine is patched with 120094-22, Symptoms are as follows.

a) When screen is locked and Accessibility is turned on, popup window 
might make x86/SPARC machine unresponsive.
b) When screen is locked and Trusted Extension is turned on, may cause 
performance degradation of CPU. [tx] Xsun chews cpu and console appear 
to be hung.

*Questions*
Q:why we have not fixed it at WindowManager?
Ans: We got some success in fixing this bug at  metacity/WM, but with 
lots of code changes. Login helper interface is required at metacity

Q: Is it fixed completly .What is remaining?
Ans: Yes this bug is fixed completely.  But we should wait for final 
test results,  if any problem comes we will fix in CR6875930.
There are some special cases, where we need to do restacking of pop up 
windows in timer.c . Also  there are some existing bugs in a11y, we will 
address them separately.
We are fixing this bug in incremental mode, all the remaining problem 
will be fixed in CR6875930


*What we have fixied*
Xsun is consuming 100% cpu cycle with trusted path because of  CR6769901
Also we found, with accessibility, cpu consumption goes to 100%
Popup window should not come through screensaver.

*Testing *

a) Pop-ups will not come through screensaver  in case of dual head 
display with and without xinerama . Same is the case when a11y is turned on.
b)Pop-ups will not come through screensaver  with  twinview  display of 
Xorg. Also there will be no performance degradation with my fixes
c) Pop-ups will not come through screensaver  with trusted path
d) Pop-ups will not come through screensaver  with all  a11y cases
e) works fine with Xnewt,Xorg and Xsun
f) works fine with x86, x64, SPARC
g) The only pop-ups to get through are the ally pop-ups  which are 
allowed by design.  GOK and MAG  always on top of screensaver when we 
lock the screen.





I am including svn diff of repository trunk/vermillion.  For more detail 
please see the attached source file.

Index: ChangeLog
===================================================================
--- ChangeLog   (revision 19180)
+++ ChangeLog   (working copy)
@@ -1,3 +1,8 @@
+2009-09-10  Arvind Umrao  <arvind.umrao at sun.com>
+
+    * SUNWxscreensaver.spec, patches/xscreensaver-48-bug-6839026.diff:
+    * CR#6839026 Regression in screensaver may cause Performance 
Degradation and make lock ed screensaver unresponsive.
+
 2009-08-27  Abhijit Nath <abhijit.nath at sun.com>

        * SUNWTiff.spec: add patch libtiff-05-CVE-2009-2285.diff
Index: patches/xscreensaver-48-bug-6839026.diff
===================================================================
--- patches/xscreensaver-48-bug-6839026.diff    (revision 0)
+++ patches/xscreensaver-48-bug-6839026.diff    (revision 0)
@@ -0,0 +1,150 @@
+--- xscreensaver-5.01/driver/lock.c_org        2009-08-27 
16:40:31.474335000 +0530
++++ xscreensaver-5.01/driver/lock.c    2009-09-10 15:39:37.444268000 +0530
+@@ -109,8 +109,8 @@ extern Atom XA_UNLOCK_RATIO;
+
+
+ /* GOK bug */
+-Window at_win[4] = {0,0,0,0}; /* wIds for XRestackWindows() */
+-                              /* dialog, GOK, or MAG or screenSaver */
++Window at_win[5] = {0,0,0,0,0}; /* wIds for XRestackWindows() */
++                              /* dialog, GOK, or MAG or screenSaver or 
temporary popup wi ndow */
+
+ int no_atserv = 0;            /* GOK or MAG or Both on def. screen 0 */
+
+@@ -2139,36 +2139,6 @@ passwd_event_loop (saver_info *si)
+           }
+       }
+
+-      //bugid 6769901: popup windows appearing through xscreensaver
+-        //code to stop popup windows while screen is locked
+-        //Raise the screen saver window and then the password dialog 
window
+-        if (event.xany.type == VisibilityNotify || event.xany.type == 
ConfigureNotify || event.xany.type == CreateNotify)
+-        {
+-              int screen;
+-                for (screen = 0; screen < si->nscreens; screen++)
+-                {
+-                      if(si->passwd_dialog)for
+-                        {
+-                              saver_screen_info *ssi = 
&si->screens[screen];
+-                                if(screen==0)
+-                                {
+-                                      Window screen_win[2] = {
+-                                              si->passwd_dialog,
+-                                                ssi->screensaver_window
+-                                      };
+-                                        XRestackWindows(si->dpy, 
screen_win, 2);
+-                                        
XMapRaised(si->dpy,si->passwd_dialog);
+-                                        XFlush(si->dpy);
+-                              }
+-                                else
+-                                {
+-                                      
XMapRaised(si->dpy,ssi->screensaver_window);
+-                                        XFlush(si->dpy);
+-                                }
+-                      }
+-              }
+-        }
+-
+ #else /* !HAVE_XSCREENSAVER_LOCK */
+       if (event.xany.window == si->passwd_dialog && event.xany.type == 
Expose)
+       draw_passwd_window (si);
+@@ -2219,24 +2189,87 @@ passwd_event_loop (saver_info *si)
+      Now, GOK only supports 2nd USB/mouse/Dwell, corepointer is supposed
+      not to be used, and GOK cannot disable it
+ */
+-        else if (((event.type == UnmapNotify)
+-                || (event.type == MapNotify )
+-                || (event.type == ConfigureNotify)
+-                || (event.type == PropertyNotify )
+-                || (event.type == ReparentNotify ))*dfdf


*
+-                && (si->passwd_dialog) && (no_atserv))
+-        {
++/*
++     bugid 6769901,6839026: popup windows appearing through xscreensaver
++     Also this routine is to stop the popup window when a11y is on 
also when a11y is not on.
++     Note: when a11y is on no_atserv > 0for
++*/
++
++else if (((event.type == UnmapNotify)
++              || (event.type == MapNotify )
++              || (event.type == VisibilityNotify)
++              || (event.type == ConfigureNotify)
++              || (event.type == PropertyNotify )
++              || (event.type == CreateNotify)
++              || (event.type == ReparentNotify ))
++              && (si->passwd_dialog) )
++      {
+ /* AT_LOCK_DEBUG
+ fprintf (stderr, "client window(0x%x) %s\n", 
event.xclient.window,blurb());
+ fprintf (stderr, "dialog window 0x%x:\n", si->passwd_dialog);
+ fprintf(stderr, "** no_atserv: %d \n", no_atserv);
+ for (ii = 0; ii < 4;  ii++)
+-         fprintf(stderr, "** win : 0x%x \n", at_win[ii]);
++       fprintf(stderr, "** win : 0x%x \n", at_win[ii]);
+ */
+-          at_win[no_atserv+1] = si->screens[0].screensaver_window;
+-/* 2 => screensaver and dialog Wids */
+-         XRestackWindows(si->dpy, at_win, no_atserv+2);
+-          XFlush(si->dpy);
++
++       /* this if case is for safety,it prevent screensaver stuck in 
loop of ConfigureNot ify */
++       if(event.xany.window && (event.xany.window != 
si->screens[0].screensaver_window) & & (event.xany.window != 
si->passwd_dialog
++))
++       {
++            /* find the handle of popup window */
++            /* Note: we can not get handle of popup window with 
event.xany.window, thats why we have switch cases. */
++             Window wPopWin =0;
++             switch(event.type)
++             {
++                case ConfigureNotify:
++                wPopWin = event.xconfigure.window;
++                break;
++                case CreateNotify:
++                wPopWin = event.xcreatewindow.window;
++                break;
++                case VisibilityNotify:
++                wPopWin = event.xvisibility.window;
++                break;
++                default:
++                break;
++             }
++
++
++             /* Array at_win stores password and screensaver window, 
also MAG and/or GOK if a11y is on
++             /* if any window apart from password, MAG ,GOK or 
screensaver comes over is considered as popup window. */
++             /* If it is not popup window but password, MAG, GOK, or 
screensaver window t hen nWin < no_atserv+2 */
++             /* If it is popup window then nWin == no_atserv+2 */
++             int nWin =0;
++             if(wPopWin) // check if it is really a popup window
++                for(;nWin < no_atserv+2 ; ++nWin)
++                {
++                   if(at_win[nWin]==wPopWin)
++                   break;
++                }
++
++           /* Do restacking if it is popup window ie nWin == 
no_atserv+2 */
++             /* Also do restacking when a11y is on */
++             if( nWin== no_atserv+2 ||no_atserv )
++             {
++
++                /* at_win[0] -> passwordwindow */
++                /* at_win[1-2]-> if a11y on, may GOK or MAG */
++
++                at_win[no_atserv+1] = si->screens[0].screensaver_window;
++                if(nWin== no_atserv+2)
++                {
++                   /* store popup window in array of at_win to restack 
it */
++                   at_win[no_atserv+2] = wPopWin;
++                   XRestackWindows(si->dpy, at_win,no_atserv+3);
++                }
++                else
++                {
++                   XRestackWindows(si->dpy, at_win,no_atserv+2);
++                }
++                XFlush(si->dpy);
++             }
++          }
++
+         }
+ /* the above new code for restacking under the conidtion
+ */
Index: SUNWxscreensaver.spec
===================================================================
--- SUNWxscreensaver.spec       (revision 19180)
+++ SUNWxscreensaver.spec       (working copy)
@@ -149,6 +149,8 @@
 Patch46: xscreensaver-46-bug-6857559.diff
 # date:2009-07-31 owner:bp230705 type:bug bugster:6859039
 Patch47: xscreensaver-47-bug-6859039.diff
+# date:2009-09-10 owner:au230626 type:bug bugster:6839026
+Patch48: xscreensaver-48-bug-6839026.diff

 # date:2008-03-07 owner:alanc type:branding
 Patch101: rss-glx-101-matrixview.diff
@@ -327,6 +329,7 @@
 %patch45 -p1
 %patch46 -p1
 %patch47 -p1
+%patch48 -p1

------------------------------------------------------------------------

/* lock.c --- handling the password dialog for locking-mode.
 * xscreensaver, Copyright (c) 1993-2006 Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

/* Athena locking code contributed by Jon A. Christopher <jac8782 at tamu.edu> 
*/
/* Copyright 1997, with the same permissions as above. */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <ctype.h>
#include <X11/Intrinsic.h>
#include <X11/cursorfont.h>
#include <X11/Xos.h>            /* for time() */
#include <X11/Xatom.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include "exec.h"
#include "xscreensaver.h"
#include "resources.h"
#include <gconf/gconf-client.h>

#ifndef NO_LOCKING              /* (mostly) whole file */

#ifdef HAVE_SYSLOG
# include <syslog.h>
#endif /* HAVE_SYSLOG */

#ifdef HAVE_XHPDISABLERESET
# include <X11/XHPlib.h>
  static void hp_lock_reset (saver_info *si, Bool lock_p);
#endif /* HAVE_XHPDISABLERESET */

#ifdef HAVE_XF86VMODE
# include <X11/extensions/xf86vmode.h>
  static void xfree_lock_mode_switch (saver_info *si, Bool lock_p);
#endif /* HAVE_XF86VMODE */

#ifdef HAVE_XF86MISCSETGRABKEYSSTATE
# include <X11/extensions/xf86misc.h>
  static void xfree_lock_grab_smasher (saver_info *si, Bool lock_p);
#endif /* HAVE_XF86MISCSETGRABKEYSSTATE */

#ifdef HAVE_RANDR
#include <X11/extensions/Xrandr.h>
#endif /* HAVE_RANDR */

#ifdef _VROOT_H_
ERROR!  You must not include vroot.h in this file.
#endif

#ifdef HAVE_UNAME
# include <sys/utsname.h> /* for hostname info */
#endif /* HAVE_UNAME */
#include <ctype.h>

#ifndef VMS
# include <pwd.h>
#else /* VMS */

extern char *getenv(const char *name);
extern int validate_user(char *name, char *password);

static Bool
vms_passwd_valid_p(char *pw, Bool verbose_p)
{
  return (validate_user (getenv("USER"), typed_passwd) == 1);
}
# undef passwd_valid_p
# define passwd_valid_p vms_passwd_valid_p

#endif /* VMS */

/* 5059445(p3) screen kb and reader support */
extern int grab_mouse (saver_info *si, Window window, Cursor cursor, int 
screen_no);
extern int grab_kbd (saver_info *si, Window window,  int screen_no);

extern int kill_job (saver_info *si, pid_t pid, int signal);
extern struct screenhack_job *make_job (pid_t pid, int screen, const char *cmd);
void hack_uid (saver_info *si);

Bool g_passwd_dialog_created = 0;

#undef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))

/* enum passwd_state & struct passwd_dialog_data moved to xscreensaver.h */

static void make_window (saver_info *si, enum window_type w_type);
static void draw_passwd_window (saver_info *si);
       void update_passwd_window (saver_info *si, const char *printed_passwd,
                                  float ratio);
       void destroy_passwd_window (saver_info *si);
static void undo_vp_motion (saver_info *si);
static void handle_passwd_button (saver_info *si, XEvent *event);

extern Atom XA_UNLOCK_RATIO;


/* GOK bug */
Window at_win[5] = {0,0,0,0,0}; /* wIds for XRestackWindows() */
                                /* dialog, GOK, or MAG or screenSaver or 
temporary popup window */

int no_atserv = 0;              /* GOK or MAG or Both on def. screen 0 */

Bool at_enabled = False;        /* Ass. Tech support? def. no */
                                /* for restoring the origin setting
                                   override_redirect setting of MAG/GOK
                                */
Bool winatt_reset[2] = {FALSE,FALSE};

char  *globalkey_text = NULL;
char  *globalmenu_key = NULL;
GConfClient *client = NULL;

/*
5083155 Unable to unlock screen when running dual-head MAG
*adding dual or multiple heads for magnifier support
*
  screen 0: loginhelp can pass the raisedWid of GOK or MAG or both
            found: return its parent Wid (child of root)
            not found:  0

  other screen: MAG only if the target screen no > 0 is selected
        found:  restack on that screen
                return 0
        not-found : rturn 0

*/
Atom atom_type[1], atom_window_type;

Window
check_raisedWid(saver_info *si,Window wid)
{
int screen_no,status;
Bool loop, found = FALSE;
Window root_ret, parent_ret, *children = NULL,root;
unsigned int nchildren = 0;

Screen *screen;
saver_screen_info *ssi;
Display *dpy;
Window screen_win[2] = {0,0};


for (screen_no = 0; screen_no < si->nscreens; screen_no++)
 {
   loop = TRUE;
   ssi = &si->screens[screen_no];
   screen = ssi->screen;
   root =    RootWindowOfScreen (screen);
   if (screen_no == 0)
        dpy = DisplayOfScreen(screen);
   else
        dpy = ssi->other_dpy;
   if (dpy)
   {
     while (loop)
     {
     status =
        XQueryTree (dpy, wid ,&root_ret,&parent_ret, &children, &nchildren);
/*  AT_LOCK_DEBUG
fprintf(stderr, " ==>screen(%x) root(%x) wid(%x) root_ret(%x) 
parent_ret(%x)\n", screen, root, wid, root_ret, parent_ret);
fprintf(stderr, " screen_no(%d) ==>dpy(%x)\n", screen_no,dpy);
*/

        if (parent_ret == 0 || root != root_ret) /* not found */
                        loop = FALSE;
        else if ( root_ret != parent_ret)
          wid  = parent_ret;
        else
        {

          loop = FALSE;
          found = TRUE;
/*  AT_LOCK_DEBUG
fprintf(stderr,"==> found wid is 0x%x screen_no(%d)\n", wid, screen_no);
*/
          if (screen_no)
          {
/*
** found in other screen(not scn 0), implies MAG target scn,
** invoke XRestackWindow()
*/
                screen_win[0] = wid;
                screen_win[1] = ssi->screensaver_window;
                XRestackWindows(dpy, screen_win, 2);
                XSync (dpy, False);
                wid = 0;   /* no need to do the restack on screen 0 */
           }
           screen_no = si->nscreens;
        }
        } /* while loop */
  } /*dpy check */

 } /* for loop */
 if (found)
        return wid;
 else
        return 0;
}

static int  ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error);

#ifdef HAVE_XSCREENSAVER_LOCK

int
write_to_child (saver_info* si, char* msg)
{
      if (si->external_passwd && g_passwd_dialog_created && 
si->pw_data->stdin_fd != -1)
        {
          ssize_t len;
          char *nlmsg;

          nlmsg = (char *)malloc (strlen (msg) + 2);
          sprintf (nlmsg, "%s\n", msg);

          if (si->prefs.verbose_p)
            {
              fprintf (stderr, 
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
              fprintf (stderr, "HAVE_SCRSVR_LOCK message is:%s writing to 
fd:%d\n",
                                   msg, si->pw_data->stdin_fd);
              fprintf (stderr, 
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
            }

        write_msg:
          len = write (si->pw_data->stdin_fd, nlmsg, strlen (nlmsg));
          if (len < 0 && errno == EINTR)
            goto write_msg;

          free (nlmsg);
          return (1);
        }
      return (0); /* if we didnt write anything return 0*/
}

static int
sane_dup2 (int fd1, int fd2)
{
  int ret;

 retry:
  ret = dup2 (fd1, fd2);
  if (ret < 0 && errno == EINTR)
    goto retry;

  return ret;
}

static int
close_and_invalidate (int *fd)
{
  int ret;

  ret = close (*fd);
  *fd = -1;

  return ret;
}

void
handle_passwd_input (XtPointer data, int *fd, XtInputId *id)
{
  saver_info *si = (saver_info *)data;
  saver_preferences *p = &si->prefs;
  char buffer[1024];
  char *s;
  int status;

  if (si->prefs.verbose_p)
    fprintf (stderr, "passwd input handler() fd=%d\n",*fd);

  s = fgets (buffer, sizeof (buffer), si->pw_data->input_file);
  if (!s)
    {
      if (si->prefs.verbose_p)
        {
          fprintf (stderr, "done reading...\n");
          fprintf (stderr, "removing input handler...\n");
        }
      XtRemoveInput (*id);
      si->pw_data->stdout_input_id = 0;

      if (si->pw_data->state == pw_read)
        si->pw_data->state = pw_null;

      if (si->prefs.verbose_p)
        fprintf (stderr, "passwd input handler() returning...done reading\n");

      return;
    }

  if (si->pw_data->got_windowid)
    {
      char *nl;
      if (si->prefs.verbose_p)
        fprintf (stderr, "got a password\n");
      nl = strchr (s, '\n');
      if (nl)
        *nl = '\0';
      si->pw_data->passwd_string = strdup (s);
      if (si->prefs.verbose_p)
        fprintf(stderr,"Dude got password and saving it in passwd_string:%s\n", 
s);

     /* We want to send null to lock dialog to say we are working on 
authentication*/
     si->pw_data->state = pw_null;
    }
  else /* Get the window id of lock dialog from Child ***/
    {
      Window window = strtoul (s, NULL, 0);

        XSetWindowAttributes setwinattr;
        unsigned long valuemask = CWOverrideRedirect;
        XWindowChanges changes;
        setwinattr.override_redirect = True;
        XWindowAttributes window_attributes_return;

      Window window1 = 0, passwd_win = 0,wintemp = 0; int j;
/*CR 5039878 2 3 "Password:" field should be focused / have flashing caret */
      s = fgets (buffer, sizeof (buffer), si->pw_data->input_file);
      passwd_win = strtoul (s, NULL, 0);
      no_atserv = 0;
      at_win[no_atserv] = window;

        /* There is no need to reset the timer for Normal user
           for each pop-up dialog
        */
      at_enabled = False;


      for (j= 0; j < 2; j++)
      {
        s = fgets (buffer, sizeof (buffer), si->pw_data->input_file);
        window1 = strtoul (s, NULL, 0);
/* GOK, MAG, not running, Ass. Tech support is still selected
   not enough interface info from loginhelper to cover all
   possible conditions, ungrab kb/mouse now
 */
        if (window1 == 0x1)
                at_enabled = True;
        else
        if (window1 != 0x0 ) {
/*
5083155 Unable to unlock screen when running dual-head MAG
*adding dual or multiple heads for magnifier support
*/

                at_enabled = True;
                wintemp = check_raisedWid(si, window1);
                if (wintemp) {
        status =
        XGetWindowAttributes(si->dpy,wintemp,&window_attributes_return);

        if ((status) && (!window_attributes_return.override_redirect))
        {
           XFlush(si->dpy);
           XChangeWindowAttributes(si->dpy,wintemp,valuemask,&setwinattr);
           winatt_reset[j] = TRUE;
/*  AT_LOCK_DEBUG
fprintf(stderr,"Debug: ==> winatt_reset[%d] override_redirect needs to be 
reset\n",j);
*/
        }
        XMapSubwindows(si->dpy, wintemp);
        no_atserv++;
        at_win[no_atserv] = wintemp;
                } /* wintemp != 0 */
        }
      }
        /* common parent, i.e root win */

/* cases for running GOK , or MAG or GOK+MAG */
/* 6461887(P1) screen lock does not prevent access to other
**  applications via 'alt-tab',
** see 6519433 mem leaks in libgconf-2.so's gconf_client_get_default()
*/
        client = gconf_client_get_default();

        if (no_atserv > 0) {
        /* pop-up dialog in dock mode */
/* AT_LOCK_DEBUG
fprintf(stderr,"==> found dialog wid 0x%x\n", window);
*/
          XRestackWindows(si->dpy, at_win, no_atserv+1);
          XUngrabKeyboard(si->dpy, CurrentTime);
          XUngrabPointer(si->dpy, CurrentTime);
          si->at_external_passwd = True;
          XFlush(si->dpy);
          globalkey_text = gconf_client_get_string (client, \
        "/apps/metacity/global_keybindings/switch_windows", NULL);
          if (globalkey_text && strncmp(globalkey_text,"dis",3))
            gconf_client_set_string (client, \
        "/apps/metacity/global_keybindings/switch_windows", "disabled", NULL);
        }
        /* no MAG or GOK, only SPEECH is running
           just Ass. Tech support is selected
        */
        else if ((no_atserv == 0) && (at_enabled))
        {
                XUngrabKeyboard(si->dpy, CurrentTime);
                XUngrabPointer(si->dpy, CurrentTime);
                si->at_external_passwd = True;
                XFlush(si->dpy);
                globalkey_text = \
                  gconf_client_get_string(client, \
                  "/apps/metacity/global_keybindings/switch_windows", NULL);
                if ( globalkey_text && strncmp(globalkey_text,"dis",3))
                  gconf_client_set_string ( client, \
        "/apps/metacity/global_keybindings/switch_windows", "disabled", NULL);
/*
** 6736157 A11Y]Security problem when desktop a11y support is turned on
*/
                globalmenu_key = \
                  gconf_client_get_string(client, \
                  "/apps/metacity/global_keybindings/panel_main_menu",NULL);
                if ( globalmenu_key && strncmp(globalmenu_key,"dis",3))
                  gconf_client_set_string ( client, \
        "/apps/metacity/global_keybindings/panel_main_menu","disabled",NULL);
        }

/*  AT_LOCK_DEBUG
        fprintf(stderr,"debug no_atserv   0x%x\n", no_atserv);
        fprintf(stderr,"debug passwd win   0x%x\n", passwd_win);
        fprintf(stderr,"debug window   0x%x\n", window);
*/

      XSelectInput(si->dpy, passwd_win,KeyPressMask);
      XSetInputFocus (si->dpy, passwd_win,RevertToPointerRoot, CurrentTime);
      XSync (si->dpy, False);

      si->pw_data->got_windowid = True;
      si->passwd_dialog = window;
      /**g_passwd_dialog_created = True;**/ /*set global flag to check in 
timers.c*/
      if (si->prefs.verbose_p)
        fprintf (stderr, "<---handle_passwd_input(): gotwindowid:0x%x\n", 
passwd_win);
    }
}

/* returns successful fork/exec */
Bool
spawn_external_passwd_process (saver_info *si, passwd_dialog_data *pw)
{
  saver_preferences *p = &si->prefs;
  pid_t forked;
  const char *command = LOCKDIR "/xscreensaver-lock";
  int stdin_pipe[2]  = { -1, -1 };
  int stdout_pipe[2] = { -1, -1 };

  pw->stdin_fd = pw->stdout_fd = -1;
  pw->got_windowid = False;

  if (si->prefs.verbose_p)
     fprintf(stderr, "-->spawn_external_passwd()\n");
  if (si->passwd_pid>0) {
        if (si->prefs.verbose_p)
           fprintf(stderr,"pid %d still exists.  Killing it with SIGKILL\n",
                        si->passwd_pid);
        kill(si->passwd_pid,SIGKILL);
  }
  si->passwd_pid = 0;
  if (pipe (stdin_pipe) < 0)
   {
    perror ("pipe(stdin_pipe) failed!");
    return False;
   }

  if (pipe (stdout_pipe) < 0)
    {
      perror ("pipe(stdout_pipe) failed!");
      close_and_invalidate (&stdin_pipe[0]);
      close_and_invalidate (&stdin_pipe[1]);
      return False;
    }
  switch ((int) (forked = fork ()))
    {
    case -1:
      fprintf (stderr, "%s: ", blurb ());
      perror ("couldn't fork");

      close_and_invalidate (&stdin_pipe[0]);
      close_and_invalidate (&stdin_pipe[1]);
      close_and_invalidate (&stdout_pipe[0]);
      close_and_invalidate (&stdout_pipe[1]);

      return False;

    case 0:
      close (ConnectionNumber (si->dpy)); /* close display fd */
      /* limit_subproc_memory (p->inferior_memory_limit, p->verbose_p); */
      /* hack_subproc_environment (ssi); */ /* FIX $DISPLAY */

      /* Inside Child Process */
      if (p->verbose_p)
        fprintf (stderr, "%s: spawning \"%s\" in pid %lu.\n",
                 blurb(), command, (unsigned long) getpid ());

      close_and_invalidate (&stdin_pipe[1]);
      close_and_invalidate (&stdout_pipe[0]);

      sane_dup2 (stdin_pipe[0], 0);  /* Listen to Parent from here */
      sane_dup2 (stdout_pipe[1], 9); /* Talk to Parent from here */

      /* Make sure we have relinquished setuid privs or lock dialog gtk
       * program will not run as libgtk is not setuid safe.
       */
      hack_uid (si);

      exec_command (p->shell, command, 0);
      /* print_path_error (command); */
      fprintf (stderr, "%s: couldn't exec: %s\n",
               blurb (), command);
      abort ();

    default:
      /* In Parent */
      make_job(forked, 0, command);
      close_and_invalidate (&stdin_pipe[0]);
      close_and_invalidate (&stdout_pipe[1]);

      sane_dup2 (stdin_pipe[0], 0);  /* Listen to Child from here */
      sane_dup2 (stdout_pipe[1], 13); /* Talk to Child from here */

      pw->stdin_fd   = stdin_pipe[1];   /* Talk to child from here */
      pw->stdout_fd  = stdout_pipe[0];  /* Listen to Child from here */
      si->passwd_pid = forked;

      write_to_child (si, "Hello There"); /* Send a test message to Child */

      /* Password from child dialog comes through this pipe/fd */
      pw->input_file = fdopen (pw->stdout_fd, "r");

      pw->stdout_input_id = XtAppAddInput (si->app, pw->stdout_fd,
                                           (XtPointer) XtInputReadMask,
                                           handle_passwd_input,
                                           si);

      /* Set global flag to indicate that lock dialog is visible */
      g_passwd_dialog_created = True;
      return True;
    }

  /* shouldn't reach */
  abort ();
  return False;
}
#endif /* HAVE_XSCREENSAVER_LOCK */

void
make_passwd_window (saver_info *si)
{
  make_window(si, w_dialog);
}


static void
make_window (saver_info *si, enum window_type w_type)
{
  struct passwd *p = getpwuid (getuid ());
  XSetWindowAttributes attrs;
  unsigned long attrmask = 0;
  passwd_dialog_data *pw = si->pw_data;
  Screen *screen;
  Colormap cmap;
  char *f;
  saver_screen_info *ssi = &si->screens [mouse_screen (si)];

  if (si->prefs.verbose_p)
    fprintf(stderr, "-->make_window()\n");

#ifdef HAVE_XSCREENSAVER_LOCK
  if (spawn_external_passwd_process (si, si->pw_data))
    {
/***************
          if (si->prefs.verbose_p)
            fprintf(stderr, "spawning external passwd process in 
make_window()\n");
*******************/

/****************mali blank_fails remove this...
          if(!blank_screen(si))
            fprintf(stderr, "Failed to blank the screen\n");
*******************/

      si->pw_data->ratio = 1.0;
      si->pw_data->w_type = w_type;
      /*si->pw_data = pw;*/
      si->external_passwd = True;
      return;
    }
  si->external_passwd = False;
  si->at_external_passwd = False;
  /* FIXME: don't abort() */
  /*abort ();*/
#endif /* HAVE_XSCREENSAVER_LOCK */

  /* Display the button only if the "newLoginCommand" pref is non-null.
   */
  pw->login_button_p = (si->prefs.new_login_command &&
                        *si->prefs.new_login_command);

  if (pw->login_button_p)
    pw->passwd_cursor = XCreateFontCursor (si->dpy, XC_top_left_arrow);
  else
    pw->passwd_cursor = 0;

  pw->prompt_screen = ssi;
  if (si->prefs.verbose_p)
    fprintf (stderr, "%s: %d: creating password dialog.\n",
             blurb(), pw->prompt_screen->number);

  screen = pw->prompt_screen->screen;
  cmap = DefaultColormapOfScreen (screen);

  pw->w_type = w_type;
  pw->state = pw_read;
  pw->ratio = 1.0;

  pw->show_stars_p = get_boolean_resource(si->dpy, "passwd.asterisks", 
                                          "Boolean");
  
  pw->heading_label = get_string_resource (si->dpy, "passwd.heading.label",
                                           "Dialog.Label.Label");
  pw->body_label = get_string_resource (si->dpy, "passwd.body.label",
                                        "Dialog.Label.Label");
  pw->user_label = get_string_resource (si->dpy, "passwd.user.label",
                                        "Dialog.Label.Label");
  pw->passwd_label = get_string_resource (si->dpy, "passwd.passwd.label",
                                          "Dialog.Label.Label");
  pw->login_label = get_string_resource (si->dpy, "passwd.login.label",
                                         "Dialog.Button.Label");

  pw->date_label = get_string_resource (si->dpy, "dateFormat", "DateFormat");

  if (!pw->heading_label)
    pw->heading_label = strdup("ERROR: RESOURCES NOT INSTALLED CORRECTLY");
  if (!pw->body_label)
    pw->body_label = strdup("ERROR: RESOURCES NOT INSTALLED CORRECTLY");
  if (!pw->user_label) pw->user_label = strdup("ERROR");
  if (!pw->passwd_label) pw->passwd_label = strdup("ERROR");
  if (!pw->date_label) pw->date_label = strdup("ERROR");
  if (!pw->login_label) pw->login_label = strdup ("ERROR (LOGIN)") ;

  /* Put the version number in the label. */
  {
    char *s = (char *) malloc (strlen(pw->heading_label) + 20);
    sprintf(s, pw->heading_label, si->version);
    free (pw->heading_label);
    pw->heading_label = s;
  }

  /* Get hostname info */
  pw->uname_label = strdup(""); /* Initialy, write nothing */

# ifdef HAVE_UNAME
  {
    struct utsname uts;

    if (uname (&uts) == 0)
      {
#if 0 /* Get the full hostname */
        {
          char *s;
          if ((s = strchr(uts.nodename, '.')))
            *s = 0;
        }
#endif
        char *s = strdup (uts.nodename);
        free (pw->uname_label);
        pw->uname_label = s;
      }
  }
# endif

  f = get_string_resource (si->dpy, "passwd.headingFont", "Dialog.Font");
  pw->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->heading_font) pw->heading_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource (si->dpy, "passwd.buttonFont", "Dialog.Font");
  pw->button_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->button_font) pw->button_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.bodyFont", "Dialog.Font");
  pw->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->body_font) pw->body_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.labelFont", "Dialog.Font");
  pw->label_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->label_font) pw->label_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.passwdFont", "Dialog.Font");
  pw->passwd_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->passwd_font) pw->passwd_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.dateFont", "Dialog.Font");
  pw->date_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->date_font) pw->date_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.unameFont", "Dialog.Font");
  pw->uname_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->uname_font) pw->uname_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);
  
  pw->show_uname_p = get_boolean_resource(si->dpy, "passwd.uname", "Boolean");

  pw->foreground = get_pixel_resource (si->dpy, cmap,
                                       "passwd.foreground",
                                       "Dialog.Foreground" );
  pw->background = get_pixel_resource (si->dpy, cmap,
                                       "passwd.background",
                                       "Dialog.Background" );

  if (pw->foreground == pw->background)
    {
      /* Make sure the error messages show up. */
      pw->foreground = BlackPixelOfScreen (screen);
      pw->background = WhitePixelOfScreen (screen);
    }

  pw->passwd_foreground = get_pixel_resource (si->dpy, cmap,
                                              "passwd.text.foreground",
                                              "Dialog.Text.Foreground" );
  pw->passwd_background = get_pixel_resource (si->dpy, cmap,
                                              "passwd.text.background",
                                              "Dialog.Text.Background" );
  pw->button_foreground = get_pixel_resource (si->dpy, cmap, 
                                              "splash.Button.foreground",
                                              "Dialog.Button.Foreground" );
  pw->button_background = get_pixel_resource (si->dpy, cmap,
                                              "splash.Button.background",
                                              "Dialog.Button.Background" );
  pw->thermo_foreground = get_pixel_resource (si->dpy, cmap,
                                              "passwd.thermometer.foreground",
                                              "Dialog.Thermometer.Foreground" );
  pw->thermo_background = get_pixel_resource ( si->dpy, cmap,
                                              "passwd.thermometer.background",
                                              "Dialog.Thermometer.Background" );
  pw->shadow_top = get_pixel_resource ( si->dpy, cmap,
                                       "passwd.topShadowColor",
                                       "Dialog.Foreground" );
  pw->shadow_bottom = get_pixel_resource (si->dpy, cmap, 
                                          "passwd.bottomShadowColor",
                                          "Dialog.Background" );

  pw->logo_width = get_integer_resource (si->dpy, "passwd.logo.width",
                                         "Dialog.Logo.Width");
  pw->logo_height = get_integer_resource (si->dpy, "passwd.logo.height",
                                          "Dialog.Logo.Height");
  pw->thermo_width = get_integer_resource (si->dpy, "passwd.thermometer.width",
                                           "Dialog.Thermometer.Width");
  pw->internal_border = get_integer_resource (si->dpy, 
"passwd.internalBorderWidth",
                                              "Dialog.InternalBorderWidth");
  pw->shadow_width = get_integer_resource (si->dpy, "passwd.shadowThickness",
                                           "Dialog.ShadowThickness");

  if (pw->logo_width == 0)  pw->logo_width = 150;
  if (pw->logo_height == 0) pw->logo_height = 150;
  if (pw->internal_border == 0) pw->internal_border = 15;
  if (pw->shadow_width == 0) pw->shadow_width = 4;
  if (pw->thermo_width == 0) pw->thermo_width = pw->shadow_width;

  {
    int direction, ascent, descent;
    XCharStruct overall;

    pw->width = 0;
    pw->height = 0;

    /* Measure the heading_label. */
    XTextExtents (pw->heading_font,
                  pw->heading_label, strlen(pw->heading_label),
                  &direction, &ascent, &descent, &overall);
    if (overall.width > pw->width) pw->width = overall.width;
    pw->height += ascent + descent;

    /* Measure the uname_label. */
    if ((strlen(pw->uname_label)) && pw->show_uname_p)
      {
        XTextExtents (pw->uname_font,
                      pw->uname_label, strlen(pw->uname_label),
                      &direction, &ascent, &descent, &overall);
        if (overall.width > pw->width) pw->width = overall.width;
        pw->height += ascent + descent;
      }

    pw->width  += (pw->internal_border * 2);
    pw->height += (pw->internal_border * 4);

    pw->width += pw->thermo_width + (pw->shadow_width * 3);

    if (pw->logo_height > pw->height)
      pw->height = pw->logo_height;
    else if (pw->height > pw->logo_height)
      pw->logo_height = pw->height;

    pw->logo_width = pw->logo_height;

    pw->width += pw->logo_width;
  }

  attrmask |= CWOverrideRedirect; attrs.override_redirect = True;

  attrmask |= CWEventMask;
  attrs.event_mask = (ExposureMask | KeyPressMask |
                      ButtonPressMask | ButtonReleaseMask);

  /* We need to remember the mouse position and restore it afterward, or
     sometimes (perhaps only with Xinerama?) the mouse gets warped to
     inside the bounds of the lock dialog window.
   */
  {
    Window pointer_root, pointer_child;
    int root_x, root_y, win_x, win_y;
    unsigned int mask;
    pw->previous_mouse_x = 0;
    pw->previous_mouse_y = 0;
    if (XQueryPointer (si->dpy, RootWindowOfScreen (pw->prompt_screen->screen),
                       &pointer_root, &pointer_child,
                       &root_x, &root_y, &win_x, &win_y, &mask))
      {
        pw->previous_mouse_x = root_x;
        pw->previous_mouse_y = root_y;
        if (si->prefs.verbose_p)
          fprintf (stderr, "%s: %d: mouse is at %d,%d.\n",
                   blurb(), pw->prompt_screen->number,
                   pw->previous_mouse_x, pw->previous_mouse_y);
      }
    else if (si->prefs.verbose_p)
      fprintf (stderr, "%s: %d: unable to determine mouse position?\n",
               blurb(), pw->prompt_screen->number);
  }

  /* Figure out where on the desktop to place the window so that it will
     actually be visible; this takes into account virtual viewports as
     well as Xinerama. */
  {
    int x, y, w, h;
    get_screen_viewport (pw->prompt_screen, &x, &y, &w, &h,
                         pw->previous_mouse_x, pw->previous_mouse_y,
                         si->prefs.verbose_p);
    if (si->prefs.debug_p) w /= 2;
    pw->x = x + ((w + pw->width) / 2) - pw->width;
    pw->y = y + ((h + pw->height) / 2) - pw->height;
    if (pw->x < x) pw->x = x;
    if (pw->y < y) pw->y = y;
  }

  pw->border_width = get_integer_resource (si->dpy, "passwd.borderWidth",
                                           "Dialog.BorderWidth");

  si->passwd_dialog =
    XCreateWindow (si->dpy,
                   RootWindowOfScreen(screen),
                   pw->x, pw->y, pw->width, pw->height, pw->border_width,
                   DefaultDepthOfScreen (screen), InputOutput,
                   DefaultVisualOfScreen(screen),
                   attrmask, &attrs);
  XSetWindowBackground (si->dpy, si->passwd_dialog, pw->background);

  /* We use the default visual, not ssi->visual, so that the logo pixmap's
     visual matches that of the si->passwd_dialog window. */
  pw->logo_pixmap = xscreensaver_logo (ssi->screen,
                                       /* ssi->current_visual, */
                                       DefaultVisualOfScreen(screen),
                                       si->passwd_dialog, cmap,
                                       pw->background, 
                                       &pw->logo_pixels, &pw->logo_npixels,
                                       &pw->logo_clipmask, True);

  /* Before mapping the window, save the bits that are underneath the
     rectangle the window will occlude.  When we lower the window, we
     restore these bits.  This works, because the running screenhack
     has already been sent SIGSTOP, so we know nothing else is drawing
     right now! */
  {
    XGCValues gcv;
    GC gc;
    pw->save_under = XCreatePixmap (si->dpy,
                                    pw->prompt_screen->screensaver_window,
                                    pw->width + (pw->border_width*2) + 1,
                                    pw->height + (pw->border_width*2) + 1,
                                    pw->prompt_screen->current_depth);
    gcv.function = GXcopy;
    gc = XCreateGC (si->dpy, pw->save_under, GCFunction, &gcv);
    XCopyArea (si->dpy, pw->prompt_screen->screensaver_window,
               pw->save_under, gc,
               pw->x - pw->border_width, pw->y - pw->border_width,
               pw->width + (pw->border_width*2) + 1,
               pw->height + (pw->border_width*2) + 1,
               0, 0);
    XFreeGC (si->dpy, gc);
  }

  XMapRaised (si->dpy, si->passwd_dialog);
  XSync (si->dpy, False);

  move_mouse_grab (si, si->passwd_dialog,
                   (pw->passwd_cursor
                    ? pw->passwd_cursor
                    : pw->prompt_screen->cursor),
                   pw->prompt_screen->number);
  undo_vp_motion (si);

  /*mali si->pw_data = pw; */

  if (cmap)
    XInstallColormap (si->dpy, cmap);
  draw_passwd_window (si);
  XSync (si->dpy, False);
}


static void
draw_passwd_window (saver_info *si)
{
  passwd_dialog_data *pw = si->pw_data;
  XGCValues gcv;
  GC gc1, gc2;
  int spacing, height;
  int x1, x2, x3, y1, y2;
  int sw;
  int tb_height;


  if (si->prefs.verbose_p)
    fprintf (stderr, "-->draw_passwd_window() case w_dialog!!\n");

  height = (pw->heading_font->ascent + pw->heading_font->descent +
            pw->body_font->ascent + pw->body_font->descent +
            (2 * MAX ((pw->label_font->ascent + pw->label_font->descent),
                      (pw->passwd_font->ascent + pw->passwd_font->descent +
                       (pw->shadow_width * 4)))) +
            pw->date_font->ascent + pw->date_font->descent);

  if ((strlen(pw->uname_label)) && pw->show_uname_p)
    height += (pw->uname_font->ascent + pw->uname_font->descent); /* for uname 
*/

  if (pw->login_button_p)
    height += ((pw->button_font->ascent + pw->button_font->descent) * 2 +
               2 * pw->shadow_width);

  spacing = (((pw->height
               - ((pw->login_button_p ? 4 : 2) * pw->shadow_width)
               - pw->internal_border - height))
             / 8);

  if (spacing < 0) spacing = 0;

  gcv.foreground = pw->foreground;
  gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
  gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
  x1 = pw->logo_width + pw->thermo_width + (pw->shadow_width * 3);
  x3 = pw->width - (pw->shadow_width * 2);
  y1 = (pw->shadow_width * 2) + spacing + spacing;

  /* top heading
   */
  XSetFont (si->dpy, gc1, pw->heading_font->fid);
  sw = string_width (pw->heading_font, pw->heading_label);
  x2 = (x1 + ((x3 - x1 - sw) / 2));
  y1 += spacing + pw->heading_font->ascent + pw->heading_font->descent;
  XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
               pw->heading_label, strlen(pw->heading_label));

  /* uname below top heading
   */
  if ((strlen(pw->uname_label)) && pw->show_uname_p)
    {
      XSetFont (si->dpy, gc1, pw->uname_font->fid);
      y1 += spacing + pw->uname_font->ascent + pw->uname_font->descent;
      sw = string_width (pw->uname_font, pw->uname_label);
      x2 = (x1 + ((x3 - x1 - sw) / 2));
      XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
                   pw->uname_label, strlen(pw->uname_label));
    }

  /* text below uname
   */
  XSetFont (si->dpy, gc1, pw->body_font->fid);
  y1 += spacing + pw->body_font->ascent + pw->body_font->descent;
  sw = string_width (pw->body_font, pw->body_label);
  x2 = (x1 + ((x3 - x1 - sw) / 2));
  XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
               pw->body_label, strlen(pw->body_label));


  tb_height = (pw->passwd_font->ascent + pw->passwd_font->descent +
               (pw->shadow_width * 4));

  /* the "User:" prompt
   */
  y1 += spacing;
  y2 = y1;
  XSetForeground (si->dpy, gc1, pw->foreground);
  XSetFont (si->dpy, gc1, pw->label_font->fid);
  y1 += (spacing + tb_height);
  x2 = (x1 + pw->internal_border +
        MAX(string_width (pw->label_font, pw->user_label),
            string_width (pw->label_font, pw->passwd_label)));
  XDrawString (si->dpy, si->passwd_dialog, gc1,
               x2 - string_width (pw->label_font, pw->user_label),
               y1 - pw->passwd_font->descent,
               pw->user_label, strlen(pw->user_label));

  /* the "Password:" prompt
   */
  y1 += (spacing + tb_height);
  XDrawString (si->dpy, si->passwd_dialog, gc1,
               x2 - string_width (pw->label_font, pw->passwd_label),
               y1 - pw->passwd_font->descent,
               pw->passwd_label, strlen(pw->passwd_label));


  XSetForeground (si->dpy, gc2, pw->passwd_background);

  /* the "user name" text field
   */
  y1 = y2;
  XSetForeground (si->dpy, gc1, pw->passwd_foreground);
  XSetFont (si->dpy, gc1, pw->passwd_font->fid);
  y1 += (spacing + tb_height);
  x2 += (pw->shadow_width * 4);

  pw->passwd_field_width = x3 - x2 - pw->internal_border;
  pw->passwd_field_height = (pw->passwd_font->ascent +
                             pw->passwd_font->descent +
                             pw->shadow_width);

  XFillRectangle (si->dpy, si->passwd_dialog, gc2,
                  x2 - pw->shadow_width,
                  y1 - (pw->passwd_font->ascent + pw->passwd_font->descent),
                  pw->passwd_field_width, pw->passwd_field_height);
  XDrawString (si->dpy, si->passwd_dialog, gc1,
               x2,
               y1 - pw->passwd_font->descent,
               pw->user_string, strlen(pw->user_string));

  /* the "password" text field
   */
  y1 += (spacing + tb_height);

  pw->passwd_field_x = x2 - pw->shadow_width;
  pw->passwd_field_y = y1 - (pw->passwd_font->ascent +
                             pw->passwd_font->descent);

  /* The shadow around the text fields
   */
  y1 = y2;
  y1 += (spacing + (pw->shadow_width * 3));
  x1 = x2 - (pw->shadow_width * 2);
  x2 = pw->passwd_field_width + (pw->shadow_width * 2);
  y2 = pw->passwd_field_height + (pw->shadow_width * 2);

  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         x1, y1, x2, y2,
                         pw->shadow_width,
                         pw->shadow_bottom, pw->shadow_top);

  y1 += (spacing + pw->passwd_font->ascent + pw->passwd_font->descent +
         (pw->shadow_width * 4));
  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         x1, y1, x2, y2,
                         pw->shadow_width,
                         pw->shadow_bottom, pw->shadow_top);


  /* The date, below the text fields
   */
  {
    char buf[100];
    time_t now = time ((time_t *) 0);
    struct tm *tm = localtime (&now);
    memset (buf, 0, sizeof(buf));
    strftime (buf, sizeof(buf)-1, pw->date_label, tm);

    XSetFont (si->dpy, gc1, pw->date_font->fid);
    y1 += pw->shadow_width;
    y1 += (spacing + tb_height);
    y1 += spacing/2;
    sw = string_width (pw->date_font, buf);
    x2 = x1 + x2 - sw;
    XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, buf, strlen(buf));
  }

  /* The "New Login" button
   */
  if (pw->login_button_p)
    {
      XSetForeground (si->dpy, gc1, pw->button_foreground);
      XSetForeground (si->dpy, gc2, pw->button_background);
      XSetFont (si->dpy, gc1, pw->button_font->fid);

      sw = string_width (pw->button_font, pw->login_label);

      x2 = pw->width - pw->internal_border - (pw->shadow_width * 2);

      /* right aligned button */
      /* x1 = x2 - pw->login_button_width;  */

      /* centered button */
      x1 = (pw->logo_width + pw->thermo_width + (pw->shadow_width * 3) +
            pw->internal_border);
      x1 = x1 + (x2 - x1 - pw->login_button_width) / 2;

      y1 = (pw->height - pw->internal_border - pw->login_button_height +
            spacing);
      y2 = (y1 +
            ((pw->login_button_height -
              (pw->button_font->ascent + pw->button_font->descent))
             / 2) +
            pw->button_font->ascent);

      pw->login_button_x = x1;
      pw->login_button_y = y1;
    }

  /* The logo
   */
  x1 = pw->shadow_width * 6;
  y1 = pw->shadow_width * 6;
  x2 = pw->logo_width - (pw->shadow_width * 12);
  y2 = pw->logo_height - (pw->shadow_width * 12);

  if (pw->logo_pixmap)
    {
      Window root;
      int x, y;
      unsigned int w, h, bw, d;
      XGetGeometry (si->dpy, pw->logo_pixmap, &root, &x, &y, &w, &h, &bw, &d);
      XSetForeground (si->dpy, gc1, pw->foreground);
      XSetBackground (si->dpy, gc1, pw->background);
      XSetClipMask (si->dpy, gc1, pw->logo_clipmask);
      XSetClipOrigin (si->dpy, gc1, x1 + ((x2 - (int)w) / 2), y1 + ((y2 - 
(int)h) / 2));
      if (d == 1)
        XCopyPlane (si->dpy, pw->logo_pixmap, si->passwd_dialog, gc1,
                    0, 0, w, h,
                    x1 + ((x2 - (int)w) / 2),
                    y1 + ((y2 - (int)h) / 2),
                    1);
      else
        XCopyArea (si->dpy, pw->logo_pixmap, si->passwd_dialog, gc1,
                   0, 0, w, h,
                   x1 + ((x2 - (int)w) / 2),
                   y1 + ((y2 - (int)h) / 2));
    }

  /* The thermometer
   */
  XSetForeground (si->dpy, gc1, pw->thermo_foreground);
  XSetForeground (si->dpy, gc2, pw->thermo_background);

  pw->thermo_field_x = pw->logo_width + pw->shadow_width;
  pw->thermo_field_y = pw->shadow_width * 5;
  pw->thermo_field_height = pw->height - (pw->shadow_width * 10);

#if 0
  /* Solid border inside the logo box. */
  XSetForeground (si->dpy, gc1, pw->foreground);
  XDrawRectangle (si->dpy, si->passwd_dialog, gc1, x1, y1, x2-1, y2-1);
#endif

  /* The shadow around the logo
   */
  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         pw->shadow_width * 4,
                         pw->shadow_width * 4,
                         pw->logo_width - (pw->shadow_width * 8),
                         pw->logo_height - (pw->shadow_width * 8),
                         pw->shadow_width,
                         pw->shadow_bottom, pw->shadow_top);

  /* The shadow around the thermometer
   */
  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         pw->logo_width,
                         pw->shadow_width * 4,
                         pw->thermo_width + (pw->shadow_width * 2),
                         pw->height - (pw->shadow_width * 8),
                         pw->shadow_width,
                         pw->shadow_bottom, pw->shadow_top);

#if 1
  /* Solid border inside the thermometer. */
  XSetForeground (si->dpy, gc1, pw->foreground);
  XDrawRectangle (si->dpy, si->passwd_dialog, gc1, 
                  pw->thermo_field_x, pw->thermo_field_y,
                  pw->thermo_width - 1, pw->thermo_field_height - 1);
#endif

  /* The shadow around the whole window
   */
  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         0, 0, pw->width, pw->height, pw->shadow_width,
                         pw->shadow_top, pw->shadow_bottom);

  XFreeGC (si->dpy, gc1);
  XFreeGC (si->dpy, gc2);

  update_passwd_window (si, pw->passwd_string, pw->ratio);
}


void
update_passwd_window (saver_info *si, const char *printed_passwd, float ratio)
{
  passwd_dialog_data *pw = si->pw_data;
  XGCValues gcv;
  GC gc1, gc2;
  int x, y;
  XRectangle rects[1];

  pw->ratio = ratio;

  if (si->prefs.verbose_p)
    fprintf (stderr, "-->update_passwd_window() w_dialog !!\n");

  if (!si->pw_data->got_windowid )
    {
      if (si->prefs.verbose_p)
        fprintf (stderr, "-->update_passwd_window() lockdialog not created 
returning.. !!\n");
      return;
    }

  gcv.foreground = pw->passwd_foreground;
  if (pw->passwd_font)
    gcv.font = pw->passwd_font->fid;
  gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground|GCFont, &gcv);
  gcv.foreground = pw->passwd_background;
  gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);

  if (printed_passwd)
    {
      char *s = strdup (printed_passwd);
      if (pw->passwd_string) free (pw->passwd_string);
      pw->passwd_string = s;
    }

  /* the "password" text field
   */
  rects[0].x =  pw->passwd_field_x;
  rects[0].y =  pw->passwd_field_y;
  rects[0].width = pw->passwd_field_width;
  rects[0].height = pw->passwd_field_height;

  XFillRectangle (si->dpy, si->passwd_dialog, gc2,
                  rects[0].x, rects[0].y, rects[0].width, rects[0].height);

  XSetClipRectangles (si->dpy, gc1, 0, 0, rects, 1, Unsorted);

  XDrawString (si->dpy, si->passwd_dialog, gc1,
               rects[0].x + pw->shadow_width,
               rects[0].y + pw->passwd_font->ascent,
               pw->passwd_string, strlen(pw->passwd_string));

  XSetClipMask (si->dpy, gc1, None);

  /* The I-beam
   */
  if (pw->i_beam != 0)
    {
      x = (rects[0].x + pw->shadow_width +
           string_width (pw->passwd_font, pw->passwd_string));
      y = rects[0].y + pw->shadow_width;

      if (x > rects[0].x + rects[0].width - 1)
        x = rects[0].x + rects[0].width - 1;
      XDrawLine (si->dpy, si->passwd_dialog, gc1, 
                 x, y,
                 x, y + pw->passwd_font->ascent + pw->passwd_font->descent-1);
    }

  pw->i_beam = (pw->i_beam + 1) % 4;


  /* the thermometer
   */
  y = (pw->thermo_field_height - 2) * (1.0 - pw->ratio);
  if (y > 0)
    {
      XFillRectangle (si->dpy, si->passwd_dialog, gc2,
                      pw->thermo_field_x + 1,
                      pw->thermo_field_y + 1,
                      pw->thermo_width-2,
                      y);
      XSetForeground (si->dpy, gc1, pw->thermo_foreground);
      XFillRectangle (si->dpy, si->passwd_dialog, gc1,
                      pw->thermo_field_x + 1,
                      pw->thermo_field_y + 1 + y,
                      pw->thermo_width-2,
                      MAX (0, pw->thermo_field_height - y - 2));
    }

  /* The "New Login" button
   */
  if (pw->login_button_p)
    {
      int x2, y2, sw;
      XSetFont (si->dpy, gc1, pw->button_font->fid);
      XSetForeground (si->dpy, gc1,
                      (pw->login_button_enabled_p
                       ? pw->passwd_foreground
                       : pw->shadow_bottom));
      XSetForeground (si->dpy, gc2, pw->button_background);

      XFillRectangle (si->dpy, si->passwd_dialog, gc2,
                      pw->login_button_x, pw->login_button_y,
                      pw->login_button_width, pw->login_button_height);

      sw = string_width (pw->button_font, pw->login_label);
      x2 = pw->login_button_x + ((pw->login_button_width - sw) / 2);
      y2 = (pw->login_button_y +
            ((pw->login_button_height -
              (pw->button_font->ascent + pw->button_font->descent))
             / 2) +
            pw->button_font->ascent);

      XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y2,
                   pw->login_label, strlen(pw->login_label));

      draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                             pw->login_button_x, pw->login_button_y, 
                             pw->login_button_width, pw->login_button_height,
                             pw->shadow_width,
                             (pw->login_button_down_p
                              ? pw->shadow_bottom
                              : pw->shadow_top), 
                             (pw->login_button_down_p
                              ? pw->shadow_top
                              : pw->shadow_bottom));
    }

  XFreeGC (si->dpy, gc1);
  XFreeGC (si->dpy, gc2);
  XSync (si->dpy, False);
}


void
destroy_passwd_window (saver_info *si)
{
  saver_preferences *p = &si->prefs;
  passwd_dialog_data *pw = si->pw_data;
  saver_screen_info *ssi;
  Colormap cmap;
  Pixel black, white;
  XEvent event;
/* CR5083155 [Cinn Solaris]Unable to unlock screen when running dual-head MAG
*/
  int j;
  XSetWindowAttributes setwinattr;
  unsigned long valuemask = CWOverrideRedirect;
  XWindowChanges changes;
  setwinattr.override_redirect = FALSE;

  if (si->prefs.verbose_p)
    fprintf (stderr, "destroy_passwd_window\n");

  /*reset global flag to indicate passwd dialog is no longer there*/
  g_passwd_dialog_created = 0;

  if (pw == NULL || si->external_passwd == 0)
    return;

  if (pw->timer)
    XtRemoveTimeOut (pw->timer);


#ifdef HAVE_XSCREENSAVER_LOCK
  if (si->external_passwd)
    {
      /* kill the child etc. */

      if (si->passwd_dialog)
        {
          XErrorHandler old_handler;

          XSync (si->dpy, False);
          old_handler = XSetErrorHandler (ignore_all_errors_ehandler);

          XDestroyWindow (si->dpy, si->passwd_dialog);
          XSync (si->dpy, False);
          XSetErrorHandler (old_handler);

          si->passwd_dialog = 0;
        }

      if (pw->stdout_input_id)
        XtRemoveInput (pw->stdout_input_id);
      if (pw->stdin_fd != -1)
        close_and_invalidate (&pw->stdin_fd);
      if (pw->input_file)
        fclose (pw->input_file);
      else if (pw->stdout_fd != -1)
        close_and_invalidate (&pw->stdout_fd);

      if (si->passwd_pid)
        {
          kill_job (si, si->passwd_pid, SIGTERM);
          si->passwd_pid = 0;
        }

      si->external_passwd = False;
      si->at_external_passwd = False;
     }
  else
#endif /* HAVE_XSCREENSAVER_LOCK */
{
  if (p->verbose_p)
    fprintf (stderr, "In destroy_passwd else case..i.e. si->external-passwd is 
False already\n");

  memset (pw->typed_passwd, 0, sizeof(pw->typed_passwd));
  memset (pw->passwd_string, 0, strlen(pw->passwd_string));

  ssi = pw->prompt_screen;
  cmap = DefaultColormapOfScreen (ssi->screen);
  black = BlackPixelOfScreen (ssi->screen);
  white = WhitePixelOfScreen (ssi->screen);
  move_mouse_grab (si, RootWindowOfScreen (ssi->screen),
                   ssi->cursor, ssi->number);

  if (pw->passwd_cursor)
    XFreeCursor (si->dpy, pw->passwd_cursor);

  if (p->verbose_p)
    fprintf (stderr, "%s: %d: moving mouse back to %d,%d.\n",
             blurb(), ssi->number,
             pw->previous_mouse_x, pw->previous_mouse_y);

  XWarpPointer (si->dpy, None, RootWindowOfScreen (ssi->screen),
                0, 0, 0, 0,
                pw->previous_mouse_x, pw->previous_mouse_y);

  XSync (si->dpy, False);
  while (XCheckMaskEvent (si->dpy, PointerMotionMask, &event))
    if (p->verbose_p)
      fprintf (stderr, "%s: discarding MotionNotify event.\n", blurb());

  if (si->passwd_dialog)
    {
      XDestroyWindow (si->dpy, si->passwd_dialog);
      si->passwd_dialog = 0;
    }
  
  if (pw->save_under)
    {
      XGCValues gcv;
      GC gc;
      gcv.function = GXcopy;
      gc = XCreateGC (si->dpy, ssi->screensaver_window, GCFunction, &gcv);
      XCopyArea (si->dpy, pw->save_under,
                 ssi->screensaver_window, gc,
                 0, 0,
                 pw->width + (pw->border_width*2) + 1,
                 pw->height + (pw->border_width*2) + 1,
                 pw->x - pw->border_width, pw->y - pw->border_width);
      XFreePixmap (si->dpy, pw->save_under);
      pw->save_under = 0;
      XFreeGC (si->dpy, gc);
    }

  if (pw->heading_label) free (pw->heading_label);
  if (pw->body_label)    free (pw->body_label);
  if (pw->user_label)    free (pw->user_label);
  if (pw->passwd_label)  free (pw->passwd_label);
  if (pw->date_label)    free (pw->date_label);
  if (pw->login_label)   free (pw->login_label);
  if (pw->user_string)   free (pw->user_string);
  if (pw->passwd_string) free (pw->passwd_string);
  if (pw->uname_label)   free (pw->uname_label);

  if (pw->heading_font) XFreeFont (si->dpy, pw->heading_font);
  if (pw->body_font)    XFreeFont (si->dpy, pw->body_font);
  if (pw->label_font)   XFreeFont (si->dpy, pw->label_font);
  if (pw->passwd_font)  XFreeFont (si->dpy, pw->passwd_font);
  if (pw->date_font)    XFreeFont (si->dpy, pw->date_font);
  if (pw->button_font)  XFreeFont (si->dpy, pw->button_font);
  if (pw->uname_font)   XFreeFont (si->dpy, pw->uname_font);

  if (pw->foreground != black && pw->foreground != white)
    XFreeColors (si->dpy, cmap, &pw->foreground, 1, 0L);
  if (pw->background != black && pw->background != white)
    XFreeColors (si->dpy, cmap, &pw->background, 1, 0L);
  if (!(pw->button_foreground == black || pw->button_foreground == white))
    XFreeColors (si->dpy, cmap, &pw->button_foreground, 1, 0L);
  if (!(pw->button_background == black || pw->button_background == white))
    XFreeColors (si->dpy, cmap, &pw->button_background, 1, 0L);
  if (pw->passwd_foreground != black && pw->passwd_foreground != white)
    XFreeColors (si->dpy, cmap, &pw->passwd_foreground, 1, 0L);
  if (pw->passwd_background != black && pw->passwd_background != white)
    XFreeColors (si->dpy, cmap, &pw->passwd_background, 1, 0L);
  if (pw->thermo_foreground != black && pw->thermo_foreground != white)
    XFreeColors (si->dpy, cmap, &pw->thermo_foreground, 1, 0L);
  if (pw->thermo_background != black && pw->thermo_background != white)
    XFreeColors (si->dpy, cmap, &pw->thermo_background, 1, 0L);
  if (pw->shadow_top != black && pw->shadow_top != white)
    XFreeColors (si->dpy, cmap, &pw->shadow_top, 1, 0L);
  if (pw->shadow_bottom != black && pw->shadow_bottom != white)
    XFreeColors (si->dpy, cmap, &pw->shadow_bottom, 1, 0L);

  if (pw->logo_pixmap)
    XFreePixmap (si->dpy, pw->logo_pixmap);
  if (pw-> logo_clipmask)
    XFreePixmap (si->dpy, pw->logo_clipmask);
  if (pw->logo_pixels)
    {
      if (pw->logo_npixels)
        XFreeColors (si->dpy, cmap, pw->logo_pixels, pw->logo_npixels, 0L);
      free (pw->logo_pixels);
      pw->logo_pixels = 0;
      pw->logo_npixels = 0;
    }

  if (pw->save_under)
    XFreePixmap (si->dpy, pw->save_under);

  if (cmap)
    XInstallColormap (si->dpy, cmap);
}
  memset (pw, 0, sizeof(*pw));
/*** NO mali99 we only create a copy of pw in main and keep it
     so dont free it.
  free (pw);
  si->pw_data = 0;
  ************/

 for (j= 1; j < 3 ; j++)
 {
   if (winatt_reset[j-1] && at_win[j] )
   {
      XChangeWindowAttributes(si->dpy,at_win[j],valuemask,&setwinattr);
      winatt_reset[j-1] = FALSE;
      at_win[j] = 0;
/*fprintf(stderr, "DEBUG: at(%d) override_redirect set to FALSE\n", j);
*/
   }
 }
/*
** restore the prev one
** 6520014(P3) mem. leak in lock.c
*/
        if ( client && globalkey_text)
        gconf_client_set_string ( client, \
        "/apps/metacity/global_keybindings/switch_windows", \
        globalkey_text, NULL);
        g_free(globalkey_text);
        globalkey_text = NULL;
/*
** 6736157 A11Y]Security problem when desktop a11y support is turned on
*/
        if ( client && globalmenu_key)
        gconf_client_set_string ( client, \
        "/apps/metacity/global_keybindings/panel_main_menu", \
        globalmenu_key, NULL);
        g_free(globalmenu_key);
        globalmenu_key = NULL;

}


static Bool error_handler_hit_p = False;

static int
ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
{
  error_handler_hit_p = True;
  return 0;
}


#ifdef HAVE_XHPDISABLERESET
/* This function enables and disables the C-Sh-Reset hot-key, which
   normally resets the X server (logging out the logged-in user.)
   We don't want random people to be able to do that while the
   screen is locked.
 */
static void
hp_lock_reset (saver_info *si, Bool lock_p)
{
  static Bool hp_locked_p = False;

  /* Calls to XHPDisableReset and XHPEnableReset must be balanced,
     or BadAccess errors occur.  (It's ok for this to be global,
     since it affects the whole machine, not just the current screen.)
  */
  if (hp_locked_p == lock_p)
    return;

  if (lock_p)
    XHPDisableReset (si->dpy);
  else
    XHPEnableReset (si->dpy);
  hp_locked_p = lock_p;
}
#endif /* HAVE_XHPDISABLERESET */


#ifdef HAVE_XF86MISCSETGRABKEYSSTATE

/* This function enables and disables the Ctrl-Alt-KP_star and 
   Ctrl-Alt-KP_slash hot-keys, which (in XFree86 4.2) break any
   grabs and/or kill the grabbing client.  That would effectively
   unlock the screen, so we don't like that.

   The Ctrl-Alt-KP_star and Ctrl-Alt-KP_slash hot-keys only exist
   if AllowDeactivateGrabs and/or AllowClosedownGrabs are turned on
   in XF86Config.  I believe they are disabled by default.

   This does not affect any other keys (specifically Ctrl-Alt-BS or
   Ctrl-Alt-F1) but I wish it did.  Maybe it will someday.
 */
static void
xfree_lock_grab_smasher (saver_info *si, Bool lock_p)
{
  saver_preferences *p = &si->prefs;
  int status;
  int event, error;

  if (!XF86MiscQueryExtension(si->dpy, &event, &error))
    return;

  XErrorHandler old_handler;
  XSync (si->dpy, False);
  error_handler_hit_p = False;
  old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
  XSync (si->dpy, False);
  status = XF86MiscSetGrabKeysState (si->dpy, !lock_p);
  XSync (si->dpy, False);
  if (error_handler_hit_p) status = 666;

  if (!lock_p && status == MiscExtGrabStateAlready)
    status = MiscExtGrabStateSuccess;  /* shut up, consider this success */

  if (p->verbose_p && status != MiscExtGrabStateSuccess)
    fprintf (stderr, "%s: error: XF86MiscSetGrabKeysState(%d) returned %s\n",
             blurb(), !lock_p,
             (status == MiscExtGrabStateSuccess ? "MiscExtGrabStateSuccess" :
              status == MiscExtGrabStateLocked  ? "MiscExtGrabStateLocked"  :
              status == MiscExtGrabStateAlready ? "MiscExtGrabStateAlready" :
              status == 666 ? "an X error" :
              "unknown value"));

  XSync (si->dpy, False);
  XSetErrorHandler (old_handler);
  XSync (si->dpy, False);
}
#endif /* HAVE_XF86MISCSETGRABKEYSSTATE */



/* This function enables and disables the C-Alt-Plus and C-Alt-Minus
   hot-keys, which normally change the resolution of the X server.
   We don't want people to be able to switch the server resolution
   while the screen is locked, because if they switch to a higher
   resolution, it could cause part of the underlying desktop to become
   exposed.
 */
#ifdef HAVE_XF86VMODE

static void
xfree_lock_mode_switch (saver_info *si, Bool lock_p)
{
  static Bool any_mode_locked_p = False;
  saver_preferences *p = &si->prefs;
  int screen;
  int event, error;
  Bool status;
  XErrorHandler old_handler;

  if (any_mode_locked_p == lock_p)
    return;
  if (!XF86VidModeQueryExtension (si->dpy, &event, &error))
    return;

  for (screen = 0; screen < (si->xinerama_p ? 1 : si->nscreens); screen++)
    {
      XSync (si->dpy, False);
      old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
      error_handler_hit_p = False;
      status = XF86VidModeLockModeSwitch (si->dpy, screen, lock_p);
      XSync (si->dpy, False);
      XSetErrorHandler (old_handler);
      if (error_handler_hit_p) status = False;

      if (status)
        any_mode_locked_p = lock_p;

      if (!status && (p->verbose_p || !lock_p))
        /* Only print this when verbose, or when we locked but can't unlock.
           I tried printing this message whenever it comes up, but
           mode-locking always fails if DontZoom is set in XF86Config. */
        fprintf (stderr, "%s: %d: unable to %s mode switching!\n",
                 blurb(), screen, (lock_p ? "lock" : "unlock"));
      else if (p->verbose_p)
        fprintf (stderr, "%s: %d: %s mode switching.\n",
                 blurb(), screen, (lock_p ? "locked" : "unlocked"));
    }
}
#endif /* HAVE_XF86VMODE */


/* If the viewport has been scrolled since the screen was blanked,
   then scroll it back to where it belongs.  This function only exists
   to patch over a very brief race condition.
 */
static void
undo_vp_motion (saver_info *si)
{
#ifdef HAVE_XF86VMODE
  saver_preferences *p = &si->prefs;
  int screen;
  int event, error;

  if (!XF86VidModeQueryExtension (si->dpy, &event, &error))
    return;

  for (screen = 0; screen < si->nscreens; screen++)
    {
      saver_screen_info *ssi = &si->screens[screen];
      int x, y;
      Bool status;

      if (ssi->blank_vp_x == -1 && ssi->blank_vp_y == -1)
        break;
      if (!XF86VidModeGetViewPort (si->dpy, screen, &x, &y))
        return;
      if (ssi->blank_vp_x == x && ssi->blank_vp_y == y)
        return;
    
      /* We're going to move the viewport.  The mouse has just been grabbed on
         (and constrained to, thus warped to) the password window, so it is no
         longer near the edge of the screen.  However, wait a bit anyway, just
         to make sure the server drains its last motion event, so that the
         screen doesn't continue to scroll after we've reset the viewport.
       */
      XSync (si->dpy, False);
      usleep (250000);  /* 1/4 second */
      XSync (si->dpy, False);

      status = XF86VidModeSetViewPort (si->dpy, screen,
                                       ssi->blank_vp_x, ssi->blank_vp_y);

      if (!status)
        fprintf (stderr,
                 "%s: %d: unable to move vp from (%d,%d) back to (%d,%d)!\n",
                 blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y);
      else if (p->verbose_p)
        fprintf (stderr,
                 "%s: %d: vp moved to (%d,%d); moved it back to (%d,%d).\n",
                 blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y);
    }
#endif /* HAVE_XF86VMODE */
}



/* Interactions
 */

static void
passwd_animate_timer (XtPointer closure, XtIntervalId *id)
{
  saver_info *si = (saver_info *) closure;
  int tick = 166;
  passwd_dialog_data *pw = si->pw_data;

/*  if (si->prefs.verbose_p)
   fprintf (stderr,"-->passwd_animate_timer()\n");
**/

  /*We want to make sure dialog isup before we try to animate**/
  if (!si->external_passwd || !g_passwd_dialog_created)
   {
    if (si->prefs.verbose_p)
      fprintf (stderr,"-->passwd_animate_timer() returning..no dialog yet\n");
    return;
   }

  pw->ratio -= (1.0 / ((double) si->prefs.passwd_timeout / (double) tick));
  if (pw->ratio < 0)
    {
      pw->ratio = 0;
      if (pw->state == pw_read || pw->state == pw_null)
       {
        pw->state = pw_time;
       }
    }

/*** Communicating with the Child lock dialog...sending ratio back... mali99***/
#ifdef HAVE_XSCREENSAVER_LOCK
  if (si->passwd_dialog)
    {
      XEvent event;
      Bool status;
      XErrorHandler old_handler;

/*      fprintf (stderr,"-->passwd_animate_timer() sending ratio to child\n");
**/

      event.xany.type = ClientMessage;
      event.xclient.display = si->dpy;
      event.xclient.window = si->passwd_dialog;
      event.xclient.message_type = XA_UNLOCK_RATIO;
      event.xclient.format = 32;
      memset (&event.xclient.data, 0, sizeof (event.xclient.data));
      event.xclient.data.l[0] = (long)(pw->ratio * 100);
      event.xclient.data.l[1] = 0;
      event.xclient.data.l[2] = 0;

/* CR 6176524 passwdTimeoutEnable for disabled user */
      if (!si->prefs.pwd_p)
        event.xclient.data.l[1] = 1;

      XSync (si->dpy, False);
      old_handler = XSetErrorHandler (ignore_all_errors_ehandler);

      status = XSendEvent (si->dpy, si->passwd_dialog, False, 0L, &event);

      XSync (si->dpy, False);
      XSetErrorHandler (old_handler);

      if (!status)
        fprintf (stderr, "%s: error sending ratio to lock dialog\n", blurb ());

    }
#else /* !HAVE_XSCREENSAVER_LOCK */
  update_passwd_window (si, 0, pw->ratio);
#endif /* !HAVE_XSCREENSAVER_LOCK */

  if (pw->state == pw_read)
    pw->timer = XtAppAddTimeOut (si->app, tick, passwd_animate_timer,
                                 (XtPointer) si);
  else
    pw->timer = 0;

  idle_timer ((XtPointer) si, 0);
}


static XComposeStatus *compose_status;

static void
handle_passwd_button (saver_info *si, XEvent *event)
{
  saver_preferences *p = &si->prefs;
  Bool mouse_in_box = False;
  Bool hit_p = False;
  passwd_dialog_data *pw = si->pw_data;
  saver_screen_info *ssi = pw->prompt_screen;

  if (! pw->login_button_enabled_p)
    return;

  mouse_in_box = 
    (event->xbutton.x >= pw->login_button_x &&
     event->xbutton.x <= pw->login_button_x + pw->login_button_width &&
     event->xbutton.y >= pw->login_button_y &&
     event->xbutton.y <= pw->login_button_y + pw->login_button_height);

  if (ButtonRelease == event->xany.type &&
      pw->login_button_down_p &&
      mouse_in_box)
    {
      /* Only allow them to press the button once: don't want to
         accidentally launch a dozen gdm choosers if the machine
         is being slow.
       */
      hit_p = True;
      pw->login_button_enabled_p = False;
    }

  pw->login_button_down_p = (mouse_in_box &&
                             ButtonRelease != event->xany.type);

  update_passwd_window (si, 0, pw->ratio);

  if (hit_p)
    fork_and_exec (ssi, p->new_login_command);
}


static void
handle_passwd_key (saver_info *si, XKeyEvent *event)
{
  saver_preferences *p = &si->prefs;
  passwd_dialog_data *pw = si->pw_data;
  int pw_size = sizeof (pw->typed_passwd) - 1;
  char *typed_passwd = pw->typed_passwd;
  char s[2];
  char *stars = 0;
  int i;
  int size = XLookupString (event, s, 1, 0, compose_status);

  if (size != 1) return;

  s[1] = 0;

  /* Add 10% to the time remaining every time a key is pressed. */
  pw->ratio += 0.1;
  if (pw->ratio > 1) pw->ratio = 1;

  switch (*s)
    {
    case '\010': case '\177':                           /* Backspace */
      if (!*typed_passwd)
        XBell (si->dpy, 0);
      else
        typed_passwd [strlen(typed_passwd)-1] = 0;
      break;

    case '\025': case '\030':                           /* Erase line */
      memset (typed_passwd, 0, pw_size);
      break;

    case '\012': case '\015':                           /* Enter */
      if (pw->state != pw_read)
        ;  /* already done? */
      else if (typed_passwd[0] == 0)
        pw->state = pw_null;
      else
        {
          update_passwd_window (si, "Checking...", pw->ratio);
          XSync (si->dpy, False);

/***************mali99************************************************
          if (passwd_valid_p (typed_passwd, p->verbose_p, PAM_SERVICE))
            pw->state = pw_ok;
          else
            pw->state = pw_fail;
          update_passwd_window (si, "", pw->ratio);
****************************************************************************/
            pw->state = pw_ok;
        }
      break;

    default:
      /* Though technically the only illegal characters in Unix passwords
         are LF and NUL, most GUI programs (e.g., GDM) use regular text-entry
         fields that only let you type printable characters.  So, people
         who use funky characters in their passwords are already broken.
         We follow that precedent.
       */
      if (isprint ((unsigned char) *s))
        {
          i = strlen (typed_passwd);
          if (i >= pw_size-1)
            XBell (si->dpy, 0);
          else
            {
              typed_passwd [i] = *s;
              typed_passwd [i+1] = 0;
            }
        }
      else
        XBell (si->dpy, 0);
      break;
    }

  if (pw->show_stars_p)
    {
      i = strlen(typed_passwd);
      stars = (char *) malloc(i+1);
      memset (stars, '*', i);
      stars[i] = 0;
      update_passwd_window (si, stars, pw->ratio);
      free (stars);
    }
  else
    {
      update_passwd_window (si, "", pw->ratio);
    }
}

void XTSOLMakeTPWindow(Display *, Window);

void
passwd_event_loop (saver_info *si)
{
  saver_preferences *p = &si->prefs;
  char *msg = 0;
  XEvent event;
  unsigned int caps_p = 0;
  passwd_dialog_data *pw = si->pw_data;
  int ii;
   Window w;
  int mscreen;
  int status = -2;
  int counter = 0;
  int retries = 2;

  /*bugid 6580862 Unable to type in windows session with full screen mode when 
hotdesked...
    The issue is sunray connector grabs keyboard and focus is in connector 
window. When xscreensaver
    pastes the unlock dialog box the password typed by user goes into connector 
window.
    The following code attempts to set focus back in unlock dialog box. The 
connector is looking
    for focus out events to get a hint to let go of keyboard grab. Which is 
exactly what we try to
    do in the following code.
  */
  write_to_child (si, "pw_read");
  mscreen = mouse_screen (si);
  w = RootWindowOfScreen(si->screens[mscreen].screen);
  /* grab_kbd() uses GrabModeSync which is holding up pointer events and hence 
unlcok
   * dialog box does not show up when you move mouse, only when you hit a key.
   * So, we locally call XGrabKeyboard() with GrabModeAsync instead of calling 
grab_kbd().
   * status = grab_kbd(si, w, mscreen);
   **/
  status = XGrabKeyboard (si->dpy, w, True,
                          GrabModeAsync, GrabModeAsync,
                          CurrentTime);

  XSync (si->dpy, False);
  while (status != GrabSuccess && counter++ <=retries)
   {
    status = XGrabKeyboard (si->dpy, w, True,
                            GrabModeAsync, GrabModeAsync,
                            CurrentTime);
    write_to_child (si, "pw_read");
    usleep (250000); /** 1/4 second */
    XSync (si->dpy, False);
    XTSOLMakeTPWindow(si->dpy,w);
    if(p->verbose_p)
      fprintf (stderr, "event loop..trying to grab keyboard######\n");
   }

  if (status == GrabSuccess)
    {
      si->keyboard_grab_window = w;
      si->keyboard_grab_screen = mscreen;
    }

/* bugid 6176524 passwdTimeout and reset timer for each key press  */
  passwd_animate_timer ((XtPointer) si, 0);

  while (si->pw_data && si->pw_data->state == pw_read)
    {
      XtAppNextEvent (si->app, &event);
#ifdef HAVE_RANDR
        /*
         * 6757448 xscreensaver doesn't notice XRandR resize events.
         */
        if (event.type == (si->randr_event_number + RRScreenChangeNotify))
          {
            /* The Resize and Rotate extension sends an event when the
               size, rotation, or refresh rate of the screen has changed. */

            XRRScreenChangeNotifyEvent *xrr_event =
              (XRRScreenChangeNotifyEvent *) &event;
            /* XRRRootToScreen is in Xrandr.h 1.4, 2001/06/07 */
            int screen = XRRRootToScreen (si->dpy, xrr_event->window);

            if (p->verbose_p)
              {
                if (si->screens[screen].width  == xrr_event->width &&
                    si->screens[screen].height == xrr_event->height)
                  fprintf (stderr,
                          "%s: %d: no-op screen size change event (%dx%d)\n",
                           blurb(), screen,
                           xrr_event->width, xrr_event->height);
                else
                  fprintf (stderr,
                       "%s: %d: screen size changed from %dx%d to %dx%d\n",
                           blurb(), screen,
                           si->screens[screen].width,
                           si->screens[screen].height,
                           xrr_event->width, xrr_event->height);
              }

# ifdef RRScreenChangeNotifyMask
            /* Inform Xlib that it's ok to update its data structures. */
            XRRUpdateConfiguration (&event); /* Xrandr.h 1.9, 2002/09/29 */
# endif /* RRScreenChangeNotifyMask */
            /* Resize the existing xscreensaver windows and cached ssi data. */
            resize_screensaver_window (si);
          }
#endif /* HAVE_RANDR */

#ifdef HAVE_XSCREENSAVER_LOCK
      if (event.xany.type == KeyPress)
        {
          if (si->pw_data->got_windowid)
            {
              Bool status,pwd_status;
              XErrorHandler old_handler;

              if(p->verbose_p)
               fprintf (stderr, "event loop..gotwindowid..and keypress 
event...\n");

               event.xany.window = si->passwd_dialog;

              XSync (si->dpy, False);
              old_handler = XSetErrorHandler (ignore_all_errors_ehandler);

              status =
        XSendEvent (si->dpy, si->passwd_dialog, False, KeyPressMask, &event);
              XSync (si->dpy, False);
              XSetErrorHandler (old_handler);

/* CR 6176524 passwdTimeoutEnable for disabled user
   timer will be reset if 4 conditions art true (for each char of pwd)
   (status) && (p->pwd_p) && (at_enabled) && (pw->timer)
   However AT group wants to remove at_enabled
   i.e reset the password timer for each key for all users
   * 6240938 screensaver-lock's password timer needs to to be reset
        for each key (all users) and enabling AT support
*/

        if ((status) && (p->pwd_p)  && (pw->timer)) {
        XtRemoveTimeOut (pw->timer);
        pw->ratio = 1.0;
        pw->timer = XtAppAddTimeOut (si->app, 166, passwd_animate_timer,
                                 (XtPointer) si);
        }

              if (p->verbose_p)
                {
                  if (status)
                    fprintf (stderr, "sent key...\n");
                  else
                    fprintf (stderr, "error sending key...\n");
                }
            }
          else
            {
              if (p->verbose_p)
                fprintf (stderr, "got keypress but no window id yet :(\n");
              XtDispatchEvent (&event);
            }
        }

#else /* !HAVE_XSCREENSAVER_LOCK */
      if (event.xany.window == si->passwd_dialog && event.xany.type == Expose)
        draw_passwd_window (si);
      else if (event.xany.type == KeyPress)
        {
          handle_passwd_key (si, &event.xkey);
          caps_p = (event.xkey.state & LockMask);
        }
      else if ((event.xany.type == ButtonPress || 
                event.xany.type == ButtonRelease) && 
               si->pw_data->login_button_p)
        handle_passwd_button (si, &event);
#endif /* !HAVE_XSCREENSAVER_LOCK */
      else if (event.xany.window == si->passwd_dialog && event.xany.type == 
Expose &&
               si->pw_data->passwd_label != NULL)
       {
          if(p->verbose_p)
            fprintf (stderr, "event loop...and expose event.should update lock 
with new label...\n");
          /***if (si->pw_data->passwd_label)**/
          update_passwd_window (si, si->pw_data->passwd_label, pw->ratio);
          free (si->pw_data->passwd_label);
          si->pw_data->passwd_label = 0;
          si->pw_data->state = pw_read;
       }

 /*
* 5077974 P1 "Bug 147583: Screen Lock unlocks because of GOK dwell movement in
              core pointer mode"
*
* ScreenLock did not unlock the screen, but WM's XRestackWindow() did.
* Once WM/metacity fixes the problem, the code can be removed.
  The problem:
  repositioning the Wids in the wrong positions when
  1. the window type is changed from NORMAL to DOCK or vice versa
  2. the Wid is managed
  within the X window stack with or without screen-lock in a mixed Wids
  there are two temp. get-around solutions:
  1. non-managed GOK or MAG Wid
  or
  2. screensaver picks up the WM's restacking task and fixes the prevous
     restacking problem.
     the cons: there is a flashing screen when corepointer is touching
     GOK or MAG and mouse is moved in a fast way
     when GOK or MAG window type is DOCK only.
     and it is not a good temp. get-around solution.
     This is the only choice if WM did not want to fix the problem now
     and AT group did not want to use non-managed Wids.
     Now, GOK only supports 2nd USB/mouse/Dwell, corepointer is supposed
     not to be used, and GOK cannot disable it
*/
/*
     bugid 6769901,6839026: popup windows appearing through xscreensaver
     Also this routine is to stop the popup window when a11y is on also when 
a11y is not on.
     Note: when a11y is on no_atserv > 0 
*/

else if (((event.type == UnmapNotify)
                || (event.type == MapNotify )
                || (event.type == VisibilityNotify)
                || (event.type == ConfigureNotify)
                || (event.type == PropertyNotify )
                || (event.type == CreateNotify)
                || (event.type == ReparentNotify ))
                && (si->passwd_dialog) )
        {
/* AT_LOCK_DEBUG
fprintf (stderr, "client window(0x%x) %s\n", event.xclient.window,blurb());
fprintf (stderr, "dialog window 0x%x:\n", si->passwd_dialog);
fprintf(stderr, "** no_atserv: %d \n", no_atserv);
for (ii = 0; ii < 4;  ii++)
         fprintf(stderr, "** win : 0x%x \n", at_win[ii]);
*/
         
         /* this if case is for safety,it prevent screensaver stuck in loop of 
ConfigureNotify */
         if(event.xany.window && (event.xany.window != 
si->screens[0].screensaver_window) && (event.xany.window != si->passwd_dialog
))
         {
            /* find the handle of popup window */
            /* Note: we can not get handle of popup window with 
event.xany.window, thats why we have switch cases. */
             Window wPopWin =0;
             switch(event.type)
             {
                case ConfigureNotify:
                wPopWin = event.xconfigure.window;
                break;
                case CreateNotify:
                wPopWin = event.xcreatewindow.window;
                break;
                case VisibilityNotify: 
                wPopWin = event.xvisibility.window;
                break;
                default:
                break;
             }  


             /* Array at_win stores password and screensaver window, also MAG 
and/or GOK if a11y is on 
             /* if any window apart from password, MAG ,GOK or screensaver 
comes over is considered as popup window. */
             /* If it is not popup window but password, MAG, GOK, or 
screensaver window then nWin < no_atserv+2 */ 
             /* If it is popup window then nWin == no_atserv+2 */ 
             int nWin =0;
             if(wPopWin) // check if it is really a popup window
                for(;nWin < no_atserv+2 ; ++nWin)
                {
                   if(at_win[nWin]==wPopWin)
                   break;
                }

             /* Do restacking if it is popup window ie nWin == no_atserv+2 */
             /* Also do restacking when a11y is on */
             if( nWin== no_atserv+2 ||no_atserv ) 
             {

                /* at_win[0] -> passwordwindow */
                /* at_win[1-2]-> if a11y on, may GOK or MAG */

                at_win[no_atserv+1] = si->screens[0].screensaver_window;
                if(nWin== no_atserv+2)
                { 
                   /* store popup window in array of at_win to restack it */
                   at_win[no_atserv+2] = wPopWin;
                   XRestackWindows(si->dpy, at_win,no_atserv+3);
                }
                else
                {
                   XRestackWindows(si->dpy, at_win,no_atserv+2);
                }
                XFlush(si->dpy);
             }
          }

        }
/* the above new code for restacking under the conidtion
*/
      else
        {
/*
         if ((si->passwd_dialog) && (no_atserv) && (event.type != 0))
         fprintf(stderr, "** DEbug other event %d\n", event.type);
*/
        XtDispatchEvent (&event);
        }

    }

  switch (si->pw_data->state)
    {
    case pw_ok:   msg = strdup("pw_ok"); break;
    case pw_null: msg = strdup("pw_null"); break;
    case pw_time: msg = strdup("pw_time"); break;
    case pw_read: msg = strdup("pw_read"); break;
    case pw_fail: msg = strdup("pw_fail"); break;
    case pw_cancel: msg = strdup("pw_cancel"); break;
    default:      msg = 0;
        fprintf(stderr, "si->pw_data->state is bad, serious error\n");
        break;
    }

  if (si->pw_data->state == pw_fail)
    si->unlock_failures++;

  if (p->verbose_p)
    switch (si->pw_data->state)
      {
      case pw_ok:
       {
        fprintf (stderr, "%s: password correct.\n", blurb());
        fprintf (stderr, "%s: setting state to be null.\n", blurb());
        si->pw_data->state = pw_null;
        break;
       }
      case pw_fail:
        fprintf (stderr, "%s: password incorrect!%s\n", blurb(),
                 (caps_p ? "  (CapsLock)" : ""));
        break;
      case pw_null:
      case pw_cancel:
        fprintf (stderr, "%s: password entry cancelled.\n", blurb()); break;
      case pw_time:
        fprintf (stderr, "%s: password entry timed out.\n", blurb()); break;
      default:
        break;
      }

#ifdef HAVE_SYSLOG
  if (si->pw_data->state == pw_fail)
    {
      /* If they typed a password (as opposed to just hitting return) and
         the password was invalid, log it.
      */
      struct passwd *pw = getpwuid (getuid ());
      char *d = DisplayString (si->dpy);
      char *u = (pw->pw_name ? pw->pw_name : "???");
      int opt = 0;
      int fac = 0;

# ifdef LOG_PID
      opt = LOG_PID;
# endif

# if defined(LOG_AUTHPRIV)
      fac = LOG_AUTHPRIV;
# elif defined(LOG_AUTH)
      fac = LOG_AUTH;
# else
      fac = LOG_DAEMON;
# endif

      if (!d) d = "";
      openlog (progname, opt, fac);
      syslog (LOG_NOTICE, "FAILED LOGIN %d ON DISPLAY \"%s\", FOR \"%s\"",
              si->unlock_failures, d, u);
      closelog ();
    }
#endif /* HAVE_SYSLOG */

  if (si->pw_data->state == pw_fail)
    XBell (si->dpy, False);

  if (si->pw_data->state == pw_ok && si->unlock_failures != 0)
    {
      if (si->unlock_failures == 1)
        fprintf (real_stderr,
                 "%s: WARNING: 1 failed attempt to unlock the screen.\n",
                 blurb());
      else
        fprintf (real_stderr,
                 "%s: WARNING: %d failed attempts to unlock the screen.\n",
                 blurb(), si->unlock_failures);

      si->unlock_failures = 0;
    }

  if (msg)
    {
          if (p->verbose_p)
            {
              fprintf (stderr, "..eventloop...msg is:%s\n",msg);
            }
#ifdef HAVE_XSCREENSAVER_LOCK
    /* DONT NEED TO SEND ANY INFO TO CHILD AT THIS STAGE */
    /*  if (write_to_child (si, msg));**/ /*if write is successful do nothing*/
      free(msg);

      /*********************************************************
      if (si->external_passwd && si->pw_data->stdin_fd != -1)
        {
          ssize_t len;
          char *nlmsg;

          nlmsg = (char *)malloc (strlen (msg) + 2);
          sprintf (nlmsg, "%s\n", msg);

          if (p->verbose_p)
            {
              fprintf (stderr, 
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
              fprintf (stderr, "HAVE_SCRSVR_LOCK message is:%s writing to 
fd:%d\n",
                                   msg, si->pw_data->stdin_fd);
              fprintf (stderr, 
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
            }

        write_msg:
          len = write (si->pw_data->stdin_fd, nlmsg, strlen (nlmsg));
          if (len < 0 && errno == EINTR)
            goto write_msg;

          free (nlmsg);
        }
      else
      
******************************************************************************/
#endif /* HAVE_XSCREENSAVER_LOCK */
/************
    {
      si->pw_data->i_beam = 0;
      update_passwd_window (si, msg, 0.0);
    }
************/

      XSync (si->dpy, False);
      usleep (250000);  /* 1/4 second */

      /* Swallow all pending KeyPress/KeyRelease events. */
      {
        XEvent e;
        while (XCheckMaskEvent (si->dpy, KeyPressMask|KeyReleaseMask, &e))
          ;
      }
    }
}


void
handle_typeahead (saver_info *si)
{
  passwd_dialog_data *pw = si->pw_data;
  int i;
  if (!si->unlock_typeahead)
    return;

  i = strlen (si->unlock_typeahead);
  if (i >= sizeof(pw->typed_passwd) - 1)
    i = sizeof(pw->typed_passwd) - 1;

  memcpy (pw->typed_passwd, si->unlock_typeahead, i);
  pw->typed_passwd [i] = 0;

  memset (si->unlock_typeahead, '*', strlen(si->unlock_typeahead));
  si->unlock_typeahead[i] = 0;
#ifdef HAVE_XSCREENSAVER_LOCK
  /* FIXME: bugzilla.gnome.org #77077 */
  /* need to handle this in the external dialog case */

#else
  update_passwd_window (si, si->unlock_typeahead, pw->ratio);
#endif /* !HAVE_XSCREENSAVER_LOCK */

  free (si->unlock_typeahead);
  si->unlock_typeahead = 0;
}


Bool
unlock_p (saver_info *si)
{
  saver_preferences *p = &si->prefs;
  Bool status;

  raise_window (si, True, True, True);

  if (p->verbose_p)
    fprintf (stderr, "%s: -->unlock_p()\n", blurb());

Need to update about SUBCR of  Nevada #6839026

My new fixes are very  stable now. Barun and I have tested it very 
thoroughly with a11y on.  Today I will raise it for JDS-Review, if no 
objection from Jeremy and Alan.

*Background*
Patch 120094-22, may cause performance degradation of CPU and system 
become unresposive when Trusted Extension or  Accessibility is turned 
on. Fixes of CR 6769901 are not appropriate should be corrected with CR 
6839026, on all the x86 and SPARC machine .

When a machine is patched with 120094-22, Symptoms are as follows.

a) When screen is locked and Accessibility is turned on, popup window 
might make x86/SPARC machine unresponsive.
b) When screen is locked and Trusted Extension is turned on, may cause 
performance degradation of CPU. [tx] Xsun chews cpu and console appear 
to be hung.

*Questions*
Q:why we have not fixed it at WindowManager?
Ans: We got some success in fixing this bug at  metacity/WM, but with 
lots of code changes. Login helper interface is required at metacity

Q: Is it fixed completly .What is remaining?
Ans: Yes this bug is fixed completely.  But we should wait for final 
test results,  if any problem comes we will fix in CR6875930.
There are some special cases, where we need to do restacking of pop up 
windows in timer.c . Also  there are some existing bugs in a11y, we will 
address them separately.
We are fixing this bug in incremental mode, all the remaining problem 
will be fixed in CR6875930


*What we have fixied*
Xsun is consuming 100% cpu cycle with trusted path because of  CR6769901
Also we found, with accessibility, cpu consumption goes to 100%
Popup window should not come through screensaver.

*Testing *
Barun and Arvind have tested new fixes very thoroughly
a) Pop-ups will not come through screensaver  in case of dual head 
display with and without xinerama . Same is the case when a11y is turned on.
b)Pop-ups will not come through screensaver  with  twinview  display of 
Xorg. Also there will be no performance degradation with my fixes
c) Pop-ups will not come through screensaver  with trusted path
d) Pop-ups will not come through screensaver  with all  a11y cases
e) works fine with Xnewt,Xorg and Xsun
f) works fine with x86, x64, SPARC
g) The only pop-ups to get through are the ally pop-ups  which are 
allowed by design.  GOK and MAG  always on top of screensaver when we 
lock the screen.





I am including svn diff of repository trunk/vermillion.  For more detail 
please see the attached source file.

Index: ChangeLog
===================================================================
--- ChangeLog   (revision 19180)
+++ ChangeLog   (working copy)
@@ -1,3 +1,8 @@
+2009-09-10  Arvind Umrao  <arvind.umrao at sun.com>
+
+    * SUNWxscreensaver.spec, patches/xscreensaver-48-bug-6839026.diff:
+    * CR#6839026 Regression in screensaver may cause Performance 
Degradation and make lock ed screensaver unresponsive.
+
 2009-08-27  Abhijit Nath <abhijit.nath at sun.com>

        * SUNWTiff.spec: add patch libtiff-05-CVE-2009-2285.diff
Index: patches/xscreensaver-48-bug-6839026.diff
===================================================================
--- patches/xscreensaver-48-bug-6839026.diff    (revision 0)
+++ patches/xscreensaver-48-bug-6839026.diff    (revision 0)
@@ -0,0 +1,150 @@
+--- xscreensaver-5.01/driver/lock.c_org        2009-08-27 
16:40:31.474335000 +0530
++++ xscreensaver-5.01/driver/lock.c    2009-09-10 15:39:37.444268000 +0530
+@@ -109,8 +109,8 @@ extern Atom XA_UNLOCK_RATIO;
+
+
+ /* GOK bug */
+-Window at_win[4] = {0,0,0,0}; /* wIds for XRestackWindows() */
+-                              /* dialog, GOK, or MAG or screenSaver */
++Window at_win[5] = {0,0,0,0,0}; /* wIds for XRestackWindows() */
++                              /* dialog, GOK, or MAG or screenSaver or 
temporary popup wi ndow */
+
+ int no_atserv = 0;            /* GOK or MAG or Both on def. screen 0 */
+
+@@ -2139,36 +2139,6 @@ passwd_event_loop (saver_info *si)
+           }
+       }
+
+-      //bugid 6769901: popup windows appearing through xscreensaver
+-        //code to stop popup windows while screen is locked
+-        //Raise the screen saver window and then the password dialog 
window
+-        if (event.xany.type == VisibilityNotify || event.xany.type == 
ConfigureNotify || event.xany.type == CreateNotify)
+-        {
+-              int screen;
+-                for (screen = 0; screen < si->nscreens; screen++)
+-                {
+-                      if(si->passwd_dialog)for
+-                        {
+-                              saver_screen_info *ssi = 
&si->screens[screen];
+-                                if(screen==0)
+-                                {
+-                                      Window screen_win[2] = {
+-                                              si->passwd_dialog,
+-                                                ssi->screensaver_window
+-                                      };
+-                                        XRestackWindows(si->dpy, 
screen_win, 2);
+-                                        
XMapRaised(si->dpy,si->passwd_dialog);
+-                                        XFlush(si->dpy);
+-                              }
+-                                else
+-                                {
+-                                      
XMapRaised(si->dpy,ssi->screensaver_window);
+-                                        XFlush(si->dpy);
+-                                }
+-                      }
+-              }
+-        }
+-
+ #else /* !HAVE_XSCREENSAVER_LOCK */
+       if (event.xany.window == si->passwd_dialog && event.xany.type == 
Expose)
+       draw_passwd_window (si);
+@@ -2219,24 +2189,87 @@ passwd_event_loop (saver_info *si)
+      Now, GOK only supports 2nd USB/mouse/Dwell, corepointer is supposed
+      not to be used, and GOK cannot disable it
+ */
+-        else if (((event.type == UnmapNotify)
+-                || (event.type == MapNotify )
+-                || (event.type == ConfigureNotify)
+-                || (event.type == PropertyNotify )
+-                || (event.type == ReparentNotify ))*dfdf


*
+-                && (si->passwd_dialog) && (no_atserv))
+-        {
++/*
++     bugid 6769901,6839026: popup windows appearing through xscreensaver
++     Also this routine is to stop the popup window when a11y is on 
also when a11y is not on.
++     Note: when a11y is on no_atserv > 0for
++*/
++
++else if (((event.type == UnmapNotify)
++              || (event.type == MapNotify )
++              || (event.type == VisibilityNotify)
++              || (event.type == ConfigureNotify)
++              || (event.type == PropertyNotify )
++              || (event.type == CreateNotify)
++              || (event.type == ReparentNotify ))
++              && (si->passwd_dialog) )
++      {
+ /* AT_LOCK_DEBUG
+ fprintf (stderr, "client window(0x%x) %s\n", 
event.xclient.window,blurb());
+ fprintf (stderr, "dialog window 0x%x:\n", si->passwd_dialog);
+ fprintf(stderr, "** no_atserv: %d \n", no_atserv);
+ for (ii = 0; ii < 4;  ii++)
+-         fprintf(stderr, "** win : 0x%x \n", at_win[ii]);
++       fprintf(stderr, "** win : 0x%x \n", at_win[ii]);
+ */
+-          at_win[no_atserv+1] = si->screens[0].screensaver_window;
+-/* 2 => screensaver and dialog Wids */
+-         XRestackWindows(si->dpy, at_win, no_atserv+2);
+-          XFlush(si->dpy);
++
++       /* this if case is for safety,it prevent screensaver stuck in 
loop of ConfigureNot ify */
++       if(event.xany.window && (event.xany.window != 
si->screens[0].screensaver_window) & & (event.xany.window != 
si->passwd_dialog
++))
++       {
++            /* find the handle of popup window */
++            /* Note: we can not get handle of popup window with 
event.xany.window, thats why we have switch cases. */
++             Window wPopWin =0;
++             switch(event.type)
++             {
++                case ConfigureNotify:
++                wPopWin = event.xconfigure.window;
++                break;
++                case CreateNotify:
++                wPopWin = event.xcreatewindow.window;
++                break;
++                case VisibilityNotify:
++                wPopWin = event.xvisibility.window;
++                break;
++                default:
++                break;
++             }
++
++
++             /* Array at_win stores password and screensaver window, 
also MAG and/or GOK if a11y is on
++             /* if any window apart from password, MAG ,GOK or 
screensaver comes over is considered as popup window. */
++             /* If it is not popup window but password, MAG, GOK, or 
screensaver window t hen nWin < no_atserv+2 */
++             /* If it is popup window then nWin == no_atserv+2 */
++             int nWin =0;
++             if(wPopWin) // check if it is really a popup window
++                for(;nWin < no_atserv+2 ; ++nWin)
++                {
++                   if(at_win[nWin]==wPopWin)
++                   break;
++                }
++
++           /* Do restacking if it is popup window ie nWin == 
no_atserv+2 */
++             /* Also do restacking when a11y is on */
++             if( nWin== no_atserv+2 ||no_atserv )
++             {
++
++                /* at_win[0] -> passwordwindow */
++                /* at_win[1-2]-> if a11y on, may GOK or MAG */
++
++                at_win[no_atserv+1] = si->screens[0].screensaver_window;
++                if(nWin== no_atserv+2)
++                {
++                   /* store popup window in array of at_win to restack 
it */
++                   at_win[no_atserv+2] = wPopWin;
++                   XRestackWindows(si->dpy, at_win,no_atserv+3);
++                }
++                else
++                {
++                   XRestackWindows(si->dpy, at_win,no_atserv+2);
++                }
++                XFlush(si->dpy);
++             }
++          }
++
+         }
+ /* the above new code for restacking under the conidtion
+ */
Index: SUNWxscreensaver.spec
===================================================================
--- SUNWxscreensaver.spec       (revision 19180)
+++ SUNWxscreensaver.spec       (working copy)
@@ -149,6 +149,8 @@
 Patch46: xscreensaver-46-bug-6857559.diff
 # date:2009-07-31 owner:bp230705 type:bug bugster:6859039
 Patch47: xscreensaver-47-bug-6859039.diff
+# date:2009-09-10 owner:au230626 type:bug bugster:6839026
+Patch48: xscreensaver-48-bug-6839026.diff

 # date:2008-03-07 owner:alanc type:branding
 Patch101: rss-glx-101-matrixview.diff
@@ -327,6 +329,7 @@
 %patch45 -p1
 %patch46 -p1
 %patch47 -p1
+%patch48 -p1

------------------------------------------------------------------------

/* lock.c --- handling the password dialog for locking-mode.
 * xscreensaver, Copyright (c) 1993-2006 Jamie Zawinski <jwz at jwz.org>
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of this
 * software for any purpose.  It is provided "as is" without express or 
 * implied warranty.
 */

/* Athena locking code contributed by Jon A. Christopher <jac8782 at tamu.edu> 
*/
/* Copyright 1997, with the same permissions as above. */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <ctype.h>
#include <X11/Intrinsic.h>
#include <X11/cursorfont.h>
#include <X11/Xos.h>            /* for time() */
#include <X11/Xatom.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include "exec.h"
#include "xscreensaver.h"
#include "resources.h"
#include <gconf/gconf-client.h>

#ifndef NO_LOCKING              /* (mostly) whole file */

#ifdef HAVE_SYSLOG
# include <syslog.h>
#endif /* HAVE_SYSLOG */

#ifdef HAVE_XHPDISABLERESET
# include <X11/XHPlib.h>
  static void hp_lock_reset (saver_info *si, Bool lock_p);
#endif /* HAVE_XHPDISABLERESET */

#ifdef HAVE_XF86VMODE
# include <X11/extensions/xf86vmode.h>
  static void xfree_lock_mode_switch (saver_info *si, Bool lock_p);
#endif /* HAVE_XF86VMODE */

#ifdef HAVE_XF86MISCSETGRABKEYSSTATE
# include <X11/extensions/xf86misc.h>
  static void xfree_lock_grab_smasher (saver_info *si, Bool lock_p);
#endif /* HAVE_XF86MISCSETGRABKEYSSTATE */

#ifdef HAVE_RANDR
#include <X11/extensions/Xrandr.h>
#endif /* HAVE_RANDR */

#ifdef _VROOT_H_
ERROR!  You must not include vroot.h in this file.
#endif

#ifdef HAVE_UNAME
# include <sys/utsname.h> /* for hostname info */
#endif /* HAVE_UNAME */
#include <ctype.h>

#ifndef VMS
# include <pwd.h>
#else /* VMS */

extern char *getenv(const char *name);
extern int validate_user(char *name, char *password);

static Bool
vms_passwd_valid_p(char *pw, Bool verbose_p)
{
  return (validate_user (getenv("USER"), typed_passwd) == 1);
}
# undef passwd_valid_p
# define passwd_valid_p vms_passwd_valid_p

#endif /* VMS */

/* 5059445(p3) screen kb and reader support */
extern int grab_mouse (saver_info *si, Window window, Cursor cursor, int 
screen_no);
extern int grab_kbd (saver_info *si, Window window,  int screen_no);

extern int kill_job (saver_info *si, pid_t pid, int signal);
extern struct screenhack_job *make_job (pid_t pid, int screen, const char *cmd);
void hack_uid (saver_info *si);

Bool g_passwd_dialog_created = 0;

#undef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))

/* enum passwd_state & struct passwd_dialog_data moved to xscreensaver.h */

static void make_window (saver_info *si, enum window_type w_type);
static void draw_passwd_window (saver_info *si);
       void update_passwd_window (saver_info *si, const char *printed_passwd,
                                  float ratio);
       void destroy_passwd_window (saver_info *si);
static void undo_vp_motion (saver_info *si);
static void handle_passwd_button (saver_info *si, XEvent *event);

extern Atom XA_UNLOCK_RATIO;


/* GOK bug */
Window at_win[5] = {0,0,0,0,0}; /* wIds for XRestackWindows() */
                                /* dialog, GOK, or MAG or screenSaver or 
temporary popup window */

int no_atserv = 0;              /* GOK or MAG or Both on def. screen 0 */

Bool at_enabled = False;        /* Ass. Tech support? def. no */
                                /* for restoring the origin setting
                                   override_redirect setting of MAG/GOK
                                */
Bool winatt_reset[2] = {FALSE,FALSE};

char  *globalkey_text = NULL;
char  *globalmenu_key = NULL;
GConfClient *client = NULL;

/*
5083155 Unable to unlock screen when running dual-head MAG
*adding dual or multiple heads for magnifier support
*
  screen 0: loginhelp can pass the raisedWid of GOK or MAG or both
            found: return its parent Wid (child of root)
            not found:  0

  other screen: MAG only if the target screen no > 0 is selected
        found:  restack on that screen
                return 0
        not-found : rturn 0

*/
Atom atom_type[1], atom_window_type;

Window
check_raisedWid(saver_info *si,Window wid)
{
int screen_no,status;
Bool loop, found = FALSE;
Window root_ret, parent_ret, *children = NULL,root;
unsigned int nchildren = 0;

Screen *screen;
saver_screen_info *ssi;
Display *dpy;
Window screen_win[2] = {0,0};


for (screen_no = 0; screen_no < si->nscreens; screen_no++)
 {
   loop = TRUE;
   ssi = &si->screens[screen_no];
   screen = ssi->screen;
   root =    RootWindowOfScreen (screen);
   if (screen_no == 0)
        dpy = DisplayOfScreen(screen);
   else
        dpy = ssi->other_dpy;
   if (dpy)
   {
     while (loop)
     {
     status =
        XQueryTree (dpy, wid ,&root_ret,&parent_ret, &children, &nchildren);
/*  AT_LOCK_DEBUG
fprintf(stderr, " ==>screen(%x) root(%x) wid(%x) root_ret(%x) 
parent_ret(%x)\n", screen, root, wid, root_ret, parent_ret);
fprintf(stderr, " screen_no(%d) ==>dpy(%x)\n", screen_no,dpy);
*/

        if (parent_ret == 0 || root != root_ret) /* not found */
                        loop = FALSE;
        else if ( root_ret != parent_ret)
          wid  = parent_ret;
        else
        {

          loop = FALSE;
          found = TRUE;
/*  AT_LOCK_DEBUG
fprintf(stderr,"==> found wid is 0x%x screen_no(%d)\n", wid, screen_no);
*/
          if (screen_no)
          {
/*
** found in other screen(not scn 0), implies MAG target scn,
** invoke XRestackWindow()
*/
                screen_win[0] = wid;
                screen_win[1] = ssi->screensaver_window;
                XRestackWindows(dpy, screen_win, 2);
                XSync (dpy, False);
                wid = 0;   /* no need to do the restack on screen 0 */
           }
           screen_no = si->nscreens;
        }
        } /* while loop */
  } /*dpy check */

 } /* for loop */
 if (found)
        return wid;
 else
        return 0;
}

static int  ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error);

#ifdef HAVE_XSCREENSAVER_LOCK

int
write_to_child (saver_info* si, char* msg)
{
      if (si->external_passwd && g_passwd_dialog_created && 
si->pw_data->stdin_fd != -1)
        {
          ssize_t len;
          char *nlmsg;

          nlmsg = (char *)malloc (strlen (msg) + 2);
          sprintf (nlmsg, "%s\n", msg);

          if (si->prefs.verbose_p)
            {
              fprintf (stderr, 
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
              fprintf (stderr, "HAVE_SCRSVR_LOCK message is:%s writing to 
fd:%d\n",
                                   msg, si->pw_data->stdin_fd);
              fprintf (stderr, 
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
            }

        write_msg:
          len = write (si->pw_data->stdin_fd, nlmsg, strlen (nlmsg));
          if (len < 0 && errno == EINTR)
            goto write_msg;

          free (nlmsg);
          return (1);
        }
      return (0); /* if we didnt write anything return 0*/
}

static int
sane_dup2 (int fd1, int fd2)
{
  int ret;

 retry:
  ret = dup2 (fd1, fd2);
  if (ret < 0 && errno == EINTR)
    goto retry;

  return ret;
}

static int
close_and_invalidate (int *fd)
{
  int ret;

  ret = close (*fd);
  *fd = -1;

  return ret;
}

void
handle_passwd_input (XtPointer data, int *fd, XtInputId *id)
{
  saver_info *si = (saver_info *)data;
  saver_preferences *p = &si->prefs;
  char buffer[1024];
  char *s;
  int status;

  if (si->prefs.verbose_p)
    fprintf (stderr, "passwd input handler() fd=%d\n",*fd);

  s = fgets (buffer, sizeof (buffer), si->pw_data->input_file);
  if (!s)
    {
      if (si->prefs.verbose_p)
        {
          fprintf (stderr, "done reading...\n");
          fprintf (stderr, "removing input handler...\n");
        }
      XtRemoveInput (*id);
      si->pw_data->stdout_input_id = 0;

      if (si->pw_data->state == pw_read)
        si->pw_data->state = pw_null;

      if (si->prefs.verbose_p)
        fprintf (stderr, "passwd input handler() returning...done reading\n");

      return;
    }

  if (si->pw_data->got_windowid)
    {
      char *nl;
      if (si->prefs.verbose_p)
        fprintf (stderr, "got a password\n");
      nl = strchr (s, '\n');
      if (nl)
        *nl = '\0';
      si->pw_data->passwd_string = strdup (s);
      if (si->prefs.verbose_p)
        fprintf(stderr,"Dude got password and saving it in passwd_string:%s\n", 
s);

     /* We want to send null to lock dialog to say we are working on 
authentication*/
     si->pw_data->state = pw_null;
    }
  else /* Get the window id of lock dialog from Child ***/
    {
      Window window = strtoul (s, NULL, 0);

        XSetWindowAttributes setwinattr;
        unsigned long valuemask = CWOverrideRedirect;
        XWindowChanges changes;
        setwinattr.override_redirect = True;
        XWindowAttributes window_attributes_return;

      Window window1 = 0, passwd_win = 0,wintemp = 0; int j;
/*CR 5039878 2 3 "Password:" field should be focused / have flashing caret */
      s = fgets (buffer, sizeof (buffer), si->pw_data->input_file);
      passwd_win = strtoul (s, NULL, 0);
      no_atserv = 0;
      at_win[no_atserv] = window;

        /* There is no need to reset the timer for Normal user
           for each pop-up dialog
        */
      at_enabled = False;


      for (j= 0; j < 2; j++)
      {
        s = fgets (buffer, sizeof (buffer), si->pw_data->input_file);
        window1 = strtoul (s, NULL, 0);
/* GOK, MAG, not running, Ass. Tech support is still selected
   not enough interface info from loginhelper to cover all
   possible conditions, ungrab kb/mouse now
 */
        if (window1 == 0x1)
                at_enabled = True;
        else
        if (window1 != 0x0 ) {
/*
5083155 Unable to unlock screen when running dual-head MAG
*adding dual or multiple heads for magnifier support
*/

                at_enabled = True;
                wintemp = check_raisedWid(si, window1);
                if (wintemp) {
        status =
        XGetWindowAttributes(si->dpy,wintemp,&window_attributes_return);

        if ((status) && (!window_attributes_return.override_redirect))
        {
           XFlush(si->dpy);
           XChangeWindowAttributes(si->dpy,wintemp,valuemask,&setwinattr);
           winatt_reset[j] = TRUE;
/*  AT_LOCK_DEBUG
fprintf(stderr,"Debug: ==> winatt_reset[%d] override_redirect needs to be 
reset\n",j);
*/
        }
        XMapSubwindows(si->dpy, wintemp);
        no_atserv++;
        at_win[no_atserv] = wintemp;
                } /* wintemp != 0 */
        }
      }
        /* common parent, i.e root win */

/* cases for running GOK , or MAG or GOK+MAG */
/* 6461887(P1) screen lock does not prevent access to other
**  applications via 'alt-tab',
** see 6519433 mem leaks in libgconf-2.so's gconf_client_get_default()
*/
        client = gconf_client_get_default();

        if (no_atserv > 0) {
        /* pop-up dialog in dock mode */
/* AT_LOCK_DEBUG
fprintf(stderr,"==> found dialog wid 0x%x\n", window);
*/
          XRestackWindows(si->dpy, at_win, no_atserv+1);
          XUngrabKeyboard(si->dpy, CurrentTime);
          XUngrabPointer(si->dpy, CurrentTime);
          si->at_external_passwd = True;
          XFlush(si->dpy);
          globalkey_text = gconf_client_get_string (client, \
        "/apps/metacity/global_keybindings/switch_windows", NULL);
          if (globalkey_text && strncmp(globalkey_text,"dis",3))
            gconf_client_set_string (client, \
        "/apps/metacity/global_keybindings/switch_windows", "disabled", NULL);
        }
        /* no MAG or GOK, only SPEECH is running
           just Ass. Tech support is selected
        */
        else if ((no_atserv == 0) && (at_enabled))
        {
                XUngrabKeyboard(si->dpy, CurrentTime);
                XUngrabPointer(si->dpy, CurrentTime);
                si->at_external_passwd = True;
                XFlush(si->dpy);
                globalkey_text = \
                  gconf_client_get_string(client, \
                  "/apps/metacity/global_keybindings/switch_windows", NULL);
                if ( globalkey_text && strncmp(globalkey_text,"dis",3))
                  gconf_client_set_string ( client, \
        "/apps/metacity/global_keybindings/switch_windows", "disabled", NULL);
/*
** 6736157 A11Y]Security problem when desktop a11y support is turned on
*/
                globalmenu_key = \
                  gconf_client_get_string(client, \
                  "/apps/metacity/global_keybindings/panel_main_menu",NULL);
                if ( globalmenu_key && strncmp(globalmenu_key,"dis",3))
                  gconf_client_set_string ( client, \
        "/apps/metacity/global_keybindings/panel_main_menu","disabled",NULL);
        }

/*  AT_LOCK_DEBUG
        fprintf(stderr,"debug no_atserv   0x%x\n", no_atserv);
        fprintf(stderr,"debug passwd win   0x%x\n", passwd_win);
        fprintf(stderr,"debug window   0x%x\n", window);
*/

      XSelectInput(si->dpy, passwd_win,KeyPressMask);
      XSetInputFocus (si->dpy, passwd_win,RevertToPointerRoot, CurrentTime);
      XSync (si->dpy, False);

      si->pw_data->got_windowid = True;
      si->passwd_dialog = window;
      /**g_passwd_dialog_created = True;**/ /*set global flag to check in 
timers.c*/
      if (si->prefs.verbose_p)
        fprintf (stderr, "<---handle_passwd_input(): gotwindowid:0x%x\n", 
passwd_win);
    }
}

/* returns successful fork/exec */
Bool
spawn_external_passwd_process (saver_info *si, passwd_dialog_data *pw)
{
  saver_preferences *p = &si->prefs;
  pid_t forked;
  const char *command = LOCKDIR "/xscreensaver-lock";
  int stdin_pipe[2]  = { -1, -1 };
  int stdout_pipe[2] = { -1, -1 };

  pw->stdin_fd = pw->stdout_fd = -1;
  pw->got_windowid = False;

  if (si->prefs.verbose_p)
     fprintf(stderr, "-->spawn_external_passwd()\n");
  if (si->passwd_pid>0) {
        if (si->prefs.verbose_p)
           fprintf(stderr,"pid %d still exists.  Killing it with SIGKILL\n",
                        si->passwd_pid);
        kill(si->passwd_pid,SIGKILL);
  }
  si->passwd_pid = 0;
  if (pipe (stdin_pipe) < 0)
   {
    perror ("pipe(stdin_pipe) failed!");
    return False;
   }

  if (pipe (stdout_pipe) < 0)
    {
      perror ("pipe(stdout_pipe) failed!");
      close_and_invalidate (&stdin_pipe[0]);
      close_and_invalidate (&stdin_pipe[1]);
      return False;
    }
  switch ((int) (forked = fork ()))
    {
    case -1:
      fprintf (stderr, "%s: ", blurb ());
      perror ("couldn't fork");

      close_and_invalidate (&stdin_pipe[0]);
      close_and_invalidate (&stdin_pipe[1]);
      close_and_invalidate (&stdout_pipe[0]);
      close_and_invalidate (&stdout_pipe[1]);

      return False;

    case 0:
      close (ConnectionNumber (si->dpy)); /* close display fd */
      /* limit_subproc_memory (p->inferior_memory_limit, p->verbose_p); */
      /* hack_subproc_environment (ssi); */ /* FIX $DISPLAY */

      /* Inside Child Process */
      if (p->verbose_p)
        fprintf (stderr, "%s: spawning \"%s\" in pid %lu.\n",
                 blurb(), command, (unsigned long) getpid ());

      close_and_invalidate (&stdin_pipe[1]);
      close_and_invalidate (&stdout_pipe[0]);

      sane_dup2 (stdin_pipe[0], 0);  /* Listen to Parent from here */
      sane_dup2 (stdout_pipe[1], 9); /* Talk to Parent from here */

      /* Make sure we have relinquished setuid privs or lock dialog gtk
       * program will not run as libgtk is not setuid safe.
       */
      hack_uid (si);

      exec_command (p->shell, command, 0);
      /* print_path_error (command); */
      fprintf (stderr, "%s: couldn't exec: %s\n",
               blurb (), command);
      abort ();

    default:
      /* In Parent */
      make_job(forked, 0, command);
      close_and_invalidate (&stdin_pipe[0]);
      close_and_invalidate (&stdout_pipe[1]);

      sane_dup2 (stdin_pipe[0], 0);  /* Listen to Child from here */
      sane_dup2 (stdout_pipe[1], 13); /* Talk to Child from here */

      pw->stdin_fd   = stdin_pipe[1];   /* Talk to child from here */
      pw->stdout_fd  = stdout_pipe[0];  /* Listen to Child from here */
      si->passwd_pid = forked;

      write_to_child (si, "Hello There"); /* Send a test message to Child */

      /* Password from child dialog comes through this pipe/fd */
      pw->input_file = fdopen (pw->stdout_fd, "r");

      pw->stdout_input_id = XtAppAddInput (si->app, pw->stdout_fd,
                                           (XtPointer) XtInputReadMask,
                                           handle_passwd_input,
                                           si);

      /* Set global flag to indicate that lock dialog is visible */
      g_passwd_dialog_created = True;
      return True;
    }

  /* shouldn't reach */
  abort ();
  return False;
}
#endif /* HAVE_XSCREENSAVER_LOCK */

void
make_passwd_window (saver_info *si)
{
  make_window(si, w_dialog);
}


static void
make_window (saver_info *si, enum window_type w_type)
{
  struct passwd *p = getpwuid (getuid ());
  XSetWindowAttributes attrs;
  unsigned long attrmask = 0;
  passwd_dialog_data *pw = si->pw_data;
  Screen *screen;
  Colormap cmap;
  char *f;
  saver_screen_info *ssi = &si->screens [mouse_screen (si)];

  if (si->prefs.verbose_p)
    fprintf(stderr, "-->make_window()\n");

#ifdef HAVE_XSCREENSAVER_LOCK
  if (spawn_external_passwd_process (si, si->pw_data))
    {
/***************
          if (si->prefs.verbose_p)
            fprintf(stderr, "spawning external passwd process in 
make_window()\n");
*******************/

/****************mali blank_fails remove this...
          if(!blank_screen(si))
            fprintf(stderr, "Failed to blank the screen\n");
*******************/

      si->pw_data->ratio = 1.0;
      si->pw_data->w_type = w_type;
      /*si->pw_data = pw;*/
      si->external_passwd = True;
      return;
    }
  si->external_passwd = False;
  si->at_external_passwd = False;
  /* FIXME: don't abort() */
  /*abort ();*/
#endif /* HAVE_XSCREENSAVER_LOCK */

  /* Display the button only if the "newLoginCommand" pref is non-null.
   */
  pw->login_button_p = (si->prefs.new_login_command &&
                        *si->prefs.new_login_command);

  if (pw->login_button_p)
    pw->passwd_cursor = XCreateFontCursor (si->dpy, XC_top_left_arrow);
  else
    pw->passwd_cursor = 0;

  pw->prompt_screen = ssi;
  if (si->prefs.verbose_p)
    fprintf (stderr, "%s: %d: creating password dialog.\n",
             blurb(), pw->prompt_screen->number);

  screen = pw->prompt_screen->screen;
  cmap = DefaultColormapOfScreen (screen);

  pw->w_type = w_type;
  pw->state = pw_read;
  pw->ratio = 1.0;

  pw->show_stars_p = get_boolean_resource(si->dpy, "passwd.asterisks", 
                                          "Boolean");
  
  pw->heading_label = get_string_resource (si->dpy, "passwd.heading.label",
                                           "Dialog.Label.Label");
  pw->body_label = get_string_resource (si->dpy, "passwd.body.label",
                                        "Dialog.Label.Label");
  pw->user_label = get_string_resource (si->dpy, "passwd.user.label",
                                        "Dialog.Label.Label");
  pw->passwd_label = get_string_resource (si->dpy, "passwd.passwd.label",
                                          "Dialog.Label.Label");
  pw->login_label = get_string_resource (si->dpy, "passwd.login.label",
                                         "Dialog.Button.Label");

  pw->date_label = get_string_resource (si->dpy, "dateFormat", "DateFormat");

  if (!pw->heading_label)
    pw->heading_label = strdup("ERROR: RESOURCES NOT INSTALLED CORRECTLY");
  if (!pw->body_label)
    pw->body_label = strdup("ERROR: RESOURCES NOT INSTALLED CORRECTLY");
  if (!pw->user_label) pw->user_label = strdup("ERROR");
  if (!pw->passwd_label) pw->passwd_label = strdup("ERROR");
  if (!pw->date_label) pw->date_label = strdup("ERROR");
  if (!pw->login_label) pw->login_label = strdup ("ERROR (LOGIN)") ;

  /* Put the version number in the label. */
  {
    char *s = (char *) malloc (strlen(pw->heading_label) + 20);
    sprintf(s, pw->heading_label, si->version);
    free (pw->heading_label);
    pw->heading_label = s;
  }

  /* Get hostname info */
  pw->uname_label = strdup(""); /* Initialy, write nothing */

# ifdef HAVE_UNAME
  {
    struct utsname uts;

    if (uname (&uts) == 0)
      {
#if 0 /* Get the full hostname */
        {
          char *s;
          if ((s = strchr(uts.nodename, '.')))
            *s = 0;
        }
#endif
        char *s = strdup (uts.nodename);
        free (pw->uname_label);
        pw->uname_label = s;
      }
  }
# endif

  f = get_string_resource (si->dpy, "passwd.headingFont", "Dialog.Font");
  pw->heading_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->heading_font) pw->heading_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource (si->dpy, "passwd.buttonFont", "Dialog.Font");
  pw->button_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->button_font) pw->button_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.bodyFont", "Dialog.Font");
  pw->body_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->body_font) pw->body_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.labelFont", "Dialog.Font");
  pw->label_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->label_font) pw->label_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.passwdFont", "Dialog.Font");
  pw->passwd_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->passwd_font) pw->passwd_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.dateFont", "Dialog.Font");
  pw->date_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->date_font) pw->date_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);

  f = get_string_resource(si->dpy, "passwd.unameFont", "Dialog.Font");
  pw->uname_font = XLoadQueryFont (si->dpy, (f ? f : "fixed"));
  if (!pw->uname_font) pw->uname_font = XLoadQueryFont (si->dpy, "fixed");
  if (f) free (f);
  
  pw->show_uname_p = get_boolean_resource(si->dpy, "passwd.uname", "Boolean");

  pw->foreground = get_pixel_resource (si->dpy, cmap,
                                       "passwd.foreground",
                                       "Dialog.Foreground" );
  pw->background = get_pixel_resource (si->dpy, cmap,
                                       "passwd.background",
                                       "Dialog.Background" );

  if (pw->foreground == pw->background)
    {
      /* Make sure the error messages show up. */
      pw->foreground = BlackPixelOfScreen (screen);
      pw->background = WhitePixelOfScreen (screen);
    }

  pw->passwd_foreground = get_pixel_resource (si->dpy, cmap,
                                              "passwd.text.foreground",
                                              "Dialog.Text.Foreground" );
  pw->passwd_background = get_pixel_resource (si->dpy, cmap,
                                              "passwd.text.background",
                                              "Dialog.Text.Background" );
  pw->button_foreground = get_pixel_resource (si->dpy, cmap, 
                                              "splash.Button.foreground",
                                              "Dialog.Button.Foreground" );
  pw->button_background = get_pixel_resource (si->dpy, cmap,
                                              "splash.Button.background",
                                              "Dialog.Button.Background" );
  pw->thermo_foreground = get_pixel_resource (si->dpy, cmap,
                                              "passwd.thermometer.foreground",
                                              "Dialog.Thermometer.Foreground" );
  pw->thermo_background = get_pixel_resource ( si->dpy, cmap,
                                              "passwd.thermometer.background",
                                              "Dialog.Thermometer.Background" );
  pw->shadow_top = get_pixel_resource ( si->dpy, cmap,
                                       "passwd.topShadowColor",
                                       "Dialog.Foreground" );
  pw->shadow_bottom = get_pixel_resource (si->dpy, cmap, 
                                          "passwd.bottomShadowColor",
                                          "Dialog.Background" );

  pw->logo_width = get_integer_resource (si->dpy, "passwd.logo.width",
                                         "Dialog.Logo.Width");
  pw->logo_height = get_integer_resource (si->dpy, "passwd.logo.height",
                                          "Dialog.Logo.Height");
  pw->thermo_width = get_integer_resource (si->dpy, "passwd.thermometer.width",
                                           "Dialog.Thermometer.Width");
  pw->internal_border = get_integer_resource (si->dpy, 
"passwd.internalBorderWidth",
                                              "Dialog.InternalBorderWidth");
  pw->shadow_width = get_integer_resource (si->dpy, "passwd.shadowThickness",
                                           "Dialog.ShadowThickness");

  if (pw->logo_width == 0)  pw->logo_width = 150;
  if (pw->logo_height == 0) pw->logo_height = 150;
  if (pw->internal_border == 0) pw->internal_border = 15;
  if (pw->shadow_width == 0) pw->shadow_width = 4;
  if (pw->thermo_width == 0) pw->thermo_width = pw->shadow_width;

  {
    int direction, ascent, descent;
    XCharStruct overall;

    pw->width = 0;
    pw->height = 0;

    /* Measure the heading_label. */
    XTextExtents (pw->heading_font,
                  pw->heading_label, strlen(pw->heading_label),
                  &direction, &ascent, &descent, &overall);
    if (overall.width > pw->width) pw->width = overall.width;
    pw->height += ascent + descent;

    /* Measure the uname_label. */
    if ((strlen(pw->uname_label)) && pw->show_uname_p)
      {
        XTextExtents (pw->uname_font,
                      pw->uname_label, strlen(pw->uname_label),
                      &direction, &ascent, &descent, &overall);
        if (overall.width > pw->width) pw->width = overall.width;
        pw->height += ascent + descent;
      }

    pw->width  += (pw->internal_border * 2);
    pw->height += (pw->internal_border * 4);

    pw->width += pw->thermo_width + (pw->shadow_width * 3);

    if (pw->logo_height > pw->height)
      pw->height = pw->logo_height;
    else if (pw->height > pw->logo_height)
      pw->logo_height = pw->height;

    pw->logo_width = pw->logo_height;

    pw->width += pw->logo_width;
  }

  attrmask |= CWOverrideRedirect; attrs.override_redirect = True;

  attrmask |= CWEventMask;
  attrs.event_mask = (ExposureMask | KeyPressMask |
                      ButtonPressMask | ButtonReleaseMask);

  /* We need to remember the mouse position and restore it afterward, or
     sometimes (perhaps only with Xinerama?) the mouse gets warped to
     inside the bounds of the lock dialog window.
   */
  {
    Window pointer_root, pointer_child;
    int root_x, root_y, win_x, win_y;
    unsigned int mask;
    pw->previous_mouse_x = 0;
    pw->previous_mouse_y = 0;
    if (XQueryPointer (si->dpy, RootWindowOfScreen (pw->prompt_screen->screen),
                       &pointer_root, &pointer_child,
                       &root_x, &root_y, &win_x, &win_y, &mask))
      {
        pw->previous_mouse_x = root_x;
        pw->previous_mouse_y = root_y;
        if (si->prefs.verbose_p)
          fprintf (stderr, "%s: %d: mouse is at %d,%d.\n",
                   blurb(), pw->prompt_screen->number,
                   pw->previous_mouse_x, pw->previous_mouse_y);
      }
    else if (si->prefs.verbose_p)
      fprintf (stderr, "%s: %d: unable to determine mouse position?\n",
               blurb(), pw->prompt_screen->number);
  }

  /* Figure out where on the desktop to place the window so that it will
     actually be visible; this takes into account virtual viewports as
     well as Xinerama. */
  {
    int x, y, w, h;
    get_screen_viewport (pw->prompt_screen, &x, &y, &w, &h,
                         pw->previous_mouse_x, pw->previous_mouse_y,
                         si->prefs.verbose_p);
    if (si->prefs.debug_p) w /= 2;
    pw->x = x + ((w + pw->width) / 2) - pw->width;
    pw->y = y + ((h + pw->height) / 2) - pw->height;
    if (pw->x < x) pw->x = x;
    if (pw->y < y) pw->y = y;
  }

  pw->border_width = get_integer_resource (si->dpy, "passwd.borderWidth",
                                           "Dialog.BorderWidth");

  si->passwd_dialog =
    XCreateWindow (si->dpy,
                   RootWindowOfScreen(screen),
                   pw->x, pw->y, pw->width, pw->height, pw->border_width,
                   DefaultDepthOfScreen (screen), InputOutput,
                   DefaultVisualOfScreen(screen),
                   attrmask, &attrs);
  XSetWindowBackground (si->dpy, si->passwd_dialog, pw->background);

  /* We use the default visual, not ssi->visual, so that the logo pixmap's
     visual matches that of the si->passwd_dialog window. */
  pw->logo_pixmap = xscreensaver_logo (ssi->screen,
                                       /* ssi->current_visual, */
                                       DefaultVisualOfScreen(screen),
                                       si->passwd_dialog, cmap,
                                       pw->background, 
                                       &pw->logo_pixels, &pw->logo_npixels,
                                       &pw->logo_clipmask, True);

  /* Before mapping the window, save the bits that are underneath the
     rectangle the window will occlude.  When we lower the window, we
     restore these bits.  This works, because the running screenhack
     has already been sent SIGSTOP, so we know nothing else is drawing
     right now! */
  {
    XGCValues gcv;
    GC gc;
    pw->save_under = XCreatePixmap (si->dpy,
                                    pw->prompt_screen->screensaver_window,
                                    pw->width + (pw->border_width*2) + 1,
                                    pw->height + (pw->border_width*2) + 1,
                                    pw->prompt_screen->current_depth);
    gcv.function = GXcopy;
    gc = XCreateGC (si->dpy, pw->save_under, GCFunction, &gcv);
    XCopyArea (si->dpy, pw->prompt_screen->screensaver_window,
               pw->save_under, gc,
               pw->x - pw->border_width, pw->y - pw->border_width,
               pw->width + (pw->border_width*2) + 1,
               pw->height + (pw->border_width*2) + 1,
               0, 0);
    XFreeGC (si->dpy, gc);
  }

  XMapRaised (si->dpy, si->passwd_dialog);
  XSync (si->dpy, False);

  move_mouse_grab (si, si->passwd_dialog,
                   (pw->passwd_cursor
                    ? pw->passwd_cursor
                    : pw->prompt_screen->cursor),
                   pw->prompt_screen->number);
  undo_vp_motion (si);

  /*mali si->pw_data = pw; */

  if (cmap)
    XInstallColormap (si->dpy, cmap);
  draw_passwd_window (si);
  XSync (si->dpy, False);
}


static void
draw_passwd_window (saver_info *si)
{
  passwd_dialog_data *pw = si->pw_data;
  XGCValues gcv;
  GC gc1, gc2;
  int spacing, height;
  int x1, x2, x3, y1, y2;
  int sw;
  int tb_height;


  if (si->prefs.verbose_p)
    fprintf (stderr, "-->draw_passwd_window() case w_dialog!!\n");

  height = (pw->heading_font->ascent + pw->heading_font->descent +
            pw->body_font->ascent + pw->body_font->descent +
            (2 * MAX ((pw->label_font->ascent + pw->label_font->descent),
                      (pw->passwd_font->ascent + pw->passwd_font->descent +
                       (pw->shadow_width * 4)))) +
            pw->date_font->ascent + pw->date_font->descent);

  if ((strlen(pw->uname_label)) && pw->show_uname_p)
    height += (pw->uname_font->ascent + pw->uname_font->descent); /* for uname 
*/

  if (pw->login_button_p)
    height += ((pw->button_font->ascent + pw->button_font->descent) * 2 +
               2 * pw->shadow_width);

  spacing = (((pw->height
               - ((pw->login_button_p ? 4 : 2) * pw->shadow_width)
               - pw->internal_border - height))
             / 8);

  if (spacing < 0) spacing = 0;

  gcv.foreground = pw->foreground;
  gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
  gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);
  x1 = pw->logo_width + pw->thermo_width + (pw->shadow_width * 3);
  x3 = pw->width - (pw->shadow_width * 2);
  y1 = (pw->shadow_width * 2) + spacing + spacing;

  /* top heading
   */
  XSetFont (si->dpy, gc1, pw->heading_font->fid);
  sw = string_width (pw->heading_font, pw->heading_label);
  x2 = (x1 + ((x3 - x1 - sw) / 2));
  y1 += spacing + pw->heading_font->ascent + pw->heading_font->descent;
  XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
               pw->heading_label, strlen(pw->heading_label));

  /* uname below top heading
   */
  if ((strlen(pw->uname_label)) && pw->show_uname_p)
    {
      XSetFont (si->dpy, gc1, pw->uname_font->fid);
      y1 += spacing + pw->uname_font->ascent + pw->uname_font->descent;
      sw = string_width (pw->uname_font, pw->uname_label);
      x2 = (x1 + ((x3 - x1 - sw) / 2));
      XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
                   pw->uname_label, strlen(pw->uname_label));
    }

  /* text below uname
   */
  XSetFont (si->dpy, gc1, pw->body_font->fid);
  y1 += spacing + pw->body_font->ascent + pw->body_font->descent;
  sw = string_width (pw->body_font, pw->body_label);
  x2 = (x1 + ((x3 - x1 - sw) / 2));
  XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1,
               pw->body_label, strlen(pw->body_label));


  tb_height = (pw->passwd_font->ascent + pw->passwd_font->descent +
               (pw->shadow_width * 4));

  /* the "User:" prompt
   */
  y1 += spacing;
  y2 = y1;
  XSetForeground (si->dpy, gc1, pw->foreground);
  XSetFont (si->dpy, gc1, pw->label_font->fid);
  y1 += (spacing + tb_height);
  x2 = (x1 + pw->internal_border +
        MAX(string_width (pw->label_font, pw->user_label),
            string_width (pw->label_font, pw->passwd_label)));
  XDrawString (si->dpy, si->passwd_dialog, gc1,
               x2 - string_width (pw->label_font, pw->user_label),
               y1 - pw->passwd_font->descent,
               pw->user_label, strlen(pw->user_label));

  /* the "Password:" prompt
   */
  y1 += (spacing + tb_height);
  XDrawString (si->dpy, si->passwd_dialog, gc1,
               x2 - string_width (pw->label_font, pw->passwd_label),
               y1 - pw->passwd_font->descent,
               pw->passwd_label, strlen(pw->passwd_label));


  XSetForeground (si->dpy, gc2, pw->passwd_background);

  /* the "user name" text field
   */
  y1 = y2;
  XSetForeground (si->dpy, gc1, pw->passwd_foreground);
  XSetFont (si->dpy, gc1, pw->passwd_font->fid);
  y1 += (spacing + tb_height);
  x2 += (pw->shadow_width * 4);

  pw->passwd_field_width = x3 - x2 - pw->internal_border;
  pw->passwd_field_height = (pw->passwd_font->ascent +
                             pw->passwd_font->descent +
                             pw->shadow_width);

  XFillRectangle (si->dpy, si->passwd_dialog, gc2,
                  x2 - pw->shadow_width,
                  y1 - (pw->passwd_font->ascent + pw->passwd_font->descent),
                  pw->passwd_field_width, pw->passwd_field_height);
  XDrawString (si->dpy, si->passwd_dialog, gc1,
               x2,
               y1 - pw->passwd_font->descent,
               pw->user_string, strlen(pw->user_string));

  /* the "password" text field
   */
  y1 += (spacing + tb_height);

  pw->passwd_field_x = x2 - pw->shadow_width;
  pw->passwd_field_y = y1 - (pw->passwd_font->ascent +
                             pw->passwd_font->descent);

  /* The shadow around the text fields
   */
  y1 = y2;
  y1 += (spacing + (pw->shadow_width * 3));
  x1 = x2 - (pw->shadow_width * 2);
  x2 = pw->passwd_field_width + (pw->shadow_width * 2);
  y2 = pw->passwd_field_height + (pw->shadow_width * 2);

  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         x1, y1, x2, y2,
                         pw->shadow_width,
                         pw->shadow_bottom, pw->shadow_top);

  y1 += (spacing + pw->passwd_font->ascent + pw->passwd_font->descent +
         (pw->shadow_width * 4));
  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         x1, y1, x2, y2,
                         pw->shadow_width,
                         pw->shadow_bottom, pw->shadow_top);


  /* The date, below the text fields
   */
  {
    char buf[100];
    time_t now = time ((time_t *) 0);
    struct tm *tm = localtime (&now);
    memset (buf, 0, sizeof(buf));
    strftime (buf, sizeof(buf)-1, pw->date_label, tm);

    XSetFont (si->dpy, gc1, pw->date_font->fid);
    y1 += pw->shadow_width;
    y1 += (spacing + tb_height);
    y1 += spacing/2;
    sw = string_width (pw->date_font, buf);
    x2 = x1 + x2 - sw;
    XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y1, buf, strlen(buf));
  }

  /* The "New Login" button
   */
  if (pw->login_button_p)
    {
      XSetForeground (si->dpy, gc1, pw->button_foreground);
      XSetForeground (si->dpy, gc2, pw->button_background);
      XSetFont (si->dpy, gc1, pw->button_font->fid);

      sw = string_width (pw->button_font, pw->login_label);

      x2 = pw->width - pw->internal_border - (pw->shadow_width * 2);

      /* right aligned button */
      /* x1 = x2 - pw->login_button_width;  */

      /* centered button */
      x1 = (pw->logo_width + pw->thermo_width + (pw->shadow_width * 3) +
            pw->internal_border);
      x1 = x1 + (x2 - x1 - pw->login_button_width) / 2;

      y1 = (pw->height - pw->internal_border - pw->login_button_height +
            spacing);
      y2 = (y1 +
            ((pw->login_button_height -
              (pw->button_font->ascent + pw->button_font->descent))
             / 2) +
            pw->button_font->ascent);

      pw->login_button_x = x1;
      pw->login_button_y = y1;
    }

  /* The logo
   */
  x1 = pw->shadow_width * 6;
  y1 = pw->shadow_width * 6;
  x2 = pw->logo_width - (pw->shadow_width * 12);
  y2 = pw->logo_height - (pw->shadow_width * 12);

  if (pw->logo_pixmap)
    {
      Window root;
      int x, y;
      unsigned int w, h, bw, d;
      XGetGeometry (si->dpy, pw->logo_pixmap, &root, &x, &y, &w, &h, &bw, &d);
      XSetForeground (si->dpy, gc1, pw->foreground);
      XSetBackground (si->dpy, gc1, pw->background);
      XSetClipMask (si->dpy, gc1, pw->logo_clipmask);
      XSetClipOrigin (si->dpy, gc1, x1 + ((x2 - (int)w) / 2), y1 + ((y2 - 
(int)h) / 2));
      if (d == 1)
        XCopyPlane (si->dpy, pw->logo_pixmap, si->passwd_dialog, gc1,
                    0, 0, w, h,
                    x1 + ((x2 - (int)w) / 2),
                    y1 + ((y2 - (int)h) / 2),
                    1);
      else
        XCopyArea (si->dpy, pw->logo_pixmap, si->passwd_dialog, gc1,
                   0, 0, w, h,
                   x1 + ((x2 - (int)w) / 2),
                   y1 + ((y2 - (int)h) / 2));
    }

  /* The thermometer
   */
  XSetForeground (si->dpy, gc1, pw->thermo_foreground);
  XSetForeground (si->dpy, gc2, pw->thermo_background);

  pw->thermo_field_x = pw->logo_width + pw->shadow_width;
  pw->thermo_field_y = pw->shadow_width * 5;
  pw->thermo_field_height = pw->height - (pw->shadow_width * 10);

#if 0
  /* Solid border inside the logo box. */
  XSetForeground (si->dpy, gc1, pw->foreground);
  XDrawRectangle (si->dpy, si->passwd_dialog, gc1, x1, y1, x2-1, y2-1);
#endif

  /* The shadow around the logo
   */
  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         pw->shadow_width * 4,
                         pw->shadow_width * 4,
                         pw->logo_width - (pw->shadow_width * 8),
                         pw->logo_height - (pw->shadow_width * 8),
                         pw->shadow_width,
                         pw->shadow_bottom, pw->shadow_top);

  /* The shadow around the thermometer
   */
  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         pw->logo_width,
                         pw->shadow_width * 4,
                         pw->thermo_width + (pw->shadow_width * 2),
                         pw->height - (pw->shadow_width * 8),
                         pw->shadow_width,
                         pw->shadow_bottom, pw->shadow_top);

#if 1
  /* Solid border inside the thermometer. */
  XSetForeground (si->dpy, gc1, pw->foreground);
  XDrawRectangle (si->dpy, si->passwd_dialog, gc1, 
                  pw->thermo_field_x, pw->thermo_field_y,
                  pw->thermo_width - 1, pw->thermo_field_height - 1);
#endif

  /* The shadow around the whole window
   */
  draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                         0, 0, pw->width, pw->height, pw->shadow_width,
                         pw->shadow_top, pw->shadow_bottom);

  XFreeGC (si->dpy, gc1);
  XFreeGC (si->dpy, gc2);

  update_passwd_window (si, pw->passwd_string, pw->ratio);
}


void
update_passwd_window (saver_info *si, const char *printed_passwd, float ratio)
{
  passwd_dialog_data *pw = si->pw_data;
  XGCValues gcv;
  GC gc1, gc2;
  int x, y;
  XRectangle rects[1];

  pw->ratio = ratio;

  if (si->prefs.verbose_p)
    fprintf (stderr, "-->update_passwd_window() w_dialog !!\n");

  if (!si->pw_data->got_windowid )
    {
      if (si->prefs.verbose_p)
        fprintf (stderr, "-->update_passwd_window() lockdialog not created 
returning.. !!\n");
      return;
    }

  gcv.foreground = pw->passwd_foreground;
  if (pw->passwd_font)
    gcv.font = pw->passwd_font->fid;
  gc1 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground|GCFont, &gcv);
  gcv.foreground = pw->passwd_background;
  gc2 = XCreateGC (si->dpy, si->passwd_dialog, GCForeground, &gcv);

  if (printed_passwd)
    {
      char *s = strdup (printed_passwd);
      if (pw->passwd_string) free (pw->passwd_string);
      pw->passwd_string = s;
    }

  /* the "password" text field
   */
  rects[0].x =  pw->passwd_field_x;
  rects[0].y =  pw->passwd_field_y;
  rects[0].width = pw->passwd_field_width;
  rects[0].height = pw->passwd_field_height;

  XFillRectangle (si->dpy, si->passwd_dialog, gc2,
                  rects[0].x, rects[0].y, rects[0].width, rects[0].height);

  XSetClipRectangles (si->dpy, gc1, 0, 0, rects, 1, Unsorted);

  XDrawString (si->dpy, si->passwd_dialog, gc1,
               rects[0].x + pw->shadow_width,
               rects[0].y + pw->passwd_font->ascent,
               pw->passwd_string, strlen(pw->passwd_string));

  XSetClipMask (si->dpy, gc1, None);

  /* The I-beam
   */
  if (pw->i_beam != 0)
    {
      x = (rects[0].x + pw->shadow_width +
           string_width (pw->passwd_font, pw->passwd_string));
      y = rects[0].y + pw->shadow_width;

      if (x > rects[0].x + rects[0].width - 1)
        x = rects[0].x + rects[0].width - 1;
      XDrawLine (si->dpy, si->passwd_dialog, gc1, 
                 x, y,
                 x, y + pw->passwd_font->ascent + pw->passwd_font->descent-1);
    }

  pw->i_beam = (pw->i_beam + 1) % 4;


  /* the thermometer
   */
  y = (pw->thermo_field_height - 2) * (1.0 - pw->ratio);
  if (y > 0)
    {
      XFillRectangle (si->dpy, si->passwd_dialog, gc2,
                      pw->thermo_field_x + 1,
                      pw->thermo_field_y + 1,
                      pw->thermo_width-2,
                      y);
      XSetForeground (si->dpy, gc1, pw->thermo_foreground);
      XFillRectangle (si->dpy, si->passwd_dialog, gc1,
                      pw->thermo_field_x + 1,
                      pw->thermo_field_y + 1 + y,
                      pw->thermo_width-2,
                      MAX (0, pw->thermo_field_height - y - 2));
    }

  /* The "New Login" button
   */
  if (pw->login_button_p)
    {
      int x2, y2, sw;
      XSetFont (si->dpy, gc1, pw->button_font->fid);
      XSetForeground (si->dpy, gc1,
                      (pw->login_button_enabled_p
                       ? pw->passwd_foreground
                       : pw->shadow_bottom));
      XSetForeground (si->dpy, gc2, pw->button_background);

      XFillRectangle (si->dpy, si->passwd_dialog, gc2,
                      pw->login_button_x, pw->login_button_y,
                      pw->login_button_width, pw->login_button_height);

      sw = string_width (pw->button_font, pw->login_label);
      x2 = pw->login_button_x + ((pw->login_button_width - sw) / 2);
      y2 = (pw->login_button_y +
            ((pw->login_button_height -
              (pw->button_font->ascent + pw->button_font->descent))
             / 2) +
            pw->button_font->ascent);

      XDrawString (si->dpy, si->passwd_dialog, gc1, x2, y2,
                   pw->login_label, strlen(pw->login_label));

      draw_shaded_rectangle (si->dpy, si->passwd_dialog,
                             pw->login_button_x, pw->login_button_y, 
                             pw->login_button_width, pw->login_button_height,
                             pw->shadow_width,
                             (pw->login_button_down_p
                              ? pw->shadow_bottom
                              : pw->shadow_top), 
                             (pw->login_button_down_p
                              ? pw->shadow_top
                              : pw->shadow_bottom));
    }

  XFreeGC (si->dpy, gc1);
  XFreeGC (si->dpy, gc2);
  XSync (si->dpy, False);
}


void
destroy_passwd_window (saver_info *si)
{
  saver_preferences *p = &si->prefs;
  passwd_dialog_data *pw = si->pw_data;
  saver_screen_info *ssi;
  Colormap cmap;
  Pixel black, white;
  XEvent event;
/* CR5083155 [Cinn Solaris]Unable to unlock screen when running dual-head MAG
*/
  int j;
  XSetWindowAttributes setwinattr;
  unsigned long valuemask = CWOverrideRedirect;
  XWindowChanges changes;
  setwinattr.override_redirect = FALSE;

  if (si->prefs.verbose_p)
    fprintf (stderr, "destroy_passwd_window\n");

  /*reset global flag to indicate passwd dialog is no longer there*/
  g_passwd_dialog_created = 0;

  if (pw == NULL || si->external_passwd == 0)
    return;

  if (pw->timer)
    XtRemoveTimeOut (pw->timer);


#ifdef HAVE_XSCREENSAVER_LOCK
  if (si->external_passwd)
    {
      /* kill the child etc. */

      if (si->passwd_dialog)
        {
          XErrorHandler old_handler;

          XSync (si->dpy, False);
          old_handler = XSetErrorHandler (ignore_all_errors_ehandler);

          XDestroyWindow (si->dpy, si->passwd_dialog);
          XSync (si->dpy, False);
          XSetErrorHandler (old_handler);

          si->passwd_dialog = 0;
        }

      if (pw->stdout_input_id)
        XtRemoveInput (pw->stdout_input_id);
      if (pw->stdin_fd != -1)
        close_and_invalidate (&pw->stdin_fd);
      if (pw->input_file)
        fclose (pw->input_file);
      else if (pw->stdout_fd != -1)
        close_and_invalidate (&pw->stdout_fd);

      if (si->passwd_pid)
        {
          kill_job (si, si->passwd_pid, SIGTERM);
          si->passwd_pid = 0;
        }

      si->external_passwd = False;
      si->at_external_passwd = False;
     }
  else
#endif /* HAVE_XSCREENSAVER_LOCK */
{
  if (p->verbose_p)
    fprintf (stderr, "In destroy_passwd else case..i.e. si->external-passwd is 
False already\n");

  memset (pw->typed_passwd, 0, sizeof(pw->typed_passwd));
  memset (pw->passwd_string, 0, strlen(pw->passwd_string));

  ssi = pw->prompt_screen;
  cmap = DefaultColormapOfScreen (ssi->screen);
  black = BlackPixelOfScreen (ssi->screen);
  white = WhitePixelOfScreen (ssi->screen);
  move_mouse_grab (si, RootWindowOfScreen (ssi->screen),
                   ssi->cursor, ssi->number);

  if (pw->passwd_cursor)
    XFreeCursor (si->dpy, pw->passwd_cursor);

  if (p->verbose_p)
    fprintf (stderr, "%s: %d: moving mouse back to %d,%d.\n",
             blurb(), ssi->number,
             pw->previous_mouse_x, pw->previous_mouse_y);

  XWarpPointer (si->dpy, None, RootWindowOfScreen (ssi->screen),
                0, 0, 0, 0,
                pw->previous_mouse_x, pw->previous_mouse_y);

  XSync (si->dpy, False);
  while (XCheckMaskEvent (si->dpy, PointerMotionMask, &event))
    if (p->verbose_p)
      fprintf (stderr, "%s: discarding MotionNotify event.\n", blurb());

  if (si->passwd_dialog)
    {
      XDestroyWindow (si->dpy, si->passwd_dialog);
      si->passwd_dialog = 0;
    }
  
  if (pw->save_under)
    {
      XGCValues gcv;
      GC gc;
      gcv.function = GXcopy;
      gc = XCreateGC (si->dpy, ssi->screensaver_window, GCFunction, &gcv);
      XCopyArea (si->dpy, pw->save_under,
                 ssi->screensaver_window, gc,
                 0, 0,
                 pw->width + (pw->border_width*2) + 1,
                 pw->height + (pw->border_width*2) + 1,
                 pw->x - pw->border_width, pw->y - pw->border_width);
      XFreePixmap (si->dpy, pw->save_under);
      pw->save_under = 0;
      XFreeGC (si->dpy, gc);
    }

  if (pw->heading_label) free (pw->heading_label);
  if (pw->body_label)    free (pw->body_label);
  if (pw->user_label)    free (pw->user_label);
  if (pw->passwd_label)  free (pw->passwd_label);
  if (pw->date_label)    free (pw->date_label);
  if (pw->login_label)   free (pw->login_label);
  if (pw->user_string)   free (pw->user_string);
  if (pw->passwd_string) free (pw->passwd_string);
  if (pw->uname_label)   free (pw->uname_label);

  if (pw->heading_font) XFreeFont (si->dpy, pw->heading_font);
  if (pw->body_font)    XFreeFont (si->dpy, pw->body_font);
  if (pw->label_font)   XFreeFont (si->dpy, pw->label_font);
  if (pw->passwd_font)  XFreeFont (si->dpy, pw->passwd_font);
  if (pw->date_font)    XFreeFont (si->dpy, pw->date_font);
  if (pw->button_font)  XFreeFont (si->dpy, pw->button_font);
  if (pw->uname_font)   XFreeFont (si->dpy, pw->uname_font);

  if (pw->foreground != black && pw->foreground != white)
    XFreeColors (si->dpy, cmap, &pw->foreground, 1, 0L);
  if (pw->background != black && pw->background != white)
    XFreeColors (si->dpy, cmap, &pw->background, 1, 0L);
  if (!(pw->button_foreground == black || pw->button_foreground == white))
    XFreeColors (si->dpy, cmap, &pw->button_foreground, 1, 0L);
  if (!(pw->button_background == black || pw->button_background == white))
    XFreeColors (si->dpy, cmap, &pw->button_background, 1, 0L);
  if (pw->passwd_foreground != black && pw->passwd_foreground != white)
    XFreeColors (si->dpy, cmap, &pw->passwd_foreground, 1, 0L);
  if (pw->passwd_background != black && pw->passwd_background != white)
    XFreeColors (si->dpy, cmap, &pw->passwd_background, 1, 0L);
  if (pw->thermo_foreground != black && pw->thermo_foreground != white)
    XFreeColors (si->dpy, cmap, &pw->thermo_foreground, 1, 0L);
  if (pw->thermo_background != black && pw->thermo_background != white)
    XFreeColors (si->dpy, cmap, &pw->thermo_background, 1, 0L);
  if (pw->shadow_top != black && pw->shadow_top != white)
    XFreeColors (si->dpy, cmap, &pw->shadow_top, 1, 0L);
  if (pw->shadow_bottom != black && pw->shadow_bottom != white)
    XFreeColors (si->dpy, cmap, &pw->shadow_bottom, 1, 0L);

  if (pw->logo_pixmap)
    XFreePixmap (si->dpy, pw->logo_pixmap);
  if (pw-> logo_clipmask)
    XFreePixmap (si->dpy, pw->logo_clipmask);
  if (pw->logo_pixels)
    {
      if (pw->logo_npixels)
        XFreeColors (si->dpy, cmap, pw->logo_pixels, pw->logo_npixels, 0L);
      free (pw->logo_pixels);
      pw->logo_pixels = 0;
      pw->logo_npixels = 0;
    }

  if (pw->save_under)
    XFreePixmap (si->dpy, pw->save_under);

  if (cmap)
    XInstallColormap (si->dpy, cmap);
}
  memset (pw, 0, sizeof(*pw));
/*** NO mali99 we only create a copy of pw in main and keep it
     so dont free it.
  free (pw);
  si->pw_data = 0;
  ************/

 for (j= 1; j < 3 ; j++)
 {
   if (winatt_reset[j-1] && at_win[j] )
   {
      XChangeWindowAttributes(si->dpy,at_win[j],valuemask,&setwinattr);
      winatt_reset[j-1] = FALSE;
      at_win[j] = 0;
/*fprintf(stderr, "DEBUG: at(%d) override_redirect set to FALSE\n", j);
*/
   }
 }
/*
** restore the prev one
** 6520014(P3) mem. leak in lock.c
*/
        if ( client && globalkey_text)
        gconf_client_set_string ( client, \
        "/apps/metacity/global_keybindings/switch_windows", \
        globalkey_text, NULL);
        g_free(globalkey_text);
        globalkey_text = NULL;
/*
** 6736157 A11Y]Security problem when desktop a11y support is turned on
*/
        if ( client && globalmenu_key)
        gconf_client_set_string ( client, \
        "/apps/metacity/global_keybindings/panel_main_menu", \
        globalmenu_key, NULL);
        g_free(globalmenu_key);
        globalmenu_key = NULL;

}


static Bool error_handler_hit_p = False;

static int
ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
{
  error_handler_hit_p = True;
  return 0;
}


#ifdef HAVE_XHPDISABLERESET
/* This function enables and disables the C-Sh-Reset hot-key, which
   normally resets the X server (logging out the logged-in user.)
   We don't want random people to be able to do that while the
   screen is locked.
 */
static void
hp_lock_reset (saver_info *si, Bool lock_p)
{
  static Bool hp_locked_p = False;

  /* Calls to XHPDisableReset and XHPEnableReset must be balanced,
     or BadAccess errors occur.  (It's ok for this to be global,
     since it affects the whole machine, not just the current screen.)
  */
  if (hp_locked_p == lock_p)
    return;

  if (lock_p)
    XHPDisableReset (si->dpy);
  else
    XHPEnableReset (si->dpy);
  hp_locked_p = lock_p;
}
#endif /* HAVE_XHPDISABLERESET */


#ifdef HAVE_XF86MISCSETGRABKEYSSTATE

/* This function enables and disables the Ctrl-Alt-KP_star and 
   Ctrl-Alt-KP_slash hot-keys, which (in XFree86 4.2) break any
   grabs and/or kill the grabbing client.  That would effectively
   unlock the screen, so we don't like that.

   The Ctrl-Alt-KP_star and Ctrl-Alt-KP_slash hot-keys only exist
   if AllowDeactivateGrabs and/or AllowClosedownGrabs are turned on
   in XF86Config.  I believe they are disabled by default.

   This does not affect any other keys (specifically Ctrl-Alt-BS or
   Ctrl-Alt-F1) but I wish it did.  Maybe it will someday.
 */
static void
xfree_lock_grab_smasher (saver_info *si, Bool lock_p)
{
  saver_preferences *p = &si->prefs;
  int status;
  int event, error;

  if (!XF86MiscQueryExtension(si->dpy, &event, &error))
    return;

  XErrorHandler old_handler;
  XSync (si->dpy, False);
  error_handler_hit_p = False;
  old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
  XSync (si->dpy, False);
  status = XF86MiscSetGrabKeysState (si->dpy, !lock_p);
  XSync (si->dpy, False);
  if (error_handler_hit_p) status = 666;

  if (!lock_p && status == MiscExtGrabStateAlready)
    status = MiscExtGrabStateSuccess;  /* shut up, consider this success */

  if (p->verbose_p && status != MiscExtGrabStateSuccess)
    fprintf (stderr, "%s: error: XF86MiscSetGrabKeysState(%d) returned %s\n",
             blurb(), !lock_p,
             (status == MiscExtGrabStateSuccess ? "MiscExtGrabStateSuccess" :
              status == MiscExtGrabStateLocked  ? "MiscExtGrabStateLocked"  :
              status == MiscExtGrabStateAlready ? "MiscExtGrabStateAlready" :
              status == 666 ? "an X error" :
              "unknown value"));

  XSync (si->dpy, False);
  XSetErrorHandler (old_handler);
  XSync (si->dpy, False);
}
#endif /* HAVE_XF86MISCSETGRABKEYSSTATE */



/* This function enables and disables the C-Alt-Plus and C-Alt-Minus
   hot-keys, which normally change the resolution of the X server.
   We don't want people to be able to switch the server resolution
   while the screen is locked, because if they switch to a higher
   resolution, it could cause part of the underlying desktop to become
   exposed.
 */
#ifdef HAVE_XF86VMODE

static void
xfree_lock_mode_switch (saver_info *si, Bool lock_p)
{
  static Bool any_mode_locked_p = False;
  saver_preferences *p = &si->prefs;
  int screen;
  int event, error;
  Bool status;
  XErrorHandler old_handler;

  if (any_mode_locked_p == lock_p)
    return;
  if (!XF86VidModeQueryExtension (si->dpy, &event, &error))
    return;

  for (screen = 0; screen < (si->xinerama_p ? 1 : si->nscreens); screen++)
    {
      XSync (si->dpy, False);
      old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
      error_handler_hit_p = False;
      status = XF86VidModeLockModeSwitch (si->dpy, screen, lock_p);
      XSync (si->dpy, False);
      XSetErrorHandler (old_handler);
      if (error_handler_hit_p) status = False;

      if (status)
        any_mode_locked_p = lock_p;

      if (!status && (p->verbose_p || !lock_p))
        /* Only print this when verbose, or when we locked but can't unlock.
           I tried printing this message whenever it comes up, but
           mode-locking always fails if DontZoom is set in XF86Config. */
        fprintf (stderr, "%s: %d: unable to %s mode switching!\n",
                 blurb(), screen, (lock_p ? "lock" : "unlock"));
      else if (p->verbose_p)
        fprintf (stderr, "%s: %d: %s mode switching.\n",
                 blurb(), screen, (lock_p ? "locked" : "unlocked"));
    }
}
#endif /* HAVE_XF86VMODE */


/* If the viewport has been scrolled since the screen was blanked,
   then scroll it back to where it belongs.  This function only exists
   to patch over a very brief race condition.
 */
static void
undo_vp_motion (saver_info *si)
{
#ifdef HAVE_XF86VMODE
  saver_preferences *p = &si->prefs;
  int screen;
  int event, error;

  if (!XF86VidModeQueryExtension (si->dpy, &event, &error))
    return;

  for (screen = 0; screen < si->nscreens; screen++)
    {
      saver_screen_info *ssi = &si->screens[screen];
      int x, y;
      Bool status;

      if (ssi->blank_vp_x == -1 && ssi->blank_vp_y == -1)
        break;
      if (!XF86VidModeGetViewPort (si->dpy, screen, &x, &y))
        return;
      if (ssi->blank_vp_x == x && ssi->blank_vp_y == y)
        return;
    
      /* We're going to move the viewport.  The mouse has just been grabbed on
         (and constrained to, thus warped to) the password window, so it is no
         longer near the edge of the screen.  However, wait a bit anyway, just
         to make sure the server drains its last motion event, so that the
         screen doesn't continue to scroll after we've reset the viewport.
       */
      XSync (si->dpy, False);
      usleep (250000);  /* 1/4 second */
      XSync (si->dpy, False);

      status = XF86VidModeSetViewPort (si->dpy, screen,
                                       ssi->blank_vp_x, ssi->blank_vp_y);

      if (!status)
        fprintf (stderr,
                 "%s: %d: unable to move vp from (%d,%d) back to (%d,%d)!\n",
                 blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y);
      else if (p->verbose_p)
        fprintf (stderr,
                 "%s: %d: vp moved to (%d,%d); moved it back to (%d,%d).\n",
                 blurb(), screen, x, y, ssi->blank_vp_x, ssi->blank_vp_y);
    }
#endif /* HAVE_XF86VMODE */
}



/* Interactions
 */

static void
passwd_animate_timer (XtPointer closure, XtIntervalId *id)
{
  saver_info *si = (saver_info *) closure;
  int tick = 166;
  passwd_dialog_data *pw = si->pw_data;

/*  if (si->prefs.verbose_p)
   fprintf (stderr,"-->passwd_animate_timer()\n");
**/

  /*We want to make sure dialog isup before we try to animate**/
  if (!si->external_passwd || !g_passwd_dialog_created)
   {
    if (si->prefs.verbose_p)
      fprintf (stderr,"-->passwd_animate_timer() returning..no dialog yet\n");
    return;
   }

  pw->ratio -= (1.0 / ((double) si->prefs.passwd_timeout / (double) tick));
  if (pw->ratio < 0)
    {
      pw->ratio = 0;
      if (pw->state == pw_read || pw->state == pw_null)
       {
        pw->state = pw_time;
       }
    }

/*** Communicating with the Child lock dialog...sending ratio back... mali99***/
#ifdef HAVE_XSCREENSAVER_LOCK
  if (si->passwd_dialog)
    {
      XEvent event;
      Bool status;
      XErrorHandler old_handler;

/*      fprintf (stderr,"-->passwd_animate_timer() sending ratio to child\n");
**/

      event.xany.type = ClientMessage;
      event.xclient.display = si->dpy;
      event.xclient.window = si->passwd_dialog;
      event.xclient.message_type = XA_UNLOCK_RATIO;
      event.xclient.format = 32;
      memset (&event.xclient.data, 0, sizeof (event.xclient.data));
      event.xclient.data.l[0] = (long)(pw->ratio * 100);
      event.xclient.data.l[1] = 0;
      event.xclient.data.l[2] = 0;

/* CR 6176524 passwdTimeoutEnable for disabled user */
      if (!si->prefs.pwd_p)
        event.xclient.data.l[1] = 1;

      XSync (si->dpy, False);
      old_handler = XSetErrorHandler (ignore_all_errors_ehandler);

      status = XSendEvent (si->dpy, si->passwd_dialog, False, 0L, &event);

      XSync (si->dpy, False);
      XSetErrorHandler (old_handler);

      if (!status)
        fprintf (stderr, "%s: error sending ratio to lock dialog\n", blurb ());

    }
#else /* !HAVE_XSCREENSAVER_LOCK */
  update_passwd_window (si, 0, pw->ratio);
#endif /* !HAVE_XSCREENSAVER_LOCK */

  if (pw->state == pw_read)
    pw->timer = XtAppAddTimeOut (si->app, tick, passwd_animate_timer,
                                 (XtPointer) si);
  else
    pw->timer = 0;

  idle_timer ((XtPointer) si, 0);
}


static XComposeStatus *compose_status;

static void
handle_passwd_button (saver_info *si, XEvent *event)
{
  saver_preferences *p = &si->prefs;
  Bool mouse_in_box = False;
  Bool hit_p = False;
  passwd_dialog_data *pw = si->pw_data;
  saver_screen_info *ssi = pw->prompt_screen;

  if (! pw->login_button_enabled_p)
    return;

  mouse_in_box = 
    (event->xbutton.x >= pw->login_button_x &&
     event->xbutton.x <= pw->login_button_x + pw->login_button_width &&
     event->xbutton.y >= pw->login_button_y &&
     event->xbutton.y <= pw->login_button_y + pw->login_button_height);

  if (ButtonRelease == event->xany.type &&
      pw->login_button_down_p &&
      mouse_in_box)
    {
      /* Only allow them to press the button once: don't want to
         accidentally launch a dozen gdm choosers if the machine
         is being slow.
       */
      hit_p = True;
      pw->login_button_enabled_p = False;
    }

  pw->login_button_down_p = (mouse_in_box &&
                             ButtonRelease != event->xany.type);

  update_passwd_window (si, 0, pw->ratio);

  if (hit_p)
    fork_and_exec (ssi, p->new_login_command);
}


static void
handle_passwd_key (saver_info *si, XKeyEvent *event)
{
  saver_preferences *p = &si->prefs;
  passwd_dialog_data *pw = si->pw_data;
  int pw_size = sizeof (pw->typed_passwd) - 1;
  char *typed_passwd = pw->typed_passwd;
  char s[2];
  char *stars = 0;
  int i;
  int size = XLookupString (event, s, 1, 0, compose_status);

  if (size != 1) return;

  s[1] = 0;

  /* Add 10% to the time remaining every time a key is pressed. */
  pw->ratio += 0.1;
  if (pw->ratio > 1) pw->ratio = 1;

  switch (*s)
    {
    case '\010': case '\177':                           /* Backspace */
      if (!*typed_passwd)
        XBell (si->dpy, 0);
      else
        typed_passwd [strlen(typed_passwd)-1] = 0;
      break;

    case '\025': case '\030':                           /* Erase line */
      memset (typed_passwd, 0, pw_size);
      break;

    case '\012': case '\015':                           /* Enter */
      if (pw->state != pw_read)
        ;  /* already done? */
      else if (typed_passwd[0] == 0)
        pw->state = pw_null;
      else
        {
          update_passwd_window (si, "Checking...", pw->ratio);
          XSync (si->dpy, False);

/***************mali99************************************************
          if (passwd_valid_p (typed_passwd, p->verbose_p, PAM_SERVICE))
            pw->state = pw_ok;
          else
            pw->state = pw_fail;
          update_passwd_window (si, "", pw->ratio);
****************************************************************************/
            pw->state = pw_ok;
        }
      break;

    default:
      /* Though technically the only illegal characters in Unix passwords
         are LF and NUL, most GUI programs (e.g., GDM) use regular text-entry
         fields that only let you type printable characters.  So, people
         who use funky characters in their passwords are already broken.
         We follow that precedent.
       */
      if (isprint ((unsigned char) *s))
        {
          i = strlen (typed_passwd);
          if (i >= pw_size-1)
            XBell (si->dpy, 0);
          else
            {
              typed_passwd [i] = *s;
              typed_passwd [i+1] = 0;
            }
        }
      else
        XBell (si->dpy, 0);
      break;
    }

  if (pw->show_stars_p)
    {
      i = strlen(typed_passwd);
      stars = (char *) malloc(i+1);
      memset (stars, '*', i);
      stars[i] = 0;
      update_passwd_window (si, stars, pw->ratio);
      free (stars);
    }
  else
    {
      update_passwd_window (si, "", pw->ratio);
    }
}

void XTSOLMakeTPWindow(Display *, Window);

void
passwd_event_loop (saver_info *si)
{
  saver_preferences *p = &si->prefs;
  char *msg = 0;
  XEvent event;
  unsigned int caps_p = 0;
  passwd_dialog_data *pw = si->pw_data;
  int ii;
   Window w;
  int mscreen;
  int status = -2;
  int counter = 0;
  int retries = 2;

  /*bugid 6580862 Unable to type in windows session with full screen mode when 
hotdesked...
    The issue is sunray connector grabs keyboard and focus is in connector 
window. When xscreensaver
    pastes the unlock dialog box the password typed by user goes into connector 
window.
    The following code attempts to set focus back in unlock dialog box. The 
connector is looking
    for focus out events to get a hint to let go of keyboard grab. Which is 
exactly what we try to
    do in the following code.
  */
  write_to_child (si, "pw_read");
  mscreen = mouse_screen (si);
  w = RootWindowOfScreen(si->screens[mscreen].screen);
  /* grab_kbd() uses GrabModeSync which is holding up pointer events and hence 
unlcok
   * dialog box does not show up when you move mouse, only when you hit a key.
   * So, we locally call XGrabKeyboard() with GrabModeAsync instead of calling 
grab_kbd().
   * status = grab_kbd(si, w, mscreen);
   **/
  status = XGrabKeyboard (si->dpy, w, True,
                          GrabModeAsync, GrabModeAsync,
                          CurrentTime);

  XSync (si->dpy, False);
  while (status != GrabSuccess && counter++ <=retries)
   {
    status = XGrabKeyboard (si->dpy, w, True,
                            GrabModeAsync, GrabModeAsync,
                            CurrentTime);
    write_to_child (si, "pw_read");
    usleep (250000); /** 1/4 second */
    XSync (si->dpy, False);
    XTSOLMakeTPWindow(si->dpy,w);
    if(p->verbose_p)
      fprintf (stderr, "event loop..trying to grab keyboard######\n");
   }

  if (status == GrabSuccess)
    {
      si->keyboard_grab_window = w;
      si->keyboard_grab_screen = mscreen;
    }

/* bugid 6176524 passwdTimeout and reset timer for each key press  */
  passwd_animate_timer ((XtPointer) si, 0);

  while (si->pw_data && si->pw_data->state == pw_read)
    {
      XtAppNextEvent (si->app, &event);
#ifdef HAVE_RANDR
        /*
         * 6757448 xscreensaver doesn't notice XRandR resize events.
         */
        if (event.type == (si->randr_event_number + RRScreenChangeNotify))
          {
            /* The Resize and Rotate extension sends an event when the
               size, rotation, or refresh rate of the screen has changed. */

            XRRScreenChangeNotifyEvent *xrr_event =
              (XRRScreenChangeNotifyEvent *) &event;
            /* XRRRootToScreen is in Xrandr.h 1.4, 2001/06/07 */
            int screen = XRRRootToScreen (si->dpy, xrr_event->window);

            if (p->verbose_p)
              {
                if (si->screens[screen].width  == xrr_event->width &&
                    si->screens[screen].height == xrr_event->height)
                  fprintf (stderr,
                          "%s: %d: no-op screen size change event (%dx%d)\n",
                           blurb(), screen,
                           xrr_event->width, xrr_event->height);
                else
                  fprintf (stderr,
                       "%s: %d: screen size changed from %dx%d to %dx%d\n",
                           blurb(), screen,
                           si->screens[screen].width,
                           si->screens[screen].height,
                           xrr_event->width, xrr_event->height);
              }

# ifdef RRScreenChangeNotifyMask
            /* Inform Xlib that it's ok to update its data structures. */
            XRRUpdateConfiguration (&event); /* Xrandr.h 1.9, 2002/09/29 */
# endif /* RRScreenChangeNotifyMask */
            /* Resize the existing xscreensaver windows and cached ssi data. */
            resize_screensaver_window (si);
          }
#endif /* HAVE_RANDR */

#ifdef HAVE_XSCREENSAVER_LOCK
      if (event.xany.type == KeyPress)
        {
          if (si->pw_data->got_windowid)
            {
              Bool status,pwd_status;
              XErrorHandler old_handler;

              if(p->verbose_p)
               fprintf (stderr, "event loop..gotwindowid..and keypress 
event...\n");

               event.xany.window = si->passwd_dialog;

              XSync (si->dpy, False);
              old_handler = XSetErrorHandler (ignore_all_errors_ehandler);

              status =
        XSendEvent (si->dpy, si->passwd_dialog, False, KeyPressMask, &event);
              XSync (si->dpy, False);
              XSetErrorHandler (old_handler);

/* CR 6176524 passwdTimeoutEnable for disabled user
   timer will be reset if 4 conditions art true (for each char of pwd)
   (status) && (p->pwd_p) && (at_enabled) && (pw->timer)
   However AT group wants to remove at_enabled
   i.e reset the password timer for each key for all users
   * 6240938 screensaver-lock's password timer needs to to be reset
        for each key (all users) and enabling AT support
*/

        if ((status) && (p->pwd_p)  && (pw->timer)) {
        XtRemoveTimeOut (pw->timer);
        pw->ratio = 1.0;
        pw->timer = XtAppAddTimeOut (si->app, 166, passwd_animate_timer,
                                 (XtPointer) si);
        }

              if (p->verbose_p)
                {
                  if (status)
                    fprintf (stderr, "sent key...\n");
                  else
                    fprintf (stderr, "error sending key...\n");
                }
            }
          else
            {
              if (p->verbose_p)
                fprintf (stderr, "got keypress but no window id yet :(\n");
              XtDispatchEvent (&event);
            }
        }

#else /* !HAVE_XSCREENSAVER_LOCK */
      if (event.xany.window == si->passwd_dialog && event.xany.type == Expose)
        draw_passwd_window (si);
      else if (event.xany.type == KeyPress)
        {
          handle_passwd_key (si, &event.xkey);
          caps_p = (event.xkey.state & LockMask);
        }
      else if ((event.xany.type == ButtonPress || 
                event.xany.type == ButtonRelease) && 
               si->pw_data->login_button_p)
        handle_passwd_button (si, &event);
#endif /* !HAVE_XSCREENSAVER_LOCK */
      else if (event.xany.window == si->passwd_dialog && event.xany.type == 
Expose &&
               si->pw_data->passwd_label != NULL)
       {
          if(p->verbose_p)
            fprintf (stderr, "event loop...and expose event.should update lock 
with new label...\n");
          /***if (si->pw_data->passwd_label)**/
          update_passwd_window (si, si->pw_data->passwd_label, pw->ratio);
          free (si->pw_data->passwd_label);
          si->pw_data->passwd_label = 0;
          si->pw_data->state = pw_read;
       }

 /*
* 5077974 P1 "Bug 147583: Screen Lock unlocks because of GOK dwell movement in
              core pointer mode"
*
* ScreenLock did not unlock the screen, but WM's XRestackWindow() did.
* Once WM/metacity fixes the problem, the code can be removed.
  The problem:
  repositioning the Wids in the wrong positions when
  1. the window type is changed from NORMAL to DOCK or vice versa
  2. the Wid is managed
  within the X window stack with or without screen-lock in a mixed Wids
  there are two temp. get-around solutions:
  1. non-managed GOK or MAG Wid
  or
  2. screensaver picks up the WM's restacking task and fixes the prevous
     restacking problem.
     the cons: there is a flashing screen when corepointer is touching
     GOK or MAG and mouse is moved in a fast way
     when GOK or MAG window type is DOCK only.
     and it is not a good temp. get-around solution.
     This is the only choice if WM did not want to fix the problem now
     and AT group did not want to use non-managed Wids.
     Now, GOK only supports 2nd USB/mouse/Dwell, corepointer is supposed
     not to be used, and GOK cannot disable it
*/
/*
     bugid 6769901,6839026: popup windows appearing through xscreensaver
     Also this routine is to stop the popup window when a11y is on also when 
a11y is not on.
     Note: when a11y is on no_atserv > 0 
*/

else if (((event.type == UnmapNotify)
                || (event.type == MapNotify )
                || (event.type == VisibilityNotify)
                || (event.type == ConfigureNotify)
                || (event.type == PropertyNotify )
                || (event.type == CreateNotify)
                || (event.type == ReparentNotify ))
                && (si->passwd_dialog) )
        {
/* AT_LOCK_DEBUG
fprintf (stderr, "client window(0x%x) %s\n", event.xclient.window,blurb());
fprintf (stderr, "dialog window 0x%x:\n", si->passwd_dialog);
fprintf(stderr, "** no_atserv: %d \n", no_atserv);
for (ii = 0; ii < 4;  ii++)
         fprintf(stderr, "** win : 0x%x \n", at_win[ii]);
*/
         
         /* this if case is for safety,it prevent screensaver stuck in loop of 
ConfigureNotify */
         if(event.xany.window && (event.xany.window != 
si->screens[0].screensaver_window) && (event.xany.window != si->passwd_dialog
))
         {
            /* find the handle of popup window */
            /* Note: we can not get handle of popup window with 
event.xany.window, thats why we have switch cases. */
             Window wPopWin =0;
             switch(event.type)
             {
                case ConfigureNotify:
                wPopWin = event.xconfigure.window;
                break;
                case CreateNotify:
                wPopWin = event.xcreatewindow.window;
                break;
                case VisibilityNotify: 
                wPopWin = event.xvisibility.window;
                break;
                default:
                break;
             }  


             /* Array at_win stores password and screensaver window, also MAG 
and/or GOK if a11y is on 
             /* if any window apart from password, MAG ,GOK or screensaver 
comes over is considered as popup window. */
             /* If it is not popup window but password, MAG, GOK, or 
screensaver window then nWin < no_atserv+2 */ 
             /* If it is popup window then nWin == no_atserv+2 */ 
             int nWin =0;
             if(wPopWin) // check if it is really a popup window
                for(;nWin < no_atserv+2 ; ++nWin)
                {
                   if(at_win[nWin]==wPopWin)
                   break;
                }

             /* Do restacking if it is popup window ie nWin == no_atserv+2 */
             /* Also do restacking when a11y is on */
             if( nWin== no_atserv+2 ||no_atserv ) 
             {

                /* at_win[0] -> passwordwindow */
                /* at_win[1-2]-> if a11y on, may GOK or MAG */

                at_win[no_atserv+1] = si->screens[0].screensaver_window;
                if(nWin== no_atserv+2)
                { 
                   /* store popup window in array of at_win to restack it */
                   at_win[no_atserv+2] = wPopWin;
                   XRestackWindows(si->dpy, at_win,no_atserv+3);
                }
                else
                {
                   XRestackWindows(si->dpy, at_win,no_atserv+2);
                }
                XFlush(si->dpy);
             }
          }

        }
/* the above new code for restacking under the conidtion
*/
      else
        {
/*
         if ((si->passwd_dialog) && (no_atserv) && (event.type != 0))
         fprintf(stderr, "** DEbug other event %d\n", event.type);
*/
        XtDispatchEvent (&event);
        }

    }

  switch (si->pw_data->state)
    {
    case pw_ok:   msg = strdup("pw_ok"); break;
    case pw_null: msg = strdup("pw_null"); break;
    case pw_time: msg = strdup("pw_time"); break;
    case pw_read: msg = strdup("pw_read"); break;
    case pw_fail: msg = strdup("pw_fail"); break;
    case pw_cancel: msg = strdup("pw_cancel"); break;
    default:      msg = 0;
        fprintf(stderr, "si->pw_data->state is bad, serious error\n");
        break;
    }

  if (si->pw_data->state == pw_fail)
    si->unlock_failures++;

  if (p->verbose_p)
    switch (si->pw_data->state)
      {
      case pw_ok:
       {
        fprintf (stderr, "%s: password correct.\n", blurb());
        fprintf (stderr, "%s: setting state to be null.\n", blurb());
        si->pw_data->state = pw_null;
        break;
       }
      case pw_fail:
        fprintf (stderr, "%s: password incorrect!%s\n", blurb(),
                 (caps_p ? "  (CapsLock)" : ""));
        break;
      case pw_null:
      case pw_cancel:
        fprintf (stderr, "%s: password entry cancelled.\n", blurb()); break;
      case pw_time:
        fprintf (stderr, "%s: password entry timed out.\n", blurb()); break;
      default:
        break;
      }

#ifdef HAVE_SYSLOG
  if (si->pw_data->state == pw_fail)
    {
      /* If they typed a password (as opposed to just hitting return) and
         the password was invalid, log it.
      */
      struct passwd *pw = getpwuid (getuid ());
      char *d = DisplayString (si->dpy);
      char *u = (pw->pw_name ? pw->pw_name : "???");
      int opt = 0;
      int fac = 0;

# ifdef LOG_PID
      opt = LOG_PID;
# endif

# if defined(LOG_AUTHPRIV)
      fac = LOG_AUTHPRIV;
# elif defined(LOG_AUTH)
      fac = LOG_AUTH;
# else
      fac = LOG_DAEMON;
# endif

      if (!d) d = "";
      openlog (progname, opt, fac);
      syslog (LOG_NOTICE, "FAILED LOGIN %d ON DISPLAY \"%s\", FOR \"%s\"",
              si->unlock_failures, d, u);
      closelog ();
    }
#endif /* HAVE_SYSLOG */

  if (si->pw_data->state == pw_fail)
    XBell (si->dpy, False);

  if (si->pw_data->state == pw_ok && si->unlock_failures != 0)
    {
      if (si->unlock_failures == 1)
        fprintf (real_stderr,
                 "%s: WARNING: 1 failed attempt to unlock the screen.\n",
                 blurb());
      else
        fprintf (real_stderr,
                 "%s: WARNING: %d failed attempts to unlock the screen.\n",
                 blurb(), si->unlock_failures);

      si->unlock_failures = 0;
    }

  if (msg)
    {
          if (p->verbose_p)
            {
              fprintf (stderr, "..eventloop...msg is:%s\n",msg);
            }
#ifdef HAVE_XSCREENSAVER_LOCK
    /* DONT NEED TO SEND ANY INFO TO CHILD AT THIS STAGE */
    /*  if (write_to_child (si, msg));**/ /*if write is successful do nothing*/
      free(msg);

      /*********************************************************
      if (si->external_passwd && si->pw_data->stdin_fd != -1)
        {
          ssize_t len;
          char *nlmsg;

          nlmsg = (char *)malloc (strlen (msg) + 2);
          sprintf (nlmsg, "%s\n", msg);

          if (p->verbose_p)
            {
              fprintf (stderr, 
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
              fprintf (stderr, "HAVE_SCRSVR_LOCK message is:%s writing to 
fd:%d\n",
                                   msg, si->pw_data->stdin_fd);
              fprintf (stderr, 
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
            }

        write_msg:
          len = write (si->pw_data->stdin_fd, nlmsg, strlen (nlmsg));
          if (len < 0 && errno == EINTR)
            goto write_msg;

          free (nlmsg);
        }
      else
      
******************************************************************************/
#endif /* HAVE_XSCREENSAVER_LOCK */
/************
    {
      si->pw_data->i_beam = 0;
      update_passwd_window (si, msg, 0.0);
    }
************/

      XSync (si->dpy, False);
      usleep (250000);  /* 1/4 second */

      /* Swallow all pending KeyPress/KeyRelease events. */
      {
        XEvent e;
        while (XCheckMaskEvent (si->dpy, KeyPressMask|KeyReleaseMask, &e))
          ;
      }
    }
}


void
handle_typeahead (saver_info *si)
{
  passwd_dialog_data *pw = si->pw_data;
  int i;
  if (!si->unlock_typeahead)
    return;

  i = strlen (si->unlock_typeahead);
  if (i >= sizeof(pw->typed_passwd) - 1)
    i = sizeof(pw->typed_passwd) - 1;

  memcpy (pw->typed_passwd, si->unlock_typeahead, i);
  pw->typed_passwd [i] = 0;

  memset (si->unlock_typeahead, '*', strlen(si->unlock_typeahead));
  si->unlock_typeahead[i] = 0;
#ifdef HAVE_XSCREENSAVER_LOCK
  /* FIXME: bugzilla.gnome.org #77077 */
  /* need to handle this in the external dialog case */

#else
  update_passwd_window (si, si->unlock_typeahead, pw->ratio);
#endif /* !HAVE_XSCREENSAVER_LOCK */

  free (si->unlock_typeahead);
  si->unlock_typeahead = 0;
}


Bool
unlock_p (saver_info *si)
{
  saver_preferences *p = &si->prefs;
  Bool status;

  raise_window (si, True, True, True);

  if (p->verbose_p)
    fprintf (stderr, "%s: -->unlock_p()\n", blurb());

/*******mali99**/
  if (si->pw_data || si->passwd_dialog)
    destroy_passwd_window (si);

  make_passwd_window (si);
/****mali99*********/

  compose_status = calloc (1, sizeof (*compose_status));

  handle_typeahead (si);
  passwd_event_loop (si);

  status = (si->pw_data->state == pw_ok);

  destroy_passwd_window (si);

  free (compose_status);
  compose_status = 0;

  return status;
}


void
set_locked_p (saver_info *si, Bool locked_p)
{
  si->locked_p = locked_p;

#ifdef HAVE_XHPDISABLERESET
  hp_lock_reset (si, locked_p);                 /* turn off/on C-Sh-Reset */
#endif
#ifdef HAVE_XF86VMODE
  xfree_lock_mode_switch (si, locked_p);        /* turn off/on C-Alt-Plus */
#endif
#ifdef HAVE_XF86MISCSETGRABKEYSSTATE
  xfree_lock_grab_smasher (si, locked_p);       /* turn off/on C-Alt-KP-*,/ */
#endif

  store_saver_status (si);                      /* store locked-p */
}


#else  /*  NO_LOCKING -- whole file */

void
set_locked_p (saver_info *si, Bool locked_p)
{
  if (locked_p) abort();
}

#endif /* !NO_LOCKING */


/*******mali99**/
  if (si->pw_data || si->passwd_dialog)
    destroy_passwd_window (si);

  make_passwd_window (si);
/****mali99*********/

  compose_status = calloc (1, sizeof (*compose_status));

  handle_typeahead (si);
  passwd_event_loop (si);

  status = (si->pw_data->state == pw_ok);

  destroy_passwd_window (si);

  free (compose_status);
  compose_status = 0;

  return status;
}


void
set_locked_p (saver_info *si, Bool locked_p)
{
  si->locked_p = locked_p;

#ifdef HAVE_XHPDISABLERESET
  hp_lock_reset (si, locked_p);                 /* turn off/on C-Sh-Reset */
#endif
#ifdef HAVE_XF86VMODE
  xfree_lock_mode_switch (si, locked_p);        /* turn off/on C-Alt-Plus */
#endif
#ifdef HAVE_XF86MISCSETGRABKEYSSTATE
  xfree_lock_grab_smasher (si, locked_p);       /* turn off/on C-Alt-KP-*,/ */
#endif

  store_saver_status (si);                      /* store locked-p */
}


#else  /*  NO_LOCKING -- whole file */

void
set_locked_p (saver_info *si, Bool locked_p)
{
  if (locked_p) abort();
}

#endif /* !NO_LOCKING */


++                break;
++                case VisibilityNotify:
++                wPopWin = event.xvisibility.window;
++                break;
++                default:
++                break;
++             }
++
++
++             /* Array at_win stores password and screensaver window, 
also MAG and/or GOK if a11y is on
++             /* if any window apart from password, MAG ,GOK or 
screensaver comes over is considered as popup window. */
++             /* If it is not popup window but password, MAG, GOK, or 
screensaver window t hen nWin < no_atserv+2 */
++             /* If it is popup window then nWin == no_atserv+2 */
++             int nWin =0;
++             if(wPopWin) // check if it is really a popup window
++                for(;nWin < no_atserv+2 ; ++nWin)
++                {
++                   if(at_win[nWin]==wPopWin)
++                   break;
++                }
++
++           /* Do restacking if it is popup window ie nWin == 
no_atserv+2 */
++             /* Also do restacking when a11y is on */
++             if( nWin== no_atserv+2 ||no_atserv )
++             {
++
++                /* at_win[0] -> passwordwindow */
++                /* at_win[1-2]-> if a11y on, may GOK or MAG */
++
++                at_win[no_atserv+1] = si->screens[0].screensaver_window;
++                if(nWin== no_atserv+2)
++                {
++                   /* store popup window in array of at_win to restack 
it */
++                   at_win[no_atserv+2] = wPopWin;
++                   XRestackWindows(si->dpy, at_win,no_atserv+3);
++                }
++                else
++                {
++                   XRestackWindows(si->dpy, at_win,no_atserv+2);
++                }
++                XFlush(si->dpy);
++             }
++          }
++
+         }
+ /* the above new code for restacking under the conidtion
+ */
Index: SUNWxscreensaver.spec
===================================================================
--- SUNWxscreensaver.spec       (revision 19180)
+++ SUNWxscreensaver.spec       (working copy)
@@ -149,6 +149,8 @@
 Patch46: xscreensaver-46-bug-6857559.diff
 # date:2009-07-31 owner:bp230705 type:bug bugster:6859039
 Patch47: xscreensaver-47-bug-6859039.diff
+# date:2009-09-10 owner:au230626 type:bug bugster:6839026
+Patch48: xscreensaver-48-bug-6839026.diff

 # date:2008-03-07 owner:alanc type:branding
 Patch101: rss-glx-101-matrixview.diff
@@ -327,6 +329,7 @@
 %patch45 -p1
 %patch46 -p1
 %patch47 -p1
+%patch48 -p1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: lock.c
Type: text/x-csrc
Size: 79111 bytes
Desc: not available
URL: 
<http://mail.opensolaris.org/pipermail/jds-review/attachments/20090911/8a5b4f65/attachment.bin>

Reply via email to