keyboard-fix-merge.patch.txt   [plain text]


Index: ChangeLog
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/ChangeLog,v
retrieving revision 1.1991.2.2.8.2
diff -u -p -r1.1991.2.2.8.2 ChangeLog
--- ChangeLog	2003/11/14 00:15:45	1.1991.2.2.8.2
+++ ChangeLog	2003/11/16 05:27:41
@@ -1,3 +1,150 @@
+2003-11-15  Maciej Stachowiak  <mjs@apple.com>
+
+	- merged the following fixes from HEAD
+	
+    2003-11-13  Darin Adler  <darin@apple.com>
+
+        Reviewed by Ken.
+
+        - fixed 3452554 -- keyCode attribute for DOM events reports incorrect value
+
+        * khtml/dom/dom2_events.cpp:
+        (UIEvent::keyCode): Return the Windows key code for keydown and keyup events.
+        But for other events, return the character code. This matches IE.
+        (UIEvent::which): Same behavior for now; may need further refinement.
+
+        * kwq/KWQEvent.h: Change QEvent to allow copying. The Qt version probably doesn't
+        allow it, but for us it's no big deal. Our event objects are just data holders.
+        (QKeyEvent::QKeyEvent): Change parameters; take an NSEvent and figure the rest out
+        here. Except for now get the type, button state, and auto repeat flag from the caller
+        because that's a smaller change from how things are done now. I'll take this the next
+        step later.
+        * kwq/KWQEvent.mm:
+        (characterCode): Added. Extracts the character code from the string if it's exactly
+        1 character long.
+        (WindowsKeyCode): Added. Given an event, figures out the Windows key code. 
+        (QKeyEvent::QKeyEvent): Changed to get things from the NSEvent rather than having them
+        passed individually. One change is that _ascii is now the Unicode value of the first
+        character in the string. This causes us to return the Unicode value from keyCode for
+        keypress events. Another change is that we now compute the Windows key code.
+
+        * kwq/KWQKHTMLPart.mm: (KWQKHTMLPart::keyEvent): Change to use the new QKeyEvent
+        constructor, passing in the NSEvent.
+
+        * khtml/xml/dom2_eventsimpl.cpp: (KeyboardEventImpl::KeyboardEventImpl):
+        In APPLE_CHANGES, copy the QKeyEvent using the copy constructor rather than
+        listing the fields. This is easier to maintain when the list of fields changes.
+
+        * khtml/rendering/render_form.cpp: (ComboBoxWidget::eventFilter): Put #if
+        !APPLE_CHANGES around code that constructs a QKeyEvent. We don't ever run this
+        code, but now we can't compile it either so we need the #if.
+
+    2003-11-12  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by Richard
+
+	Fix for this bug:
+
+	<rdar://problem/3481600>: key event objects do not preserve unmodified keys
+
+        * khtml/xml/dom2_eventsimpl.cpp: Modified constructor call to include
+	unmodifiedText.
+        (KeyboardEventImpl::KeyboardEventImpl):
+        * kwq/KWQEvent.h: Added unmodifiedText accessor and variable to QKeyEvent.
+        * kwq/KWQEvent.mm:
+        (QKeyEvent::QKeyEvent): Modified constructor to include unmodifiedText.
+        (QKeyEvent::unmodifiedText): Added accessor.
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::keyEvent): Modified constructor call to include
+        unmodifiedText.
+
+    2003-11-05  Darin Adler  <darin@apple.com>
+
+        Reviewed by Maciej.
+
+        - fixed 3475109 -- support keyboard event object properties of altkey, ctrlKey, shiftKey
+
+        We had the DOM Level 3 KeyboardEvent class already; I just had to add JavaScript bindings.
+
+        * khtml/ecma/kjs_events.h: Added DOMKeyboardEvent class.
+        * khtml/ecma/kjs_events.cpp:
+        (KJS::getDOMEvent): Added code to make a DOMKeyboardEvent if the event is a DOM::KeyboardEvent.
+        (DOMKeyboardEvent::~DOMKeyboardEvent): Added.
+        (DOMKeyboardEvent::classInfo): Added.
+        (DOMKeyboardEvent::tryGet): Added.
+        (DOMKeyboardEvent::getValueProperty): Added.
+        (DOMKeyboardEventProtoFunc::tryCall): Added.
+
+        * khtml/dom/dom2_events.cpp:
+        (KeyboardEvent::keyIdentifier): Added.
+        (KeyboardEvent::keyLocation): Added.
+
+        * khtml/ecma/kjs_events.lut.h: Regenerated.
+
+    2003-10-20  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by David
+
+        * khtml/dom/dom2_events.cpp:
+        (UIEvent::keyCode): Change over to use ascii value for key code.
+        (UIEvent::which): Ditto.
+        (KeyboardEvent::KeyboardEvent): New key event class which
+	tracks the DOM Level 3 spec more closely.
+        (KeyboardEvent::operator = ): New function.
+        (KeyboardEvent::~KeyboardEvent): New function.
+        (KeyboardEvent::ctrlKey): New function.
+        (KeyboardEvent::shiftKey): New function.
+        (KeyboardEvent::altKey): New function.
+        (KeyboardEvent::metaKey): New function.
+        (KeyboardEvent::altGraphKey): New function.
+        (KeyboardEvent::initKeyboardEvent): New function.
+        * khtml/dom/dom2_events.h: Ditto.
+        * khtml/html/html_formimpl.cpp:
+        (HTMLGenericFormElementImpl::defaultEventHandler): Use key 
+	identifiers to test which key was pressed, instead of removed keyVal().
+        (HTMLInputElementImpl::defaultEventHandler): Ditto.
+        (HTMLSelectElementImpl::defaultEventHandler): Ditto.
+        * khtml/html/html_inlineimpl.cpp:
+        (HTMLAnchorElementImpl::defaultEventHandler): Change casts to match new
+	class name. Use key identifiers to test which key was pressed, 
+	instead of removed keyVal(). Use new modifier accessors.
+        * khtml/xml/dom2_eventsimpl.cpp:
+        (EventImpl::typeToId): Some reorganization of the constants in the
+	switch statements. Name change for these to remove the KHTML_ prefix
+	from the key up and key down events will happen soon.
+        (EventImpl::idToType): Ditto.
+        (KeyboardEventImpl::KeyboardEventImpl): New key event class which
+        tracks the DOM Level 3 spec more closely.
+        (KeyboardEventImpl::~KeyboardEventImpl): Ditto.
+        (KeyboardEventImpl::initKeyboardEvent): Ditto.
+        * khtml/xml/dom2_eventsimpl.h:
+        (DOM::EventImpl::): Some reorganization of the constants in the
+        switch statements. Name change for these to remove the KHTML_ prefix
+        from the key up and key down events will happen soon.
+        (DOM::KeyboardEventImpl::keyIdentifier): New function.
+        (DOM::KeyboardEventImpl::keyLocation): New function.
+        (DOM::KeyboardEventImpl::ctrlKey): New function.
+        (DOM::KeyboardEventImpl::shiftKey): New function.
+        (DOM::KeyboardEventImpl::altKey): New function.
+        (DOM::KeyboardEventImpl::metaKey): New function.
+        (DOM::KeyboardEventImpl::altGraphKey): New function.
+        (DOM::KeyboardEventImpl::qKeyEvent): New function.
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::createEvent): Now can create keyboard events.
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeImpl::dispatchKeyEvent): Class name changes.
+        * kwq/KWQEvent.h: Added QString identifier member.
+        * kwq/KWQEvent.mm:
+        (hexDigit): Added helper.
+        (identifierForKeyText): Added new function to map keys to DOM
+	key identifiers as listed in the DOM spec.
+        (QKeyEvent::identifier): Added accessor.
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::stateForCurrentEvent): Added check to see if
+	a key press is on one of the numeric keypad keys.
+        * kwq/KWQLogging.h: Added log constant for DOM events.
+        * kwq/KWQLogging.m: Ditto
+
 2003-11-13  Vicki Murley  <vicki@apple.com>
 
         Reviewed by NOBODY (OOPS!).
Index: khtml/dom/dom2_events.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/dom/dom2_events.cpp,v
retrieving revision 1.11
diff -u -p -r1.11 khtml/dom/dom2_events.cpp
--- khtml/dom/dom2_events.cpp	2003/04/02 00:46:02	1.11
+++ khtml/dom/dom2_events.cpp	2003/11/16 05:27:41
@@ -261,11 +261,17 @@ int UIEvent::keyCode() const
     if (!impl)
 	throw DOMException(DOMException::INVALID_STATE_ERR);
     
-    KeyEventImpl *keyEvent = dynamic_cast<KeyEventImpl*>(impl);
-    if (keyEvent)
-        return keyEvent->keyVal();
-    else
-        return 0;
+    KeyboardEventImpl *keyEvent = dynamic_cast<KeyboardEventImpl*>(impl);
+    if (keyEvent) {
+#if APPLE_CHANGES
+        if (impl->id() == EventImpl::KHTML_KEYDOWN_EVENT || impl->id() == EventImpl::KHTML_KEYUP_EVENT) {
+            return keyEvent->qKeyEvent()->WindowsKeyCode();
+        }
+#endif
+        return keyEvent->qKeyEvent()->ascii();
+    }
+
+    return 0;
 }
 
 int UIEvent::pageX() const
@@ -323,10 +329,16 @@ 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);
-    if (keyEvent)
-        return keyEvent->keyVal();
+    // Netscape's "which" returns a virtual key code for keydown and keyup, and a character code for keypress.
+    KeyboardEventImpl *keyEvent = dynamic_cast<KeyboardEventImpl*>(impl);
+    if (keyEvent) {
+#if APPLE_CHANGES
+        if (impl->id() == EventImpl::KHTML_KEYDOWN_EVENT || impl->id() == EventImpl::KHTML_KEYUP_EVENT) {
+            return keyEvent->qKeyEvent()->WindowsKeyCode();
+        }
+#endif
+        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 +611,120 @@ void MutationEvent::initMutationEvent(co
 }
 
 
+// -----------------------------------------------------------------------------
+
+KeyboardEvent::KeyboardEvent()
+{
+}
+
+KeyboardEvent::KeyboardEvent(const KeyboardEvent &other) : UIEvent(other)
+{
+}
+
+KeyboardEvent::KeyboardEvent(const Event &other)
+{
+    *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()
+{
+}
+
+DOMString KeyboardEvent::keyIdentifier() const
+{
+    if (!impl)
+	throw DOMException(DOMException::INVALID_STATE_ERR);
+
+    return static_cast<KeyboardEventImpl*>(impl)->keyIdentifier();
+}
+
+unsigned long KeyboardEvent::keyLocation() const
+{
+    if (!impl)
+	throw DOMException(DOMException::INVALID_STATE_ERR);
+
+    return static_cast<KeyboardEventImpl*>(impl)->keyLocation();
+}
+
+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
diff -u -p -r1.10 khtml/dom/dom2_events.h
--- khtml/dom/dom2_events.h	2003/04/02 00:46:02	1.10
+++ khtml/dom/dom2_events.h	2003/11/16 05:27:41
@@ -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/ecma/kjs_events.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/ecma/kjs_events.cpp,v
retrieving revision 1.17
diff -u -p -r1.17 khtml/ecma/kjs_events.cpp
--- khtml/ecma/kjs_events.cpp	2003/05/13 21:19:56	1.17
+++ khtml/ecma/kjs_events.cpp	2003/11/16 05:27:41
@@ -33,6 +33,8 @@
 
 using namespace KJS;
 
+using DOM::KeyboardEvent;
+
 // -------------------------------------------------------------------------
 
 JSEventListener::JSEventListener(Object _listener, const Object &_win, bool _html)
@@ -303,7 +305,9 @@ Value KJS::getDOMEvent(ExecState *exec, 
     return Value(ret);
 
   DOM::DOMString module = e.eventModuleName();
-  if (module == "UIEvents")
+  if (e.handle()->isKeyboardEvent())
+    ret = new DOMKeyboardEvent(exec, static_cast<DOM::KeyboardEvent>(e));
+  else if (module == "UIEvents")
     ret = new DOMUIEvent(exec, static_cast<DOM::UIEvent>(e));
   else if (module == "MouseEvents")
     ret = new DOMMouseEvent(exec, static_cast<DOM::MouseEvent>(e));
@@ -563,6 +567,94 @@ Value DOMMouseEventProtoFunc::tryCall(Ex
                                 args[12].toBoolean(exec), // metaKeyArg
                                 args[13].toInteger(exec), // buttonArg
                                 toNode(args[14])); // relatedTargetArg
+      return Undefined();
+  }
+  return Undefined();
+}
+
+// -------------------------------------------------------------------------
+
+const ClassInfo DOMKeyboardEvent::info = { "KeyboardEvent", &DOMUIEvent::info, &DOMKeyboardEventTable, 0 };
+
+/*
+@begin DOMKeyboardEventTable 5
+  keyIdentifier	DOMKeyboardEvent::KeyIdentifier	DontDelete|ReadOnly
+  keyLocation	DOMKeyboardEvent::KeyLocation	DontDelete|ReadOnly
+  ctrlKey	DOMKeyboardEvent::CtrlKey	DontDelete|ReadOnly
+  shiftKey	DOMKeyboardEvent::ShiftKey	DontDelete|ReadOnly
+  altKey	DOMKeyboardEvent::AltKey	DontDelete|ReadOnly
+  metaKey	DOMKeyboardEvent::MetaKey	DontDelete|ReadOnly
+  altGraphKey	DOMKeyboardEvent::AltGraphKey	DontDelete|ReadOnly
+@end
+@begin DOMKeyboardEventProtoTable 1
+  initKeyboardEvent	DOMKeyboardEvent::InitKeyboardEvent	DontDelete|Function 11
+@end
+*/
+DEFINE_PROTOTYPE("DOMKeyboardEvent", DOMKeyboardEventProto)
+IMPLEMENT_PROTOFUNC(DOMKeyboardEventProtoFunc)
+IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMKeyboardEventProto, DOMKeyboardEventProtoFunc, DOMUIEventProto)
+
+DOMKeyboardEvent::~DOMKeyboardEvent()
+{
+}
+
+const ClassInfo* DOMKeyboardEvent::classInfo() const
+{
+    return &info;
+}
+
+Value DOMKeyboardEvent::tryGet(ExecState *exec, const Identifier &p) const
+{
+#ifdef KJS_VERBOSE
+  kdDebug(6070) << "DOMKeyboardEvent::tryGet " << p.qstring() << endl;
+#endif
+  return DOMObjectLookupGetValue<DOMKeyboardEvent, DOMUIEvent>(exec, p, &DOMKeyboardEventTable, this);
+}
+
+Value DOMKeyboardEvent::getValueProperty(ExecState *exec, int token) const
+{
+  switch (token) {
+  case KeyIdentifier:
+    return String(static_cast<KeyboardEvent>(event).keyIdentifier());
+  case KeyLocation:
+    return Number(static_cast<KeyboardEvent>(event).keyLocation());
+  case CtrlKey:
+    return Boolean(static_cast<KeyboardEvent>(event).ctrlKey());
+  case ShiftKey:
+    return Boolean(static_cast<KeyboardEvent>(event).shiftKey());
+  case AltKey:
+    return Boolean(static_cast<KeyboardEvent>(event).altKey());
+  case MetaKey:
+    return Boolean(static_cast<KeyboardEvent>(event).metaKey());
+  case AltGraphKey:
+    return Boolean(static_cast<KeyboardEvent>(event).altGraphKey());
+  default:
+    kdWarning() << "Unhandled token in DOMKeyboardEvent::getValueProperty : " << token << endl;
+    return Value();
+  }
+}
+
+Value DOMKeyboardEventProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+  if (!thisObj.inherits(&DOMKeyboardEvent::info)) {
+    Object err = Error::create(exec,TypeError);
+    exec->setException(err);
+    return err;
+  }
+  KeyboardEvent event = static_cast<DOMKeyboardEvent *>(thisObj.imp())->toKeyboardEvent();
+  switch (id) {
+    case DOMKeyboardEvent::InitKeyboardEvent:
+      event.initKeyboardEvent(args[0].toString(exec).string(), // typeArg
+                              args[1].toBoolean(exec), // canBubbleArg
+                              args[2].toBoolean(exec), // cancelableArg
+                              toAbstractView(args[3]), // viewArg
+                              args[4].toString(exec).string(), // keyIdentifier
+                              args[5].toInteger(exec), // keyLocationArg
+                              args[6].toBoolean(exec), // ctrlKeyArg
+                              args[7].toBoolean(exec), // altKeyArg
+                              args[8].toBoolean(exec), // shiftKeyArg
+                              args[9].toBoolean(exec), // metaKeyArg
+                              args[10].toBoolean(exec)); // altGraphKeyArg
       return Undefined();
   }
   return Undefined();
Index: khtml/ecma/kjs_events.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/ecma/kjs_events.h,v
retrieving revision 1.12
diff -u -p -r1.12 khtml/ecma/kjs_events.h
--- khtml/ecma/kjs_events.h	2003/04/02 00:46:02	1.12
+++ khtml/ecma/kjs_events.h	2003/11/16 05:27:41
@@ -128,6 +128,19 @@ namespace KJS {
     DOM::MouseEvent toMouseEvent() const { return static_cast<DOM::MouseEvent>(event); }
   };
 
+  class DOMKeyboardEvent : public DOMUIEvent {
+  public:
+    DOMKeyboardEvent(ExecState *exec, DOM::KeyboardEvent ke) : DOMUIEvent(exec, ke) {}
+    ~DOMKeyboardEvent();
+    virtual Value tryGet(ExecState *exec, const Identifier &p) const;
+    Value getValueProperty(ExecState *, int token) const;
+    // no put - all read-only
+    virtual const ClassInfo* classInfo() const;
+    static const ClassInfo info;
+    enum { KeyIdentifier, KeyLocation, CtrlKey, ShiftKey, AltKey, MetaKey, AltGraphKey, InitKeyboardEvent};
+    DOM::KeyboardEvent toKeyboardEvent() const { return event; }
+  };
+
   // Constructor object MutationEvent
   class MutationEventConstructor : public DOMObject {
   public:
Index: khtml/ecma/kjs_events.lut.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/ecma/kjs_events.lut.h,v
retrieving revision 1.5
diff -u -p -r1.5 khtml/ecma/kjs_events.lut.h
--- khtml/ecma/kjs_events.lut.h	2002/12/15 01:48:23	1.5
+++ khtml/ecma/kjs_events.lut.h	2003/11/16 05:27:41
@@ -26,7 +26,7 @@ const struct HashEntry EventConstructorT
 
 const struct HashTable EventConstructorTable = { 2, 19, EventConstructorTableEntries, 3 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
@@ -47,7 +47,7 @@ const struct HashEntry DOMEventTableEntr
 
 const struct HashTable DOMEventTable = { 2, 12, DOMEventTableEntries, 7 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
@@ -61,7 +61,7 @@ const struct HashEntry DOMEventProtoTabl
 
 const struct HashTable DOMEventProtoTable = { 2, 5, DOMEventProtoTableEntries, 3 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
@@ -71,7 +71,7 @@ const struct HashEntry EventExceptionCon
 
 const struct HashTable EventExceptionConstructorTable = { 2, 1, EventExceptionConstructorTableEntries, 1 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
@@ -92,7 +92,7 @@ const struct HashEntry DOMUIEventTableEn
 
 const struct HashTable DOMUIEventTable = { 2, 12, DOMUIEventTableEntries, 8 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
@@ -102,7 +102,7 @@ const struct HashEntry DOMUIEventProtoTa
 
 const struct HashTable DOMUIEventProtoTable = { 2, 1, DOMUIEventProtoTableEntries, 1 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
@@ -127,7 +127,7 @@ const struct HashEntry DOMMouseEventTabl
 
 const struct HashTable DOMMouseEventTable = { 2, 16, DOMMouseEventTableEntries, 2 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
@@ -137,10 +137,37 @@ const struct HashEntry DOMMouseEventProt
 
 const struct HashTable DOMMouseEventProtoTable = { 2, 1, DOMMouseEventProtoTableEntries, 1 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
+const struct HashEntry DOMKeyboardEventTableEntries[] = {
+   { "metaKey", DOMKeyboardEvent::MetaKey, DontDelete|ReadOnly, 0, 0 },
+   { "keyIdentifier", DOMKeyboardEvent::KeyIdentifier, DontDelete|ReadOnly, 0, &DOMKeyboardEventTableEntries[7] },
+   { 0, 0, 0, 0, 0 },
+   { "altKey", DOMKeyboardEvent::AltKey, DontDelete|ReadOnly, 0, 0 },
+   { "keyLocation", DOMKeyboardEvent::KeyLocation, DontDelete|ReadOnly, 0, &DOMKeyboardEventTableEntries[5] },
+   { "ctrlKey", DOMKeyboardEvent::CtrlKey, DontDelete|ReadOnly, 0, &DOMKeyboardEventTableEntries[6] },
+   { "shiftKey", DOMKeyboardEvent::ShiftKey, DontDelete|ReadOnly, 0, 0 },
+   { "altGraphKey", DOMKeyboardEvent::AltGraphKey, DontDelete|ReadOnly, 0, 0 }
+};
+
+const struct HashTable DOMKeyboardEventTable = { 2, 8, DOMKeyboardEventTableEntries, 5 };
+
+} // namespace
+
+namespace KJS {
+
+const struct HashEntry DOMKeyboardEventProtoTableEntries[] = {
+   { "initKeyboardEvent", DOMKeyboardEvent::InitKeyboardEvent, DontDelete|Function, 11, 0 }
+};
+
+const struct HashTable DOMKeyboardEventProtoTable = { 2, 1, DOMKeyboardEventProtoTableEntries, 1 };
+
+} // namespace
+
+namespace KJS {
+
 const struct HashEntry MutationEventConstructorTableEntries[] = {
    { "ADDITION", DOM::MutationEvent::ADDITION, DontDelete|ReadOnly, 0, &MutationEventConstructorTableEntries[3] },
    { "MODIFICATION", DOM::MutationEvent::MODIFICATION, DontDelete|ReadOnly, 0, 0 },
@@ -150,7 +177,7 @@ const struct HashEntry MutationEventCons
 
 const struct HashTable MutationEventConstructorTable = { 2, 4, MutationEventConstructorTableEntries, 3 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
@@ -165,7 +192,7 @@ const struct HashEntry DOMMutationEventT
 
 const struct HashTable DOMMutationEventTable = { 2, 6, DOMMutationEventTableEntries, 5 };
 
-}; // namespace
+} // namespace
 
 namespace KJS {
 
@@ -175,4 +202,4 @@ const struct HashEntry DOMMutationEventP
 
 const struct HashTable DOMMutationEventProtoTable = { 2, 1, DOMMutationEventProtoTableEntries, 1 };
 
-}; // namespace
+} // namespace
Index: khtml/html/html_formimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_formimpl.cpp,v
retrieving revision 1.71
diff -u -p -r1.71 khtml/html/html_formimpl.cpp
--- khtml/html/html_formimpl.cpp	2003/08/26 23:13:37	1.71
+++ khtml/html/html_formimpl.cpp	2003/11/16 05:27:42
@@ -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);
 	}
Index: khtml/html/html_inlineimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/html/html_inlineimpl.cpp,v
retrieving revision 1.17
diff -u -p -r1.17 khtml/html/html_inlineimpl.cpp
--- khtml/html/html_inlineimpl.cpp	2003/07/24 22:07:45	1.17
+++ khtml/html/html_inlineimpl.cpp	2003/11/16 05:27:42
@@ -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/rendering/render_form.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_form.cpp,v
retrieving revision 1.59
diff -u -p -r1.59 khtml/rendering/render_form.cpp
--- khtml/rendering/render_form.cpp	2003/08/27 20:53:13	1.59
+++ khtml/rendering/render_form.cpp	2003/11/16 05:27:42
@@ -898,6 +898,7 @@ bool ComboBoxWidget::event(QEvent *e)
 
 bool ComboBoxWidget::eventFilter(QObject *dest, QEvent *e)
 {
+#if !APPLE_CHANGES
     if (dest==listBox() &&  e->type()==QEvent::KeyPress)
     {
 	QKeyEvent *ke = static_cast<QKeyEvent *>(e);
@@ -918,6 +919,7 @@ bool ComboBoxWidget::eventFilter(QObject
 	    return KComboBox::eventFilter(dest, e);
 	}
     }
+#endif
     return KComboBox::eventFilter(dest, e);
 }
 
Index: khtml/xml/dom2_eventsimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom2_eventsimpl.cpp,v
retrieving revision 1.11
diff -u -p -r1.11 khtml/xml/dom2_eventsimpl.cpp
--- khtml/xml/dom2_eventsimpl.cpp	2003/08/18 21:12:40	1.11
+++ khtml/xml/dom2_eventsimpl.cpp	2003/11/16 05:27:42
@@ -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,111 @@ 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;
+#if APPLE_CHANGES
+    m_keyEvent = new QKeyEvent(*key);
+#else
+    m_keyEvent = new QKeyEvent(key->type(), key->key(), key->ascii(), key->state(), key->text(), key->isAutoRepeat(), key->count());
+#endif
+    // 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.7
diff -u -p -r1.7 khtml/xml/dom2_eventsimpl.h
--- khtml/xml/dom2_eventsimpl.h	2003/08/18 21:12:40	1.7
+++ khtml/xml/dom2_eventsimpl.h	2003/11/16 05:27:42
@@ -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
     };
@@ -113,6 +116,8 @@ public:
     virtual bool isUIEvent() { return false; }
     virtual bool isMouseEvent() { return false; }
     virtual bool isMutationEvent() { return false; }
+    virtual bool isKeyboardEvent() { return false; }
+  
     virtual DOMString eventModuleName() { return ""; }
 
     virtual bool propagationStopped() { return m_propagationStopped; }
@@ -121,7 +126,7 @@ public:
     static EventId typeToId(DOMString type);
     static DOMString idToType(EventId id);
 
-    void setDefaultHandled();
+    virtual void setDefaultHandled();
     bool defaultHandled() const { return m_defaultHandled; }
 
 protected:
@@ -234,270 +239,59 @@ protected:
  private:
     void computeLayerPos();
 };
-
 
-// 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; }
-
- QKeyEvent *qKeyEvent;
-
+    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; }
+  
 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.75
diff -u -p -r1.75 khtml/xml/dom_docimpl.cpp
--- khtml/xml/dom_docimpl.cpp	2003/07/30 00:39:43	1.75
+++ khtml/xml/dom_docimpl.cpp	2003/11/16 05:27:42
@@ -2113,6 +2113,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.36
diff -u -p -r1.36 khtml/xml/dom_nodeimpl.cpp
--- khtml/xml/dom_nodeimpl.cpp	2003/08/19 20:58:56	1.36
+++ khtml/xml/dom_nodeimpl.cpp	2003/11/16 05:27:42
@@ -737,14 +737,14 @@ 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);
     // 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())
       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
diff -u -p -r1.30 kwq/KWQEvent.h
--- kwq/KWQEvent.h	2003/05/02 20:09:49	1.30
+++ kwq/KWQEvent.h	2003/11/16 05:27:42
@@ -31,6 +31,12 @@
 #include "KWQPointArray.h"
 #include "KWQString.h"
 
+#ifdef __OBJC__
+@class NSEvent;
+#else
+class NSEvent;
+#endif
+
 class QEvent : public Qt {
 public:
 
@@ -58,9 +64,6 @@ public:
     Type type() const { return _type; }
 
 private:
-    QEvent(const QEvent &);
-    QEvent &operator=(const QEvent &);
-
     Type  _type;
 };
 
@@ -99,9 +102,10 @@ private:
 
 class QKeyEvent : public QEvent {
 public:
-    QKeyEvent(Type type, int key, int ascii, int buttonState, const QString &textVal = QString::null, bool autoRepeat = FALSE, ushort countVal = 1);
+    QKeyEvent(NSEvent *, Type, int buttonState, bool autoRepeat);
 
     int key() const;
+    int WindowsKeyCode() const { return _WindowsKeyCode; }
     ButtonState state() const;
     void accept();
     void ignore();
@@ -109,15 +113,21 @@ public:
     bool isAccepted() const;
     int count()  const;
     QString text() const;
+    QString unmodifiedText() const;
     int ascii() const;
- private:
+    QString identifier() const;
+
+private:
     int _key;
     int _ascii;
     ButtonState _state;
     QString _text;
+    QString _unmodifiedText;
+    QString _identifier;
     bool _autoRepeat;
     int _count;
     bool _isAccepted;
+    int _WindowsKeyCode;
 };
 
 class QFocusEvent : public QEvent {
Index: kwq/KWQEvent.mm
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/kwq/KWQEvent.mm,v
retrieving revision 1.18
diff -u -p -r1.18 kwq/KWQEvent.mm
--- kwq/KWQEvent.mm	2003/01/22 00:12:34	1.18
+++ kwq/KWQEvent.mm	2003/11/16 05:27:42
@@ -58,16 +58,630 @@ 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;
+    }
+}
+
+static int characterCode(NSString *characters)
+{
+    return [characters length] != 1 ? 0 : [characters characterAtIndex:0];
+}
+
+static int WindowsKeyCode(NSEvent *event)
+{
+    switch ([event keyCode]) {
+        // VK_NUMPAD0 (60) Numeric keypad 0 key
+        case 82: return 0x60;
+        // VK_NUMPAD1 (61) Numeric keypad 1 key
+        case 83: return 0x61;
+        // VK_NUMPAD2 (62) Numeric keypad 2 key
+        case 84: return 0x62;
+        // VK_NUMPAD3 (63) Numeric keypad 3 key
+        case 85: return 0x63;
+        // VK_NUMPAD4 (64) Numeric keypad 4 key
+        case 86: return 0x64;
+        // VK_NUMPAD5 (65) Numeric keypad 5 key
+        case 87: return 0x65;
+        // VK_NUMPAD6 (66) Numeric keypad 6 key
+        case 88: return 0x66;
+        // VK_NUMPAD7 (67) Numeric keypad 7 key
+        case 89: return 0x67;
+        // VK_NUMPAD8 (68) Numeric keypad 8 key
+        case 91: return 0x68;
+        // VK_NUMPAD9 (69) Numeric keypad 9 key
+        case 92: return 0x69;
+        // VK_MULTIPLY (6A) Multiply key
+        case 67: return 0x6A;
+        // VK_ADD (6B) Add key
+        case 69: return 0x6B;
+
+        // VK_SUBTRACT (6D) Subtract key
+        case 78: return 0x6D;
+        // VK_DECIMAL (6E) Decimal key
+        case 65: return 0x6E;
+        // VK_DIVIDE (6F) Divide key
+        case 75: return 0x6F;
+     }
+
+    switch (characterCode([event charactersIgnoringModifiers])) {
+        // VK_LBUTTON (01) Left mouse button
+        // VK_RBUTTON (02) Right mouse button
+        // VK_CANCEL (03) Control-break processing
+        // VK_MBUTTON (04) Middle mouse button (three-button mouse)
+        // VK_XBUTTON1 (05)
+        // VK_XBUTTON2 (06)
+
+        // VK_BACK (08) BACKSPACE key
+        case 8: case 0x7F: return 0x08;
+        // VK_TAB (09) TAB key
+        case 9: return 0x09;
+
+        // VK_CLEAR (0C) CLEAR key
+        // handled by key code above
+
+        // VK_RETURN (0D)
+        case 0xD: case 3: return 0x0D;
+
+        // VK_SHIFT (10) SHIFT key
+        // VK_CONTROL (11) CTRL key
+        // VK_MENU (12) ALT key
+
+        // VK_PAUSE (13) PAUSE key
+        case NSPauseFunctionKey: return 0x13;
+
+        // VK_CAPITAL (14) CAPS LOCK key
+        // VK_KANA (15) Input Method Editor (IME) Kana mode
+        // VK_HANGUEL (15) IME Hanguel mode (maintained for compatibility; use VK_HANGUL)
+        // VK_HANGUL (15) IME Hangul mode
+        // VK_JUNJA (17) IME Junja mode
+        // VK_FINAL (18) IME final mode
+        // VK_HANJA (19) IME Hanja mode
+        // VK_KANJI (19) IME Kanji mode
+
+        // VK_ESCAPE (1B) ESC key
+        case 0x1B: return 0x1B;
+
+        // VK_CONVERT (1C) IME convert
+        // VK_NONCONVERT (1D) IME nonconvert
+        // VK_ACCEPT (1E) IME accept
+        // VK_MODECHANGE (1F) IME mode change request
 
-QKeyEvent::QKeyEvent(Type t, int key, int ascii, int buttonState, const QString &text, bool autoRepeat, ushort count)
+        // VK_SPACE (20) SPACEBAR
+        case ' ': return 0x20;
+        // VK_PRIOR (21) PAGE UP key
+        case NSPageUpFunctionKey: return 0x21;
+        // VK_NEXT (22) PAGE DOWN key
+        case NSPageDownFunctionKey: return 0x22;
+        // VK_END (23) END key
+        case NSEndFunctionKey: return 0x23;
+        // VK_HOME (24) HOME key
+        case NSHomeFunctionKey: return 0x24;
+        // VK_LEFT (25) LEFT ARROW key
+        case NSLeftArrowFunctionKey: return 0x25;
+        // VK_UP (26) UP ARROW key
+        case NSUpArrowFunctionKey: return 0x26;
+        // VK_RIGHT (27) RIGHT ARROW key
+        case NSRightArrowFunctionKey: return 0x27;
+        // VK_DOWN (28) DOWN ARROW key
+        case NSDownArrowFunctionKey: return 0x28;
+        // VK_SELECT (29) SELECT key
+        case NSSelectFunctionKey: return 0x29;
+        // VK_PRINT (2A) PRINT key
+        case NSPrintFunctionKey: return 0x2A;
+        // VK_EXECUTE (2B) EXECUTE key
+        case NSExecuteFunctionKey: return 0x2B;
+        // VK_SNAPSHOT (2C) PRINT SCREEN key
+        case NSPrintScreenFunctionKey: return 0x2C;
+        // VK_INSERT (2D) INS key
+        case NSInsertFunctionKey: case NSHelpFunctionKey: return 0x2D;
+        // VK_DELETE (2E) DEL key
+        case NSDeleteFunctionKey: return 0x2E;
+
+        // VK_HELP (2F) HELP key
+
+        //  (30) 0 key
+        case '0': case ')': return 0x30;
+        //  (31) 1 key
+        case '1': case '!': return 0x31;
+        //  (32) 2 key
+        case '2': case '@': return 0x32;
+        //  (33) 3 key
+        case '3': case '#': return 0x33;
+        //  (34) 4 key
+        case '4': case '$': return 0x34;
+        //  (35) 5 key
+        case '5': case '%': return 0x35;
+        //  (36) 6 key
+        case '6': case '^': return 0x36;
+        //  (37) 7 key
+        case '7': case '&': return 0x37;
+        //  (38) 8 key
+        case '8': case '*': return 0x38;
+        //  (39) 9 key
+        case '9': case '(': return 0x39;
+        //  (41) A key
+        case 'a': case 'A': return 0x41;
+        //  (42) B key
+        case 'b': case 'B': return 0x42;
+        //  (43) C key
+        case 'c': case 'C': return 0x43;
+        //  (44) D key
+        case 'd': case 'D': return 0x44;
+        //  (45) E key
+        case 'e': case 'E': return 0x45;
+        //  (46) F key
+        case 'f': case 'F': return 0x46;
+        //  (47) G key
+        case 'g': case 'G': return 0x47;
+        //  (48) H key
+        case 'h': case 'H': return 0x48;
+        //  (49) I key
+        case 'i': case 'I': return 0x49;
+        //  (4A) J key
+        case 'j': case 'J': return 0x4A;
+        //  (4B) K key
+        case 'k': case 'K': return 0x4B;
+        //  (4C) L key
+        case 'l': case 'L': return 0x4C;
+        //  (4D) M key
+        case 'm': case 'M': return 0x4D;
+        //  (4E) N key
+        case 'n': case 'N': return 0x4E;
+        //  (4F) O key
+        case 'o': case 'O': return 0x4F;
+        //  (50) P key
+        case 'p': case 'P': return 0x50;
+        //  (51) Q key
+        case 'q': case 'Q': return 0x51;
+        //  (52) R key
+        case 'r': case 'R': return 0x52;
+        //  (53) S key
+        case 's': case 'S': return 0x53;
+        //  (54) T key
+        case 't': case 'T': return 0x54;
+        //  (55) U key
+        case 'u': case 'U': return 0x55;
+        //  (56) V key
+        case 'v': case 'V': return 0x56;
+        //  (57) W key
+        case 'w': case 'W': return 0x57;
+        //  (58) X key
+        case 'x': case 'X': return 0x58;
+        //  (59) Y key
+        case 'y': case 'Y': return 0x59;
+        //  (5A) Z key
+        case 'z': case 'Z': return 0x5A;
+
+        // VK_LWIN (5B) Left Windows key (Microsoft Natural keyboard)
+        // VK_RWIN (5C) Right Windows key (Natural keyboard)
+        // VK_APPS (5D) Applications key (Natural keyboard)
+        // VK_SLEEP (5F) Computer Sleep key
+
+        // VK_NUMPAD0 (60) Numeric keypad 0 key
+        // VK_NUMPAD1 (61) Numeric keypad 1 key
+        // VK_NUMPAD2 (62) Numeric keypad 2 key
+        // VK_NUMPAD3 (63) Numeric keypad 3 key
+        // VK_NUMPAD4 (64) Numeric keypad 4 key
+        // VK_NUMPAD5 (65) Numeric keypad 5 key
+        // VK_NUMPAD6 (66) Numeric keypad 6 key
+        // VK_NUMPAD7 (67) Numeric keypad 7 key
+        // VK_NUMPAD8 (68) Numeric keypad 8 key
+        // VK_NUMPAD9 (69) Numeric keypad 9 key
+        // VK_MULTIPLY (6A) Multiply key
+        // VK_ADD (6B) Add key
+        // handled by key code above
+
+        // VK_SEPARATOR (6C) Separator key
+
+        // VK_SUBTRACT (6D) Subtract key
+        // VK_DECIMAL (6E) Decimal key
+        // VK_DIVIDE (6F) Divide key
+        // handled by key code above
+
+        // VK_F1 (70) F1 key
+        case NSF1FunctionKey: return 0x70;
+        // VK_F2 (71) F2 key
+        case NSF2FunctionKey: return 0x71;
+        // VK_F3 (72) F3 key
+        case NSF3FunctionKey: return 0x72;
+        // VK_F4 (73) F4 key
+        case NSF4FunctionKey: return 0x73;
+        // VK_F5 (74) F5 key
+        case NSF5FunctionKey: return 0x74;
+        // VK_F6 (75) F6 key
+        case NSF6FunctionKey: return 0x75;
+        // VK_F7 (76) F7 key
+        case NSF7FunctionKey: return 0x76;
+        // VK_F8 (77) F8 key
+        case NSF8FunctionKey: return 0x77;
+        // VK_F9 (78) F9 key
+        case NSF9FunctionKey: return 0x78;
+        // VK_F10 (79) F10 key
+        case NSF10FunctionKey: return 0x79;
+        // VK_F11 (7A) F11 key
+        case NSF11FunctionKey: return 0x7A;
+        // VK_F12 (7B) F12 key
+        case NSF12FunctionKey: return 0x7B;
+        // VK_F13 (7C) F13 key
+        case NSF13FunctionKey: return 0x7C;
+        // VK_F14 (7D) F14 key
+        case NSF14FunctionKey: return 0x7D;
+        // VK_F15 (7E) F15 key
+        case NSF15FunctionKey: return 0x7E;
+        // VK_F16 (7F) F16 key
+        case NSF16FunctionKey: return 0x7F;
+        // VK_F17 (80H) F17 key
+        case NSF17FunctionKey: return 0x80;
+        // VK_F18 (81H) F18 key
+        case NSF18FunctionKey: return 0x81;
+        // VK_F19 (82H) F19 key
+        case NSF19FunctionKey: return 0x82;
+        // VK_F20 (83H) F20 key
+        case NSF20FunctionKey: return 0x83;
+        // VK_F21 (84H) F21 key
+        case NSF21FunctionKey: return 0x84;
+        // VK_F22 (85H) F22 key
+        case NSF22FunctionKey: return 0x85;
+        // VK_F23 (86H) F23 key
+        case NSF23FunctionKey: return 0x86;
+        // VK_F24 (87H) F24 key
+        case NSF24FunctionKey: return 0x87;
+
+        // VK_NUMLOCK (90) NUM LOCK key
+
+        // VK_SCROLL (91) SCROLL LOCK key
+        case NSScrollLockFunctionKey: return 0x91;
+
+        // VK_LSHIFT (A0) Left SHIFT key
+        // VK_RSHIFT (A1) Right SHIFT key
+        // VK_LCONTROL (A2) Left CONTROL key
+        // VK_RCONTROL (A3) Right CONTROL key
+        // VK_LMENU (A4) Left MENU key
+        // VK_RMENU (A5) Right MENU key
+        // VK_BROWSER_BACK (A6) Windows 2000/XP: Browser Back key
+        // VK_BROWSER_FORWARD (A7) Windows 2000/XP: Browser Forward key
+        // VK_BROWSER_REFRESH (A8) Windows 2000/XP: Browser Refresh key
+        // VK_BROWSER_STOP (A9) Windows 2000/XP: Browser Stop key
+        // VK_BROWSER_SEARCH (AA) Windows 2000/XP: Browser Search key
+        // VK_BROWSER_FAVORITES (AB) Windows 2000/XP: Browser Favorites key
+        // VK_BROWSER_HOME (AC) Windows 2000/XP: Browser Start and Home key
+        // VK_VOLUME_MUTE (AD) Windows 2000/XP: Volume Mute key
+        // VK_VOLUME_DOWN (AE) Windows 2000/XP: Volume Down key
+        // VK_VOLUME_UP (AF) Windows 2000/XP: Volume Up key
+        // VK_MEDIA_NEXT_TRACK (B0) Windows 2000/XP: Next Track key
+        // VK_MEDIA_PREV_TRACK (B1) Windows 2000/XP: Previous Track key
+        // VK_MEDIA_STOP (B2) Windows 2000/XP: Stop Media key
+        // VK_MEDIA_PLAY_PAUSE (B3) Windows 2000/XP: Play/Pause Media key
+        // VK_LAUNCH_MAIL (B4) Windows 2000/XP: Start Mail key
+        // VK_LAUNCH_MEDIA_SELECT (B5) Windows 2000/XP: Select Media key
+        // VK_LAUNCH_APP1 (B6) Windows 2000/XP: Start Application 1 key
+        // VK_LAUNCH_APP2 (B7) Windows 2000/XP: Start Application 2 key
+
+        // VK_OEM_1 (BA) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ';:' key
+        case ';': case ':': return 0xBA;
+        // VK_OEM_PLUS (BB) Windows 2000/XP: For any country/region, the '+' key
+        case '=': case '+': return 0xBB;
+        // VK_OEM_COMMA (BC) Windows 2000/XP: For any country/region, the ',' key
+        case ',': case '<': return 0xBC;
+        // VK_OEM_MINUS (BD) Windows 2000/XP: For any country/region, the '-' key
+        case '-': case '_': return 0xBD;
+        // VK_OEM_PERIOD (BE) Windows 2000/XP: For any country/region, the '.' key
+        case '.': case '>': return 0xBE;
+        // VK_OEM_2 (BF) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '/?' key
+        case '/': case '?': return 0xBF;
+        // VK_OEM_3 (C0) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '`~' key
+        case '`': case '~': return 0xC0;
+        // VK_OEM_4 (DB) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '[{' key
+        case '[': case '{': return 0xDB;
+        // VK_OEM_5 (DC) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '\|' key
+        case '\\': case '|': return 0xDC;
+        // VK_OEM_6 (DD) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ']}' key
+        case ']': case '}': return 0xDD;
+        // VK_OEM_7 (DE) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
+        case '\'': case '"': return 0xDE;
+
+        // VK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard.
+        // VK_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
+        // VK_PROCESSKEY (E5) Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key
+        // VK_PACKET (E7) Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT,SendInput, WM_KEYDOWN, and WM_KEYUP
+        // VK_ATTN (F6) Attn key
+        // VK_CRSEL (F7) CrSel key
+        // VK_EXSEL (F8) ExSel key
+        // VK_EREOF (F9) Erase EOF key
+        // VK_PLAY (FA) Play key
+        // VK_ZOOM (FB) Zoom key
+        // VK_NONAME (FC) Reserved for future use
+        // VK_PA1 (FD) PA1 key
+        // VK_OEM_CLEAR (FE) Clear key
+    }
+
+    return 0;
+ }
+ 
+QKeyEvent::QKeyEvent(NSEvent *event, Type t, int buttonState, bool autoRepeat)
     : QEvent(t),
-      _key(key),
-      _ascii(ascii),
+      _key([event keyCode]),
+      _ascii(characterCode([event characters])),
       _state((ButtonState)buttonState),
-      _text(text),
+      _text(QString::fromNSString([event characters])),
+      _unmodifiedText(QString::fromNSString([event charactersIgnoringModifiers])),
+      _identifier(identifierForKeyText(_unmodifiedText)),
       _autoRepeat(autoRepeat),
-      _count(count),
-      _isAccepted(false)
+      _count(1),
+      _isAccepted(false),
+      _WindowsKeyCode(::WindowsKeyCode(event))
 {
 }
 
@@ -101,6 +715,11 @@ QString QKeyEvent::text(void) const
     return _text;
 }
 
+QString QKeyEvent::unmodifiedText(void) const
+{
+    return _unmodifiedText;
+}
+
 int QKeyEvent::ascii(void) const
 {
     return _ascii;
@@ -114,4 +733,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.395.10.1
diff -u -p -r1.395.10.1 kwq/KWQKHTMLPart.mm
--- kwq/KWQKHTMLPart.mm	2003/11/14 00:15:45	1.395.10.1
+++ kwq/KWQKHTMLPart.mm	2003/11/16 05:27:42
@@ -1326,26 +1326,16 @@ bool KWQKHTMLPart::keyEvent(NSEvent *eve
     NSEvent *oldCurrentEvent = _currentEvent;
     _currentEvent = [event retain];
 
-    const char *characters = [[event characters] lossyCString];
-    int ascii = (characters != nil && strlen(characters) == 1) ? characters[0] : 0;
-
-    QKeyEvent qEvent([event type] == NSKeyDown ? QEvent::KeyPress : QEvent::KeyRelease,
-		     [event keyCode],
-		     ascii,
-		     stateForCurrentEvent(),
-		     QString::fromNSString([event characters]),
-		     [event isARepeat]);
+    QEvent::Type type = [event type] == NSKeyDown ? QEvent::KeyPress : QEvent::KeyRelease;
+    QKeyEvent qEvent(event, type, stateForCurrentEvent(), [event isARepeat]);
     bool result = node->dispatchKeyEvent(&qEvent);
 
     // We want to send both a down and a press for the initial key event.
-    // This is a temporary hack; we need to do this a better way.
+    // To get KHTML to do this, we send a second KeyPress QKeyEvent with "is repeat" set to true,
+    // which causes it to send a press to the DOM.
+    // That's not a great hack; it would be good to do this in a better way.
     if ([event type] == NSKeyDown && ![event isARepeat]) {
-	QKeyEvent qEvent(QEvent::KeyPress,
-			 [event keyCode],
-			 ascii,
-			 stateForCurrentEvent(),
-			 QString::fromNSString([event characters]),
-			 true);
+	QKeyEvent qEvent(event, QEvent::KeyPress, stateForCurrentEvent(), true);
         node->dispatchKeyEvent(&qEvent);
     }
 
@@ -1689,6 +1679,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
diff -u -p -r1.6 kwq/KWQLogging.h
--- kwq/KWQLogging.h	2003/01/22 00:12:35	1.6
+++ kwq/KWQLogging.h	2003/11/16 05:27:42
@@ -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
diff -u -p -r1.5 kwq/KWQLogging.m
--- kwq/KWQLogging.m	2003/01/22 00:12:35	1.5
+++ kwq/KWQLogging.m	2003/11/16 05:27:42
@@ -31,3 +31,5 @@ KWQLogChannel KWQLogFrames =            
 KWQLogChannel KWQLogLoading =           { 0x00000020, "WebCoreLogLevel", KWQLogChannelUninitialized };
 
 KWQLogChannel KWQLogPopupBlocking =     { 0x00000040, "WebCoreLogLevel", KWQLogChannelUninitialized };
+
+KWQLogChannel KWQLogEvents =            { 0x00000080, "WebCoreLogLevel", KWQLogChannelUninitialized };