/* GDK - The GIMP Drawing Kit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <X11/Xlib.h>
#include <X11/Xos.h>
#include "gdk.h"
#include "gdkprivate.h"


void
gdk_draw_line (GdkDrawable *drawable,
	       GdkGC       *gc,
	       gint         x1,
	       gint         y1,
	       gint         x2,
	       gint         y2)
{
  GdkWindowPrivate *drawable_private;
  GdkGCPrivate *gc_private;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (gc != NULL);

  drawable_private = (GdkWindowPrivate*) drawable;
  gc_private = (GdkGCPrivate*) gc;

  XDrawLine (drawable_private->xdisplay, drawable_private->xwindow,
	     gc_private->xgc, x1, y1, x2, y2);
}

void
gdk_draw_rectangle (GdkDrawable *drawable,
		    GdkGC       *gc,
		    gint         filled,
		    gint         x,
		    gint         y,
		    gint         width,
		    gint         height)
{
  GdkWindowPrivate *drawable_private;
  GdkGCPrivate *gc_private;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (gc != NULL);

  drawable_private = (GdkWindowPrivate*) drawable;
  gc_private = (GdkGCPrivate*) gc;

  if (width == -1)
    width = drawable_private->width;
  if (height == -1)
    height = drawable_private->height;

  if (filled)
    XFillRectangle (drawable_private->xdisplay, drawable_private->xwindow,
		    gc_private->xgc, x, y, width, height);
  else
    XDrawRectangle (drawable_private->xdisplay, drawable_private->xwindow,
		    gc_private->xgc, x, y, width, height);
}

void
gdk_draw_arc (GdkDrawable *drawable,
	      GdkGC       *gc,
	      gint         filled,
	      gint         x,
	      gint         y,
	      gint         width,
	      gint         height,
	      gint         angle1,
	      gint         angle2)
{
  GdkWindowPrivate *drawable_private;
  GdkGCPrivate *gc_private;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (gc != NULL);

  drawable_private = (GdkWindowPrivate*) drawable;
  gc_private = (GdkGCPrivate*) gc;

  if (width == -1)
    width = drawable_private->width;
  if (height == -1)
    height = drawable_private->height;

  if (filled)
    XFillArc (drawable_private->xdisplay, drawable_private->xwindow,
	      gc_private->xgc, x, y, width, height, angle1, angle2);
  else
    XDrawArc (drawable_private->xdisplay, drawable_private->xwindow,
	      gc_private->xgc, x, y, width, height, angle1, angle2);
}

void
gdk_draw_polygon (GdkDrawable *drawable,
		  GdkGC       *gc,
		  gint         filled,
		  GdkPoint    *points,
		  gint         npoints)
{
  GdkWindowPrivate *drawable_private;
  GdkGCPrivate *gc_private;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (gc != NULL);

  drawable_private = (GdkWindowPrivate*) drawable;
  gc_private = (GdkGCPrivate*) gc;

  if (filled)
    {
      XFillPolygon (drawable_private->xdisplay, drawable_private->xwindow,
		    gc_private->xgc, (XPoint*) points, npoints, Complex, CoordModeOrigin);
    }
  else
    {
      XDrawLines (drawable_private->xdisplay, drawable_private->xwindow,
		  gc_private->xgc, (XPoint*) points, npoints, CoordModeOrigin);

      if ((points[0].x != points[npoints-1].x) ||
	  (points[0].y != points[npoints-1].y))
	XDrawLine (drawable_private->xdisplay, drawable_private->xwindow,
		   gc_private->xgc, points[npoints-1].x, points[npoints-1].y,
		   points[0].x, points[0].y);
    }
}

void
gdk_draw_string (GdkDrawable *drawable,
		 GdkGC       *gc,
		 gint         x,
		 gint         y,
		 gchar       *string)
{
  GdkWindowPrivate *drawable_private;
  GdkGCPrivate *gc_private;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (gc != NULL);
  g_return_if_fail (string != NULL);

  drawable_private = (GdkWindowPrivate*) drawable;
  gc_private = (GdkGCPrivate*) gc;

  XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
	       gc_private->xgc, x, y, string, strlen (string));
}

void
gdk_draw_text (GdkDrawable *drawable,
	       GdkGC       *gc,
	       gint         x,
	       gint         y,
	       gchar       *text,
	       gint         text_length)
{
  GdkWindowPrivate *drawable_private;
  GdkGCPrivate *gc_private;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (gc != NULL);
  g_return_if_fail (text != NULL);

  drawable_private = (GdkWindowPrivate*) drawable;
  gc_private = (GdkGCPrivate*) gc;

  XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
	       gc_private->xgc, x, y, text, text_length);
}

void
gdk_draw_pixmap (GdkDrawable *drawable,
		 GdkGC       *gc,
		 GdkPixmap   *src,
		 gint         xsrc,
		 gint         ysrc,
		 gint         xdest,
		 gint         ydest,
		 gint         width,
		 gint         height)
{
  GdkWindowPrivate *drawable_private;
  GdkWindowPrivate *src_private;
  GdkGCPrivate *gc_private;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (src != NULL);
  g_return_if_fail (gc != NULL);

  drawable_private = (GdkWindowPrivate*) drawable;
  src_private = (GdkWindowPrivate*) src;
  gc_private = (GdkGCPrivate*) gc;

  if (width == -1)
    width = src_private->width;
  if (height == -1)
    height = src_private->height;

  XCopyArea (drawable_private->xdisplay,
	     src_private->xwindow,
	     drawable_private->xwindow,
	     gc_private->xgc,
	     xsrc, ysrc,
	     width, height,
	     xdest, ydest);
}

void
gdk_draw_image (GdkDrawable *drawable,
		GdkGC       *gc,
		GdkImage    *image,
		gint         xsrc,
		gint         ysrc,
		gint         xdest,
		gint         ydest,
		gint         width,
		gint         height)
{
  GdkImagePrivate *image_private;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (image != NULL);
  g_return_if_fail (gc != NULL);

  image_private = (GdkImagePrivate*) image;

  g_return_if_fail (image_private->image_put != NULL);

  if (width == -1)
    width = image->width;
  if (height == -1)
    height = image->height;

  (* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
				xdest, ydest, width, height);
}

void
gdk_draw_points (GdkDrawable *drawable,
		 GdkGC       *gc,
		 GdkPoint    *points,
		 gint         npoints)
{
  GdkWindowPrivate *drawable_private;
  GdkGCPrivate *gc_private;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail ((points != NULL) && (npoints > 0));
  g_return_if_fail (gc != NULL);

  drawable_private = (GdkWindowPrivate*) drawable;
  gc_private = (GdkGCPrivate*) gc;

  XDrawPoints (drawable_private->xdisplay,
	       drawable_private->xwindow,
	       gc_private->xgc,
	       (XPoint *) points,
	       npoints,
	       CoordModeOrigin);
}

void
gdk_draw_segments (GdkDrawable *drawable,
		   GdkGC       *gc,
		   GdkSegment  *segs,
		   gint         nsegs)
{
  GdkWindowPrivate *drawable_private;
  GdkGCPrivate *gc_private;

  if (nsegs <= 0)
    return;

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (segs != NULL);
  g_return_if_fail (gc != NULL);

  drawable_private = (GdkWindowPrivate*) drawable;
  gc_private = (GdkGCPrivate*) gc;

  XDrawSegments (drawable_private->xdisplay,
		 drawable_private->xwindow,
		 gc_private->xgc,
		 (XSegment *) segs,
		 nsegs);
}
