/* @(#)xlib_drawable_c.c 1.5 95/04/09 */

/*
 * Copyright (c) 1995 by Wayne C. Gramlich.
 * All rights reserved.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * for any purpose is hereby granted without fee provided that the above
 * copyright notice and this permission are retained.  The author makes
 * no representations about the suitability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 */

/*
 * This file provide a bunch of interface routines for accessing objects
 * of type Drawable from Xlib from STIPPLE code.
 */

#ifndef XLIB_H
#include "xlib.h"
#endif

/*
 * xlib_drawable__area_copy_helper(source_drawable_number, source_x, source_y,
 *   destination_drawable_number, destination_x, destination_y,
 *   gc, width, height)
 *	This routine will copy a rectangular region from {source_drawable}
 *	to {destination_drawable} using {gc}.  The rectangular region copied
 *	is {width} by {height} pixels starting at ({source_x}, {source_y})
 *	in {source_drawable} and going to ({destination_x}, {destination_y})
 *	in {destination_drawable}.  All error checking is done by
 *	{area_copy_drawable@xlib_drawable}().
 */
void
xlib_drawable__area_copy_helper(
    Drawable source_drawable_number,
    unsigned source_x,
    unsigned source_y,
    Drawable destination_drawable_number,
    unsigned destination_x,
    unsigned destination_y,
    unsigned width,
    unsigned height,
    Xlib_gc gc)
{
    XCopyArea(gc->screen->display->display,
      source_drawable_number, destination_drawable_number,
      gc->gc, source_x, source_y, width, height,
      destination_x, destination_y);
}

/*
 * xlib_drawable__lines_draw_helper(drawable, gc, points, coordinate_mode)
 *	This procedure will draw a sequence of lines to {drawable_number}
 *	in the shape of {points} using {gc}.  {mode} specifies whether the
 *	points are relative to the origin {absolute} or one another {relative}.
 */
void
xlib_drawable__lines_draw_helper(
    Drawable drawable_number,
    Xlib_gc gc,
    Xlib_points points,
    unsigned coordinate_mode)
{
    int mode;
    extern unsigned xlib_coordinate_mode__absolute;
    extern unsigned xlib_coordinate_mode__relative;

    if (coordinate_mode == xlib_coordinate_mode__absolute) {
	mode = CoordModeOrigin;
    } else if (coordinate_mode == xlib_coordinate_mode__relative) {
	mode = CoordModePrevious;
    } else {
	assert(0);
    }

    XDrawLines(gc->screen->display->display, drawable_number, gc->gc,
      points->xpoints, points->size, mode);
}

/*
 * xlib_drawable__point_draw_helper(drawable, gc, x, y)
 *    This procedure will draw a point at ({x}, {y}) in {drawable} using {gc}.
 *    All error checking is done by {point_draw@xlib_drawable}().
 */
void
xlib_drawable__point_draw_helper(
    Drawable drawable,
    Xlib_gc gc,
    unsigned x,
    unsigned y)
{
    XDrawPoint(gc->screen->display->display, drawable, gc->gc, x, y);
}


/*
 * xlib_drawable__plane_copy_helper(source_drawable_number, source_x, source_y,
 *   source_mask, destination_drawable_number, destination_x, destination_y,
 *   gc, width, height)
 *    This routine will copy a rectangular region from the
 *    {plane}'th plane from {source_drawable} to {destination_drawable}
 *    using {gc} for the forground and background pixels.  The
 *    rectangular region copied is {width} by {height} pixels starting 
 *    at ({source_x}, {source_y}) in {source_drawable} and going to
 *    ({destination_x}, {destination_y}) in {destination_drawable}.
 *    All error checking is done by {plane_copy_drawable@xlib_drawable}().
 */
void
xlib_drawable__plane_copy_helper(
    Drawable source_drawable_number,
    unsigned source_x,
    unsigned source_y,
    unsigned source_mask,
    Drawable destination_drawable_number,
    unsigned destination_x,
    unsigned destination_y,
    unsigned width,
    unsigned height,
    Xlib_gc gc)
{
    XCopyPlane(gc->screen->display->display,
      source_drawable_number, destination_drawable_number,
      gc->gc, source_x, source_y, width, height,
      destination_x, destination_y, source_mask);
}

/*
 * xlib_drawable__polygon_fill_helper(drawable, gc, points, coordinate_mode,
 *   polygon_shape)
 *	This procedure will draw a polygon to {drawable_number} in the
 *	shape of {points} using {gc}.  {mode} specifies whether the points
 *	are relative to the origin {absolute} or one another {relative}.
 *	{shape} specifies the kind of polygon -- {complex}, {convext},
 *	or {non_convex}.
 */
void
xlib_drawable__polygon_fill_helper(
    Drawable drawable_number,
    Xlib_gc gc,
    Xlib_points points,
    unsigned coordinate_mode,
    unsigned polygon_shape)
{
    int mode;
    int shape;
    extern unsigned xlib_coordinate_mode__absolute;
    extern unsigned xlib_coordinate_mode__relative;
    extern unsigned xlib_polygon_shape__complex;
    extern unsigned xlib_polygon_shape__convex;
    extern unsigned xlib_polygon_shape__non_convex;

    if (coordinate_mode == xlib_coordinate_mode__absolute) {
	mode = CoordModeOrigin;
    } else if (coordinate_mode == xlib_coordinate_mode__relative) {
	mode = CoordModePrevious;
    } else {
	assert(0);
    }
    if (polygon_shape == xlib_polygon_shape__complex) {
	shape = Complex;
    } else if (polygon_shape == xlib_polygon_shape__convex) {
	shape = Convex;
    } else if (polygon_shape == xlib_polygon_shape__non_convex) {
	shape = Nonconvex;
    } else {
	assert(0);
    }

    XFillPolygon(gc->screen->display->display, drawable_number, gc->gc,
      points->xpoints, points->size, shape, mode);
}


