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

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