home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / edit / point20 / button.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-04  |  14.1 KB  |  565 lines

  1. #include "pt.h"
  2. #include "stdlib.h"
  3.  
  4. /* delay to start scrolling */
  5. static int hsecToWait;
  6.  
  7. int pascal
  8. /* XTAG:mouseButton */
  9. mouseButton(evhead)
  10.     int evhead;
  11. {
  12.     extern unsigned char msgBuffer[];
  13.     extern union REGS rin, rout;
  14.     extern int menuRow, menuCol;
  15.     extern struct menuBlock far *menus[];
  16.     extern int debug;
  17.     extern struct window *selWindow;
  18.     extern long selBegin, selEnd;
  19.     extern struct window *activeWindow;
  20.     extern int scrRows, scrCols;
  21.     extern struct event events[];
  22.     extern unsigned char buttonVector[];
  23.     extern unsigned char toplineVector[];
  24.     extern int passEvhead;
  25.     extern long passCp;
  26.     extern int mousePresent;
  27.     extern int menuLine;
  28.     extern int helpMode;
  29.     extern int descrFileId;
  30.     extern int menuShowing;
  31.     extern int lastOnTopline;
  32.     extern int lastCommand;
  33.     extern int isMessage;
  34.     extern int searchMode;
  35.     extern int smoothScroll;
  36.     extern int scrollDelay;
  37.     extern unsigned char windowPoints[];
  38.     extern struct openFile *files;
  39.     extern unsigned char *outOfWindows;
  40.     extern int toplineMenu;
  41.  
  42.     struct window *w;
  43.     struct window  *newW;
  44.     int anchorRow, anchorCol, curRow, curCol;
  45.     int row1, col1, row2, col2;
  46.     int where, buttons, i, n, fid;
  47.     int menuNumber, buttonMask, thisShift, thisButton;
  48.     long cp, thumbcp, size;
  49.  
  50.     hsecToWait = scrollDelay;
  51.     anchorRow = events[evhead].vertical>>3;
  52.     anchorCol = events[evhead].horizontal>>3;
  53.     thisButton = events[evhead].buttons;
  54.     buttonMask = events[evhead].mask;
  55.     /* if no buttons down and not a mouse movement command */
  56.     /* thit it must be a left over button up event */
  57.     /* ignore left over button up events */
  58.     if( thisButton == 0 && buttonMask != 1 )
  59.         return 0;
  60.     if( thisButton == 0 ) {
  61.         /* is this the (top or bottom) menu line? */
  62.         if( anchorRow != (menuLine > 0 ? 0 : (scrRows-1) ) ) {
  63.             /* if we are displaying top line descriptions */
  64.             /* then erase them when you leave the top line */
  65.             if( helpMode > 1 && lastOnTopline == 1 ) {
  66.                 lastOnTopline = 0;
  67.                 msg("", 1);
  68.             }
  69.             return 0;
  70.         }
  71.  
  72.         /* if it is a menu, the figure out which item on it */
  73.         if( menuShowing != 0 ) {
  74.             n = FindMenuItem( menuShowing, anchorCol );
  75.             /* remember the last command selected */
  76.             lastCommand = n;
  77.             if( helpMode > 1 ) {
  78.                 readLine(descrFileId, 80L*(long)n,
  79.                             &msgBuffer[0], 0);
  80.                 msgBuffer[78] = '\0';
  81.                 msg(msgBuffer, 1);
  82.                 lastOnTopline = 1;
  83.             }
  84.         }
  85.         return 0;
  86.     }
  87.  
  88.     /* handle things that we need to do every command */
  89.     handleTempItems();
  90.  
  91.     switch( thisButton ) {
  92.         case 1:
  93.             buttons = LEFTBUTTON;
  94.             break;
  95.         case 2:
  96.             buttons = RIGHTBUTTON;
  97.             break;
  98.         case 3:
  99.         case 4:
  100.         default:
  101.             buttons = BOTHBUTTONS;
  102.             break;
  103.     }
  104.  
  105.     /* find out what window (if any) and where this mouse was */
  106.     xyToPos(&anchorRow, &anchorCol, &where, &cp, &w);
  107.     
  108.     /* set these now that anchorRow and anchorCol are set by xyToPos */
  109.     curRow = anchorRow;
  110.     curCol = anchorCol;
  111.  
  112.     /* execute the appropriate command for the mouse position */
  113.     /* and mouse buttons that were pressed */
  114.     switch( buttons+where ) {
  115.     
  116.     /* Any corner, Left => Top/Bottom */
  117.     case LEFTBUTTON+UPPERLEFT:
  118.         if( waitUp(1) )
  119.             goto bothUpperLeft;
  120.         else
  121.             return command(windowPoints[0], 0, w);
  122.     case LEFTBUTTON+LOWERLEFT:
  123.         if( waitUp(1) )
  124.             goto bothLowerLeft;
  125.         else
  126.             return command(windowPoints[4], 0, w);
  127.     case LEFTBUTTON+UPPERRIGHT:
  128.         if( waitUp(1) )
  129.             goto bothUpperRight;
  130.         else
  131.             return command(windowPoints[2], 0, w);
  132.     case LEFTBUTTON+LOWERRIGHT:
  133.         if( waitUp(1) )
  134.             goto bothLowerRight;
  135.         else
  136.             return command(windowPoints[6], 0, w);
  137.  
  138.     /* Any corner -- Right => Stretch Window */
  139.     case RIGHTBUTTON+UPPERLEFT:
  140.         row1 = w->row2;
  141.         col1 = w->col2;
  142.         goto allStretch;
  143.     case RIGHTBUTTON+UPPERRIGHT:
  144.         row1 = w->row2;
  145.         col1 = w->col1;
  146.         goto allStretch;
  147.     case RIGHTBUTTON+LOWERLEFT:
  148.         row1 = w->row1;
  149.         col1 = w->col2;
  150.         goto allStretch;
  151.     case RIGHTBUTTON+LOWERRIGHT:
  152.         row1 = w->row1;
  153.         col1 = w->col1;
  154.     allStretch:
  155.         if( getBox(row1, col1, &row1, &col1, &row2, &col2, 1) )
  156.             goto noAction;
  157.         /* move the window */
  158.         if( moveWindow(w, row1, col1, row2, col2) != 0 )
  159.             msg("Window too small, not changed", 1);
  160.         break;
  161.  
  162.     /* upper border, right button ==> move window */
  163.     case RIGHTBUTTON+UPPERBORDER:
  164.         row1 = w->row1;
  165.         col1 = w->col1;
  166.         row2 = w->row2;
  167.         col2 = w->col2;
  168.         if( getBox(curRow, curCol, &row1, &col1, &row2, &col2, 2) )
  169.             goto bothUpper;
  170.  
  171.         /* move the window */
  172.         if( moveWindow(w, row1, col1, row2, col2) != 0 )
  173.             msg("Window too small, not changed", 1);
  174.         break;
  175.  
  176.     /* Upper and Right, Both => Split Window */
  177.     case BOTHBUTTONS+UPPERBORDER:
  178.     bothUpper:
  179.         /* do the action on buttons up */
  180.         up2Buttons(&anchorRow, &anchorCol);
  181.         /* do not allow splits that are too small */
  182.         col2 = w->col2;    /* save this for the createWindow */
  183.         if( col2 < anchorCol + 10 || w->row2 < anchorRow + 2 ) {
  184.             msg("Split window too small, not created", 1);
  185.             break;
  186.         }
  187.         newW = createWindow(files[w->fileId].origName, anchorRow,
  188.             anchorCol, w->row2, col2, CRTOP, 0);
  189.         if( newW == NULL )
  190.             break;
  191.         newW->posTopline = w->posTopline;
  192.         newW->numTopline = w->numTopline;
  193.         newW->indent = w->indent;
  194.         redrawWindow(newW);
  195.         break;
  196.  
  197.     case BOTHBUTTONS+RIGHTBORDER:
  198.     bothRight:
  199.         /* do the action on buttons up */
  200.         up2Buttons(&anchorRow, &anchorCol);
  201.         /* do not allow splits that are too small */
  202.         row2 = w->row2;    /* save this for the createWindow */
  203.         if( anchorCol < w->col1 + 10 || row2 < anchorRow + 2 ) {
  204.             msg("Split window too small, not created", 1);
  205.             break;
  206.         }
  207.         newW = createWindow(files[w->fileId].origName, anchorRow,
  208.             w->col1, row2, anchorCol, CRTOP, 0);
  209.         if( newW == NULL )
  210.             break;
  211.         row1 = anchorRow+1;
  212.         col1 = w->col1+1;
  213.         newW->posTopline = xyToWindow(w, &row1, &col1);
  214.         newW->numTopline = w->numTopline + anchorRow - w->row1;
  215.         newW->indent = w->indent;
  216.         redrawWindow(newW);
  217.         break;
  218.  
  219.     /* Lower border, Left, Right => Scroll, Both => Thumb */
  220.     case LEFTBUTTON+LOWERBORDER:
  221.     moreRightScrolling:
  222.         if( !smoothScroll && waitUp(1) )
  223.             goto bothLower;
  224.         if( (where = anchorCol - w->col1 - 1) < 1 )
  225.             where = 1;
  226.         if( (w->indent -= where) < 0 )
  227.             w->indent = 0;
  228.         redrawWindow(w);
  229.         if( ScrollSomeMore() )
  230.             goto moreRightScrolling;
  231.         break;
  232.  
  233.     case RIGHTBUTTON+LOWERBORDER:
  234.     moreLeftScrolling:
  235.         if( !smoothScroll && waitUp(1) )
  236.             goto bothLower;
  237.         if( (where = anchorCol - w->col1 - 1) < 1 )
  238.             where = 1;
  239.         w->indent += where;
  240.         redrawWindow(w);
  241.         if( ScrollSomeMore() )
  242.             goto moreLeftScrolling;
  243.         break;
  244.  
  245.     case BOTHBUTTONS+LOWERBORDER:
  246.     bothLower:
  247.         /* do the action on buttons up */
  248.         up2Buttons(&anchorRow, &anchorCol);
  249.         where = anchorCol - w->col1 - 1;
  250.         w->indent = where;
  251.         redrawWindow(w);
  252.         break;
  253.  
  254.     /* Left border, left and right => scroll, both => thumb */
  255.     case LEFTBUTTON+LEFTBORDER:
  256.     rev1scr:
  257.         if( !smoothScroll && waitUp(1) )
  258.             goto bothLeft;
  259.         where = anchorRow - w->row1 - 1;
  260.         if( where < 1 )
  261.             where = 1;
  262.         /* set up the screen map and scroll the window */
  263.         setMap( w->row1, w->col1, w->row2, w->col2, 1, 0x07);
  264.         maskTop(w);
  265.         downScroll(w, where);
  266.         if( ScrollSomeMore() )
  267.             goto rev1scr;
  268.         break;
  269.  
  270.     case RIGHTBUTTON+LEFTBORDER:
  271.     rev2scr:
  272.         if( !smoothScroll && waitUp(1) )
  273.             goto bothLeft;
  274.         where = anchorRow - w->row1 - 1;
  275.         if( where < 1 )
  276.             where = 1;
  277.         /* set up the screen map and scroll the window */
  278.         setMap(w->row1, w->col1, w->row2, w->col2, 1, 0x7);
  279.         maskTop(w);
  280.         upScroll(w, where);
  281.         if( ScrollSomeMore() )
  282.             goto rev2scr;
  283.         break;
  284.  
  285.     case BOTHBUTTONS+LEFTBORDER:
  286.     bothLeft:
  287.         /* do the action on buttons up */
  288.         up2Buttons(&anchorRow, &anchorCol);
  289.         /* remember where we came from */
  290.         w->rowLastline = w->numTopline;
  291.  
  292.         fid = w->fileId;
  293.         size = fileSize(fid);
  294.         n = w->row2 - w->row1 - 2; /* find the size of the window */
  295.         where = anchorRow - w->row1 - 1;
  296.         if( where < 0 )
  297.             where = 0;
  298.         else if( where > n )
  299.             where = n;
  300.         /* handle going to EOF as a special case */
  301.         if( where  == n ) {
  302.             /* this puts the EOF mark on the bottom line */
  303.             i = n + 1;
  304.             thumbcp = prevLine(fid, size-1, &i);
  305.         } else {
  306.             if(n == 0 )    /* eschew zerodivide */
  307.                 n = 1;
  308.             thumbcp = ((long)where * (size+1L)) / (long)n;
  309.         }
  310.         i = 1;
  311.         if( thumbcp != 0 )
  312.             thumbcp = nextLine(fid, thumbcp, &i);
  313.         cp = w->posTopline;
  314.         n = w->numTopline;
  315.         while( cp < thumbcp ) {
  316.             i = 1;
  317.             cp = nextLine(fid, cp, &i);
  318.             n += i;
  319.         }
  320.         while( cp > thumbcp ) {
  321.             i = 1;
  322.             cp = prevLine(fid, cp, &i);
  323.             n -= i;
  324.         }
  325.         w->posTopline = cp;
  326.         w->numTopline = n;
  327.         redrawWindow(w);
  328.         break;
  329.  
  330.     /* Inside a window or outside any window */
  331.     case LEFTBUTTON+INSIDEWINDOW:
  332.     case LEFTBUTTON+OUTSIDEWINDOW:
  333.     case RIGHTBUTTON+INSIDEWINDOW:
  334.     case RIGHTBUTTON+OUTSIDEWINDOW:
  335.     case BOTHBUTTONS+INSIDEWINDOW:
  336.     case BOTHBUTTONS+OUTSIDEWINDOW:
  337.         /* find the shift state of the keyboard */
  338.         rin.h.ah = 2;
  339.         int86(0x16, &rin, &rout);
  340.  
  341.         /* mask of the Ins, Caps, Num, and Scroll states */
  342.         thisShift = rout.h.al & 0xF;
  343.         
  344.         /* adjust for cursor simulation of the mouse */
  345.         if( !mousePresent )
  346.             thisShift = buttonMask>>8;
  347.  
  348.         /* fix thisShift so that either shift keys implies shift */
  349.         /* shift over bit1 and OR bit0 with it */
  350.         thisShift = (thisShift>>1) | (thisShift&0x1);
  351.  
  352.         /* get the command number from the table */
  353.         i = (thisShift<<3) + thisButton;
  354.         n = buttonVector[i];
  355.  
  356.         /* record where to put the menu */
  357.         menuRow = curRow;
  358.         menuCol = curCol;
  359.  
  360.         /* pass some things command might need */
  361.         passEvhead = evhead;
  362.         passCp = cp;
  363.  
  364.         /* let the general command processor handle it */
  365.         return command(n, 0, w);
  366.  
  367.     case LEFTBUTTON+UPPERBORDER:
  368.         if( waitUp(1) )
  369.             goto bothUpper;
  370.         else {
  371.             activeWindow = w;
  372.             redoBorders(0);
  373.             updateScreen(0, scrRows-1);
  374.             break;
  375.         }
  376.     case RIGHTBUTTON+RIGHTBORDER:
  377.         if( waitUp(1) )
  378.             goto bothRight;
  379.         return command(windowPoints[9], 0, w);
  380.  
  381.     case LEFTBUTTON+RIGHTBORDER:
  382.         if( waitUp(1) )
  383.             goto bothRight;
  384.         return command(windowPoints[8], 0, w);
  385.  
  386.     /* top line menus and commands */
  387.     case LEFTBUTTON+TOPLINE:
  388.     case RIGHTBUTTON+TOPLINE:
  389.     case BOTHBUTTONS+TOPLINE:
  390.         /* find the shift state of the keyboard */
  391.         rin.h.ah = 2;
  392.         int86(0x16, &rin, &rout);
  393.  
  394.         /* mask of the Ins, Caps, Num, and Scroll states */
  395.         thisShift = rout.h.al & 0xF;
  396.         
  397.         /* adjust for cursor simulation of the mouse */
  398.         if( !mousePresent )
  399.             thisShift = 0x0;
  400.  
  401.         /* fix thisShift so that either shift keys implies shift */
  402.         /* shift over bit1 and OR bit0 with it */
  403.         thisShift = (thisShift>>1) | (thisShift&0x1);
  404.  
  405.         /* get the menu number from the table */
  406.         i = (thisShift<<3) + thisButton;
  407.         n = toplineVector[i];
  408.         
  409.         /* figure out if it is menu or a command */
  410.         menuNumber = CommandToMenuNumber( n );
  411.         
  412.         /* redraw the menu if necessary */
  413.         if( menuNumber != 0 ) {
  414.             /* redraw the correct menu */
  415.             row1 = (menuLine > 0 ? 0 : (scrRows-1) );
  416.             setMap(row1, 0, row1, scrCols-1, 2, 0x07);
  417.             pulldown(menuNumber);
  418.             updateScreen(row1, row1);
  419.             menuShowing = menuNumber;
  420.         }
  421.  
  422.         if( (abs(menuLine) > 1) ) {
  423.             /* execute the command at button release time */
  424.             up2Buttons(&menuRow, &menuCol);
  425.         } else {
  426.             menuRow = curRow;
  427.             menuCol = curCol;
  428.         }
  429.  
  430.         /* if it is a menu, the figure out which item on it */
  431.         if( menuNumber != 0 ) {
  432.             toplineMenu = menuNumber;
  433.             n = FindMenuItem( menuNumber, menuCol );
  434.         }
  435.  
  436.         /* if not still on the menu line, cancel */
  437.         if( (menuLine > 0 && menuRow != 0)
  438.          || (menuLine < 0 && menuRow != (scrRows-1)) ) {
  439.             if( menuNumber == 0 )
  440.                 /* cancel a single command */
  441.                 n = FDONOTHING;
  442.             else
  443.                 /* use the default command for a menu */
  444.                 n = menus[menuNumber]->cmdNumber[0];
  445.         }
  446.  
  447.         w = activeWindow;
  448.  
  449.         /* pass some things command might need */
  450.         passEvhead = evhead;
  451.         passCp = cp;
  452.  
  453.         /* record where to put the menu */
  454.         menuRow = curRow + 1;    /* 1 down from the top line */
  455.         menuCol = curCol;
  456.  
  457.         /* let the general command processor handle it */
  458.         return command(n, 0, w);
  459.  
  460.     /* these are programmed by the user */
  461.     case BOTHBUTTONS+UPPERLEFT:
  462.     bothUpperLeft:
  463.         n = command(windowPoints[1], 0, w);
  464.         waitUp(0);
  465.         return n;
  466.     case BOTHBUTTONS+LOWERLEFT:
  467.     bothLowerLeft:
  468.         n = command(windowPoints[5], 0, w);
  469.         waitUp(0);
  470.         return n;
  471.     case BOTHBUTTONS+UPPERRIGHT:
  472.     bothUpperRight:
  473.         n = command(windowPoints[3], 0, w);
  474.         waitUp(0);
  475.         return n;
  476.     case BOTHBUTTONS+LOWERRIGHT:
  477.     bothLowerRight:
  478.         n = command(windowPoints[7], 0, w);
  479.         waitUp(0);
  480.         return n;
  481.  
  482.     noAction:
  483.         /* wait for buttons up */
  484.         up2Buttons(&n, &n);
  485.         msg("No action is defined for that mouse button", 1);
  486.         break;
  487.     default:
  488.         ;    /* ignore no button events */
  489.     }
  490.  
  491.     return 0;
  492. }
  493.  
  494.  
  495. int pascal
  496. /* XTAG:ScrollSomeMore */
  497. ScrollSomeMore() {
  498.     extern int smoothScroll;
  499.     extern union REGS rin, rout;
  500.     extern int mousePresent;
  501.     extern int scrollRate;
  502.  
  503.     int timeBegin, timeEnd, hsecElapsed;
  504.  
  505.     /* if there is no button up then keep scrolling */
  506.     if( smoothScroll && mousePresent ) {
  507.         timeBegin = GetTime();
  508.         while( 1 ) {
  509.             /* if the mouse moves, stop scrolling */
  510.             if( isMouseEvent(1) )
  511.                 return 0;
  512.             /* get the current button state */
  513.             rin.x.ax = 3;
  514.             int86(51, &rin, &rout);
  515.             /* if the buttons are up, stop scrolling */
  516.             if( (rout.x.bx & 0x7) == 0 )    /* all buttons up */
  517.                 return 0;
  518.             timeEnd = GetTime();
  519.             hsecElapsed = timeEnd - timeBegin;
  520.             /* if overflow add 60sec = 6000hsec */
  521.             if( hsecElapsed < 0 )
  522.                 hsecElapsed += 6000;
  523.             /* if enough time has passed, scroll again */
  524.             if( hsecToWait < hsecElapsed ) {
  525.                 /* reset wait time to repeat rate */
  526.                 hsecToWait = scrollRate;
  527.                 return 1;
  528.             }
  529.         }
  530.     } else
  531.         return 0;
  532. }
  533.  
  534.  
  535. int pascal
  536. /* XTAG:waitUp */
  537. waitUp(twoButtons)
  538.     int twoButtons;
  539. {
  540.     extern struct event events[];
  541.  
  542.     register int evhead;
  543.  
  544.     while( 1 ) {
  545.         while( !isMouseEvent(1) )
  546.             ;    /* wait for a mouse event */
  547.         evhead = getMouseEvent();
  548.         switch( events[evhead].buttons ) {
  549.             /* return 0 if the buttons are all up */
  550.             case 0:
  551.                 return 0;
  552.             /* keep waiting if only one button is down */
  553.             case 1:
  554.             case 2:
  555.             case 4:
  556.                 break;
  557.             /* return 1 if more than one button is down */
  558.             default:
  559.                 if( twoButtons )
  560.                     return 1;
  561.                 break;
  562.         }
  563.     }
  564. }
  565.