/*+MHDR*/
/*
+------------------------------------------------------------------------------+
#  Modulname: usergate.c
#  Clearcase: @@/main/8
#  VersionId: Tau4.2
+------------------------------------------------------------------------------+
|                                                                              |
|  Description  : This is the main modul of the SDL Target Tester Gateways.    |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-MHDR*/

/*
+------------------------------------------------------------------------------+
|                                                                              |
|  Copyright by Telelogic AB 1993 - 2001                                       |
|                                                                              |
|  This Program is owned by Telelogic and is protected by national             |
|  copyright laws and international copyright treaties. Telelogic              |
|  grants you the right to use this Program on one computer or in              |
|  one local computer network at any one time.                                 |
|  Under this License you may only modify the source code for the purpose      |
|  of adapting it to your environment. You must reproduce and include          |
|  any copyright and trademark notices on all copies of the source code.       |
|  You may not use, copy, merge, modify or transfer the Program except as      |
|  provided in this License.                                                   |
|  Telelogic does not warrant that the Program will meet your                  |
|  requirements or that the operation of the Program will be                   |
|  uninterrupted and error free. You are solely responsible that the           |
|  selection of the Program and the modification of the source code            |
|  will achieve your intended results and that the results are actually        |
|  obtained.                                                                   |
|                                                                              |
+------------------------------------------------------------------------------+
*/
#ifndef __USERGATE_C_
#define __USERGATE_C_

/*+IMPORT*/
/*====================  I M P O R T  =========================================*/
#include "usergate.h"
#include "mg_ctrl.h"
#include "mg_dl.h"
#include "mp_lib.h"
#include <stdio.h>

#ifdef XMK_UNIX
  #include <fcntl.h>
  #include <errno.h>
  #include <pwd.h>
  #include <unistd.h>
  #include <stdlib.h>

#else /* XMK_WINDOWS */
  #include <windows.h>
  #include <windowsx.h>

  #ifdef LAUTGATE
    #include <winsock.h>
    #include "lautcomm.h"
    #include "t32.h"
  #endif

#endif

#ifdef GET_VERSION_FILE
  #include "versions.h"
#endif

/*--------------------  Functions    -----------------------------------------*/
/*--------------------  Variables    -----------------------------------------*/
#ifdef XMK_WINDOWS
 extern int     com_handle;
#endif

/*============================================================================*/
/*-IMPORT*/


/*+MGG*/
/*====================  V A L U E S  O F  T H I S   M O D U L E  =============*/

/*--------------------  Constants,  Macros  ----------------------------------*/
#ifdef XMK_WINDOWS
  #ifdef LAUTERBACH
    #define ABOUT_CAPTION "SDL Target Tester Lauterbach Gateway"
  #else
    #define ABOUT_CAPTION "SDL Target Tester Gateway"
  #endif
#endif
/*--------------------  Typedefinitions     ----------------------------------*/

/*--------------------  Functions    -----------------------------------------*/
#ifdef XMK_WINDOWS
  BOOL FAR PASCAL  InitApplication     (HANDLE hInstance);
  BOOL             InitInstance        (HANDLE hInstance, int nCmdShow);
  LRESULT CALLBACK MainWndProc         (HWND, UINT, WPARAM, LPARAM);
  BOOL FAR PASCAL  AboutDlgProc        (HWND, UINT, WPARAM, LPARAM) ;
#endif

/*--------------------  Variables    -----------------------------------------*/
/* Device configuration */
xmk_T_GateDevice xmk_GateDevice;

/* store the status of the communications interface */
xmk_T_GateLineStatusCnf   xmk_LineStatus;

/* Coding rules for the message decoding */
xmk_T_GateCodingRules    GateCodingRules;

xmk_U_MsgParams   MessageParams;
int               xmk_TargetStarted = XMK_ERROR;

#ifdef LAUTERBACH
  int EmulationState = 0;
#endif

#ifdef XMK_WINDOWS
  static int     MessageTag;
  HANDLE         hInst;                /* Current instance of application  */
  HWND           hWnd;                 /* Handle of Main window            */
  int            xScreen;              /* Screen metrics                   */
  int            yScreen;              /*  ...                             */

  #ifdef LAUTERBACH
    char szAppName[] = "Emulator Connection";
  #else
    char szAppName[] = "SDL Target Tester Gateway";
  #endif
#endif /* XMK_WINDOWS */

/*============================================================================*/
/*-MGG*/

#ifdef XMK_UNIX
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : main - for UNIX only                                         |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :                                                               |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/
/*+FDEF E*/
int main (int argc, char **argv)
/*-FDEF E*/
{
  int deinit_confirm ;
  int result;

  if( CheckMinusVOptions( argc, argv ) == TRUE )
  {
    return(0);
  }
 
  /*
  **  Init Cmicro PostMaster connection
  */
  result = MPMInit (ID_SDTGATE);
  if (result == MPM_ERROR)
  {
    fprintf (stderr, "%s:Connection denied", "SDTGATE Error");
    exit (-5);
  }

  MPMBroadcast (GateStartupNotification, (void *) NULL, 0);

  /*
  ** Sleep to let the UI coming up faster
  */
  sleep(2);

  /*
  ** Run Cmicro Gateway if Connection established
  */
  while (1)
  {
    /* 
    ** The call to MPMListen below checks whether there is a message received
    ** and if yes, MPMListen calls MPMReceive.
    ** possibility to do other things here 
    **   -use MPM_NO_BLOCKING for that case !
    */
    result = MPMListen (MPM_NO_BLOCKING);
    switch (result)
    {
      case MPM_IS_DISCONNECTED:
      {
        if(xmk_TargetStarted != XMK_ERROR)
        {
          deinit_confirm = xmk_DLDeinit ();
          xmk_TargetStarted = XMK_ERROR;
        }
        MPMExit (ID_SDTGATE);
      }
      break;

      default:
        break;
    }

    if(xmk_TargetStarted != XMK_ERROR)
    {
      #ifdef LAUTERBACH
        unsigned long count;
        if( count == 30 ) /* 30 ms */
        {
          xmk_DLHandleTimer();
          count = 0;
        }
        else
        {
          count++;
        }
      #else
        xmk_DLHandleTimer();
      #endif
    }
    #ifdef LAUTERBACH
      usleep(1000);
    #else
     usleep(10000);
    #endif
  }
}

#endif /* XMK_UNIX */

#ifdef XMK_WINDOWS
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : WinMain                                                      |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description : The main function for the Windows application.                |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/
/*+FDEF E*/
int WINAPI WinMain( HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR     lpszCmdLine,
                    int       nCmdShow)
/*-FDEF E*/
{
  MSG msg;
  HWND otherWnd;

  /*
  ** Program already has been started ?
  */
  if ((otherWnd = FindWindow(szAppName,NULL)) != NULL)
  {
    MessageBeep(-1);
    SetFocus (otherWnd);
    return (FALSE);
  }

  if( SetMessageQueue( 100 ) == 0)
  {
    MessageBeep(-1);
    return (FALSE);
  }

  if(!hPrevInstance)                     /* Other instances of app running?  */
    if(!InitApplication(hInstance))      /* Initialize shared things         */
      return (FALSE);                    /* Exits if unable to initialize    */

  if(!InitInstance (hInstance, nCmdShow))
    return (FALSE);

  if ( MPMInit(ID_SDTGATE) != MPM_ERROR)
  {
    MPMBroadcast(GateStartupNotification, (void*) NULL, 0);
  }
  else
  {
    char text[256];
    #ifdef GET_VERSION_FILE
      sprintf(text, "No Postmaster connection.\n"
                    ABOUT_CAPTION"\n%s", SUGetTAUVersionString());
    #else
      sprintf(text, "No Postmaster connection.\nUser Compiled Gateway\n");
    #endif
    MessageBox(NULL, text, ABOUT_CAPTION " - Error", MB_OK);
    return(FALSE);
  }

  if ((otherWnd = FindWindow(NULL, "SDL Target Tester UI - .\\ - NO SYMBOLS LOADED")) != NULL)
  {
    /* Switch to sdtmtui */
    SetForegroundWindow(otherWnd);
    return (FALSE);;
  }


  while (GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage (&msg);
  }
  return (msg.wParam);
}
/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : InitApplication                                              |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description : The windows application will be initialized.                  |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/
/*+FDEF E*/
BOOL FAR PASCAL 
  InitApplication( HANDLE hInstance)
/*-FDEF E*/
{
  WNDCLASS wc;
  wc.style         = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc   = MainWndProc;
  wc.cbClsExtra    = 0;
  wc.cbWndExtra    = 0;
  wc.hInstance     = hInstance;
  wc.hIcon         = LoadIcon ( hInstance, "SdtgateIcon" );
  wc.hCursor       = LoadCursor ( NULL, IDC_ARROW );
  wc.hbrBackground = GetStockObject ( WHITE_BRUSH );
  wc.lpszMenuName  = "SdtgateMenu";
  wc.lpszClassName = szAppName;

  if ( ! RegisterClass(&wc) )
  {
    return (FALSE);
  }
  else
  {
    return (TRUE);
  }
}

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : InitInstance                                                 |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description : The applications instance is initialized.                     |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/
/*+FDEF E*/
BOOL 
  InitInstance( HANDLE hInstance,
                int nCmdShow)
/*-FDEF E*/
{
  HMENU hMenu;
  hInst = hInstance;
  xScreen = GetSystemMetrics(SM_CXSCREEN);
  yScreen = GetSystemMetrics(SM_CYSCREEN);
  hWnd = CreateWindow(szAppName,
                      szAppName,
                      WS_OVERLAPPEDWINDOW,
                      190,                   /* These co-ordinates look */
                      yScreen / 2 - 20,      /* good on a VGA monitor   */
                      xScreen - 200,         /* running in 640x480.  No */
                      yScreen / 2 - 50,      /* combination was tried.  */
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

  if(!hWnd)
    return (FALSE);

  hMenu = GetSystemMenu( hWnd, FALSE );

  AppendMenu( hMenu, MF_SEPARATOR, 0, NULL);
  AppendMenu( hMenu, MF_STRING, IDM_ABOUT, "About...");

  ShowWindow(hWnd, SW_SHOWMINNOACTIVE);      /* Show the window                  */
  UpdateWindow(hWnd);                        /* Sends WM_PAINT message           */
  return (TRUE);
}

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : MainWndProc                                                  |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description : The applications main loop. Handling all the windows messages.|
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/
/*+FDEF E*/
LRESULT CALLBACK 
MainWndProc( HWND hWnd,
             UINT message,
             WPARAM wParam,
             LPARAM lParam )
/*-FDEF E*/
{
  int    deinit_confirm ;
  static FARPROC lpfnAboutDlgProc ;
  static HINSTANCE  hInstance ;

  switch (message)
  {
    case WM_CREATE:
    {
      hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
      lpfnAboutDlgProc = MakeProcInstance ((FARPROC) AboutDlgProc, hInstance) ;
    }
    break;

    case WM_TIMER:
    {
      xmk_DLHandleTimer(wParam);
    }
    break;

    case WM_COMMAND:
    {
      switch ((MessageTag=GET_WM_COMMAND_ID(wParam, lParam)))
      {
        case IDM_EXIT:
        {
          deinit_confirm = xmk_DLDeinit();
          DestroyWindow(hWnd);
        }
        break;

        case UDM_TOSERVER:
        {
          int i = DialogBox (hInstance, "AboutBox", hWnd, lpfnAboutDlgProc) ;
        }
        break;

        default:
        {
          return (DefWindowProc(hWnd, message, wParam, lParam));
        }
      }
    }
    break;

    case WM_SYSCOMMAND:
    {
      switch (wParam)
      {
        case IDM_ABOUT:
        {
          int i = DialogBox (hInstance, "AboutBox", hWnd, lpfnAboutDlgProc) ;
        }
        break;

        default:
        {
          return (DefWindowProc(hWnd, message, wParam, lParam));
        }
      }
    }
    break;

    case WM_DESTROY:
    {
      PostQuitMessage(0);
    }
    break;
    
    case WM_QUERYOPEN:
    {
      return 0;
    }

    default:
    {
      return (DefWindowProc(hWnd, message, wParam, lParam));
    }
  }
  return (FALSE);
}

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : AboutDlgProc                                                 |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :  This function shows the about dialog.                        |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/
/*+FDEF E*/
BOOL FAR PASCAL 
AboutDlgProc ( HWND hDlg, 
               UINT message,
               WPARAM wParam,
               LPARAM lParam)
/*-FDEF*/
{
  switch (message)
  {
    case WM_INITDIALOG:
    {
      HWND hString = GetDlgItem( hDlg, ID_VERSIONSTRING );
      #ifdef GET_VERSION_FILE
        SetWindowText( hString, SUGetTAUVersionString());
      #else
        SetWindowText( hString, "User Version");
      #endif
    }
    return TRUE ;

    case WM_COMMAND:
    switch (wParam)
    {
      case IDOK:
      case IDCANCEL:
      {
        EndDialog (hDlg, 0) ;
      }
      return TRUE ;
    }
    break ;
  }
  return FALSE ;
}

#endif /* XMK_WINDOWS */

/*+FHDR E*/
/*
+------------------------------------------------------------------------------+
|  Functionname : MPMReceive                                                   |
+------------------------------------------------------------------------------+
|                                                                              |
|  Description :  This function retrieves all the Cmicro Postmaster messages   |
|                 and reacts to them.                                          |
|                                                                              |
+------------------------------------------------------------------------------+
*/
/*-FHDR E*/
/*+FDEF E*/
void 
MPMReceive( int   sender,
            int   mtag,
            int   len,
            void* data)
/*-FDEF E*/
{
  int  deinit_confirm ;

  switch (mtag)
  {
    case SdtmtStartupNotification:
    case UIStartupNotification:
    case GateStartupNotification:
    case LinkStartupNotification:
    case GateConnectionCnf:
    /*
    **  No need to deal with this stuff here
    */
    break;

#ifdef XMK_WINDOWS
    case AlertExit:
    {
      MPMExit();
      deinit_confirm = xmk_DLDeinit();
      PostQuitMessage(0);
    }
    break;
#else 
    case MPMDisconnectInd:
    {
      deinit_confirm = xmk_DLDeinit (); 
      MPMExit (ID_SDTGATE);
      exit(-1);
    }
    break;
#endif

    default:
    {
      int err_code = xmk_GateControl( mtag, len, data, &MessageParams );

      if (err_code != CTRL_OKAY )
      {
        xmk_GateErrorHandler( "Error in message handling" );
      }
    }
  }
}

/*====================  E N D   O F   M O D U L E   ==========================*/

#endif /* __USERGATE_C_ */
