/* # skkinput (Simple Kana-Kanji Input)
 * WmcloseShell.c --- Define Window Manager Close Shell 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 <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>

#include "WmcloseShellP.h"

/*
 * プロトタイプ宣言。
 */
static void WMCS_Initialize 
( Widget greq, Widget gnew, ArgList args, Cardinal *num_args ) ;
static void WMCS_Realize
( Widget gw, XtValueMask *valuemask, XSetWindowAttributes *attr ) ;
static Boolean WMCS_SetValues
( Widget current, Widget request, Widget new,
  ArgList args, Cardinal *num_args ) ;
static void WMCS_Close
( Widget gw, XEvent *xevent, String *params, Cardinal *num_params ) ;
static void WMCS_Destroy( Widget gw ) ;

extern int  IsWindowExist( Display *disp, Window win ) ;


#define offset(field)  XtOffsetOf( WmcloseShellRec, wmclose.field)
#define goffset(field) XtOffsetOf( WidgetRec, shell.field )

static XtResource WMCS_resources[] = {
  { XtNwmcloseNotify, XtCCallback, XtRCallback, sizeof( caddr_t ),
    offset( wmclosecallback ), XtRCallback, ( caddr_t )NULL },
  { XtNdestroyNotify, XtCCallback, XtRCallback, sizeof( caddr_t ),
    offset( destroycallback ), XtRCallback, ( caddr_t )NULL },
} ;

#undef offset
#undef goffset

static XtActionsRec wmcloseActionsTbl [] = {
  { "WMMessageHandler",   	WMCS_Close },
};

static char defaultWmcloseTranslations[] =  
"<Message>WM_PROTOCOLS:   WMMessageHandler()\n" ;

WmcloseShellClassRec wmcloseShellClassRec = {
  { /* core fields */
    /* superclass		*/	(WidgetClass) &transientShellClassRec,
    /* class_name		*/	"WmcloseShell",
    /* widget_size		*/	sizeof( WmcloseShellRec ),
    /* class_initialize		*/	NULL,
    /* class_part_initialize	*/	NULL,
    /* class_inited		*/	FALSE,
    /* initialize		*/	WMCS_Initialize,
    /* initialize_hook		*/	NULL,
    /* realize			*/	WMCS_Realize,
    /* actions			*/	wmcloseActionsTbl,
    /* num_actions		*/	XtNumber( wmcloseActionsTbl ),
    /* resources		*/	WMCS_resources,
    /* num_resources		*/	XtNumber( WMCS_resources ),
    /* xrm_class		*/	NULLQUARK,
    /* compress_motion		*/	TRUE,
    /* compress_exposure	*/	TRUE,
    /* compress_enterleave	*/	TRUE,
    /* visible_interest		*/	FALSE,
    /* destroy			*/	WMCS_Destroy,
    /* resize			*/	XtInheritResize,
    /* expose			*/	XtInheritExpose,
    /* set_values		*/	WMCS_SetValues,
    /* set_values_hook		*/	NULL,
    /* set_values_almost	*/	XtInheritSetValuesAlmost,
    /* get_values_hook		*/	NULL,
    /* accept_focus		*/	NULL,
    /* version			*/	XtVersion,
    /* callback_private		*/	NULL,
    /* tm_table			*/	defaultWmcloseTranslations,
    /* query_geometry		*/	XtInheritQueryGeometry,
    /* display_accelerator	*/	XtInheritDisplayAccelerator,
    /* extension		*/	NULL
  },
  { /* Composite */
    /* geometry_manager		*/	XtInheritGeometryManager,
    /* change_managed		*/	XtInheritChangeManaged,
    /* insert_child		*/	XtInheritInsertChild,
    /* delete_child		*/	XtInheritDeleteChild,
    /* extension		*/	NULL
  },
  { /* shell fields */
    /* extension		*/	NULL
  },
  { /* Window Manager Shell fields */
    /* extension                */      NULL
  },
  { /* Vendor Shell fields */
    /* extension                */      NULL
  },
  { /* transientShell fields */
    /* extension		*/	NULL
  },
  { /* WmcloseShell fields */
    /* empty			*/	0
  }
};

WidgetClass wmcloseShellWidgetClass =
( WidgetClass )&wmcloseShellClassRec ;

static void WMCS_Initialize 
( Widget greq, Widget gnew, ArgList args, Cardinal *num_args )
{
  /* 特にすることは無かったりするあたりがなかなか。*/
  return ;
}

static void WMCS_Realize
( Widget gw, XtValueMask *valuemask, XSetWindowAttributes *attr )
{
  /* WM_PROTOCOL を受けるために必要な ATOM */
  static Atom wm_delete_window = None ;
  
  /* もともとの realize 関数を利用して起こす。*/
  ( *wmcloseShellWidgetClass->core_class.superclass->core_class.realize)
    (gw, valuemask, attr) ;

  if( wm_delete_window == None ){
    /* Window Manager の delete message を受けられるように atom を作る。*/
    wm_delete_window = XInternAtom
      ( XtDisplay( gw ), "WM_DELETE_WINDOW", False ) ;
  }
  (void) XSetWMProtocols
    ( XtDisplay( gw ), XtWindow( gw ), &wm_delete_window, 1 ) ;
  return ;
}

/*
 *
 */
static Boolean WMCS_SetValues
( Widget current, Widget request, Widget new,
  ArgList args, Cardinal *num_args )
{
  return FALSE ;
}

static void WMCS_Close
( Widget gw, XEvent *xevent, String *params, Cardinal *num_params )
{
  /* Window Manager から閉じるよう要請があったことを告げる。*/
  XtCallCallbacks( gw, XtNwmcloseNotify, NULL ) ;
  return ;
}

static void WMCS_Destroy( Widget gw )
{
  /* Window Manager から閉じるよう要請があったことを告げる。*/
  XtCallCallbacks( gw, XtNdestroyNotify, NULL ) ;
  return ;
}

