API Reference | developer.brewmp.com API Reference | developer.brewmp.com

Developer

API Reference

AEECLSID_POINTERLOG

Brew Release
Brew MP 1.0.2
See Also
IPort1, Pointer events, std_letohs, std_letohl, ISignal, ISignalHandler, ISignalFactory, ISignalCtl
Description
The PointerLog class provides a way to listen for EVT_POINTER events. When EVT_POINTER events are delivered to applications, they are also logged through the PointerLog class to any other interested application or extension. The following events are logged through this class: - EVT_POINTER_DOWN
- EVT_POINTER_UP
- EVT_POINTER_MOVE
- EVT_POINTER_STALE_MOVE
- EVT_LBUTTON_DOWN (same event code as EVT_POINTER_DOWN)
- EVT_LBUTTON_UP (same event code as EVT_POINTER_UP)
- EVT_MBUTTON_DOWN
- EVT_MBUTTON_UP
- EVT_RBUTTON_DOWN
- EVT_RBUTTON_UP
- EVT_XBUTTON_DOWN
- EVT_XBUTTON_UP
- EVT_POINTER_POS
- EVT_POINTER_STALE_POS
- EVT_MOUSE_HSCROLL
- EVT_MOUSE_VSCROLL

Any new pointer or mouse events added in the future will also be logged through this class. The PointerLog class implements the IPort1 interface. The application gets back an IPort1 instance when this class is created. The application can then use IPort1_Readable and IPort1_Read to get pointer event data.
This is a privileged class. AEECLSID_PointerLog is also a privilege. An application using this class needs to have AEECLSID_PointerLog as a privilege.
The format of the message log for each pointer event is described below:
   -------------------------------------------------------------------------------
   + Message Length + Timestamp +   clsID   +  eCode     + wParam    + dwParam   +
   + (4 bytes)      + (4 bytes) + (4 bytes) +  (2 bytes) + (2 bytes) + (variable +   
   +                +           +           +            +           + length)   +
   -------------------------------------------------------------------------------

- Message Length: Length of entire message, including the length field
(4 bytes - little endian) - Timestamp: The time reference value at which the corresponding EVT_POINTER
event was delivered to an application (4 bytes - little endian) - ClsID: Class ID of the application to which event was delivered
(4 bytes - little endian) - eCode: The event code of the event. This will be one of the EVT_POINTER
EVT_LBUTTON, EVT_MBUTTON, EVT_RBUTTON, EVT_XBUTTON, EVT_MOUSE events (2 bytes - little endian) - wParam: The size of dwParam string including NUL terminator
(2 bytes - little endian) - dwParam: The actual NUL terminated single byte character string payload
representing information about pointing device (variable length). This is the same payload that is sent as dwParam with EVT_POINTER events. Refer to the EVT_POINTER events description in AEEEvent.h for an explanation of the string format.
To stay endianness clean, use std_letohs / std_letohl and other endian conversion functions to convert numeric values above from little endian to host endian order. For little endian architectures, this will be a no-op.
A separate log buffer is created for each instance of AEECLSID_PointerLog. If the log buffer fills up, new pointer events will be dropped until space is created in the log buffer by reading from the log. It is possible to retrieve or change the log buffer size by using AEEUID_PointerLog_BufferSize in IPort1_Control. It is also possible to flush out the current data in the log buffer by using AEEUID_PointerLog_FlushData in IPort1_Control.
A typical usage scenario for AEECLSID_PointerLog would look like this:


   // In App initialization function

   #define STREAMPOS_BEGINNING 1
   #define STREAMPOS_NLEN_READ 2
   #define STREAMPOS_PARTIAL_MSG 3

   App *me;

   //
   ... Code to create ISignalCtl/ISignal and set the signal callback to
   ... App_SignalCB (See AEEISignal.h, AEEISignalFactory.h, 
   ... AEEISignalHandler.h)
   //

   if( AEE_SUCCESS != IEnv_CreateInstance(piEnv, AEECLSID_PointerLog,
                          (void **)&me->piPointerLog)) {
      // Handle error
   } 
   
   IPort1_Readable(me->piPointerLog, me->piSignal);

   me->nStreamPos = STREAMPOS_BEGINNING;
   me->buffer = 0;
   me->nCachedLen = 0;
   me->nLenRead = 0;
   ....
   .... Other initialization

 
   // Callback function called when Readable signal is set
   // Error handling is not completely shown for clarity

   void App_SignalCB(App *me) 
   {
      int nErr;
      uint32 nLen, nLenRead;
      uint32 dwTimeStamp;
      AEECLSID cls;
      AEEEvent eCode;
      uint16 wParam;
      const char *dwParam;
      byte *buffer;
      byte *bCurr;

      // Read all logged events from pipe
      while(1) {
         if(STREAMPOS_BEGINNING == me->nStreamPos) {
            // Read the length
            nErr = IPort1_Read(me->piPointerLog, (byte *)&nLen, sizeof(uint32), NULL);
   
            if(AEE_SUCCESS != nErr) {
               if(AEE_EWOULDBLOCK == nErr) {
                  ISignalCtl_Enable(me->piSignalCtl);
                  return;
               } else {
                  // Handle other errors
               }
            }
         
            // Convert from little endian to host order
            nLen = (uint32)std_letohl(nLen);
   
            // nLen includes size of nLen field itself, subtract that
            nLen -= sizeof(uint32); 
   
            buffer = MALLOC(nLen);
   
            if(!buffer) {
   	         // Handle no memory condition
            }
            me->nStreamPos = STREAMPOS_NLEN_READ;
            me->nCachedLen = nLen;
            me->buffer = buffer;
         }
   
   
         // Read the remaining message
         if (STREAMPOS_NLEN_READ == me->nStreamPos) {
            bCurr = me->buffer;
         } else {
            // STREAMPOS_PARTIAL_MSG - set bCurr to the correct
            // read position beyond what has already been read
            bCurr = me->buffer + me->nLenRead;
            nLen = me->nCachedLen - me->nLenRead;
         }
   
         nErr = IPort1_Read(me->piPointerLog, bCurr, nLen, &nLenRead);
         if(AEE_SUCCESS != nErr) {
            if(AEE_EWOULDBLOCK == nErr) {
               ISignalCtl_Enable(me->piSignalCtl);
               return;
            } else {
                 // Handle other errors
            }
         }
   
         // Partial read - maintain buffer position, reenable signal
         if(nLen != nLenRead) {
            me->nStreamPos = STREAMPOS_PARTIAL_MSG;
            me->nLenRead += nLenRead;
            ISignalCtl_Enable(me->piSignalCtl);
            return;
         } 
   
         // The entire message has been read at this point - proceed
         // to parse it
         bCurr = me->buffer;
   
         // Read timestamp at which event was delivered
         dwTimeStamp = (uint32)std_letohl(*(unsigned long *)bCurr);
         
         bCurr += sizeof(uint32);
   
         // Read class ID of app to which event was delivered
         cls = (AEECLSID)std_letohl(*(unsigned long *)bCurr);
         
         bCurr += sizeof(AEECLSID);
   
         // Read the eCode (will be one of the EVT_POINTER events)
         eCode = (AEEEvent)std_letohs(*(unsigned short *)bCurr);
   
         bCurr += sizeof(AEEEvent);
   
         // Read the wParam (length of dwParam string for pointer events)
         wParam = (uint16)std_letohs(*(unsigned short *)bCurr);
   
         bCurr += sizeof(uint16);
   
         // Read dwParam (the actual dwParam string
         dwParam = (const char *)bCurr;
   
   
         // Event is now captured, do actual processing...
         // Refer to AEEPointerHelpers.h for parsing the dwParam string
         // payload

         // Go on to read next event (top of while loop)
   
      } // end while(1)

      // Free buffer once done - also reset bookkeeping variables
      FREE(me->buffer); 
      me->buffer = 0;
      me->nStreamPos = STREAMPOS_BEGINNING;
      me->nCachedLen = 0;
      me->nLenRead = 0;   

  
     // Re-enable signal for future messages
     ISignalCtl_Enable(me->piSignalCtl);
   }
   

Default Interface Name