/* -*- Mode: C; c-file-style: "gnu" -*-
   graphics.c -- native methods for sun/awt/motif/X11Graphics.
   Created: Chris Toshok <toshok@hungry.com>, 18-Sep-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 <stdio.h>
#include <stdlib.h>

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_createFromComponent(JNIEnv *env,
						   jobject graphics,
						   jobject component_peer)
{
  GraphicsData *data;
  Widget widget = get_component_widget(env, component_peer);

  data = (GraphicsData*)jmalloc(env, sizeof(GraphicsData));
  if (data == NULL)
      return;

  LOCK_AWT();
  if (!XtIsRealized(widget))
    XtRealizeWidget(widget);
  
  data->drawable = XtWindow(widget);
  data->gc = XCreateGC(_awt_Display,
		       data->drawable,
		       0, NULL);
  
  UNLOCK_AWT();

  set_graphics_data(env, graphics, data);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_createFromGraphics(JNIEnv *env,
						  jobject graphics,
						  jobject graphics_to_copy)
{
  GraphicsData* data = get_graphics_data(env, graphics_to_copy);
  GraphicsData* new_data;

  new_data = (GraphicsData*)jmalloc(env, sizeof(GraphicsData));
  if (data == NULL)
    return;

  new_data->drawable = data->drawable;

  LOCK_AWT();
  new_data->gc = XCreateGC(_awt_Display, new_data->drawable, 0, NULL);

  if (new_data->gc == NULL)
    {
      /* hmm... XXX */
      return;
    }

  XCopyGC(_awt_Display, data->gc, ~0/*everything*/, new_data->gc);
  UNLOCK_AWT();

  set_graphics_data(env, graphics, new_data);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_imageCreate(JNIEnv *env,
					   jobject graphics,
					   jobject imagerep)
{
  GraphicsData* data;

  data = (GraphicsData*)jmalloc(env, sizeof(GraphicsData));
  if (data == NULL)
    return;
  
  data->drawable = (Pixmap)HVM_ObjectGetNativeState(imagerep);
  data->gc = XCreateGC(_awt_Display,
		       data->drawable,
		       0, NULL);
  XSetFillStyle(_awt_Display, data->gc, FillSolid);
  set_graphics_data(env, graphics, data);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_pSetFont(JNIEnv *env,
					jobject graphics,
					jobject font)
{
  GraphicsData* data = get_graphics_data(env, graphics);
  XFontStruct *fontstruct = jfont_to_xfontstruct(env, font);

  LOCK_AWT();
  XSetFont(_awt_Display, data->gc, fontstruct->fid);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_pSetForeground(JNIEnv *env,
					      jobject graphics,
					      jobject color)
{
  GraphicsData* data = get_graphics_data(env, graphics);
  Pixel fg_pixel = jcolor_to_pixel(env, color);

  LOCK_AWT();
  XSetForeground(_awt_Display, data->gc, fg_pixel);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_dispose(JNIEnv *env,
				       jobject graphics)
{
  GraphicsData* data = get_graphics_data(env, graphics);

  if (data != NULL)
    {
      LOCK_AWT();
      XFreeGC(_awt_Display, data->gc);
      UNLOCK_AWT();

      free(data);
      set_graphics_data(env, graphics, NULL);
    }
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_disposeImpl(JNIEnv *env,
					   jobject graphics)
{
  Java_sun_awt_motif_X11Graphics_dispose(env, graphics);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_setPaintMode(JNIEnv *env,
					    jobject graphics)
{
  GraphicsData* data = get_graphics_data(env, graphics);

  LOCK_AWT();
  XSetFunction(_awt_Display, data->gc, GXcopy);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_setXORMode(JNIEnv *env,
					  jobject graphics,
					  jobject umm /* XXX */)
{
  GraphicsData* data = get_graphics_data(env, graphics);

  LOCK_AWT();
  XSetFunction(_awt_Display, data->gc, GXxor);
  UNLOCK_AWT();
}

JNIEXPORT jobject JNICALL
Java_sun_awt_motif_X11Graphics_getClipBounds(JNIEnv *env,
					     jobject graphics)
{
  GraphicsData* data = get_graphics_data(env, graphics);
  jclass rect_cls = (*env)->FindClass(env, "java/awt/Rectangle");
  jmethodID ctor = (*env)->GetMethodID(env, rect_cls, "<init>", "(IIII)V");

  return (*env)->NewObject(env, rect_cls, ctor,
			   data->r.x, data->r.y,
			   data->r.width, data->r.height);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_changeClip(JNIEnv *env,
					  jobject graphics,
					  jint x,
					  jint y,
					  jint width,
					  jint height,
					  jboolean umm)
{
  GraphicsData* data = get_graphics_data(env, graphics);
  XRectangle rect;
  jfieldID originX_field, originY_field;
  jint originX, originY;

  originX_field = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, graphics), "originX", "I");
  originY_field = (*env)->GetFieldID(env, (*env)->GetObjectClass(env, graphics), "originY", "I");
  originX = (*env)->GetIntField(env, graphics, originX_field);
  originY = (*env)->GetIntField(env, graphics, originY_field);

  rect.x = x; rect.y = y;
  rect.width = width; rect.height = height;

  LOCK_AWT();
  XSetClipRectangles(_awt_Display, data->gc, originX, originY, &rect, 1, Unsorted);
  UNLOCK_AWT();

  data->r = rect;
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_removeClip(JNIEnv *env,
					  jobject obj)
{
  printf ("removeClip\n");
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_clearRect(JNIEnv *env,
					 jobject graphics,
					 jint x,
					 jint y,
					 jint width,
					 jint height)
{
  GraphicsData *data = get_graphics_data(env, graphics);

  LOCK_AWT();
  XClearArea(_awt_Display,
	     data->drawable,
	     x, y, width, height, False);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_fillRect(JNIEnv *env,
					jobject graphics,
					jint x,
					jint y,
					jint width,
					jint height)
{
  GraphicsData *data = get_graphics_data(env, graphics);

  LOCK_AWT();
  XFillRectangle(_awt_Display,
		 data->drawable,
		 data->gc,
		 x, y, width, height);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_drawRect(JNIEnv *env,
					jobject graphics,
					jint x,
					jint y,
					jint width,
					jint height)
{
  GraphicsData *data = get_graphics_data(env, graphics);

  LOCK_AWT();
  XDrawRectangle(_awt_Display,
		 data->drawable,
		 data->gc,
		 x, y, width, height);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_drawSFChars(JNIEnv *env,
					   jobject obj,
					   jcharArray arr,
					   jint offset,
					   jint len,
					   jint width,
					   jint height)
{
  printf ("here1\n");
}


JNIEXPORT jint JNICALL
Java_sun_awt_motif_X11Graphics_drawMFCharsSegment(JNIEnv *env,
						  jobject graphics,
						  jboolean flag,
						  jobject font,
						  jobject fontdescriptor,
						  jbyteArray arr,
						  jint byte_len,
						  jint x,
						  jint y)
{
  GraphicsData *data = get_graphics_data(env, graphics);
  jbyte *arr_bytes;

  arr_bytes = (*env)->GetByteArrayElements(env, arr, NULL);

  LOCK_AWT();
  XDrawString(_awt_Display,
	      data->drawable,
	      data->gc,
	      x, y,
	      arr_bytes,
	      byte_len);
  UNLOCK_AWT();

  (*env)->ReleaseByteArrayElements(env, arr, arr_bytes, JNI_ABORT);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_drawBytes(JNIEnv *env,
					 jobject graphics,
					 jbyteArray arr,
					 jint off,
					 jint len,
					 jint x,
					 jint y)
{
  GraphicsData *data = get_graphics_data(env, graphics);
  jbyte *arr_bytes;

  arr_bytes = (*env)->GetByteArrayElements(env, arr, NULL);

  LOCK_AWT();
  XDrawString(_awt_Display,
	      data->drawable,
	      data->gc,
	      x, y,
	      arr_bytes + off,
	      len);
  UNLOCK_AWT();

  (*env)->ReleaseByteArrayElements(env, arr, arr_bytes, JNI_ABORT);
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_drawLine(JNIEnv *env,
					jobject graphics,
					jint x1,
					jint y1,
					jint x2,
					jint y2)
{
  GraphicsData* data = get_graphics_data(env, graphics);

  LOCK_AWT();
  XDrawLine(_awt_Display,
	    data->drawable,
	    data->gc,
	    x1, y1,
	    x2, y2);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_copyArea(JNIEnv *env,
					jobject obj,
					jint x,
					jint y,
					jint width,
					jint height,
					jint dest_x,
					jint dest_y)
{
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_drawRoundRect(JNIEnv *env,
					     jobject obj,
					     jint x,
					     jint y,
					     jint width,
					     jint height,
					     jint umm1,
					     jint umm2)
{
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_fillRoundRect(JNIEnv *env,
					     jobject obj,
					     jint x,
					     jint y,
					     jint width,
					     jint height,
					     jint umm1,
					     jint umm2)
{
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_drawPoly(JNIEnv *env,
					jobject obj,
					jintArray xs,
					jintArray ys,
					jint num_points,
					jboolean umm1)
{
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_fillPolygon(JNIEnv *env,
					   jobject obj,
					   jintArray xs,
					   jintArray ys,
					   jint num_points)
{
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_drawOval(JNIEnv *env,
					jobject obj,
					jint x,
					jint y,
					jint umm1,
					jint umm2)
{
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_fillOval(JNIEnv *env,
					jobject obj,
					jint x,
					jint y,
					jint umm1,
					jint umm2)
{
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_drawArc(JNIEnv *env,
				       jobject graphics,
				       jint x,
				       jint y,
				       jint width,
				       jint height,
				       jint startAngle,
				       jint arcAngle)
{
  GraphicsData* data = get_graphics_data(env, graphics);

  printf ("drawArc\n");

  LOCK_AWT();
  XDrawArc(_awt_Display,
	   data->drawable,
	   data->gc,
	   x, y,
	   width, height,
	   startAngle * 64, arcAngle * 64);
  UNLOCK_AWT();
}

JNIEXPORT void JNICALL
Java_sun_awt_motif_X11Graphics_fillArc(JNIEnv *env,
				       jobject graphics,
				       jint x,
				       jint y,
				       jint width,
				       jint height,
				       jint startAngle,
				       jint arcAngle)
{
  GraphicsData* data = get_graphics_data(env, graphics);

  printf ("fillArc\n");
  LOCK_AWT();
  XFillArc(_awt_Display,
	   data->drawable,
	   data->gc,
	   x, y,
	   width, height,
	   startAngle * 64, arcAngle * 64);
  UNLOCK_AWT();
}
