stlab.adobe.com Adobe Systems Incorporated

macintosh_events.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://stlab.adobe.com/licenses.html)
00005 */
00006 
00007 /**************************************************************************************************/
00008 
00009 #ifndef ADOBE_MACINTOSH_EVENTS_HPP
00010 #define ADOBE_MACINTOSH_EVENTS_HPP
00011 
00012 /**************************************************************************************************/
00013 
00014 #if !defined(__LP64__)
00015 
00016 /**************************************************************************************************/
00017 
00018 #include <adobe/algorithm/lower_bound.hpp>
00019 #include <adobe/algorithm/sort.hpp>
00020 #include <adobe/algorithm/unique.hpp>
00021 #include <adobe/future/macintosh_error.hpp>
00022 #include <adobe/macintosh_carbon_safe.hpp>
00023 #include <adobe/macintosh_memory.hpp>
00024 
00025 #include <boost/noncopyable.hpp>
00026 #include <boost/static_assert.hpp>
00027 #include <boost/type_traits.hpp>
00028 
00029 #include <iterator>
00030 #include <vector>
00031 
00032 /**************************************************************************************************/
00033 
00034 inline bool operator == (const ::EventTypeSpec& x, const ::EventTypeSpec& y)
00035 { return x.eventClass == y.eventClass && x.eventKind == y.eventKind; }
00036 
00037 inline bool operator < (const ::EventTypeSpec& x, const ::EventTypeSpec& y)
00038 { return x.eventClass < y.eventClass || x.eventClass == y.eventClass && x.eventKind < y.eventKind; }
00039 
00040 /**************************************************************************************************/
00041 
00042 namespace adobe {
00043 
00044 /**************************************************************************************************/
00045 
00046 template <typename T> struct event_param_type;
00047 
00048 #define ADOBE_EVENT_PARAM_TYPE_HELPER(type, event_type) \
00049 template <> struct event_param_type< type > { static const ::EventParamType value = event_type; }
00050 
00051 ADOBE_EVENT_PARAM_TYPE_HELPER(::CFArrayRef,             typeCFArrayRef);
00052 ADOBE_EVENT_PARAM_TYPE_HELPER(::CFDictionaryRef,        typeCFDictionaryRef);
00053 ADOBE_EVENT_PARAM_TYPE_HELPER(::CFMutableArrayRef,      typeCFMutableArrayRef);
00054 ADOBE_EVENT_PARAM_TYPE_HELPER(::CFMutableDictionaryRef, typeCFMutableDictionaryRef);
00055 ADOBE_EVENT_PARAM_TYPE_HELPER(::CFMutableStringRef,     typeCFMutableStringRef);
00056 ADOBE_EVENT_PARAM_TYPE_HELPER(::CFStringRef,            typeCFStringRef);
00057 ADOBE_EVENT_PARAM_TYPE_HELPER(::CFTypeRef,              typeCFTypeRef);
00058 ADOBE_EVENT_PARAM_TYPE_HELPER(::ControlPartCode,        typeControlPartCode);
00059 ADOBE_EVENT_PARAM_TYPE_HELPER(::DragRef,                typeDragRef);
00060 ADOBE_EVENT_PARAM_TYPE_HELPER(::EventMouseWheelAxis,    typeMouseWheelAxis);
00061 ADOBE_EVENT_PARAM_TYPE_HELPER(::EventTargetRef,         typeEventTargetRef);
00062 ADOBE_EVENT_PARAM_TYPE_HELPER(::HICommand,              typeHICommand);
00063 ADOBE_EVENT_PARAM_TYPE_HELPER(::HIPoint,                typeHIPoint);
00064 ADOBE_EVENT_PARAM_TYPE_HELPER(::SInt32,                 typeLongInteger);
00065 ADOBE_EVENT_PARAM_TYPE_HELPER(::TabletPointRec,         typeTabletPointRec);
00066 ADOBE_EVENT_PARAM_TYPE_HELPER(::TabletProximityRec,     typeTabletProximityRec);
00067 ADOBE_EVENT_PARAM_TYPE_HELPER(::UInt32,                 typeUInt32);
00068 ADOBE_EVENT_PARAM_TYPE_HELPER(::WindowRef,              typeWindowRef);
00069 ADOBE_EVENT_PARAM_TYPE_HELPER(bool,                     typeBoolean);
00070 
00071 #undef ADOBE_EVENT_PARAM_TYPE_HELPER
00072 
00073 /**************************************************************************************************/
00074 
00075 template < ::EventParamName name, typename T >
00076 bool get_event_parameter(::EventRef       the_event,
00077                          T&               value,
00078                          ::EventParamType type = event_param_type<T>::value)
00079 {
00080     ::EventParamType actual_type;
00081     ::UInt32         actual_size;
00082     ::OSStatus       err(::GetEventParameter(the_event,
00083                                              name,
00084                                              type,
00085                                              &actual_type,
00086                                              sizeof(T),
00087                                              &actual_size,
00088                                              &value));
00089 
00090     return err == noErr && actual_type == type && actual_size == sizeof(T);
00091 }
00092 
00093 /**************************************************************************************************/
00094 
00095 template < ::EventParamName name, typename T >
00096 bool set_event_parameter(::EventRef       the_event,
00097                          const T&         value,
00098                          ::EventParamType type = event_param_type<T>::value)
00099 {
00100     ::OSStatus err(::SetEventParameter(the_event,
00101                                        name,
00102                                        type,
00103                                        sizeof(T),
00104                                        &value));
00105 
00106     return err == noErr;
00107 }
00108 
00109 /**************************************************************************************************/
00110 
00111 template <typename Target>
00112 ::EventTargetRef get_event_target(Target target);
00113 
00114 #define ADOBE_GET_EVENT_TARGET_HELPER(type, proc) \
00115 template <> inline ::EventTargetRef get_event_target<>(type target) { return proc(target); }
00116 
00117 ADOBE_GET_EVENT_TARGET_HELPER(::WindowRef,      ::GetWindowEventTarget)
00118 ADOBE_GET_EVENT_TARGET_HELPER(::ControlRef,     ::GetControlEventTarget)
00119 ADOBE_GET_EVENT_TARGET_HELPER(::MenuRef,        ::GetMenuEventTarget)
00120 ADOBE_GET_EVENT_TARGET_HELPER(::EventTargetRef, ::EventTargetRef)
00121 
00122 #undef ADOBE_GET_EVENT_TARGET_HELPER
00123 
00124 /**************************************************************************************************/
00125 
00126 class event_handler_t : boost::noncopyable
00127 {
00128 public:
00129     typedef boost::function< ::OSStatus (::EventHandlerCallRef, ::EventRef) > monitor_proc_t;
00130 
00131     event_handler_t();
00132 
00133     template <typename Target>
00134     void install(Target target)
00135         { install(get_event_target(target)); }
00136 
00137     void install(::EventTargetRef target);
00138 
00139     void uninstall();
00140 
00141     bool is_installed() const
00142         { return ref_m.get() != 0; }
00143 
00144     void insert(const ::EventTypeSpec& event_spec);
00145 
00146     void insert(::UInt32 event_class, ::UInt32 event_kind)
00147         { ::EventTypeSpec event = { event_class, event_kind }; insert(event); }
00148 
00149     template <typename ForwardIterator>
00150     void insert(const ForwardIterator first, const ForwardIterator last)
00151     {
00152         typedef typename std::iterator_traits<ForwardIterator>::value_type        value_type;
00153         typedef typename std::iterator_traits<ForwardIterator>::iterator_category iterator_category;
00154 
00155         BOOST_STATIC_ASSERT((boost::is_convertible<value_type, ::EventTypeSpec>::value));
00156 
00157         insert(first, last, iterator_category());
00158     }
00159 
00160     void erase(const ::EventTypeSpec& event_spec);
00161 
00162     void erase(::UInt32 event_class, ::UInt32 event_kind)
00163         { ::EventTypeSpec event = { event_class, event_kind }; erase(event); }
00164 
00165     template <typename ForwardIterator>
00166     void erase(const ForwardIterator first, const ForwardIterator last)
00167     {
00168         typedef typename std::iterator_traits<ForwardIterator>::value_type        value_type;
00169         typedef typename std::iterator_traits<ForwardIterator>::iterator_category iterator_category;
00170 
00171         BOOST_STATIC_ASSERT((boost::is_convertible<value_type, ::EventTypeSpec>::value));
00172 
00173         erase(first, last, iterator_category());
00174     }
00175 
00176     monitor_proc_t monitor_proc_m; // no need to be private
00177 
00178 private:
00179     template <typename ForwardIterator>
00180     void insert(const ForwardIterator first,
00181                 const ForwardIterator last,
00182                 std::forward_iterator_tag);
00183 
00184     template <typename ForwardIterator>
00185     void insert(const ForwardIterator first,
00186                 const ForwardIterator last,
00187                 std::random_access_iterator_tag);
00188 
00189     template <typename ForwardIterator>
00190     void erase(const ForwardIterator first,
00191                const ForwardIterator last,
00192                std::forward_iterator_tag);
00193 
00194     template <typename ForwardIterator>
00195     void erase(const ForwardIterator first,
00196                const ForwardIterator last,
00197                std::random_access_iterator_tag);
00198 
00199     typedef adobe::auto_resource< ::EventHandlerRef > auto_ref_t;
00200     typedef adobe::auto_resource< ::EventHandlerUPP > auto_upp_t;
00201     typedef std::vector< ::EventTypeSpec >            event_type_set_t;
00202 
00203     auto_ref_t       ref_m;
00204     auto_upp_t       upp_m;
00205     event_type_set_t event_type_set_m;
00206 };
00207 
00208 /**************************************************************************************************/
00209 
00210 template <typename ForwardIterator>
00211 void event_handler_t::insert(const ForwardIterator first,
00212                              const ForwardIterator last,
00213                              std::forward_iterator_tag)
00214 {
00215     typedef void (event_handler_t::*proc_type)(const ::EventTypeSpec&);
00216 
00217     proc_type proc(&event_handler_t::insert);
00218 
00219     std::for_each(first, last, boost::bind(proc, boost::ref(*this), _1));
00220 }
00221 
00222 /**************************************************************************************************/
00223 
00224 template <typename ForwardIterator>
00225 void event_handler_t::insert(const ForwardIterator first,
00226                              const ForwardIterator last,
00227                              std::random_access_iterator_tag)
00228 {
00229     std::size_t n(std::distance(first, last));
00230 
00231     // this will fill the event_type_set_m vector with new
00232     // events without duplicating ones already present.
00233     event_type_set_m.insert(event_type_set_m.end(), first, last);
00234     adobe::sort(event_type_set_m);
00235     event_type_set_m.erase(adobe::unique(event_type_set_m), event_type_set_m.end());
00236 
00237     if (!is_installed())
00238         return;
00239 
00240     // now add the event set to the handler.
00241     ::ADOBE_REQUIRE_STATUS(::AddEventTypesToHandler(ref_m.get(), n, first));
00242 }
00243 
00244 /**************************************************************************************************/
00245 
00246 template <typename ForwardIterator>
00247 void event_handler_t::erase(const ForwardIterator first,
00248                             const ForwardIterator last,
00249                             std::forward_iterator_tag)
00250 {
00251     typedef void (event_handler_t::*proc_type)(const ::EventTypeSpec&);
00252 
00253     proc_type proc(&event_handler_t::erase);
00254 
00255     std::for_each(first, last, boost::bind(proc, boost::ref(*this), _1));
00256 }
00257 
00258 /**************************************************************************************************/
00259 
00260 template <typename ForwardIterator>
00261 void event_handler_t::erase(const ForwardIterator first,
00262                             const ForwardIterator last,
00263                             std::random_access_iterator_tag)
00264 {
00265     std::size_t n(std::distance(first, last));
00266 
00267     adobe::sort(event_type_set_m);
00268 
00269     for (ForwardIterator iter(first); iter != last; ++iter)
00270     {
00271         ForwardIterator found(adobe::lower_bound(event_type_set_m, *iter));
00272 
00273         if (found != event_type_set_m.end() && *found == *iter)
00274             event_type_set_m.erase(found);
00275     }
00276 
00277     if (!is_installed())
00278         return;
00279 
00280     // now remove the event set from the handler.
00281     ::ADOBE_REQUIRE_STATUS(::RemoveEventTypesFromHandler(ref_m.get(), n, first));
00282 }
00283 
00284 /**************************************************************************************************/
00285 
00286 } // namespace adobe
00287 
00288 /**************************************************************************************************/
00289 
00290 #endif
00291 
00292 /**************************************************************************************************/
00293 
00294 #endif
00295 
00296 /**************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google