let create () =
  let channel = Event.new_channel () in
  let viewer_thread () =
    let viewer = Viewer.create () in
    let frame_handler = ref ((fun _ -> ()):frame_handler) in
    let exit = ref false in
    let process_messages () =
      match Event.poll (Event.receive channel) with
        | None -> ()
        | Some x ->
            (match x with
               | `exit -> exit := true
               | `call ((f : Viewer.t -> Obj.t), ret_ch) ->
                   (* use some Obj magic to make all `calls
                      of the same type *)

                   Event.sync (Event.send ret_ch (
                                 try
                                   Return (f viewer)
                                 with e ->
                                   Exception_return e))
               | `set_frame_handler fh ->
                   frame_handler := fh
            )
    in
      Viewer.realize viewer;
      while not (Viewer.vdone viewer)  && not !exit do
        process_messages ();
        Viewer.frame viewer;
        !frame_handler viewer;
      done;
      Viewer.frame viewer; (* ? *)
      Viewer.close viewer
  in
    { thread = Thread.create viewer_thread ();
      channel = channel }