home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / ddjmag / ddj9103.zip / C_PROGRM.ASC < prev    next >
Text File  |  1991-02-15  |  19KB  |  798 lines

  1. _C PROGRAMMING COLUMN_
  2. by Al Stevens
  3.  
  4. [LISTING ONE]
  5.  
  6. /* ----------- keys.h ------------ */
  7.  
  8. #define TRUE  1
  9. #define FALSE 0
  10.  
  11. #define ESC      27
  12. #define F2      188
  13. #define UP      200
  14. #define FWD     205
  15. #define DN      208
  16. #define BS      203
  17.  
  18. int getkey(void);
  19. int keyhit(void);
  20. void curr_cursor(int *, int *);
  21. void cursor(int, int);
  22. void hidecursor(void);
  23. void unhidecursor(void);
  24. void savecursor(void);
  25. void restorecursor(void);
  26. void set_cursor_type(unsigned);
  27. #define normalcursor() set_cursor_type(0x0607)
  28.  
  29.  
  30. [LISTING TWO]
  31.  
  32. /* ----------- getkey.c ---------- */
  33.  
  34. #include <bios.h>
  35. #include <dos.h>
  36. #include "keys.h"
  37.  
  38. #define KEYBOARD 0x16
  39. #define ZEROFLAG 0x40
  40. #define SETCURSORTYPE 1
  41. #define SETCURSOR     2
  42. #define READCURSOR    3
  43. #define HIDECURSOR 0x20
  44.  
  45. static unsigned video_mode;
  46. static unsigned video_page;
  47. static int cursorpos;
  48. static int cursorshape;
  49.  
  50. /* ---- Test for keystroke ---- */
  51. int keyhit(void)
  52. {
  53.     _AH = 1;
  54.     geninterrupt(KEYBOARD);
  55.     return (_FLAGS & ZEROFLAG) == 0;
  56. }
  57.  
  58. /* ---- Read a keystroke ---- */
  59. int getkey(void)
  60. {
  61.     int c;
  62.     while (keyhit() == 0)
  63.         ;
  64.     if (((c = bioskey(0)) & 0xff) == 0)
  65.         c = (c >> 8) | 0x80;
  66.     else
  67.         c &= 0xff;
  68.     return c;
  69. }
  70.  
  71. static void videoint(void)
  72. {
  73.     static unsigned oldbp;
  74.     _DI = _DI;
  75.     oldbp = _BP;
  76.     geninterrupt(0x10);
  77.     _BP = oldbp;
  78. }
  79.  
  80. void videomode(void)
  81. {
  82.     _AH = 15;
  83.     videoint();
  84.     video_mode = _AL;
  85.     video_page = _BX;
  86.     video_page &= 0xff00;
  87.     video_mode &= 0x7f;
  88. }
  89.  
  90. /* ---- Position the cursor ---- */
  91. void cursor(int x, int y)
  92. {
  93.     videomode();
  94.     _DX = ((y << 8) & 0xff00) + x;
  95.     _AX = 0x0200;
  96.     _BX = video_page;
  97.     videoint();
  98. }
  99.  
  100. /* ---- get cursor shape and position ---- */
  101. static void near getcursor(void)
  102. {
  103.     videomode();
  104.     _AH = READCURSOR;
  105.     _BX = video_page;
  106.     videoint();
  107. }
  108.  
  109. /* ---- Get current cursor position ---- */
  110. void curr_cursor(int *x, int *y)
  111. {
  112.     getcursor();
  113.     *x = _DL;
  114.     *y = _DH;
  115. }
  116.  
  117. /* ---- Hide the cursor ---- */
  118. void hidecursor(void)
  119. {
  120.     getcursor();
  121.     _CH |= HIDECURSOR;
  122.     _AH = SETCURSORTYPE;
  123.     videoint();
  124. }
  125.  
  126. /* ---- Unhide the cursor ---- */
  127. void unhidecursor(void)
  128. {
  129.     getcursor();
  130.     _CH &= ~HIDECURSOR;
  131.     _AH = SETCURSORTYPE;
  132.     videoint();
  133. }
  134.  
  135. /* ---- Save the current cursor configuration ---- */
  136. void savecursor(void)
  137. {
  138.     getcursor();
  139.     cursorshape = _CX;
  140.     cursorpos = _DX;
  141. }
  142.  
  143. /* ---- Restore the saved cursor configuration ---- */
  144. void restorecursor(void)
  145. {
  146.     videomode();
  147.     _DX = cursorpos;
  148.     _AH = SETCURSOR;
  149.      _BX = video_page;
  150.     videoint();
  151.     set_cursor_type(cursorshape);
  152. }
  153.  
  154. /* ----------- set the cursor type -------------- */
  155. void set_cursor_type(unsigned t)
  156. {
  157.     videomode();
  158.     _AH = SETCURSORTYPE;
  159.      _BX = video_page;
  160.     _CX = t;
  161.     videoint();
  162. }
  163.  
  164.  
  165. [LISTING THREE]
  166.  
  167. /* ------------- mouse.h ------------- */
  168.  
  169. #ifndef MOUSE_H
  170. #define MOUSE_H
  171.  
  172. #define MOUSE 0x33
  173.  
  174. int mouse_installed(void);
  175. int mousebuttons(void);
  176. void get_mouseposition(int *x, int *y);
  177. void set_mouseposition(int x, int y);
  178. void show_mousecursor(void);
  179. void hide_mousecursor(void);
  180. int button_releases(void);
  181. void intercept_mouse(void);
  182. void restore_mouse(void);
  183. void resetmouse(void);
  184.  
  185. #define leftbutton() (mousebuttons()&1)
  186. #define rightbutton() (mousebuttons()&2)
  187. #define waitformouse() while(mousebuttons());
  188.  
  189. #endif
  190.  
  191.  
  192.  
  193. [LISTING FOUR]
  194.  
  195. /* ------------- mouse.c ------------- */
  196.  
  197. #include <stdio.h>
  198. #include <dos.h>
  199. #include <stdlib.h>
  200. #include <string.h>
  201. #include "mouse.h"
  202.  
  203. static void mouse(int m1,int m2,int m3,int m4)
  204. {
  205.     _DX = m4;
  206.     _CX = m3;
  207.     _BX = m2;
  208.     _AX = m1;
  209.     geninterrupt(MOUSE);
  210. }
  211.  
  212. /* ---------- reset the mouse ---------- */
  213. void reset_mouse(void)
  214. {
  215.     mouse(0,0,0,0);
  216. }
  217.  
  218. /* ----- test to see if the mouse driver is installed ----- */
  219. int mouse_installed(void)
  220. {
  221.     unsigned char far *ms;
  222.     ms = MK_FP(peek(0, MOUSE*4+2), peek(0, MOUSE*4));
  223.     return (ms != NULL && *ms != 0xcf);
  224. }
  225.  
  226. /* ------ return true if mouse buttons are pressed ------- */
  227. int mousebuttons(void)
  228. {
  229.     int bx = 0;
  230.     if (mouse_installed())    {
  231.         mouse(3,0,0,0);
  232.         bx = _BX;
  233.     }
  234.     return bx & 3;
  235. }
  236.  
  237. /* ---------- return mouse coordinates ---------- */
  238. void get_mouseposition(int *x, int *y)
  239. {
  240.     if (mouse_installed())    {
  241.         int mx, my;
  242.         mouse(3,0,0,0);
  243.         mx = _CX;
  244.         my = _DX;
  245.         *x = mx/8;
  246.         *y = my/8;
  247.     }
  248. }
  249.  
  250. /* -------- position the mouse cursor -------- */
  251. void set_mouseposition(int x, int y)
  252. {
  253.     if(mouse_installed())
  254.         mouse(4,0,x*8,y*8);
  255. }
  256.  
  257. /* --------- display the mouse cursor -------- */
  258. void show_mousecursor(void)
  259. {
  260.     if(mouse_installed())
  261.         mouse(1,0,0,0);
  262. }
  263.  
  264. /* --------- hide the mouse cursor ------- */
  265. void hide_mousecursor(void)
  266. {
  267.     if(mouse_installed())
  268.         mouse(2,0,0,0);
  269. }
  270.  
  271. /* --- return true if a mouse button has been released --- */
  272. int button_releases(void)
  273. {
  274.     int ct = 0;
  275.     if(mouse_installed())    {
  276.         mouse(6,0,0,0);
  277.         ct = _BX;
  278.     }
  279.     return ct;
  280. }
  281.  
  282. static int mx, my;
  283.  
  284. /* ----- intercept the mouse in case an interrupted program is using it ---- */
  285. void intercept_mouse(void)
  286. {
  287.     if (mouse_installed())    {
  288.         _AX = 3;
  289.         geninterrupt(MOUSE);
  290.         mx = _CX;
  291.         my = _DX;
  292.         _AX = 31;
  293.         geninterrupt(MOUSE);
  294.     }
  295. }
  296.  
  297. /* ----- restore the mouse to the interrupted program ----- */
  298. void restore_mouse(void)
  299. {
  300.     if (mouse_installed())    {
  301.         _AX = 32;
  302.         geninterrupt(MOUSE);
  303.         _CX = mx;
  304.         _DX = my;
  305.         _AX = 4;
  306.         geninterrupt(MOUSE);
  307.     }
  308. }
  309.  
  310.  
  311.  
  312. [LISTING FIVE]
  313.  
  314. /* ----------- message.h ------------ */
  315.  
  316. #ifndef MESSAGES_H
  317. #define MESSGAES_H
  318.  
  319. #define MAXMESSAGES 50
  320.  
  321. /* --------- event message codes ----------- */
  322. enum messages {
  323.     START,
  324.     STOP,
  325.     KEYBOARD,
  326.     RIGHT_BUTTON,
  327.     LEFT_BUTTON,
  328.     MOUSE_MOVED,
  329.     BUTTON_RELEASED,
  330.     CURRENT_MOUSE_CURSOR,
  331.     MOUSE_CURSOR,
  332.     SHOW_MOUSE,
  333.     HIDE_MOUSE,
  334.     KEYBOARD_CURSOR,
  335.     CURRENT_KEYBOARD_CURSOR,
  336.     VIDEO_CHAR,
  337.     PUT_VIDEORECT,
  338.     GET_VIDEORECT
  339. };
  340.  
  341. /* ------- defines a screen rectangle ------ */
  342. typedef struct {
  343.     int x, y, x1, y1;
  344. } RECT;
  345.  
  346. /* ------ integer type for message parameters ----- */
  347. typedef int PARAM;
  348.  
  349. void post_message(enum messages, PARAM, PARAM);
  350. int send_message(enum messages, PARAM, PARAM);
  351. int dispatch_message(int (*)(enum messages, PARAM, PARAM));
  352. RECT rect(int, int, int, int);
  353.  
  354. #endif
  355.  
  356.  
  357.  
  358. [LISTING SIX]
  359.  
  360. /* --------- message.c ---------- */
  361.  
  362. #include <stdio.h>
  363. #include <dos.h>
  364. #include <conio.h>
  365. #include "mouse.h"
  366. #include "keys.h"
  367. #include "message.h"
  368.  
  369. static int mouse_event(void);
  370.  
  371. static int px = -1, py = -1;
  372. static int mx, my;
  373. static int first_dispatch = TRUE;
  374.  
  375. static struct msgs {
  376.     enum messages msg;
  377.     PARAM p1;
  378.     PARAM p2;
  379. } msg_queue[MAXMESSAGES];
  380.  
  381. static int qonctr;
  382. static int qoffctr;
  383. static int (*mproc)(enum messages,int,int);
  384.  
  385. /* ----- post a message and parameters to msg queue ---- */
  386. void post_message(enum messages msg, PARAM p1, PARAM p2)
  387. {
  388.     msg_queue[qonctr].msg = msg;
  389.     msg_queue[qonctr].p1 = p1;
  390.     msg_queue[qonctr].p2 = p2;
  391.     if (++qonctr == MAXMESSAGES)
  392.         qonctr = 0;
  393. }
  394.  
  395. /* --------- clear the message queue --------- */
  396. static void clear_queue(void)
  397. {
  398.     px = py = -1;
  399.     mx = my = 0;
  400.     first_dispatch = TRUE;
  401.     qonctr = qoffctr = 0;
  402. }
  403.  
  404. /* ------ collect events into the message queue ------ */
  405. static int collect_messages(void)
  406. {
  407.     /* ---- collect any unqueued messages ---- */
  408.     enum messages event;
  409.     if (first_dispatch)    {
  410.         first_dispatch = FALSE;
  411.         reset_mouse();
  412.         show_mousecursor();
  413.         send_message(START,0,0);
  414.     }
  415.     if ((event = mouse_event()) != 0)
  416.         post_message(event, mx, my);
  417.     if (keyhit())
  418.         post_message(KEYBOARD, getkey(), 0);
  419.     return qoffctr != qonctr;
  420. }
  421.  
  422. int send_message(enum messages msg, PARAM p1, PARAM p2)
  423. {
  424.     int rtn = 0;
  425.     RECT rc;
  426.     if (mproc == NULL)
  427.         return -1;
  428.     if (mproc(msg, p1, p2))    {
  429.         switch (msg)    {
  430.             case STOP:
  431.                 hide_mousecursor();
  432.                 clear_queue();
  433.                 mproc = NULL;
  434.                 break;
  435.             /* -------- keyboard messages ------- */
  436.             case KEYBOARD_CURSOR:
  437.                 unhidecursor();
  438.                 cursor(p1, p2);
  439.                 break;
  440.             case CURRENT_KEYBOARD_CURSOR:
  441.                 curr_cursor((int*)p1,(int*)p2);
  442.                 break;
  443.             /* -------- mouse messages -------- */
  444.             case SHOW_MOUSE:
  445.                 show_mousecursor();
  446.                 break;
  447.             case HIDE_MOUSE:
  448.                 hide_mousecursor();
  449.                 break;
  450.             case MOUSE_CURSOR:
  451.                 set_mouseposition(p1, p2);
  452.                 break;
  453.             case CURRENT_MOUSE_CURSOR:
  454.                 get_mouseposition((int*)p1,(int*)p2);
  455.                 break;
  456.             /* ----------- video messages ----------- */
  457.             case VIDEO_CHAR:
  458.                 gettext(p1+1, p2+1, p1+1, p2+1, &rtn);
  459.                 rtn &= 255;
  460.                 break;
  461.             case PUT_VIDEORECT:
  462.                 rc = *(RECT *) p1;
  463.                 puttext(rc.x+1, rc.y+1, rc.x1+1, rc.y1+1,(char *) p2);
  464.                 break;
  465.             case GET_VIDEORECT:
  466.                 rc = *(RECT *) p1;
  467.                 gettext(rc.x+1, rc.y+1, rc.x1+1, rc.y1+1,(char *) p2);
  468.                 break;
  469.             default:
  470.                 break;
  471.         }
  472.     }
  473.     return rtn;
  474. }
  475.  
  476. /* ---- dispatch messages to the message proc function ---- */
  477. int dispatch_message(
  478.     int (*msgproc)(enum messages msg,PARAM p1,PARAM p2))
  479. {
  480.     mproc = msgproc;
  481.     /* ------ dequeue the next message ----- */
  482.     if (collect_messages())  {
  483.         struct msgs mq = msg_queue[qoffctr];
  484.         send_message(mq.msg, mq.p1, mq.p2);
  485.         if (++qoffctr == MAXMESSAGES)
  486.             qoffctr = 0;
  487.         if (mq.msg == STOP)
  488.                return FALSE;
  489.     }
  490.     return TRUE;
  491. }
  492.  
  493. /* ---------- gather and interpret mouse events -------- */
  494. static int mouse_event(void)
  495. {
  496.     get_mouseposition(&mx, &my);
  497.     if (mx != px || my != py)  {
  498.         px = mx;
  499.         py = my;
  500.         return MOUSE_MOVED;
  501.     }
  502.     if (button_releases())
  503.         return BUTTON_RELEASED;
  504.     if (rightbutton())
  505.         return RIGHT_BUTTON;
  506.     if (leftbutton())
  507.         return LEFT_BUTTON;
  508.     return 0;
  509. }
  510.  
  511. /* ----------- make a RECT from coordinates --------- */
  512. RECT rect(int x, int y, int x1, int y1)
  513. {
  514.     RECT rc;
  515.     rc.x = x;
  516.     rc.y = y;
  517.     rc.x1 = x1;
  518.     rc.y1 = y1;
  519.     return rc;
  520. }
  521.  
  522.  
  523.  
  524.  
  525. [LISTING SEVEN]
  526.  
  527. /* ---------------- copyscrn.c -------------- */
  528. #include <stdio.h>
  529. #include <stdlib.h>
  530. #include "keys.h"
  531. #include "message.h"
  532.  
  533. static int message_proc(enum messages, int, int);
  534. static void near highlight(RECT);
  535. static void writescreen(RECT);
  536. static void near setstart(int *, int, int);
  537. static void near forward(int);
  538. static void near backward(int);
  539. static void near upward(int);
  540. static void near downward(int);
  541. static void init_variables(void);
  542.  
  543. static int cursorx, cursory;    /* Cursor position       */
  544. static int mousex, mousey;      /* Mouse cursor position */
  545.  
  546. static RECT blk;
  547. static int kx = 0, ky = 0;
  548. static int px = -1, py = -1;
  549. static int mouse_marking = FALSE;
  550. static int keyboard_marking = FALSE;
  551. static int marked_block = FALSE;
  552. static FILE *fp;
  553.  
  554. #ifdef TSR
  555. #define main tsr_program
  556. #endif
  557.  
  558. /* ---------- enter here to run screen grabber --------- */
  559. void main(void)
  560. {
  561.     fp = fopen("grab.dat", "wt");
  562.     if (fp != NULL)    {
  563.         /* ----- event message dispatching loop ---- */
  564.         while(dispatch_message(message_proc))
  565.             ;
  566.         fclose(fp);
  567.     }
  568. }
  569.  
  570. /* --------- event-driven message processing function ------- */
  571. static int message_proc(
  572.     enum message message,   /* message */
  573.     int param1,             /* 1st parameter */
  574.     int param2)             /* 2nd parameter */
  575. {
  576.     int mx = param1;
  577.     int my = param2;
  578.     int key = param1;
  579.  
  580.     switch (message)    {
  581.       case START:
  582.       init_variables();
  583.       post_message(CURRENT_KEYBOARD_CURSOR,(PARAM) &cursorx, (PARAM) &cursory);
  584.       post_message(KEYBOARD_CURSOR, 0, 0);
  585.       post_message(CURRENT_MOUSE_CURSOR,(PARAM) &mousex, (PARAM) &mousey);
  586.       post_message(MOUSE_CURSOR, 0, 0);
  587.             break;
  588.       case KEYBOARD:
  589.       switch (key)    {
  590.                 case FWD:
  591.                     if (kx < 79)    {
  592.                         if (keyboard_marking)
  593.                             forward(1);
  594.                         kx++;
  595.                     }
  596.                     break;
  597.                 case BS:
  598.                     if (kx)    {
  599.                         if (keyboard_marking)
  600.                             backward(1);
  601.                         --kx;
  602.                     }
  603.                     break;
  604.                 case UP:
  605.                     if (ky)    {
  606.                         if (keyboard_marking)
  607.                             upward(1);
  608.                         --ky;
  609.                     }
  610.                     break;
  611.                 case DN:
  612.                     if (ky < 24)    {
  613.                         if (keyboard_marking)
  614.                             downward(1);
  615.                         ky++;
  616.                     }
  617.                     break;
  618.                 case F2:
  619.                     mouse_marking = FALSE;
  620.                     setstart(&keyboard_marking, kx, ky);
  621.                     break;
  622.                 case '\r':
  623.                     post_message(STOP, TRUE, 0);
  624.                     break;
  625.                 case ESC:
  626.                     post_message(STOP, FALSE, 0);
  627.                     break;
  628.       }
  629.       send_message(KEYBOARD_CURSOR, kx, ky);
  630.       break;
  631.       case LEFT_BUTTON:
  632.             if (!mouse_marking)    {
  633.                 px = mx;
  634.                 py = my;
  635.                 keyboard_marking = FALSE;
  636.                 setstart(&mouse_marking, mx, my);
  637.       }
  638.       break;
  639.       case MOUSE_MOVED:
  640.             if (mouse_marking)    {
  641.                 if (px < mx)
  642.                     forward(mx-px);
  643.                 if (mx < px)
  644.                     backward(px-mx);
  645.                 if (py < my)
  646.                     downward(my-py);
  647.                 if (my < py)
  648.                     upward(py-my);
  649.                 px = mx;
  650.                 py = my;
  651.       }
  652.       break;
  653.       case BUTTON_RELEASED:
  654.             mouse_marking = FALSE;
  655.             break;
  656.       case RIGHT_BUTTON:
  657.             post_message(STOP, TRUE, 0);
  658.             break;
  659.       case STOP:
  660.       if (marked_block)    {
  661.                 highlight(blk);
  662.                 if (param1)
  663.                     writescreen(rect(min(blk.x, blk.x1),min(blk.y, blk.y1),
  664.                                      max(blk.x, blk.x1),max(blk.y, blk.y1)));
  665.             }
  666.             send_message(MOUSE_CURSOR, mousex, mousey);
  667.             send_message(KEYBOARD_CURSOR, cursorx, cursory);
  668.             init_variables();
  669.             break;
  670.         default:
  671.             break;
  672.     }
  673.     return TRUE;
  674. }
  675.  
  676. /* ------- set the start of block marking ------- */
  677. static void near setstart(int *marking, int x, int y)
  678. {
  679.     if (marked_block)
  680.         highlight(blk);      /* turn off old block */
  681.  
  682.     marked_block = FALSE;
  683.     *marking ^= TRUE;
  684.     blk.x1 = blk.x = x;   /* set the corners of the new block */
  685.     blk.y1 = blk.y = y;
  686.     if (*marking)
  687.         highlight(blk);   /* turn on the new block */
  688. }
  689.  
  690. /* ----- move the block rectangle forward one position ----- */
  691. static void near forward(int n)
  692. {
  693.     marked_block = TRUE;
  694.     while (n-- > 0)    {
  695.         if (blk.x < blk.x1)
  696.             highlight(rect(blk.x,blk.y,blk.x,blk.y1));
  697.         else
  698.             highlight(rect(blk.x+1,blk.y,blk.x+1,blk.y1));
  699.         blk.x++;
  700.     }
  701. }
  702.  
  703. /* ---- move the block rectangle backward one position ----- */
  704. static void near backward(int n)
  705. {
  706.     marked_block = TRUE;
  707.     while (n-- > 0)    {
  708.         if (blk.x > blk.x1)
  709.             highlight(rect(blk.x,blk.y,blk.x,blk.y1));
  710.         else
  711.             highlight(rect(blk.x-1,blk.y,blk.x-1,blk.y1));
  712.         --blk.x;
  713.     }
  714. }
  715.  
  716. /* ----- move the block rectangle up one position ----- */
  717. static void near upward(int n)
  718. {
  719.     marked_block = TRUE;
  720.     while (n-- > 0)    {
  721.         if (blk.y > blk.y1)
  722.             highlight(rect(blk.x,blk.y,blk.x1,blk.y));
  723.         else
  724.             highlight(rect(blk.x,blk.y-1,blk.x1,blk.y-1));
  725.         --blk.y;
  726.     }
  727. }
  728.  
  729. /* ----- move the block rectangle down one position ----- */
  730. static void near downward(int n)
  731. {
  732.     marked_block = TRUE;
  733.     while (n-- > 0)    {
  734.         if (blk.y < blk.y1)
  735.             highlight(rect(blk.x,blk.y,blk.x1,blk.y));
  736.         else
  737.             highlight(rect(blk.x,blk.y+1,blk.x1,blk.y+1));
  738.         blk.y++;
  739.     }
  740. }
  741.  
  742. /* ------ write the rectangle to the file ------- */
  743. static void writescreen(RECT rc)
  744. {
  745.     int vx = rc.x;
  746.     int vy = rc.y;
  747.     while (vy != rc.y1+1)    {
  748.         if (vx == rc.x1+1)    {
  749.             fputc('\n', fp);
  750.             vx = rc.x;
  751.             vy++;
  752.         }
  753.         else    {
  754.             fputc(send_message(VIDEO_CHAR, vx, vy), fp);
  755.             vx++;
  756.         }
  757.     }
  758. }
  759.  
  760. /* ------- simple swap macro ------ */
  761. #define swap(a,b) {int s=a;a=b;b=s;}
  762.  
  763. /* -------- invert the video of a defined rectangle ------- */
  764. static void near highlight(RECT rc)
  765. {
  766.     int *bf, *bf1, bflen;
  767.     if (rc.x > rc.x1)
  768.         swap(rc.x,rc.x1);
  769.     if (rc.y > rc.y1)
  770.         swap(rc.y,rc.y1);
  771.     bflen = (rc.y1-rc.y+1) * (rc.x1-rc.x+1) * 2;
  772.     if ((bf = malloc(bflen)) != NULL)    {
  773.         send_message(HIDE_MOUSE, 0, 0);
  774.         send_message(GET_VIDEORECT, (PARAM) &rc, (PARAM) bf);
  775.         bf1 = bf;
  776.         bflen /= 2;
  777.         while (bflen--)
  778.             *bf1++ ^= 0x7700;
  779.         send_message(PUT_VIDEORECT, (PARAM) &rc, (PARAM) bf);
  780.         send_message(SHOW_MOUSE, 0, 0);
  781.         free(bf);
  782.     }
  783. }
  784.  
  785. /* ---- initialize global variables for later popup ---- */
  786. static void init_variables(void)
  787. {
  788.     mouse_marking = keyboard_marking = FALSE;
  789.     kx = ky = blk.x = blk.y = blk.x1 = blk.y1 = 0;
  790.     px = py = -1;
  791.     mouse_marking = FALSE;
  792.     keyboard_marking = FALSE;
  793.     marked_block = FALSE;
  794. }
  795.  
  796.  
  797.  
  798.