Index: khtml/dom/dom2_events.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/dom2_events.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -p -r1.11 khtml/dom/dom2_events.cpp
--- khtml/dom/dom2_events.cpp	2003/04/02 00:46:02	1.11
+++ dom2_events.cpp	2003/10/20 17:28:09	1.12
@@ -261,9 +261,9 @@ int UIEvent::keyCode() const
     if (!impl)
 	throw DOMException(DOMException::INVALID_STATE_ERR);
     
-    KeyEventImpl *keyEvent = dynamic_cast<KeyEventImpl*>(impl);
+    KeyboardEventImpl *keyEvent = dynamic_cast<KeyboardEventImpl*>(impl);
     if (keyEvent)
-        return keyEvent->keyVal();
+        return keyEvent->qKeyEvent()->ascii();
     else
         return 0;
 }
@@ -323,10 +323,10 @@ int UIEvent::which() const
 
     // Note: This property supports both key events and mouse events
 
-    // Value is just like keyCode()
-    KeyEventImpl *keyEvent = dynamic_cast<KeyEventImpl*>(impl);
+    // Value is just ascii of key event
+    KeyboardEventImpl *keyEvent = dynamic_cast<KeyboardEventImpl*>(impl);
     if (keyEvent)
-        return keyEvent->keyVal();
+        return keyEvent->qKeyEvent()->ascii();
 
     // For khtml, the return values for left, middle and right mouse buttons are 0, 1, 2, respectively.
     // For the Netscape "which" property, the return values for left, middle and right mouse buttons are 1, 2, 3, respectively. 
@@ -599,3 +599,104 @@ void MutationEvent::initMutationEvent(co
 }
 
 
+// -----------------------------------------------------------------------------
+
+KeyboardEvent::KeyboardEvent() : UIEvent()
+{
+}
+
+KeyboardEvent::KeyboardEvent(const KeyboardEvent &other) : UIEvent(other)
+{
+}
+
+KeyboardEvent::KeyboardEvent(const Event &other) : UIEvent()
+{
+    (*this)=other;
+}
+
+KeyboardEvent::KeyboardEvent(KeyboardEventImpl *impl) : UIEvent(impl)
+{
+}
+
+KeyboardEvent &KeyboardEvent::operator = (const KeyboardEvent &other)
+{
+    UIEvent::operator = (other);
+    return *this;
+}
+
+KeyboardEvent &KeyboardEvent::operator = (const Event &other)
+{
+    Event e;
+    e = other;
+    if (!e.isNull() && !e.handle()->isKeyboardEvent()) {
+	if ( impl ) impl->deref();
+	impl = 0;
+    } else
+	UIEvent::operator = (other);
+    return *this;
+}
+
+KeyboardEvent::~KeyboardEvent()
+{
+}
+
+bool KeyboardEvent::ctrlKey() const
+{
+    if (!impl)
+	throw DOMException(DOMException::INVALID_STATE_ERR);
+
+    return static_cast<KeyboardEventImpl*>(impl)->ctrlKey();
+}
+
+bool KeyboardEvent::shiftKey() const
+{
+    if (!impl)
+	throw DOMException(DOMException::INVALID_STATE_ERR);
+
+    return static_cast<KeyboardEventImpl*>(impl)->shiftKey();
+}
+
+bool KeyboardEvent::altKey() const
+{
+    if (!impl)
+	throw DOMException(DOMException::INVALID_STATE_ERR);
+
+    return static_cast<KeyboardEventImpl*>(impl)->altKey();
+}
+
+bool KeyboardEvent::metaKey() const
+{
+    if (!impl)
+	throw DOMException(DOMException::INVALID_STATE_ERR);
+
+    return static_cast<KeyboardEventImpl*>(impl)->metaKey();
+}
+
+bool KeyboardEvent::altGraphKey() const
+{
+    if (!impl)
+	throw DOMException(DOMException::INVALID_STATE_ERR);
+
+    return static_cast<KeyboardEventImpl*>(impl)->altGraphKey();
+}
+
+void KeyboardEvent::initKeyboardEvent(const DOMString &typeArg, 
+                                        bool canBubbleArg,
+                                        bool cancelableArg,
+                                        const AbstractView &viewArg, 
+                                        const DOMString &keyIdentifierArg, 
+                                        unsigned long keyLocationArg, 
+                                        bool ctrlKeyArg, 
+                                        bool shiftKeyArg, 
+                                        bool altKeyArg, 
+                                        bool metaKeyArg, 
+                                        bool altGraphKeyArg)
+{
+    if (!impl)
+	throw DOMException(DOMException::INVALID_STATE_ERR);
+
+    static_cast<KeyboardEventImpl*>(impl)->initKeyboardEvent(typeArg,canBubbleArg,
+	cancelableArg,viewArg,keyIdentifierArg,keyLocationArg,ctrlKeyArg,altKeyArg,
+        shiftKeyArg,metaKeyArg,altGraphKeyArg);
+}
+                                    
Index: khtml/dom/dom2_events.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/dom2_events.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -p -r1.10 khtml/dom/dom2_events.h
--- khtml/dom/dom2_events.h	2003/04/02 00:46:02	1.10
+++ dom2_events.h	2003/10/20 17:28:09	1.11
@@ -34,6 +34,7 @@ class EventException;
 class UIEvent;
 class MouseEvent;
 class MutationEvent;
+class KeyboardEvent;
 class AbstractView;
 
 class EventListenerImpl;
@@ -41,6 +42,7 @@ class EventImpl;
 class UIEventImpl;
 class MouseEventImpl;
 class MutationEventImpl;
+class KeyboardEventImpl;
 
 
 
@@ -660,6 +662,93 @@ protected:
 };
 
 
+/**
+ * Introduced in DOM Level 3
+ *
+ * The KeyboardEvent interface provides specific contextual information
+ * associated with Keyboard events.
+ *
+ */
+class KeyboardEvent : public UIEvent {
+public:
+    KeyboardEvent();
+    KeyboardEvent(const KeyboardEvent &other);
+    KeyboardEvent(const Event &other);
+    KeyboardEvent & operator = (const KeyboardEvent &other);
+    KeyboardEvent & operator = (const Event &other);
+    virtual ~KeyboardEvent();
+
+    // KeyLocationCode
+    static const unsigned long DOM_KEY_LOCATION_STANDARD      = 0x00;
+    static const unsigned long DOM_KEY_LOCATION_LEFT          = 0x01;
+    static const unsigned long DOM_KEY_LOCATION_RIGHT         = 0x02;
+    static const unsigned long DOM_KEY_LOCATION_NUMPAD        = 0x03;
+    static const unsigned long DOM_KEY_LOCATION_UNKNOWN       = 0x04;
+    
+    /**
+     * Holds the identifier of the key.
+     *
+     */
+    DOMString keyIdentifier() const;
+
+    /**
+     * Contains an indication of the location of they key on the device.
+     *
+     */
+    unsigned long keyLocation() const;
+
+    /**
+     * Used to indicate whether the 'ctrl' key was depressed during the firing
+     * of the event.
+     */
+    bool ctrlKey() const;
+
+    /**
+     * Used to indicate whether the 'shift' key was depressed during the firing
+     * of the event.
+     *
+     */
+    bool shiftKey() const;
+
+    /**
+     * Used to indicate whether the 'alt' key was depressed during the firing
+     * of the event. On some platforms this key may map to an alternative key
+     * name.
+     *
+     */
+    bool altKey() const;
+
+    /**
+     * Used to indicate whether the 'meta' key was depressed during the firing
+     * of the event. On some platforms this key may map to an alternative key
+     * name.
+     *
+     */
+    bool metaKey() const;
+
+    /**
+     * Used to indicate whether the 'alt graph' (?) key was depressed during the firing
+     * of the event. On some platforms this key may map to an alternative key
+     * name.
+     *
+     */
+    bool altGraphKey() const;
+
+    void initKeyboardEvent(const DOMString &typeArg, 
+                                bool canBubbleArg,
+                                bool cancelableArg,
+                                const AbstractView &viewArg, 
+                                const DOMString &keyIdentifierArg, 
+                                unsigned long keyLocationArg, 
+                                bool ctrlKeyArg, 
+                                bool shiftKeyArg, 
+                                bool altKeyArg, 
+                                bool metaKeyArg, 
+                                bool altGraphKeyArg);
+                                       
+protected:
+    KeyboardEvent(KeyboardEventImpl *impl);
+};
 
 }; //namespace
 #endif
Index: khtml/html/html_formimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_formimpl.cpp,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -p -r1.74 khtml/html/html_formimpl.cpp
--- khtml/html/html_formimpl.cpp	2003/10/20 04:16:16	1.74
+++ html_formimpl.cpp	2003/10/20 17:28:09	1.75
@@ -856,7 +856,7 @@ void HTMLGenericFormElementImpl::default
 	if (evt->id()==EventImpl::KHTML_KEYDOWN_EVENT ||
 	    evt->id()==EventImpl::KHTML_KEYUP_EVENT)
 	{
-	    KeyEventImpl * k = static_cast<KeyEventImpl *>(evt);
+	    KeyboardEventImpl * k = static_cast<KeyboardEventImpl *>(evt);
 	    if (k->keyVal() == QChar('\n').unicode() && m_render && m_render->isWidget() && k->qKeyEvent)
 		QApplication::sendEvent(static_cast<RenderWidget *>(m_render)->widget(), k->qKeyEvent);
 	}
@@ -1725,14 +1725,14 @@ void HTMLInputElementImpl::defaultEventH
         if (!m_form || !m_render || !evt->isKeyboardEvent())
             return;
         
-        unsigned long keyVal = static_cast<KeyEventImpl *>(evt)->keyVal();
+        DOMString key = static_cast<KeyboardEventImpl *>(evt)->keyIdentifier();
         
         switch (m_type) {
             case IMAGE:
             case RESET:
             case SUBMIT:
                 // simulate mouse click for spacebar, return, and enter
-                if (keyVal == ' ' || keyVal == '\r' || keyVal == 0x3) {
+                if (key == "U+000020" || key == "U+00000d" || key == "Enter") {
                     simulateButtonClickForEvent(evt);
                 }
                 break;
@@ -1740,7 +1740,7 @@ void HTMLInputElementImpl::defaultEventH
             case RADIO:
                 // for return or enter, find the first successful image or submit element 
                 // send it a simulated mouse click
-                if (keyVal == '\r' || keyVal == 0x3) {
+                if (key == "U+00000d" || key == "Enter") {
                     QPtrListIterator<HTMLGenericFormElementImpl> it(m_form->formElements);
                     for (; it.current(); ++it) {
                         if (it.current()->id() == ID_INPUT) {
@@ -2279,9 +2279,9 @@ void HTMLSelectElementImpl::defaultEvent
         if (!m_form || !m_render || !evt->isKeyboardEvent())
             return;
         
-        unsigned long keyVal = static_cast<KeyEventImpl *>(evt)->keyVal();
+        DOMString key = static_cast<KeyboardEventImpl *>(evt)->keyIdentifier();
         
-        if (keyVal == '\r' || keyVal == 0x3) {
+        if (key == "U+00000d" || key == "Enter") {
             QPtrListIterator<HTMLGenericFormElementImpl> it(m_form->formElements);
             for (; it.current(); ++it) {
                 if (it.current()->id() == ID_INPUT) {
Index: khtml/html/html_inlineimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_inlineimpl.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -p -r1.17 khtml/html/html_inlineimpl.cpp
--- khtml/html/html_inlineimpl.cpp	2003/07/24 22:07:45	1.17
+++ html_inlineimpl.cpp	2003/10/20 17:28:10	1.18
@@ -61,7 +61,7 @@ NodeImpl::Id HTMLAnchorElementImpl::id()
 void HTMLAnchorElementImpl::defaultEventHandler(EventImpl *evt)
 {
     // React on clicks and on keypresses.
-    // Don't make this KEYUP_EVENT again, it makes khtml follow links it shouldn't,
+    // Don't make this KHTML_KEYUP_EVENT again, it makes khtml follow links it shouldn't,
     // when pressing Enter in the combo.
     if ( ( evt->id() == EventImpl::KHTML_CLICK_EVENT ||
          ( evt->id() == EventImpl::KHTML_KEYDOWN_EVENT && m_focused)) && m_hasAnchor) {
@@ -69,9 +69,9 @@ void HTMLAnchorElementImpl::defaultEvent
         if ( evt->id() == EventImpl::KHTML_CLICK_EVENT )
             e = static_cast<MouseEventImpl*>( evt );
 
-        KeyEventImpl *k = 0;
+        KeyboardEventImpl *k = 0;
         if (evt->id() == EventImpl::KHTML_KEYDOWN_EVENT)
-            k = static_cast<KeyEventImpl *>( evt );
+            k = static_cast<KeyboardEventImpl *>( evt );
 
         QString utarget;
         QString url;
@@ -82,11 +82,11 @@ void HTMLAnchorElementImpl::defaultEvent
         }
 
         if ( k ) {
-            if (k->virtKeyVal() != KeyEventImpl::DOM_VK_ENTER) {
+            if (k->keyIdentifier() != "Enter") {
                 HTMLElementImpl::defaultEventHandler(evt);
                 return;
             }
-            if (k->qKeyEvent) k->qKeyEvent->accept();
+            if (k->qKeyEvent()) k->qKeyEvent()->accept();
         }
 
         url = khtml::parseURL(getAttribute(ATTR_HREF)).string();
@@ -138,11 +138,11 @@ void HTMLAnchorElementImpl::defaultEvent
             }
 	    else if ( k )
 	    {
-	      if ( k->checkModifier(Qt::ShiftButton) )
+	      if ( k->shiftKey() )
                 state |= Qt::ShiftButton;
-	      if ( k->checkModifier(Qt::AltButton) )
+	      if ( k->altKey() )
                 state |= Qt::AltButton;
-	      if ( k->checkModifier(Qt::ControlButton) )
+	      if ( k->ctrlKey() )
                 state |= Qt::ControlButton;
 	    }
 
Index: khtml/xml/dom2_eventsimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom2_eventsimpl.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -p -r1.11 khtml/xml/dom2_eventsimpl.cpp
--- khtml/xml/dom2_eventsimpl.cpp	2003/08/18 21:12:40	1.11
+++ dom2_eventsimpl.cpp	2003/10/20 17:28:10	1.12
@@ -221,6 +221,12 @@ EventImpl::EventId EventImpl::typeToId(D
 	return SCROLL_EVENT;
     else if (type == "contextmenu")
 	return CONTEXTMENU_EVENT;
+    else if (type == "keydown")
+	return KHTML_KEYDOWN_EVENT;
+    else if (type == "keyup")
+	return KHTML_KEYUP_EVENT;
+    else if (type == "textInput")
+	return TEXTINPUT_EVENT;
     // ignore: KHTML_DBLCLICK_EVENT
     // ignore: KHTML_CLICK_EVENT
     return UNKNOWN_EVENT;
@@ -287,6 +293,12 @@ DOMString EventImpl::idToType(EventImpl:
 	    return "scroll";
         case CONTEXTMENU_EVENT:
             return "contextmenu";
+	case KHTML_KEYDOWN_EVENT:
+            return "keydown";
+	case KHTML_KEYUP_EVENT:
+            return "keyup";
+	case TEXTINPUT_EVENT:
+            return "textInput";
 	// khtml extensions
 	case KHTML_DBLCLICK_EVENT:
             return "dblclick";
@@ -296,12 +308,8 @@ DOMString EventImpl::idToType(EventImpl:
             return "khtml_dragdrop";
 	case KHTML_ERROR_EVENT:
             return "khtml_error";
-	case KHTML_KEYDOWN_EVENT:
-            return "khtml_keydown";
 	case KHTML_KEYPRESS_EVENT:
             return "khtml_keypress";
-	case KHTML_KEYUP_EVENT:
-            return "khtml_keyup";
 	case KHTML_MOVE_EVENT:
             return "khtml_move";
         case KHTML_ORIGCLICK_MOUSEUP_EVENT:
@@ -550,267 +558,107 @@ void MouseEventImpl::initMouseEvent(cons
 }
 
 //---------------------------------------------------------------------------------------------
-
 
-KeyEventImpl::KeyEventImpl()
+KeyboardEventImpl::KeyboardEventImpl()
 {
-  qKeyEvent = 0;
+  m_keyEvent = 0;
 }
 
-KeyEventImpl::KeyEventImpl(QKeyEvent *key, AbstractViewImpl *view)
+KeyboardEventImpl::KeyboardEventImpl(QKeyEvent *key, AbstractViewImpl *view)
   : UIEventImpl(key->type() == QEvent::KeyRelease ? KHTML_KEYUP_EVENT : key->isAutoRepeat() ? KHTML_KEYPRESS_EVENT : KHTML_KEYDOWN_EVENT,
                 true,true,view,0)
 {
-  qKeyEvent = new QKeyEvent(key->type(), key->key(), key->ascii(), key->state(), key->text(), key->isAutoRepeat(), key->count() );
-  // Events are supposed to be accepted by default in Qt!
-  // This line made QLineEdit's keyevents be ignored, so they were sent to the khtmlview
-  // (and e.g. space would make it scroll down)
-  //qKeyEvent->ignore();
-
-  m_detail = key->count();
-
-  m_numPad = false;
-  m_keyVal = 0;
-  m_virtKeyVal = DOM_VK_UNDEFINED;
-  m_inputGenerated = true;
-
-  switch(key->key())
-  {
-  case Qt::Key_Enter:
-      m_numPad = true;
-      /* fall through */
-  case Qt::Key_Return:
-      m_virtKeyVal = DOM_VK_ENTER;
-      break;
-  case Qt::Key_NumLock:
-      m_numPad = true;
-      m_virtKeyVal = DOM_VK_NUM_LOCK;
-      break;
-  case Qt::Key_Alt:
-      m_virtKeyVal = DOM_VK_RIGHT_ALT;
-      // ### DOM_VK_LEFT_ALT;
-      break;
-  case Qt::Key_Control:
-      m_virtKeyVal = DOM_VK_LEFT_CONTROL;
-      // ### DOM_VK_RIGHT_CONTROL
-      break;
-  case Qt::Key_Shift:
-      m_virtKeyVal = DOM_VK_LEFT_SHIFT;
-      // ### DOM_VK_RIGHT_SHIFT
-      break;
-  case Qt::Key_Meta:
-      m_virtKeyVal = DOM_VK_LEFT_META;
-      // ### DOM_VK_RIGHT_META
-      break;
-  case Qt::Key_CapsLock:
-      m_virtKeyVal = DOM_VK_CAPS_LOCK;
-      break;
-  case Qt::Key_Delete:
-      m_virtKeyVal = DOM_VK_DELETE;
-      break;
-  case Qt::Key_End:
-      m_virtKeyVal = DOM_VK_END;
-      break;
-  case Qt::Key_Escape:
-      m_virtKeyVal = DOM_VK_ESCAPE;
-      break;
-  case Qt::Key_Home:
-      m_virtKeyVal = DOM_VK_HOME;
-      break;
-  case Qt::Key_Insert:
-      m_virtKeyVal = DOM_VK_INSERT;
-      break;
-  case Qt::Key_Pause:
-      m_virtKeyVal = DOM_VK_PAUSE;
-      break;
-  case Qt::Key_Print:
-      m_virtKeyVal = DOM_VK_PRINTSCREEN;
-      break;
-  case Qt::Key_ScrollLock:
-      m_virtKeyVal = DOM_VK_SCROLL_LOCK;
-      break;
-  case Qt::Key_Left:
-      m_virtKeyVal = DOM_VK_LEFT;
-      break;
-  case Qt::Key_Right:
-      m_virtKeyVal = DOM_VK_RIGHT;
-      break;
-  case Qt::Key_Up:
-      m_virtKeyVal = DOM_VK_UP;
-      break;
-  case Qt::Key_Down:
-      m_virtKeyVal = DOM_VK_DOWN;
-      break;
-  case Qt::Key_Next:
-      m_virtKeyVal = DOM_VK_PAGE_DOWN;
-      break;
-  case Qt::Key_Prior:
-      m_virtKeyVal = DOM_VK_PAGE_UP;
-      break;
-  case Qt::Key_F1:
-      m_virtKeyVal = DOM_VK_F1;
-      break;
-  case Qt::Key_F2:
-      m_virtKeyVal = DOM_VK_F2;
-      break;
-  case Qt::Key_F3:
-      m_virtKeyVal = DOM_VK_F3;
-      break;
-  case Qt::Key_F4:
-      m_virtKeyVal = DOM_VK_F4;
-      break;
-  case Qt::Key_F5:
-      m_virtKeyVal = DOM_VK_F5;
-      break;
-  case Qt::Key_F6:
-      m_virtKeyVal = DOM_VK_F6;
-      break;
-  case Qt::Key_F7:
-      m_virtKeyVal = DOM_VK_F7;
-      break;
-  case Qt::Key_F8:
-      m_virtKeyVal = DOM_VK_F8;
-      break;
-  case Qt::Key_F9:
-      m_virtKeyVal = DOM_VK_F9;
-      break;
-  case Qt::Key_F10:
-      m_virtKeyVal = DOM_VK_F10;
-      break;
-  case Qt::Key_F11:
-      m_virtKeyVal = DOM_VK_F11;
-      break;
-  case Qt::Key_F12:
-      m_virtKeyVal = DOM_VK_F12;
-      break;
-  case Qt::Key_F13:
-      m_virtKeyVal = DOM_VK_F13;
-      break;
-  case Qt::Key_F14:
-      m_virtKeyVal = DOM_VK_F14;
-      break;
-  case Qt::Key_F15:
-      m_virtKeyVal = DOM_VK_F15;
-      break;
-  case Qt::Key_F16:
-      m_virtKeyVal = DOM_VK_F16;
-      break;
-  case Qt::Key_F17:
-      m_virtKeyVal = DOM_VK_F17;
-      break;
-  case Qt::Key_F18:
-      m_virtKeyVal = DOM_VK_F18;
-      break;
-  case Qt::Key_F19:
-      m_virtKeyVal = DOM_VK_F19;
-      break;
-  case Qt::Key_F20:
-      m_virtKeyVal = DOM_VK_F20;
-      break;
-  case Qt::Key_F21:
-      m_virtKeyVal = DOM_VK_F21;
-      break;
-  case Qt::Key_F22:
-      m_virtKeyVal = DOM_VK_F22;
-      break;
-  case Qt::Key_F23:
-      m_virtKeyVal = DOM_VK_F23;
-      break;
-  case Qt::Key_F24:
-      m_virtKeyVal = DOM_VK_F24;
-      break;
-  default:
-      m_virtKeyVal = DOM_VK_UNDEFINED;
-      break;
-  }
-
-  // m_keyVal should contain the unicode value
-  // of the pressed key if available.
-  if (m_virtKeyVal == DOM_VK_UNDEFINED && !key->text().isNull())
-      m_keyVal = key->text().unicode()[0];
-
-  //  m_numPad = ???
-
-  // key->state returns enum ButtonState, which is ShiftButton, ControlButton and AltButton or'ed together.
-  m_modifier = key->state();
-
-  // key->text() returns the unicode sequence as a QString
-  m_outputString = DOMString(key->text());
-}
-
-KeyEventImpl::KeyEventImpl(EventId _id,
-			   bool canBubbleArg,
-			   bool cancelableArg,
-			   AbstractViewImpl *viewArg,
-			   unsigned short detailArg,
-			   DOMString &outputStringArg,
-			   unsigned long keyValArg,
-			   unsigned long virtKeyValArg,
-			   bool inputGeneratedArg,
-			   bool numPadArg)
-  : UIEventImpl(_id,canBubbleArg,cancelableArg,viewArg,detailArg)
-{
-  qKeyEvent = 0;
-  m_keyVal = keyValArg;
-  m_virtKeyVal = virtKeyValArg;
-  m_inputGenerated = inputGeneratedArg;
-  m_outputString = outputStringArg;
-  m_numPad = numPadArg;
-  m_modifier = 0;
-}
-
-KeyEventImpl::~KeyEventImpl()
-{
-    delete qKeyEvent;
-}
-
-bool KeyEventImpl::checkModifier(unsigned long modifierArg)
-{
-  return ((m_modifier && modifierArg) == modifierArg);
-}
-
-void KeyEventImpl::initKeyEvent(DOMString &typeArg,
-				bool canBubbleArg,
-				bool cancelableArg,
-				const AbstractView &viewArg,
-				long detailArg,
-				DOMString &outputStringArg,
-				unsigned long keyValArg,
-				unsigned long virtKeyValArg,
-				bool inputGeneratedArg,
-				bool numPadArg)
-{
-  UIEventImpl::initUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg);
-
-  m_outputString = outputStringArg;
-  m_keyVal = keyValArg;
-  m_virtKeyVal = virtKeyValArg;
-  m_inputGenerated = inputGeneratedArg;
-  m_numPad = numPadArg;
-}
-
-void KeyEventImpl::initModifier(unsigned long modifierArg,
-				bool valueArg)
-{
-  if (valueArg)
-      m_modifier |= modifierArg;
-  else
-      m_modifier &= (modifierArg ^ 0xFFFFFFFF);
-}
-
-bool             KeyEventImpl::inputGenerated() const
-{
-  return m_inputGenerated;
+    m_keyEvent = new QKeyEvent(key->type(), key->key(), key->ascii(), key->state(), key->text(), key->isAutoRepeat(), key->count());
+    // Events are supposed to be accepted by default in Qt!
+    // This line made QLineEdit's keyevents be ignored, so they were sent to the khtmlview
+    // (and e.g. space would make it scroll down)
+    //qKeyEvent->ignore();
+
+    // m_keyIdentifier should contain the unicode value of the pressed key if available.
+    // key->text() returns the unicode sequence as a QString
+    if (!key->text().isNull()) {
+        DOMString identifier(m_keyEvent->identifier());
+        m_keyIdentifier = identifier.implementation();
+        m_keyIdentifier->ref();
+    }
+    else {
+        m_keyIdentifier = DOMString("Unidentified").implementation();
+        m_keyIdentifier->ref();
+    }
+
+    // key->state returns enum ButtonState, which is ShiftButton, ControlButton and AltButton or'ed together.
+    int keyState = key->state();
+    if (keyState & Qt::ControlButton)
+        m_ctrlKey = true;
+    if (keyState & Qt::ShiftButton)
+        m_shiftKey = true;
+    if (keyState & Qt::AltButton)
+        m_altKey = true;
+    if (keyState & Qt::MetaButton)
+        m_metaKey = true;
+    // altGraphKey is not supported by Qt.
+    
+    // Note: we only support testing for num pad
+    m_keyLocation = (keyState & Qt::Keypad) ? KeyboardEvent::DOM_KEY_LOCATION_NUMPAD : KeyboardEvent::DOM_KEY_LOCATION_STANDARD;
 }
 
-unsigned long    KeyEventImpl::keyVal() const
-{
-  return m_keyVal;
+KeyboardEventImpl::KeyboardEventImpl(EventId _id,
+                                        bool canBubbleArg,
+                                        bool cancelableArg,
+                                        AbstractViewImpl *viewArg, 
+                                        const DOMString &keyIdentifierArg, 
+                                        unsigned long keyLocationArg, 
+                                        bool ctrlKeyArg, 
+                                        bool shiftKeyArg, 
+                                        bool altKeyArg, 
+                                        bool metaKeyArg, 
+                                        bool altGraphKeyArg)
+  : UIEventImpl(_id,canBubbleArg,cancelableArg,viewArg,0)
+{
+    m_keyEvent = 0;
+    m_keyIdentifier = keyIdentifierArg.implementation();
+    if (m_keyIdentifier)
+        m_keyIdentifier->ref();
+    m_keyLocation = keyLocationArg;
+    m_ctrlKey = ctrlKeyArg;
+    m_shiftKey = shiftKeyArg;
+    m_altKey = altKeyArg;
+    m_metaKey = metaKeyArg;
+    m_altGraphKey = altGraphKeyArg;
 }
 
-DOMString        KeyEventImpl::outputString() const
+KeyboardEventImpl::~KeyboardEventImpl()
 {
-  return m_outputString;
+    delete m_keyEvent;
+    if (m_keyIdentifier)
+        m_keyIdentifier->deref();
+}
+
+void KeyboardEventImpl::initKeyboardEvent(const DOMString &typeArg,
+                        bool canBubbleArg,
+                        bool cancelableArg,
+                        const AbstractView &viewArg, 
+                        const DOMString &keyIdentifierArg, 
+                        unsigned long keyLocationArg, 
+                        bool ctrlKeyArg, 
+                        bool shiftKeyArg, 
+                        bool altKeyArg, 
+                        bool metaKeyArg, 
+                        bool altGraphKeyArg)
+{
+    if (m_keyIdentifier)
+        m_keyIdentifier->deref();
+
+    UIEventImpl::initUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, 0);
+    m_keyIdentifier = keyIdentifierArg.implementation();
+    if (m_keyIdentifier)
+        m_keyIdentifier->ref();
+    m_keyLocation = keyLocationArg;
+    m_ctrlKey = ctrlKeyArg;
+    m_shiftKey = shiftKeyArg;
+    m_altKey = altKeyArg;
+    m_metaKey = metaKeyArg;
+    m_altGraphKey = altGraphKeyArg;
 }
 
 // -----------------------------------------------------------------------------
Index: khtml/xml/dom2_eventsimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom2_eventsimpl.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -p -r1.8 khtml/xml/dom2_eventsimpl.h
--- khtml/xml/dom2_eventsimpl.h	2003/10/03 18:46:38	1.8
+++ dom2_eventsimpl.h	2003/10/20 17:28:10	1.9
@@ -78,14 +78,17 @@ public:
 	RESIZE_EVENT,
 	SCROLL_EVENT,
         CONTEXTMENU_EVENT,
+        // Keyboard events
+	KHTML_KEYDOWN_EVENT,
+	KHTML_KEYUP_EVENT,
+        // Text events
+        TEXTINPUT_EVENT,
 	// khtml events (not part of DOM)
 	KHTML_DBLCLICK_EVENT, // for html ondblclick
 	KHTML_CLICK_EVENT, // for html onclick
 	KHTML_DRAGDROP_EVENT,
 	KHTML_ERROR_EVENT,
-	KHTML_KEYDOWN_EVENT,
 	KHTML_KEYPRESS_EVENT,
-	KHTML_KEYUP_EVENT,
 	KHTML_MOVE_EVENT,
 	KHTML_ORIGCLICK_MOUSEUP_EVENT
     };
@@ -122,7 +125,7 @@ public:
     static EventId typeToId(DOMString type);
     static DOMString idToType(EventId id);
 
-    void setDefaultHandled();
+    virtual void setDefaultHandled();
     bool defaultHandled() const { return m_defaultHandled; }
 
 protected:
@@ -237,270 +240,58 @@ protected:
 };
 
 
-// Introduced in DOM Level 3:
-/**
- * DOM::KeyEvent
- * The detail attribute inherited from UIEvent is used to indicate
- * the number of keypresses which have occurred during key repetition.
- * If this information is not available this value should be 0.
- */
-class KeyEventImpl : public UIEventImpl {
+// Introduced in DOM Level 3
+class KeyboardEventImpl : public UIEventImpl {
 public:
-  KeyEventImpl();
-  KeyEventImpl(EventId _id,
-	       bool canBubbleArg,
-	       bool cancelableArg,
-	       AbstractViewImpl *viewArg,
-	       unsigned short detailArg,
-	       DOMString &outputStringArg,
-	       unsigned long keyValArg,
-	       unsigned long virtKeyValArg,
-	       bool inputGeneratedArg,
-	       bool numPadArg);
-
-  KeyEventImpl(QKeyEvent *key, AbstractViewImpl *view);
-
-  virtual ~KeyEventImpl();
-
-  // VirtualKeyCode
-  enum KeyCodes  {
-         DOM_VK_UNDEFINED               = 0x0,
-         DOM_VK_RIGHT_ALT               = 0x01,
-         DOM_VK_LEFT_ALT                = 0x02,
-         DOM_VK_LEFT_CONTROL            = 0x03,
-         DOM_VK_RIGHT_CONTROL           = 0x04,
-         DOM_VK_LEFT_SHIFT              = 0x05,
-         DOM_VK_RIGHT_SHIFT             = 0x06,
-         DOM_VK_LEFT_META               = 0x07,
-         DOM_VK_RIGHT_META              = 0x08,
-         DOM_VK_CAPS_LOCK               = 0x09,
-         DOM_VK_DELETE                  = 0x0A,
-         DOM_VK_END                     = 0x0B,
-         DOM_VK_ENTER                   = 0x0C,
-         DOM_VK_ESCAPE                  = 0x0D,
-         DOM_VK_HOME                    = 0x0E,
-         DOM_VK_INSERT                  = 0x0F,
-         DOM_VK_NUM_LOCK                = 0x10,
-         DOM_VK_PAUSE                   = 0x11,
-         DOM_VK_PRINTSCREEN             = 0x12,
-         DOM_VK_SCROLL_LOCK             = 0x13,
-         DOM_VK_LEFT                    = 0x14,
-         DOM_VK_RIGHT                   = 0x15,
-         DOM_VK_UP                      = 0x16,
-         DOM_VK_DOWN                    = 0x17,
-         DOM_VK_PAGE_DOWN               = 0x18,
-         DOM_VK_PAGE_UP                 = 0x19,
-         DOM_VK_F1                      = 0x1A,
-         DOM_VK_F2                      = 0x1B,
-         DOM_VK_F3                      = 0x1C,
-         DOM_VK_F4                      = 0x1D,
-         DOM_VK_F5                      = 0x1E,
-         DOM_VK_F6                      = 0x1F,
-         DOM_VK_F7                      = 0x20,
-         DOM_VK_F8                      = 0x21,
-         DOM_VK_F9                      = 0x22,
-         DOM_VK_F10                     = 0x23,
-         DOM_VK_F11                     = 0x24,
-         DOM_VK_F12                     = 0x25,
-         DOM_VK_F13                     = 0x26,
-         DOM_VK_F14                     = 0x27,
-         DOM_VK_F15                     = 0x28,
-         DOM_VK_F16                     = 0x29,
-         DOM_VK_F17                     = 0x2A,
-         DOM_VK_F18                     = 0x2B,
-         DOM_VK_F19                     = 0x2C,
-         DOM_VK_F20                     = 0x2D,
-         DOM_VK_F21                     = 0x2E,
-         DOM_VK_F22                     = 0x2F,
-         DOM_VK_F23                     = 0x30,
-         DOM_VK_F24                     = 0x31
-  };
-
- /**
-  *  checkModifier
-  *
-  * Note: the below description does not match the actual behaviour.
-  *       it's extended in a way that you can query multiple modifiers
-  *       at once by logically OR`ing them.
-  *       also, we use the Qt modifier enum instead of the DOM one.
-  *
-  * The CheckModifier method is used to check the status of a single
-  * modifier key associated with a KeyEvent. The identifier of the
-  * modifier in question is passed into the CheckModifier function. If
-  * the modifier is triggered it will return true. If not, it will
-  * return false.  The list of keys below represents the allowable
-  * modifier paramaters for this method:
-  *     DOM_VK_LEFT_ALT
-  *     DOM_VK_RIGHT_ALT
-  *     DOM_VK_LEFT_CONTROL
-  *     DOM_VK_RIGHT_CONTROL
-  *     DOM_VK_LEFT_SHIFT
-  *     DOM_VK_RIGHT_SHIFT
-  *     DOM_VK_META
-  *
-  * Parameters:
-  *
-  * modifer of type unsigned long
-  *   The modifier which the user wishes to query.
-  *
-  * Return Value: boolean
-  *   The status of the modifier represented as a boolean.
-  *
-  * No Exceptions
-  */
- bool checkModifier(unsigned long modiferArg);
-
- /**
-  * initKeyEvent
-  *
-  * The initKeyEvent method is used to initialize the value of a
-  * MouseEvent created through the DocumentEvent interface. This
-  * method may only be called before the KeyEvent has been dispatched
-  * via the dispatchEvent method, though it may be called multiple
-  * times during that phase if necessary. If called multiple times,
-  * the final invocation takes precedence. This method has no effect
-  * if called after the event has been dispatched.
-  *
-  * Parameters:
-  *
-  * typeArg of type DOMString
-  *   Specifies the event type.
-  * canBubbleArg of type boolean
-  *   Specifies whether or not the event can bubble.
-  * cancelableArg of type boolean
-  *   Specifies whether or not the event's default action can be prevent.
-  * viewArg of type views::AbstractView
-  *   Specifies the KeyEvent's AbstractView.
-  * detailArg of type unsigned short
-  *   Specifies the number of repeated keypresses, if available.
-  * outputStringArg of type DOMString
-  *   Specifies the KeyEvent's outputString attribute
-  * keyValArg of type unsigned long
-  *   Specifies the KeyEvent's keyValattribute
-  * virtKeyValArg of type unsigned long
-  *   Specifies the KeyEvent's virtKeyValattribute
-  * inputGeneratedArg of type boolean
-  *   Specifies the KeyEvent's inputGeneratedattribute
-  * numPadArg of type boolean
-  *   Specifies the KeyEvent's numPadattribute
-  *
-  * No Return Value.
-  * No Exceptions.
-  */
- void initKeyEvent(DOMString &typeArg,
-		   bool canBubbleArg,
-		   bool cancelableArg,
-		   const AbstractView &viewArg,
-		   long detailArg,
-		   DOMString &outputStringArg,
-		   unsigned long keyValArg,
-		   unsigned long virtKeyValArg,
-		   bool inputGeneratedArg,
-		   bool numPadArg);
- /**
-  * initModifier
-  *
-  * The initModifier method is used to initialize the values of any
-  * modifiers associated with a KeyEvent created through the
-  * DocumentEvent interface. This method may only be called before the
-  * KeyEvent has been dispatched via the dispatchEvent method, though
-  * it may be called multiple times during that phase if necessary. If
-  * called multiple times with the same modifier property the final
-  * invocation takes precedence. Unless explicitly give a value of
-  * true, all modifiers have a value of false. This method has no
-  * effect if called after the event has been dispatched.  The list of
-  * keys below represents the allowable modifier paramaters for this
-  * method:
-  *    DOM_VK_LEFT_ALT
-  *    DOM_VK_RIGHT_ALT
-  *    DOM_VK_LEFT_CONTROL
-  *    DOM_VK_RIGHT_CONTROL
-  *    DOM_VK_LEFT_SHIFT
-  *    DOM_VK_RIGHT_SHIFT
-  *    DOM_VK_META
-  *
-  * Parameters:
-  *
-  * modifier of type unsigned long
-  *   The modifier which the user wishes to initialize
-  * value of type boolean
-  *   The new value of the modifier.
-  *
-  * No Return Value
-  * No Exceptions
-  */
- void initModifier(unsigned long modifierArg, bool valueArg);
-
- //Attributes:
-
- /**
-  * inputGenerated of type boolean
-  *
-  *  The inputGenerated attribute indicates whether the key event will
-  *  normally cause visible output. If the key event does not
-  *  generate any visible output, such as the use of a function key
-  *  or the combination of certain modifier keys used in conjunction
-  *  with another key, then the value will be false. If visible
-  *  output is normally generated by the key event then the value
-  *  will be true.  The value of inputGenerated does not guarantee
-  *  the creation of a character. If a key event causing visible
-  *  output is cancelable it may be prevented from causing
-  *  output. This attribute is intended primarily to differentiate
-  *  between keys events which may or may not produce visible output
-  *  depending on the system state.
-  */
- bool             inputGenerated() const;
-
- /** keyVal of type unsigned long
-  *
-  *  The value of keyVal holds the value of the Unicode character
-  *  associated with the depressed key. If the key has no Unicode
-  *  representation or no Unicode character is available the value is
-  *  0.
-  */
- unsigned long    keyVal() const;
-
- /** numPad of type boolean
-  *
-  *  The numPad attribute indicates whether or not the key event was
-  *  generated on the number pad section of the keyboard. If the number
-  *  pad was used to generate the key event the value is true,
-  *  otherwise the value is false.
-  */
-    bool             numPad() const { return m_numPad; }
-
- /**
-  *outputString of type DOMString
-  *
-  *  outputString holds the value of the output generated by the key
-  *  event. This may be a single Unicode character or it may be a
-  *  string. It may also be null in the case where no output was
-  *  generated by the key event.
-  */
- DOMString        outputString() const;
-
- /** virtKeyVal of type unsigned long
-  *
-  *  When the key associated with a key event is not representable via
-  *  a Unicode character virtKeyVale holds the virtual key code
-  *  associated with the depressed key. If the key has a Unicode
-  *  representation or no virtual code is available the value is
-  *  DOM_VK_UNDEFINED.
-  */
-    unsigned long virtKeyVal() const { return m_virtKeyVal; }
-
+    KeyboardEventImpl();
+    KeyboardEventImpl(QKeyEvent *key, AbstractViewImpl *view);
+    KeyboardEventImpl(EventId _id,
+                bool canBubbleArg,
+                bool cancelableArg,
+                AbstractViewImpl *viewArg,
+                const DOMString &keyIdentifierArg,
+                unsigned long keyLocationArg,
+                bool ctrlKeyArg,
+                bool shiftKeyArg,
+                bool altKeyArg,
+                bool metaKeyArg,
+                bool altGraphKeyArg);
+    virtual ~KeyboardEventImpl();
+    
+    void initKeyboardEvent(const DOMString &typeArg,
+                bool canBubbleArg,
+                bool cancelableArg,
+                const AbstractView &viewArg,
+                const DOMString &keyIdentifierArg,
+                unsigned long keyLocationArg,
+                bool ctrlKeyArg,
+                bool shiftKeyArg,
+                bool altKeyArg,
+                bool metaKeyArg,
+                bool altGraphKeyArg);
+    
+    DOMString keyIdentifier() const { return m_keyIdentifier; }
+    unsigned long keyLocation() const { return m_keyLocation; }
+    
+    bool ctrlKey() const { return m_ctrlKey; }
+    bool shiftKey() const { return m_shiftKey; }
+    bool altKey() const { return m_altKey; }
+    bool metaKey() const { return m_metaKey; }
+    bool altGraphKey() const { return m_altGraphKey; }
+    
+    QKeyEvent *qKeyEvent() const { return m_keyEvent; }
+    
     virtual bool isKeyboardEvent() { return true; }
 
- QKeyEvent *qKeyEvent;
-
 private:
-  unsigned long m_keyVal;
-  unsigned long m_virtKeyVal;
-  bool m_inputGenerated;
-  DOMString m_outputString;
-  bool m_numPad;
-  // bitfield containing state of modifiers. not part of the dom.
-  unsigned long    m_modifier;
+    QKeyEvent *m_keyEvent;
+    DOMStringImpl *m_keyIdentifier;
+    unsigned long m_keyLocation;
+    bool m_ctrlKey : 1;
+    bool m_shiftKey : 1;
+    bool m_altKey : 1;
+    bool m_metaKey : 1;
+    bool m_altGraphKey : 1;
 };
 
 class MutationEventImpl : public EventImpl {
Index: khtml/xml/dom_docimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_docimpl.cpp,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -p -r1.82 khtml/xml/dom_docimpl.cpp
--- khtml/xml/dom_docimpl.cpp	2003/10/03 18:40:21	1.82
+++ dom_docimpl.cpp	2003/10/20 17:28:10	1.83
@@ -2155,6 +2155,8 @@ EventImpl *DocumentImpl::createEvent(con
         return new MouseEventImpl();
     else if (eventType == "MutationEvents")
         return new MutationEventImpl();
+    else if (eventType == "KeyboardEvents")
+        return new KeyboardEventImpl();
     else if (eventType == "HTMLEvents")
         return new EventImpl();
     else {
Index: khtml/xml/dom_nodeimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_nodeimpl.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -p -r1.40 khtml/xml/dom_nodeimpl.cpp
--- khtml/xml/dom_nodeimpl.cpp	2003/10/01 20:58:56	1.40
+++ dom_nodeimpl.cpp	2003/10/20 17:28:10	1.41
@@ -737,23 +737,23 @@ bool NodeImpl::dispatchKeyEvent(QKeyEven
 {
     int exceptioncode = 0;
     //kdDebug(6010) << "DOM::NodeImpl: dispatching keyboard event" << endl;
-    KeyEventImpl *keyEventImpl = new KeyEventImpl(key, getDocument()->defaultView());
-    keyEventImpl->ref();
-    bool r = dispatchEvent(keyEventImpl,exceptioncode,true);
+    KeyboardEventImpl *keyboardEventImpl = new KeyboardEventImpl(key, getDocument()->defaultView());
+    keyboardEventImpl->ref();
+    bool r = dispatchEvent(keyboardEventImpl,exceptioncode,true);
 
 #if APPLE_CHANGES
     // we want to return false if default is prevented (already taken care of)
     // or if the element is default-handled by the DOM. Otherwise we let it just
     // let it get handled by AppKit 
-    if (keyEventImpl->defaultHandled())
+    if (keyboardEventImpl->defaultHandled())
 #else
     // the default event handler should accept() the internal QKeyEvent
     // to prevent the view from further evaluating it.
-    if (!keyEventImpl->defaultPrevented() && !keyEventImpl->qKeyEvent->isAccepted())
+    if (!keyboardEventImpl->defaultPrevented() && !keyboardEventImpl->qKeyEvent->isAccepted())
 #endif
       r = false;
 
-    keyEventImpl->deref();
+    keyboardEventImpl->deref();
     return r;
 }
 
Index: kwq/KWQEvent.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/kwq/KWQEvent.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -p -r1.30 kwq/KWQEvent.h
--- kwq/KWQEvent.h	2003/05/02 20:09:49	1.30
+++ KWQEvent.h	2003/10/20 17:28:10	1.31
@@ -110,11 +110,13 @@ public:
     int count()  const;
     QString text() const;
     int ascii() const;
+    QString identifier() const;
  private:
     int _key;
     int _ascii;
     ButtonState _state;
     QString _text;
+    QString _identifier;
     bool _autoRepeat;
     int _count;
     bool _isAccepted;
Index: kwq/KWQEvent.mm
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/kwq/KWQEvent.mm,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -p -r1.18 kwq/KWQEvent.mm
--- kwq/KWQEvent.mm	2003/01/22 00:12:34	1.18
+++ KWQEvent.mm	2003/10/20 17:28:10	1.19
@@ -58,6 +58,281 @@ QTimerEvent::QTimerEvent(int t)
     _timerId = t;
 }
 
+static char hexDigit(int i) {
+    if (i < 0 || i > 16) {
+        ERROR("illegal hex digit");
+        return '0';
+    }
+    int h = i;
+    if (h >= 10) {
+        h = h - 10 + 'a'; 
+    }
+    else {
+        h += '0';
+    }
+    return h;
+}
+
+static QString identifierForKeyText(const QString &text)
+{
+    int count = text.length();
+    if (count == 0 || count > 1) {
+#ifdef APPLE_CHANGES
+        LOG(Events, "received an unexpected number of characters in key event: %d", count);
+#endif
+        return "Unidentified";
+    }
+    ushort c = text[0].unicode();
+    switch (c) {
+        // Each identifier listed in the DOM spec is listed here.
+        // Many are simply commented out since they do not appear on standard Macintosh keyboards.
+        // "Accept"
+        // "AllCandidates"
+        // "Alt"
+        // "Apps"
+        // "BrowserBack"
+        // "BrowserForward"
+        // "BrowserHome"
+        // "BrowserRefresh"
+        // "BrowserSearch"
+        // "BrowserStop"
+        // "CapsLock"
+        // "Clear"
+        case NSClearLineFunctionKey:
+            return "Clear";
+            break;
+        // "CodeInput"
+        // "Compose"
+        // "Control"
+        // "Crsel"
+        // "Convert"
+        // "Copy"
+        // "Cut"
+        // "Down"
+        case NSDownArrowFunctionKey:
+            return "Down";
+            break;
+        // "End"
+        case NSEndFunctionKey:
+            return "End";
+            break;
+        // "Enter"
+        case 0x3:
+            return "Enter";
+            break;
+        // "EraseEof"
+        // "Execute"
+        case NSExecuteFunctionKey:
+            return "Execute";
+            break;
+        // "Exsel"
+        // "F1"
+        case NSF1FunctionKey:
+            return "F1";
+            break;
+        // "F2"
+        case NSF2FunctionKey:
+            return "F2";
+            break;
+        // "F3"
+        case NSF3FunctionKey:
+            return "F3";
+            break;
+        // "F4"
+        case NSF4FunctionKey:
+            return "F4";
+            break;
+        // "F5"
+        case NSF5FunctionKey:
+            return "F5";
+            break;
+        // "F6"
+        case NSF6FunctionKey:
+            return "F6";
+            break;
+        // "F7"
+        case NSF7FunctionKey:
+            return "F7";
+            break;
+        // "F8"
+        case NSF8FunctionKey:
+            return "F8";
+            break;
+        // "F9"
+        case NSF9FunctionKey:
+            return "F9";
+            break;
+        // "F10"
+        case NSF10FunctionKey:
+            return "F10";
+            break;
+        // "F11"
+        case NSF11FunctionKey:
+            return "F11";
+            break;
+        // "F12"
+        case NSF12FunctionKey:
+            return "F12";
+            break;
+        // "F13"
+        case NSF13FunctionKey:
+            return "F13";
+            break;
+        // "F14"
+        case NSF14FunctionKey:
+            return "F14";
+            break;
+        // "F15"
+        case NSF15FunctionKey:
+            return "F15";
+            break;
+        // "F16"
+        case NSF16FunctionKey:
+            return "F16";
+            break;
+        // "F17"
+        case NSF17FunctionKey:
+            return "F17";
+            break;
+        // "F18"
+        case NSF18FunctionKey:
+            return "F18";
+            break;
+        // "F19"
+        case NSF19FunctionKey:
+            return "F19";
+            break;
+        // "F20"
+        case NSF20FunctionKey:
+            return "F20";
+            break;
+        // "F21"
+        case NSF21FunctionKey:
+            return "F21";
+            break;
+        // "F22"
+        case NSF22FunctionKey:
+            return "F22";
+            break;
+        // "F23"
+        case NSF23FunctionKey:
+            return "F23";
+            break;
+        // "F24"
+        case NSF24FunctionKey:
+            return "F24";
+            break;
+        // "FinalMode"
+        // "Find"
+        case NSFindFunctionKey:
+            return "Find";
+            break;
+        // "ForwardDelete" (Non-standard)
+        case NSDeleteFunctionKey:
+            return "ForwardDelete";
+            break;
+        // "FullWidth"
+        // "HalfWidth"
+        // "HangulMode"
+        // "HanjaMode"
+        // "Help"
+        case NSHelpFunctionKey:
+            return "Help";
+            break;
+        // "Hiragana"
+        // "Home"
+        case NSHomeFunctionKey:
+            return "Home";
+            break;
+        // "Insert"
+        case NSInsertFunctionKey:
+            return "Left";
+            break;
+        // "JapaneseHiragana"
+        // "JapaneseKatakana"
+        // "JapaneseRomaji"
+        // "JunjaMode"
+        // "KanaMode"
+        // "KanjiMode"
+        // "Katakana"
+        // "LaunchApplication1"
+        // "LaunchApplication2"
+        // "LaunchMail"
+        // "Left"
+        case NSLeftArrowFunctionKey:
+            return "Left";
+            break;
+        // "Meta"
+        // "MediaNextTrack"
+        // "MediaPlayPause"
+        // "MediaPreviousTrack"
+        // "MediaStop"
+        // "ModeChange"
+        case NSModeSwitchFunctionKey:
+            return "ModeChange";
+            break;
+        // "Nonconvert"
+        // "NumLock"
+        // "PageDown"
+        case NSPageDownFunctionKey:
+            return "PageDown";
+            break;
+        // "PageUp"
+        case NSPageUpFunctionKey:
+            return "PageUp";
+            break;
+        // "Paste"
+        // "Pause"
+        case NSPauseFunctionKey:
+            return "Pause";
+            break;
+        // "Play"
+        // "PreviousCandidate"
+        // "PrintScreen"
+        case NSPrintScreenFunctionKey:
+            return "PrintScreen";
+            break;
+        // "Process"
+        // "Props"
+        // "Right"
+        case NSRightArrowFunctionKey:
+            return "Right";
+            break;
+        // "RomanCharacters"
+        // "Scroll"
+        // "Select"
+        // "SelectMedia"
+        // "Shift"
+        // "Stop"
+        case NSStopFunctionKey:
+            return "Stop";
+            break;
+        // "Up"
+        case NSUpArrowFunctionKey:
+            return "Up";
+            break;
+        // "Undo"
+        case NSUndoFunctionKey:
+            return "Undo";
+            break;
+        // "VolumeDown"
+        // "VolumeMute"
+        // "VolumeUp"
+        // "Win"
+        // "Zoom"
+        default:
+            char escaped[5];
+            escaped[0] = hexDigit((c >> 12) & 0xf);
+            escaped[1] = hexDigit((c >> 8) & 0xf);
+            escaped[2] = hexDigit((c >> 4) & 0xf);
+            escaped[3] = hexDigit(c & 0xf);
+            escaped[4] = '\0';
+            NSString *nsstring = [[NSString alloc] initWithFormat:@"U+00%s", escaped];
+            QString qstring = QString::fromNSString(nsstring);
+            [nsstring release];
+            return qstring;
+    }
+}
 
 QKeyEvent::QKeyEvent(Type t, int key, int ascii, int buttonState, const QString &text, bool autoRepeat, ushort count)
     : QEvent(t),
@@ -69,6 +344,7 @@ QKeyEvent::QKeyEvent(Type t, int key, in
       _count(count),
       _isAccepted(false)
 {
+    _identifier = identifierForKeyText(text);
 }
 
 int QKeyEvent::key() const
@@ -114,4 +390,9 @@ int QKeyEvent::count(void) const
 bool QKeyEvent::isAccepted(void) const
 {
     return _isAccepted;
+}
+
+QString QKeyEvent::identifier() const
+{
+    return _identifier;
 }
Index: kwq/KWQKHTMLPart.mm
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/kwq/KWQKHTMLPart.mm,v
retrieving revision 1.408
retrieving revision 1.409
diff -u -p -r1.408 kwq/KWQKHTMLPart.mm
--- kwq/KWQKHTMLPart.mm	2003/10/07 22:23:56	1.408
+++ KWQKHTMLPart.mm	2003/10/20 17:28:10	1.409
@@ -1694,6 +1694,8 @@ int KWQKHTMLPart::stateForCurrentEvent()
         state |= Qt::AltButton;
     if (modifiers & NSCommandKeyMask)
         state |= Qt::MetaButton;
+    if (modifiers & NSNumericPadKeyMask)
+        state |= Qt::Keypad;
     
     return state;
 }
Index: kwq/KWQLogging.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/kwq/KWQLogging.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -p -r1.6 kwq/KWQLogging.h
--- kwq/KWQLogging.h	2003/01/22 00:12:35	1.6
+++ KWQLogging.h	2003/10/20 17:28:10	1.7
@@ -34,3 +34,4 @@ extern KWQLogChannel KWQLogNotYetImpleme
 extern KWQLogChannel KWQLogFrames;
 extern KWQLogChannel KWQLogLoading;
 extern KWQLogChannel KWQLogPopupBlocking;
+extern KWQLogChannel KWQLogEvents;
Index: kwq/KWQLogging.m
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/kwq/KWQLogging.m,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -p -r1.5 kwq/KWQLogging.m
--- kwq/KWQLogging.m	2003/01/22 00:12:35	1.5
+++ KWQLogging.m	2003/10/20 17:28:10	1.6
@@ -31,3 +31,5 @@ KWQLogChannel KWQLogFrames =            
 KWQLogChannel KWQLogLoading =           { 0x00000020, "WebCoreLogLevel", KWQLogChannelUninitialized };
 
 KWQLogChannel KWQLogPopupBlocking =     { 0x00000040, "WebCoreLogLevel", KWQLogChannelUninitialized };
+
+KWQLogChannel KWQLogEvents =            { 0x00000080, "WebCoreLogLevel", KWQLogChannelUninitialized };
