Click here to show toolbars of the Web Online Help System: show toolbars |
/********************************************************************************/ /* * File name: cameraevents.cpp * Location: See Matrox Example Launcher in the MIL Control Center * * * Synopsis: This program demonstrates new MIL features for managing GenICam(c) * devices. This program focuses on hooking a MIL handler to asynchronous * camera events. * */ /* Headers. */ #include <mil.h> #if M_MIL_USE_WINDOWS #include <windows.h> #endif #if M_MIL_UNICODE_API #define MosStrncmp wcsncmp #else #define MosStrncmp strncmp #endif typedef struct { MIL_ID MilDigitizer; MIL_ID MilImageDisp; MIL_INT ProcessedImageCount; MIL_TEXT_PTR* Events; MIL_INT EventCount; MIL_DOUBLE TimeStamp; } HookDataStruct; /* Gets and prints the events supported by the camera. */ void GetCameraEventControls(MIL_ID MilDigitizer, MIL_INT& SupportedEventCount, MIL_TEXT_PTR** Events, bool& StandardEventEnable); /* Hooks a MIL function callback to camera events. */ void HookToEvent(MIL_ID MilDigitizer, MIL_TEXT_PTR Event, void* HookDataPtr, bool StandardEventEnable, MIL_INT Unhook = 0); /* Does a lookup of the event name that triggered the callback. */ void EventTypeLookUp(MIL_ID MilDigitizer, MIL_ID HookId, HookDataStruct* HookDataPtr); /* Starts image acquisition. */ void DoAcquisition(MIL_ID MilSystem, MIL_ID MilDigitizer, MIL_ID MilImageDisp); /* User's processing function prototype. */ MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr); /* User's callback function prototype. Called when a camera event fires. */ MIL_INT MFTYPE CameraEventHandler(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr); /* Main function. */ int MosMain(void) { MIL_ID MilApplication, /* Application identifier. */ MilSystem, /* System identifier. */ MilDisplay, /* Display identifier. */ MilDigitizer, /* Digitizer identifier. */ MilImage; /* Image buffer identifier. */ MIL_INT BoardType, EventCount, Done = 0; MIL_TEXT_PTR* Events; MIL_INT Selection = 0; bool StandardEventEnbale = false; HookDataStruct UserHookData; /* Allocate defaults. */ MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, &MilDigitizer, M_NULL); MbufAllocColor(MilSystem, MdigInquire(MilDigitizer, M_SIZE_BAND, M_NULL), MdigInquire(MilDigitizer, M_SIZE_X, M_NULL), MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL), MdigInquire(MilDigitizer, M_TYPE, M_NULL), M_IMAGE+M_DISP+M_GRAB, &MilImage); MosPrintf(MIL_TEXT("------------------------------------------------------------\n\n")); /* Get information on the system we are using and print a welcome message to the console. */ MsysInquire(MilSystem, M_BOARD_TYPE, &BoardType); if(((BoardType & M_BOARD_TYPE_MASK) == M_GIGE_VISION) || ((BoardType & M_BOARD_TYPE_MASK) == M_USB3_VISION)) MosPrintf(MIL_TEXT("Matrox Driver for GigE/USB3 Vision - Camera event example\n\n")); else { MosPrintf(MIL_TEXT("This example program can only be used with the Matrox Driver for ") MIL_TEXT("GigE Vision or USB3 Vision.\n")); MosPrintf(MIL_TEXT("Please ensure that the default system type is set accordingly in ") MIL_TEXT("MIL Config.\n")); MosPrintf(MIL_TEXT("-------------------------------------------------------------\n\n")); MosPrintf(MIL_TEXT("Press <enter> to quit.\n")); MosGetch(); MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImage); return 1; } MosPrintf(MIL_TEXT("Press <Enter> to start.\n\n")); MosGetch(); /* Disable error printing in case camera is not Standard Feature Naming Convention compliant. */ MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE); /*Get the list of events supported by the camera. */ GetCameraEventControls(MilDigitizer, EventCount, &Events, StandardEventEnbale); /* Re-enable error printing. */ MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE); /* If camera supports events, ask the user to select an event to use. */ if(EventCount) { do { MosPrintf(MIL_TEXT("\nPlease select the event you wish to hook a function to: ")); #if M_MIL_USE_WINDOWS scanf_s("%ld", &Selection); #else scanf("%ld", &Selection); #endif if((Selection >= 0) && (Selection < EventCount)) Done = 1; else MosPrintf(MIL_TEXT("\nInvalid selection")); } while(!Done); UserHookData.MilDigitizer = MilDigitizer; UserHookData.MilImageDisp = MilImage; UserHookData.ProcessedImageCount = 0; UserHookData.Events = Events; UserHookData.EventCount = EventCount; UserHookData.TimeStamp = 0.0; /* Hook a callback to the camera's event. */ HookToEvent(MilDigitizer, Events[Selection], &UserHookData, StandardEventEnbale); MosPrintf(MIL_TEXT("\nAwaiting %s events.\n"), Events[Selection]); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n")); MosGetch(); /* Start a continuous acquisition. */ MdispSelect(MilDisplay, MilImage); /* Some events such as ExposureStart, ExposureEnd, ..., require an acquisition in order to be generated, therefore start an acquisition. */ MosPrintf(MIL_TEXT("\nPress <Enter> to quit.\n")); DoAcquisition(MilSystem, MilDigitizer, MilImage); MosGetch(); /* Unhook MIL callback from event. */ HookToEvent(MilDigitizer, Events[Selection], &UserHookData, StandardEventEnbale, M_UNHOOK); } /* Free allocations. */ if(EventCount) { for(MIL_INT i = 0; i < EventCount; i++) delete [] Events[i]; delete[] Events; } MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImage); return 0; } /* Gets and prints the events supported by the camera. */ void GetCameraEventControls(MIL_ID MilDigitizer, MIL_INT& SupportedEventCount, MIL_TEXT_PTR** Events, bool& StandardEventEnable) { MIL_TEXT_PTR CameraVendor = M_NULL; MIL_TEXT_PTR CameraModel = M_NULL; MIL_TEXT_PTR* EventNotification = M_NULL; MIL_INT EventCnt = 0, Cnt = 0, Len = 0; bool SupportsOn = false, SupportsOff = false; StandardEventEnable = false; /* Inquire general device information such as device vendor and name. */ MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE+M_STRING_SIZE, MIL_TEXT("DeviceVendorName"), M_DEFAULT, &Len); if(Len) { CameraVendor = new MIL_TEXT_CHAR[Len]; MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE, MIL_TEXT("DeviceVendorName"), M_TYPE_STRING, CameraVendor); } Len = 0; MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE+M_STRING_SIZE, MIL_TEXT("DeviceModelName"), M_DEFAULT, &Len); if(Len) { CameraModel = new MIL_TEXT_CHAR[Len]; MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE, MIL_TEXT("DeviceModelName"), M_TYPE_STRING, CameraModel); } /* Inquire supported events. */ MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("EventSelector"), M_DEFAULT, &EventCnt); if(EventCnt) { (*Events) = new MIL_TEXT_PTR [EventCnt]; for(MIL_INT i=0; i<EventCnt; i++) { MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+M_STRING_SIZE+i, MIL_TEXT("EventSelector"), M_DEFAULT, &Len); (*Events)[i] = new MIL_TEXT_CHAR[Len]; MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+i, MIL_TEXT("EventSelector"), M_DEFAULT, (*Events)[i]); } } /*Validate if device supports standard event notification mechanism. */ MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("EventNotification"), M_DEFAULT, &Cnt); if(Cnt) { EventNotification = new MIL_TEXT_PTR[Cnt]; for(MIL_INT i=0; i<Cnt; i++) { MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+M_STRING_SIZE+i, MIL_TEXT("EventNotification"), M_DEFAULT, &Len); EventNotification[i] = new MIL_TEXT_CHAR[Len]; MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_NAME+i, MIL_TEXT("EventNotification"), M_DEFAULT, EventNotification[i]); if(MosStrcmp(EventNotification[i], MIL_TEXT("On")) == 0) SupportsOn = true; else if(MosStrcmp(EventNotification[i], MIL_TEXT("Off")) == 0) SupportsOff = true; } if(SupportsOn && SupportsOff) StandardEventEnable = true; } /* Print data inquired above. */ MosPrintf(MIL_TEXT("%20s %s %s\n"), MIL_TEXT("Connected to camera:"), CameraVendor?CameraVendor:MIL_TEXT("N/A"), CameraModel?CameraModel:MIL_TEXT("N/A")); MosPrintf(MIL_TEXT("%20s "), MIL_TEXT("Supported events:")); /* If camera supports events, ask the user to which event to hook to. */ if(EventCnt == 0) { MosPrintf(MIL_TEXT("Your camera does not support events.\n\n")); MosPrintf(MIL_TEXT("Press <Enter> to quit.\n\n")); MosGetch(); } else { MosPrintf(MIL_TEXT("(0) %s\n"), (*Events)[0]); for(MIL_INT i = 1; i < EventCnt; i++) MosPrintf(MIL_TEXT("%20s (%d) %s\n"), MIL_TEXT(""), i, (*Events)[i]); } /* Free allocations. */ if(Cnt) { for(MIL_INT i=0; i<Cnt; i++) delete [] EventNotification[i]; delete [] EventNotification; } if(CameraVendor) delete [] CameraVendor; if(CameraModel) delete [] CameraModel; SupportedEventCount = EventCnt; } /* Hooks a MIL function callback to camera events. */ void HookToEvent(MIL_ID MilDigitizer, MIL_TEXT_PTR Event, void* HookDataPtr, bool StandardEventEnable, MIL_INT Unhook /*= 0*/) { MIL_INT MilHookType = 0; MIL_INT Error = M_NULL_ERROR; bool UnknownEventType = false; if(Unhook) Unhook = M_UNHOOK; if(StandardEventEnable) { /* If the camera supports standard event notification we can simply hook user MdigHookFunction with the event name. */ if(MosStrcmp(Event, MIL_TEXT("AcquisitionTrigger")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_TRIGGER+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("AcquisitionStart")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_START+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("AcquisitionEnd")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_END+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("AcquisitionTransferStart")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_TRANSFER_START+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("AcquisitionTransferEnd")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_TRANSFER_END+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("AcquisitionError")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_ACQUISITION_ERROR+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("FrameTrigger")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_TRIGGER+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("FrameStart")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_START+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("FrameEnd")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_END+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("FrameTransferStart")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_TRANSFER_START+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("FrameTransferEnd")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_FRAME_TRANSFER_END+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("ExposureStart")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_EXPOSURE_START+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrcmp(Event, MIL_TEXT("ExposureEnd")) == 0) { MdigHookFunction(MilDigitizer, M_GC_EVENT+M_EXPOSURE_END+Unhook, CameraEventHandler, HookDataPtr); } else if(MosStrncmp(Event, MIL_TEXT("Counter"), MosStrlen(MIL_TEXT("Counter"))) == 0) { /* For counter events we must generate the string that targets the proper counter instance. */ MIL_TEXT_CHAR String1[256]; MIL_TEXT_CHAR String2[256]; MIL_INT Count = 0; MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("CounterSelector"), M_DEFAULT, &Count); for(int i=0; i<Count && MilHookType == 0; i++) { MosSprintf(String1, 256, MIL_TEXT("Counter%dStart"), i); MosSprintf(String2, 256, MIL_TEXT("Counter%dEnd"), i); if(MosStrcmp(Event, String1) == 0) MilHookType = M_GC_EVENT+M_COUNTER_START; else if(MosStrcmp(Event, String2) == 0) MilHookType = M_GC_EVENT+M_COUNTER_END; } if(MilHookType) MdigHookFunction(MilDigitizer, MilHookType+Unhook, CameraEventHandler, HookDataPtr); else UnknownEventType = true; } else if(MosStrncmp(Event, MIL_TEXT("Timer"), MosStrlen(MIL_TEXT("Timer"))) == 0) { /* For timer events we must generate the string that targets the proper timer instance. */ MIL_TEXT_CHAR String1[256]; MIL_TEXT_CHAR String2[256]; MIL_INT Count = 0; MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("TimerSelector"), M_DEFAULT, &Count); for(int i=0; i<Count && MilHookType == 0; i++) { MosSprintf(String1, 256, MIL_TEXT("Timer%dStart"), i); MosSprintf(String2, 256, MIL_TEXT("Timer%dEnd"), i); if(MosStrcmp(Event, String1) == 0) MilHookType = M_GC_EVENT+M_TIMER_START; else if(MosStrcmp(Event, String2) == 0) MilHookType = M_GC_EVENT+M_TIMER_END; } if(MilHookType) MdigHookFunction(MilDigitizer, MilHookType+Unhook, CameraEventHandler, HookDataPtr); else UnknownEventType = true; } else if(MosStrncmp(Event, MIL_TEXT("Line"), MosStrlen(MIL_TEXT("Line"))) == 0) { /* For Line events we must generate the string that targets the proper Line instance. */ MIL_TEXT_CHAR String1[256]; MIL_TEXT_CHAR String2[256]; MIL_TEXT_CHAR String3[256]; MIL_INT Count = 0; MdigInquireFeature(MilDigitizer, M_FEATURE_ENUM_ENTRY_COUNT, MIL_TEXT("LineSelector"), M_DEFAULT, &Count); for(int i=0; i<Count && MilHookType == 0; i++) { MosSprintf(String1, 256, MIL_TEXT("Line%dRisingEdge"), i); MosSprintf(String2, 256, MIL_TEXT("Line%dFallingEdge"), i); MosSprintf(String3, 256, MIL_TEXT("Line%dAnyEdge"), i); if(MosStrcmp(Event, String1) == 0) MilHookType = M_GC_EVENT+M_LINE_RISING_EDGE; else if(MosStrcmp(Event, String2) == 0) MilHookType = M_GC_EVENT+M_LINE_FALLING_EDGE; else if(MosStrcmp(Event, String3) == 0) MilHookType = M_GC_EVENT+M_LINE_ANY_EDGE; } if(MilHookType) MdigHookFunction(MilDigitizer, MilHookType+Unhook, CameraEventHandler, HookDataPtr); else UnknownEventType = true; } else { /* Unknown hook types are handled as generic M_GC_EVENT indicated below. */ UnknownEventType = true; } } if((StandardEventEnable == false) || UnknownEventType) { /* Disable error printing for cameras that do not support the SNFC EventNotification feature. */ MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE); //Hook to a generic (unknown to MIL) event type. MdigHookFunction(MilDigitizer, M_GC_EVENT+Unhook, CameraEventHandler, HookDataPtr); //Try to enable the event assuming that the "EventNotification" feature is implemented in the camera. MdigControlFeature(MilDigitizer, M_FEATURE_VALUE_AS_STRING, MIL_TEXT("EventSelector"), M_DEFAULT, Event); if(!Unhook) { MdigControlFeature(MilDigitizer, M_FEATURE_VALUE_AS_STRING, MIL_TEXT("EventNotification"), M_DEFAULT, MIL_TEXT("On")); MappGetError(M_DEFAULT, M_CURRENT+M_THREAD_CURRENT, &Error); if(Error != M_NULL_ERROR) { /* Standard EventNotification support is missing. Print message to user about this. */ MosPrintf(MIL_TEXT("\nThe %s feature as implemented by the camera manufacturer lacks\n"), Event); MosPrintf(MIL_TEXT("standard \"EventNotification\" support. Make sure the event is enabled using\n")); MosPrintf(MIL_TEXT("the feature browser before continuing.\n\n")); MosPrintf(MIL_TEXT("Some older camera models might require \"EventNotification\" to be set to\n")); MosPrintf(MIL_TEXT("\"GigEVisionEvent\" or \"GenICamEvent\" for event notification to occur.\n")); /* Pop up the feature browser, the user should find the feature that enables event notification and set it. */ MdigControl(MilDigitizer, M_GC_FEATURE_BROWSER, M_OPEN+M_ASYNCHRONOUS); } } else MdigControlFeature(MilDigitizer, M_FEATURE_VALUE_AS_STRING, MIL_TEXT("EventNotification"), M_DEFAULT, MIL_TEXT("Off")); MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE); } } /* Does a lookup of the event name that triggered the callback. */ void EventTypeLookUp(MIL_ID MilDigitizer, MIL_ID HookId, HookDataStruct* HookDataPtr) { MIL_TEXT_CHAR String[256]; bool Found = false; MIL_DOUBLE EventTimeStamp; MIL_INT EventType; MIL_INT64 LocalEventType = 0; /* Inquire the raw event type and the timestamp when the event occurred. */ MdigGetHookInfo(HookId, M_GC_EVENT_TYPE, &EventType); MdigGetHookInfo(HookId, M_GC_CAMERA_TIME_STAMP, &EventTimeStamp); MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE); for(MIL_INT i=0; i<HookDataPtr->EventCount && !Found; i++) { /*Lookup the event name from the raw event type. */ MosSprintf(String, 256, MIL_TEXT("Event%s"), HookDataPtr->Events[i]); MdigInquireFeature(MilDigitizer, M_FEATURE_VALUE, String, M_TYPE_INT64, &LocalEventType); if(LocalEventType == EventType) { MosPrintf(MIL_TEXT("Received %s event. Interval from last: %.6f sec.\n"), HookDataPtr->Events[i], EventTimeStamp-HookDataPtr->TimeStamp); Found = true; } } MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE); /* Look-up failed, camera probably does not support EventExposureData features. Simply print the raw event type. */ if(Found == false) MosPrintf(MIL_TEXT("Event #%d received. Interval from last: %.6f sec.\n"), EventType, EventTimeStamp-HookDataPtr->TimeStamp); HookDataPtr->TimeStamp = EventTimeStamp; } /* User's processing function hook data structure. */ void DoAcquisition(MIL_ID MilSystem, MIL_ID MilDigitizer, MIL_ID MilImageDisp) { MIL_INT NbFrames = 10; MIL_INT MilGrabBufferListSize; MIL_INT Done = 0; MIL_INT Ch = 0; MIL_ID* MilGrabBufferList = NULL; HookDataStruct UserHookData; MilGrabBufferList = new MIL_INT[(NbFrames==M_INFINITE) ? 10 : NbFrames]; /* Allocate the grab buffers and clear them. */ MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE); for(MilGrabBufferListSize = 0; MilGrabBufferListSize<NbFrames; MilGrabBufferListSize++) { MbufAlloc2d(MilSystem, MdigInquire(MilDigitizer, M_SIZE_X, M_NULL), MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL), 8+M_UNSIGNED, M_IMAGE+M_GRAB+M_PROC, &MilGrabBufferList[MilGrabBufferListSize]); if (MilGrabBufferList[MilGrabBufferListSize]) { MbufClear(MilGrabBufferList[MilGrabBufferListSize], 0xFF); } else break; } MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE); /* Initialize the User's processing function data structure. */ UserHookData.MilDigitizer = MilDigitizer; UserHookData.MilImageDisp = MilImageDisp; UserHookData.ProcessedImageCount = 0; /* Start the processing. The processing function is called for every frame grabbed. */ MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, M_START, M_DEFAULT, ProcessingFunction, &UserHookData); /* NOTE: Now the main() is free to perform other tasks while the processing is executing. */ /* -------------------------------------------------------------------------------- */ MosGetch(); /* Stop the processing. */ MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize, Done ? M_STOP : M_STOP+M_WAIT, M_DEFAULT, ProcessingFunction, &UserHookData); /* Free the grab buffers. */ while(MilGrabBufferListSize > 0) MbufFree(MilGrabBufferList[--MilGrabBufferListSize]); delete [] MilGrabBufferList; } /* User's processing function called every time a grab buffer is modified. */ /* -----------------------------------------------------------------------*/ /* Local defines. */ #define STRING_LENGTH_MAX 20 #define STRING_POS_X 20 #define STRING_POS_Y 20 MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr) { HookDataStruct *UserHookDataPtr = (HookDataStruct *)HookDataPtr; MIL_ID ModifiedBufferId; MIL_TEXT_CHAR Text[STRING_LENGTH_MAX]= {MIL_TEXT('\0'),}; /* Retrieve the MIL_ID of the grabbed buffer. */ MdigGetHookInfo(HookId, M_MODIFIED_BUFFER+M_BUFFER_ID, &ModifiedBufferId); /* Print and draw the frame count. */ UserHookDataPtr->ProcessedImageCount++; MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%ld"), UserHookDataPtr->ProcessedImageCount); MgraText(M_DEFAULT, ModifiedBufferId, STRING_POS_X, STRING_POS_Y, Text); /* Perform the processing and update the display. */ MbufCopy(ModifiedBufferId, UserHookDataPtr->MilImageDisp); return 0; } /* User's callback function prototype. Called when a camera event fires. */ MIL_INT MFTYPE CameraEventHandler(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr) { HookDataStruct *UserHookDataPtr = (HookDataStruct *)HookDataPtr; /* Print info related to the camera event that was fired. */ EventTypeLookUp(UserHookDataPtr->MilDigitizer, HookId, UserHookDataPtr); return 0; }