home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / comm / term33so.lha / termStringHook.c < prev    next >
C/C++ Source or Header  |  1993-04-30  |  9KB  |  421 lines

  1. /*
  2. **    termStringHook.c
  3. **
  4. **    Custom string gadget editing hook routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Partial gadget support information. */
  13.  
  14. struct PartialGadgetSupportInfo
  15. {
  16.     STRPTR    Original,    /* Password string entry, original contents (for undo). */
  17.         Buffer;        /* Password string entry, current contents. */
  18. };
  19.  
  20.     /* CommandKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
  21.      *
  22.      *    This routine is called whenever input passes through
  23.      *    a `term' string gadget. It releases the currently
  24.      *    active string gadget as soon as the Right-Amiga-key is
  25.      *    pressed (user is about to select a menu item).
  26.      */
  27.  
  28. ULONG __saveds
  29. CommandKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg)
  30. {
  31.     if(*Msg == SGH_KEY)
  32.     {
  33.         if(Work -> EditOp == EO_INSERTCHAR || Work -> EditOp == EO_REPLACECHAR)
  34.         {
  35.                 /* This looks like a built-in command. */
  36.  
  37.             if(Work -> IEvent -> ie_Qualifier & IEQUALIFIER_RCOMMAND)
  38.             {
  39.                     /* Amiga+C = Copy contents of string
  40.                      *           gadget to the clipboard.
  41.                      */
  42.  
  43.                 if(Work -> Code == 'c')
  44.                 {
  45.                     Work -> Actions &= ~SGA_USE;
  46.                     Work -> Actions |= SGA_BEEP;
  47.  
  48.                         /* Valid buffer contents? */
  49.  
  50.                     if(Work -> PrevBuffer[0])
  51.                     {
  52.                         struct MsgPort *ReplyPort;
  53.  
  54.                             /* Post a message... */
  55.  
  56.                         if(ReplyPort = CreateMsgPort())
  57.                         {
  58.                             struct Message ClipMessage;
  59.  
  60.                             ClipMessage . mn_Node . ln_Name    = Work -> PrevBuffer;
  61.                             ClipMessage . mn_ReplyPort    = ReplyPort;
  62.                             ClipMessage . mn_Length        = sizeof(struct Message);
  63.  
  64.                             PutMsg(ClipPort,&ClipMessage);
  65.  
  66.                             WaitPort(ReplyPort);
  67.  
  68.                             GetMsg(ReplyPort);
  69.  
  70.                             DeleteMsgPort(ReplyPort);
  71.  
  72.                             Work -> Actions &= ~SGA_BEEP;
  73.                         }
  74.                     }
  75.  
  76.                     return(1);
  77.                 }
  78.  
  79.                     /* Amiga+V = Insert current clipboard
  80.                      *           contents at cursor position.
  81.                      */
  82.  
  83.                 if(Work -> Code == 'v')
  84.                 {
  85.                     Work -> Actions &= ~SGA_USE;
  86.                     Work -> Actions |= SGA_BEEP;
  87.  
  88.                         /* Don't paste to integer gadgets
  89.                          * (it could confuse Intuition if
  90.                          *  the buffer contained non-numeric
  91.                          *  symbols...).
  92.                          */
  93.  
  94.                     if(!(Work -> Gadget -> Activation & GACT_LONGINT))
  95.                     {
  96.                         struct MsgPort *ReplyPort;
  97.  
  98.                             /* Post a message... */
  99.  
  100.                         if(ReplyPort = CreateMsgPort())
  101.                         {
  102.                             STATIC UBYTE    Buffer[2048];
  103.                             struct Message    ClipMessage;
  104.  
  105.                             Buffer[0] = 0;
  106.  
  107.                             ClipMessage . mn_Node . ln_Name    = Buffer;
  108.                             ClipMessage . mn_ReplyPort    = ReplyPort;
  109.                             ClipMessage . mn_Length        = sizeof(struct Message);
  110.  
  111.                             PutMsg(ClipPort,&ClipMessage);
  112.  
  113.                             WaitPort(ReplyPort);
  114.  
  115.                             GetMsg(ReplyPort);
  116.  
  117.                             DeleteMsgPort(ReplyPort);
  118.  
  119.                                 /* Anything in the buffer? */
  120.  
  121.                             if(Buffer[0])
  122.                             {
  123.                                 WORD Len = strlen(Buffer);
  124.  
  125.                                     /* Insert as many characters as we can. */
  126.  
  127.                                 while(Len > 0 && Work -> NumChars + Len > Work -> StringInfo -> MaxChars)
  128.                                     Len--;
  129.  
  130.                                     /* Any characters left? */
  131.  
  132.                                 if(Len > 0)
  133.                                 {
  134.                                     STATIC UBYTE OtherBuffer[2048];
  135.  
  136.                                         /* Provide null-termination. */
  137.  
  138.                                     Buffer[Len] = 0;
  139.  
  140.                                         /* Set up undo buffer correctly. */
  141.  
  142.                                     if(Work -> StringInfo -> UndoBuffer)
  143.                                         strcpy(Work -> StringInfo -> UndoBuffer,Work -> PrevBuffer);
  144.  
  145.                                     Work -> StringInfo -> UndoPos = --Work -> BufferPos;
  146.  
  147.                                         /* Save the characters before the cursor. */
  148.  
  149.                                     if(Work -> BufferPos)
  150.                                         CopyMem(Work -> PrevBuffer,OtherBuffer,Work -> BufferPos);
  151.  
  152.                                         /* Provide null-termination. */
  153.  
  154.                                     OtherBuffer[Work -> BufferPos] = 0;
  155.  
  156.                                         /* Append the clipboard data. */
  157.  
  158.                                     strcat(OtherBuffer,Buffer);
  159.  
  160.                                         /* Append the characters following the cursor. */
  161.  
  162.                                     strcat(OtherBuffer,&Work -> PrevBuffer[Work -> BufferPos]);
  163.  
  164.                                         /* = new work buffer. */
  165.  
  166.                                     strcpy(Work -> WorkBuffer,OtherBuffer);
  167.  
  168.                                         /* Fiddle with some cursor data. */
  169.  
  170.                                     Work -> BufferPos    += Len;
  171.                                     Work -> NumChars    += Len;
  172.  
  173.                                         /* And that's it... */
  174.  
  175.                                     Work -> Actions    |= SGA_USE;
  176.                                     Work -> EditOp     = EO_BIGCHANGE;
  177.  
  178.                                     Work -> Actions &= ~SGA_BEEP;
  179.                                 }
  180.                             }
  181.                             else
  182.                                 Work -> Actions &= ~SGA_BEEP;
  183.                         }
  184.                     }
  185.  
  186.                     return(1);
  187.                 }
  188.             }
  189.  
  190.                 /* Release the gadget in case a menu item is to be selected. */
  191.  
  192.             if((Work -> IEvent -> ie_Qualifier & AMIGARIGHT) && Work -> IEvent -> ie_Code < 96)
  193.             {
  194.                 if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) && (Work -> IEvent -> ie_Code == KEYCODE_X || Work -> IEvent -> ie_Code == KEYCODE_Q))
  195.                     return(1);
  196.                 else
  197.                 {
  198.                     Work -> Actions |= (SGA_END|SGA_REUSE);
  199.                     Work -> Actions &= ~(SGA_USE|SGA_BEEP);
  200.  
  201.                     CommandWindow = Work -> GadgetInfo -> gi_Window;
  202.                     CommandGadget = Work -> Gadget;
  203.                 }
  204.             }
  205.         }
  206.  
  207.             /* The user pressed the cursor-right key to
  208.              * move the cursor to the next word in the buffer.
  209.              */
  210.  
  211.         if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  212.         {
  213.             if(Work -> BufferPos != Work -> NumChars)
  214.             {
  215.                 WORD i,Position = -1;
  216.  
  217.                 for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
  218.                 {
  219.                     if(Work -> WorkBuffer[i] == ' ')
  220.                     {
  221.                         for( ; i < Work -> NumChars ; i++)
  222.                         {
  223.                             if(Work -> WorkBuffer[i] != ' ')
  224.                             {
  225.                                 Position = i;
  226.                                 break;
  227.                             }
  228.                         }
  229.  
  230.                         break;
  231.                     }
  232.                 }
  233.  
  234.                 if(Position != -1)
  235.                     Work -> BufferPos = Position;
  236.                 else
  237.                     Work -> BufferPos = Work -> NumChars;
  238.  
  239.                 Work -> EditOp = EO_MOVECURSOR;
  240.             }
  241.         }
  242.  
  243.             /* The user pressed the cursor-right key to
  244.              * move the cursor to the previous word in the buffer.
  245.              */
  246.  
  247.         if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  248.         {
  249.             if(Work -> BufferPos)
  250.             {
  251.                 WORD i,Position = -1;
  252.  
  253.                 for(i = Work -> BufferPos ; i >= 0 ; i--)
  254.                 {
  255.                     if(Work -> WorkBuffer[i] != ' ')
  256.                     {
  257.                         Position = i;
  258.                         break;
  259.                     }
  260.                 }
  261.  
  262.                 if(Position == -1)
  263.                     Position = 0;
  264.  
  265.                 if(Position)
  266.                 {
  267.                     i = Position;
  268.  
  269.                     Position = -1;
  270.  
  271.                     for( ; i >= 0 ; i--)
  272.                     {
  273.                         if(Work -> WorkBuffer[i] == ' ')
  274.                         {
  275.                             Position = i + 1;
  276.                             break;
  277.                         }
  278.                     }
  279.                 }
  280.  
  281.                 if(Position != -1)
  282.                     Work -> BufferPos = Position;
  283.                 else
  284.                     Work -> BufferPos = 0;
  285.  
  286.                 Work -> EditOp = EO_MOVECURSOR;
  287.             }
  288.         }
  289.  
  290.         return(1);
  291.     }
  292.     else
  293.     {
  294.         if(*Msg == SGH_CLICK)
  295.             return(1);
  296.         else
  297.             return(0);
  298.     }
  299. }
  300.  
  301.     /* PasswordKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
  302.      *
  303.      *    Editing code for a password-entry string gadget. Credits for
  304.      *    the original implementation go to Hans-Joachim Widmaier.
  305.      */
  306.  
  307. ULONG __saveds
  308. PasswordKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg)
  309. {
  310.     struct PartialGadgetSupportInfo    *Info = (struct PartialGadgetSupportInfo *)Work -> Gadget -> UserData;
  311.     LONG                 Len;
  312.  
  313.     switch(*Msg)
  314.     {
  315.             /* Some key was pressed. */
  316.  
  317.         case SGH_KEY:
  318.  
  319.             switch(Work -> EditOp)
  320.             {
  321.                     /* Entered another character. */
  322.  
  323.                 case EO_INSERTCHAR:
  324.  
  325.                     Info -> Buffer[Work -> BufferPos - 1]        = Work -> Code;
  326.                     Info -> Buffer[Work -> NumChars]        = 0;
  327.  
  328.                     Work -> Code = '*';
  329.                     Work -> WorkBuffer[Work -> BufferPos - 1]    = '*';
  330.  
  331.                     break;
  332.  
  333.                     /* Undo changes. */
  334.  
  335.                 case EO_RESET:
  336.  
  337.                     Len = strlen(Info -> Original);
  338.  
  339.                     strcpy(Info -> Buffer,Info -> Original);
  340.  
  341.                     memset(Work -> WorkBuffer,'*',Len);
  342.  
  343.                     Work -> WorkBuffer[Len] = 0;
  344.  
  345.                     Work -> NumChars    = Len;
  346.                     Work -> BufferPos    = Len;
  347.                     Work -> EditOp         = EO_BIGCHANGE;
  348.  
  349.                     break;
  350.  
  351.                     /* Clear the gadget. */
  352.  
  353.                 case EO_CLEAR:
  354.  
  355.                     Work -> WorkBuffer[0]    = 0;
  356.                     Work -> NumChars    = 0;
  357.                     Work -> BufferPos    = 0;
  358.                     Work -> EditOp         = EO_BIGCHANGE;
  359.  
  360.                     Info -> Buffer[0]    = 0;
  361.  
  362.                     break;
  363.  
  364.                     /* Deleted the last character. */
  365.  
  366.                 case EO_DELBACKWARD:
  367.  
  368.                     Info -> Buffer[Work -> NumChars] = 0;
  369.                     break;
  370.  
  371.                     /* Default. */
  372.  
  373.                 case EO_NOOP:
  374.  
  375.                     break;
  376.  
  377.                     /* Terminate input. */
  378.  
  379.                 case EO_ENTER:
  380.  
  381.                     strcpy(Info -> Original,Info -> Buffer);
  382.                     break;
  383.  
  384.                     /* Don't move the cursor or try to
  385.                      * delete from the middle of the string.
  386.                      */
  387.  
  388.                 case EO_MOVECURSOR:
  389.                 case EO_DELFORWARD:
  390.  
  391.                     Work -> Actions &= ~SGA_USE;
  392.                     break;
  393.  
  394.                     /* Reject the rest. */
  395.  
  396.                 default:
  397.  
  398.                     Work -> Actions &= ~SGA_USE;
  399.                     Work -> Actions    |= SGA_BEEP;
  400.                     break;
  401.             }
  402.  
  403.             return(1);
  404.  
  405.             /* Clicking inside the box sets up the defaults. */
  406.  
  407.         case SGH_CLICK:
  408.  
  409.             Work -> BufferPos    = Work -> NumChars;
  410.             Work -> EditOp         = EO_BIGCHANGE;
  411.  
  412.             return(1);
  413.  
  414.             /* Reject the rest. */
  415.  
  416.         default:
  417.  
  418.             return(0);
  419.     }
  420. }
  421.