home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / S12659.ZIP / SERVER.C < prev    next >
Text File  |  1989-01-09  |  17KB  |  385 lines

  1. /*
  2.  *  This module contains the winprocs for the Graphics Exchange server
  3.  *  application window as well as the DDE conversation windows.
  4.  *  A supplementary routine, InitWindowWordVars, is also included.
  5.  */
  6.  
  7. #include <os2.h>
  8. #include <stdio.h>      /* sprintf */
  9. #include <stdlib.h>     /* memcpy,itoa */
  10. #include <string.h>     /* strcpy,strcmp,strlen */
  11. #include "st.h"
  12. #include "server.h"
  13.  
  14. HWND    hwndDDE;
  15. HPS     hpsGraphics;
  16.  
  17. /*
  18.  *  Function GraphicWndProc
  19.  *
  20.  *  This function processes the system and application menu messages.
  21.  *  When a WM_DDE_INITIATE message contains the correct parameters,
  22.  *  a DDE conversation window is created to manage the conversation.
  23.  *  The WM_TIMER message simulates the arrival of phone messages.  This
  24.  *  message is processed by sending a WM_DDE_REQUEST message to all
  25.  *  conversations which are ADVISING a client application.  The WM_CLOSE
  26.  *  message is processed by terminating ALL conversations related to this
  27.  *  instance of the application.
  28.  */
  29.  
  30. MRESULT APIENTRY   GraphicWndProc(hwnd, message, lParam1, lParam2)
  31. HWND    hwnd;
  32. USHORT  message;
  33. MPARAM  lParam1;
  34. MPARAM  lParam2;
  35. {
  36.       HPS         hps;           /* window micro-ps                   */
  37.       RECTL       lRect;         /* rectangle for sizing operations   */
  38.       SIZEL       lSize;         /* size structure for ps creation    */
  39.       HWND        hwndConv;      /* window handle for conversation    */
  40.       HWND        hwndEnum;      /* current enumeration handle        */
  41.       HENUM       hEnum;         /* enumeration handle                */
  42.       char        szMsgStr[13];  /* temporary work strings            */
  43.       char        szTemp[24];    /* temporary work strings            */
  44.       PDDEINIT    pDDEInit;      /* DDEINIT structure                 */
  45.       PDDESTRUCT  pDDEStruct;    /* DDESTRUCT for DDE messages        */
  46.       PWWVARS     pWWVar;        /* pointer to window data            */
  47.       PWWVARS     pWWChild;      /* pointer to children's window data */
  48.       static int  nConvID = 0;   /* conversation id for dde windows   */
  49.       static char szNameStr[][10] = { "Carl","Tony","Susan","Ellen","David","Patrick",
  50.                                       "Bob","Cliff","Linda","Steve","Dagny" };
  51.       int         currmsg;       /* phone message to be inserted      */
  52.  
  53.       /* pointer to window data block is always queried */
  54.       pWWVar = (PWWVARS)WinQueryWindowPtr(hwnd, QWL_USER);
  55.  
  56.       switch(message) {
  57.  
  58.           case WM_CREATE:    /* create the anchor window,
  59.                                 initialize the PS, and initiate the conversation */
  60.                hwndDDE  = WinCreateWindow(hwnd, (PSZ)"DDEManager", (PSZ)NULL,
  61.                                           NULL, 0,0,0,0, hwnd, HWND_TOP,
  62.                                           NULL, (PVOID)NULL, (PVOID)NULL);
  63.                pWWVar = InitWindowWordVars();
  64.                WinSetWindowPtr(hwnd, QWL_USER, pWWVar);
  65.  
  66.                /* initialize colors array   */
  67.                InitPhoneColors(&pWWVar->PhColors[0], 0);
  68.                InitPhoneColors(&pWWVar->PhColors[1], 1);
  69.  
  70.                /* create presentation space */
  71.                lSize.cx=(LONG)1000; lSize.cy=(LONG)1000;
  72.                hpsGraphics = GpiCreatePS(hab, WinOpenWindowDC(hwnd),
  73.                                          (PSIZEL)&lSize, PU_PELS | GPIA_ASSOC);
  74.                GpiSetDrawingMode(hpsGraphics,DM_RETAIN);
  75.                GpiSetInitialSegmentAttrs(hpsGraphics,ATTR_CHAINED,DCTL_ON);
  76.                GpiSetInitialSegmentAttrs(hpsGraphics,ATTR_VISIBLE,DCTL_ON);
  77.                /* create graphical segment */
  78.                InitPhoneSeg(hpsGraphics, pWWVar->nMsgCnt, &pWWVar->PhColors[0]);
  79.  
  80.                /* initiate conversation */
  81.                WinDdeInitiate(hwnd, "Client", "Graphics_Exchange");
  82.                break;
  83.  
  84.           case WM_DDE_INITIATE:  /* respond if app and topic strings match */
  85.                pDDEInit = (PDDEINIT)lParam2;
  86.  
  87.                /* check for null strings or "Graphics Exchange" */
  88.                if ((HWND)lParam1 != hwnd) {
  89.                   itoa((int)hwnd, szTemp, 10);
  90.                   if(((!strlen(pDDEInit->pszAppName)) &&
  91.                        (!strcmp("Graphics_Exchange", pDDEInit->pszTopic))) ||
  92.                      ((!strcmp(szTemp, pDDEInit->pszAppName)) &&
  93.                        (!strcmp("Graphics_Exchange", pDDEInit->pszTopic))) ||
  94.                      ((!strlen(pDDEInit->pszTopic)) &&
  95.                        (!strlen(pDDEInit->pszAppName))))    {
  96.  
  97.                      /* create conversation window and respond */
  98.                      hwndConv = WinCreateWindow(hwndDDE, (PSZ)"DDEConversation", (PSZ)NULL, WS_VISIBLE,
  99.                                                 0,0,0,0, hwnd, HWND_TOP, ++nConvID, (PVOID)NULL, (PVOID)NULL);
  100.                      pWWVar->ConvCnt++;
  101.                      WinDdeRespond(lParam1, hwndConv, "Client", "Graphics_Exchange");
  102.                   }
  103.                }
  104.                DosFreeSeg(PDDEITOSEL(pDDEInit));
  105.                break;
  106.  
  107.           case WM_CLOSE:  /* enumerate all conversations for termination and quit */
  108.                if (pWWVar->ConvCnt) {
  109.                    pWWVar->bClose = TRUE;
  110.                    hEnum = WinBeginEnumWindows(hwndDDE);
  111.                    while((hwndEnum = WinGetNextWindow(hEnum))) {
  112.                       pWWChild = (PWWVARS)WinQueryWindowULong(hwndEnum, QWL_USER);
  113.                       pWWChild->bClose = TRUE;
  114.                       WinDdePostMsg(pWWChild->hwndLink, hwndEnum, WM_DDE_TERMINATE, NULL, TRUE);
  115.                       WinLockWindow(hwndEnum, FALSE);
  116.                    }
  117.                    WinEndEnumWindows(hEnum);
  118.                }
  119.                else {   /* quit if all conversations have terminated */
  120.                     WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  121.                }
  122.                break;
  123.  
  124.           case APPM_CONV_CLOSE:  /* decrement conversation count and quit if ready */
  125.                pWWVar->ConvCnt--;
  126.                if (!pWWVar->ConvCnt && pWWVar->bClose) {
  127.                   WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  128.                }
  129.                break;
  130.  
  131.           case WM_TIMER:  /* insert phone message into listbox, update graphics,
  132.                              and generate new REQUESTS for all ADVISING windows */
  133.                if(pWWVar->nMsgCnt > 10) {
  134.                   pWWVar->bInsert = !pWWVar->bInsert;
  135.                   pWWVar->nMsgCnt = 0;
  136.                }
  137.                pWWVar->nMsgCnt++;
  138.                GpiDeleteSegment(hpsGraphics, (LONG)IDSEG_PHONE);
  139.                if(pWWVar->bInsert){
  140.                   currmsg = pWWVar->nMsgCnt;
  141.                   sprintf(szMsgStr, "Message No. %d from %s", currmsg, szNameStr[currmsg-1]);
  142.                   WinSendMsg(hStdLB, LM_INSERTITEM, MPFROMSHORT(LIT_END), (MPARAM)szMsgStr);
  143.                   InitPhoneSeg(hpsGraphics, currmsg, &pWWVar->PhColors[0]);
  144.                }
  145.                else {
  146.                   currmsg = 11-pWWVar->nMsgCnt;
  147.                   WinSendMsg(hStdLB, LM_DELETEITEM, MPFROMSHORT(currmsg), (MPARAM)NULL);
  148.                   InitPhoneSeg(hpsGraphics, currmsg, &pWWVar->PhColors[1]);
  149.                }
  150.  
  151.                hEnum = WinBeginEnumWindows(hwndDDE);
  152.                while((hwndEnum = WinGetNextWindow(hEnum))) {
  153.                   pWWChild = (PWWVARS)WinQueryWindowULong(hwndEnum, QWL_USER);
  154.                   if (pWWChild->bAdvise) {
  155.                       pDDEStruct = st_DDE_Alloc(sizeof(DDESTRUCT) + strlen("Graphics") + 1, "DDEFMT_graphics_data");
  156.                       pDDEStruct->offszItemName = (USHORT)sizeof(DDESTRUCT);
  157.                       strcpy(DDES_PSZITEMNAME(pDDEStruct), "Graphics");
  158.                       WinDdePostMsg(hwndEnum, hwnd, WM_DDE_REQUEST, pDDEStruct, TRUE);
  159.                   }
  160.                   WinLockWindow(hwndEnum, FALSE);
  161.                }
  162.                WinEndEnumWindows(hEnum);
  163.                if (pWWVar->nMode == PHONE_MODE) {
  164.                    WinQueryWindowRect(hwnd, &lRect);
  165.                    WinInvalidateRect(hwnd, &lRect, FALSE);
  166.                }
  167.                break;
  168.  
  169.           case WM_PAINT:  /* repaint the window */
  170.                hps = WinBeginPaint(hwnd, NULL, &lRect);
  171.                WinFillRect(hps, &lRect, CLR_WHITE);
  172.                if(pWWVar->nMode == PHONE_MODE)
  173.                   GpiDrawChain(hpsGraphics);
  174.                WinEndPaint(hps);
  175.                break;
  176.  
  177.           case WM_SIZE: /* adjust size of child */
  178.                WinQueryWindowRect(hwnd, &lRect);
  179.                WinSetWindowPos(hStdLB, HWND_TOP, LOUSHORT(lRect.xLeft),
  180.                                LOUSHORT(lRect.yBottom),
  181.                                LOUSHORT(lRect.xRight - lRect.xLeft),
  182.                                LOUSHORT(lRect.yTop - lRect.yBottom),
  183.                                SWP_SIZE | SWP_MOVE);
  184.                GpiSetPageViewport(hpsGraphics, &lRect);
  185.                break;
  186.  
  187.           case WM_COMMAND:  /* menu processing */
  188.                switch (SHORT1FROMMP(lParam1)) {
  189.  
  190.                   case IDM_PHONE:  /* display phone segment */
  191.                        pWWVar->nMode = PHONE_MODE;
  192.                        WinShowWindow(hStdLB, FALSE);
  193.                        break;
  194.  
  195.                   case IDM_STD_LB:  /* display message list box */
  196.                        pWWVar->nMode = STD_LB_MODE;
  197.                        WinShowWindow(hStdLB, TRUE);
  198.                        break;
  199.  
  200.                   case IDM_TIMERON:  /* start system timer */
  201.                        WinStartTimer(hab, hwnd, (USHORT)1, (USHORT)5000);
  202.                        break;
  203.  
  204.                   case IDM_TIMEROFF: /* stop system timer */
  205.                        WinStopTimer(hab, hwnd, (USHORT)1);
  206.                        break;
  207.  
  208.                   default:
  209.                        break;
  210.                }
  211.                break;
  212.  
  213.           case WM_DESTROY:  /* destroy resources and window structure memory */
  214.                GpiAssociate(hpsGraphics, NULL);
  215.                GpiDestroyPS(hpsGraphics);
  216.                free(pWWVar);
  217.                break;
  218.  
  219.           default:
  220.               return(WinDefWindowProc(hwnd, message, lParam1, lParam2));
  221.       }
  222.  
  223.    return((MRESULT)0L);
  224.  
  225. }
  226.  
  227. /*
  228.  *  Function ConversationWndProc
  229.  *
  230.  *  This function is the wndproc for the conversational DDE window
  231.  *  and processes the WM_DDE_REQUEST, WM_DDE_ADVISE, WM_DDE_UNADVISE,
  232.  *  and WM_DDE_TERMINATE messages.  WM_DDE_REQUEST results in the
  233.  *  packaging of relevant data and posting of the WM_DDE_DATA message
  234.  *  to the client application.  WM_DDE_ADVISE and WM_DDE_UNADVISE are
  235.  *  processed by setting an advise bit in the DDE window structure.
  236.  *  WM_DDE_TERMINATE posts a corresponding WM_DDE_TERMINATE to the
  237.  *  client as well as a WM_CONVCLOSE to the main server application.
  238.  *  The conversational window destroys itself when a WM_DDE_TERMINATE
  239.  *  is received.
  240.  */
  241.  
  242. MRESULT APIENTRY ConversationWndProc(hwnd, message, lParam1, lParam2)
  243. HWND    hwnd;
  244. USHORT  message;
  245. MPARAM  lParam1;
  246. MPARAM  lParam2;
  247. {
  248.       PWWVARS       pWWVar;         /* pointer to window data    */
  249.       char          szTemp[24];     /* temporary work string     */
  250.       LONG          lOffset = 0;    /* offset for GpiGetData     */
  251.       SHORT         nNumBytes;      /* data length variable      */
  252.       PDDESTRUCT    pDDEStruct;     /* pointer for DDESTRUCTS    */
  253.       PGDEDATA      pGDEData;       /* pointer for graphics data */
  254.  
  255.       /* pointer to window data block is always queried */
  256.       pWWVar = (PWWVARS)WinQueryWindowPtr(hwnd, QWL_USER);
  257.  
  258.       switch(message) {
  259.  
  260.           case  WM_CREATE: /* initialize window structure and register data format */
  261.                 pWWVar = InitWindowWordVars();
  262.                 WinSetWindowULong(hwnd, QWL_USER, (ULONG)pWWVar);
  263.                 pWWVar->usFormat = st_Register_DDEFMT("DDEFMT_graphics_data");
  264.                 break;
  265.  
  266.           case WM_DDE_REQUEST: /* allocate DDESTRUCT and dump graphics data */
  267.                pDDEStruct = (PDDESTRUCT)lParam2;
  268.                strcpy(szTemp, "Graphics");
  269.                if((pDDEStruct->usFormat == pWWVar->usFormat) &&
  270.                    (!strcmp(szTemp, DDES_PSZITEMNAME(pDDEStruct)))) {
  271.                     if(!pWWVar->bNoData) {
  272.                        nNumBytes = (strlen(szTemp) + 1 + sizeof(GDEDATA) + LOUSHORT(lPhFigCnt));
  273.                        pDDEStruct = st_DDE_Alloc((sizeof(DDESTRUCT) + nNumBytes), "DDEFMT_graphics_data");
  274.                        pDDEStruct->cbData  = sizeof(GDEDATA) + lPhFigCnt;
  275.                        pDDEStruct->offszItemName = (USHORT)sizeof(DDESTRUCT);
  276.                        pDDEStruct->offabData     = (USHORT)((sizeof(DDESTRUCT) + strlen(szTemp)) + 1);
  277.                        pGDEData = (PGDEDATA)DDES_PABDATA(pDDEStruct);
  278.                        st_Init_GDEData(pGDEData);
  279.                        pGDEData->cBytes = lPhFigCnt;
  280.                        strcpy(pGDEData->szItem, "phone");
  281.                        pGDEData->pGpi = (unsigned char far *)((LONG)pGDEData + sizeof(GDEDATA));
  282.                        GpiGetData(hpsGraphics, (LONG)IDSEG_PHONE,
  283.                                   (PLONG)&lOffset, DFORM_NOCONV,
  284.                                   (LONG)lPhFigCnt, (PBYTE)pGDEData->pGpi);
  285.                        memcpy(DDES_PSZITEMNAME(pDDEStruct), szTemp, (strlen(szTemp) + 1));
  286.                        if(lParam1 != WinQueryWindow(hwnd, QW_OWNER, FALSE)) {
  287.                           pDDEStruct->fsStatus |= DDE_FRESPONSE;
  288.                           pWWVar->hwndLink = (HWND)lParam1;
  289.                        }
  290.                        WinDdePostMsg(pWWVar->hwndLink, hwnd, WM_DDE_DATA, pDDEStruct, TRUE);
  291.                     }
  292.                     else {
  293.                        WinDdePostMsg(pWWVar->hwndLink, hwnd, WM_DDE_DATA, NULL, TRUE);
  294.                     }
  295.                     DosFreeSeg(PDDESTOSEL(lParam2));
  296.                }
  297.                else {  /* post negative ack using their DDESTRUCT */
  298.                     pDDEStruct->fsStatus &= (~DDE_FACK);
  299.                     WinDdePostMsg(lParam1, hwnd, WM_DDE_ACK, pDDEStruct, TRUE);
  300.                }
  301.                break;
  302.  
  303.           case WM_DDE_ADVISE:  /* set ADVISE bit in window data and ACK */
  304.                pDDEStruct = (PDDESTRUCT)lParam2;
  305.                if(pDDEStruct->usFormat == pWWVar->usFormat) {
  306.                   pWWVar->hwndLink = (HWND)lParam1;
  307.                   pWWVar->bAdvise = TRUE;
  308.                   if(pDDEStruct->fsStatus & DDE_FNODATA) {
  309.                     pWWVar->bNoData = TRUE;
  310.                   }
  311.                   if(pDDEStruct->fsStatus & DDE_FACKREQ) {
  312.                      pDDEStruct->fsStatus |= DDE_FACK;
  313.                      WinDdePostMsg(pWWVar->hwndLink, hwnd, WM_DDE_ACK, pDDEStruct, TRUE);
  314.                   }
  315.                   else {
  316.                      DosFreeSeg(PDDESTOSEL(lParam2));
  317.                   }
  318.                }
  319.                else {    /* Send a Negative ACK using their DDEStruct */
  320.                   pDDEStruct->fsStatus &= (~DDE_FACK);
  321.                   WinDdePostMsg(lParam1, hwnd, WM_DDE_ACK, pDDEStruct, TRUE);
  322.                }
  323.                break;
  324.  
  325.           case WM_DDE_UNADVISE: /* turn off ADVISE bit in window data and ACK */
  326.                pDDEStruct = (PDDESTRUCT)lParam2;
  327.                if((lParam1 == pWWVar->hwndLink) &&
  328.                   (pDDEStruct->usFormat == pWWVar->usFormat)) {
  329.                     pWWVar->bAdvise       = FALSE;
  330.                     pWWVar->bNoData       = TRUE;
  331.                     pDDEStruct->fsStatus |= DDE_FACK;
  332.                     WinDdePostMsg(lParam1, hwnd, WM_DDE_ACK, pDDEStruct, TRUE);
  333.                }
  334.                else {
  335.                   pDDEStruct->fsStatus &= (~DDE_FACK);
  336.                   WinDdePostMsg(lParam1, hwnd, WM_DDE_ACK, pDDEStruct, TRUE);
  337.                }
  338.                break;
  339.  
  340.           case WM_DDE_TERMINATE: /* destroy conversation window and confirm TERMINATE */
  341.                   if (!pWWVar->bClose) {
  342.                      WinDdePostMsg((HWND)lParam1, hwnd, WM_DDE_TERMINATE, NULL, TRUE);
  343.                   }
  344.                   WinPostMsg(WinQueryWindow(hwnd, QW_OWNER, FALSE), APPM_CONV_CLOSE, MPFROMLONG(hwnd), (MPARAM)NULL);
  345.                   WinDestroyWindow(hwnd);
  346.                   break;
  347.  
  348.           case WM_DESTROY:  /* free window data structure */
  349.                   free(pWWVar);
  350.                   break;
  351.  
  352.           default:
  353.               return(WinDefWindowProc(hwnd, message, lParam1, lParam2));
  354.  
  355.       }
  356.  
  357.       return((MRESULT)0L);
  358.  
  359. }
  360.  
  361. /*
  362.  *  Function InitWindowWordVars
  363.  *
  364.  *  This function allocates memory for the window structure and
  365.  *  initializes the values of the fields.  It returns a pointer to be
  366.  *  stored in the window word.
  367.  */
  368.  
  369. PWWVARS  InitWindowWordVars()
  370. {
  371.    PWWVARS   pWWVar;   /* pointer to window structure */
  372.  
  373.    pWWVar = (PWWVARS)malloc(sizeof(WWVARS));
  374.    pWWVar->nMsgCnt    = 0;
  375.    pWWVar->ConvCnt    = 0;
  376.    pWWVar->nMode      = STD_LB_MODE;
  377.    pWWVar->bInsert    = TRUE;
  378.    pWWVar->bClose     = FALSE;
  379.    pWWVar->hwndLink   = NULL;
  380.    pWWVar->bAdvise    = FALSE;
  381.    pWWVar->bNoData    = FALSE;
  382.    pWWVar->usFormat   = NULL;
  383.    return(pWWVar);
  384. }
  385.