home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ehp14cs.zip / mouse.c < prev    next >
Text File  |  1995-05-10  |  48KB  |  1,316 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  mouse.c                                         */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*       - Fenster ermitteln, in dem Position liegt (pos_to_win)*/
  7. /*       - Zum Fenster wechseln, in dem Position liegt (sw_pos) */
  8. /*       - Liegt Position innerhalb von akt_winp? (in_akt_win)  */
  9. /*       - Mauscursor verstecken und wieder zeigen (hide_show)  */
  10. /*       - Maus-Status lesen (get_mouse)                        */
  11. /*       - Fenster mit Maus bewegen (mouse_movewin)             */
  12. /*       - Fenstergröße mit Maus ändern (mouse_sizewin)         */
  13. /*       - Bildschirm gemäß Mausposition scrollen (check_scroll)*/
  14. /*       - Cursor setzen oder Block (set_cursor_or_mark_block)  */
  15. /*       - Mausposition in Schaltfäache wandeln (pos_to_button) */
  16. /*       - Fenster mit Maus schließen (mouse_win_zu)            */
  17. /*       - Mit Maus nach rechts scrollen (msr)                  */
  18. /*       - Mit Maus nach links scrollen (msl)                   */
  19. /*       - Mit Maus nach oben scrollen (msu)                    */
  20. /*       - Mit Maus nach unten scrollen (msd)                   */
  21. /*       - Maus-Routine (mouse_routine)                         */
  22. /*       - Mouse-Interrupt aktivieren/sperren (set_mouse_int)   */
  23. /*       - Maus initialisieren (init_mouse)                     */
  24. /*                                                              */
  25. /****************************************************************/
  26.  
  27. #ifdef OS2
  28.  
  29. #define INCL_DOSPROCESS
  30. #define INCL_DOSSEMAPHORES
  31. #include <os2.h>
  32. #include <stdlib.h>
  33.  
  34. extern HMTX sem_handle; /* Handle für Semaphor */
  35.  
  36. struct MPTRPOS          /* Kann die Position des Mauszeigers aufnehmen */
  37. {
  38.   short int line,
  39.         col;
  40. };
  41.  
  42. #pragma pack(1)
  43. typedef struct MEVENT   /* Nimmt das Mouse-Event aus der Event-Queue auf */
  44. {
  45.   short int button_status; /* Bit 2 links, Bit 4 rechts */
  46.   int       time;
  47.   short int y,
  48.         x;
  49. } mouse_type;
  50. #pragma pack(4)
  51.  
  52. short int mouse_handle; /* Globale Variable enthält den Mouse-Handle */
  53. TID       mouse_ThreadID; /* Hier steht die ID des Mouse-Threads */
  54. char      mouse_active = FALSE;    /* Soll Mouse_Thread laufen ? */
  55.  
  56. #else
  57.  
  58. #pragma inline
  59. #include <dos.h>
  60. typedef struct mouse_struct
  61. {
  62.   int button_status,  /* Knopfstatus: Bit 0 links, Bit 1 rechts, Bit 2 Mitte */
  63.       x,              /* X-Position (0..COLS-1) */
  64.       y;              /* Y-Position (0..LINES-1) */
  65. } mouse_type;
  66.  
  67.  
  68. #endif
  69.  
  70. #include "defs.h"
  71.  
  72. extern (*funktion[])(),
  73.        do_win_zu();
  74. extern short int mc_index;
  75. extern comm_typ *comm_feld;
  76. extern char highblockflag;
  77.  
  78. /******************************************************************************
  79. 
  80.  Funktion     : Fenster ermitteln, in dem Position liegt (pos_to_win)
  81.  --------------
  82. 
  83.  Parameter    : x           :
  84.                   Typ          : int
  85.                   Wertebereich : 0-COLS
  86.                   Bedeutung    : X-Achse der Position
  87. 
  88.                 y           :
  89.                   Typ          : int
  90.                   Wertebereich : 0-LINES
  91.                   Bedeutung    : Y-Achse der Position
  92. 
  93.  Ergebnis     :
  94. *                  Typ          : win_typ *
  95. *                  Wertebereich : Pointer auf Fensterstruktur
  96. *                  Bedeutung    : Zeigt auf das sichtbare Fenster, in dem die
  97. *                                 angegebene Position liegt
  98. *
  99. * Beschreibung : Es werden in der Reihenfolge. in der sie beim Refresh
  100. *                gezeichnet würden, alle Fenster durchgegangen und der Zeiger
  101. *                auf das Fenster gemerkt, falls die angegebene Position in
  102. *                dem getesteten Fenster liegt. So erhält man das Fenster,
  103. *                in dem die übergebene Position liegt.
  104. *
  105. ******************************************************************************/
  106.  
  107. win_typ *pos_to_win(x,y)
  108. int x,y;
  109. {
  110.   win_typ *w,          /* Pointer zum Durchlaufen der Fensterliste */
  111.       *res = NULL; /* Pointe auf Fenster, in dem Position liegt */
  112.  
  113.   for(w=akt_winp->next->next; w != akt_winp->next; w=w->next)
  114.     /* Alle Fenster durchlaufen */
  115.     if(x >= w->x && x <= w->x + w->dx + 1
  116.     && y >= w->y && y <= w->y + w->dy + 1)
  117.       res = w;  /* Position liegt im Fenster, Fenster merken */
  118.   return(res);
  119. }
  120.  
  121. /******************************************************************************
  122. *
  123. * Funktion     : Zum Fenster wechseln, in dem Position liegt (sw_pos)
  124. * --------------
  125. *
  126. * Parameter    : x           :
  127. *                  Typ          : int
  128. *                  Wertebereich : 0-COLS
  129. *                  Bedeutung    : X-Achse der Position
  130. *
  131. *                y           :
  132. *                  Typ          : int
  133. *                  Wertebereich : 0-LINES
  134. *                  Bedeutung    : Y-Achse der Position
  135. *
  136. * Ergebnis     :
  137. *                  Typ          : int
  138. *                  Wertebereich : TRUE, FALSE
  139. *                  Bedeutung    : TRUE: Fenster gefunden, FALSE: nicht gefunden
  140. *
  141. * Beschreibung : Mittels der Funktion pos_to_win wird das Fenster ermittelt,
  142. *                in dem die Position liegt. Wird ein solches Fenster gefunden,
  143. *                so wird es zum aktuellen gemacht und TRUE geliefert, ansonsten
  144. *                wird FALSE geliefert.
  145. *
  146. ******************************************************************************/
  147.  
  148. int sw_pos(x,y)
  149. int x,y;
  150. {
  151.   win_typ *w, /* Zeiger auf zu aktivierendes Fenster */
  152.       *dummy;
  153.  
  154.   if(w = pos_to_win(x,y))  /* Liegt die Position in einem sichtbaren Fenster ? */
  155.   {
  156.     if(w != akt_winp)
  157.     {
  158.       dummy = akt_winp->next;   /* Dann gefundenes Fenster zum aktuellen */
  159.       akt_winp->next = w;       /* machen, indem man es vor dummy in     */
  160.       w->prev->next = w->next;  /* die Fensterliste einhaengt.           */
  161.       w->next->prev = w->prev;
  162.       w->prev = akt_winp;
  163.       w->next = dummy;
  164.       dummy->prev = w;
  165.       akt_winp = w;
  166.     }
  167.     return(TRUE);
  168.   }
  169.   return(FALSE); /* Position lag nicht in einem Fenster */
  170. }
  171.  
  172. /******************************************************************************
  173. *
  174. * Funktion     : Liegt Position innerhalb von akt_winp? (in_akt_win)
  175. * --------------
  176. *
  177. * Parameter    : x           :
  178. *                  Typ          : int
  179. *                  Wertebereich : 0-MAXINT
  180. *                  Bedeutung    : X-Position, die zu testen ist
  181. *
  182. *                y           :
  183. *                  Typ          : int
  184. *                  Wertebereich : 0-MAXINT
  185. *                  Bedeutung    : Y-Position, die zu testen ist
  186. *
  187. * Ergebnis     :
  188. *                  Typ          : int
  189. *                  Wertebereich : TRUE, FALSE
  190. *                  Bedeutung    : TRUE: Position liegt im aktuellen Fenster
  191. *                                 FALSE: Position liegt nicht im aktuellen
  192. *                                        Fenster
  193. *
  194. * Beschreibung : Die übergebenen Koordinaten werden mit den Koordinaten
  195. *                des aktuellen Fensters verglichen. Liegen sie innerhalb,
  196. *                also in der Textfläche, so wird TRUE, sonst FALSE ge-
  197. *                liefert.
  198. *
  199. ******************************************************************************/
  200.  
  201. int in_akt_win(x,y)
  202. int x,y;
  203. {
  204.   return(x > akt_winp->x && x <= akt_winp->x+akt_winp->dx
  205.   && y > akt_winp->y && y <= akt_winp->y+akt_winp->dy);
  206. }
  207.  
  208. /******************************************************************************
  209. *
  210. * Funktion     : Mauscursor verstecken und wieder zeigen (hide_show)
  211. * --------------
  212. *
  213. * Parameter    : hs          :
  214. *                  Typ          : int
  215. *                  Wertebereich : MOUSE_SHOW, MOUSE_HIDE,
  216. *                  Bedeutung    : MOUSE_HIDE : Mauszeiger verstecken
  217. *                                 MOUSE_SHOW : Mauszeiger anzeigen
  218. *
  219. * Beschreibung : Der Mauscursor wird mit der Funktion 2 des Mausinterrupts
  220. *                versteckt, falls MOUSE_HIDE gesetzt war, und anschließend
  221. *                mit der Funktion 1 wieder dargestellt, falls MOUSE_SHOW
  222. *                gesetzt war. War der Mauscursor also vorher eingeschal-
  223. *                tet, so ist dann garantiert, daß er auch sichtbar ist.
  224. *                Das ist wichtig, falls nach einem Refresh der Mauscursor
  225. *                sichtbar sein soll.
  226. *
  227. ******************************************************************************/
  228.  
  229. void hide_show(hs)
  230. int hs;
  231. {
  232. #ifdef OS2
  233.   static struct MOUREMOVESTRUCT
  234.   {
  235.      short int startline,
  236.            startcol,
  237.            endline,
  238.            endcol;
  239.   } mrs;
  240.   static char need_init = TRUE;
  241.  
  242.   if (hs & MOUSE_HIDE)
  243.   {
  244.     if (need_init)
  245.     {
  246.       mrs.startline = mrs.startcol = 0;
  247.       mrs.endline   = LINES-1;
  248.       mrs.endcol    = COLS-1;
  249.       need_init     = FALSE;
  250.     }
  251.     MouRemovePtr (&mrs, mouse_handle);
  252.   }
  253.   if (hs & MOUSE_SHOW)
  254.     MouDrawPtr (mouse_handle);
  255. #else
  256.   union  REGS  regs;
  257.  
  258.   if(hs & MOUSE_HIDE)
  259.   {
  260.     regs.x.ax = 2;
  261.     int86(51,®s,®s);
  262.   }
  263.   if(hs & MOUSE_SHOW)
  264.   {
  265.     regs.x.ax = 1;
  266.     int86(51,®s,®s);
  267.   }
  268. #endif
  269. }
  270.  
  271. #ifndef OS2
  272. /*******************************************************************************
  273. 
  274. * Funktion     : Maus-Status lesen (get_mouse)
  275. * --------------
  276. *
  277. * Ergebnis     :
  278. *                  Typ          : *mouse_type
  279. *                  Wertebereich : Pointer auf Maus-Struktur
  280. *                  Bedeutung    : Zeigt auf Struktur, die die aktuellen
  281. *                                 Mausdaten enthält.
  282. *
  283. * Beschreibung : Mittels der Funktion 3 des Mausinterrupts wird der Mausstatus
  284. *                eingelesen.
  285. *
  286. ******************************************************************************/
  287.  
  288. mouse_type *get_mouse()
  289. {
  290.   static mouse_type m; /* zur Ablage des Maus-Status */
  291.   union  REGS  regs;
  292.  
  293.   regs.x.ax  = 3;
  294.   int86(51,®s,®s);
  295.   m.button_status = regs.x.bx;
  296.   m.x             = regs.x.cx / 8;
  297.   m.y             = regs.x.dx / 8;
  298.   return(&m);
  299. }
  300. #endif
  301.  
  302. /******************************************************************************
  303. *
  304. * Funktion     : Fenster mit Maus bewegen (mouse_movewin)
  305. * --------------
  306. *
  307. * Parameter    : m           :
  308. *                  Typ          : mouse_type *
  309. *                  Wertebereich : Pointer aus Mausstruktur
  310. *                  Bedeutung    : Mauszustand mit Position und Knopfdrücken
  311. *
  312. * Beschreibung : Das aktuelle Fenster wird durch die Maus verschoben.
  313. *                Die Mauskoordinaten werden solange geprüft, bis der
  314. *                linke Mausknopf nicht mehr gedrückt ist. Dann wird
  315. *                das Fenster in seiner dortigen Position gezeichnet.
  316. *
  317. ******************************************************************************/
  318.  
  319. void mouse_movewin(m)
  320. mouse_type *m;
  321. {
  322.   int old_x = m->x, /* Ablage für alte Mauskoordinaten */
  323.       old_y = m->y,
  324.       moved = FALSE;
  325. #ifdef OS2
  326.   short int wait = 1; /* Auf Mausereignisse warten */
  327. #endif
  328.  
  329.   /* Wenn rechter Mausknopf gedrückt wurde, dann Fenster in den Hintergrund
  330.      schieben. Bei linkem Mausknopf evtl. Fenster verschieben. */
  331.   if(m->button_status & MOUSE_BUT2) /* rechter Knopf ? */
  332.   {
  333.     hide_show(MOUSE_HIDE); /* Mauszeiger verstecken */
  334.     push_win_back(); /* Fenster zum hintersten machen */
  335.     do_refresh();
  336.     hide_show(MOUSE_SHOW); /* Mauszeiger wieder anzeigen */
  337.   }
  338.   else /* linker Mausknopf war gedrückt */
  339.   {
  340.     /* warten, bis entweder der Mausknopf losgelassen wird, oder */
  341.     /* die Maus bewegt wird. */
  342. #ifdef OS2
  343.     MouReadEventQue (m, &wait, mouse_handle);
  344.     while (m->button_status & (MOUSE_BUT1_MOVE | MOUSE_BUT1))
  345.     {  /* Maus wurde mit gedrücktem linken Knopf bewegt. */
  346. #else
  347.     while((m=get_mouse())->button_status & MOUSE_BUT1)
  348.     {
  349.       if(m->x != old_x || m->y != old_y)  /* Maus wurde mit gedrücktem Knopf */
  350.       {                                   /* bewegt. */
  351. #endif
  352.     hide_show(MOUSE_HIDE);
  353.     if(!moved)
  354.     {
  355.       moved = TRUE;
  356.       werase (akt_winp->winp);  /* Fensterinhalt auf Bildschirm loeschen */
  357.       wrefresh(akt_winp->winp); /* damit kein Fehler beim Verschieben passiert */
  358.       cpwins2stdscr(); /* Alle Fenster ausser akt. nach stdscr kopieren */
  359.     }
  360.     else
  361.       eckenhw();                 /* Ecken des Fensters demarkieren      */
  362.     if(m->x > old_x)
  363.       win_right(m->x - old_x);
  364.     else
  365.       win_left(old_x - m->x);
  366.     if(m->y > old_y)
  367.       win_down(m->y - old_y);
  368.     else
  369.       win_up(old_y - m->y);
  370.     old_x = m->x; /* Mauskoordinaten merken */
  371.     old_y = m->y;
  372.     eckenhw();                   /* Ecken markieren */
  373.     hide_show(MOUSE_SHOW);
  374. #ifdef OS2
  375.       MouReadEventQue (m, &wait, mouse_handle);
  376. #else
  377.       }
  378. #endif
  379.     }
  380.     if(moved)    /* Falls Fenster verschoben wurde, Ecken wieder löschen */
  381.     {            /* und Fenster neu zeichnen */
  382.       hide_show(MOUSE_HIDE);
  383.       eckenhw();
  384.       erase();
  385.       refresh();
  386.       mvwin (akt_winp->winp,akt_winp->y,akt_winp->x); /* Fenster verschieben */
  387.       do_refresh();                   /* Alle Fenster neu zeichnen           */
  388.       hide_show(MOUSE_SHOW);
  389.     }
  390.   }
  391. }
  392.  
  393. /******************************************************************************
  394. *
  395. * Funktion     : Fenstergröße mit Maus ändern (mouse_sizewin)
  396. * --------------
  397. *
  398. * Parameter    : m           :
  399. *                  Typ          : mouse_type *
  400. *                  Wertebereich : Pointer aus Mausstruktur
  401. *                  Bedeutung    : Mauszustand mit Position und Knopfdrücken
  402. *
  403. * Beschreibung : Das aktuelle Fenster wird durch die Maus vergrößert
  404. *                oder verkleinert.
  405. *                Die Mauskoordinaten werden solange geprüft, bis der
  406. *                linke Mausknopf nicht mehr gedrückt ist. Dann wird
  407. *                das Fenster in seiner dortigen Größe gezeichnet.
  408. *
  409. ******************************************************************************/
  410.  
  411. void mouse_sizewin(m)
  412. mouse_type *m;
  413. {
  414.   int old_x = m->x, /* Ablage für alte Mauskoordinaten */
  415.       old_y = m->y,
  416.       moved = FALSE;
  417. #ifdef OS2
  418.   short int wait = 1; /* auf Mausereignisse warten */
  419. #endif
  420.  
  421.   /* warten, bis entweder der Mausknopf losgelassen wird, oder */
  422.   /* die Maus bewegt wird. */
  423. #ifdef OS2
  424.   MouReadEventQue (m, &wait, mouse_handle);
  425.   while (m->button_status & (MOUSE_BUT1_MOVE | MOUSE_BUT2_MOVE
  426.                | MOUSE_BUT1 | MOUSE_BUT2))
  427.   {
  428. #else
  429.   while((m=get_mouse())->button_status & (MOUSE_BUT1 | MOUSE_BUT2))
  430.   {
  431.     if(m->x != old_x || m->y != old_y)  /* Maus wurde mit gedrücktem Knopf */
  432.     {                                   /* bewegt. */
  433. #endif
  434.       hide_show(MOUSE_HIDE);
  435.       if(!moved)
  436.       {
  437.     moved = TRUE;
  438.     werase (akt_winp->winp);  /* Fensterinhalt auf Bildschirm loeschen */
  439.     wrefresh(akt_winp->winp); /* damit kein Fehler beim Verschieben passiert */
  440.     cpwins2stdscr(); /* Alle Fenster ausser akt. nach stdscr kopieren */
  441.       }
  442.       else
  443.     eckenhw();                 /* Ecken des Fensters demarkieren      */
  444.       if(m->x > old_x)
  445.     size_right(m->x - old_x);
  446.       else
  447.     size_left(old_x - m->x);
  448.       if(m->y > old_y)
  449.     size_down(m->y - old_y);
  450.       else
  451.     size_up(old_y - m->y);
  452.       old_x = m->x; /* Mauskoordinaten merken */
  453.       old_y = m->y;
  454.       eckenhw();                   /* Ecken markieren */
  455.       hide_show(MOUSE_SHOW);
  456. #ifdef OS2
  457.     MouReadEventQue (m, &wait, mouse_handle);
  458. #else
  459.     }
  460. #endif
  461.   }
  462.   if(moved)    /* Falls Fenster verschoben wurde, Ecken wieder löschen */
  463.   {            /* und Fenster neu zeichnen */
  464.     hide_show(MOUSE_HIDE);
  465.     eckenhw();
  466.     erase();                  /* gedrueckt wurde (RETURN) */
  467.     refresh();                /* Fensterinhalt loeschen */
  468.     delwin(akt_winp->winp);   /* Fenster mit Curses loeschen und neu anlegen */
  469.     akt_winp->winp=newwin(akt_winp->dy+2,akt_winp->dx+2,akt_winp->y,akt_winp->x);
  470.     init_win();               /* Fensterattribute setzen (raw etc.) */
  471.  
  472.     /* Falls Cursor jetzt ausserhalb des Fensters steht, Cursorposition anpassen */
  473.     if (akt_winp->ws_line+akt_winp->dy <= akt_winp->textline)
  474.       gotox(akt_winp->ws_line+akt_winp->dy-1);
  475.     if (akt_winp->ws_col+akt_winp->dx <= akt_winp->screencol)
  476.       akt_winp->screencol = akt_winp->ws_col+akt_winp->dx-1;
  477.     do_refresh();  /* Alle Fenster neu zeichnen */
  478.     hide_show(MOUSE_SHOW);
  479.   }
  480. }
  481.  
  482. /******************************************************************************
  483. *
  484. * Funktion     : Bildschirm gemäß Mausposition scrollen (check_scroll)
  485. * --------------
  486. *
  487. * Parameter    : m           :
  488. *                  Typ          : mouse_type *
  489. *                  Wertebereich : Pointer auf Mausstruktur
  490. *                  Bedeutung    : Mausstatus
  491. *
  492. * Beschreibung : Die Mausposition liegt außerhalb des aktuellen Fensters.
  493. *                Der Fensterinhalt soll in Richtung des Mauscursors an-
  494. *                gepaßt werden. Steht also beispielsweise die Maus unter-
  495. *                halb des aktuellen Fensters, so soll der Text im Fenster
  496. *                nach oben geschoben werden (damit z.B. auch fensterüber-
  497. *                greifende Blöcke markiert werden können.
  498. *
  499. ******************************************************************************/
  500.  
  501. void check_scroll(m)
  502. mouse_type *m;
  503. {
  504.   /* Zuerst die Verschiebung nach oben/unten testen */
  505.   if(m->y < akt_winp->y+1
  506.   && akt_winp->ws_line) /* Verschiebung des Inhalts nach unten */
  507.   {
  508.     akt_winp->ws_line--; /* dann Nummer der ersten sichtbaren Zeile erhoehen */
  509.     text_down(0);        /* gesamten Fenstertext um 1 Zeile nach unten */
  510.     up();                /* Cursor um 1 Zeile nach oben bewegen */
  511.     setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  512.   }
  513.   else
  514.     if(m->y > akt_winp->y+akt_winp->dy /* Verschiebung der Inhalts nach */
  515.     && akt_winp->ws_line < akt_winp->maxline) /* oben */
  516.     {
  517.       akt_winp->ws_line++; /* dann Nummer der ersten sichtbaren Zeile erhoehen */
  518.       text_up(0);          /* gesamten Fenstertext um 1 Zeile nach oben */
  519.       down();              /* Cursor um 1 Zeile nach unten bewegen */
  520.       setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  521.     }
  522.  
  523.   /* Jetzt Verschiebung nach rechts/links testen */
  524.   if(m->x < akt_winp->x+1
  525.   && akt_winp->ws_col)  /* Verschiebung des Inhalts nach rechts */
  526.   {
  527.     text_right();
  528.     left();
  529.     setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  530.   }
  531.   else
  532.     if(m->x > akt_winp->x+akt_winp->dx
  533.     && akt_winp->ws_col < MAXLENGTH)
  534.     {
  535.       text_left();
  536.       right();
  537.       setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  538.     }
  539. }
  540.  
  541. /******************************************************************************
  542. *
  543. * Funktion     : Blockende setzen (mouse_blend)
  544. * --------------
  545. *
  546. * Parameter    : m           :
  547. *                  Typ          : mouse_type *
  548. *                  Wertebereich : Pointer auf Mausstruktur
  549. *                  Bedeutung    : Mauszustand
  550. *
  551. *              : old_x       :
  552. *                  Typ          : int
  553. *                  Wertebereich : 0-COLS
  554. *                  Bedeutung    : Alte Mausposition Spalte
  555. *
  556. *              : old_y       :
  557. *                  Typ          : int
  558. *                  Wertebereich : 0-LINES
  559. *                  Bedeutung    : Alte Mausposition Zeile
  560. *
  561. *              : bl_typ      :
  562. *                  Typ          : char
  563. *                  Wertebereich : BT_RECHTECK, BT_NORMAL
  564. *                  Bedeutung    : Blocktyp
  565. *
  566. *              : need_show_win:
  567. *                  Typ          : char
  568. *                  Wertebereich : TRUE, FALSE
  569. *                  Bedeutung    : Wenn TRUE, muß statt der Anzeige der Zeilen
  570. *                                 zwischen alter und neuer Mausposition
  571. *                                 ein show_win ausgeführt werden.
  572. *
  573. * Beschreibung : Die Maus wurde mit gedrücktem Mausknopf von der Position
  574. *                old_x/old_y nach der von m angegebenen Position verschoben.
  575. *                An der neuen Position muß also nun das Blockende gesetzt
  576. *                werden und der so entstandene neue Block gehighlighted
  577. *                werden, falls die Blockhervorhebung aktiviert ist.
  578. *                Dazu werden die Zeilen zwischen dem alten Blockende (old_y)
  579. *                und dem neuen Blockende (m->y) mittels lineout neu
  580. *                angezeigt.
  581. *
  582. ******************************************************************************/
  583.  
  584. void mouse_blend (mouse_type *m, int old_x, int old_y,
  585.           char bl_typ, char need_show_win)
  586. {
  587.   int y, /* Fensterzeile, in der aktuelle Zeile angezeigt wird */
  588.       i, /* zählt die Zeilen, um die sich Maus bewegt hat. */
  589.       old_tl = akt_winp->textline, /* zur Restaurierung nötig */
  590.       woy,  wy,   /* Mauskoordinaten in Bezug auf das Window */
  591.       first_l, last_l, /* bei rechteckigem Block: 1. und */
  592.                /* letzte anzuzeigende Zeile      */
  593.       direction_dn; /* FALSE für Mausbewegung nach oben, TRUE für
  594.                Mausbewegung nach unten oder Stillstand */
  595.   char block_got_unmarked;  /* Wurde Block bei dieser Aktion unmarkiert? */
  596.  
  597.   /* Prüfen, ob Block durch diese Aktion einen negativen Zeilenumfang
  598.      erhält. Dann ist nämlich auch eine Nachbesserung vorzunehmen */
  599.   if (akt_winp->block.e_line >= akt_winp->block.s_line
  600.   &&  akt_winp->textline < akt_winp->block.s_line)
  601.     block_got_unmarked = TRUE;
  602.   else
  603.     block_got_unmarked = FALSE;
  604.  
  605.   akt_winp->block.e_line = akt_winp->textline; /* Zeile und Spalte als Block- */
  606.   akt_winp->block.e_col = akt_winp->screencol; /* ende eintragen              */
  607.   akt_winp->block.typ = bl_typ;                /* Blocktyp eintragen          */
  608.   if (need_show_win)
  609.     show_win (W_AKT);
  610.   else
  611.   {
  612.     /* Wenn Block zu highlighten ist und (der Block Zeilenumfang >= 0 hat
  613.        oder gerade durch diesen Aufruf negativen Zeilenumfang erhält),
  614.        dann ist die Blockdarstellung nachzubessern. */
  615.     if (highblockflag &&
  616.     (akt_winp->block.s_line <= akt_winp->block.e_line || block_got_unmarked))
  617.     {
  618.       if (bl_typ == BT_NORMAL  /* bei normalem Block und bei rechteckigem   */
  619.       ||  m->x == old_x) /* Block, falls sich die x-Position nicht geändert */
  620.       { /* hat, müssen nur die Zeilen, die von der Maus überstrichen wurden,*/
  621.     /* neu angezeigt werden. */
  622.     direction_dn = m->y >= old_y;
  623.     y = akt_winp->textline - akt_winp->ws_line;
  624.     for (i=m->y; direction_dn
  625.              ? i >= old_y : 
  626.              (i <= old_y && y+akt_winp->ws_line <= akt_winp->maxline);
  627.          direction_dn ? i-- : i++)
  628.     {
  629.       lineout (direction_dn ? y-- : y++);
  630.       direction_dn ? up() : down();
  631.     }
  632.       }
  633.       else /* bei rechteckigem Block müssen alle sichtbaren Blockzeilen neu */
  634.       { /* angezeigt werden, falls sich die x-Koordinate geändert hat.
  635.        Es wird immer mit der ersten sichtbaren Blockzeile begonnen und
  636.        von dort aus nach unten gegangen. */
  637.     woy = akt_winp->ws_line-1-akt_winp->y+old_y; /* umrechnen in       */
  638.     wy  = akt_winp->ws_line-1-akt_winp->y+m->y;  /* Form               */
  639.     if (woy < wy) { first_l = woy; last_l  = wy;  }
  640.     else          { first_l = wy;  last_l  = woy; }
  641.     if (akt_winp->block.s_line < akt_winp->ws_line) /* Block beginnt */
  642.       first_l = akt_winp->ws_line;           /* oberhalb von Fenster */
  643.     else /* beginnt Block oberhalb von Mausbewegungsbereich ? */
  644.       if (akt_winp->block.s_line < first_l)
  645.         first_l = akt_winp->block.s_line;
  646.     if (first_l > akt_winp->maxline)      /* Stand Maus vorher unter */
  647.        first_l = akt_winp->maxline;       /* Textende?               */
  648.     if (akt_winp->block.e_line > last_l)  /* Block endet unterhalb */
  649.       last_l = akt_winp->block.e_line;    /* von Mausposition?     */
  650.     else
  651.        if (last_l > akt_winp->maxline)    /* Maus unter Textende?      */
  652.           last_l = akt_winp->maxline;     /* Dann nur bis zum Textende */
  653.     /* Jetzt liegt first_l und last_l im Fenster */
  654.     gotox (first_l);
  655.     y = akt_winp->textline - akt_winp->ws_line;
  656.     for (i=first_l; i<=last_l; i++, down())
  657.       lineout (y++);
  658.       }
  659.       gotox (old_tl);
  660.     }
  661.     setz_cursor (W_AKT);
  662.   }
  663. }
  664.  
  665. /******************************************************************************
  666. *
  667. * Funktion     : Cursor setzen oder Block markieren (set_cursor_or_mark_block)
  668. * --------------
  669. *
  670. * Parameter    : m           :
  671. *                  Typ          : mouse_type *
  672. *                  Wertebereich : Pointer auf Mausstruktur
  673. *                  Bedeutung    : Mauszustand
  674. *
  675. * Beschreibung : Wird der Mausknopf ohne Mausbewegung losgelassen, dann
  676. *                wird lediglich der Cursor auf die Mausposition gesetzt.
  677. *                Wird die Maus jedoch mit gedrücktem Mausknopf bewegt,
  678. *                dann wird damit ein Block markiert.
  679. *
  680. ******************************************************************************/
  681.  
  682. void set_cursor_or_mark_block(m)
  683. mouse_type *m;
  684. {
  685. #ifdef OS2
  686.   short int wait = 1; /* auf Mausereignisse warten */
  687.   mouse_type old_event; /* Damit bei leerem Event Position nicht weg ist */
  688. #endif
  689.   int old_x = m->x, /* Ablage für alte Mauskoordinaten */
  690.       old_y = m->y;
  691.   int old_button = m->button_status, /* Zwischenspeicher für Knöpfe */
  692.       moved = FALSE;
  693.   char event_valid = TRUE, /* Wird auf FALSE gesetzt, wenn in OS/2 leeres
  694.                   Mouse-Event auftritt (bei wait=0 möglich) */
  695.        need_show_win = TRUE; /* wird TRUE, wenn in mouse_bl...end nicht
  696.                 nur die Zeilen zwischen alter und neuer
  697.                 Mausposition neu angezeigt werden müssen,
  698.                 sondern ein show_win notwendig geworden ist. */
  699.  
  700.   /* zunächst wird der Cursor an die Mausposition gesetzt */
  701.   gotox(akt_winp->ws_line + m->y - 1 - akt_winp->y);
  702.   akt_winp->screencol = akt_winp->ws_col + m->x - 1 - akt_winp->x;
  703.   hide_show (MOUSE_HIDE);
  704.   setz_cursor(W_AKT);
  705.   hide_show (MOUSE_SHOW);
  706.   /* warten, bis entweder der Mausknopf losgelassen wird, oder */
  707.   /* die Maus bewegt wird. */
  708. #ifdef OS2
  709.   MouReadEventQue (m, &wait, mouse_handle);
  710.   if (!(old_button & MOUSE_BUT3)) /* Wenn Mitte, dann sofort zur Block- */
  711.   {                               /* behandlung springen                */
  712.     /* solange, wie die Maus bewegt wird, oder kein Mausereignis stattgefunden
  713.        hat (nur bei wait==0 möglich) die Blockgrößen anpassen. */
  714.     while ((m->button_status & (MOUSE_BUT1_MOVE | MOUSE_BUT2_MOVE
  715.                   | MOUSE_BUT1 | MOUSE_BUT2))
  716.       || (!wait && !m->button_status && !m->time && !m->x && !m->y))
  717.     {
  718.       if (!wait && !m->button_status && !m->time && !m->x && !m->y)
  719.     event_valid = FALSE;  /* leeres Event gelesen bei wait=0 */
  720.       else
  721.       {
  722.     old_event = *m;      /* gültige Events werden gemerkt */
  723.     event_valid = TRUE;
  724.       }
  725. #else
  726.     while((m=get_mouse())->button_status & (MOUSE_BUT1 | MOUSE_BUT2))
  727.     {
  728. #endif
  729.       if(event_valid && in_akt_win(m->x,m->y)) /* Innerhalb des Fenster ? */
  730.       {
  731. #ifdef OS2
  732.     wait = 1; /* Innerhalb auf Mausereignis warten */
  733. #endif
  734.     if(m->x != old_x || m->y != old_y)  /* Maus wurde mit gedrücktem Knopf */
  735.     {                                   /* bewegt: */
  736.       hide_show(MOUSE_HIDE);
  737.       if(!moved) /* Falls erste Bewegung: */
  738.       {
  739.         moved = TRUE;
  740.         /* Jetzt Blockanfang auf die alte Cursorposition setzen */
  741.         do_blstart();
  742.         /* Dann Cursor auf neue Position setzen */
  743.         gotox(akt_winp->ws_line + m->y - 1 - akt_winp->y);
  744.         akt_winp->screencol = akt_winp->ws_col + m->x - 1 - akt_winp->x;
  745.       }
  746.       else
  747.       {
  748.         gotox(akt_winp->ws_line + m->y - 1 - akt_winp->y);
  749.         akt_winp->screencol = akt_winp->ws_col + m->x - 1 - akt_winp->x;
  750.       }
  751. #ifdef OS2
  752.       if(m->button_status & MOUSE_BUT1_MOVE)
  753. #else
  754.       if(m->button_status & MOUSE_BUT1) /* Bei linkem Knopf normaler Block */
  755. #endif
  756.         mouse_blend(m, old_x, old_y, BT_NORMAL, need_show_win);
  757.       else                     /* Bei rechtem Knopf rechteckiger Block */
  758.         mouse_blend(m, old_x, old_y, BT_RECHTECK, need_show_win);
  759.       hide_show(MOUSE_SHOW);
  760.       old_x = m->x; /* neue Mauskoordinaten merken */
  761.       old_y = m->y;
  762.       need_show_win = FALSE; /* Block wurde richtig angezeigt, */
  763.     } /* also muß beim nächsten mal nur die Differenz gezeigt  */
  764.       }   /* werden */
  765.       else /* Maus steht außerhalb des Fensters */
  766.       { /* Jetzt muß evtl. der Fensterinhalt gescrollt werden. */
  767.     need_show_win = TRUE;  /* beim nächsten Blockendesetzen muß */
  768.     hide_show(MOUSE_HIDE); /* das Fenster neu gezeichnet werden */
  769.     check_scroll(
  770. #ifdef OS2
  771.              &old_event);
  772. #else
  773.              m);
  774. #endif
  775.     hide_show(MOUSE_SHOW);   /* Mauscursor wieder sichtbar machen */
  776. #ifdef OS2
  777.     wait = 0; /* Solange Maus außerhalb des Fensters steht, nicht auf */
  778.           /* Mausereignis warten, sondern ständig scrollen. */
  779. #endif
  780.     old_x = m->x; /* neue Mauskoordinaten merken */
  781.     old_y = m->y;
  782.       }
  783. #ifdef OS2
  784.       MouReadEventQue (m, &wait, mouse_handle);
  785.     }
  786. #endif
  787.   }
  788.   if(!moved)
  789.     if((old_button | m->button_status) & MOUSE_BUT2) /* Wenn der Mauszeiger nicht mit */
  790.     { /* gedrücktem Knopf bewegt wurde und der rechte Knopf gedrückt war: */
  791.       hide_show(MOUSE_HIDE);
  792.       if(block_defined()) /* Wenn im aktuellen Fenster ein Block markiert ist, */
  793.       {                    /* und neben dem rechten noch der mittlere Knopf */
  794.     if(old_button & MOUSE_BUT3) /* gedrückt war, dann Block löschen */
  795.       do_blweg();
  796.     else             /* Wenn nur der rechte Knopf gedrückt war, */
  797.     {
  798.       do_blcut();    /* dann diesen Cutten */
  799.       do_blunmark(); /* und anschließend unmarkieren */
  800.     }
  801.       }
  802.       else          /* Ist jedoch kein Block markiert, dann Pasten */
  803.     do_blpaste();
  804.       hide_show(MOUSE_SHOW);
  805.     }
  806.     else
  807.       if(((old_button | m->button_status) & (MOUSE_BUT1 | MOUSE_BUT3))
  808.       == (MOUSE_BUT1 | MOUSE_BUT3))
  809.       { /* linker und mittlerer Knopf gedrückt ? */
  810.     hide_show(MOUSE_HIDE);
  811.     do_blmove();
  812.     hide_show(MOUSE_SHOW);
  813.       }
  814. }
  815.  
  816. /******************************************************************************
  817. *
  818. * Funktion     : Mausposition in Schaltfäache wandeln (pos_to_button)
  819. * --------------
  820. *
  821. * Parameter    : m           :
  822. *                  Typ          : mouse_type *
  823. *                  Wertebereich : Pointer auf Mausstruktur
  824. *                  Bedeutung    : Mausstatus
  825. *
  826. * Ergebnis     :
  827. *                  Typ          : int
  828. *                  Wertebereich : MOUSE_...
  829. *                  Bedeutung    : Bezeichner der Schaltfläche
  830. *
  831. * Beschreibung : Die Mausposition wird mit der Lage der Schaltflächen
  832. *                verglichen und die entsprechende Schaltfläche
  833. *                zurückgeliefert.
  834. *
  835. ******************************************************************************/
  836.  
  837. int pos_to_button(m)
  838. mouse_type *m;
  839. {
  840.   if(in_akt_win(m->x,m->y))
  841.     return(MOUSE_TEXT); /* Maus steht im Textbereich */
  842.   if(m->x == akt_winp->x && m->y == akt_winp->y)
  843.     return(MOUSE_CLOSE); /* linke obere Ecke: Schließknopf */
  844.   if(m->x == akt_winp->x+akt_winp->dx+1 && m->y == akt_winp->y)
  845.     return(MOUSE_TOG_SIZE);
  846.   if(m->x == akt_winp->x+akt_winp->dx+1 
  847.   && m->y == akt_winp->y+akt_winp->dy+1)
  848.     return(MOUSE_SIZE);
  849.   if(m->y == akt_winp->y)
  850.     return(MOUSE_KOPF);
  851.   if(m->x == akt_winp->x+akt_winp->dx+1)
  852.     if(m->y == akt_winp->y+1)
  853.       return(MOUSE_SCROLL_DOWN);
  854.     else
  855.       if(m->y == akt_winp->y+akt_winp->dy)
  856.     return(MOUSE_SCROLL_UP);
  857.   if(m->y == akt_winp->y+akt_winp->dy+1)
  858.     if(m->x == akt_winp->x+1)
  859.       return(MOUSE_SCROLL_RIGHT);
  860.     else
  861.       if(m->x == akt_winp->x+akt_winp->dx)
  862.     return(MOUSE_SCROLL_LEFT);
  863.   return(MOUSE_RAHMEN);
  864. }
  865.  
  866. /******************************************************************************
  867. *
  868. * Funktion     : Fenster mit Maus schließen (mouse_win_zu)
  869. * --------------
  870. *
  871. * Beschreibung : Offensichtlich kann während der Maus-Routine keine andere
  872. *                Maus-Routine installiert werden. Das hat zur Folge, daß
  873. *                beim Ausführen der Mausfunktion "Fenster schließen" im
  874. *                Falle der Ausführung der Funktion ja_nein dort keine
  875. *                neue Maus-Routine installiert werden kann, wenn die alte
  876. *                Maus-Routine noch läuft.
  877. *                Die äußerst unschöne Lösung, die nach Verbesserung schreit,
  878. *                ist folgende:
  879. *                In den Tastaturpuffer wird der Code für das Kommando
  880. *                "Fenster schließen" geschrieben.
  881. *                Dann wird die Maus-Routine verlassen. Während der Ausführung
  882. *                des Kommandos ist die alte Maus-Routine sowieso gesperrt und
  883.                 die neue kann bedenkenlos installiert werden.
  884. *
  885. ******************************************************************************/
  886.  
  887. void mouse_win_zu()
  888. {
  889. #ifdef OS2
  890.   hide_show (MOUSE_HIDE);
  891.   do_win_zu(FALSE);
  892.   hide_show (MOUSE_SHOW);
  893. #else
  894.   int kom_nr=0, /* Nummer des Kommandos do_win_zu */
  895.       i;        /* Zum Durchlaufen des Kommandostrings */
  896.   short int *key_buff_in = (short int *) 0x41C,
  897.         *key_buff    = (short int *) 0x41E; /* Tastaturpuffer */
  898.  
  899.   /* Zuerst den Index des Kommandos "Fenster schließen" ermitteln */
  900.   while(funktion[kom_nr] != do_win_zu && kom_nr++ <= mc_index);
  901.  
  902.   /* Jetzt Schreibadresse in Tastaturpuffer ermitteln: */
  903.   key_buff += (*key_buff_in - 0x1E) / 2;
  904.   for(i=0;i<comm_feld[kom_nr].blen;i++)
  905.   {
  906.     *key_buff++ = comm_feld[kom_nr].befehl[i];
  907.     if(key_buff == (short int *) 0x43E) /* Am Ende wrap around */
  908.       key_buff = (short int *) 0x41E;
  909.   }
  910.   *key_buff_in = FP_OFF(key_buff) - 0x400;
  911. #endif
  912. }
  913.  
  914. /******************************************************************************
  915. *
  916. * Funktion     : Mit Maus nach rechts scrollen (msr)
  917. * --------------
  918. *
  919. * Beschreibung : Der Mauszeiger wird versteckt. Dann wird der Text im Fenster
  920. *                nach rechts geschoben und nötigenfalls der Cursor angepaßt.
  921. *                Dann wird setz_cursor aufgerufem imd der Mauszeiger wieder
  922. *                angezeigt.
  923. *                Der Verschiebe-Vorgang wird solange wiederholt, bis kein
  924. *                Mausknopf mehr gedrückt ist.
  925. *
  926. ******************************************************************************/
  927.  
  928. void msr()
  929. {
  930. #ifdef OS2
  931.   mouse_type m;
  932.   short int wait = 0; /* auf Mausereignisse warten */
  933. #endif
  934.  
  935.   hide_show(MOUSE_HIDE); /* Mauszeiger verstecken */
  936. #ifdef OS2
  937.   MouReadEventQue (&m, &wait, mouse_handle);
  938.   while ((m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT1_MOVE
  939.                | MOUSE_BUT2_MOVE))
  940.        || (!m.button_status && !m.x && !m.y && !m.time)) /* kein Event */
  941. #else
  942.   while(get_mouse()->button_status & (MOUSE_BUT1 | MOUSE_BUT2))
  943. #endif
  944.   {
  945.     text_right();          /* Text nach rechts scrollen */
  946.     /* Falls Cursor am rechten Rand "rausgefallen", dann eins nach links */
  947.     if(akt_winp->screencol >= akt_winp->ws_col + akt_winp->dx)
  948.       left();
  949.     setz_cursor(W_AKT);
  950. #ifdef OS2
  951.     MouReadEventQue (&m, &wait, mouse_handle);
  952. #endif
  953.   }
  954.   hide_show(MOUSE_SHOW);
  955. }
  956.  
  957. /******************************************************************************
  958. *
  959. * Funktion     : Mit Maus nach links scrollen (msl)
  960. * --------------
  961. *
  962. * Beschreibung : Der Mauszeiger wird versteckt. Dann wird der Text im Fenster
  963. *                nach links geschoben und nötigenfalls der Cursor angepaßt.
  964. *                Dann wird setz_cursor aufgerufem imd der Mauszeiger wieder
  965. *                angezeigt.
  966. *                Der Verschiebe-Vorgang wird solange wiederholt, bis kein
  967. *                Mausknopf mehr gedrückt ist.
  968. *
  969. ******************************************************************************/
  970.  
  971. void msl()
  972. {
  973. #ifdef OS2
  974.   mouse_type m;
  975.   short int wait = 0; /* auf Mausereignisse warten */
  976. #endif
  977.  
  978.   hide_show(MOUSE_HIDE); /* Mauszeiger verstecken */
  979. #ifdef OS2
  980.   MouReadEventQue (&m, &wait, mouse_handle);
  981.   while ((m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT1_MOVE
  982.                | MOUSE_BUT2_MOVE))
  983.        || (!m.button_status && !m.x && !m.y && !m.time)) /* kein Event */
  984. #else
  985.   while(get_mouse()->button_status & (MOUSE_BUT1 | MOUSE_BUT2))
  986. #endif
  987.   {
  988.     text_left();          /* Text nach links scrollen */
  989.     /* Falls Cursor am linken Rand "rausgefallen", dann eins nach rechts */
  990.     if(akt_winp->screencol < akt_winp->ws_col)
  991.       right();
  992.     setz_cursor(W_AKT);
  993. #ifdef OS2
  994.     MouReadEventQue (&m, &wait, mouse_handle);
  995. #endif
  996.   }
  997.   hide_show(MOUSE_SHOW);
  998. }
  999.  
  1000. /******************************************************************************
  1001. *
  1002. * Funktion     : Mit Maus nach oben scrollen (msu)
  1003. * --------------
  1004. *
  1005. * Beschreibung : Der Mauszeiger wird versteckt. Dann wird der Text im Fenster
  1006. *                nach oben geschoben und nötigenfalls der Cursor angepaßt.
  1007. *                Dann wird setz_cursor aufgerufem imd der Mauszeiger wieder
  1008. *                angezeigt.
  1009. *                Der Verschiebe-Vorgang wird solange wiederholt, bis kein
  1010. *                Mausknopf mehr gedrückt ist.
  1011. *
  1012. ******************************************************************************/
  1013.  
  1014. void msu()
  1015. {
  1016. #ifdef OS2
  1017.   mouse_type m;
  1018.   short int wait = 0; /* auf Mausereignisse warten */
  1019. #endif
  1020.  
  1021.   hide_show(MOUSE_HIDE);  /* Mauszeiger verstecken */
  1022. #ifdef OS2
  1023.   MouReadEventQue (&m, &wait, mouse_handle);
  1024.   while (((m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT1_MOVE
  1025.                | MOUSE_BUT2_MOVE))
  1026.        || (!m.button_status && !m.x && !m.y && !m.time)) /* kein Event */
  1027. #else
  1028.   while(get_mouse()->button_status & (MOUSE_BUT1 | MOUSE_BUT2)
  1029. #endif
  1030.   && akt_winp->ws_line < akt_winp->maxline)
  1031.   {
  1032.     akt_winp->ws_line++; /* dann Nummer der ersten sichtbaren Zeile erhoehen */
  1033.     text_up(0);          /* gesamten Fenstertext um 1 Zeile nach oben */
  1034.     if(akt_winp->textline < akt_winp->ws_line) /* Falls Cursor in oberster */
  1035.       down();            /* Zeile, dann Cursor um 1 Zeile nach unten bewegen */
  1036.     setz_cursor(W_AKT);       /* Cursor an richtige Position setzen */
  1037. #ifdef OS2
  1038.     MouReadEventQue (&m, &wait, mouse_handle);
  1039. #endif
  1040.   }
  1041.   hide_show(MOUSE_SHOW);
  1042. }
  1043.  
  1044. /******************************************************************************
  1045. *
  1046. * Funktion     : Mit Maus nach unten scrollen (msd)
  1047. * --------------
  1048. *
  1049. * Beschreibung : Der Mauszeiger wird versteckt. Dann wird der Text im Fenster
  1050. *                nach unten geschoben und nötigenfalls der Cursor angepaßt.
  1051. *                Dann wird setz_cursor aufgerufem imd der Mauszeiger wieder
  1052. *                angezeigt.
  1053. *                Der Verschiebe-Vorgang wird solange wiederholt, bis kein
  1054. *                Mausknopf mehr gedrückt ist.
  1055. *
  1056. ******************************************************************************/
  1057.  
  1058. void msd()
  1059. {
  1060. #ifdef OS2
  1061.   mouse_type m;
  1062.   short int wait = 0; /* auf Mausereignisse warten */
  1063. #endif
  1064.  
  1065.   hide_show(MOUSE_HIDE); /* Mauszeiger verstecken */
  1066. #ifdef OS2
  1067.   MouReadEventQue (&m, &wait, mouse_handle);
  1068.   while (((m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT1_MOVE
  1069.                | MOUSE_BUT2_MOVE))
  1070.        || (!m.button_status && !m.x && !m.y && !m.time)) /* kein Event */
  1071. #else
  1072.   while(get_mouse()->button_status & (MOUSE_BUT1 | MOUSE_BUT2)
  1073. #endif
  1074.   && akt_winp->ws_line)
  1075.   {
  1076.     akt_winp->ws_line--; /* Nummer der ersten sichtbaren Zeile dekrementieren */
  1077.     text_down(0);        /* Text ab Zeile 0 (ganzes Fenster) um 1 nach unten  */
  1078.     if(akt_winp->textline >= akt_winp->ws_line + akt_winp->dy)
  1079.       up(); /* Stand Cursor in letzter Schirmzeile, Cursor 1 Zeile hoch */
  1080.     setz_cursor(W_AKT);        /* Cursor an richtige Position */
  1081. #ifdef OS2
  1082.     MouReadEventQue (&m, &wait, mouse_handle);
  1083. #endif
  1084.   }
  1085.   hide_show(MOUSE_SHOW);
  1086. }
  1087.  
  1088. /******************************************************************************
  1089. *
  1090. * Funktion     : Fenstergröße mit Maus togglen (mouse_tog_size)
  1091. * --------------
  1092. *
  1093. * Beschreibung : Diese Routine wird aufgerufen, wenn der Benutzer mit der
  1094. *                Maus auf die obere rechte Fensterecke geklickt hat. Es
  1095. *                wird die Fenstergröße korrekt eingestellt. Im Falle von OS2
  1096. *                muß man anschließend noch auf das Loslassen des Mausknopfs
  1097. *                warten, da dies sonst als weiteres Ereignis in der Queue
  1098. *                landet.
  1099. *
  1100. ******************************************************************************/
  1101.  
  1102. void mouse_tog_size()
  1103. {
  1104.   mouse_type m;
  1105.   short int wait = 1; /* Auf Mausereignis warten */
  1106.  
  1107.   hide_show(MOUSE_HIDE);
  1108.   do_toggle_size();
  1109.   hide_show(MOUSE_SHOW);
  1110. #ifdef OS2            /* Im Fall von OS2 auf Loslassen des Knopfes warten */
  1111.   do
  1112.   {
  1113.     MouReadEventQue (&m, &wait, mouse_handle);
  1114.   } while (m.button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT3
  1115.      |  MOUSE_BUT1_MOVE | MOUSE_BUT2_MOVE | MOUSE_BUT3_MOVE));
  1116. #endif
  1117. }
  1118.  
  1119. /******************************************************************************
  1120. *
  1121. * Funktion     : Maus-Routine (mouse_routine)
  1122. * --------------
  1123. *
  1124. * Beschreibung : Diese Routine wird angesrpugen, wenn mit set_mouse_int eine
  1125. *                Event-Mask ungleich 0 eingetragen wurde und das entsprechende
  1126. *                Ereignis eingetreten ist.
  1127. *                Diese Funktion führt dann die entsprechenden Mausfunktionen
  1128. *                aus.
  1129. *
  1130. ******************************************************************************/
  1131.  
  1132. void mouse_routine(
  1133. #ifdef OS2
  1134.            mouse_type *m
  1135. #endif
  1136.           )
  1137. {
  1138. #ifdef OS2  /* Wurde einer der Knöpfe gedrückt, oder hat man nur eine
  1139.            Message "Losgelassen" empfangen? */
  1140.   if (m->button_status & (MOUSE_BUT1 | MOUSE_BUT2 | MOUSE_BUT3))
  1141.   {
  1142. #else
  1143.   mouse_type *m;    /* Mausstatus */
  1144.  
  1145.   asm push ds;
  1146.   asm push es;
  1147.   asm mov  ax,DGROUP;
  1148.   asm mov  es,ax;
  1149.   asm mov  ds,ax;
  1150.  
  1151. /*  outportb(32,(char) 32); Interrupt für beendet erklären, (nicht auf 386)*/
  1152.       /* damit z.B. im Schneider PC Maus wieder erkannt wird. */
  1153.   m = get_mouse();  /* Mauskoordinaten und Knopfstatus einlesen */
  1154. #endif
  1155.   check_buff();     /* Pufferinhalt in Text uebernehmen       */
  1156.   if(pos_to_win(m->x,m->y) != akt_winp) /* Klick auf aktuelles Fenster? */
  1157.   {                     /* Nein: */
  1158.     hide_show(MOUSE_HIDE); /* Maus solange verstecken */
  1159.     kopf(W_NOTAKT);     /* Altes Fenster als inaktiv markieren */
  1160.     rahmen(W_NOTAKT);
  1161.     wrefresh(akt_winp->winp);
  1162.     sw_pos(m->x,m->y);  /* Zum Fenster wechseln */
  1163.     show_win(W_AKT);    /* Fenster neu zeichnen */
  1164.     hide_show(MOUSE_SHOW); /* Maus wieder anzeigen */
  1165.   }
  1166.   else  /* Wenn schon Fensterwechsel, dann nichts sonst tun. */
  1167.   {
  1168.     switch(pos_to_button(m))
  1169.     {
  1170.       case MOUSE_TEXT        : set_cursor_or_mark_block(m); break;
  1171.       case MOUSE_KOPF        : mouse_movewin(m); break;
  1172.       case MOUSE_SIZE        : mouse_sizewin(m); break;
  1173.       case MOUSE_CLOSE       : mouse_win_zu(); break;
  1174.       case MOUSE_TOG_SIZE    : mouse_tog_size(); break;
  1175.  
  1176.       case MOUSE_SCROLL_UP   : msu(); break;
  1177.       case MOUSE_SCROLL_DOWN : msd(); break;
  1178.       case MOUSE_SCROLL_RIGHT: msr(); break;
  1179.       case MOUSE_SCROLL_LEFT : msl(); break;
  1180.     }
  1181.   }
  1182. #ifdef OS2
  1183.   }
  1184. #else
  1185.   asm pop  es;
  1186.   asm pop  ds;
  1187. #endif
  1188. }
  1189.  
  1190. /******************************************************************************
  1191. *
  1192. * Funktion     : Mouse-Interrupt aktivieren/sperren (set_mouse_int)
  1193. * --------------
  1194. *
  1195. * Parameter    : event_mask :
  1196. *                  Typ          : int
  1197. *                  Wertebereich : 0-31
  1198. *                  Bedeutung    : Bit 0 : Mausbewegung melden
  1199. *                                 Bit 1 : Druck linker Mausknopf melden
  1200. *                                 Bit 2 : Lösen linker Mausknopf melden
  1201. *                                 Bit 3 : Druck rechter Mausknopf melden
  1202. *                                 Bit 4 : Lösen linker Mausknopf melden
  1203. *
  1204. * Beschreibung : Mittels des Mausinterrupts 51, Funktion 12 wird die
  1205. *                Funktion mouse_routine als anzuspringende Funktion
  1206. *                eingetragen. Die Event-Mask wird gesetzt.
  1207. *
  1208. ******************************************************************************/
  1209.  
  1210. #ifndef OS2
  1211. void set_mouse_int(event_mask)
  1212. int event_mask;
  1213. {
  1214.   union  REGS  regs;
  1215.   struct SREGS sregs;
  1216.  
  1217.   /* Mauszeiger löschen, falls Maus demaskiert wird, sonst */
  1218.   /* Mauszeiger anzeigen */
  1219.   hide_show(event_mask ? MOUSE_SHOW : MOUSE_HIDE);
  1220.   regs.x.ax  = 12;
  1221.   regs.x.cx  = event_mask; /* Linken Mausknopf melden */
  1222.   regs.x.dx  = FP_OFF(mouse_routine);
  1223.   sregs.es   = FP_SEG(mouse_routine);
  1224.   int86x(51,®s,®s,&sregs);
  1225. }
  1226. #endif
  1227.  
  1228. /******************************************************************************
  1229. *
  1230. * Funktion     : Maus initialisieren und abfragen (mouse_thread) (Nur OS/2!!!)
  1231. * --------------
  1232. *
  1233. * Beschreibung : Es werden die Attribute des Maus-Cursors festgelegt, der
  1234. *                Maus-Cursor wird eingeschaltet, als Events sollen Druck des
  1235. *                linken oder rechten Mausknopfs erkannt werden.
  1236. *                Der Zähler sleep_time gibt die Anzahl der Mikrosekunden an,
  1237. *                die zwischen zwei Abfragen gewartet werden soll. Dieser
  1238. *                Zähler wird nach einem gefundenen Mausereignis auf 0 gesetzt,
  1239. *                da weitere Mausereignisse erwartet werden. Schnell nach-
  1240. *                folgende Ereignisse werden somit nahezu verzögerungsfrei be-
  1241. *                arbeitet, während nach längerer Zeit eine maximale Zeit
  1242. *                von 1/10 s bis zur Bearbeitung des Ereignisses vergehen kann.
  1243. *                Durch diese Technik wird trotz des Pollings die Systemaus-
  1244. *                lastung gering gehalten.
  1245. *
  1246. ******************************************************************************/
  1247.  
  1248. #ifdef OS2
  1249. void mouse_thread ()
  1250. {
  1251.   short int  wait = 0,            /* nicht auf Ereignisse warten */
  1252.          mask = MOUSE_MASK;
  1253.   int        sleep_time = 0;      /* sleep in us zwischen zwei Aufrufen */
  1254.   mouse_type event;
  1255.  
  1256.   MouOpen (NULL, &mouse_handle);  /* Maus "öffnen" */
  1257.   hide_show (MOUSE_SHOW);
  1258.   MouSetEventMask (&mask, mouse_handle);
  1259.   while (mouse_active)
  1260.   {
  1261.     DosSleep (sleep_time/1000); /* Zwischen Ereignissen warten */
  1262.     if (sleep_time < 100000)    /* Auf maximal 100 ms erhöhen */
  1263.       sleep_time++;
  1264.     MouReadEventQue (&event, &wait, mouse_handle);
  1265.     if (event.time || event.button_status) /* Ereignis ? */
  1266.     {
  1267.       sleep_time = 0;      /* Wartezeit wieder von 0 beginnen lassen */
  1268.       DosRequestMutexSem (sem_handle, -1); /* ohne Timeout auf Semaphor warten */
  1269.       mouse_routine (&event);
  1270.       DosReleaseMutexSem (sem_handle);     /* Semaphor wieder freigeben */
  1271.     }
  1272.   }
  1273.   MouClose (mouse_handle);
  1274. }
  1275. #endif
  1276.  
  1277. /******************************************************************************
  1278. *
  1279. * Funktion     : Maus initialisieren (init_mouse)
  1280. * --------------
  1281. *
  1282. * Beschreibung : Es werden die Attribute des Maus-Cursors festgelegt, der
  1283. *                Maus-Cursor wird eingeschaltet, die Maus-Routine eingebunden
  1284. *                und so eingestellt, daß sie durch Druck auf den linken
  1285. *                Mausknopf aktiviert wird.
  1286. *
  1287. ******************************************************************************/
  1288.  
  1289. void init_mouse()
  1290. {
  1291. #ifdef OS2
  1292.   /* Starte eigenen Mouse-Thread */
  1293.   mouse_active = TRUE;
  1294.   mouse_ThreadID = _beginthread (mouse_thread, 0, 20000, 0); 
  1295. #else
  1296.   /* Ruft die Maus-Funktion 12 auf, wodurch der Vektor der User-Routine */
  1297.   /* auf die Funktion mouse_routine gesetzt werden soll. */
  1298.   union  REGS  regs;
  1299.   struct SREGS sregs;
  1300.  
  1301.   regs.x.ax  = 10;  /* Set Text Cursor */
  1302.   regs.x.bx  = 0;   /* Software-Cursor */
  1303.   regs.x.cx  = 0x77ff;  /* Screen Mask */
  1304.   regs.x.dx  = 0x7700;  /* Cursor Mask */
  1305.   int86(51,®s,®s);
  1306.   regs.x.ax  = 7;   /* Set Minimum and Maximum X-Cursor Position */
  1307.   regs.x.cx  = 0;
  1308.   regs.x.dx  = 8*(COLS-1);
  1309.   int86(51,®s,®s);
  1310.   regs.x.ax  = 8;   /* Set Minimum and Maximum Y-Cursor Position */
  1311.   regs.x.cx  = 0;
  1312.   regs.x.dx  = 8*(LINES-1);
  1313.   int86(51,®s,®s);
  1314. #endif
  1315. }
  1316.