/* # skkinput (Simple Kana-Kanji Input)
 * CliMsg.c --- Define Client Message 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/IntrinsicP.h>
#include <X11/StringDefs.h>

#include "CliMsgP.h"

/*
 * プロトタイプ宣言。
 */
static void CM_Initialize
( Widget greq, Widget gnew, ArgList args, Cardinal *num_args ) ;
static void CM_Realize
( Widget gw, XtValueMask *valueMask, XSetWindowAttributes *attrs ) ;
static Boolean CM_SetValues
( Widget current, Widget request, Widget new,
  ArgList args, Cardinal *num_args ) ;
static void CM_Destroy( Widget gw ) ;
static void clientMessageHandler
( Widget gw, XEvent *xevent, String *params, Cardinal *num_params ) ;

/*
 * グローバル変数。
 */
#define offset(field)  XtOffsetOf( CliMsgRec, cliMsg.field )
#define goffset(field) XtOffsetOf( WidgetRec, core.field )

static XtResource CM_resources[] = {
  /* クライアントからメッセージが送られて来た時の処理をするコールバック */
  { XtNclientMessageNotify, XtCCallback, XtRCallback, sizeof( caddr_t ),
    offset(clientMessageCallback), XtRImmediate, ( caddr_t )NULL },
  /* XtDestroyWidget 時に用いるコールバック */
  { XtNdestroyNotify, XtCCallback, XtRCallback, sizeof( caddr_t ), 
    offset(destroyCallback), XtRCallback, ( caddr_t )NULL },
} ;

#undef offset
#undef goffset

static XtActionsRec CM_actions[] = {
  { "clientMessageHandler",	   clientMessageHandler },
} ;

static char defaultCliMsgTranslations[] =  
"<Message>:              clientMessageHandler()\n" ;

CliMsgClassRec cliMsgClassRec = {
    { /* core fields */
    /* superclass		*/	&widgetClassRec,
    /* class_name		*/	"ClientMessage",
    /* size			*/	sizeof( CliMsgRec ),
    /* class_initialize		*/	NULL,
    /* class_part_initialize	*/	NULL,
    /* class_inited		*/	FALSE,
    /* initialize		*/	CM_Initialize,
    /* initialize_hook		*/	NULL,
    /* realize			*/	CM_Realize,
    /* actions			*/	CM_actions,
    /* num_actions		*/	XtNumber( CM_actions ),
    /* resources		*/	CM_resources,
    /* num_resources		*/	XtNumber( CM_resources ),
    /* xrm_class		*/	NULLQUARK,
    /* compress_motion		*/	TRUE,
    /* compress_exposure	*/	TRUE,
    /* compress_enterleave	*/	TRUE,
    /* visible_interest		*/	FALSE,
    /* destroy			*/	CM_Destroy,
    /* resize			*/	NULL,
    /* expose			*/	NULL,
    /* set_values		*/      CM_SetValues,
    /* set_values_hook		*/	NULL,
    /* set_values_almost	*/	XtInheritSetValuesAlmost,
    /* get_values_hook		*/	NULL,
    /* accept_focus		*/	NULL,
    /* version			*/	XtVersion,
    /* callback_private		*/	NULL,
    /* tm_table			*/	defaultCliMsgTranslations,
    /* query_geometry		*/	XtInheritQueryGeometry,
    }
};

WidgetClass cliMsgWidgetClass = ( WidgetClass )&cliMsgClassRec ;

static void CM_Initialize
( Widget greq, Widget gnew, ArgList args, Cardinal *num_args )
{
  /*
   * CliMsgWidget w = ( CliMsgWidget )gnew ;
   */
  /* 何を初期化したら良いのでしょうねえ。はははは…じゃないって！ */
  return ;
}

static void CM_Realize
( Widget gw, XtValueMask *valueMask, XSetWindowAttributes *attrs )
{
  /* CliMsgWidget w     = ( CliMsgWidget )gw ; */
  CoreWidgetClass super =
    ( CoreWidgetClass )XtClass( gw )->core_class.superclass ;

  /* 先に適切なウィンドウを用意させておく。*/
  ( *super->core_class.realize )( gw, valueMask, attrs ) ;
  return ;
}

static void CM_Destroy( Widget gw )
{
  /* 破棄される時には親に自分が破棄されようとしていることを伝える。*/
  XtCallCallbacks( gw, XtNdestroyNotify, NULL ) ;
  return ;
}

static Boolean CM_SetValues
( Widget current, Widget request, Widget new,
  ArgList args, Cardinal *num_args )
{
  /* 取り敢えず通信はしない。*/
  return FALSE ;
}

/*
 * この関数が XIM クライアントからの要求( XEVENT の形で来る )を受けて、
 * それをディスパッチする。まず、正しいイベントであるかどうかを調べる。
 * ClientMessage Event できちんとサーバ宛に送られてきて…。
 */
static void clientMessageHandler
( Widget gw, XEvent *xevent, String *params, Cardinal *num_params )
{
  /* 親にコミュニケーションをはかろうとした人がいたことを伝える。*/
  XtCallCallbacks( gw, XtNclientMessageNotify, xevent ) ;
  return ;
}

