Blame support/cltkWait.c

Packit bd2e5d
/***********************************************************************/
Packit bd2e5d
/*                                                                     */
Packit bd2e5d
/*                 MLTk, Tcl/Tk interface of OCaml                     */
Packit bd2e5d
/*                                                                     */
Packit bd2e5d
/*    Francois Rouaix, Francois Pessaux, Jun Furuse and Pierre Weis    */
Packit bd2e5d
/*               projet Cristal, INRIA Rocquencourt                    */
Packit bd2e5d
/*            Jacques Garrigue, Kyoto University RIMS                  */
Packit bd2e5d
/*                                                                     */
Packit bd2e5d
/*  Copyright 2002 Institut National de Recherche en Informatique et   */
Packit bd2e5d
/*  en Automatique and Kyoto University.  All rights reserved.         */
Packit bd2e5d
/*  This file is distributed under the terms of the GNU Library        */
Packit bd2e5d
/*  General Public License, with the special exception on linking      */
Packit bd2e5d
/*  described in file LICENSE found in the OCaml source tree.          */
Packit bd2e5d
/*                                                                     */
Packit bd2e5d
/***********************************************************************/
Packit bd2e5d
Packit bd2e5d
/* $Id$ */
Packit bd2e5d
Packit bd2e5d
#include <tcl.h>
Packit bd2e5d
#include <tk.h>
Packit bd2e5d
#include <mlvalues.h>
Packit bd2e5d
#include <memory.h>
Packit bd2e5d
#include <callback.h>
Packit bd2e5d
#include "camltk.h"
Packit bd2e5d
Packit bd2e5d
/* The following are replacements for
Packit bd2e5d
    tkwait visibility
Packit bd2e5d
    tkwait window
Packit bd2e5d
   in the case where we use threads (tkwait internally calls an event loop,
Packit bd2e5d
   and thus prevents thread scheduling from taking place).
Packit bd2e5d
Packit bd2e5d
   Instead, one should set up a callback, wait for a signal, and signal
Packit bd2e5d
   from inside the callback
Packit bd2e5d
*/
Packit bd2e5d
Packit bd2e5d
static void             WaitVisibilityProc _ANSI_ARGS_((ClientData clientData,
Packit bd2e5d
                            XEvent *eventPtr));
Packit bd2e5d
static void             WaitWindowProc _ANSI_ARGS_((ClientData clientData,
Packit bd2e5d
                            XEvent *eventPtr));
Packit bd2e5d
Packit bd2e5d
/* For the other handlers, we need a bit more data */
Packit bd2e5d
struct WinCBData {
Packit bd2e5d
  int cbid;
Packit bd2e5d
  Tk_Window win;
Packit bd2e5d
};
Packit bd2e5d
Packit bd2e5d
static void WaitVisibilityProc(clientData, eventPtr)
Packit bd2e5d
    ClientData clientData;
Packit bd2e5d
    XEvent *eventPtr;           /* Information about event (not used). */
Packit bd2e5d
{
Packit bd2e5d
  struct WinCBData *vis = clientData;
Packit bd2e5d
  value cbid = Val_int(vis->cbid);
Packit bd2e5d
Packit bd2e5d
  Tk_DeleteEventHandler(vis->win, VisibilityChangeMask,
Packit bd2e5d
            WaitVisibilityProc, clientData);
Packit bd2e5d
Packit bd2e5d
  caml_stat_free((char *)vis);
Packit bd2e5d
  caml_callback2(*handler_code,cbid,Val_int(0));
Packit bd2e5d
}
Packit bd2e5d
Packit bd2e5d
/* Sets up a callback upon Visibility of a window */
Packit bd2e5d
CAMLprim value camltk_wait_vis(value win, value cbid)
Packit bd2e5d
{
Packit bd2e5d
  struct WinCBData *vis =
Packit bd2e5d
    (struct WinCBData *)caml_stat_alloc(sizeof(struct WinCBData));
Packit bd2e5d
  vis->win = Tk_NameToWindow(cltclinterp, String_val(win), cltk_mainWindow);
Packit bd2e5d
  if (vis -> win == NULL) {
Packit bd2e5d
    caml_stat_free((char *)vis);
Packit bd2e5d
    tk_error(Tcl_GetStringResult(cltclinterp));
Packit bd2e5d
  };
Packit bd2e5d
  vis->cbid = Int_val(cbid);
Packit bd2e5d
  Tk_CreateEventHandler(vis->win, VisibilityChangeMask,
Packit bd2e5d
                        WaitVisibilityProc, (ClientData) vis);
Packit bd2e5d
  return Val_unit;
Packit bd2e5d
}
Packit bd2e5d
Packit bd2e5d
static void WaitWindowProc(ClientData clientData, XEvent *eventPtr)
Packit bd2e5d
{
Packit bd2e5d
  if (eventPtr->type == DestroyNotify) {
Packit bd2e5d
    struct WinCBData *vis = clientData;
Packit bd2e5d
    value cbid = Val_int(vis->cbid);
Packit bd2e5d
    caml_stat_free((char *)clientData);
Packit bd2e5d
    /* The handler is destroyed by Tk itself */
Packit bd2e5d
    caml_callback2(*handler_code,cbid,Val_int(0));
Packit bd2e5d
  }
Packit bd2e5d
}
Packit bd2e5d
Packit bd2e5d
/* Sets up a callback upon window destruction */
Packit bd2e5d
CAMLprim value camltk_wait_des(value win, value cbid)
Packit bd2e5d
{
Packit bd2e5d
  struct WinCBData *vis =
Packit bd2e5d
    (struct WinCBData *)caml_stat_alloc(sizeof(struct WinCBData));
Packit bd2e5d
  vis->win = Tk_NameToWindow(cltclinterp, String_val(win), cltk_mainWindow);
Packit bd2e5d
  if (vis -> win == NULL) {
Packit bd2e5d
    caml_stat_free((char *)vis);
Packit bd2e5d
    tk_error(Tcl_GetStringResult(cltclinterp));
Packit bd2e5d
  };
Packit bd2e5d
  vis->cbid = Int_val(cbid);
Packit bd2e5d
  Tk_CreateEventHandler(vis->win, StructureNotifyMask,
Packit bd2e5d
                        WaitWindowProc, (ClientData) vis);
Packit bd2e5d
  return Val_unit;
Packit bd2e5d
}