home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / fed0217s.zip / source / clip.cpp < prev    next >
C/C++ Source or Header  |  2000-11-16  |  7KB  |  332 lines

  1. /*
  2. ** Module   :CLIP.CPP
  3. ** Abstract :Clipboard command line utility
  4. **
  5. ** Public domain by Sergey I. Yevtushenko
  6. **
  7. ** Log: Tue  15/02/2000 Created
  8. **
  9. */
  10.  
  11. #define INCL_DOS
  12. #define INCL_WIN
  13.  
  14. #include <os2.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17.  
  18. #define MODE_NONE   0
  19. #define MODE_IN     0x0001
  20. #define MODE_OUT    0x0002
  21.  
  22. struct Chunk
  23. {
  24.     Chunk *next;
  25.     int  sz;
  26.     char data[2048];
  27.  
  28.  
  29.     Chunk():next(0), sz(0) {}
  30. };
  31.  
  32. BOOL (APIENTRY *_inCloseClipbrd)(HAB);
  33. HMQ  (APIENTRY *_inCreateMsgQueue)(HAB, LONG);
  34. BOOL (APIENTRY *_inDestroyMsgQueue)(HMQ);
  35. BOOL (APIENTRY *_inEmptyClipbrd)(HAB);
  36. HAB  (APIENTRY *_inInitialize)(ULONG);
  37. BOOL (APIENTRY *_inOpenClipbrd)(HAB);
  38. ULONG(APIENTRY *_inQueryClipbrdData)(HAB, ULONG);
  39. BOOL (APIENTRY *_inQueryClipbrdFmtInfo)(HAB, ULONG, PULONG);
  40. BOOL (APIENTRY *_inSetClipbrdData)(HAB, ULONG, ULONG, ULONG);
  41. BOOL (APIENTRY *_inTerminate)(HAB);
  42.  
  43. HAB hab;
  44. HMQ hmq;
  45.  
  46. //---------------------------------------------------------------
  47. // STDIN Stuff
  48. //---------------------------------------------------------------
  49.  
  50. char *ReadPipe(int iPipe)
  51. {
  52.     APIRET rc;
  53.     ULONG ulTotal     = 0;
  54.     ULONG ulBytesRead = 0;
  55.     Chunk* pHead = new Chunk;
  56.     Chunk* pCurr = pHead;
  57.  
  58.     do
  59.     {
  60.         ulBytesRead = 0;
  61.  
  62.         rc = DosRead(0, pCurr->data, sizeof(pCurr->data), &ulBytesRead);
  63.  
  64.         pCurr->sz = ulBytesRead;
  65.         ulTotal += ulBytesRead;
  66.  
  67.         if(ulBytesRead)
  68.         {
  69.             pCurr->next = new Chunk;
  70.             pCurr       = pCurr->next;
  71.         }
  72.     }
  73.     while(!rc && ulBytesRead);
  74.  
  75.     char *str = 0;
  76.  
  77.     if(ulTotal)
  78.     {
  79.         str = new char[ulTotal+1];
  80.  
  81.         char *ptr = str;
  82.  
  83.         for(pCurr = pHead; pCurr; pCurr = pCurr->next)
  84.         {
  85.             if(!pCurr->sz)
  86.                 continue;
  87.  
  88.             memcpy(ptr, pCurr->data, pCurr->sz);
  89.             ptr += pCurr->sz;
  90.         }
  91.         *ptr = 0;
  92.     }
  93.  
  94.     //Free memory
  95.  
  96.     for(pCurr = pHead; pCurr; )
  97.     {
  98.         Chunk* pTmp  = pCurr;
  99.         pCurr = pCurr->next;
  100.  
  101.         delete pTmp;
  102.     }
  103.  
  104.     return str;
  105. }
  106.  
  107. //---------------------------------------------------------------
  108. // PM Stuff
  109. //---------------------------------------------------------------
  110.  
  111. int init_pm(void)
  112. {
  113.     PPIB pib;
  114.     PTIB tib;
  115.     APIRET rc;
  116.     HMODULE hMte = 0;
  117.     char loadErr[256];
  118.  
  119.     if(hab || hmq)
  120.         return 0;
  121.  
  122.     rc = DosGetInfoBlocks(&tib, &pib);
  123.  
  124.     rc = DosQueryModuleHandle((PCH)"PMWIN", &hMte);
  125.  
  126.     if(rc)
  127.         return 1;
  128.  
  129.     pib->pib_ultype = 3;
  130.  
  131.     rc = DosLoadModule((PCH)loadErr, sizeof(loadErr), (PCH)"PMWIN", &hMte);
  132.  
  133.     if(rc)
  134.         return 1;
  135.  
  136.     rc = DosQueryProcAddr(hMte, 707, 0, (PFN*)&_inCloseClipbrd);
  137.     rc = DosQueryProcAddr(hMte, 716, 0, (PFN*)&_inCreateMsgQueue);
  138.     rc = DosQueryProcAddr(hMte, 726, 0, (PFN*)&_inDestroyMsgQueue);
  139.     rc = DosQueryProcAddr(hMte, 733, 0, (PFN*)&_inEmptyClipbrd);
  140.     rc = DosQueryProcAddr(hMte, 763, 0, (PFN*)&_inInitialize);
  141.     rc = DosQueryProcAddr(hMte, 793, 0, (PFN*)&_inOpenClipbrd);
  142.     rc = DosQueryProcAddr(hMte, 806, 0, (PFN*)&_inQueryClipbrdData);
  143.     rc = DosQueryProcAddr(hMte, 807, 0, (PFN*)&_inQueryClipbrdFmtInfo);
  144.     rc = DosQueryProcAddr(hMte, 854, 0, (PFN*)&_inSetClipbrdData);
  145.     rc = DosQueryProcAddr(hMte, 888, 0, (PFN*)&_inTerminate);
  146.  
  147.     hab = _inInitialize(0);
  148.     hmq = _inCreateMsgQueue(hab, 0);
  149.  
  150.     return 0;
  151. }
  152.  
  153. void done_pm(void)
  154. {
  155.     if(hmq)
  156.         _inDestroyMsgQueue(hmq);
  157.     if(hab)
  158.         _inTerminate(hab);
  159.  
  160.     hab = 0;
  161.     hmq = 0;
  162. }
  163.  
  164. void set_clip(char *text)
  165. {
  166.     if(!hab || !text)
  167.         return;
  168.  
  169.     char *pByte = 0;
  170.  
  171.     //Calculate size of buffer
  172.  
  173.     int sz = strlen(text) + 1;
  174.     int i;
  175.  
  176.     _inOpenClipbrd(hab);
  177.     _inEmptyClipbrd(hab);
  178.  
  179.     if (!DosAllocSharedMem((PPVOID)&pByte, 0, sz,
  180.         PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_GETTABLE))
  181.     {
  182.         memcpy(pByte, text, sz);
  183.         _inSetClipbrdData(hab, (ULONG) pByte, CF_TEXT, CFI_POINTER);
  184.     }
  185.     _inCloseClipbrd(hab);
  186. }
  187.  
  188. char* get_clip(void)
  189. {
  190.     if(!hab)
  191.         return 0;
  192.  
  193.     char *ClipData;
  194.     ULONG ulFormat;
  195.  
  196.     _inQueryClipbrdFmtInfo(hab, CF_TEXT, &ulFormat);
  197.  
  198.     if(ulFormat != CFI_POINTER)
  199.         return 0;
  200.  
  201.     _inOpenClipbrd(hab);
  202.  
  203.     ClipData = (char *)_inQueryClipbrdData(hab, CF_TEXT);
  204.  
  205.     if(!ClipData)
  206.         return 0;
  207.  
  208.     int sz = strlen(ClipData) + 1;
  209.     char *str = new char[sz];
  210.  
  211.     memcpy(str, ClipData, sz);
  212.  
  213.     _inCloseClipbrd(hab);
  214.  
  215.     return str;
  216. }
  217.  
  218.  
  219. char cUsage[] = "CLIP V0.1 Command line clipboard handler.\r\n"
  220.                 "Public domain by Sergey I. Yevtushenko.\r\n"
  221.                 "\r\n"
  222.                 "Usage: CLIP [-o[-]] [-i[-]] [-{h|?}]\r\n"
  223.                 ;
  224.  
  225. void usage(void)
  226. {
  227.     ULONG  ulWrote = 0;
  228.     DosWrite(1, cUsage, sizeof(cUsage) - 1, &ulWrote);
  229. }
  230.  
  231. int main(int argc, char **argv)
  232. {
  233.     ULONG ulType = 0;
  234.     ULONG ulAttr = 0;
  235.     APIRET rc;
  236.     int i;
  237.     int iMode = MODE_NONE;
  238.  
  239.     rc = DosQueryHType(0, &ulType, &ulAttr);    //STDIN
  240.  
  241.     //printf("rc = %d, type = %08x, attr = %08x\n", rc, ulType, ulAttr);
  242.  
  243.     if(!rc)
  244.     {
  245.         ulType &= 0xFF;
  246.  
  247.         if(ulType == 0 || ulType == 2)  //file or pipe
  248.             iMode |= MODE_IN;
  249.     }
  250.  
  251.     rc = DosQueryHType(1, &ulType, &ulAttr);    //STDOUT
  252.  
  253.     //printf("rc = %d, type = %08x, attr = %08x\n", rc, ulType, ulAttr);
  254.  
  255.     if(!rc)
  256.     {
  257.         ulType &= 0xFF;
  258.  
  259.         if(ulType == 0 || ulType == 2)  //file or pipe
  260.             iMode |= MODE_OUT;
  261.     }
  262.  
  263.  
  264.     for(i = 1; i < argc; i++)
  265.     {
  266.         if(argv[i][0] == '-' || argv[i][0] == '/')
  267.         {
  268.             switch(argv[i][1])
  269.             {
  270.                 case 'I':
  271.                 case 'i':
  272.                     if(argv[i][2] == '-')
  273.                         iMode &= ~MODE_IN;
  274.                     else
  275.                         iMode |= MODE_IN;
  276.                     break;
  277.  
  278.                 case 'o':
  279.                 case 'O':
  280.                     if(argv[i][2] == '-')
  281.                         iMode &= ~MODE_OUT;
  282.                     else
  283.                         iMode |= MODE_OUT;
  284.                     break;
  285.  
  286.                 case 'h':
  287.                 case 'H':
  288.                 case '?':
  289.                     usage();
  290.                     return 0;
  291.             }
  292.         }
  293.     }
  294.  
  295.     if(!iMode)
  296.     {
  297.         usage();
  298.         return 0;
  299.     }
  300.  
  301.     rc = init_pm();
  302.  
  303.     if(rc)
  304.         return -1;
  305.  
  306.     if(iMode & MODE_IN)
  307.     {
  308.         char *str = ReadPipe(0);
  309.  
  310.         if(str)
  311.             set_clip(str);
  312.  
  313.         delete str;
  314.     }
  315.  
  316.     if(iMode & MODE_OUT)
  317.     {
  318.         char *str = get_clip();
  319.  
  320.         if(str)
  321.         {
  322.             ULONG  ulWrote = 0;
  323.             rc = DosWrite(1, str, strlen(str), &ulWrote);
  324.         }
  325.     }
  326.  
  327.     done_pm();
  328.  
  329.     return rc;
  330. }
  331.  
  332.