/* -*- Mode: C; c-file-style: "gnu" -*-
   component.c -- native methods for sun/awt/motif/MComponentPeer
   Created: Chris Toshok <toshok@hungry.com>, 3-Mar-1998.
 */
/*
  This file is part of Japhar, the GNU Virtual Machine for Java Bytecodes.
  Japhar is a project of The Hungry Programmers, GNU, and OryxSoft.

  Copyright (C) 1998, 1999 The Hungry Programmers

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

  This library 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "config.h"
#include "jni.h"
#include "common.h"
#include "runtime.h"

#include <Xm/XmP.h>

#include <assert.h>

#include <X11/cursorfont.h>

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pInitialize(JNIEnv *env,
                                              jobject peer)
{
  Widget w = get_component_widget(env, peer);
  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_pInitialize(peer = %p)\n", peer));

  if (NULL == w)
    {
      PR_LOG(awtLm, PR_LOG_DEBUG,
             ("widget is NULL in MComponentPeer.pInitialize!\n"));
      return;
    }

  add_component_event_handler(w, peer);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pShow(JNIEnv *env,
                                        jobject peer)
{
  Widget w = get_component_widget(env, peer);

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("in sun_awt_motif_MComponentPeer_pShow(peer = %p)\n", peer));

  if (NULL == w)
    {
      PR_LOG(awtLm, PR_LOG_DEBUG,
             ("widget is NULL in MComponentPeer.pShow!\n"));
      return;
    }

  LOCK_AWT();
  XtManageChild(w);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pHide(JNIEnv *env,
                                        jobject peer)
{
  Widget w = NULL;
  assert(NULL != env);

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("in sun_awt_motif_MComponentPeer_pHide(peer = %p)\n", peer));

  if (NULL == peer)
    {
      PR_LOG(awtLm, PR_LOG_DEBUG, ("peer is NULL in MComponentPeer.pHide!\n"));
      return;
    }

  w = get_component_widget(env, peer);

  if (NULL == w)
    {
      PR_LOG(awtLm, PR_LOG_DEBUG,
             ("widget is NULL in MComponentPeer.pHide!\n"));
      return;
    }

  LOCK_AWT();
  XtUnmanageChild(w);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pEnable(JNIEnv *env,
                                          jobject peer)
{
  Widget w = get_component_widget(env, peer);

  if (NULL == w)
    {
      PR_LOG(awtLm, PR_LOG_DEBUG,
             ("widget is NULL in MComponentPeer.pEnable!\n"));
      return;
    }

  LOCK_AWT();
  XtSetSensitive(w, True);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pDisable(JNIEnv *env,
                                           jobject peer)
{
  Widget w = get_component_widget(env, peer);

  if (NULL == w)
    {
      PR_LOG(awtLm, PR_LOG_DEBUG,
             ("widget is NULL in MComponentPeer.pDisable!\n"));
      return;
    }

  LOCK_AWT();
  XtSetSensitive(w, False);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pReshape(JNIEnv *env,
                                           jobject peer,
                                           jint x,
                                           jint y,
                                           jint width,
                                           jint height)
{
  Widget widget = get_component_widget(env, peer);

  if (NULL == widget)
    {
      PR_LOG(awtLm, PR_LOG_DEBUG,
             ("widget is NULL in MComponentPeer.pReshape!\n"));
      return;
    }

  LOCK_AWT();

  XtVaSetValues(widget,
                XmNx, x,
                XmNy, y,
                NULL);

  if (width)
    XtVaSetValues(widget,
                  XmNwidth, width,
                  NULL);

  if (height)
    XtVaSetValues(widget,
                  XmNheight, height,
                  NULL);

  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pAddRepaint(JNIEnv *env,
                                              jobject peer,
                                              jint x,
                                              jint y,
                                              jint width,
                                              jint height)
{
  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_pAddRepaint(peer = %p, x = %d, y = %d, width = %d, height = %d)\n",
           peer, x, y, width, height));
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pTriggerRepaint(JNIEnv *env,
                                                  jobject peer)
{
  Widget w = get_component_widget(env, peer);
  XEvent fake_expose_event;

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_pTriggerRepaint(peer = %p)\n",
           peer));

  LOCK_AWT();
  fake_expose_event.xexpose.x =
    fake_expose_event.xexpose.y = 0;
  fake_expose_event.xexpose.width = XtWidth(w);
  fake_expose_event.xexpose.height = XtHeight(w);

  send_paint_event(env, w, &fake_expose_event, peer);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pDispose(JNIEnv *env,
                                           jobject peer)
{
  Widget w = get_component_widget(env, peer);

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_pDispose(peer = %p)\n", peer));

  if (NULL == w)
    {
      PR_LOG(awtLm, PR_LOG_DEBUG,
             ("widget is NULL in MComponentPeer.pDispose!\n"));
      return;
    }

  LOCK_AWT();
  XtDestroyWidget(w);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pMakeCursorVisible(JNIEnv *env,
                                                     jobject peer)
{
  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_pMakeCursorVisible(peer = %p)\n",
           peer));
}

JNIEXPORT jobject JNICALL
Java_sun_awt_motif_MComponentPeer_pGetLocationOnScreen(JNIEnv *env,
                                                       jobject peer)
{
  Widget w = get_component_widget(env, peer);
  jclass point_cls = (*env)->FindClass(env, "java/awt/Point");
  jmethodID ctor = (*env)->GetMethodID(env, point_cls, "<init>", "(II)V");
  jobject point;
  jint x, y;

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_pGetLocationOnScreen(peer = %p)\n",
           peer));

  LOCK_AWT();
  x = XtX(w);
  y = XtY(w);
  UNLOCK_AWT();

  point = (*env)->NewObject(env, point_cls, ctor, x, y);

  return point;
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pSetForeground(JNIEnv *env,
                                                 jobject peer,
                                                 jobject foreground)
{
  Widget w = get_component_widget(env, peer);
  Pixel fg_pixel = jcolor_to_pixel(env, foreground);

  if (NULL == w) /* XXX Hm, how could this happend, and what should we do? */
    {
      PR_LOG(awtLm, PR_LOG_DEBUG,
             ("widget is NULL in MComponentPeer.setForeground!\n"));
      return;
    }

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_setForeground(peer = %p, foreground = %p)\n", peer, foreground));

  LOCK_AWT();
  XtVaSetValues(w,
                XmNforeground, fg_pixel,
                NULL);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pSetBackground(JNIEnv *env,
                                                 jobject peer,
                                                 jobject background)
{
  XColor bg;
  Widget w = get_component_widget(env, peer);
  Pixel bg_pixel = jcolor_to_pixel(env, background);

  if (NULL == w) /* XXX Hm, how could this happend, and what should we do? */
    {
      PR_LOG(awtLm, PR_LOG_DEBUG,
             ("widget is NULL in MComponentPeer.setBackground!\n"));
      return;
    }

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_setBackground(peer = %p, background = %p)\n", peer, background));

  LOCK_AWT();
  XmChangeColor(w, bg_pixel);
  XtVaSetValues(w,
                XmNbackground, bg_pixel,
                NULL);
  UNLOCK_AWT();
}

/* JDK1.1 */
JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pSetFont(JNIEnv *env,
                                           jobject peer,
                                           jobject font)
{
  Widget w = get_component_widget(env, peer);
  XFontStruct *fs = jfont_to_xfontstruct(env, font);
  XmFontList fl;

  LOCK_AWT();
  fl = XmFontListCreate(fs, XmDEFAULT_FONT);
  XtVaSetValues(w,
                XmNfontList, fl,
                NULL);
  UNLOCK_AWT();
}

/* JDK 1.1.7 */
JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_setBackground(JNIEnv *env,
                                                 jobject peer,
                                                 jobject background)
{
  Java_sun_awt_motif_MComponentPeer_pSetBackground(env, peer, background);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_setForeground(JNIEnv *env,
                                                 jobject peer,
                                                 jobject foreground)
{
  Java_sun_awt_motif_MComponentPeer_pSetForeground(env, peer, foreground);
}

/* JDK1.2 */
JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_setFont(JNIEnv *env,
                                          jobject peer,
                                          jobject font)
{
  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_pSetFont(peer = %p, font = %p)\n", peer, font));
  Java_sun_awt_motif_MComponentPeer_pSetFont(env, peer, font);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_setCursor(JNIEnv *env,
                                            jobject peer,
                                            jobject cursor)
{
  Widget w = get_component_widget(env, peer);
  jclass cursor_class = (*env)->GetObjectClass(env, cursor);
  jfieldID type;
  jint cursor_type;
  Cursor xcursor;
  unsigned int shape;

  /* initialize the cursor id's if they're not already. */
  if (DEFAULT_CURSOR == -1)
    Java_java_awt_Cursor_initIDs(env, cursor_class);

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_setCursor(peer = %p, cursor = %p)\n", peer, cursor));

  if (NULL == w)
    {
      /*      HVM_ExceptionThrow(env, "java/lang/NullPointerException", "widget is null in MComponentPeer.setCursor!"); */
      return;
    }

  type = (*env)->GetFieldID(env, cursor_class, "type", "I");
  cursor_type = (*env)->GetIntField(env, cursor, type);

  if (cursor_type == DEFAULT_CURSOR)            shape = XC_arrow;
  else if (cursor_type == CROSSHAIR_CURSOR)     shape = XC_cross;
  else if (cursor_type == TEXT_CURSOR)          shape = XC_xterm;
  else if (cursor_type == WAIT_CURSOR)          shape = XC_watch;
  else if (cursor_type == SW_RESIZE_CURSOR)     shape = XC_bottom_left_corner;
  else if (cursor_type == SE_RESIZE_CURSOR)     shape = XC_bottom_right_corner;
  else if (cursor_type == NW_RESIZE_CURSOR)     shape = XC_top_left_corner;
  else if (cursor_type == NE_RESIZE_CURSOR)     shape = XC_top_right_corner;
  else if (cursor_type == N_RESIZE_CURSOR)      shape = XC_top_side;
  else if (cursor_type == S_RESIZE_CURSOR)      shape = XC_top_side;
  else if (cursor_type == W_RESIZE_CURSOR)      shape = XC_left_side;
  else if (cursor_type == E_RESIZE_CURSOR)      shape = XC_right_side;
  else if (cursor_type == HAND_CURSOR)          shape = XC_hand1;
  else if (cursor_type == MOVE_CURSOR)          shape = XC_hand2;
  else
    {
      HVM_ExceptionThrow(env, "java/lang/RuntimeException", "invalid cursor type");
      return;
    }

  if (XtWindow(w) != None)
    {
      xcursor = XCreateFontCursor(_awt_Display, shape);
      XDefineCursor(_awt_Display, XtWindow(w), xcursor);
    }

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("+  cursor_type = %d\n", cursor_type));
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_nativeHandleEvent(JNIEnv *env,
                                                    jobject peer,
                                                    jobject event)
{
  jclass event_class;
  jmethodID getID;
  jint id;

  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_nativeHandleEvent(peer = %p, event = %p)\n", peer, event));

  event_class = (*env)->GetObjectClass(env, event);
  getID = (*env)->GetMethodID(env, event_class, "getID", "()I");
  id = (*env)->CallIntMethod(env, event, getID);

  PR_LOG (awtLm, PR_LOG_DEBUG, ("+  event->id = %d\n", id));

  /* XXX what do I do here? */
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_requestFocus(JNIEnv *env,
                                               jobject peer)
{
  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("In sun_awt_motif_MComponentPeer_requestFocus(peer = %p)\n", peer));
}

/* JDK1.2 */
JNIEXPORT jobject /* java.awt.Component */ JNICALL
Java_sun_awt_motif_MComponentPeer_getParent_1NoClientCode(JNIEnv *env,
                                                          jclass cls,
                                                          jobject component)
{
  jobject parent_component;
  jmethodID getParent = (*env)->GetMethodID(env,
                                            (*env)->GetObjectClass(env, component),
                                            "getParent",
                                            "()Ljava/awt/Container;");

  parent_component = (*env)->CallObjectMethod(env,
                                              component,
                                              getParent);

  return parent_component;
}

/* JDK1.2 */
JNIEXPORT jobject /* java.awt.Container */ JNICALL
Java_sun_awt_motif_MComponentPeer_getComponents_1NoClientCode(JNIEnv *env,
                                                              jclass cls,
                                                              jobjectArray components)
{
  PR_LOG (awtLm, PR_LOG_DEBUG,
          ("in MComponentPeer.getParent_NoClientCode()\n"));
  return NULL;
}

/* JDK1.2 */
JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pSetInnerForeground(JNIEnv *env,
                                                      jobject peer,
                                                      jobject color)
{
}

/* JDK1.2 */
JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_pSetScrollbarBackground(JNIEnv *env,
                                                          jobject peer,
                                                          jobject color)
{
}

/* JDK1.2 */
JNIEXPORT jboolean JNICALL
Java_sun_awt_motif_MComponentPeer_isBackgroundInherited(JNIEnv *env,
                                                        jobject peer)
{
  return JNI_FALSE; /* XXX */
}

/* JDK1.2 */
JNIEXPORT jboolean JNICALL
Java_sun_awt_motif_MComponentPeer_isForegroundInherited(JNIEnv *env,
                                                        jobject peer)
{
  return JNI_FALSE; /* XXX */
}

/* JDK1.2 */
JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_initIDs(JNIEnv *env,
                                          jclass peer_cls)
{
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_addNativeDropTarget( JNIEnv *env,
                                                       jobject obj,
                                                       jobject a )
{
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_MComponentPeer_removeNativeDropTarget( JNIEnv *env,
                                                          jobject obj,
                                                          jobject a )
{
}
