/* gtkDPSarea.h
 * Copyright (C) 1997, 1998 GYVE Development Team
 *
 * Author:  Terumoto 'tel' HAYAKAWA <hayakawa@cv.cs.ritsumei.ac.jp>
 * Created: 
 *
 * 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.
 */

#ifndef GTK__DPS_AREA_H
#define GTK__DPS_AREA_H 

#include <gdk/gdk.h>
#include <gtkDPS/gtkDPSwidget.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#define GTK_TYPE_DPS_AREA (gtk_dps_area_get_type ())
#define GTK_DPS_AREA(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_DPS_AREA, GtkDPSArea))
#define GTK_DPS_AREA_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_DPS_AREA, GtkDPSAreaClass))
#define GTK_IS_DPS_AREA(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_DPS_AREA))
#define GTK_IS_DPS_AREA_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_DPS_AREA)

typedef struct _GtkDPSArea       GtkDPSArea;
typedef struct _GtkDPSAreaClass  GtkDPSAreaClass;

typedef enum
{
  GTK_DPS_SCREEN        = -1,
  GTK_DPS_AREA_PIXMAP   =  0,
  GTK_DPS_CACHE_PIXMAP  =  1,
} GtkDPSAreaPixmapName;

struct _GtkDPSArea
{
  GtkDPSWidget  dps_widget;

  GdkDPSCoordtr coordtr;

  /* Backing stores */
  GdkPixmap     **pixmaps;
  gint          number_of_pixmaps;
  gint          context_pixmap;

  /* Draw locking */
  GdkDPSRectangle  draw_rectangle;
  guint         draw_lock_depth;
  gboolean receiving_expose_events_sequence;

  /* Flush & Wait control */
  gboolean pixmaps_dirty;
  gboolean exec_in_mapping;
};

struct _GtkDPSAreaClass
{
  GtkDPSWidgetClass parent_class;

  /* Coord translator updating 
     Only emits only if the coordtr is really changed. */
  void (* coordtr_update) (GtkDPSArea *area, GdkDPSCoordtr * coordtr);

  /* Backing store 
     Use x_rectangle or dps_rectangle which you want. */
  void (* map_pixmap) (GtkDPSArea *area, 
		       gint dist, 
		       gint src, 
		       GdkRectangle   *x_rectangle,
		       GdkDPSRectangle   *dps_rectangle);
  void (* switch_context_pixmap) (GtkDPSArea *area, 
				  gint old,
				  gint new);
       
  void (* draw_lazy) (GtkDPSArea *area, 
		      GdkRectangle   *x_rectangle,
		      GdkDPSRectangle   *dps_rectangle);

  /* = realize */
  void (* draw_ready) (GtkDPSArea *area);
  
  /* Event with coord translation */
  void (* button_press_event_dps) (GtkDPSArea	       *area,
				   GdkEventButton     *event,
				   GdkDPSPoint        *dps_point);
  void (* button_release_event_dps) (GtkDPSArea	       *area,
				   GdkEventButton     *event,
				   GdkDPSPoint        *dps_point);
  void (* motion_notify_event_dps) (GtkDPSArea	       *area,
				    GdkEventMotion     *event,
				    GdkDPSPoint        *dps_point);
  void (* enter_notify_event_dps)   (GtkDPSArea	       *widget,
				    GdkEventCrossing   *event,
				    GdkDPSPoint        *dps_point);
  void (* leave_notify_event_dps)   (GtkDPSArea	       *widget,
				    GdkEventCrossing   *event,
				    GdkDPSPoint        *dps_point);
  /* TODO drag and drop */
};

guint      gtk_dps_area_get_type (void);
GtkWidget*  gtk_dps_area_new (guint number_of_pixmaps);

guint      gtk_dps_area_number_of_pixmaps(GtkDPSArea *);

/* Set in X World 
 The effect of this method is same to that of gtk_set_usize. 
 However, use this method instead of gtk_set_usize and we can trace 
 bugs in gtkDPS easily. */
void gtk_dps_area_size (GtkDPSArea *area, gint width, gint height);

/* Get in DPS World */
void gtk_dps_area_get_size (GtkDPSArea *area, gfloat * width, gfloat * height);

/*
 * Context pixmap switch
 */
/* Call after _realized
   pixmaps == -1 -> screen */
void gtk_dps_area_switch_context_pixmap (GtkDPSArea * dps_area,
				      gint pixmap);
gint gtk_dps_area_context_pixmap (GtkDPSArea * dps_area);

/*
 * Coordtr
 */
void gtk_dps_area_coordtr_dirty (GtkDPSArea * dps_area);
gboolean gtk_dps_area_coordtr_update (GtkDPSArea * dps_area);
void gtk_dps_area_coordtr_point (GtkDPSArea * dps_area,
				 GdkDPSTrDirection trdir, 
				 gpointer src, 
				 gpointer dist);
void gtk_dps_area_coordtr_rectangle (GtkDPSArea * dps_area,
				     GdkDPSTrDirection trdir, 
				     gpointer src, 
				     gpointer dist);
gfloat gtk_dps_area_coordtr_width (GtkDPSArea * dps_area,
				   GdkDPSTrDirection trdir, 
				   gfloat width);
gfloat gtk_dps_area_coordtr_height (GtkDPSArea * dps_area,
				    GdkDPSTrDirection trdir, 
				    gfloat height);

/*
 * Draw lock (emits draw_X)
 */
void gtk_dps_area_draw_lock_retain(GtkDPSArea * dps_area);
void gtk_dps_area_draw_lazy(GtkDPSArea * dps_area,
			    GdkDPSWorld world,
			    gpointer  rectangle);
void gtk_dps_area_draw_lock_release(GtkDPSArea * dps_area);

/*
 * Area Mapping (emits map_pixmap)
 */
void gtk_dps_area_map_pixmap(GtkDPSArea * dps_area, 
		      gint dist, 
		      gint src,
		      GdkDPSWorld world,
		      gpointer rectangle);

/* if dps_rect == NULL, full region is mapped. */
void gtk_dps_area_map_cache_on_screen(GtkDPSArea * dps_area, GdkDPSRectangle * dps_rect);
void gtk_dps_area_map_cache_on_area(GtkDPSArea * dps_area, GdkDPSRectangle * dps_rect);
void gtk_dps_area_map_area_on_screen(GtkDPSArea * dps_area, GdkDPSRectangle * dps_rect);
void gtk_dps_area_map_area_on_cache(GtkDPSArea * dps_area, GdkDPSRectangle * dps_rect);

#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* Not def: GTK__DPS_AREA_H */
