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