/* XEventPump.java -- Pumps events from X to AWT
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.awt.peer.x;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.PaintEvent;
import java.util.HashMap;

import gnu.x11.Display;
import gnu.x11.event.ButtonPress;
import gnu.x11.event.ButtonRelease;
import gnu.x11.event.ConfigureNotify;
import gnu.x11.event.Event;
import gnu.x11.event.Expose;
import gnu.x11.event.Input;
import gnu.x11.event.KeyPress;
import gnu.x11.event.KeyRelease;
import gnu.x11.event.MotionNotify;

/**
 * Fetches events from X, translates them to AWT events and pumps them up
 * into the AWT event queue.
 *
 * @author Roman Kennke (kennke@aicas.com)
 */
public class XEventPump
  implements Runnable
{

  /**
   * The X Display from which we fetch and pump up events.
   */
  private Display display;

  /**
   * Maps X Windows to AWT Windows to be able to correctly determine the
   * event targets.
   */
  private HashMap windows;

  /**
   * Indicates if we are currently inside a drag operation. This is
   * set to the button ID when a button is pressed and to -1 (indicating
   * that no drag is active) when the mouse is released.
   */
  private int drag;

  /**
   * Creates a new XEventPump for the specified X Display.
   *
   * @param d the X Display
   */
  XEventPump(Display d)
  {
    display = d;
    windows = new HashMap();
    drag = -1;
    Thread t = new Thread(this);
    t.start();
  }

  /**
   * The main event pump loop. This basically fetches events from the
   * X Display and pumps them into the system event queue.
   */
  public void run()
  {
    while (display.connected)
      {
        try
          {
            Event xEvent = display.next_event();
            handleEvent(xEvent);
          }
        catch (ThreadDeath death)
          {
            // If someone wants to kill us, let them.
            return;
          }
        catch (Throwable x)
          {
            System.err.println("Exception during event dispatch:");
            x.printStackTrace(System.err);
          }
      }
  }

  /**
   * Adds an X Window to AWT Window mapping. This is required so that the
   * event pump can correctly determine the event targets.
   *
   * @param xWindow the X Window
   * @param awtWindow the AWT Window
   */
  void registerWindow(gnu.x11.Window xWindow, Window awtWindow)
  {
    if (XToolkit.DEBUG)
      System.err.println("registering window id: " + xWindow.id);
    windows.put(new Integer(xWindow.id), awtWindow);
  }

  void unregisterWindow(gnu.x11.Window xWindow)
  {
    windows.remove(new Integer(xWindow.id));
  }

  private void handleEvent(Event xEvent)
  {
    Integer key = new Integer(xEvent.window_id());;
    Window awtWindow = (Window) windows.get(key);

    if (XToolkit.DEBUG)
      System.err.println("fetched event: " + xEvent);
    switch (xEvent.code())
    {
    case ButtonPress.CODE:
      ButtonPress bp = (ButtonPress) xEvent;
      // Create and post the mouse event.
      int button = bp.detail();
      drag = button;
      MouseEvent mp = new MouseEvent(awtWindow, MouseEvent.MOUSE_PRESSED,
                                     System.currentTimeMillis(), 0,
                                     bp.event_x(), bp.event_y(),
                                     1, false, button);
      Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mp);
      break;
    case ButtonRelease.CODE:
      ButtonRelease br = (ButtonRelease) xEvent;
      drag = -1;
      MouseEvent mr = new MouseEvent(awtWindow, MouseEvent.MOUSE_RELEASED,
                                     System.currentTimeMillis(), 0,
                                     br.event_x(), br.event_y(),
                                     1, false, br.detail());
      Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mr);
      break;
    case MotionNotify.CODE:
      MotionNotify mn = (MotionNotify) xEvent;
      MouseEvent mm;
      if (drag == -1)
        {
          mm = new MouseEvent(awtWindow, MouseEvent.MOUSE_MOVED,
                              System.currentTimeMillis(), 0,
                              mn.event_x(), mn.event_y(),
                              1, false);
        }
      else
        {
          mm = new MouseEvent(awtWindow, MouseEvent.MOUSE_DRAGGED,
                              System.currentTimeMillis(), 0,
                              mn.event_x(), mn.event_y(),
                              1, false);
        }
      Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mm);
      break;
    case ConfigureNotify.CODE:
      ConfigureNotify c = (ConfigureNotify) xEvent;
      if (XToolkit.DEBUG)
        System.err.println("resize request for window id: " + key);

      // Detect and report size changes.
      if (c.width() != awtWindow.getWidth()
          || c.height() != awtWindow.getHeight())
        {
          if (XToolkit.DEBUG)
            System.err.println("Setting size on AWT window: " + c.width()
                             + ", " + c.height() + ", " + awtWindow.getWidth()
                             + ", " + awtWindow.getHeight());
          ((XWindowPeer) awtWindow.getPeer()).callback = true;
          awtWindow.setSize(c.width(), c.height());
          ((XWindowPeer) awtWindow.getPeer()).callback = false;
        }
      break;
    case Expose.CODE:
      Expose exp = (Expose) xEvent;
      if (XToolkit.DEBUG)
        System.err.println("expose request for window id: " + key);
      Rectangle r = new Rectangle(exp.x(), exp.y(), exp.width(),
                                  exp.height());
      //System.err.println("expose paint: " + r);
      // We need to clear the background of the exposed rectangle.
      Graphics g = awtWindow.getGraphics();
      g.clearRect(r.x, r.y, r.width, r.height);
      g.dispose();
      PaintEvent pev = new PaintEvent(awtWindow, PaintEvent.PAINT, r);
      Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(pev);
      break;
    case KeyPress.CODE:
    case KeyRelease.CODE:
      handleKeyEvent(xEvent, awtWindow);
      break;
    default:
      if (XToolkit.DEBUG)
        System.err.println("Unhandled X event: " + xEvent);
    }
  }

  /**
   * Handles key events from X.
   *
   * @param xEvent the X event
   * @param awtWindow the AWT window to which the event gets posted
   */
  private void handleKeyEvent(Event xEvent, Window awtWindow)
  {
    Input keyEvent = (Input) xEvent;
    int xKeyCode = keyEvent.detail();
    int xMods = keyEvent.state();
    int keyCode = KeyboardMapping.mapToKeyCode(xEvent.display.input, xKeyCode,
                                               xMods);
    char keyChar = KeyboardMapping.mapToKeyChar(xEvent.display.input, xKeyCode,
                                                xMods);
    if (XToolkit.DEBUG)
      System.err.println("XEventPump.handleKeyEvent: " + xKeyCode + ", "
                         + xMods + ": " + ((int) keyChar) + ", " + keyCode);
    int awtMods = KeyboardMapping.mapModifiers(xMods);
    long when = System.currentTimeMillis();
    KeyEvent ke;
    if (keyEvent.code() == KeyPress.CODE)
      {
        ke = new KeyEvent(awtWindow, KeyEvent.KEY_PRESSED, when,
                          awtMods, keyCode,
                          KeyEvent.CHAR_UNDEFINED);
        Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ke);
        if (keyChar != KeyEvent.CHAR_UNDEFINED)
          {
            ke = new KeyEvent(awtWindow, KeyEvent.KEY_TYPED, when,
                              awtMods, KeyEvent.VK_UNDEFINED,
                              keyChar);
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ke);
          }
          
      }
    else
      {
        ke = new KeyEvent(awtWindow, KeyEvent.KEY_RELEASED, when,
                          awtMods, keyCode,
                          KeyEvent.CHAR_UNDEFINED);
        Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ke);
      }

  }


}

