home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-09-10 | 24.8 KB | 725 lines |
- /************************************************************************
- * JT3Conf (by John W. Gibbs)
- *
- * Copyright (c) 1997 Microsoft Corporation, All Rights Reserved.
- ***********************************************************************/
-
- import java.awt.*;
- import java.applet.*;
- import java.util.*;
- import com.ms.com.*;
- import com.ms.ui.*;
- import tapi3.*;
- import rend.*;
- import AppCtrls;
- import NewDlg;
-
-
- /////////////////////////////////////////////////////////////////////////
- // CLASS: JT3Conf
- //
- // PURPOSE: TAPI 3.0 test program
- // DATE: July 22, 1997
- //
- // DESCRIPTION:
- // Applet/application that allows the user to join, create, and
- // delete conferences using TAPI 3.0. Conference listings are
- // retrieved using the Rendezvous Controls.
- //
- /////////////////////////////////////////////////////////////////////////
-
- public class JT3Conf extends Applet
- implements TapiConstants, // misc. constants
- DISCONNECT_CODE // DC_xxx constants
- {
- // Application name.
- public static final String APP_NAME = "Java TAPI 3.0 Conferencer";
-
- // Maximum number of video window terminals.
- private int m_MaxVideoWnds = 5;
-
- // True if running as stand alone app.
- public boolean m_fStandAlone = false;
-
- // Parent frame of the app.
- private Frame m_ParentFrame = null;
-
- // Resource Wizard generated UI.
- private final AppCtrls ctrls = new AppCtrls(this);
-
- // Main interface to the TAPI component.
- private ITTAPI m_Tapi = null;
-
- // The conference directory component.
- private ITConferenceDirectory m_Directory = null;
-
- // The current call or null if there isn't one.
- private ITBasicCallControl m_Call = null;
-
-
- /////////////////////////////////////////////////////////////////////
- // init
- //
- // Performs applet initialization.
- /////////////////////////////////////////////////////////////////////
- public void init()
- {
- // select a font to use (ctrls needs this)
- Font font = new Font("Dialog", Font.PLAIN, 8);
- this.setFont(font);
-
- // setup the UI generated by the Resource Wizard
- ctrls.CreateControls();
- ctrls.tfStatusBox.setEditable(false);
- DisableControls();
-
- // get parent frame to use for message boxes
- Container parent = getParent();
- while ((parent != null) && (!(parent instanceof Frame))) {
- parent = parent.getParent();
- }
- m_ParentFrame = (Frame) parent;
-
- // resize the frame if running as standalone app
- if (m_fStandAlone) {
- m_ParentFrame.pack();
- m_ParentFrame.setResizable(false);
- }
-
- // create and initialize TAPI component
- SetStatusMessage("Initializing TAPI 3.0...");
- try {
- m_Tapi = new TAPI();
- m_Tapi.Initialize();
- }
- catch (ComException e) {
- DoMessage("Fatal Error: Could not initialize TAPI 3.0");
- m_Tapi = null;
- if (m_fStandAlone) {
- System.exit(0);
- }
- else {
- SetStatusMessage("Could not initialize TAPI 3.0");
- return;
- }
- }
-
- // initialize the conference directory
- SetStatusMessage("Initializing conference directory...");
- try {
- m_Directory = new ConferenceDirectory();
- m_Directory.Init(
- null, // use default server
- null // use default path
- );
- }
- catch (ComException e) {
- DoMessage("Fatal Error: Could not initialize conference directory");
- m_Tapi.Shutdown();
- m_Tapi = null;
- if (m_fStandAlone) {
- System.exit(0);
- }
- else {
- SetStatusMessage("Could not initialize conference directory");
- return;
- }
- }
-
- // get initial data and display it
- SetStatusMessage("Enumerating conferences...");
- if (!EnumerateConferences()) {
- DoMessage("Fatal Error: Could not enumerate conferences");
- m_Tapi.Shutdown();
- m_Tapi = null;
- if (m_fStandAlone) {
- System.exit(0);
- }
- else {
- SetStatusMessage("Could not enumerate conferences");
- return;
- }
- }
- SetStatusMessage("Ready");
-
- // app initialized... enable controls
- ctrls.lstConferences.enable();
- ctrls.btnJoin.enable();
- ctrls.btnNew.enable();
- ctrls.btnDelete.enable();
- ctrls.btnRefresh.enable();
- }
-
- /////////////////////////////////////////////////////////////////////
- // stop
- //
- // Called when the user leaves the applet's webpage.
- /////////////////////////////////////////////////////////////////////
- public void stop()
- {
- if (m_Call != null) {
- DisconnectTheCall(DC_NORMAL);
- }
-
- ctrls.btnJoin.enable();
- ctrls.btnHangup.disable();
- ctrls.btnDelete.enable();
- ctrls.lstConferences.enable();
- SetStatusMessage("Ready");
- }
-
- /////////////////////////////////////////////////////////////////////
- // destroy
- //
- // Called when the applet is destroyed by the browser.
- /////////////////////////////////////////////////////////////////////
- public void destroy()
- {
- try {
- if (m_Tapi != null) {
- m_Tapi.Shutdown();
- }
- }
- catch (ComException e) {
- e.printStackTrace();
- DoMessage("An error occurred while trying to shutdown TAPI");
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- // action
- //
- // Event.ACTION_EVENT event handler.
- /////////////////////////////////////////////////////////////////////
- public boolean action(Event evt, Object arg)
- {
- if (arg.equals("Join")) {
- // join button pressed
- if (JoinTheConference()) {
- ctrls.btnJoin.disable();
- ctrls.btnHangup.enable();
- ctrls.btnDelete.disable();
- ctrls.lstConferences.disable();
- SetStatusMessage("Connected to " + GetSelectedConfName());
- }
- else {
- DoMessage("You were unable to join the conference");
- SetStatusMessage("Ready");
- }
- }
- else if (arg.equals("Hangup")) {
- // hangup button pressed
- if (!DisconnectTheCall(DC_NORMAL)) {
- DoMessage("An error occurred while disconnecting, " +
- "but it will be ignored");
- }
- ctrls.btnJoin.enable();
- ctrls.btnHangup.disable();
- ctrls.btnDelete.enable();
- ctrls.lstConferences.enable();
- SetStatusMessage("Disconnected");
- }
- else if (arg.equals("New")) {
- // new button pressed
- NewDlg newDlg = new NewDlg(m_ParentFrame, m_Directory);
- newDlg.show();
- if (newDlg.GetButtonId() == NewDlg.CREATE) {
- ITConference conf = newDlg.GetConference();
- if (conf != null) {
- ctrls.lstConferences.addItem(conf.getName());
- }
- else {
- DoMessage("The conference failed to be created");
- }
- }
- }
- else if (arg.equals("Delete")) {
- // delete button pressed
- int index = ctrls.lstConferences.getSelectedIndex();
- if (index == -1)
- DoMessage("You must select a conference first");
- else {
- String name = GetSelectedConfName();
- try {
- m_Directory.DeleteConference(name);
- ctrls.lstConferences.delItem(index);
- SetStatusMessage("Conference " + name + " deleted");
- }
- catch (ComException e) {
- DoMessage("Could not delete " + name);
- }
- }
- }
- else if (arg.equals("Refresh")) {
- // refresh button pressed
- EnumerateConferences();
- SetStatusMessage("Ready");
- }
- else {
- return super.action(evt, arg);
- }
- return true;
- }
-
- /////////////////////////////////////////////////////////////////////
- // EnumerateConferences
- //
- // Finds all conferences on and adds their names to the conferences
- // listbox. Returns true on success and false if there was an error.
- /////////////////////////////////////////////////////////////////////
- private boolean EnumerateConferences()
- {
- IEnumVariant enumVar;
- Variant[] pVar = new Variant[1];
- int[] pInt = new int[1];
- ITConference conf;
-
- ctrls.lstConferences.clear();
-
- try {
- enumVar = (IEnumVariant) m_Directory.get_NewEnum();
-
- while (true) {
- // get the next conference (packaged in a variant)
- enumVar.Next(1, pVar, pInt);
- if (pInt[0] == 0)
- break;
- pInt[0] = 0;
-
- // get the conference from the variant
- conf = (ITConference) pVar[0].toObject();
-
- // display the conference name and store its interface
- ctrls.lstConferences.addItem(conf.getName());
- }
- return true;
- }
- catch (ComException e) {
- e.printStackTrace();
- return false;
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- // JoinTheConference
- //
- // Joins the selected conference. The steps required to join a
- // conference are the same as those for making a one-to-one call.
- /////////////////////////////////////////////////////////////////////
- private boolean JoinTheConference()
- {
- ITAddress srcAddr;
- String destAddr;
- ITTerminal[] staticTerms, dynamicTerms, temp;
- ITMediaTerminal[] mediaTerms;
- SafeArray sa;
- Variant var;
-
- // get the destination address
- destAddr = GetSelectedConfName();
- if (destAddr == null) {
- DoMessage("You must select a conference first");
- return false;
- }
-
- // get the source address (an interface)
- srcAddr = GetAddress(ADDRESSTYPE_CONFERENCENAME);
- if (srcAddr == null) {
- DoMessage("No local address supports conferencing");
- return false;
- }
-
- // get static terminals
- staticTerms = GetStaticTerminals(srcAddr);
- if (staticTerms == null) {
- DoMessage("No static terminals were found");
- return false;
- }
-
- // get Video Window Terminals (dynamic terminals)
- dynamicTerms = GetVideoWndTerms(srcAddr, m_MaxVideoWnds);
- if (dynamicTerms == null && m_MaxVideoWnds > 0) {
- DoMessage("No dynamic terminals could be created");
- return false;
- }
-
- // put terminals into a single array
- temp = new ITTerminal[staticTerms.length + dynamicTerms.length];
- System.arraycopy(staticTerms, 0, temp, 0, staticTerms.length);
- System.arraycopy(dynamicTerms, 0, temp, staticTerms.length, dynamicTerms.length);
-
- // create media-terminals
- mediaTerms = CreateMediaTerminals(temp);
- if (mediaTerms == null) {
- DoMessage("Failed to create media-terminals");
- return false;
- }
-
- try {
- // Note that SelectMediaTerminals requires you to package the
- // media-terminals you intend to select in the following way:
- // 1. Each media-terminal must be placed in a variant,
- // 2. the varaints must then be placed in a safearray, and
- // finally,
- // 3. the safearray must be placed in a variant and passed
- // to select media-terminals.
-
- // create a safearray to put the media-terminals into
- sa = new SafeArray(Variant.VariantObject, mediaTerms.length);
-
- // package each media-terminal into a variant and store it
- // in the safearray
- for (int i=0; i < mediaTerms.length; i++) {
- sa.setVariant(i, new Variant(
- Variant.VariantObject,
- mediaTerms[i]
- ));
- }
-
- // put the safearray in a variant
- var = new Variant(sa, false);
-
- // create a call between srcAddr and destAddr
- m_Call = srcAddr.CreateCall(destAddr);
-
- // attach the media-terminals to the call
- m_Call.SelectMediaTerminals(var);
-
- // make the call (true = synchronous)
- m_Call.Connect(true);
- return true;
- }
- catch (Exception e) {
- e.printStackTrace();
- m_Call = null;
- return false;
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- // DisconnectTheCall
- //
- // Disconnects the call using the given disconnect code. Disconnect
- // codes are defined in the DisconnectCode interface.
- /////////////////////////////////////////////////////////////////////
- public boolean DisconnectTheCall(int code)
- {
- if (m_Call == null)
- return true;
-
- try {
- m_Call.Disconnect(code);
- return true;
- }
- catch (ComException e) {
- e.printStackTrace();
- return false;
- }
- finally {
- m_Call = null;
-
- // force a garbage collect. This will ensure that terminals
- // get released (unless you have references to them!), etc.
- // If you do not do this you may have effects such as video
- // windows lingering after a call has disconnected.
- System.gc();
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- // GetStaticTerminals
- //
- // Returns an array of static terminals on the given address. If no
- // static terminals are found then null is returned.
- /////////////////////////////////////////////////////////////////////
- private ITTerminal[] GetStaticTerminals(ITAddress address)
- {
- ITTerminalSupport termSupp;
- Variant var;
- ITCollection itc;
- ITTerminal[] terminals;
-
- if (address == null)
- return null;
-
- try {
- // get the terminal support interface on the address
- termSupp = (ITTerminalSupport) address;
-
- // get the collection interface for static terminals
- var = termSupp.getStaticTerminals();
- itc = (ITCollection) var.toDispatch();
-
- if (itc.getCount() == 0)
- return null;
-
- // create storage for the terminals
- terminals = new ITTerminal[itc.getCount()];
-
- // NOTE: this needs to be modified if the
- // machine has multiple static terminals.
- // the correct way to select terminals
- // is to select only default terminals
-
- for (int i=1; i <= itc.getCount(); i++) {
- // get the next static terminal and store it
- var = itc.getItem(i);
- terminals[i-1] = (ITTerminal) var.toObject();
- }
- return terminals;
- }
- catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- // GetVideoWndTerms
- //
- // Returns an array of Video Window Terminals on the given address,
- // or null if there was an error. count is the number of Video
- // Window Terminals that should be returned.
- //
- // Video Window Terminals are dynamic terminals. Dynamic terminals
- // are different from static terminals in that there is no set
- // number that may exist at any particular time.
- //
- // Static terminals are (usually) tied to hardware devices (eg,
- // microphones, speakers, etc) and, therefore, have a specific count.
- // There is no specific maximum to the number of dynamic terminals
- // (eg, video windows, files, etc) that may be created.
- /////////////////////////////////////////////////////////////////////
- private ITTerminal[] GetVideoWndTerms(ITAddress address, int count)
- {
- ITTerminalSupport termSupp;
- ITTerminal[] terminals;
-
- if (address == null || count < 1)
- return null;
-
- terminals = new ITTerminal[count];
-
- try {
- // get the terminal support interface on the address
- termSupp = (ITTerminalSupport) address;
-
- // create the video window terminals
- for (int i=0; i < count; i++) {
- terminals[i] = termSupp.CreateTerminal(CLSID_String_VideoWindowTerm);
- }
- return terminals;
- }
- catch (ComException e) {
- e.printStackTrace();
- return null;
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- // CreateMediaTerminals
- //
- // Takes an array of terminals and creates media-terminals from them.
- // The media-terminals are returned on success; null is returned on
- // failure.
- //
- // Media-terminals are the association of a terminal object and the
- // mediatype that it will use. In this case, the first mediatype
- // supported by each terminal is used.
- /////////////////////////////////////////////////////////////////////
- private ITMediaTerminal[] CreateMediaTerminals(ITTerminal[] terminals)
- {
- ITMediaTerminal[] mediaTerms;
- ITMediaSupport mediaSupp;
- Variant var;
- ITCollection itc;
- String mediaType;
-
- if (terminals == null || terminals.length == 0)
- return null;
-
- mediaTerms = new ITMediaTerminal[terminals.length];
-
- try {
- for (int i=0; i < terminals.length; i++) {
- // get the media support interface on the terminal
- mediaSupp = (ITMediaSupport) terminals[i];
-
- // get the collection interface for mediatypes
- var = mediaSupp.getMediaTypes();
- itc = (ITCollection) var.toDispatch();
-
- if (itc.getCount() < 1)
- continue;
-
- // get the first mediatype (mediatypes are string GUIDs)
- var = itc.getItem(1);
- mediaType = var.toString();
-
- // create a media-terminal and store it.
- mediaTerms[i] = m_Tapi.CreateMediaTerminal(
- mediaType,
- terminals[i]
- );
- }
- return mediaTerms;
- }
- catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- // GetAddress
- //
- // Returns an interface to the first local address that supports the
- // given address type. If an error occurs or the given address type
- // is not supported by any local addresses, null is returned.
- // Address type constants are defined in the TapiConstants interface.
- /////////////////////////////////////////////////////////////////////
- private ITAddress GetAddress(int addressType)
- {
- Variant var;
- ITCollection itcAddr, itcType;
- ITAddress address;
- int type;
-
- try {
- // get the collection interface for addresses
- var = m_Tapi.getAddresses();
- itcAddr = (ITCollection) var.toDispatch();
-
- for (int i=1; i <= itcAddr.getCount(); i++) {
- // get the next address
- var = itcAddr.getItem(i);
- address = (ITAddress) var.toObject();
-
- // get the collection interface for address types
- var = address.getAddressTypes();
- itcType = (ITCollection) var.toDispatch();
-
- for (int j=1; j <= itcType.getCount(); j++) {
- // get the next address type
- var = itcType.getItem(j);
- type = var.toInt();
-
- // if it's the type we're looking for then return
- // the address
- if (type == addressType)
- return address;
- }
- }
-
- // no address supports the type we're looking for
- return null;
- }
- catch (ComException e) {
- e.printStackTrace();
- return null;
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- // GetSelectedConfName
- //
- // Returns the name of the currently selected conference.
- /////////////////////////////////////////////////////////////////////
- private String GetSelectedConfName()
- {
- return ctrls.lstConferences.getSelectedItem();
- }
-
- /////////////////////////////////////////////////////////////////////
- // DisableControls
- //
- // Disables all of the app's controls.
- /////////////////////////////////////////////////////////////////////
- private void DisableControls()
- {
- ctrls.lstConferences.disable();
- ctrls.btnJoin.disable();
- ctrls.btnHangup.disable();
- ctrls.btnNew.disable();
- ctrls.btnDelete.disable();
- ctrls.btnRefresh.disable();
- }
-
- /////////////////////////////////////////////////////////////////////
- // SetStatusMessage
- //
- // Displays messages in the status box.
- /////////////////////////////////////////////////////////////////////
- private void SetStatusMessage(String msg)
- {
- ctrls.tfStatusBox.setText(msg);
- }
-
- /////////////////////////////////////////////////////////////////////
- // DoMessage
- //
- // Displays messages in a message box.
- /////////////////////////////////////////////////////////////////////
- private void DoMessage(String msg)
- {
- AwtUIMessageBox msgbox = new AwtUIMessageBox(
- m_ParentFrame,
- APP_NAME,
- msg,
- AwtUIMessageBox.EXCLAMATION,
- UIButtonBar.OK
- );
- msgbox.doModal();
- }
-
- /////////////////////////////////////////////////////////////////////
- // main
- //
- // Standalone application entry point. Not called for applets.
- /////////////////////////////////////////////////////////////////////
- public static void main(String[] args)
- {
- JT3Conf applet = new JT3Conf();
-
- AppFrame frame = new AppFrame(APP_NAME, applet);
- frame.show();
-
- applet.m_fStandAlone = true;
- applet.init();
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////
- // CLASS: AppFrame
- //
- // DESCRIPTION:
- // Frame for standalone application.
- //
- /////////////////////////////////////////////////////////////////////////
-
- class AppFrame extends Frame
- {
- private Applet m_App = null;
-
- public AppFrame(String title, Applet applet)
- {
- super(title);
- m_App = applet;
- this.add(applet);
- }
-
- public boolean handleEvent(Event evt)
- {
- if (evt.id == Event.WINDOW_DESTROY) {
- // since a browser would close the applet by calling stop and
- // destroy, we should also.
- m_App.stop();
- m_App.destroy();
- System.exit(0);
- }
-
- return super.handleEvent(evt);
- }
- }
-