## server.tcl - Communication with the GravityServer
## ==============
##
## Authors:
## Joseph Wang, Department of Astronomy, University of Texas at Austin
## (joe@athena.mit.edu)
##
## History:
## 12 Aug 1992 Separated this file from proc.tcl
##
## Copyright:
## Copyright (C) 1992 Joseph Wang
##
## 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 of the License, 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 this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##

## Conventions:
##   all globally visible objects in this file should begin with
##     GravityServer
##   all interaction with the Gravity server should occur through the
##     procedures in this file

## Global Variables

# the file handle of the server

## *************************
## Procedures for communicating with the Gravity server
##    GravityServerOpen - opens a connection with the Gravity server and
##       returns the opening message
##    GravityServerSend - sends a string to the Gravity server
##    GravityServerReceive - receives a string from the Gravity server
##    GravityServerClose - shuts down the Gravity server
## There are likely to be a lot of problems with deadlock here
## *************************

## GravityServerOpen: Open connection with GravityServer
## ----------
## On entry,
##   exec_string: string to execute
## On exit,
##   the introductory message given by the server
## Side effects,
##   resets the variable GravityServer

proc GravityServerOpen {exec_string} {
   global GravityServer
# open connection with server
# There should be some way of figuring out if the server responds
   set GravityServer [open "| $exec_string" w+]
   return [GravityServerReceive]
}

## GravityServerSend: Send message to Gravity Server
## ----------
## On entry,
##   w: message to server
## On exit,
##   returns response from server
## WARNING:
##   SERVER MUST MAKE SOME SORT OF RESPONSE OR ELSE THERE WILL BE DEADLOCK

proc GravityServerSend {w} {
   global GravityServer
   puts $GravityServer $w
   return [GravityServerReceive]
}

## GravityServerReceive: Wait for response from server
## ----------
## On exit,
##   returns response from server
## WARNING:
##   SERVER MUST MAKE SOME SORT OF RESPONSE OR ELSE THERE WILL BE DEADLOCK

proc GravityServerReceive {} {
  global GravityServer
  set return_string ""

# *** THIS FLUSH IS VERY IMPORTANT
# *** If this isn't put here, you are likely to send the application
# ***    into deadlock

  flush $GravityServer

# Get stuff from the server until the prompt string is detected
# Then return everything.  WARNING.  This will freeze if the prompt
# string is never detected

  while {1} {
    gets $GravityServer string
    if {[regexp ".*Gravity:.*" $string] == 1} {
       break;
    }
    append return_string "$string\n"
  }
  return $return_string;
}

## GravityServerClose: Close connection with server
## ----------
## Side effects:
##   Closes the pipe to the server, resets the server value

proc GravityServerClose {} {
   global GravityServer
# Tell the server to exit
   puts $GravityServer "exit"
# Make sure the message gets there
   flush $GravityServer
# Close the pipe
   close $GravityServer
# reset the server value
   set GravityServer ""
}
