home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / S12518.ZIP / PMSERVER.C < prev    next >
C/C++ Source or Header  |  1989-10-19  |  9KB  |  268 lines

  1. /* pmserver.c RHS 8/24/89
  2.  *
  3.  * Pm program that supplies PM services to VIO apps
  4.  *
  5.  */
  6.  
  7. #define INCL_WIN
  8. #define INCL_VIO
  9. #define INCL_AVIO
  10. #define INCL_DOS
  11. #include<os2.h>
  12. #include<mt\stdlib.h>
  13. #include<mt\process.h>
  14. #include<mt\string.h>
  15. #include"pmserver.h"
  16. #include"msgq.h"
  17. #include"errexit.h"
  18.  
  19. #define WM_COPY             (WM_USER + 0)
  20. #define WM_PASTE            (WM_USER + 1)
  21. #define WM_PASTE_MSG        (WM_USER + 2)
  22.  
  23. typedef struct _client
  24.     {
  25.     PID     clientpid;
  26.     HQUEUE  clientqhandle;
  27.     } CLIENT;
  28.  
  29. #define    MAXCLIENTS    25
  30. CLIENT clients[MAXCLIENTS];
  31.  
  32.  
  33. HAB     hab;
  34. HWND    ThreadWindowHdl;
  35. #define QMGRTHREADSTACK        500
  36. BYTE    QMgrThreadStack[QMGRTHREADSTACK];
  37. HQUEUE  qhandle;
  38.  
  39. int main(void);
  40. MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  41. void QMgrThread(void);
  42. USHORT QMgrFindClient(PID pid,HQUEUE *qhandle,USHORT *position);
  43.  
  44. int main(void)
  45.     {
  46.     static CHAR  szClientClass[] = "PMServer";
  47.     static ULONG flFrameFlags = FCF_TASKLIST;
  48.     HMQ          hmq;
  49.     HWND         hwndFrame, hwndClient;
  50.     QMSG         qmsg;
  51.  
  52.     MsgQCreate(&qhandle,PMSERVERQUE);           // create input queue
  53.  
  54.     hab = WinInitialize(0);                     // initialize window
  55.  
  56.     if(_beginthread(QMgrThread,QMgrThreadStack, // start queue manager thread
  57.             sizeof(QMgrThreadStack),NULL) == -1)
  58.         error_exit(0,"_beginthread(QMgrThread)");
  59.  
  60.     hmq = WinCreateMsgQueue(hab, 0);            // create window message queue
  61.  
  62.                                                 // register window class
  63.     WinRegisterClass(hab, szClientClass, ClientWndProc, 0L, 0);
  64.  
  65.                                                 // create window
  66.     hwndFrame = WinCreateStdWindow(HWND_DESKTOP, 0L,
  67.             &flFrameFlags, szClientClass, NULL,
  68.             0L, NULL, 0L, &hwndClient);
  69.  
  70.     while(WinGetMsg(hab, &qmsg, NULL, 0, 0))    // process messages
  71.         WinDispatchMsg(hab, &qmsg);
  72.  
  73.     WinDestroyWindow(hwndFrame);                // destroy window
  74.     WinDestroyMsgQueue(hmq);                    // destroy message queue
  75.     WinTerminate(hab);                          // terminate window
  76.     return 0;
  77.     }
  78.  
  79. MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  80.     {
  81.     SEL             ClipTextSel;
  82.     PVOID           temp1,temp2;
  83.     USHORT          len;
  84.     PCH             temp3;
  85.     USHORT          fmtInfo;
  86.  
  87.     switch(msg)
  88.         {
  89.         // ************* Create processing **********
  90.         case WM_CREATE:
  91.             ThreadWindowHdl = hwnd;
  92.             return 0;
  93.  
  94.         // **************Clipboard handling *********
  95.  
  96.         case WM_COPY:                           // place client data in Clpbrd
  97.             DosAllocSeg(SHORT1FROMMP(mp2),&ClipTextSel,SEG_GIVEABLE);
  98.             temp1 = MAKEP(ClipTextSel,0);
  99.             temp2 = PVOIDFROMMP(mp1);
  100.             memmove(temp1,temp2,SHORT1FROMMP(mp2));
  101.             temp1 = temp2 = NULL;
  102.  
  103.             WinOpenClipbrd(hab);                // open the clipboard
  104.             WinEmptyClipbrd(hab);               // empty it
  105.                                                 // put the new data in it
  106.             WinSetClipbrdData(hab, (ULONG)ClipTextSel, CF_TEXT, CFI_SELECTOR);
  107.             WinCloseClipbrd(hab);               // close the clipboard
  108.             return 0;
  109.  
  110.         case WM_PASTE:                          // get client data from Clpbrd
  111.             WinOpenClipbrd(hab);                // open the clipboard
  112.             ClipTextSel = (SEL)WinQueryClipbrdData(hab, CF_TEXT);
  113.             if(ClipTextSel)                     // if data in clipboard
  114.                 {
  115.                 temp3 = temp1 = MAKEP(ClipTextSel,0);
  116.                 for( len = 0; temp3[len]; len++); // get data length
  117.                 len++;                          // include the NULL
  118.                                                 // send data to client
  119.                 MsgQSend(SHORT1FROMMP(mp1),temp1,len,PMS_CLPBRD_DATA);
  120.                 }
  121.             else                                // nothing in clipboard
  122.                 MsgQSend(SHORT1FROMMP(mp1),NULL,0,PMS_CLPBRD_EMPTY);
  123.             WinCloseClipbrd(hab);
  124.             return 0;
  125.  
  126.         case WM_PASTE_MSG:                      // client query about Clpbrd
  127.                                                 // tell client whether avail
  128.             MsgQSend(SHORT1FROMMP(mp1),NULL,0,
  129.                     (WinQueryClipbrdFmtInfo(hab,CF_TEXT,&fmtInfo) ?
  130.                     PMS_CLPBRD : PMS_CLPBRD_EMPTY));
  131.             return 0;
  132.         }
  133.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  134.     }
  135.  
  136.  
  137. void QMgrThread(void)
  138.     {
  139.     PVOID   msgdata = NULL;
  140.     USHORT  msg,i,msgsize,position;
  141.     HQUEUE  temphandle;
  142.     PBYTE   tempname;
  143.     PID     temppid;
  144.  
  145.     memset(clients,0,sizeof(clients));
  146.  
  147.     while(TRUE)
  148.         {
  149.         temppid = 0;
  150.         MsgQGet(qhandle, &msgdata, &msgsize, &msg);
  151.  
  152.         switch(msg)
  153.             {
  154.             case PMS_COPY:
  155.                 break;
  156.             case PMS_INIT:
  157.             case PMS_TERMINATE:
  158.             case PMS_CLPBRD_QUERY:
  159.             case PMS_PASTE:
  160.             default:
  161.                 temppid = (msgdata ? CLIENTDATAMSG(msgdata)->pid : 0);
  162.                 break;
  163.             }
  164.  
  165.         switch(msg)
  166.             {
  167.             case PMS_INIT:  // client is initializing to use the server
  168.                 if(msgdata)                        // if valid message packet
  169.                     {
  170.                     tempname = CLIENTDATAMSG(msgdata)->qname;
  171.                     if(*tempname)               // client has return queue
  172.                         MsgQOpen(&temphandle,tempname);
  173.  
  174.                                                 // find open slot
  175.                     for( i = 0; i < MAXCLIENTS && clients[i].clientpid; i++);
  176.                     if(i == MAXCLIENTS)            // no slots found
  177.                         {
  178.                         if(temphandle)
  179.                             MsgQSend(temphandle,NULL,0,PMS_NO_INIT);
  180.                         }
  181.                     else                        // got open slot
  182.                         {
  183.                         clients[i].clientpid = CLIENTDATAMSG(msgdata)->pid;
  184.                         if(temphandle)
  185.                             {
  186.                             clients[i].clientqhandle = temphandle;
  187.                             MsgQSend(temphandle,NULL,0,PMS_INIT_ACK);
  188.                             }
  189.                         }
  190.                     }
  191.                 tempname = NULL;
  192.                 break;
  193.  
  194.             case PMS_COPY:  // client has data for the Clipboard
  195.                 WinPostMsg(ThreadWindowHdl,WM_COPY,MPFROMP(msgdata),
  196.                         MPFROMSHORT(msgsize));
  197.                 msgdata = NULL;
  198.                 break;
  199.  
  200.             case PMS_CLPBRD_QUERY:
  201.                     // client wants to know if something's in the clipboard
  202.                 if(QMgrFindClient(temppid,&temphandle,&position))
  203.                     WinPostMsg(ThreadWindowHdl,WM_PASTE_MSG,
  204.                             MPFROMSHORT(temphandle),NULL);
  205.                 break;
  206.  
  207.             case PMS_PASTE:
  208.                     // client is requesting a copy of the Clipboard data
  209.                 if(QMgrFindClient(temppid,&temphandle,&position))
  210.                     WinPostMsg(ThreadWindowHdl,WM_PASTE,
  211.                             MPFROMSHORT(temphandle),NULL);
  212.                 break;
  213.  
  214.             case PMS_TERMINATE:
  215.                     // client is terminating or is no longer using PM Services
  216.                 if(QMgrFindClient(temppid,&temphandle,&position))
  217.                     {
  218.                         // if not last slot, shift down 1
  219.                     if(position != MAXCLIENTS-1)
  220.                         memmove(&clients[position],&clients[position+1],
  221.                             (sizeof(CLIENT)*(MAXCLIENTS-position-1)));
  222.  
  223.                                             // clear last slot
  224.                     memset(&clients[MAXCLIENTS-1],0,sizeof(CLIENT));
  225.                     }
  226.                 break;
  227.  
  228.             default:
  229.                 // unknown message rec'd, notify client if it has a queue
  230.                 if(QMgrFindClient(temppid,&temphandle,&position))
  231.                     MsgQSend(temphandle,NULL,0,PMS_MSG_UNKNOWN);
  232.                 break;
  233.             }
  234.         if(msgdata)
  235.             DosFreeSeg(SELECTOROF(msgdata));
  236.         msgdata = NULL;
  237.         }
  238.     }
  239.  
  240. // finds PMServer client and qhandle in table
  241. USHORT QMgrFindClient(PID pid,HQUEUE *qhandle,USHORT *position)
  242.     {
  243.     USHORT  i;
  244.  
  245.     for( i = 0; i < MAXCLIENTS; i++)
  246.         if(clients[i].clientpid == pid)
  247.             {
  248.             *qhandle = clients[i].clientqhandle;
  249.             *position = i;
  250.             return TRUE;
  251.             }
  252.     return FALSE;
  253.     }
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.