home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / commodities / newedit / hook.c < prev    next >
C/C++ Source or Header  |  1992-09-24  |  11KB  |  287 lines

  1. /*----------------------------------------------------------------------------
  2.    File   :    Hook.c
  3.    Projekt:    NewEdit
  4.    Inhalt :    next_word()
  5.                prev_word()
  6.                string_hook()
  7.  
  8.    Version:    1.5
  9.    Datum  :    18. August 1992
  10.  
  11.    Autor  :    Uwe Röhm
  12.    Adresse:    Auber Str. 25,  W-6209 Hohenstein 4
  13.     (Semester) Wörthstr. 18    W-8390 Passau
  14.    Bemerkung:
  15.    Neue globale String-Hook, die verschiedene Cursorfunktionen, Abbruch per
  16.    ESC-Taste und vorallem Copy und Paste per Clipboard unterstuetzt!
  17.    Benoetigt Funktionen aus ClipBoard.c!!!!
  18. ----------------------------------------------------------------------------*/
  19. #include <intuition/sghooks.h>
  20. #include <intuition/intuition.h>
  21. #include <devices/inputevent.h>
  22. #include <exec/semaphores.h>
  23.  
  24. /* ------------------------  Prototypes & Pragmas  ------------------------ */
  25. #include <clib/exec_protos.h>
  26. #include <clib/utility_protos.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29. #ifdef LATTICE
  30.    #include <pragmas/exec_pragmas.h>
  31.    #include <pragmas/utility_pragmas.h>
  32. #endif
  33.  
  34. /* -------------------------  externe Funktionen  ------------------------- */
  35. extern ULONG read_clip ( UBYTE *, ULONG );
  36. extern void  write_clip( UBYTE *, ULONG );
  37.  
  38. /* ---------------------------  eigene Defines  --------------------------- */
  39. #define IECODE_UNUSED    0
  40. #define IECODE_C         51
  41. #define IECODE_V         52
  42. #define IECODE_RETURN    68
  43. #define IECODE_ESC       69
  44. #define IECODE_BACKSP    65
  45. #define IECODE_DEL       70
  46. #define IECODE_CRSRUP    76
  47. #define IECODE_CRSRDWN   77
  48. #define IECODE_CRSRRIGHT 78
  49. #define IECODE_CRSRLEFT  79
  50. #define IECODE_HELP      95
  51. #ifndef SGA_NEXTACTIVE
  52. #define SGA_NEXTACTIVE    (0x20L)    /* Make next possible gadget active.    */
  53. #define SGA_PREVACTIVE    (0x40L)    /* Make previous possible gadget active.*/
  54. #endif
  55.  
  56. /* ----------------------------  globale Vars  ---------------------------- */
  57. extern struct Library *SysBase;
  58. extern struct Library *DOSBase;
  59. extern struct Library *UtilityBase;
  60. extern struct Hook    *OldHook;
  61. extern char           *SemaphoreName;
  62. extern struct SignalSemaphore *Sem;
  63. extern BOOL            Disabled;
  64.  
  65. /*
  66.  *    Zwei kleine Hilfsfunktionen für die Stringhook unten
  67.  *    zum Bewegen/Loeschen im Stinggadget
  68.  */
  69. LONG next_word ( UBYTE *buffer, LONG pos, LONG max )
  70. {
  71.    while ( pos < max && !isspace(buffer[ pos ]))
  72.       pos++;
  73.    while ( pos < max && isspace(buffer[ pos ]))
  74.       pos++;
  75.    return pos;
  76. }
  77.  
  78. LONG prev_word ( UBYTE *buffer, LONG pos )
  79. {
  80.    while ( pos > 0 && isspace(buffer[ pos - 1 ]))
  81.       pos--;
  82.    while ( pos > 0 && !isspace(buffer[ pos - 1 ]))
  83.       pos--;
  84.    return pos;
  85. }
  86.  
  87. /****** string_hook() *******************************************************
  88. *
  89. *   NAME
  90. *        string_hook -- general EditHook for Gadtools Stringgadgets
  91. *   SYNOPSIS
  92. *        Known = string_hook ( Hook, Object, Message )
  93. *        D0                    A0    A2      A1
  94. *        ULONG   string_hook ( struct Hook *, struct SGWork *, APTR * );
  95. *   FUNCTION
  96. *        Normally set as new global Hook with SetEditHook().
  97. *        The following functions will be supported:
  98. *        SHIFT CURSOR RIGHT  next word
  99. *        SHIFT CURSOR LEFT   previous word
  100. *        ALT BACKSPACE       delete previous word
  101. *        ALT DEL             delete next word
  102. *        RALT CURSOR UP      go to prev gadget (with GADGETUP)
  103. *        RALT CURSOR DOWN    go to next gadget (with GADGETUP)
  104. *        ESC                 leave gadget (with GADGETUP)
  105. *        RCommand C          copy gadget contents to clipboard 0
  106. *        RCommand V          paste contents of clip 0 to gadget
  107. *        sgw->EditOp will be set to EO_BIGCHANGE, if some text has been
  108. *        deleted or inserted from the clipboard.
  109. *        sgw->IEvent->ie_Code will be motified to 0x00 if we moved to the
  110. *        next/previous word/gadget or if AMIGA-C or AMIGA-V was pressed. The
  111. *        keycode 0 is unused by the system and therefor will be ignored by
  112. *        further stringhooks.
  113. *   INPUTS
  114. *        Hook   - pointer to own hook-structure
  115. *        Object - struct SGWork for Stringgadgets
  116. *        Message- ???
  117. *   RESULT
  118. *        ~0 - command supported, else 0
  119. *        sgw->EditOp and sgw->IEvent->ie_Code may be motified (see above)
  120. *   DATE
  121. *        18. April 1992
  122. *****************************************************************************
  123. */
  124. ULONG __saveds __asm  string_hook( register __a0 struct Hook   *hook,
  125.                                    register __a2 struct SGWork *sgw,
  126.                                    register __a1 unsigned long *msg  )
  127. {
  128.    struct InputEvent *ie;
  129.    ULONG              length;
  130.    ULONG              return_code = ~0;
  131.  
  132.    /*
  133.     *    Einen shared Lock auf die Semaphore.
  134.     *    Damit können theoretisch mehrere Stringhooks gleichzeitig
  135.     *    aktiviert sein. Das Hauptprogramm kann aber keinen exklusiven
  136.     *    Lock bekommen, solange auch nur ein shared Lock noch aktiv ist.
  137.     */
  138.    ObtainSemaphoreShared( Sem );
  139.  
  140.    if ( *msg == SGH_KEY )
  141.    {
  142.       /*
  143.        *    Zuerst abfragen, ob NewEdit momentan disabled ist
  144.        */
  145.       if ( !Disabled )
  146.       {
  147.          ie = sgw->IEvent;
  148.          if ( ie->ie_Class == IECLASS_RAWKEY )
  149.          {
  150.             switch (ie->ie_Code)
  151.             {
  152.  
  153.                case IECODE_ESC:
  154.                   sgw->Actions |= SGA_END;
  155.                   break;
  156.  
  157.                case IECODE_CRSRUP:
  158.                   if ( ie->ie_Qualifier & IEQUALIFIER_RALT )
  159.                   {
  160.                      sgw->Actions |= SGA_PREVACTIVE | SGA_END;
  161.                      ie->ie_Code   = IECODE_UNUSED;
  162.  
  163.                   } /* if IEQUALIFIER_RSHIFT */
  164.                   break;
  165.  
  166.                case IECODE_CRSRDWN:
  167.                   if ( ie->ie_Qualifier & IEQUALIFIER_RALT )
  168.                   {
  169.                      sgw->Actions |= SGA_NEXTACTIVE | SGA_END;
  170.                      ie->ie_Code   = IECODE_UNUSED;
  171.  
  172.                   } /* if IEQUALIFIER_RSHIFT */
  173.                   break;
  174.  
  175.                case IECODE_CRSRRIGHT:
  176.                   if ( ie->ie_Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) )
  177.                   {
  178.                      sgw->BufferPos= next_word( sgw->WorkBuffer, sgw->BufferPos, sgw->StringInfo->NumChars );
  179.                      ie->ie_Code   = IECODE_UNUSED;
  180.                      sgw->Actions |= SGA_REDISPLAY;
  181.  
  182.                   } /* if IEQUALIFIER_LALT */
  183.                   break;
  184.  
  185.                case IECODE_CRSRLEFT:
  186.                   if ( ie->ie_Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) )
  187.                   {
  188.                      sgw->BufferPos= prev_word ( sgw->WorkBuffer, sgw->BufferPos );
  189.                      ie->ie_Code   = IECODE_UNUSED;
  190.                      sgw->Actions |= SGA_REDISPLAY;
  191.  
  192.                   } /* if IEQUALIFIER_LALT */
  193.                   break;
  194.  
  195.                case IECODE_BACKSP:
  196.                   if ( ie->ie_Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) )
  197.                   {
  198.                      sgw->BufferPos = prev_word ( sgw->WorkBuffer, sgw->BufferPos ) + 1;
  199.                      if ( sgw->BufferPos < sgw->StringInfo->BufferPos )
  200.                         strcpy ( &sgw->WorkBuffer[ sgw->BufferPos ], &sgw->WorkBuffer[ sgw->StringInfo->BufferPos ] );
  201.                      sgw->Actions |= SGA_REDISPLAY;
  202.                      sgw->EditOp   = EO_BIGCHANGE;
  203.  
  204.                   } /* if IEQUALIFIER_LALT */
  205.                   break;
  206.  
  207.                case IECODE_DEL:
  208.                   if ( ie->ie_Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) )
  209.                   {
  210.                      length = next_word( sgw->WorkBuffer, sgw->BufferPos, sgw->StringInfo->NumChars );
  211.                      strcpy ( &sgw->WorkBuffer[ sgw->BufferPos + 1 ], &sgw->WorkBuffer[ length ] );
  212.                      sgw->Actions |= SGA_REDISPLAY;
  213.                      sgw->EditOp   = EO_BIGCHANGE;
  214.  
  215.                   } /* if IEQUALIFIER_LALT */
  216.                   break;
  217.  
  218.                default:
  219.                   /* Test, ob rechte Amiga-Taste gedrueckt wurde */
  220.                   if (ie->ie_Qualifier & IEQUALIFIER_RCOMMAND)
  221.                   {
  222.                      /* RCommand zusammen mit V: Paste from Clipboard */
  223.                      if ( ie->ie_Code == IECODE_V )
  224.                      {
  225.                         /*
  226.                          * Inhalt des Clipboards an die aktuelle Cursorposition
  227.                          * einlesen. Dazu wird zuerst alles hinter dem Cursor an
  228.                          * das Bufferende kopiert und nach dem Einfügen zurueck-
  229.                          * geschoben.
  230.                          */
  231.                         WORD  maxchars;
  232.                         WORD  pos;
  233.  
  234.                         maxchars = sgw->StringInfo->MaxChars - 1;
  235.                         pos      = sgw->NumChars;
  236.                         while ( --pos >= sgw->BufferPos )
  237.                            sgw->WorkBuffer[ maxchars - sgw->NumChars + pos ] = sgw->WorkBuffer[ pos ];
  238.                         length = read_clip ( &sgw->WorkBuffer[sgw->BufferPos], maxchars - sgw->NumChars );
  239.                         if ( length > 0 )
  240.                         {
  241.                            strcpy ( &sgw->WorkBuffer[ sgw->BufferPos + length ],
  242.                                     &sgw->WorkBuffer[ maxchars - sgw->NumChars + sgw->BufferPos ] );
  243.  
  244.                            sgw->BufferPos += length;
  245.                            sgw->NumChars  += length;
  246.  
  247.                         } /* if length > 0 */
  248.                         else
  249.                            sgw->Actions |= SGA_BEEP;
  250.  
  251.                         sgw->EditOp = EO_BIGCHANGE;
  252.                         sgw->Code   = IECODE_UNUSED; /* aktuelle Taste auf No-Op umbiegen!! */
  253.  
  254.                      } /* if IECODE_V */
  255.  
  256.                      /* RCommand zusammen mit C: Copy into Clipboard */
  257.                      else if ( ie->ie_Code == IECODE_C )
  258.                      {
  259.                         write_clip ( sgw->StringInfo->Buffer, sgw->NumChars );
  260.                         sgw->Code = IECODE_UNUSED; /* aktuelle Taste auf No-Op umbiegen!! */
  261.  
  262.                      } /* if IECODE_C */
  263.  
  264.                   } /* if IEQUALIFIER_RCOMMAND */
  265.                   break;
  266.  
  267.             } /* switch */
  268.  
  269.          } /* else EditOp */
  270.  
  271.       } /* if !Disabled */
  272.  
  273.       /*
  274.        *    Die originale Edithook von Intuition aufrufen, damit
  275.        *    das Stringgadget auch korrekt refreshed wird.
  276.        */
  277.       CallHookPkt( OldHook, (APTR) sgw, msg);
  278.  
  279.    } /* if SGH_KEY */
  280.    else
  281.       return_code = 0;
  282.  
  283.    ReleaseSemaphore( Sem );
  284.  
  285.    return return_code;
  286. }
  287.