Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
nsGtkEventHandler.cpp File Reference
#include "nsWidget.h"
#include "keysym2ucs.h"
#include "nsWindow.h"
#include "nsAppShell.h"
#include "nsGUIEvent.h"
#include "nsTextWidget.h"
#include "nsGtkIMEHelper.h"
#include <stdio.h>
#include <gtk/gtk.h>
#include <gtk/gtkprivate.h>
#include "nsGtkEventHandler.h"
#include <gdk/gdkkeysyms.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

Go to the source code of this file.

Classes

struct  nsKeyConverter

Defines

#define IS_XSUN_XSERVER(dpy)   (strstr(XServerVendor(dpy), "Sun Microsystems") != NULL)

Functions

static void dispatch_superwin_event (GdkEvent *event, nsWindow *window)
static PRBool gdk_window_child_of_gdk_window (GdkWindow *window, GdkWindow *ancestor)
void InitAllocationEvent (GtkAllocation *aAlloc, nsSizeEvent &anEvent)
int nsPlatformToDOMKeyCode (GdkEventKey *aGEK)
PRUint32 nsConvertCharCodeToUnicode (GdkEventKey *aGEK)
void InitKeyEvent (GdkEventKey *aGEK, nsKeyEvent &anEvent)
void InitKeyPressEvent (GdkEventKey *aGEK, nsKeyEvent &anEvent)
void handle_size_allocate (GtkWidget *w, GtkAllocation *alloc, gpointer p)
gint handle_key_press_event_for_text (GtkObject *w, GdkEventKey *event, gpointer p)
gint handle_key_release_event_for_text (GtkObject *w, GdkEventKey *event, gpointer p)
gint handle_key_press_event (GtkObject *w, GdkEventKey *event, gpointer p)
gint handle_key_release_event (GtkObject *w, GdkEventKey *event, gpointer p)
void handle_gdk_event (GdkEvent *event, gpointer data)
void handle_xlib_shell_event (GdkSuperWin *superwin, XEvent *event, gpointer p)
void handle_superwin_paint (gint aX, gint aY, gint aWidth, gint aHeight, gpointer aData)
void handle_superwin_flush (gpointer aData)

Variables

static PRBool suppressNextKeyDown = PR_FALSE

Class Documentation

struct nsKeyConverter

Definition at line 2227 of file nsWindow.cpp.

Collaboration diagram for nsKeyConverter:
Class Members
char bekeycode
unsigned int keysym
int keysym
unsigned long keysym
PRUint32 vkCode
int vkCode

Define Documentation

#define IS_XSUN_XSERVER (   dpy)    (strstr(XServerVendor(dpy), "Sun Microsystems") != NULL)

Definition at line 209 of file nsGtkEventHandler.cpp.


Function Documentation

void dispatch_superwin_event ( GdkEvent *  event,
nsWindow window 
) [static]

Definition at line 884 of file nsGtkEventHandler.cpp.

{
  if (event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE)
  {
    // Check to see whether or not we need to send this to the
    // toplevel window to get passed to the GtkWidget with focus.
    // This happens in the embedding case.
    if (!nsWidget::sFocusWindow)
    {
      GtkWidget *mozArea = window->GetOwningWidget();
      NS_ASSERTION(mozArea, "Failed to get GtkMozArea for superwin event!\n");
      // get the toplevel window for that widget
      GtkWidget *toplevel = gtk_widget_get_toplevel(mozArea);
      // pass it off to gtk's event system and return
      gboolean handled = gtk_widget_event(toplevel, event);
      if (handled)
        return;
    }
  }

  switch (event->type)
  {
  case GDK_KEY_PRESS:
    handle_key_press_event (NULL, &event->key, window);
    break;
  case GDK_KEY_RELEASE:
    handle_key_release_event (NULL, &event->key, window);
    break;
  default:
    window->HandleGDKEvent (event);
    break;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool gdk_window_child_of_gdk_window ( GdkWindow *  window,
GdkWindow *  ancestor 
) [static]

Definition at line 919 of file nsGtkEventHandler.cpp.

{
  GdkWindow *this_window = window;
  while (this_window)
  {
    if (this_window == ancestor)
      return PR_TRUE;
    this_window = gdk_window_get_parent(this_window);
  }
  return PR_FALSE;
}

Here is the caller graph for this function:

void handle_gdk_event ( GdkEvent *  event,
gpointer  data 
)

Definition at line 672 of file nsGtkEventHandler.cpp.

{
  GtkObject *eventObject = nsnull;

  // set the last time that we got an event.  we need this for drag
  // and drop if you can believe that.
  guint32 event_time = gdk_event_get_time(event);
  if (event_time)
    nsWidget::SetLastEventTime(event_time);

  // Get the next X event serial ID and save it for later for event
  // processing.  If it stays zero then events won't be processed
  // later.  We're using this as a flag too but with a number this big
  // we're probably not going to overflow and even if we did there
  // wouldn't be any harm.
  unsigned long serial = 0;

  if (XPending(GDK_DISPLAY())) {
    XEvent temp_event;
    XPeekEvent(GDK_DISPLAY(), &temp_event);
    serial = temp_event.xany.serial - 1;
  }

  // try to get the user data for the event window.
  if (event->any.window)
    gdk_window_get_user_data (event->any.window, (void **)&eventObject);

  // If there is an event object and it's a superwin then we need to
  // make sure that the event either is handled locally or is passed
  // on with a legitimate GtkWidget object associated with it so the
  // Gtk mainloop doesn't go spastic.

  if (eventObject && GDK_IS_SUPERWIN(eventObject)) {
    // try to find the nsWindow object associated with this superwin
    nsWindow *window = (nsWindow *)gtk_object_get_data (eventObject,
                                                        "nsWindow");

    // If we don't have a window here anymore, we are probably in
    // the process of being or have been destroyed.  give up now.
    if (!window)
      goto end;

    // Find out if there's a grabbing widget.  If there is and it's a
    // regular gtk widget, and our current event window is not the
    // child of that grab widget, we need to rewrite the event to that
    // gtk grabbing widget.
    PRBool rewriteEvent = PR_FALSE;
    GtkWidget *grabWidget = gtk_grab_get_current();
    GtkWidget *owningWidget = window->GetOwningWidget();

    if (grabWidget &&
        !GTK_IS_MOZAREA(grabWidget) &&
        !gdk_window_child_of_gdk_window(owningWidget->window,
                                        grabWidget->window)) {
      rewriteEvent = PR_TRUE;
    }


    // There are a lot of events that are always dispatched to our
    // internal handler, no matter if there is a grab or not.
    switch(event->type)
      {
      case GDK_NOTHING:
        break;

      case GDK_DESTROY:
      case GDK_DELETE:
      case GDK_PROPERTY_NOTIFY:
      case GDK_EXPOSE:
      case GDK_NO_EXPOSE:
      case GDK_FOCUS_CHANGE:
      case GDK_CONFIGURE:
      case GDK_MAP:
      case GDK_UNMAP:
      case GDK_SELECTION_CLEAR:
      case GDK_SELECTION_REQUEST:
      case GDK_SELECTION_NOTIFY:
      case GDK_CLIENT_EVENT:
      case GDK_VISIBILITY_NOTIFY:
        dispatch_superwin_event(event, window);
        break;

      case GDK_BUTTON_PRESS:
      case GDK_2BUTTON_PRESS:
      case GDK_3BUTTON_PRESS:
      case GDK_KEY_PRESS:
      case GDK_KEY_RELEASE:
        // If we need to rewrite this to the nearest real gtk widget,
        // do it here.
        if (rewriteEvent) {
          gdk_window_unref(event->any.window);
          event->any.window = owningWidget->window;
          gdk_window_ref(event->any.window);
          gtk_main_do_event(event);
          break;
        }

        // Otherwise, just send it to our event handler
        if (GTK_WIDGET_IS_SENSITIVE(owningWidget))
          dispatch_superwin_event(event, window);
        break;

      case GDK_MOTION_NOTIFY:
      case GDK_BUTTON_RELEASE:
      case GDK_PROXIMITY_IN:
      case GDK_PROXIMITY_OUT:
        // See above.
        if (rewriteEvent) {
          gdk_window_unref(event->any.window);
          event->any.window = owningWidget->window;
          gdk_window_ref(event->any.window);
          gtk_propagate_event(grabWidget, event);
          break;
        }

        if (GTK_WIDGET_IS_SENSITIVE(owningWidget))
          dispatch_superwin_event(event, window);
        break;

      case GDK_ENTER_NOTIFY:
      case GDK_LEAVE_NOTIFY:
        // Always dispatch enter and leave notify events to the
        // windows that they happened on so that state can be properly
        // tracked.  The code that handles the enter and leave events
        // tracks sensitivity as well.
        dispatch_superwin_event(event, window);
        break;

      default:
        // XXX lots of DND events not handled?  I don't think that we have to.
        NS_WARNING("Odd, hit default case in handle_gdk_event()\n");
        break;
      }
  }
  else {
    nsWindow  *grabbingWindow = nsWindow::GetGrabWindow();
    
    nsCOMPtr<nsIWidget> grabbingWindowGuard(grabbingWindow);
    GtkWidget *tempWidget = NULL;
    
    if (grabbingWindow) {
      // get the GdkWindow that we are grabbing on
      GdkWindow *grabbingGdkWindow =
        NS_STATIC_CAST(GdkWindow *,
                       grabbingWindow->GetNativeData(NS_NATIVE_WINDOW));
      
      // If the object getting the event in question is a GtkWidget
      // and it's a child of the grabbing window, we need to put a
      // grab on that window before dispatching the event.  We do this
      // so that the gtk mainloop will recognize the widget in
      // question as having the grab.  If we didn't the mainloop
      // wouldn't think that the widget that got the event is the
      // child of the grabbing window, due to the superwin(s) in the
      // middle.
      if (GTK_IS_WIDGET(eventObject)) {
        tempWidget = GTK_WIDGET(eventObject);
        if (gdk_window_child_of_gdk_window(tempWidget->window,
                                           grabbingGdkWindow)) {
          // this is so awesome.  gtk_grab_add/gtk_grab_remove don't
          // have exact push and pop semantics.  if we call grab_add
          // on the object and as part of the dispatching of this
          // event another grab_add is called on it, we can end up
          // releasing the grab early because we always call
          // grab_remove on the object after dispatching the event.
          // we can end up with a widget that doesn't have a grab on
          // it, even though it should.  the scrollbar does this.
          //
          // so, what we do here is to check and see if the widget in
          // question has a parent.  if it does and it's a mozbox
          // object we slam a grab on that instead of the widget
          // itself.  we know that no one is doing grabs on those.
          if (tempWidget->parent) {
            if (GTK_IS_MOZBOX(tempWidget->parent)) {
              tempWidget = tempWidget->parent;
            }
          }
          gtk_grab_add(tempWidget);
        }
        else  {
          // if the gtk widget in question wasn't the child of the
          // grabbing window then the grabbing window gets it.
          dispatch_superwin_event(event, grabbingWindow);
          goto end;
        }
      }
    }

    gtk_main_do_event(event);

    if (tempWidget)
      gtk_grab_remove(tempWidget);

    if (event->type == GDK_BUTTON_RELEASE) {
      // Always clear the button motion target when sending a
      // button release event to a real gtk widget, otherwise
      // mozilla will still think it has the grab.  This happens
      // when there's a native gtk widget popup over a Mozilla
      // area.
      nsWidget::DropMotionTarget();
    }
  }

 end:

  // use the saved serial to process any pending events, now that all
  // the window events have been processed
  if (serial)
    nsAppShell::ProcessBeforeID(serial);

}

Here is the call graph for this function:

Here is the caller graph for this function:

gint handle_key_press_event ( GtkObject *  w,
GdkEventKey *  event,
gpointer  p 
)

Definition at line 537 of file nsGtkEventHandler.cpp.

{
  nsWidget *win = (nsWidget*)p;

  // if there's a focused window rewrite the event to use that window.
  if (nsWidget::sFocusWindow)
    win = nsWidget::sFocusWindow;

  // work around for annoying things.
  if (event->keyval == GDK_Tab)
    if (event->state & GDK_CONTROL_MASK)
      if (event->state & GDK_MOD1_MASK)
        return PR_FALSE;


  NS_ADDREF(win);

  //
  // First, dispatch the Key event as a virtual key down event
  //   but lie about where it came from and say it is from the
  //   window that currently has focus inside our app...
  //
  PRBool noDefault = PR_FALSE;
  nsKeyEvent keyDownEvent(PR_TRUE, NS_KEY_DOWN, win);
  InitKeyEvent(event, keyDownEvent);
  // if we need to suppress this NS_KEY_DOWN event, reset the flag
  if (suppressNextKeyDown == PR_TRUE)
    suppressNextKeyDown = PR_FALSE;
  else
    noDefault = win->OnKey(keyDownEvent);

  // Don't pass Shift, Alt, Control and Meta as NS_KEY_PRESS events.
  if (event->keyval == GDK_Shift_L
      || event->keyval == GDK_Shift_R
      || event->keyval == GDK_Control_L
      || event->keyval == GDK_Control_R
      || event->keyval == GDK_Alt_L
      || event->keyval == GDK_Alt_R
      || event->keyval == GDK_Meta_L
      || event->keyval == GDK_Meta_R)
    return PR_TRUE;

  //
  // Second, dispatch the Key event as a key press event w/ a Unicode
  //  character code.  Note we have to check for modifier keys, since
  // gtk returns a character value for them
  //

  // Call nsConvertCharCodeToUnicode() here to get kevent.charCode 
  nsKeyEvent keyPressEvent(PR_TRUE, NS_KEY_PRESS, win);
  InitKeyPressEvent(event, keyPressEvent);
  if (noDefault) {  // If prevent default set for onkeydown, do the same for onkeypress
    keyPressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
  }

  if (event->length) {
    if (keyPressEvent.charCode || keyPressEvent.keyCode) {
      // keyPressEvent.charCode or keyPressEvent.keyCode is valid, just 
      // pass to OnKey()
      win->OnKey(keyPressEvent);
    } else if (nsGtkIMEHelper::GetSingleton()) {
      // commit request from IME
      win->IMECommitEvent(event);
    }
  } else { // for Home/End/Up/Down/Left/Right/PageUp/PageDown key
    win->OnKey(keyPressEvent);
  }

  NS_RELEASE(win);

  if (w)
  {
    gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_press_event");
  }

  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

gint handle_key_press_event_for_text ( GtkObject *  w,
GdkEventKey *  event,
gpointer  p 
)

Definition at line 466 of file nsGtkEventHandler.cpp.

{
  nsTextWidget* win = (nsTextWidget*)p;

  // work around for annoying things.
  if (event->keyval == GDK_Tab)
    if (event->state & GDK_CONTROL_MASK)
      if (event->state & GDK_MOD1_MASK)
        return PR_FALSE;

  NS_ADDREF(win);
  nsKeyEvent keyDownEvent(PR_TRUE, NS_KEY_DOWN, win);
  InitKeyEvent(event, keyDownEvent);
  PRBool noDefault = win->OnKey(keyDownEvent);

  // Don't pass Shift, Control, Alt and Meta as NS_KEY_PRESS events.
  if (event->keyval == GDK_Shift_L
      || event->keyval == GDK_Shift_R
      || event->keyval == GDK_Control_L
      || event->keyval == GDK_Control_R
      || event->keyval == GDK_Alt_L
      || event->keyval == GDK_Alt_R
      || event->keyval == GDK_Meta_L
      || event->keyval == GDK_Meta_R
     )
    return PR_TRUE;

  //
  // Second, dispatch the Key event as a key press event w/ a Unicode
  //  character code.  Note we have to check for modifier keys, since
  // gtk returns a character value for them
  //
  nsKeyEvent keyPressEvent(PR_TRUE, NS_KEY_PRESS, win);
  InitKeyPressEvent(event, keyPressEvent);
  if (noDefault) {  // If prevent default set for onkeydown, do the same for onkeypress
   keyPressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
  }

  win->OnKey(keyPressEvent);

  NS_RELEASE(win);
  if (w)
  {
    gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_press_event");
  }

  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

gint handle_key_release_event ( GtkObject *  w,
GdkEventKey *  event,
gpointer  p 
)

Definition at line 616 of file nsGtkEventHandler.cpp.

{
  XEvent nextEvent;
  PRBool    shouldDrop = PR_FALSE;
  // According to the DOM spec if this is the result of a key repeat
  // event we don't let it through since the DOM wants the event
  // stream to look like this: press press press press release.  The
  // way that X does things is to do press release press release, etc.
  // We check to see if this is a key release by checking to see if
  // the next event in the queue is a key press event and it has the
  // exact same timestamp as the current event.

  // have a look in the X queue to see if there's another event in the
  // queue.

  if (XPending(GDK_DISPLAY())) {
    // get a copy of the next event
    XPeekEvent(GDK_DISPLAY(), &nextEvent);
    
    // see if it's a key press event and if it has the same time as
    // the last event.
    if ((nextEvent.xany.type == KeyPress) &&
        (nextEvent.xkey.time == event->time))
    {
      shouldDrop = PR_TRUE;
      // the next key press event shouldn't generate a key down event.
      // this is a global variable
      suppressNextKeyDown = PR_TRUE;
    }
  }

  // should we drop this event?
  if (shouldDrop)
    return PR_TRUE;

  nsWidget *win = (nsWidget *)p;
  if (nsWidget::sFocusWindow)
    win = nsWidget::sFocusWindow;

  nsKeyEvent kevent(PR_TRUE, NS_KEY_UP, win);
  InitKeyEvent(event, kevent);

  NS_ADDREF(win);
  win->OnKey(kevent);
  NS_RELEASE(win);

  if (w)
  {
    gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_release_event");
  }

  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

gint handle_key_release_event_for_text ( GtkObject *  w,
GdkEventKey *  event,
gpointer  p 
)

Definition at line 517 of file nsGtkEventHandler.cpp.

{
  nsTextWidget* win = (nsTextWidget*)p;
  nsKeyEvent kevent(PR_TRUE, NS_KEY_UP, win);
  InitKeyEvent(event, kevent);
  NS_ADDREF(win);
  win->OnKey(kevent);
  NS_RELEASE(win);
  
  if (w)
  {
    gtk_signal_emit_stop_by_name (GTK_OBJECT(w), "key_release_event");
  }

  return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void handle_size_allocate ( GtkWidget *  w,
GtkAllocation *  alloc,
gpointer  p 
)

Definition at line 452 of file nsGtkEventHandler.cpp.

{
  nsWindow *widget = (nsWindow *)p;
  nsSizeEvent event(PR_TRUE, NS_SIZE, widget);

  InitAllocationEvent(alloc, event);
  NS_ADDREF(widget);
  widget->OnResize(&event);
  NS_RELEASE(widget);

  delete event.windowSize;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void handle_superwin_flush ( gpointer  aData)

Definition at line 961 of file nsGtkEventHandler.cpp.

{
  nsWindow *window = (nsWindow *)aData;
  window->Update();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void handle_superwin_paint ( gint  aX,
gint  aY,
gint  aWidth,
gint  aHeight,
gpointer  aData 
)

Definition at line 948 of file nsGtkEventHandler.cpp.

{
  nsWindow *window = (nsWindow *)aData;
  nsRect    rect;
  rect.x = aX;
  rect.y = aY;
  rect.width = aWidth;
  rect.height = aHeight;
  window->Invalidate(rect, PR_FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void handle_xlib_shell_event ( GdkSuperWin *  superwin,
XEvent *  event,
gpointer  p 
)

Definition at line 934 of file nsGtkEventHandler.cpp.

{
  nsWindow *window = (nsWindow *)p;
  switch(event->xany.type) {
  case ConfigureNotify:
    window->HandleXlibConfigureNotifyEvent(event);
    break;
  default:
    break;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void InitAllocationEvent ( GtkAllocation *  aAlloc,
nsSizeEvent anEvent 
)

Definition at line 79 of file nsGtkEventHandler.cpp.

{
  if (aAlloc != nsnull) {
    // HACK
    //    nsRect *foo = new nsRect(aAlloc->x, aAlloc->y, aAlloc->width, aAlloc->height);
    nsRect *foo = new nsRect(0, 0, aAlloc->width, aAlloc->height);
    anEvent.windowSize = foo;
    //    anEvent.point.x = aAlloc->x;
    //    anEvent.point.y = aAlloc->y;
    // HACK
    anEvent.mWinWidth = aAlloc->width;
    anEvent.mWinHeight = aAlloc->height;
  }

  anEvent.time = PR_IntervalNow();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void InitKeyEvent ( GdkEventKey *  aGEK,
nsKeyEvent anEvent 
)

Definition at line 374 of file nsGtkEventHandler.cpp.

{
  if (aGEK != nsnull) {
    anEvent.keyCode = nsPlatformToDOMKeyCode(aGEK);
    anEvent.time = aGEK->time;
    anEvent.isShift = (aGEK->state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
    anEvent.isControl = (aGEK->state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
    anEvent.isAlt = (aGEK->state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE;
    anEvent.isMeta = (aGEK->state & GDK_MOD4_MASK) ? PR_TRUE : PR_FALSE;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void InitKeyPressEvent ( GdkEventKey *  aGEK,
nsKeyEvent anEvent 
)

Definition at line 387 of file nsGtkEventHandler.cpp.

{
  //
  // init the basic event fields
  //

  if (aGEK!=nsnull) {
    anEvent.isShift = (aGEK->state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
    anEvent.isControl = (aGEK->state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
    anEvent.isAlt = (aGEK->state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE;
    anEvent.isMeta = (aGEK->state & GDK_MOD4_MASK) ? PR_TRUE : PR_FALSE;

    anEvent.charCode = nsConvertCharCodeToUnicode(aGEK);
    if (anEvent.charCode) {
      // if the control, meta, or alt key is down, then we should leave
      // the isShift flag alone (probably not a printable character)
      // if none of the other modifier keys are pressed then we need to
      // clear isShift so the character can be inserted in the editor

      if ( anEvent.isControl || anEvent.isAlt || anEvent.isMeta ) {
         // make Ctrl+uppercase functional as same as Ctrl+lowercase
         // when Ctrl+uppercase(eg.Ctrl+C) is pressed,convert the charCode
         // from uppercase to lowercase(eg.Ctrl+c),so do Alt and Meta Key
         // It is hack code for bug 61355, there is same code snip for
         // Windows platform in widget/src/windows/nsWindow.cpp: See bug 16486
         // Note: if Shift is pressed at the same time, do not to_lower()
         // Because Ctrl+Shift has different function with Ctrl
        if ( (anEvent.charCode >= GDK_A && anEvent.charCode <= GDK_Z) ||
             (anEvent.charCode >= GDK_a && anEvent.charCode <= GDK_z) ) {
          anEvent.charCode = (anEvent.isShift) ? 
            gdk_keyval_to_upper(anEvent.charCode) : 
            gdk_keyval_to_lower(anEvent.charCode);
        }
      }
    } else {
      anEvent.keyCode = nsPlatformToDOMKeyCode(aGEK);
    }

#if defined(DEBUG_akkana_not) || defined (DEBUG_ftang)
    if (!aGEK->length) printf("!length, ");
    printf("Key Press event: gtk string = '%s', keyval = '%c' = %d,\n",
           aGEK->string, aGEK->keyval, aGEK->keyval);
    printf("    --> keyCode = 0x%x, char code = '%c'",
           anEvent.keyCode, anEvent.charCode);
    if (anEvent.isShift)
      printf(" [shift]");
    if (anEvent.isControl)
      printf(" [ctrl]");
    if (anEvent.isAlt)
      printf(" [alt]");
    if (anEvent.isMeta)
      printf(" [meta]");
    printf("\n");
#endif

    anEvent.time = aGEK->time;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRUint32 nsConvertCharCodeToUnicode ( GdkEventKey *  aGEK)

Definition at line 279 of file nsGtkEventHandler.cpp.

{
  // Anything above 0xf000 is considered a non-printable
  // Exception: directly encoded UCS characters
  if (aGEK->keyval > 0xf000 && (aGEK->keyval & 0xff000000) != 0x01000000) {
    // Keypad keys are an exception: they return a value different
    // from their non-keypad equivalents, but mozilla doesn't distinguish.
    switch (aGEK->keyval)
    {
      case GDK_KP_Space:
        return ' ';
      case GDK_KP_Equal:
        return '=';
      case GDK_KP_Multiply:
        return '*';
      case GDK_KP_Add:
        return '+';
      case GDK_KP_Separator:
        return ',';
      case GDK_KP_Subtract:
        return '-';
      case GDK_KP_Decimal:
        return '.';
      case GDK_KP_Divide:
        return '/';
      case GDK_KP_0:
        return '0';
      case GDK_KP_1:
        return '1';
      case GDK_KP_2:
        return '2';
      case GDK_KP_3:
        return '3';
      case GDK_KP_4:
        return '4';
      case GDK_KP_5:
        return '5';
      case GDK_KP_6:
        return '6';
      case GDK_KP_7:
        return '7';
      case GDK_KP_8:
        return '8';
      case GDK_KP_9:
        return '9';
    }

    // non-printables
    return 0;
  }

#if defined(USE_XIM) && defined(_AIX)
  // On AIX, GDK doesn't get correct keysyms from XIM. Follow GDK 
  // reference recommending to use the 'string' member of GdkEventKey 
  // instead. See:
  //
  // developer.gnome.org/doc/API/gdk/gdk-event-structures.html#GDKEVENTKEY

  PRBool controlChar = (aGEK->state & GDK_CONTROL_MASK ||
                        aGEK->state & GDK_MOD1_MASK ||
                        aGEK->state & GDK_MOD4_MASK);

  // Use 'string' as opposed to 'keyval' when control, alt, or meta is 
  // not pressed. This allows keyboard shortcuts to continue to function
  // properly, while fixing input problems and mode switching in certain
  // locales where the 'keyval' does not correspond to the actual input.
  // See Bug #157397 and Bug #161581 for more details.

  if (!controlChar && gdk_im_ready() && aGEK->length > 0 
        && aGEK->keyval != (guint)*aGEK->string) {
    nsGtkIMEHelper* IMEHelper = nsGtkIMEHelper::GetSingleton();
    if (IMEHelper != nsnull) {
      PRUnichar* unichars = IMEHelper->GetUnichars();
      PRInt32 unilen = IMEHelper->GetUnicharsSize();
      PRInt32 unichar_size = IMEHelper->MultiByteToUnicode(
                                          aGEK->string, aGEK->length,
                                          &unichars, &unilen);
      if (unichar_size > 0) {
        IMEHelper->SetUnichars(unichars);
        IMEHelper->SetUnicharsSize(unilen);
        return (long)*unichars;
      }
    }
  }
#endif
  // we're supposedly printable, let's try to convert
  long ucs = keysym2ucs(aGEK->keyval);
  if ((ucs != -1) && (ucs < 0x10000))
    return ucs;

  // I guess we couldn't convert
  return 0;
}

Here is the caller graph for this function:

int nsPlatformToDOMKeyCode ( GdkEventKey *  aGEK)

Definition at line 226 of file nsGtkEventHandler.cpp.

{
  int i, length = 0;
  int keysym = aGEK->keyval;

  // First, try to handle alphanumeric input, not listed in nsKeycodes:
  // most likely, more letters will be getting typed in than things in
  // the key list, so we will look through these first.

  // since X has different key symbols for upper and lowercase letters and
  // mozilla does not, convert gdk's to mozilla's
  if (keysym >= GDK_a && keysym <= GDK_z)
    return keysym - GDK_a + NS_VK_A;
  if (keysym >= GDK_A && keysym <= GDK_Z)
    return keysym - GDK_A + NS_VK_A;

  // numbers
  if (keysym >= GDK_0 && keysym <= GDK_9)
    return keysym - GDK_0 + NS_VK_0;

  // keypad numbers
  if (keysym >= GDK_KP_0 && keysym <= GDK_KP_9)
    return keysym - GDK_KP_0 + NS_VK_NUMPAD0;

  // map Sun Keyboard special keysyms
  if (IS_XSUN_XSERVER(GDK_DISPLAY())) {
    length = sizeof(nsSunKeycodes) / sizeof(struct nsKeyConverter);
    for (i = 0; i < length; i++) {
      if (nsSunKeycodes[i].keysym == keysym)
        return(nsSunKeycodes[i].vkCode);
    }
  }

  // misc other things
  length = sizeof(nsKeycodes) / sizeof(struct nsKeyConverter);
  for (i = 0; i < length; i++) {
    if (nsKeycodes[i].keysym == keysym)
      return(nsKeycodes[i].vkCode);
  }

  if (keysym >= GDK_F1 && keysym <= GDK_F24)
    return keysym - GDK_F1 + NS_VK_F1;

#if defined(DEBUG_akkana) || defined(DEBUG_ftang)
  printf("No match in nsPlatformToDOMKeyCode: keysym is 0x%x, string is '%s', keyval = %d\n", keysym, aGEK->string, aGEK->keyval);
#endif

  return((int)0);
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 76 of file nsGtkEventHandler.cpp.