/* # skkinput (Simple Kana-Kanji Input)
 * Canvas.c --- Define Canvas Widget Class
 * This file is part of skkinput.
 * Copyright (C) 1997
 * Takashi SAKAMOTO (sakamoto@yajima.kuis.kyoto-u.ac.jp)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with skkinput; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>

#include "CanvasP.h"
#include "config.h"

#define offset(field)  XtOffsetOf( CanvasRec, canvas.field )
#define goffset(field) XtOffsetOf( WidgetRec, core.field )

static XtResource Canvas_resources[] = {
  /* もとからあるリソース。*/
  { XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
    goffset(width),  XtRImmediate, (XtPointer) 1},
  { XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
    goffset(height), XtRImmediate, (XtPointer)1},
  /* 再描画に用いるコールバック */
  { XtNredrawNotify, XtCCallback, XtRCallback, sizeof(caddr_t), 
    offset(redrawcallback), XtRCallback, (caddr_t)NULL },
  { XtNredrawRequest, XtCRedrawRequest, XtRImmediate, sizeof( int ),
    offset(redraw_request), XtRImmediate, ( XtPointer )FALSE },
  /* XtDestroyWidget 時に用いるコールバック */
  { XtNdestroyNotify, XtCCallback, XtRCallback, sizeof(caddr_t), 
    offset(destroycallback), XtRCallback, (caddr_t)NULL },
} ;

#undef offset
#undef goffset

/*
 *
 */
static void Canvas_Initialize 
( Widget greq, Widget gnew, ArgList args, Cardinal *num_args ) ;
static void Canvas_Realize
( Widget gw, XtValueMask *valueMask, XSetWindowAttributes *attrs ) ;
static Boolean Canvas_SetValues
( Widget current, Widget request, Widget new,
  ArgList args, Cardinal *num_args ) ;
static void Canvas_Redisplay
( Widget gw, XEvent *xevent, Region region ) ;
static void Canvas_Destroy( Widget gw ) ;

/*
 * グローバル変数。
 */
CanvasClassRec canvasClassRec = {
    { /* core fields */
    /* superclass		*/	&widgetClassRec,
    /* class_name		*/	"Canvas",
    /* size			*/	sizeof( CanvasRec ),
    /* class_initialize		*/	NULL,
    /* class_part_initialize	*/	NULL,
    /* class_inited		*/	FALSE,
    /* initialize		*/	Canvas_Initialize,
    /* initialize_hook		*/	NULL,
    /* realize			*/	Canvas_Realize,
    /* actions			*/	NULL,
    /* num_actions		*/	0,
    /* resources		*/	Canvas_resources,
    /* num_resources		*/	XtNumber( Canvas_resources ),
    /* xrm_class		*/	NULLQUARK,
    /* compress_motion		*/	TRUE,
    /* compress_exposure	*/	TRUE,
    /* compress_enterleave	*/	TRUE,
    /* visible_interest		*/	FALSE,
    /* destroy			*/	Canvas_Destroy,
    /* resize			*/	NULL,
    /* expose			*/	Canvas_Redisplay,
    /* set_values		*/	Canvas_SetValues,
    /* set_values_hook		*/	NULL,
    /* set_values_almost	*/	XtInheritSetValuesAlmost,
    /* get_values_hook		*/	NULL,
    /* accept_focus		*/	NULL,
    /* version			*/	XtVersion,
    /* callback_private		*/	NULL,
    /* tm_table			*/	NULL,
    /* query_geometry		*/	XtInheritQueryGeometry,
    }
};

WidgetClass canvasWidgetClass = ( WidgetClass )&canvasClassRec ;

static void Canvas_Initialize 
( Widget greq, Widget gnew, ArgList args, Cardinal *num_args )
{
  CanvasWidget w = ( CanvasWidget )gnew ;

  w->canvas.redraw_request = False ;
  return ;
}

static void Canvas_Realize
( Widget gw, XtValueMask *valueMask, XSetWindowAttributes *attrs )
{ 
  *valueMask        |= CWBitGravity ; 
  attrs->bit_gravity = ForgetGravity ;

  XtCreateWindow
    ( gw, (unsigned)InputOutput, (Visual *)CopyFromParent,
      *valueMask, attrs ) ;
  return ;
}

static Boolean Canvas_SetValues
( Widget current, Widget request, Widget new,
  ArgList args, Cardinal *num_args )
{
  CanvasWidget curw = ( CanvasWidget )current ;
  CanvasWidget reqw = ( CanvasWidget )request ;
  CanvasWidget neww = ( CanvasWidget )new ;

  /* 再描画要求が来たら、親を呼び出すように…なっている。*/
  if( reqw->canvas.redraw_request ){
    neww->canvas.redraw_request = curw->canvas.redraw_request = FALSE ;
#if 1
    XtCallCallbacks( new, XtNredrawNotify, NULL ) ;
    return FALSE ;
#else
    return TRUE ;
#endif
  }
  return FALSE ;
}

static void Canvas_Redisplay
( Widget gw, XEvent *xevent, Region region )
{
  XtCallCallbacks( gw, XtNredrawNotify, NULL ) ;
  return ;
}

static void Canvas_Destroy
( Widget gw )
{
  XtCallCallbacks( gw, XtNdestroyNotify, NULL ) ;
  return ;
}
