home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_06 / 2n06059a < prev    next >
Text File  |  1991-05-01  |  14KB  |  605 lines

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <io.h>
  4. #include <stdlib.h>
  5. #include <graph.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include "StdWin.h"
  9.  
  10.  
  11. /* malloc statics */
  12. static WORD LocalEntries;
  13. static WORD LocalTotalSize=0;
  14. static WORD GlobalEntries;
  15. static WORD GlobalTotalSize=0;
  16. static VOID **LocalMemPtrs;
  17. static HANDLE *LocalMemHandles;
  18. static HANDLE *GlobalMemHandles;
  19. static VOID huge **GlobalMemPtrs;
  20.  
  21. BYTE TextBuffer[1024];
  22. #define TABSIZE 4
  23.  
  24. /* two states used by printf */
  25. static int AnsiTextState=TEXT,NewLineState=0;
  26.  
  27.  
  28. /* atexit function pointer */
  29. (_cdecl _FAR_ _LOADDS_ *ExitCallFunc)(void);
  30. int ExitCallInit = 0;
  31.  
  32. /********************************************************/
  33. /* malloc() & halloc() keep a list of all the allocated
  34.    pointers and handles so that they can later be freed */
  35. /********************************************************/
  36. void *malloc(size)
  37. size_t size;
  38. {
  39.  static HANDLE MemHandle,MemPtr;
  40.  static void *Ptr;
  41.  if(!LocalTotalSize)         /* not initialized */
  42.     {
  43.     MemHandle = LocalAlloc(LMEM_MOVEABLE,50);
  44.     if(!MemHandle) return(0);
  45.     MemPtr = LocalAlloc(LMEM_MOVEABLE,50);
  46.     if(!MemPtr) return(0);
  47.     LocalTotalSize = 25;
  48.     }
  49.  if(LocalEntries >= LocalTotalSize && LocalEntries != 0)
  50.     {
  51.     MemHandle = LocalReAlloc(MemHandle,100,LMEM_MOVEABLE);
  52.     if(!MemHandle) return(0);
  53.     MemPtr = LocalReAlloc(MemPtr,100,LMEM_MOVEABLE);
  54.     if(!MemPtr) return(0);
  55.     LocalTotalSize = 50;
  56.     }
  57.  LocalMemHandles = (HANDLE *)LocalLock(MemHandle);
  58.  *LocalMemPtrs = LocalLock(MemPtr);
  59.  if(!LocalMemHandles || !*LocalMemPtrs) return(0);
  60.  
  61.  if(!(LocalMemHandles[LocalEntries] =
  62.             LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,size)))
  63.         {
  64.         LocalCompact(0xffff);
  65.         if(!(LocalMemHandles[LocalEntries] =
  66.             LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,size)))
  67.             return(0);
  68.         }
  69.  if(!(Ptr = LocalLock(LocalMemHandles[LocalEntries])))
  70.         return(0);
  71.  LocalMemPtrs[LocalEntries] = Ptr;
  72.  LocalEntries++;
  73.  LocalUnlock(MemHandle);
  74.  LocalUnlock(MemPtr);
  75.  
  76.  return(Ptr);
  77. }
  78.  
  79. /***************************************
  80. function : halloc
  81. ***************************************/
  82.  
  83. void far *halloc(n,size)
  84. long n;
  85. size_t size;
  86. {
  87.  static VOID huge *Ptr;
  88.  static HANDLE MemHandle,MemPtr;
  89.  if(!GlobalTotalSize)         /* not initialized */
  90.     {
  91.     MemHandle = LocalAlloc(LMEM_MOVEABLE,50);
  92.     if(!MemHandle) return(0);
  93.     MemPtr = LocalAlloc(LMEM_MOVEABLE,50);
  94.     if(!MemPtr) return(0);
  95.     GlobalTotalSize = 25;
  96.     }
  97.  if(GlobalEntries >= GlobalTotalSize && GlobalEntries != 0)
  98.     {
  99.     MemHandle = LocalReAlloc(MemHandle,GlobalTotalSize+50,
  100.         LMEM_MOVEABLE);
  101.     if(!MemHandle) return(0);
  102.     MemPtr = LocalReAlloc(MemPtr,GlobalTotalSize + 50,
  103.         LMEM_MOVEABLE);
  104.     if(!MemPtr) return(0);
  105.     GlobalTotalSize += 25;
  106.     }
  107.  GlobalMemHandles = (HANDLE *)LocalLock(MemHandle);
  108.  *GlobalMemPtrs = LocalLock(MemPtr);
  109.  
  110.  if(!GlobalMemHandles || !*GlobalMemPtrs) return(0);
  111.  if(!(GlobalMemHandles[GlobalEntries] =
  112.             GlobalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,
  113.             (long)size*n)))
  114.         {
  115.         GlobalCompact(-1L);
  116.         if(!(GlobalMemHandles[GlobalEntries] =
  117.             GlobalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,
  118.             (long)size*n)))
  119.             return(0);
  120.         }
  121.  if(!(Ptr =
  122.     (VOID FAR *)GlobalLock(GlobalMemHandles[GlobalEntries])))
  123.         return(0);
  124.  GlobalMemPtrs[GlobalEntries] = Ptr;
  125.  
  126.  GlobalEntries++;
  127.  LocalUnlock(MemHandle);
  128.  LocalUnlock(MemPtr);
  129.  
  130.  return(Ptr);
  131. }
  132.  
  133. /***************************************
  134. function : free
  135. ***************************************/
  136.  
  137. void free(ptr)
  138. void *ptr;
  139. {
  140.  int i = 0;
  141.  while(i < LocalEntries)
  142.     {
  143.     if(LocalMemPtrs[i] == ptr)
  144.         {
  145.         LocalUnlock(LocalMemHandles[i]);
  146.         LocalFree(LocalMemHandles[i]);
  147.         return;
  148.         }
  149.     i++;
  150.     }
  151.  
  152. }
  153.  
  154. /***************************************
  155. function : hfree
  156. ***************************************/
  157.  
  158. void hfree(hugeptr)
  159. void huge *hugeptr;
  160. {
  161.  int i = 0;
  162.  while(i < GlobalEntries)
  163.     {
  164.     if(GlobalMemPtrs[i] == hugeptr)
  165.         {
  166.         GlobalUnlock(GlobalMemHandles[i]);
  167.         GlobalFree(GlobalMemHandles[i]);
  168.         return;
  169.         }
  170.     i++;
  171.     }
  172.  
  173. }
  174.  
  175.  
  176. /***************************************
  177. function : printf
  178. ***************************************/
  179.  
  180. int printf(str,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,
  181.     arg9,arg10,arg11,arg12,arg13,arg14,arg15,arg16,arg17,
  182.     arg18,arg19,arg20,arg21,arg22)
  183. const char _FAR_ *str;
  184. WORD arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,
  185.     arg11,arg12,arg13,arg14,arg15,arg16,arg17,arg18,arg19,
  186.     arg20,arg21,arg22;
  187. {
  188.  HDC hDC;
  189.  HANDLE hOldFont,hFont;
  190.  DWORD dwExtent;
  191.  int n,i,CharCount;
  192.  static BYTE number[8];
  193.  MSG msg;
  194.  /* 1 of 2 external message loops not found in
  195.                     WinMain(), another in getch*/
  196. Loop:
  197.  /* clear the message queue */
  198.  while(PeekMessage(&msg,NULL,0,0xFFFF,PM_REMOVE)){
  199.         TranslateMessage(&msg);
  200.         DispatchMessage(&msg);}
  201.  /* if the break key is pressed, hold for another key */
  202.  if(BreakSet) goto Loop;
  203.  
  204.  CharCount = sprintf(TextBuffer,str,arg1,arg2,arg3,arg4,
  205.     arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,
  206.     arg15,arg16,arg17,arg18,arg19,arg20,arg21,arg22);
  207.  /* see if output is redirected or piped */
  208.  if(hOutFile)
  209.     write(hOutFile,TextBuffer,CharCount);
  210.  if(Redirected) return(CharCount);
  211.  
  212.  hDC=GetDC(hStdWinWnd);
  213.  SetMyDC(hDC);
  214.  ptr = TextBuffer;
  215. while(*ptr)
  216.  {
  217.  /* set up the AnsiTextState to start with */
  218.  if((*ptr == 0x1b) && (*(ptr + 1) == '['))
  219.     AnsiTextState = ANSI;
  220.  else AnsiTextState = TEXT;
  221.  
  222.  switch(AnsiTextState){
  223.     case TEXT:
  224.         hFont = hFont1;         /* default font */
  225.     if(*ptr)
  226.         { int i;
  227.         BYTE buffer[120];
  228.         hOldFont = SelectObject(hDC, hFont);
  229.         CharCount = 0;
  230.         ptr2 = ptr;
  231.         while(*ptr2 == '\b')    /* process a backspace */
  232.             {memmove(ptr2,ptr2+1,strlen(ptr2));
  233.              if(DisplayCol){
  234.                 xCurrentPos -= ScreenBuffer[DisplayLine]
  235.                     [DisplayCol].xExtent;
  236.                 DisplayCol--;
  237.                 HideCaret(hStdWinWnd);
  238.                 TextOut(hDC,xCurrentPos,yCurrentPos," ",1);
  239.                 ShowCaret(hStdWinWnd);
  240.                 }
  241.             }
  242.         /* advance until a control character */
  243.         while(*ptr2)
  244.             {
  245.             if((*ptr2 == 0x1b) && (*(ptr2 + 1) == '['))
  246.                 break;
  247.             if((*ptr2 == 0x0d) || (*ptr2 == 0x0a))
  248.                 break;
  249.             else NewLineState = 0;
  250.             if(*ptr2 == '\b')
  251.                break;
  252.             if((DisplayCol + CharCount) >= MAXCOLUMNS)
  253.                 break;
  254.             CharCount++;
  255.             if(*ptr == '\t')    /* expand tab to spaces */
  256.                 {
  257.                 i = strlen(TextBuffer);
  258.                 memmove(ptr2 + TABSIZE-1,ptr2,
  259.                     i - (ptr2-TextBuffer)+1);
  260.                 i = TABSIZE;
  261.                 while(i--) *ptr2++ = ' ';
  262.                 CharCount += TABSIZE-1;
  263.                 }
  264.             ptr2++;
  265.             }
  266.  
  267.         if(DisplayLine >= MAXROWS)
  268.             yCurrentPos = Scrollup(hStdWinWnd,yCurrentPos);
  269.  
  270.         HideCaret(hStdWinWnd);
  271.         TextOut(hDC,xCurrentPos,yCurrentPos,ptr,CharCount);
  272.         xCurrentPos +=
  273.             LOWORD(GetTextExtent(hDC,ptr,CharCount));
  274.         SetCaretPos(xCurrentPos,yCurrentPos);
  275.         ShowCaret(hStdWinWnd);
  276.         /* copy the new characters to the screen buffer */
  277.         for(i = DisplayCol;i < DisplayCol + CharCount;i++)
  278.             { ScreenBuffer[DisplayLine][i].Char = *ptr;
  279.               ScreenBuffer[DisplayLine][i].xExtent =
  280.                     LOWORD(GetTextExtent(hDC,ptr++,1));
  281.               ScreenBuffer[DisplayLine][i].Color =
  282.                 rgbTextColor;
  283.               ScreenBuffer[DisplayLine][i].hFont = hFont;
  284.               if(i < MAXCOLUMNS){
  285.               ScreenBuffer[DisplayLine][i+1].Char = 0;
  286.               ScreenBuffer[DisplayLine][i+1].Color = 0L;
  287.               ScreenBuffer[DisplayLine][i+1].hFont = 0;
  288.               }
  289.             }
  290.         DisplayCol += CharCount;
  291.  
  292.         if((DisplayCol >= MAXCOLUMNS) && !iscntrl(*ptr2)){
  293.             /* force a newline for a wrap */
  294.             NewLineState = 1;
  295.             DisplayCol = 0;
  296.             if(hOutFile) write(hOutFile,"\r",1);
  297.             xCurrentPos = 0;
  298.             }
  299.         if(*ptr2 == 0x0d){
  300.             DisplayCol = 0;
  301.             if(hOutFile) write(hOutFile,"\r",1);
  302.             xCurrentPos = 0;
  303.             if(!NewLineState) ptr2++;
  304.             NewLineState = 1;}
  305.  
  306.         if((*ptr2 == 0x0a) || NewLineState)
  307.             {
  308.             DisplayLine++;
  309.             if(!NewLineState)
  310.                 {
  311.                 DisplayCol = 0;
  312.                 if(hOutFile) write(hOutFile,"\r",1);
  313.                 xCurrentPos = 0;
  314.                 }
  315.             if(*ptr2 == 0x0a) ptr2++;
  316.             NewLineState = 0;
  317.             dwExtent = GetTextExtent(hDC,"A",1);
  318.             yCurrentPos += LineExtents[DisplayLine] =
  319.                 HIWORD(dwExtent);
  320.  
  321.             HideCaret(hStdWinWnd);
  322.             SetCaretPos(xCurrentPos,yCurrentPos);
  323.             ShowCaret(hStdWinWnd);
  324.             }
  325.         SelectObject(hDC, hOldFont);
  326.  
  327.         ptr = ptr2;
  328.         }
  329.     break;
  330.     /* process an ANSI.SYS command */
  331.     case ANSI:
  332.  
  333.         ptr += 2;
  334.         ptr2 = number;
  335.         while(isdigit(*ptr)) {*ptr2++= *ptr++;}
  336.         *ptr2 = 0;
  337.         n = atoi(number);
  338.         switch(*ptr++) {
  339.             case ';':       /* cursor position */
  340.                 ptr2 = number;
  341.                 while(isdigit(*ptr)) {*ptr2++= *ptr++;}
  342.                     *ptr2 = 0;
  343.                 i = atoi(number);
  344.                 if((*ptr != 'H') && (*ptr != 'F'))
  345.                     {ptr -= 3; *ptr2 = 0x1b;break;}
  346.                 ptr++;
  347.                 _settextposition(n-1,i-1);
  348.                 break;
  349.  
  350.             case 'J':       /* clear the screen */
  351.                 _clearscreen(0);
  352.                 break;
  353.  
  354.             case 'm':       /* bold on/off */
  355.                 switch(n){
  356.                     case 1:
  357.                         SelectObject(hDC,hBoldFont);
  358.                         break;
  359.                     case 2:
  360.                         SelectObject(hDC,hFont1);
  361.                         break;
  362.                     }
  363.                 break;
  364.             case 'o':       /* red */
  365.                 rgbTextColor = RGB(255,0,0);
  366.                 SetTextColor(hDC,rgbTextColor);
  367.                 break;
  368.             case 'p':       /* green */
  369.                 rgbTextColor = RGB(0,255,0);
  370.                 SetTextColor(hDC,rgbTextColor);
  371.                 break;
  372.             case 'q':       /* blue */
  373.                 rgbTextColor = RGB(0,0,255);
  374.                 SetTextColor(hDC,rgbTextColor);
  375.                 break;
  376.             default:
  377.                 break;
  378.             }/* switch(ANSI control code) */
  379.          }/* switch(AnsiTextState)*/
  380.  
  381.     }/* while(ptr)*/
  382.  
  383.  
  384.     ReleaseDC(hStdWinWnd, hDC);
  385.     return(strlen(TextBuffer));
  386. }
  387.  
  388. /***************************************
  389. function : Scrollup
  390.  
  391. This function is a support function for
  392. printf, it should not be called directly
  393. ***************************************/
  394.  
  395. WORD Scrollup(hWnd,LinePos)
  396. HWND hWnd;
  397. WORD LinePos;
  398. {
  399.   WORD i,n,x=0,lines;
  400.  
  401.   /* find the number of lines at the top to match one
  402.     line at the bottom */
  403.   for(lines=0;lines < DisplayLine;lines++)
  404.     {
  405.     /* add up the number of pixels to scroll */
  406.     x+=LineExtents[lines];
  407.     if(x >= LineExtents[DisplayLine]) break;
  408.     }
  409.   lines++;
  410.   ScrollWindow(hWnd,0,-x ,  NULL, NULL);
  411.   DisplayLine -= lines;
  412.   /* copy the screen information up one line */
  413.   for(i=lines;i<= DisplayLine;i++)
  414.     {
  415.     for(n = 0;n < MAXCOLUMNS;n++)
  416.         {ScreenBuffer[i-lines][n] = ScreenBuffer[i][n];}
  417.     LineExtents[i-lines] = LineExtents[i];
  418.     }
  419.   return(LinePos - x);
  420. }
  421.  
  422.  
  423.  
  424. /***************************************
  425. function : getche
  426. ***************************************/
  427.  
  428. int getche(void)
  429. {
  430.  int c;
  431.  c = getch();
  432.  printf("%c",c);
  433.  return(c);
  434. }
  435.  
  436. /***************************************
  437. function : getch
  438. ***************************************/
  439.  
  440. int getch(void)
  441. {
  442.     MSG msg;
  443.     int c;
  444.  
  445.     while (GetMessage(&msg, NULL, NULL, NULL)) {
  446.         TranslateMessage(&msg);
  447.         DispatchMessage(&msg);
  448.         if(KeyHead != KeyTail)
  449.             {
  450.             c = KeyBuffer[KeyTail];
  451.             KeyTail = ++KeyTail & KeyMask;
  452.             return(c);
  453.             }
  454.  
  455.     }
  456.     return(-3);
  457. }
  458.  
  459. /***************************************
  460. function : gets
  461. ***************************************/
  462.  
  463. char *gets(buffer)
  464. char *buffer;
  465. {
  466.  int i = 0,c;
  467.  while((c = getche()) != '\r') buffer[i++] = c;
  468.  buffer[i] = 0;
  469.  return(buffer);
  470. }
  471.  
  472. /***************************************
  473. function : _outtext
  474. ***************************************/
  475.  
  476. void far _outtext(string)
  477. const unsigned char far *string;
  478. {
  479.  while(*string)
  480.     printf("%c",*string++);
  481. }
  482.  
  483. /***************************************
  484. function : puts
  485. ***************************************/
  486.  
  487. int puts(string)
  488. const char *string;
  489. {
  490.  while(*string)
  491.     printf("%c",*string++);
  492.  printf("\n");
  493.  return(1);
  494. }
  495.  
  496. /***************************************
  497. function : _clearscreen
  498. ***************************************/
  499.  
  500. void far _clearscreen(area)
  501. short area;
  502. {
  503.  int i,n;
  504.  HideCaret(hStdWinWnd);
  505.  InvalidateRect(hStdWinWnd,NULL,TRUE);
  506.  DisplayCol = DisplayLine = xCurrentPos = yCurrentPos = 0;
  507.  SetCaretPos(xCurrentPos,yCurrentPos);
  508.  ShowCaret(hStdWinWnd);
  509.  for(i = 0;i < MAXROWS;i++)
  510.     {
  511.      for(n=0;n< MAXCOLUMNS ;n++)
  512.         {ScreenBuffer[i][n].Char = 0;
  513.          ScreenBuffer[i][n].Color = rgbTextColor;
  514.          }
  515.  
  516.     }
  517. }
  518.  
  519. /***************************************
  520. function : _settextposition
  521. ***************************************/
  522.  
  523. struct rccoord far _settextposition(row,column)
  524. short row;
  525. short column;
  526. {
  527.  static struct rccoord pos;
  528.  pos.row = DisplayLine;
  529.  pos.col = DisplayCol;
  530.  DisplayCol = DisplayLine = yCurrentPos = xCurrentPos = 0;
  531.  HideCaret(hStdWinWnd);
  532.  while(DisplayLine < row)
  533.     yCurrentPos += LineExtents[DisplayLine++];
  534.  while(DisplayCol < column)
  535.     {xCurrentPos +=
  536.         ScreenBuffer[DisplayLine][DisplayCol].xExtent;
  537.      DisplayCol++;}
  538.  SetCaretPos(xCurrentPos,yCurrentPos);
  539.  ShowCaret(hStdWinWnd);
  540.  
  541.  return(pos);
  542. }
  543.  
  544.  
  545. /*  dos color pallet table
  546.    0           Black      8           Dark gray
  547.    1           Blue       9           Light blue
  548.    2           Green      10          Light green
  549.    3           Cyan       11          Light cyan
  550.    4           Red        12          Light red
  551.    5           Magenta    13          Light magenta
  552.    6           Brown      14          Yellow
  553.    7           White      15          Bright white
  554. */
  555. COLORREF ColorTable[16] = {
  556.     BLACK,DARK_GRAY,BLUE,LIGHT_BLUE,GREEN,
  557.     LIGHT_GREEN,CYAN,LIGHT_CYAN,RED,LIGHT_RED,
  558.     MAGENTA,LIGHT_MAGENTA,BROWN,YELLOW,WHITE,BRIGHT_WHITE};
  559.  
  560. /***************************************
  561. function : _settextcolor
  562. ***************************************/
  563.  
  564. short far _settextcolor(color)
  565. short color;
  566. {
  567.  int i;
  568.  long oldcolor = (long)rgbTextColor;
  569.  color &= 0xf;
  570.  rgbTextColor = ColorTable[color];
  571.  for(i=0;i<16;i++){
  572.     if(oldcolor = ColorTable[i]) break;
  573.     }
  574.  return(i);
  575. }
  576.  
  577. /***************************************
  578. function : _setbkcolor
  579. ***************************************/
  580.  
  581. long far _setbkcolor(color)
  582. long color;
  583. {
  584.  int i;
  585.  long oldcolor = rgbBkColor;
  586.  rgbBkColor = ColorTable[color];
  587.  for(i=0;i<16;i++){
  588.     if(oldcolor = ColorTable[i]) break;
  589.     }
  590.  return (i);
  591. }
  592.  
  593. /***************************************
  594. function : atexit
  595. ***************************************/
  596.  
  597. int atexit(ExitFunc)
  598. void (*ExitFunc)(void);
  599. {
  600.   ExitCallFunc = ExitFunc;
  601.   ExitCallInit = 1;
  602.   return(1);
  603. }
  604.  
  605.