summaryrefslogtreecommitdiff
authorsandman <sandman>2002-07-27 22:43:37 (UTC)
committer sandman <sandman>2002-07-27 22:43:37 (UTC)
commitdac5c073c3e04ceb6900aeb72e53cf6d7350c3c9 (patch) (side-by-side diff)
treed8c522214a94a437ccd5339957ca64ac4779755c
parent9e728b734630d08ec5ee3ff695d1b66995a6d7c7 (diff)
downloadopie-dac5c073c3e04ceb6900aeb72e53cf6d7350c3c9.zip
opie-dac5c073c3e04ceb6900aeb72e53cf6d7350c3c9.tar.gz
opie-dac5c073c3e04ceb6900aeb72e53cf6d7350c3c9.tar.bz2
Initial checkin of the new opie-login
Just replace $OPIEDIR/bin/qpe with $OPIEDIR/bin/opie-login in /etc/init.d/opie
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/opie-login/loginwindow.ui396
-rw-r--r--core/opie-login/loginwindowimpl.cpp323
-rw-r--r--core/opie-login/loginwindowimpl.h33
-rw-r--r--core/opie-login/main.cpp178
-rw-r--r--core/opie-login/opie-login.pro25
5 files changed, 955 insertions, 0 deletions
diff --git a/core/opie-login/loginwindow.ui b/core/opie-login/loginwindow.ui
new file mode 100644
index 0000000..86d5469
--- a/dev/null
+++ b/core/opie-login/loginwindow.ui
@@ -0,0 +1,396 @@
+<!DOCTYPE UI><UI>
+<class>LoginWindow</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>LoginWindow</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>472</width>
+ <height>341</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Login</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout7</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>4</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>m_caption</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>backgroundOrigin</name>
+ <enum>ParentOrigin</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;center&gt;&lt;h1&gt;Welcome to OPIE&lt;/h1&gt;&lt;/center&gt;</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout6</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>4</number>
+ </property>
+ <widget row="0" column="1" >
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>m_user</cstring>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoCompletion</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>backgroundOrigin</name>
+ <enum>ParentOrigin</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>User</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout5</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>4</number>
+ </property>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>m_password</cstring>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>echoMode</name>
+ <enum>Password</enum>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ToolButton3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image0</pixmap>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ToolButton1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image1</pixmap>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>backgroundOrigin</name>
+ <enum>ParentOrigin</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Password</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget>
+ <class>Line</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Line1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>4</number>
+ </property>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>m_login</cstring>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Login</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>m_suspend</cstring>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Suspend</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>m_menu</cstring>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Menu</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QFrame</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>m_taskbar</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Raised</enum>
+ </property>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="394">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022230543251d2e253d856405bffcbc54105b19c856360003b0141a808a2983b03284848a298304c108240e15033141045829580cac07ac4e590f5d0c22a4876caf32d45898797a48044caf32c22948e629c39d0457a78ce60f65b8f104ec50d6c366af1e865eb4b0aab5e602008bcd444d</data>
+ </image>
+ <image>
+ <name>image1</name>
+ <data format="XPM.GZ" length="341">789c558fcd0a02310c84ef7d8ad0b915c9bae84d7c04c5a3201e4275d1c32ab8eb41c477b73fa96e43a1f30d4d266d1ced771b728d194619af9efc451ee44ecfbe7f1d8eebb7b1ed92c259506b67c63279dade6fe7a81134e6a9224ac4ae2bc85565075004901c8820731069a648b490effc26eac4a25dcc195373c94231b87a8349fabf894b7a3d27a76af8cf01eb0e534757d70da1bf8a933f2bf30509e84b68</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>ToolButton1</sender>
+ <signal>clicked()</signal>
+ <receiver>m_password</receiver>
+ <slot>clear()</slot>
+ </connection>
+ <connection>
+ <sender>ToolButton3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>LoginWindow</receiver>
+ <slot>toggleEchoMode(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_suspend</sender>
+ <signal>clicked()</signal>
+ <receiver>LoginWindow</receiver>
+ <slot>suspend()</slot>
+ </connection>
+ <connection>
+ <sender>m_password</sender>
+ <signal>returnPressed()</signal>
+ <receiver>m_login</receiver>
+ <slot>animateClick()</slot>
+ </connection>
+ <connection>
+ <sender>m_login</sender>
+ <signal>clicked()</signal>
+ <receiver>LoginWindow</receiver>
+ <slot>login()</slot>
+ </connection>
+ <slot access="public">login()</slot>
+ <slot access="public">suspend()</slot>
+ <slot access="public">toggleEchoMode(bool)</slot>
+</connections>
+</UI>
diff --git a/core/opie-login/loginwindowimpl.cpp b/core/opie-login/loginwindowimpl.cpp
new file mode 100644
index 0000000..3265b46
--- a/dev/null
+++ b/core/opie-login/loginwindowimpl.cpp
@@ -0,0 +1,323 @@
+#include <qapplication.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qlineedit.h>
+#include <qtimer.h>
+#include <qcombobox.h>
+#include <qpixmap.h>
+#include <qlabel.h>
+#include <qpopupmenu.h>
+#include <qmessagebox.h>
+
+#include <qpe/qcopenvelope_qws.h>
+
+#include <opie/odevice.h>
+
+#include <stdio.h>
+
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#ifdef USEPAM
+extern "C" {
+#include <security/pam_appl.h>
+}
+#else
+#include <crypt.h>
+#include <shadow.h>
+#endif
+
+#include "loginwindowimpl.h"
+#include "inputmethods.h"
+
+LoginWindowImpl::LoginWindowImpl ( ) : LoginWindow ( 0, "LOGIN-WINDOW", WStyle_Customize | WStyle_NoBorder | WDestructiveClose )
+{
+ QPopupMenu *pop = new QPopupMenu ( this );
+ pop-> insertItem ( tr( "Restart" ), this, SLOT( restart ( )));
+ m_menu-> setPopup ( pop );
+
+ QHBoxLayout *lay = new QHBoxLayout ( m_taskbar, 4, 4 );
+ m_input = new InputMethods ( m_taskbar );
+ lay-> addWidget ( m_input );
+ lay-> addStretch ( 10 );
+
+ setActiveWindow ( );
+ m_password-> setFocus ( );
+
+ m_user-> insertStringList ( getAllUsers ( ));
+
+ QTimer::singleShot ( 0, this, SLOT( showIM ( )));
+
+ QString opiedir = ::getenv ( "OPIEDIR" );
+ QPixmap bgpix ( opiedir + "/pics/launcher/opie-background.jpg" );
+
+ if ( !bgpix. isNull ( ))
+ setBackgroundPixmap ( bgpix );
+
+ m_caption-> setText ( m_caption-> text ( ) + tr( "<center><h1><u>%1 %2</u></h1></center>" ). arg ( ODevice::inst ( )-> systemString ( )). arg ( ODevice::inst ( )-> systemVersionString ( )));
+}
+
+LoginWindowImpl::~LoginWindowImpl ( )
+{
+}
+
+void LoginWindowImpl::keyPressEvent ( QKeyEvent *e )
+{
+ switch ( e-> key ( )) {
+ case Key_F34: suspend ( );
+ break;
+ case Key_F35: backlight ( );
+ break;
+ default : e-> ignore ( );
+ break;
+ }
+ LoginWindow::keyPressEvent ( e );
+}
+
+
+void LoginWindowImpl::toggleEchoMode ( bool t )
+{
+ m_password-> setEchoMode ( t ? QLineEdit::Normal : QLineEdit::Password );
+}
+
+QStringList LoginWindowImpl::getAllUsers ( )
+{
+ struct passwd *pwd;
+ QStringList sl;
+
+ while (( pwd = getpwent ( ))) {
+ if (( pwd-> pw_uid == 0 ) || ( pwd-> pw_uid >= 500 && pwd-> pw_uid < 65534 ))
+ sl << QString ( pwd-> pw_name );
+ }
+
+ endpwent ( );
+
+ return sl;
+}
+
+void LoginWindowImpl::showIM ( )
+{
+ m_input-> showInputMethod ( );
+}
+
+void LoginWindowImpl::restart ( )
+{
+ qApp-> quit ( );
+}
+
+void LoginWindowImpl::suspend ( )
+{
+ system ( "apm -s" );
+ usleep ( 1 * 1000 * 1000 );
+ {
+ QCopEnvelope e("QPE/System", "setBacklight(int)");
+ e << -3; // Force on
+ }
+}
+
+void LoginWindowImpl::backlight ( )
+{
+ {
+ QCopEnvelope e("QPE/System", "setBacklight(int)");
+ e << -2; // toggle
+ }
+}
+
+#ifdef USEPAM
+
+static const char *_PAM_SERVICE = "xdm";
+static const char *PAM_password;
+
+typedef const struct pam_message pam_message_type;
+
+static int PAM_conv( int, pam_message_type **, struct pam_response **, void * );
+
+static struct pam_conv PAM_conversation = {
+ &PAM_conv,
+ NULL
+};
+
+//----------------------------------------------------------------------------
+
+static char *COPY_STRING( const char * s ) {
+ return (s) ? strdup(s) : (char *)NULL;
+}
+
+#define GET_MEM if (reply) realloc(reply, size);\
+ else reply = (struct pam_response *)malloc(size); \
+ if (!reply) return PAM_CONV_ERR; \
+ size += sizeof(struct pam_response)
+
+
+static int PAM_conv( int num_msg, pam_message_type **msg,
+ struct pam_response **resp, void *)
+{
+ int count = 0, replies = 0;
+ struct pam_response *reply = NULL;
+ int size = sizeof(struct pam_response);
+
+ for( count = 0; count < num_msg; count++ ) {
+ switch (msg[count]->msg_style) {
+ case PAM_PROMPT_ECHO_ON:
+ /* user name given to PAM already */
+ return PAM_CONV_ERR;
+
+ case PAM_PROMPT_ECHO_OFF:
+ /* wants password */
+ GET_MEM;
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = COPY_STRING(PAM_password);
+ replies++;
+ /* PAM frees resp */
+ break;
+ case PAM_TEXT_INFO:
+ break;
+ default:
+ /* unknown or PAM_ERROR_MSG */
+ if (reply) free (reply);
+ return PAM_CONV_ERR;
+ }
+ }
+ if (reply) *resp = reply;
+ return PAM_SUCCESS;
+}
+
+
+static bool pwcheck_PAM( const char *user, const char *password )
+{
+ bool pw_correct = false;
+ int pam_error;
+ int pam_return = 0;
+ pam_handle_t *pamh = 0;
+ PAM_password = password;
+
+ pam_error = pam_start( _PAM_SERVICE, user, &PAM_conversation, &pamh );
+ if( pam_error == PAM_SUCCESS ) {
+ pam_error = pam_authenticate( pamh, 0 );
+ if( pam_error == PAM_SUCCESS ) {
+ //-- password correct
+ pw_correct = true;
+ pam_return = PAM_SUCCESS;
+ } else {
+ pam_return = pam_error;
+ }
+ } else {
+ // cerr << "PAM error: " << pam_strerror( pamh, pam_error ) << endl;
+ }
+ pam_end( pamh, pam_return );
+ return pw_correct;
+}
+
+#else
+
+//----------------------------------------------------------------------------
+
+static bool pwcheck_Unix( const char *user, const char *pass )
+{
+ char *encrypted, *correct;
+ struct passwd *pw;
+
+ if ( !user || !pass )
+ return false;
+
+ pw = getpwnam ( user );
+
+ if ( !pw )
+ return false;
+
+ if (( strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( strcmp ( pw-> pw_passwd, "*" ) == 0 )) {
+ struct spwd *sp = getspnam ( pw-> pw_name );
+
+ if ( !sp )
+ return false;
+
+ correct = sp-> sp_pwdp;
+ }
+ else
+ correct = pw-> pw_passwd;
+
+ if ( correct == 0 || correct[0] == '\0' )
+ return true;
+
+ encrypted = crypt ( pass, correct );
+ return ( strcmp ( encrypted, correct ) == 0 );
+}
+
+#endif
+
+
+bool LoginWindowImpl::changeIdentity ( const char *user )
+{
+ const char *DEFAULT_LOGIN_PATH = "/bin:/usr/bin";
+ const char *DEFAULT_ROOT_LOGIN_PATH = "/usr/sbin:/bin:/usr/bin:/sbin";
+
+ bool fail = false;
+ struct passwd *pw = getpwnam ( user );
+
+ fail |= ( pw == 0 );
+ printf ( "1 %d\n", fail );
+ fail |= ( initgroups ( pw-> pw_name, pw-> pw_gid ));
+ endgrent ( );
+ printf ( "2 %d\n", fail );
+ fail |= ( setgid ( pw-> pw_gid ));
+ printf ( "3 %d\n", fail );
+ fail |= ( setuid ( pw-> pw_uid ));
+
+ printf ( "4 %d\n", fail );
+ fail |= ( chdir ( pw-> pw_dir ) && chdir ( "/" ));
+
+ printf ( "5 %d\n", fail );
+ fail |= ( setenv ( "HOME", pw-> pw_dir, 1 ));
+ printf ( "6 %d\n", fail );
+ fail |= ( setenv ( "SHELL", pw-> pw_shell, 1 ));
+ printf ( "7 %d\n", fail );
+ fail |= ( setenv ( "USER", pw-> pw_name, 1 ));
+ printf ( "8 %d\n", fail );
+ fail |= ( setenv ( "LOGNAME", pw-> pw_name, 1 ));
+ printf ( "9 %d\n", fail );
+ fail |= ( setenv ( "PATH", ( pw-> pw_uid ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH ), 1 ));
+ printf ( "10 %d\n", fail );
+
+ return !fail;
+}
+
+void LoginWindowImpl::login ( )
+{
+ const char *user = strdup ( m_user-> currentText ( ). local8Bit ( ));
+ const char *pass = strdup ( m_password-> text ( ). local8Bit ( ));
+ bool ok;
+
+ if ( !user || !user [0] )
+ return;
+ if ( !pass )
+ pass = "";
+
+#if defined( USEPAM )
+ ok = pwcheck_PAM ( user, pass );
+#else
+ ok = pwcheck_Unix ( user, pass );
+#endif
+
+ if ( ok ) {
+ if ( changeIdentity ( user )) {
+ QString opie = getenv ( "OPIEDIR" );
+ opie += "/bin/qpe";
+
+ execl ( opie. latin1 ( ), "qpe", 0 );
+
+ QMessageBox::critical ( this, tr( "Failure" ), tr( "Could not start OPIE." ));
+ restart ( );
+ }
+ else {
+ QMessageBox::critical ( this, tr( "Failure" ), tr( "Could not switch to new user identity" ));
+ restart ( );
+ }
+ }
+ else {
+ QMessageBox::warning ( this, tr( "Wrong password" ), tr( "The given password is incorrect." ));
+ m_password-> clear ( );
+ }
+}
diff --git a/core/opie-login/loginwindowimpl.h b/core/opie-login/loginwindowimpl.h
new file mode 100644
index 0000000..16c42e6
--- a/dev/null
+++ b/core/opie-login/loginwindowimpl.h
@@ -0,0 +1,33 @@
+#ifndef __OPIE_LOGINWINDOW_IMPL_H__
+#define __OPIE_LOGINWINDOW_IMPL_H__
+
+#include "loginwindow.h"
+
+class InputMethods;
+
+class LoginWindowImpl : public LoginWindow {
+ Q_OBJECT
+
+public:
+ LoginWindowImpl ( );
+ virtual ~LoginWindowImpl ( );
+
+protected slots:
+ void restart ( );
+ void showIM ( );
+ void suspend ( );
+ void backlight ( );
+ void login ( );
+ void toggleEchoMode ( bool );
+
+protected:
+ virtual void keyPressEvent ( QKeyEvent *e );
+
+ QStringList getAllUsers ( );
+ bool changeIdentity ( const char *user );
+
+private:
+ InputMethods *m_input;
+};
+
+#endif
diff --git a/core/opie-login/main.cpp b/core/opie-login/main.cpp
new file mode 100644
index 0000000..9d52b75
--- a/dev/null
+++ b/core/opie-login/main.cpp
@@ -0,0 +1,178 @@
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include <opie/odevice.h>
+
+#include <qwindowsystem_qws.h>
+#include <qfile.h>
+
+#include "loginwindowimpl.h"
+#include "calibrate.h"
+
+int login_main ( int argc, char **argv );
+
+
+int main ( int argc, char **argv )
+{
+ if ( geteuid ( ) != 0 ) {
+ fprintf ( stderr, "%s can only be executed by root. (or chmod +s)", argv [0] );
+ return 1;
+ }
+
+// struct rlimit rl;
+// getrlimit ( RLIMIT_NOFILE, &rl );
+
+// for ( unsigned int i = 0; i < rl. rlim_cur; i++ )
+// close ( i );
+
+ setpgid ( 0, 0 );
+ setsid ( );
+
+ openlog ( "opie-login", LOG_CONS, LOG_AUTHPRIV );
+
+ while ( true ) {
+ pid_t child = fork ( );
+
+ if ( child < 0 ) {
+ syslog ( LOG_ERR, "Could not fork process" );
+ break;
+
+ }
+ else if ( child > 0 ) {
+ int status = 0;
+
+ while ( waitpid ( child, &status, 0 ) < 0 ) { }
+ }
+ else {
+ exit ( login_main ( argc, argv ));
+ }
+ }
+ closelog ( );
+}
+
+
+class ModelKeyFilter : public QObject, public QWSServer::KeyboardFilter
+{
+public:
+ ModelKeyFilter ( ) : QObject ( 0, "MODEL_KEY_FILTER" )
+ {
+ bool doinst = false;
+
+ m_model = ODevice::inst ( )-> model ( );
+ m_power_timer = 0;
+
+ switch ( m_model ) {
+ case OMODEL_iPAQ_H31xx:
+ case OMODEL_iPAQ_H36xx:
+ case OMODEL_iPAQ_H37xx:
+ case OMODEL_iPAQ_H38xx: doinst = true;
+ break;
+ default : break;
+ }
+ if ( doinst )
+ QWSServer::setKeyboardFilter ( this );
+ }
+
+ virtual bool filter ( int /*unicode*/, int keycode, int modifiers, bool isPress, bool autoRepeat )
+ {
+ bool kill = false;
+
+ // Rotate cursor keys 180°
+ switch ( m_model ) {
+ case OMODEL_iPAQ_H31xx:
+ case OMODEL_iPAQ_H38xx: {
+ int newkeycode = keycode;
+
+ switch ( keycode ) {
+ case Key_Left : newkeycode = Key_Right; break;
+ case Key_Right: newkeycode = Key_Left; break;
+ case Key_Up : newkeycode = Key_Down; break;
+ case Key_Down : newkeycode = Key_Up; break;
+ }
+ if ( newkeycode != keycode ) {
+ QWSServer::sendKeyEvent ( -1, newkeycode, modifiers, isPress, autoRepeat );
+ kill = true;
+ }
+ break;
+ }
+ default: break;
+ }
+
+ // map Power Button short/long press to F34/F35
+ switch ( m_model ) {
+ case OMODEL_iPAQ_H31xx:
+ case OMODEL_iPAQ_H36xx:
+ case OMODEL_iPAQ_H37xx:
+ case OMODEL_iPAQ_H38xx: {
+ if ( keycode == Key_SysReq ) {
+ if ( isPress ) {
+ m_power_timer = startTimer ( 500 );
+ }
+ else if ( m_power_timer ) {
+ killTimer ( m_power_timer );
+ m_power_timer = 0;
+ QWSServer::sendKeyEvent ( -1, Key_F34, 0, true, false );
+ QWSServer::sendKeyEvent ( -1, Key_F34, 0, false, false );
+ }
+ kill = true;
+ }
+ break;
+ }
+ default: break;
+ }
+ return kill;
+ }
+
+ virtual void timerEvent ( QTimerEvent * )
+ {
+ killTimer ( m_power_timer );
+ m_power_timer = 0;
+ QWSServer::sendKeyEvent ( -1, Key_F35, 0, true, false );
+ QWSServer::sendKeyEvent ( -1, Key_F35, 0, false, false );
+ }
+
+private:
+ OModel m_model;
+ int m_power_timer;
+};
+
+
+
+
+int login_main ( int argc, char **argv )
+{
+ QWSServer::setDesktopBackground( QImage() );
+ QPEApplication app ( argc, argv, QApplication::GuiServer );
+
+ (void) new ModelKeyFilter ( );
+
+ {
+ QCopEnvelope e("QPE/System", "setBacklight(int)" );
+ e << -3; // Forced on
+ }
+
+#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
+ if ( !QFile::exists ( "/etc/pointercal" )) {
+ // Make sure calibration widget starts on top.
+ Calibrate *cal = new Calibrate;
+ cal-> exec ( );
+ delete cal;
+ }
+#endif
+
+ LoginWindowImpl *lw = new LoginWindowImpl ( );
+ app. setMainWidget ( lw );
+ lw-> setGeometry ( 0, 0, app. desktop ( )-> width ( ), app. desktop ( )-> height ( ));
+ lw-> show ( );
+
+ return app. exec ( );
+}
+
diff --git a/core/opie-login/opie-login.pro b/core/opie-login/opie-login.pro
new file mode 100644
index 0000000..35c1ed0
--- a/dev/null
+++ b/core/opie-login/opie-login.pro
@@ -0,0 +1,25 @@
+TEMPLATE = app
+CONFIG = qt warn_on debug usepam
+
+HEADERS = loginwindowimpl.h \
+ ../launcher/inputmethods.h \
+ ../apps/calibrate/calibrate.h
+
+SOURCES = loginwindowimpl.cpp \
+ ../launcher/inputmethods.cpp \
+ ../apps/calibrate/calibrate.cpp \
+ main.cpp
+
+INTERFACES = loginwindow.ui
+
+INCLUDEPATH += $(OPIEDIR)/include ../launcher ../apps/calibrate
+DEPENDPATH += $(OPIEDIR)/include ../launcher ../apps/calibrate
+
+LIBS += -lqpe -lopie
+
+usepam:LIBS += -lpam
+usepam:DEFINES += USEPAM
+
+DESTDIR = $(OPIEDIR)/bin
+TARGET = opie-login
+