├── .gitignore ├── Doxyfile ├── LICENSE.txt ├── README.md ├── USBBusProber ├── .DS_Store ├── APPLE_LICENSE ├── BusProbeClass.h ├── BusProbeClass.m ├── BusProbeDevice.h ├── BusProbeDevice.m ├── BusProber.h ├── BusProber.m ├── BusProberSharedFunctions.h ├── BusProberSharedFunctions.m ├── DecodeAudioInterfaceDescriptor.h ├── DecodeAudioInterfaceDescriptor.m ├── DecodeBOSDescriptor.h ├── DecodeBOSDescriptor.m ├── DecodeCommClassDescriptor.h ├── DecodeCommClassDescriptor.m ├── DecodeConfigurationDescriptor.h ├── DecodeConfigurationDescriptor.m ├── DecodeDeviceDescriptor.h ├── DecodeDeviceDescriptor.m ├── DecodeDeviceQualifierDescriptor.h ├── DecodeDeviceQualifierDescriptor.m ├── DecodeEndpointDescriptor.h ├── DecodeEndpointDescriptor.m ├── DecodeHIDDescriptor.h ├── DecodeHIDDescriptor.m ├── DecodeHubDescriptor.h ├── DecodeHubDescriptor.m ├── DecodeInterfaceDescriptor.h ├── DecodeInterfaceDescriptor.m ├── DecodeVideoInterfaceDescriptor.h ├── DecodeVideoInterfaceDescriptor.m ├── DescriptorDecoder.h ├── DescriptorDecoder.m ├── ExtensionSelector.h ├── ExtensionSelector.m ├── OutlineViewAdditions.h ├── OutlineViewAdditions.m ├── OutlineViewNode.h ├── OutlineViewNode.m ├── TableViewWithCopying.h ├── TableViewWithCopying.m ├── USBBusProber-Info.plist ├── USBBusProber-Prefix.pch ├── USBBusProber.h ├── USBVendors.txt └── en.lproj │ └── InfoPlist.strings ├── UVC Test App ├── AVCaptureVideoSource.h ├── AVCaptureVideoSource.m ├── AppDelegate.h ├── AppDelegate.m ├── CVGLView.h ├── CVGLView.m ├── UVC Test App-Info.plist ├── UVC Test App-Prefix.pch ├── en.lproj │ ├── Credits.rtf │ ├── InfoPlist.strings │ └── MainMenu.xib └── main.m ├── VVUVCKit.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── UVC Test App.xcscheme └── VVUVCKit ├── VVUVCController.h ├── VVUVCController.m ├── VVUVCController.xib ├── VVUVCKit-Info.plist ├── VVUVCKit-Prefix.pch ├── VVUVCKit.h ├── VVUVCKitStringAdditions.h ├── VVUVCKitStringAdditions.m ├── VVUVCUIController.h ├── VVUVCUIController.m ├── VVUVCUIElement.h ├── VVUVCUIElement.m └── en.lproj └── InfoPlist.strings /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | 3 | VVUVCKit.xcodeproj/* 4 | 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Vidvox, LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | \mainpage 2 | The VVUVCKit framework 3 | ====================== 4 | 5 | A framework for working with UVC (USB Video Class) camera controls in OS X. 6 | 7 | 8 | Introduction 9 | ------------ 10 | 11 | Many USB Video Class Devices (UVC) have a number of built-in hardware controls. At present, there isn't a good, high-level interface for interacting with these controls on OS X (in past years some of these controls were accessible via the QuickTime "Settings" window, but this has since been deprecated). The VVUVCKit framework provides both a programmatic and a GUI interface for interacting with these controls, which allows you to adjust many parameters (on supported USB cameras) such as manual exposure and focus controls, in-camera brightness/contrast/gain/hue/saturation/sharpness, and manual control of white balance. Pan/Tilt/Roll/Zoom control is also possible, but haven't been implemented yet because I don't have a camera to test with- if you do, please open an issue! 12 | 13 | The VVUVCKit framework is essentially a heavily modified/extended version of the open source code made available with the following blog post- if you look a bit, you can still see the similar methods and workflows, so credit should go here: 14 | 15 | http://phoboslab.org/log/2009/07/uvc-camera-control-for-mac-os-x 16 | 17 | 18 | How to get help 19 | --------------- 20 | 21 | Please open an "Issue" and I'll get back to you as soon as I get a chance! 22 | 23 | 24 | What does this project include/do/make? 25 | --------------------------------------- 26 | 27 | * VVUVCKit is a framework that packages up the classes and resources for working with UVC controls- this framework is probably why you're here. VVUVCKit depends on the USBBusProber (you'll need to add both to your app). 28 | 29 | * the USBBusProber framework is a re-packaging of open source code written by Apple. I basically just took code from Apple's "Bus Prober" application and made this framework from it. If you need a quick and easy way to access the data from "Bus Prober" in your app, you may find this useful. You'll need to include the USBBusProber framework along with the VVUVCKit framework in your app (VVUVCKit uses USBBusProber internally). If you're interested, the original source for the USB Prober app- as well as bunch of other neat stuff- can be found here: http://www.opensource.apple.com/source/IOUSBFamily/ 30 | 31 | * UVC Test App is a simple app that demonstrates the use of the VVUVCKit framework- you pick a webcam input, and the app will display the video stream and open a window with the UVC settings that are available for the selected camera (different cameras have different capabilities). 32 | 33 | 34 | How to use these frameworks in your Mac app 35 | ------------------------------------------- 36 | 37 | The general idea is to compile the frameworks you want to use, add them to your XCode project so you may link against them, and then set up a build phase to copy the framework into your application bundle. This is fairly important: most of the time when you link against a framework, the framework is expected to be installed on your OS. VVUVCKit (and USBBusProber) are different: your application will include a compiled copy of these frameworks, so you're guaranteed that the framework won't change outside of your control (which means you won't inherit bugs or have to deal with changed APIs until you're ready to do so). Here's the exact procedure: 38 | 39 | 1. In XCode, close the VVUVCKit project (if it is open), and then open your project. 40 | 2. In the Finder, drag the file "VVUVCKit.xcodeproj" into your project's workspace in XCode. 41 | 3. Switch back to XCode, and locate the "Build Phases" section for your project/application's target. 42 | 4. Add a dependency for "UVC Test App". This will ensure that all the frameworks in the VVUVCKit project get compiled before your project, so there won't be any missing dependencies. 43 | 5. Add the "VVUVCKit" and "USBBusProber" frameworks to the "Link Binary with Libraries" section of your application (click the "+" button, then locate and add the frameworks from within your workspace). 44 | 6. Create a new "Copy Files" build phase, set its destination to the "Frameworks" folder, and add the frameworks you linked against in the previous step- the goal is to copy the frameworks you need into the "Frameworks" folder inside your app package. When you click the "+" button to add the frameworks, they will be listed in the "Products" folder in the "VVUVCKit" project in your workspace. 45 | 7. Switch to the "Build Settings" section of your project's target, locate the "Runpath Search Paths" settings, and add the following paths: "@loader_path/../Frameworks" and "@executable_path/../Frameworks". 46 | 8. That's it- you're done now. You can #import now! 47 | 48 | 49 | Documentation and Sample Code 50 | ----------------------------- 51 | 52 | The "UVC Test App" demonstrates how to use VVUVCController to create a window with the UVC controls available for a given webcam input, and lets you view the effect your changes have on the video stream. If you can ignore the code that does the video display, this is actually a pretty straightforward sample app. 53 | 54 | Documentation for the VVUVCKit framework can be found here- the only class you'll probably need to work with is VVUVCController: 55 | 56 | http://vidvox.net/rays_oddsnends/VVUVCKit_doc/ 57 | 58 | Generally speaking, you want to create the VVUVCController for a given (enabled) USB video device. You can use the "uniqueID" property (a string containing a 16-digit hex valu) of either a QTCaptureDevice or an AVCaptureDevice. Once you've created it, you can either open a window with a GUI for the camera's available controls (-[VVUVCController openSettingsWindow]) or get/set the parameters programmatically. Once you're happy with the state of your camera, you can use the "createSnapshot" and "loadSnapshot:" methods to save and load the settings to/from an NSDictionary. 59 | 60 | 61 | Licensing 62 | --------- 63 | 64 | The source code which this project was based upon was declared as public domain in the above-linked blog post- in keeping with the spirit of free software, this repos uses the MIT license. 65 | 66 | The USBBusProber framework is based on apple's open-source code, and as such, it retains the "apple public source license" (which is included). 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /USBBusProber/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/.DS_Store -------------------------------------------------------------------------------- /USBBusProber/APPLE_LICENSE: -------------------------------------------------------------------------------- 1 | /*! 2 | \page AppleLicense 3 | 4 | APPLE PUBLIC SOURCE LICENSE 5 | Version 2.0 - August 6, 2003 6 | 7 | Please read this License carefully before downloading this software. 8 | By downloading or using this software, you are agreeing to be bound by 9 | the terms of this License. If you do not or cannot agree to the terms 10 | of this License, please do not download or use the software. 11 | 12 | 1. General; Definitions. This License applies to any program or other 13 | work which Apple Computer, Inc. ("Apple") makes publicly available and 14 | which contains a notice placed by Apple identifying such program or 15 | work as "Original Code" and stating that it is subject to the terms of 16 | this Apple Public Source License version 2.0 ("License"). As used in 17 | this License: 18 | 19 | 1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is 20 | the grantor of rights, (i) claims of patents that are now or hereafter 21 | acquired, owned by or assigned to Apple and (ii) that cover subject 22 | matter contained in the Original Code, but only to the extent 23 | necessary to use, reproduce and/or distribute the Original Code 24 | without infringement; and (b) in the case where You are the grantor of 25 | rights, (i) claims of patents that are now or hereafter acquired, 26 | owned by or assigned to You and (ii) that cover subject matter in Your 27 | Modifications, taken alone or in combination with Original Code. 28 | 29 | 1.2 "Contributor" means any person or entity that creates or 30 | contributes to the creation of Modifications. 31 | 32 | 1.3 "Covered Code" means the Original Code, Modifications, the 33 | combination of Original Code and any Modifications, and/or any 34 | respective portions thereof. 35 | 36 | 1.4 "Externally Deploy" means: (a) to sublicense, distribute or 37 | otherwise make Covered Code available, directly or indirectly, to 38 | anyone other than You; and/or (b) to use Covered Code, alone or as 39 | part of a Larger Work, in any way to provide a service, including but 40 | not limited to delivery of content, through electronic communication 41 | with a client other than You. 42 | 43 | 1.5 "Larger Work" means a work which combines Covered Code or portions 44 | thereof with code not governed by the terms of this License. 45 | 46 | 1.6 "Modifications" mean any addition to, deletion from, and/or change 47 | to, the substance and/or structure of the Original Code, any previous 48 | Modifications, the combination of Original Code and any previous 49 | Modifications, and/or any respective portions thereof. When code is 50 | released as a series of files, a Modification is: (a) any addition to 51 | or deletion from the contents of a file containing Covered Code; 52 | and/or (b) any new file or other representation of computer program 53 | statements that contains any part of Covered Code. 54 | 55 | 1.7 "Original Code" means (a) the Source Code of a program or other 56 | work as originally made available by Apple under this License, 57 | including the Source Code of any updates or upgrades to such programs 58 | or works made available by Apple under this License, and that has been 59 | expressly identified by Apple as such in the header file(s) of such 60 | work; and (b) the object code compiled from such Source Code and 61 | originally made available by Apple under this License. 62 | 63 | 1.8 "Source Code" means the human readable form of a program or other 64 | work that is suitable for making modifications to it, including all 65 | modules it contains, plus any associated interface definition files, 66 | scripts used to control compilation and installation of an executable 67 | (object code). 68 | 69 | 1.9 "You" or "Your" means an individual or a legal entity exercising 70 | rights under this License. For legal entities, "You" or "Your" 71 | includes any entity which controls, is controlled by, or is under 72 | common control with, You, where "control" means (a) the power, direct 73 | or indirect, to cause the direction or management of such entity, 74 | whether by contract or otherwise, or (b) ownership of fifty percent 75 | (50%) or more of the outstanding shares or beneficial ownership of 76 | such entity. 77 | 78 | 2. Permitted Uses; Conditions & Restrictions. Subject to the terms 79 | and conditions of this License, Apple hereby grants You, effective on 80 | the date You accept this License and download the Original Code, a 81 | world-wide, royalty-free, non-exclusive license, to the extent of 82 | Apple's Applicable Patent Rights and copyrights covering the Original 83 | Code, to do the following: 84 | 85 | 2.1 Unmodified Code. You may use, reproduce, display, perform, 86 | internally distribute within Your organization, and Externally Deploy 87 | verbatim, unmodified copies of the Original Code, for commercial or 88 | non-commercial purposes, provided that in each instance: 89 | 90 | (a) You must retain and reproduce in all copies of Original Code the 91 | copyright and other proprietary notices and disclaimers of Apple as 92 | they appear in the Original Code, and keep intact all notices in the 93 | Original Code that refer to this License; and 94 | 95 | (b) You must include a copy of this License with every copy of Source 96 | Code of Covered Code and documentation You distribute or Externally 97 | Deploy, and You may not offer or impose any terms on such Source Code 98 | that alter or restrict this License or the recipients' rights 99 | hereunder, except as permitted under Section 6. 100 | 101 | 2.2 Modified Code. You may modify Covered Code and use, reproduce, 102 | display, perform, internally distribute within Your organization, and 103 | Externally Deploy Your Modifications and Covered Code, for commercial 104 | or non-commercial purposes, provided that in each instance You also 105 | meet all of these conditions: 106 | 107 | (a) You must satisfy all the conditions of Section 2.1 with respect to 108 | the Source Code of the Covered Code; 109 | 110 | (b) You must duplicate, to the extent it does not already exist, the 111 | notice in Exhibit A in each file of the Source Code of all Your 112 | Modifications, and cause the modified files to carry prominent notices 113 | stating that You changed the files and the date of any change; and 114 | 115 | (c) If You Externally Deploy Your Modifications, You must make 116 | Source Code of all Your Externally Deployed Modifications either 117 | available to those to whom You have Externally Deployed Your 118 | Modifications, or publicly available. Source Code of Your Externally 119 | Deployed Modifications must be released under the terms set forth in 120 | this License, including the license grants set forth in Section 3 121 | below, for as long as you Externally Deploy the Covered Code or twelve 122 | (12) months from the date of initial External Deployment, whichever is 123 | longer. You should preferably distribute the Source Code of Your 124 | Externally Deployed Modifications electronically (e.g. download from a 125 | web site). 126 | 127 | 2.3 Distribution of Executable Versions. In addition, if You 128 | Externally Deploy Covered Code (Original Code and/or Modifications) in 129 | object code, executable form only, You must include a prominent 130 | notice, in the code itself as well as in related documentation, 131 | stating that Source Code of the Covered Code is available under the 132 | terms of this License with information on how and where to obtain such 133 | Source Code. 134 | 135 | 2.4 Third Party Rights. You expressly acknowledge and agree that 136 | although Apple and each Contributor grants the licenses to their 137 | respective portions of the Covered Code set forth herein, no 138 | assurances are provided by Apple or any Contributor that the Covered 139 | Code does not infringe the patent or other intellectual property 140 | rights of any other entity. Apple and each Contributor disclaim any 141 | liability to You for claims brought by any other entity based on 142 | infringement of intellectual property rights or otherwise. As a 143 | condition to exercising the rights and licenses granted hereunder, You 144 | hereby assume sole responsibility to secure any other intellectual 145 | property rights needed, if any. For example, if a third party patent 146 | license is required to allow You to distribute the Covered Code, it is 147 | Your responsibility to acquire that license before distributing the 148 | Covered Code. 149 | 150 | 3. Your Grants. In consideration of, and as a condition to, the 151 | licenses granted to You under this License, You hereby grant to any 152 | person or entity receiving or distributing Covered Code under this 153 | License a non-exclusive, royalty-free, perpetual, irrevocable license, 154 | under Your Applicable Patent Rights and other intellectual property 155 | rights (other than patent) owned or controlled by You, to use, 156 | reproduce, display, perform, modify, sublicense, distribute and 157 | Externally Deploy Your Modifications of the same scope and extent as 158 | Apple's licenses under Sections 2.1 and 2.2 above. 159 | 160 | 4. Larger Works. You may create a Larger Work by combining Covered 161 | Code with other code not governed by the terms of this License and 162 | distribute the Larger Work as a single product. In each such instance, 163 | You must make sure the requirements of this License are fulfilled for 164 | the Covered Code or any portion thereof. 165 | 166 | 5. Limitations on Patent License. Except as expressly stated in 167 | Section 2, no other patent rights, express or implied, are granted by 168 | Apple herein. Modifications and/or Larger Works may require additional 169 | patent licenses from Apple which Apple may grant in its sole 170 | discretion. 171 | 172 | 6. Additional Terms. You may choose to offer, and to charge a fee for, 173 | warranty, support, indemnity or liability obligations and/or other 174 | rights consistent with the scope of the license granted herein 175 | ("Additional Terms") to one or more recipients of Covered Code. 176 | However, You may do so only on Your own behalf and as Your sole 177 | responsibility, and not on behalf of Apple or any Contributor. You 178 | must obtain the recipient's agreement that any such Additional Terms 179 | are offered by You alone, and You hereby agree to indemnify, defend 180 | and hold Apple and every Contributor harmless for any liability 181 | incurred by or claims asserted against Apple or such Contributor by 182 | reason of any such Additional Terms. 183 | 184 | 7. Versions of the License. Apple may publish revised and/or new 185 | versions of this License from time to time. Each version will be given 186 | a distinguishing version number. Once Original Code has been published 187 | under a particular version of this License, You may continue to use it 188 | under the terms of that version. You may also choose to use such 189 | Original Code under the terms of any subsequent version of this 190 | License published by Apple. No one other than Apple has the right to 191 | modify the terms applicable to Covered Code created under this 192 | License. 193 | 194 | 8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in 195 | part pre-release, untested, or not fully tested works. The Covered 196 | Code may contain errors that could cause failures or loss of data, and 197 | may be incomplete or contain inaccuracies. You expressly acknowledge 198 | and agree that use of the Covered Code, or any portion thereof, is at 199 | Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND 200 | WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND 201 | APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE 202 | PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM 203 | ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT 204 | NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF 205 | MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR 206 | PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD 207 | PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST 208 | INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE 209 | FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS, 210 | THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR 211 | ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO 212 | ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE 213 | AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY. 214 | You acknowledge that the Covered Code is not intended for use in the 215 | operation of nuclear facilities, aircraft navigation, communication 216 | systems, or air traffic control machines in which case the failure of 217 | the Covered Code could lead to death, personal injury, or severe 218 | physical or environmental damage. 219 | 220 | 9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO 221 | EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL, 222 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING 223 | TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR 224 | ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY, 225 | TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF 226 | APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 227 | DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY 228 | REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF 229 | INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY 230 | TO YOU. In no event shall Apple's total liability to You for all 231 | damages (other than as may be required by applicable law) under this 232 | License exceed the amount of fifty dollars ($50.00). 233 | 234 | 10. Trademarks. This License does not grant any rights to use the 235 | trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS", 236 | "QuickTime", "QuickTime Streaming Server" or any other trademarks, 237 | service marks, logos or trade names belonging to Apple (collectively 238 | "Apple Marks") or to any trademark, service mark, logo or trade name 239 | belonging to any Contributor. You agree not to use any Apple Marks in 240 | or as part of the name of products derived from the Original Code or 241 | to endorse or promote products derived from the Original Code other 242 | than as expressly permitted by and in strict compliance at all times 243 | with Apple's third party trademark usage guidelines which are posted 244 | at http://www.apple.com/legal/guidelinesfor3rdparties.html. 245 | 246 | 11. Ownership. Subject to the licenses granted under this License, 247 | each Contributor retains all rights, title and interest in and to any 248 | Modifications made by such Contributor. Apple retains all rights, 249 | title and interest in and to the Original Code and any Modifications 250 | made by or on behalf of Apple ("Apple Modifications"), and such Apple 251 | Modifications will not be automatically subject to this License. Apple 252 | may, at its sole discretion, choose to license such Apple 253 | Modifications under this License, or on different terms from those 254 | contained in this License or may choose not to license them at all. 255 | 256 | 12. Termination. 257 | 258 | 12.1 Termination. This License and the rights granted hereunder will 259 | terminate: 260 | 261 | (a) automatically without notice from Apple if You fail to comply with 262 | any term(s) of this License and fail to cure such breach within 30 263 | days of becoming aware of such breach; 264 | 265 | (b) immediately in the event of the circumstances described in Section 266 | 13.5(b); or 267 | 268 | (c) automatically without notice from Apple if You, at any time during 269 | the term of this License, commence an action for patent infringement 270 | against Apple; provided that Apple did not first commence 271 | an action for patent infringement against You in that instance. 272 | 273 | 12.2 Effect of Termination. Upon termination, You agree to immediately 274 | stop any further use, reproduction, modification, sublicensing and 275 | distribution of the Covered Code. All sublicenses to the Covered Code 276 | which have been properly granted prior to termination shall survive 277 | any termination of this License. Provisions which, by their nature, 278 | should remain in effect beyond the termination of this License shall 279 | survive, including but not limited to Sections 3, 5, 8, 9, 10, 11, 280 | 12.2 and 13. No party will be liable to any other for compensation, 281 | indemnity or damages of any sort solely as a result of terminating 282 | this License in accordance with its terms, and termination of this 283 | License will be without prejudice to any other right or remedy of 284 | any party. 285 | 286 | 13. Miscellaneous. 287 | 288 | 13.1 Government End Users. The Covered Code is a "commercial item" as 289 | defined in FAR 2.101. Government software and technical data rights in 290 | the Covered Code include only those rights customarily provided to the 291 | public as defined in this License. This customary commercial license 292 | in technical data and software is provided in accordance with FAR 293 | 12.211 (Technical Data) and 12.212 (Computer Software) and, for 294 | Department of Defense purchases, DFAR 252.227-7015 (Technical Data -- 295 | Commercial Items) and 227.7202-3 (Rights in Commercial Computer 296 | Software or Computer Software Documentation). Accordingly, all U.S. 297 | Government End Users acquire Covered Code with only those rights set 298 | forth herein. 299 | 300 | 13.2 Relationship of Parties. This License will not be construed as 301 | creating an agency, partnership, joint venture or any other form of 302 | legal association between or among You, Apple or any Contributor, and 303 | You will not represent to the contrary, whether expressly, by 304 | implication, appearance or otherwise. 305 | 306 | 13.3 Independent Development. Nothing in this License will impair 307 | Apple's right to acquire, license, develop, have others develop for 308 | it, market and/or distribute technology or products that perform the 309 | same or similar functions as, or otherwise compete with, 310 | Modifications, Larger Works, technology or products that You may 311 | develop, produce, market or distribute. 312 | 313 | 13.4 Waiver; Construction. Failure by Apple or any Contributor to 314 | enforce any provision of this License will not be deemed a waiver of 315 | future enforcement of that or any other provision. Any law or 316 | regulation which provides that the language of a contract shall be 317 | construed against the drafter will not apply to this License. 318 | 319 | 13.5 Severability. (a) If for any reason a court of competent 320 | jurisdiction finds any provision of this License, or portion thereof, 321 | to be unenforceable, that provision of the License will be enforced to 322 | the maximum extent permissible so as to effect the economic benefits 323 | and intent of the parties, and the remainder of this License will 324 | continue in full force and effect. (b) Notwithstanding the foregoing, 325 | if applicable law prohibits or restricts You from fully and/or 326 | specifically complying with Sections 2 and/or 3 or prevents the 327 | enforceability of either of those Sections, this License will 328 | immediately terminate and You must immediately discontinue any use of 329 | the Covered Code and destroy all copies of it that are in your 330 | possession or control. 331 | 332 | 13.6 Dispute Resolution. Any litigation or other dispute resolution 333 | between You and Apple relating to this License shall take place in the 334 | Northern District of California, and You and Apple hereby consent to 335 | the personal jurisdiction of, and venue in, the state and federal 336 | courts within that District with respect to this License. The 337 | application of the United Nations Convention on Contracts for the 338 | International Sale of Goods is expressly excluded. 339 | 340 | 13.7 Entire Agreement; Governing Law. This License constitutes the 341 | entire agreement between the parties with respect to the subject 342 | matter hereof. This License shall be governed by the laws of the 343 | United States and the State of California, except that body of 344 | California law concerning conflicts of law. 345 | 346 | Where You are located in the province of Quebec, Canada, the following 347 | clause applies: The parties hereby confirm that they have requested 348 | that this License and all related documents be drafted in English. Les 349 | parties ont exige que le present contrat et tous les documents 350 | connexes soient rediges en anglais. 351 | 352 | EXHIBIT A. 353 | 354 | "Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights 355 | Reserved. 356 | 357 | This file contains Original Code and/or Modifications of Original Code 358 | as defined in and that are subject to the Apple Public Source License 359 | Version 2.0 (the 'License'). You may not use this file except in 360 | compliance with the License. Please obtain a copy of the License at 361 | http://www.opensource.apple.com/apsl/ and read it before using this 362 | file. 363 | 364 | The Original Code and all software distributed under the License are 365 | distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 366 | EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 367 | INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 368 | FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 369 | Please see the License for the specific language governing rights and 370 | limitations under the License." 371 | 372 | */ -------------------------------------------------------------------------------- /USBBusProber/BusProbeClass.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/BusProbeClass.h -------------------------------------------------------------------------------- /USBBusProber/BusProbeClass.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/BusProbeClass.m -------------------------------------------------------------------------------- /USBBusProber/BusProbeDevice.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright � 1998-2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | 25 | #import 26 | #import 27 | #import "BusProberSharedFunctions.h" 28 | #import "OutlineViewNode.h" 29 | #import "BusProbeClass.h" 30 | 31 | @interface BusProbeDevice : NSObject { 32 | OutlineViewNode * _rootNode; 33 | UInt8 _speed; 34 | USBDeviceAddress _address; 35 | UInt32 _locationID; 36 | UInt32 _vendorID; 37 | UInt32 _productID; 38 | UInt16 _usbRelease; 39 | BusProbeClass * _deviceClassInfo; 40 | BusProbeClass * _lastInterfaceClassInfo; 41 | UInt8 _lastInterfaceSubclass; 42 | int _currentInterfaceNumber; 43 | uint32_t _portInfo; 44 | } 45 | 46 | - (OutlineViewNode *)rootNode; 47 | - (void)addProperty:(char *)property withValue:(char *)value atDepth:(int)depth; 48 | - (void)addNumberProperty:(char *)property value:(UInt32)value size:(int)sizeInBytes atDepth:(int)depth usingStyle:(int)style; 49 | - (void)addStringProperty:(char *)property fromStringIndex:(UInt8)strIndex fromDeviceInterface:(IOUSBDeviceRef)deviceIntf atDepth:(int)depth; 50 | 51 | - (NSString *)deviceName; 52 | - (void)setDeviceName:(NSString *)name; 53 | - (NSString *)deviceDescription; 54 | - (void)setDeviceDescription:(NSString *)description; 55 | - (UInt8)speed; 56 | - (void)setSpeed:(UInt8)speed; 57 | - (USBDeviceAddress)address; 58 | - (void)setAddress:(USBDeviceAddress)address; 59 | - (uint32_t)portInfo; 60 | - (void)setPortInfo:(uint32_t)portInfo; 61 | //- (UInt32)locationID; 62 | //- (void)setLocationID:(UInt32)locationID; 63 | - (UInt32)vendorID; 64 | - (void)setVendorID:(UInt32)vendorID; 65 | - (UInt32)productID; 66 | - (void)setProductID:(UInt32)productID; 67 | - (UInt32)locationID; 68 | - (void)setLocationID:(UInt32)locationID; 69 | - (BusProbeClass *)deviceClassInfo; 70 | - (void)setDeviceClassInfo:(BusProbeClass *)classInfo; 71 | - (BusProbeClass *)lastInterfaceClassInfo; 72 | - (void)setLastInterfaceClassInfo:(BusProbeClass *)classInfo; 73 | - (int)currentInterfaceNumber; 74 | - (void)setCurrentInterfaceNumber:(int)currentNum; 75 | - (UInt16)usbRelease; 76 | - (void)setUSBRelease:(UInt16)usbRelease; 77 | 78 | - (NSString *)descriptionForName:(NSString*)name; 79 | - (NSString *)description; 80 | - (NSMutableDictionary *)dictionaryVersionOfMe; 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /USBBusProber/BusProbeDevice.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/BusProbeDevice.m -------------------------------------------------------------------------------- /USBBusProber/BusProber.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright � 1998-2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | 25 | #import 26 | #import 27 | #import 28 | #import 29 | #import 30 | #import 31 | #import "BusProberSharedFunctions.h" 32 | #import "OutlineViewNode.h" 33 | #import "BusProbeDevice.h" 34 | #import "BusProbeClass.h" 35 | 36 | #import "DescriptorDecoder.h" 37 | 38 | @interface BusProber : NSObject { 39 | id _listener; 40 | 41 | NSMutableArray * _devicesArray; 42 | CFRunLoopSourceRef _runLoopSource; 43 | } 44 | 45 | - (BOOL)registerForUSBNotifications; 46 | - (void)unregisterForUSBNotifications; 47 | 48 | - (void)refreshData:(BOOL)shouldForce; 49 | 50 | - (void)processDevice:(IOUSBDeviceRef)deviceIntf deviceNumber:(int)deviceNumber usbName:(NSString*)usbName; 51 | - (void)PrintPortInfo: (uint32_t)portInfo forDevice:(BusProbeDevice *)thisDevice; 52 | - (void)GetAndPrintNumberOfEndpoints:(IOUSBDeviceRef)deviceIntf forDevice:(BusProbeDevice *)thisDevice portInfo:(UInt32)portInfo; 53 | 54 | - (NSMutableArray *) devicesArray; 55 | 56 | @end 57 | 58 | 59 | 60 | 61 | @protocol BusProberListener 62 | 63 | - (void)busProberInformationDidChange:(BusProber *)aProber; 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /USBBusProber/BusProber.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright � 1998-2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | 25 | #import "BusProber.h" 26 | 27 | 28 | @implementation BusProber 29 | 30 | static void DeviceAdded(void *refCon, io_iterator_t iterator) 31 | { 32 | io_service_t ioDeviceObj = IO_OBJECT_NULL; 33 | 34 | while( (ioDeviceObj = IOIteratorNext( iterator)) ) 35 | { 36 | IOObjectRelease( ioDeviceObj ); 37 | } 38 | [(BusProber *)refCon refreshData:false]; 39 | } 40 | 41 | static void DeviceRemoved(void *refCon, io_iterator_t iterator) 42 | { 43 | io_service_t ioDeviceObj = IO_OBJECT_NULL; 44 | 45 | while( (ioDeviceObj = IOIteratorNext( iterator))) 46 | { 47 | IOObjectRelease( ioDeviceObj ); 48 | } 49 | [(BusProber *)refCon refreshData:false]; 50 | } 51 | 52 | - init { 53 | if (self = [super init]) { 54 | _runLoopSource = NULL; 55 | _devicesArray = [[NSMutableArray arrayWithCapacity:0] retain]; 56 | [self refreshData:true]; 57 | } 58 | return self; 59 | } 60 | 61 | - (void)dealloc { 62 | [self unregisterForUSBNotifications]; 63 | [_devicesArray release]; 64 | [super dealloc]; 65 | } 66 | 67 | - (BOOL)registerForUSBNotifications 68 | { 69 | kern_return_t kr; 70 | mach_port_t masterPort; 71 | IONotificationPortRef gNotifyPort; 72 | io_iterator_t gAddedIter,gRemovedIter; 73 | 74 | kr = IOMasterPort(MACH_PORT_NULL, &masterPort); 75 | if (kr != KERN_SUCCESS) return NO; 76 | 77 | gNotifyPort = IONotificationPortCreate(masterPort); 78 | _runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort); 79 | CFRunLoopAddSource([[NSRunLoop currentRunLoop] getCFRunLoop], _runLoopSource, kCFRunLoopDefaultMode); 80 | kr = IOServiceAddMatchingNotification(gNotifyPort, 81 | kIOFirstMatchNotification, 82 | IOServiceMatching(kIOUSBDeviceClassName), 83 | DeviceAdded, 84 | self, 85 | &gAddedIter); 86 | if (kr != KERN_SUCCESS) return NO; 87 | 88 | kr = IOServiceAddMatchingNotification(gNotifyPort, 89 | kIOTerminatedNotification, 90 | IOServiceMatching(kIOUSBDeviceClassName), 91 | DeviceRemoved, 92 | self, 93 | &gRemovedIter); 94 | if (kr != KERN_SUCCESS) return NO; 95 | 96 | DeviceAdded(self, gAddedIter); 97 | DeviceRemoved(self, gRemovedIter); 98 | mach_port_deallocate(mach_task_self(), masterPort); 99 | return YES; 100 | } 101 | 102 | - (void)unregisterForUSBNotifications { 103 | if (_runLoopSource != NULL) 104 | { 105 | CFRunLoopSourceInvalidate(_runLoopSource); 106 | CFRelease(_runLoopSource); 107 | } 108 | } 109 | 110 | - (void)refreshData:(BOOL)shouldForce { 111 | if (!shouldForce && [[NSUserDefaults standardUserDefaults] boolForKey:@"BusProbeAutoRefresh"] == NO) { 112 | return; 113 | } 114 | 115 | [_devicesArray removeAllObjects]; 116 | 117 | CFDictionaryRef matchingDict = NULL; 118 | mach_port_t mMasterDevicePort = MACH_PORT_NULL; 119 | io_iterator_t devIter = IO_OBJECT_NULL; 120 | io_service_t ioDeviceObj = IO_OBJECT_NULL; 121 | IOReturn kr; 122 | int deviceNumber = 0; //used to iterate through devices 123 | 124 | kr = IOMasterPort(MACH_PORT_NULL, &mMasterDevicePort); 125 | if (kr != kIOReturnSuccess) { 126 | NSLog(@"USB Prober: error in -refresh at IOMasterPort()"); 127 | return; 128 | } 129 | 130 | matchingDict = IOServiceMatching(kIOUSBDeviceClassName); 131 | if (matchingDict == NULL) { 132 | NSLog(@"USB Prober: error in -refresh at IOServiceMatching() - dictionary was NULL"); 133 | mach_port_deallocate(mach_task_self(), mMasterDevicePort); 134 | return; 135 | } 136 | 137 | kr = IOServiceGetMatchingServices(mMasterDevicePort, matchingDict /*reference consumed*/, &devIter); 138 | if (kr != kIOReturnSuccess) { 139 | NSLog(@"USB Prober: error in -refresh at IOServiceGetMatchingServices()"); 140 | mach_port_deallocate(mach_task_self(), mMasterDevicePort); 141 | return; 142 | } 143 | 144 | while ((ioDeviceObj = IOIteratorNext(devIter))) { 145 | IOCFPlugInInterface **ioPlugin; 146 | IOUSBDeviceRef deviceIntf = NULL; 147 | SInt32 score; 148 | NSString * prodName = NULL; 149 | 150 | kr = IOCreatePlugInInterfaceForService(ioDeviceObj, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ioPlugin, &score); 151 | if (kr != kIOReturnSuccess) { 152 | IOObjectRelease(ioDeviceObj); 153 | continue; 154 | } 155 | 156 | kr = (*ioPlugin)->QueryInterface(ioPlugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID *)&deviceIntf); 157 | IODestroyPlugInInterface(ioPlugin); 158 | ioPlugin = NULL; 159 | 160 | if (kr != kIOReturnSuccess) { 161 | IOObjectRelease(ioDeviceObj); 162 | continue; 163 | } 164 | 165 | // Get the product name from the registry in case we can't get it from the device later on 166 | prodName = GetUSBProductNameFromRegistry( ioDeviceObj); 167 | 168 | if ( prodName == NULL ) 169 | { 170 | io_name_t class; 171 | IOReturn status; 172 | status = IORegistryEntryGetNameInPlane(ioDeviceObj, kIOServicePlane, class); 173 | if ( status == kIOReturnSuccess ) 174 | prodName = [[NSString alloc] initWithCString:class encoding:NSUTF8StringEncoding]; 175 | else 176 | prodName = [[NSString alloc] initWithFormat:@"Unknown Device"]; 177 | } 178 | 179 | [self processDevice:deviceIntf deviceNumber:deviceNumber usbName:prodName]; 180 | deviceNumber++; 181 | [prodName release]; 182 | 183 | (*deviceIntf)->Release(deviceIntf); 184 | IOObjectRelease(ioDeviceObj); 185 | } 186 | 187 | IOObjectRelease(devIter); 188 | mach_port_deallocate(mach_task_self(), mMasterDevicePort); 189 | 190 | //[_listener busProberInformationDidChange:self]; 191 | } 192 | 193 | - (void)processDevice:(IOUSBDeviceRef)deviceIntf deviceNumber:(int)deviceNumber usbName:(NSString *)usbName { 194 | BusProbeDevice * thisDevice; 195 | UInt32 locationID = 0; 196 | uint32_t portInfo = 0; 197 | UInt8 speed = 0; 198 | USBDeviceAddress address = 0; 199 | IOUSBDeviceDescriptor dev; 200 | int len = 0; 201 | int currConfig; 202 | IOReturn error = kIOReturnSuccess, actErr = kIOReturnSuccess; 203 | BOOL needToSuspend = FALSE; 204 | 205 | thisDevice = [[BusProbeDevice alloc] init]; 206 | 207 | bzero(&dev, sizeof(dev)); 208 | 209 | [_devicesArray addObject:thisDevice]; 210 | 211 | // Get the locationID for this device 212 | if (GetDeviceLocationID( deviceIntf, &locationID ) == 0) { 213 | [thisDevice setLocationID:locationID]; 214 | } 215 | 216 | // Get the connection speed for this device 217 | if (GetDeviceSpeed( deviceIntf, &speed ) == 0) { 218 | [thisDevice setSpeed:speed]; 219 | } 220 | 221 | // Get the device address for this device 222 | if (GetDeviceAddress( deviceIntf, &address ) == 0) { 223 | [thisDevice setAddress:address]; 224 | } 225 | 226 | // Set the name of the device (this is what will be shown in the UI) 227 | [thisDevice setDeviceName: 228 | [NSString stringWithFormat:@"%s Speed device @ %d (0x%08X): .............................................", 229 | (speed == kUSBDeviceSpeedSuper ? "Super" : (speed == kUSBDeviceSpeedHigh ? "High" :(speed == kUSBDeviceSpeedFull ? "Full" : "Low"))), 230 | address, 231 | (unsigned int)locationID]]; 232 | 233 | // Get the Port Information 234 | error = GetPortInformation(deviceIntf, &portInfo); 235 | if (error == kIOReturnSuccess) { 236 | [thisDevice setPortInfo:portInfo]; 237 | 238 | [self PrintPortInfo:portInfo forDevice:thisDevice]; 239 | } 240 | else { 241 | char buf[256]; 242 | 243 | // Set the Port Information with the error we received and propagate this error. If we can't get the Port Information, then 244 | // we shouldn't go ahead and try to get the descriptors. This error is telling us that we can't talk to the hub or the device 245 | 246 | sprintf((char *)buf, "%s (0x%x)", USBErrorToString(error), error ); 247 | [thisDevice addProperty:"Port Information:" withValue:buf atDepth:ROOT_LEVEL]; 248 | 249 | //NSLog(@"USB Prober: GetUSBDeviceInformation() for device @%8x failed with %s", (uint32_t)[thisDevice locationID], USBErrorToString(error)); 250 | } 251 | 252 | // Log the number of endpoints for each configuration 253 | [self GetAndPrintNumberOfEndpoints:deviceIntf forDevice:thisDevice portInfo:portInfo]; 254 | 255 | // If the device is suspended, then unsuspend it first 256 | if ( portInfo & kUSBInformationDeviceIsSuspendedMask ) { 257 | if ([[NSUserDefaults standardUserDefaults] boolForKey:@"BusProbeSuspended"] == YES) { 258 | // Set this flag so we re-suspend the device later on 259 | needToSuspend = TRUE; 260 | 261 | error = SuspendDevice(deviceIntf,false); 262 | } 263 | else { 264 | error = kIOReturnNotResponding; 265 | } 266 | } 267 | 268 | // If we are not suspended, talk to our device and get the Device Desriptor 269 | if (error == kIOReturnSuccess) { 270 | error = GetDescriptor(deviceIntf, kUSBDeviceDesc, 0, &dev, sizeof(dev), &actErr); 271 | } 272 | 273 | // OK, go get the descriptors and run with it 274 | 275 | if ( error == kIOReturnSuccess ) 276 | { 277 | int iconfig; 278 | [DecodeDeviceDescriptor decodeBytes:&dev forDevice:thisDevice deviceInterface:deviceIntf wasSuspended:needToSuspend]; 279 | if (actErr != kIOReturnSuccess) { 280 | [thisDevice setDeviceDescription: [NSString stringWithFormat:@"%@ - Gave an error getting descriptor - %s (0x%x)", usbName, USBErrorToString(actErr), actErr]]; 281 | } 282 | 283 | IOUSBBOSDescriptor bosDescriptor; 284 | 285 | // If we have a SuperSpeed device, then go get and decode the BOS descriptors. We first read the root BOS descriptor, which tells us the length, and then we read 286 | // the full descriptor, just like we do for config descriptors 287 | if ( speed == kUSBDeviceSpeedSuper ) 288 | { 289 | error = GetDescriptor(deviceIntf, kUSBBOSDescriptor, 0, &bosDescriptor, sizeof(bosDescriptor), &actErr); 290 | if ( error == kIOReturnSuccess) 291 | { 292 | [DecodeBOSDescriptor decodeBytes:(IOUSBBOSDescriptor *)&bosDescriptor forDevice:thisDevice deviceInterface:deviceIntf]; 293 | } 294 | } 295 | 296 | // Check the current configuration 297 | currConfig = GetCurrentConfiguration(deviceIntf); 298 | if(currConfig < 1) // Almost everything has a current config of 1 299 | { 300 | char buf[256]; 301 | 302 | if(currConfig == -1) 303 | { 304 | // failed the request for some reason 305 | sprintf((char *)buf, "%s", "failed to get configuration" ); 306 | } 307 | else 308 | { 309 | sprintf((char *)buf, "%d (unconfigured)", (UInt8) currConfig ); 310 | } 311 | [thisDevice addProperty:"Current configuration:" withValue:buf atDepth:ROOT_LEVEL]; 312 | 313 | 314 | } 315 | // Go decode the Config Desriptor 316 | for (iconfig = 0; iconfig < dev.bNumConfigurations; ++iconfig) { 317 | IOUSBConfigurationDescHeader cfgHeader; 318 | IOUSBConfigurationDescriptor config; 319 | 320 | // Get the Configuration descriptor. We first get just the header and later we get the full 321 | // descriptor 322 | error = GetDescriptor(deviceIntf, kUSBConfDesc, iconfig, &cfgHeader, sizeof(cfgHeader), nil); 323 | if (error != kIOReturnSuccess) { 324 | // Set a flag to the decodeBytes descriptor indicating that we didn't get the header 325 | // 326 | cfgHeader.bDescriptorType = sizeof(cfgHeader); 327 | cfgHeader.wTotalLength = 0; 328 | [DecodeConfigurationDescriptor decodeBytes:(IOUSBConfigurationDescHeader *)&cfgHeader forDevice:thisDevice deviceInterface:deviceIntf configNumber:iconfig currentConfig:currConfig isOtherSpeedDesc:NO]; 329 | 330 | // Try to get the descriptor again, using the sizeof(IOUSBConfigurationDescriptor) 331 | // 332 | bzero(&config,sizeof(config)-1); 333 | error = GetDescriptor(deviceIntf, kUSBConfDesc, iconfig, &config, sizeof(config)-1, nil); 334 | if (error != kIOReturnSuccess) { 335 | cfgHeader.bDescriptorType = sizeof(config)-1; 336 | cfgHeader.wTotalLength = 0; 337 | } 338 | else { 339 | cfgHeader.bLength = config.bLength; 340 | cfgHeader.bDescriptorType = config.bDescriptorType; 341 | cfgHeader.wTotalLength = config.wTotalLength; 342 | } 343 | } 344 | [DecodeConfigurationDescriptor decodeBytes:(IOUSBConfigurationDescHeader *)&cfgHeader forDevice:thisDevice deviceInterface:deviceIntf configNumber:iconfig currentConfig:currConfig isOtherSpeedDesc:NO]; 345 | } 346 | 347 | // If the device is a hub, then dump the Hub descriptor 348 | // 349 | if ( dev.bDeviceClass == kUSBHubClass ) { 350 | 351 | if(dev.bDeviceProtocol == 3) 352 | { 353 | IOUSB3HubDescriptor cfg; 354 | len = GetClassDescriptor(deviceIntf, kUSB3HUBDesc, 0, &cfg, sizeof(cfg)); 355 | if (len > 0) { 356 | [DescriptorDecoder decodeBytes:(Byte *)&cfg forDevice:thisDevice deviceInterface:deviceIntf userInfo:NULL isOtherSpeedDesc:false isinCurrentConfig:false]; 357 | } 358 | } 359 | else 360 | { 361 | IOUSBHubDescriptor cfg; 362 | len = GetClassDescriptor(deviceIntf, kUSBHUBDesc, 0, &cfg, sizeof(cfg)); 363 | if (len > 0) { 364 | [DescriptorDecoder decodeBytes:(Byte *)&cfg forDevice:thisDevice deviceInterface:deviceIntf userInfo:NULL isOtherSpeedDesc:false isinCurrentConfig:false]; 365 | } 366 | } 367 | 368 | } 369 | 370 | // Check to see if the device has the "Device Qualifier" descriptor 371 | // 372 | if ( dev.bcdUSB >= kUSBRel20 && speed == kUSBDeviceSpeedHigh) { 373 | IOUSBDeviceQualifierDescriptor desc; 374 | 375 | error = GetDescriptor(deviceIntf, kUSBDeviceQualifierDesc, 0, &desc, sizeof(desc), nil); 376 | 377 | if (error == kIOReturnSuccess) { 378 | [DescriptorDecoder decodeBytes:(Byte *)&desc forDevice:thisDevice deviceInterface:deviceIntf userInfo:NULL isOtherSpeedDesc:false isinCurrentConfig:false]; 379 | 380 | // Since we have a Device Qualifier Descriptor, we can get a "Other Speed Configuration Descriptor" 381 | // (It's the same as a regular configuration descriptor) 382 | // 383 | int iconfig; 384 | 385 | for (iconfig = 0; iconfig < desc.bNumConfigurations; ++iconfig) { 386 | IOUSBConfigurationDescHeader cfgHeader; 387 | IOUSBConfigurationDescriptor config; 388 | 389 | // Get the Configuration descriptor. We first get just the header and later we get the full 390 | // descriptor 391 | error = GetDescriptor(deviceIntf, kUSBOtherSpeedConfDesc, iconfig, &cfgHeader, sizeof(cfgHeader), nil); 392 | if (error != kIOReturnSuccess) { 393 | // Set a flag to the decodeBytes descriptor indicating that we didn't get the header 394 | // 395 | cfgHeader.bDescriptorType = sizeof(cfgHeader); 396 | cfgHeader.wTotalLength = 0; 397 | 398 | // Note: currentConfig:-1 as this is never in the current config. 399 | [DecodeConfigurationDescriptor decodeBytes:(IOUSBConfigurationDescHeader *)&cfgHeader forDevice:thisDevice deviceInterface:deviceIntf configNumber:iconfig currentConfig:-1 isOtherSpeedDesc:YES]; 400 | 401 | // Try to get the descriptor again, using the sizeof(IOUSBConfigurationDescriptor) 402 | // 403 | bzero(&config,sizeof(config)-1); 404 | error = GetDescriptor(deviceIntf, kUSBOtherSpeedConfDesc, iconfig, &config, sizeof(config)-1, nil); 405 | if (error != kIOReturnSuccess) { 406 | cfgHeader.bDescriptorType = sizeof(config)-1; 407 | cfgHeader.wTotalLength = 0; 408 | } 409 | else { 410 | cfgHeader.bLength = config.bLength; 411 | cfgHeader.bDescriptorType = config.bDescriptorType; 412 | cfgHeader.wTotalLength = config.wTotalLength; 413 | } 414 | } 415 | [DecodeConfigurationDescriptor decodeBytes:(IOUSBConfigurationDescHeader *)&cfgHeader forDevice:thisDevice deviceInterface:deviceIntf configNumber:iconfig currentConfig:-1 isOtherSpeedDesc:YES]; 416 | } 417 | } 418 | } 419 | } 420 | else { 421 | if ( portInfo & (1<wTotalLength)); 560 | 561 | // Go through each interface, and count the number of endpoints. If we alternate settings, count the one with the highest number 562 | // of endpoints 563 | do 564 | { 565 | err = FindNextInterfaceDescriptor(desc, intfDesc, &descOut); 566 | if ( descOut && err == kIOReturnSuccess) 567 | { 568 | if ( interfaceNumber != descOut->bInterfaceNumber) 569 | { 570 | // This is a new interface, so now add the maxEndpoints from the previous one to our running total (totalEndpoints) 571 | interfaceNumber = descOut->bInterfaceNumber; 572 | totalEndpoints += maxEndpoints; 573 | maxEndpoints = 0; 574 | } 575 | 576 | if ( descOut->bAlternateSetting > 0 ) 577 | { 578 | // This means that we have already seen this interface #, so only update the numEndpoints if greater than what we saved 579 | if (descOut->bNumEndpoints > maxEndpoints ) 580 | maxEndpoints = descOut->bNumEndpoints; 581 | } 582 | else 583 | { 584 | maxEndpoints = descOut->bNumEndpoints; 585 | } 586 | 587 | // fprintf(stderr, "Found interface #%d, altSetting: %d, bNumEndpoints: %d\n", descOut->bInterfaceNumber, descOut->bAlternateSetting, descOut->bNumEndpoints); 588 | // dump((void*) descOut, descOut->bLength); 589 | // fprintf(stderr, "\tbInterfaceNumber: %d, maxEndpoints: %d, total: %d\n", descOut->bInterfaceNumber, maxEndpoints, totalEndpoints); 590 | 591 | // Start looking for the next interface descriptor after the current one 592 | intfDesc = descOut; 593 | } 594 | 595 | // If we get to the end, we will get a kIOUSBInterfaceNotFound. We still need to take into accountthe maxEndpoints for the last interface we iterated 596 | if ( err ==kIOUSBInterfaceNotFound ) 597 | totalEndpoints += maxEndpoints; 598 | } 599 | while ( err == kIOReturnSuccess && descOut != NULL); 600 | 601 | sprintf((char *)buf, "Total Endpoints for Configuration %d %s:", i+1, (unconfigured) ? "(unconfigured)" : ( (i == currentConfig) ? "(current)":"")); 602 | sprintf((char *)buf2, "%d", totalEndpoints ); 603 | 604 | [thisDevice addProperty:buf withValue:buf2 atDepth:ROOT_LEVEL+1]; 605 | } 606 | } 607 | - (NSMutableArray *) devicesArray { 608 | return _devicesArray; 609 | } 610 | 611 | @end 612 | -------------------------------------------------------------------------------- /USBBusProber/BusProberSharedFunctions.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/BusProberSharedFunctions.h -------------------------------------------------------------------------------- /USBBusProber/BusProberSharedFunctions.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/BusProberSharedFunctions.m -------------------------------------------------------------------------------- /USBBusProber/DecodeAudioInterfaceDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeAudioInterfaceDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeAudioInterfaceDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeAudioInterfaceDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DecodeBOSDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | #import 25 | #import "BusProberSharedFunctions.h" 26 | #import "BusProbeDevice.h" 27 | 28 | 29 | @interface DecodeBOSDescriptor : NSObject { 30 | 31 | } 32 | 33 | + (void)decodeBytes:(IOUSBBOSDescriptor *)bosDescriptor forDevice:(BusProbeDevice *)thisDevice deviceInterface:(IOUSBDeviceRef)deviceIntf; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /USBBusProber/DecodeBOSDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | #import "DescriptorDecoder.h" 25 | #import "DecodeBOSDescriptor.h" 26 | 27 | @implementation DecodeBOSDescriptor 28 | 29 | + (void)decodeBytes:(IOUSBBOSDescriptor *)bosDescriptor forDevice:(BusProbeDevice *)thisDevice deviceInterface:(IOUSBDeviceRef)deviceIntf { 30 | char buf[128]; 31 | UInt8 numCaps = bosDescriptor->bNumDeviceCaps; 32 | Byte *bosBuf = nil; 33 | Byte *p = nil; 34 | IOReturn ret = kIOReturnSuccess; 35 | int i; 36 | 37 | [thisDevice addProperty:"BOS Descriptor" withValue:"" atDepth:BOS_DESCRIPTOR_LEVEL-1]; 38 | 39 | if ( bosDescriptor->wTotalLength != 0 ) 40 | { 41 | // We have device capabilities, so let's get the full descriptor 42 | Swap16(&bosDescriptor->wTotalLength); 43 | bosBuf = malloc(bosDescriptor->wTotalLength*sizeof(Byte)); 44 | 45 | ret = GetDescriptor(deviceIntf, kUSBBOSDescriptor, 0, bosBuf, bosDescriptor->wTotalLength, nil); 46 | if ( ret != kIOReturnSuccess ) 47 | { 48 | fprintf(stderr,"Failed to get full BOS descriptor: 0x%x\n", ret); 49 | return; 50 | } 51 | 52 | sprintf(buf, "%u", bosDescriptor->wTotalLength); 53 | [thisDevice addProperty:"Length (and contents):" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL]; 54 | [DescriptorDecoder dumpRawBOSDescriptor:(IOUSBBOSDescriptor *)bosBuf forDevice:thisDevice atDepth:BOS_DESCRIPTOR_LEVEL+1]; 55 | 56 | sprintf(buf, "%u", (bosDescriptor->bNumDeviceCaps)); 57 | [thisDevice addProperty:"Number of Capability Descriptors:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL]; 58 | 59 | // point to the start of the caps 60 | // 61 | p = &bosBuf[5]; 62 | 63 | for ( i = 0 ; i < numCaps; i++) 64 | { 65 | IOUSBDeviceCapabilityDescriptorHeader *header = (IOUSBDeviceCapabilityDescriptorHeader *)p; 66 | 67 | sprintf(buf, "%u", (header->bDevCapabilityType)); 68 | 69 | switch (header->bDevCapabilityType) 70 | { 71 | case kUSBDeviceCapabilityWirelessUSB: 72 | { 73 | [thisDevice addProperty:"Wireless USB:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+1]; 74 | } 75 | break; 76 | 77 | case kUSBDeviceCapabilityUSB20Extension: 78 | { 79 | IOUSBDeviceCapabilityUSB2Extension * usb2Cap = (IOUSBDeviceCapabilityUSB2Extension*)p; 80 | UInt32 attributes = USBToHostLong(usb2Cap->bmAttributes); 81 | 82 | [thisDevice addProperty:"USB 2.0 Extension:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+1]; 83 | sprintf(buf, "0x%8.8x", (uint32_t)attributes); 84 | [thisDevice addProperty:"bmAttributes:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2]; 85 | if ( attributes &( 1 << kUSB20ExtensionLPMSupported) ) 86 | [thisDevice addProperty:"" withValue:"Bit 1: Link Power Management supported" atDepth:BOS_DESCRIPTOR_LEVEL+2]; 87 | } 88 | break; 89 | 90 | case kUSBDeviceCapabilitySuperSpeedUSB: 91 | { 92 | IOUSBDeviceCapabilitySuperSpeedUSB * sspeedCap = (IOUSBDeviceCapabilitySuperSpeedUSB*)p; 93 | UInt8 attributes = (sspeedCap->bmAttributes); 94 | UInt16 speedsSupported = USBToHostWord(sspeedCap->wSpeedsSupported); 95 | UInt8 speedFunctionalitySupport = sspeedCap->bFunctionalitySupport; 96 | UInt8 u1ExitLatency = sspeedCap->bU1DevExitLat; 97 | UInt16 u2ExitLatency = USBToHostWord(sspeedCap->wU2DevExitLat); 98 | 99 | [thisDevice addProperty:"SuperSpeed USB Device:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+1]; 100 | sprintf(buf, "0x%8.8x", attributes); 101 | [thisDevice addProperty:"bmAttributes:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2]; 102 | if ( attributes &( 1 << kUSBSuperSpeedLTMCapable) ) 103 | [thisDevice addProperty:"" withValue:"Bit 1: Latency Tolerance Messages supported" atDepth:BOS_DESCRIPTOR_LEVEL+2]; 104 | 105 | sprintf(buf, "0x%4.4x", speedsSupported); 106 | [thisDevice addProperty:"wSpeedsSupported:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2]; 107 | if ( speedsSupported & (1<containerID[0]); 167 | data2 = USBToHostWord(* (uint16_t *) &container->containerID[4]); 168 | data3 = USBToHostWord(* (uint16_t *) &container->containerID[6]); 169 | uuidLO = OSSwapBigToHostInt64(* (uint64_t *) &container->containerID[8]); 170 | 171 | 172 | sprintf((char *)buf, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12qx", data1, data2, data3, 173 | (uint32_t) ( (uuidLO & 0xffff000000000000ULL)>>48), (uuidLO & 0x0000FFFFFFFFFFFFULL) ); 174 | [thisDevice addProperty:"ContainerID:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+1]; 175 | } 176 | break; 177 | } 178 | 179 | // Look at the next cap 180 | p = p + header->bLength; 181 | } 182 | } 183 | 184 | // [thisDevice addNumberProperty:"Number of Ports:" value: hubDescriptor.numPorts size:sizeof(hubDescriptor.numPorts) atDepth:HUB_DESCRIPTOR_LEVEL usingStyle:kHexOutputStyle]; 185 | if (bosBuf != nil) { 186 | free(bosBuf); 187 | bosBuf = nil; 188 | } 189 | } 190 | 191 | @end 192 | -------------------------------------------------------------------------------- /USBBusProber/DecodeCommClassDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeCommClassDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeCommClassDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeCommClassDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DecodeConfigurationDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeConfigurationDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeConfigurationDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeConfigurationDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DecodeDeviceDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeDeviceDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeDeviceDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeDeviceDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DecodeDeviceQualifierDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeDeviceQualifierDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeDeviceQualifierDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeDeviceQualifierDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DecodeEndpointDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeEndpointDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeEndpointDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeEndpointDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DecodeHIDDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeHIDDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeHIDDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeHIDDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DecodeHubDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeHubDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeHubDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeHubDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DecodeInterfaceDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeInterfaceDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeInterfaceDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeInterfaceDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DecodeVideoInterfaceDescriptor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeVideoInterfaceDescriptor.h -------------------------------------------------------------------------------- /USBBusProber/DecodeVideoInterfaceDescriptor.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DecodeVideoInterfaceDescriptor.m -------------------------------------------------------------------------------- /USBBusProber/DescriptorDecoder.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DescriptorDecoder.h -------------------------------------------------------------------------------- /USBBusProber/DescriptorDecoder.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/DescriptorDecoder.m -------------------------------------------------------------------------------- /USBBusProber/ExtensionSelector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011-2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | #import 25 | 26 | @interface ExtensionSelector : NSView 27 | { 28 | NSPopUpButton *extensionSelectionButton; 29 | NSSavePanel *theSavePanel; 30 | NSDictionary *itemDictionary; 31 | } 32 | @property (nonatomic, retain) NSPopUpButton *extensionSelectionButton; 33 | @property (nonatomic, retain) NSSavePanel *theSavePanel; 34 | @property (nonatomic, retain) NSDictionary *itemDictionary; 35 | 36 | -(void)populatePopuButtonWithArray:(NSDictionary *)addItems; 37 | -(void)setCurrentSelection:(NSString *)currentSelection; 38 | @end 39 | -------------------------------------------------------------------------------- /USBBusProber/ExtensionSelector.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011-2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | #import "ExtensionSelector.h" 25 | 26 | @implementation ExtensionSelector 27 | @synthesize extensionSelectionButton, theSavePanel, itemDictionary; 28 | 29 | - (id)initWithFrame:(NSRect)frame 30 | { 31 | self = [super initWithFrame:frame]; 32 | if (self) 33 | { 34 | // Initialization code here. 35 | NSPopUpButton *myButtonToBe; 36 | NSRect newFrame; 37 | newFrame.origin.x = 10.0; 38 | newFrame.origin.y = 10.0; 39 | newFrame.size.height = 22; 40 | newFrame.size.width = 220; 41 | myButtonToBe = [[NSPopUpButton alloc] initWithFrame:newFrame]; 42 | self.extensionSelectionButton = [myButtonToBe autorelease]; 43 | [self.extensionSelectionButton setTarget:self]; 44 | [self.extensionSelectionButton setAction:@selector(popupAction:)]; 45 | 46 | } 47 | 48 | return self; 49 | } 50 | 51 | - (void)drawRect:(NSRect)dirtyRect 52 | { 53 | // Drawing code here. 54 | } 55 | 56 | 57 | - (void)viewDidMoveToSuperview 58 | { 59 | NSRect currentFrame = self.frame; 60 | NSRect superViewFrame = [self.superview frame]; 61 | NSRect textViewFrame; 62 | textViewFrame.origin.x = 10.0; 63 | textViewFrame.origin.y = 5.0; 64 | textViewFrame.size.height = 22; 65 | textViewFrame.size.width = 70; 66 | NSTextView *theLabel = [[NSTextView alloc] initWithFrame:textViewFrame]; 67 | [theLabel setString:@"File Type:"]; 68 | [theLabel setEditable:NO]; 69 | [theLabel setDrawsBackground:NO]; 70 | [self addSubview:[theLabel autorelease]]; 71 | textViewFrame = [self.extensionSelectionButton frame]; 72 | textViewFrame.origin.x = textViewFrame.origin.x + 75; 73 | [self.extensionSelectionButton setFrame:textViewFrame]; 74 | currentFrame.size.height = 40; 75 | currentFrame.size.width = superViewFrame.size.width; 76 | [self setFrame:currentFrame]; 77 | [self addSubview:self.extensionSelectionButton]; 78 | [[self superview] setAutoresizesSubviews:YES]; 79 | [self setAutoresizingMask:NSViewWidthSizable | NSViewMaxXMargin]; 80 | } 81 | 82 | -(void)populatePopuButtonWithArray:(NSDictionary *)addItems 83 | { 84 | [self.extensionSelectionButton removeAllItems]; 85 | [self.extensionSelectionButton addItemsWithTitles:[addItems allKeys]]; 86 | self.itemDictionary = addItems; 87 | } 88 | 89 | -(void)setCurrentSelection:(NSString *)currentSelection 90 | { 91 | [self.extensionSelectionButton setTitle:currentSelection]; 92 | } 93 | 94 | -(IBAction)popupAction:(id)sender 95 | { 96 | NSString *nameField = [[self.theSavePanel nameFieldStringValue] stringByDeletingPathExtension]; 97 | [self.theSavePanel setNameFieldStringValue:[nameField stringByAppendingPathExtension:[self.itemDictionary valueForKey:[self.extensionSelectionButton titleOfSelectedItem]]]]; 98 | } 99 | 100 | -(void)dealloc 101 | { 102 | self.extensionSelectionButton = nil; 103 | self.theSavePanel = nil; 104 | self.itemDictionary = nil; 105 | [super dealloc]; 106 | } 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /USBBusProber/OutlineViewAdditions.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/OutlineViewAdditions.h -------------------------------------------------------------------------------- /USBBusProber/OutlineViewAdditions.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright � 1998-2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | #import "OutlineViewAdditions.h" 25 | 26 | 27 | @implementation NSOutlineView(OutlineViewAdditions) 28 | 29 | - (void)itemDoubleClicked { 30 | int selectedRow = (int)[self selectedRow]; 31 | 32 | if (![self isExpandable:[self itemAtRow:selectedRow]]) { 33 | return; 34 | } else if ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) { 35 | if ([self isItemExpanded:[self itemAtRow:selectedRow]]) 36 | [self collapseItem:[self itemAtRow:selectedRow]]; 37 | [self expandItem:[self itemAtRow:selectedRow] expandChildren:YES]; 38 | } else { 39 | if ([self isItemExpanded:[self itemAtRow:selectedRow]]) 40 | [self collapseItem:[self itemAtRow:selectedRow]]; 41 | else 42 | [self expandItem:[self itemAtRow:selectedRow]]; 43 | } 44 | } 45 | 46 | - (void)copy:(id)sender { 47 | NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; 48 | NSMutableString *pasteboardString = [[NSMutableString alloc] init]; 49 | NSIndexSet *indexSet; 50 | id anItem; 51 | 52 | indexSet = [self selectedRowIndexes]; 53 | NSUInteger current = [indexSet firstIndex]; 54 | 55 | [pasteboard declareTypes: [NSArray arrayWithObject: NSStringPboardType] owner: NULL]; 56 | while (current != NSNotFound) { 57 | int i; 58 | int levelForRow = (int)[self levelForRow:current]; 59 | for (i=0;i= [_children count]) { 102 | return nil; 103 | } else { 104 | return [_children objectAtIndex:i]; 105 | } 106 | } 107 | 108 | - (void)removeAllChildren { 109 | [_children removeAllObjects]; 110 | } 111 | 112 | - (BOOL)isExpandable { 113 | return [_children count] != 0; 114 | } 115 | 116 | - (void)addNode:(OutlineViewNode *)aNode atDepth:(int)depth { 117 | OutlineViewNode *walker; 118 | int counter=0; 119 | 120 | walker = self; 121 | for (counter=0; counter < depth; counter++) { 122 | walker = [walker childAtIndex:[walker childrenCount]-1]; 123 | } 124 | 125 | // NSLog(@"Attaching %@ to %@",[aNode name],[walker value]); 126 | [walker addChild:aNode]; 127 | } 128 | 129 | - (NSString*)stringRepresentation:(NSString*)name startingLevel:(int)startingLevel 130 | { 131 | int i; 132 | NSMutableString *finalText = [[NSMutableString alloc] init]; 133 | OutlineViewNode * childNode; 134 | int childrenCount = [self childrenCount]; 135 | 136 | for (i=0; i < childrenCount; i++) { 137 | childNode = [self childAtIndex:i]; 138 | 139 | if ( [[childNode name] caseInsensitiveCompare:name] == NSOrderedSame ) 140 | { 141 | [finalText appendFormat:@"%@ %@",[childNode name],[childNode value]]; 142 | } 143 | 144 | if ([childNode isExpandable]) { 145 | [finalText appendString:[childNode stringRepresentation:name startingLevel:startingLevel+1]]; 146 | } 147 | } 148 | return [finalText autorelease]; 149 | } 150 | 151 | - (void)addNodeWithName:(char *)name value:(char *)value atDepth:(int)depth { 152 | OutlineViewNode *aNode; 153 | 154 | _tempName = [[NSString alloc] initWithCString:name encoding:NSUTF8StringEncoding]; 155 | _tempValue = [[NSString alloc] initWithCString:value encoding:NSUTF8StringEncoding]; 156 | aNode = [[OutlineViewNode alloc] initWithName:_tempName value:_tempValue]; 157 | 158 | [self addNode:aNode atDepth:depth]; 159 | 160 | [aNode release]; 161 | [_tempName release]; 162 | [_tempValue release]; 163 | } 164 | 165 | - (OutlineViewNode *)deepestChild { 166 | OutlineViewNode *retNode = self; 167 | while ([retNode isExpandable]) { 168 | retNode = [retNode childAtIndex:[retNode childrenCount]-1]; 169 | } 170 | return retNode; 171 | } 172 | 173 | - (NSString *)stringRepresentation:(int)startingLevel { 174 | int i; 175 | NSMutableString *finalText = [[NSMutableString alloc] init]; 176 | OutlineViewNode * childNode; 177 | int childrenCount = [self childrenCount]; 178 | 179 | for (i=0; i < childrenCount; i++) { 180 | int counter; 181 | for (counter=0; counter <= startingLevel; counter++) 182 | [finalText appendString:@" "]; 183 | 184 | childNode = [self childAtIndex:i]; 185 | [finalText appendFormat:@"%@ %@\n",[childNode name],[childNode value]]; 186 | 187 | if ([childNode isExpandable]) { 188 | [finalText appendString:[childNode stringRepresentation:startingLevel+1]]; 189 | } 190 | } 191 | return [finalText autorelease]; 192 | } 193 | 194 | - (NSString *)stringRepresentationOfValues:(int)startingLevel { 195 | int i; 196 | NSMutableString *finalText = [[NSMutableString alloc] init]; 197 | OutlineViewNode * childNode; 198 | int childrenCount = [self childrenCount]; 199 | 200 | for (i=0; i < childrenCount; i++) { 201 | int counter; 202 | for (counter=0; counter < startingLevel; counter++) 203 | [finalText appendString:@" "]; 204 | 205 | childNode = [self childAtIndex:i]; 206 | [finalText appendFormat:@"%@\n",[childNode value]]; 207 | 208 | if ([childNode isExpandable]) { 209 | [finalText appendString:[childNode stringRepresentationOfValues:startingLevel+1]]; 210 | } 211 | } 212 | return [finalText autorelease]; 213 | } 214 | 215 | - (NSMutableDictionary *)dictionaryVersionOfMe 216 | { 217 | NSMutableDictionary *returnDict = [NSMutableDictionary dictionary]; 218 | [returnDict setObject:[self name] forKey:@"nodeName"]; 219 | [returnDict setObject:[self value] forKey:@"nodeValue"]; 220 | [returnDict setObject:[NSMutableArray array] forKey:@"children"]; 221 | NSEnumerator *childObjectEnum = [[self children] objectEnumerator]; 222 | OutlineViewNode *eachChild; 223 | while ((eachChild = [childObjectEnum nextObject])) 224 | { 225 | if ([eachChild childrenCount] > 0) 226 | { 227 | [[returnDict objectForKey:@"children"] addObject:[eachChild dictionaryVersionOfMe]]; 228 | } 229 | else 230 | { 231 | if ([eachChild name] == nil || [[eachChild name] isEqualToString:@""]) 232 | { 233 | [[returnDict objectForKey:@"children"] addObject:[eachChild value]]; 234 | } 235 | else 236 | { 237 | [[returnDict objectForKey:@"children"] addObject:[NSMutableDictionary dictionaryWithObject:[eachChild value] forKey:[eachChild name]]]; 238 | } 239 | } 240 | } 241 | return returnDict; 242 | } 243 | 244 | @end 245 | -------------------------------------------------------------------------------- /USBBusProber/TableViewWithCopying.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrRay/VVUVCKit/fa750e878fee7405541741efaf1dde4ee3f637bb/USBBusProber/TableViewWithCopying.h -------------------------------------------------------------------------------- /USBBusProber/TableViewWithCopying.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright � 1998-2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | 24 | 25 | #import "TableViewWithCopying.h" 26 | 27 | 28 | @implementation TableViewWithCopying 29 | 30 | - (IBAction)copy:(id)sender { 31 | NSMutableString *pasteboardString = [[NSMutableString alloc] init]; 32 | NSIndexSet *indexSet; 33 | BOOL doneOneRow = NO; 34 | 35 | indexSet = [self selectedRowIndexes]; 36 | NSUInteger current = [indexSet firstIndex]; 37 | 38 | while (current != NSNotFound) { 39 | NSMutableString *thisRow = [[NSMutableString alloc] init]; 40 | NSEnumerator *columnEnumerator = [[self tableColumns] objectEnumerator]; 41 | id column; 42 | BOOL doneOneCol = NO; 43 | 44 | if (doneOneRow) { 45 | [thisRow appendString:@"\n"]; 46 | } 47 | 48 | while (column = [columnEnumerator nextObject]) { 49 | if (doneOneCol) { 50 | [thisRow appendString:@" "]; 51 | } 52 | [thisRow appendFormat:@"%@",[[self dataSource] tableView:self objectValueForTableColumn:column row:current]]; 53 | doneOneCol= YES; 54 | } 55 | 56 | [pasteboardString appendString:thisRow]; 57 | doneOneRow= YES; 58 | 59 | current = [indexSet indexGreaterThanIndex: current]; 60 | [thisRow release]; 61 | } 62 | 63 | [[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self]; 64 | 65 | [[NSPasteboard generalPasteboard] setString:pasteboardString forType:@"NSStringPboardType"]; 66 | 67 | [pasteboardString release]; 68 | } 69 | 70 | - (NSString *)stringRepresentation { 71 | NSMutableString *finalString = [[NSMutableString alloc] init]; 72 | int row; 73 | BOOL doneOneRow = NO; 74 | int numberOfRows = (int)[self numberOfRows]; 75 | 76 | for (row = 0; row < numberOfRows; row++) { 77 | NSMutableString *thisRow = [[NSMutableString alloc] init]; 78 | NSEnumerator *columnEnumerator = [[self tableColumns] objectEnumerator]; 79 | id column; 80 | BOOL doneOneCol = NO; 81 | 82 | if (doneOneRow) { 83 | [thisRow appendString:@"\n"]; 84 | } 85 | 86 | while (column = [columnEnumerator nextObject]) { 87 | if (doneOneCol) { 88 | [thisRow appendString:@" "]; 89 | } 90 | [thisRow appendFormat:@"%@",[[self dataSource] tableView:self objectValueForTableColumn:column row:row]]; 91 | doneOneCol= YES; 92 | } 93 | 94 | [finalString appendString:thisRow]; 95 | doneOneRow= YES; 96 | [thisRow release]; 97 | } 98 | 99 | return [finalString autorelease]; 100 | } 101 | 102 | - (BOOL)validateMenuItem:(NSMenuItem *)menuItem { 103 | if ([NSStringFromSelector([menuItem action]) isEqualToString:@"copy:"]) { 104 | return ([self selectedRow] != -1); 105 | } else { 106 | return YES; 107 | } 108 | } 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /USBBusProber/USBBusProber-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSHumanReadableCopyright 26 | Copyright © 2014 Vidvox. All rights reserved. 27 | NSPrincipalClass 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /USBBusProber/USBBusProber-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'USBBusProber' target in the 'USBBusProber' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /USBBusProber/USBBusProber.h: -------------------------------------------------------------------------------- 1 | 2 | #import "BusProberSharedFunctions.h" 3 | //#import "BusProbeController.h" 4 | #import "BusProber.h" 5 | //#import "BusProbeDevice.h" 6 | //#import "BusProbeClass.h" 7 | -------------------------------------------------------------------------------- /USBBusProber/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /UVC Test App/AVCaptureVideoSource.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | 6 | 7 | 8 | extern CVOpenGLTextureCacheRef _textureCache; 9 | 10 | 11 | 12 | 13 | @protocol AVCaptureVideoSourceDelegate 14 | - (void) listOfStaticSourcesUpdated:(id)videoSource; 15 | @end 16 | 17 | 18 | 19 | 20 | @interface AVCaptureVideoSource : NSObject { 21 | OSSpinLock propLock; 22 | id propDelegate; 23 | BOOL propRunning; 24 | 25 | AVCaptureDeviceInput *propDeviceInput; 26 | AVCaptureSession *propSession; 27 | AVCaptureVideoDataOutput *propOutput; 28 | dispatch_queue_t propQueue; 29 | CVOpenGLTextureRef propTexture; 30 | } 31 | 32 | - (void) loadDeviceWithUniqueID:(NSString *)n; 33 | - (void) stop; 34 | - (void) _stop; 35 | 36 | - (BOOL) running; 37 | - (void) setDelegate:(id)n; 38 | - (NSArray *) arrayOfSourceMenuItems; 39 | 40 | - (CVOpenGLTextureRef) safelyGetRetainedTextureRef; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /UVC Test App/AVCaptureVideoSource.m: -------------------------------------------------------------------------------- 1 | #import "AVCaptureVideoSource.h" 2 | 3 | 4 | 5 | 6 | CVOpenGLTextureCacheRef _textureCache = nil; 7 | 8 | 9 | 10 | 11 | @implementation AVCaptureVideoSource 12 | 13 | 14 | - (id) init { 15 | if (self = [super init]) { 16 | propLock = OS_SPINLOCK_INIT; 17 | propDelegate = nil; 18 | propRunning = NO; 19 | propDeviceInput = nil; 20 | propSession = nil; 21 | propOutput = nil; 22 | propQueue = nil; 23 | propTexture = nil; 24 | return self; 25 | } 26 | [self release]; 27 | return nil; 28 | } 29 | - (void) dealloc { 30 | [self stop]; 31 | 32 | OSSpinLockLock(&propLock); 33 | if (propTexture != nil) { 34 | CVOpenGLTextureRelease(propTexture); 35 | propTexture = nil; 36 | } 37 | OSSpinLockUnlock(&propLock); 38 | [super dealloc]; 39 | } 40 | 41 | 42 | /*===================================================================================*/ 43 | #pragma mark --------------------- control messages 44 | /*------------------------------------*/ 45 | 46 | 47 | - (void) loadDeviceWithUniqueID:(NSString *)n { 48 | if ([self running]) 49 | [self stop]; 50 | if (n==nil) 51 | return; 52 | BOOL bail = NO; 53 | NSError *err = nil; 54 | OSSpinLockLock(&propLock); 55 | AVCaptureDevice *propDevice = [AVCaptureDevice deviceWithUniqueID:n]; 56 | propDeviceInput = (propDevice==nil) ? nil : [[AVCaptureDeviceInput alloc] initWithDevice:propDevice error:&err]; 57 | if (propDeviceInput != nil) { 58 | propSession = [[AVCaptureSession alloc] init]; 59 | propOutput = [[AVCaptureVideoDataOutput alloc] init]; 60 | 61 | if (![propSession canAddInput:propDeviceInput]) { 62 | NSLog(@"\t\tproblem adding propDeviceInput in %s",__func__); 63 | bail = YES; 64 | } 65 | if (![propSession canAddOutput:propOutput]) { 66 | NSLog(@"\t\tproblem adding propOutput in %s",__func__); 67 | bail = YES; 68 | } 69 | 70 | if (!bail) { 71 | propQueue = dispatch_queue_create([[[NSBundle mainBundle] bundleIdentifier] UTF8String], NULL); 72 | [propOutput setSampleBufferDelegate:self queue:propQueue]; 73 | 74 | [propSession addInput:propDeviceInput]; 75 | [propSession addOutput:propOutput]; 76 | [propSession startRunning]; 77 | } 78 | } 79 | else 80 | bail = YES; 81 | OSSpinLockUnlock(&propLock); 82 | 83 | if (bail) 84 | [self stop]; 85 | else 86 | [self start]; 87 | } 88 | 89 | 90 | - (void) start { 91 | //NSLog(@"%s ... %@",__func__,self); 92 | OSSpinLockLock(&propLock); 93 | if (!propRunning) { 94 | [self _start]; 95 | propRunning = YES; 96 | } 97 | else 98 | NSLog(@"\t\tERR: starting something that wasn't stopped, %s",__func__); 99 | OSSpinLockUnlock(&propLock); 100 | } 101 | - (void) stop { 102 | //NSLog(@"%s ... %@",__func__,self); 103 | OSSpinLockLock(&propLock); 104 | if (propRunning) { 105 | [self _stop]; 106 | propRunning = NO; 107 | } 108 | else 109 | NSLog(@"\t\tERR: stopping something that wasn't running, %s",__func__); 110 | OSSpinLockUnlock(&propLock); 111 | } 112 | 113 | 114 | /*===================================================================================*/ 115 | #pragma mark --------------------- backend 116 | /*------------------------------------*/ 117 | 118 | 119 | - (void) _start { 120 | 121 | } 122 | - (void) _stop { 123 | if (propSession != nil) { 124 | [propSession stopRunning]; 125 | if (propDeviceInput != nil) 126 | [propSession removeInput:propDeviceInput]; 127 | if (propOutput != nil) 128 | [propSession removeOutput:propOutput]; 129 | 130 | dispatch_release(propQueue); 131 | propQueue = NULL; 132 | 133 | [propDeviceInput release]; 134 | propDeviceInput = nil; 135 | [propOutput release]; 136 | propOutput = nil; 137 | [propSession release]; 138 | propSession = nil; 139 | } 140 | } 141 | 142 | 143 | /*===================================================================================*/ 144 | #pragma mark --------------------- AVCaptureVideoDataOutputSampleBufferDelegate protocol (and AVCaptureFileOutputDelegate, too- some protocols share these methods) 145 | /*------------------------------------*/ 146 | 147 | 148 | - (void)captureOutput:(AVCaptureOutput *)o didDropSampleBuffer:(CMSampleBufferRef)b fromConnection:(AVCaptureConnection *)c { 149 | NSLog(@"%s",__func__); 150 | } 151 | - (void)captureOutput:(AVCaptureOutput *)o didOutputSampleBuffer:(CMSampleBufferRef)b fromConnection:(AVCaptureConnection *)c { 152 | //NSLog(@"%s",__func__); 153 | /* 154 | CMFormatDescriptionRef portFormatDesc = CMSampleBufferGetFormatDescription(b); 155 | NSLog(@"\t\t\tCMMediaType is %ld, video is %ld",CMFormatDescriptionGetMediaType(portFormatDesc),kCMMediaType_Video); 156 | NSLog(@"\t\t\tthe FourCharCode for the media subtype is %ld",CMFormatDescriptionGetMediaSubType(portFormatDesc)); 157 | CMVideoDimensions vidDims = CMVideoFormatDescriptionGetDimensions(portFormatDesc); 158 | NSLog(@"\t\t\tport size is %d x %d",vidDims.width,vidDims.height); 159 | */ 160 | 161 | 162 | // if this came from a connection belonging to the data output 163 | //VVBuffer *newBuffer = nil; 164 | //CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(b) 165 | CVImageBufferRef imgBufferRef = CMSampleBufferGetImageBuffer(b); 166 | if (imgBufferRef != NULL) { 167 | //CGSize imgBufferSize = CVImageBufferGetDisplaySize(imgBufferRef); 168 | //NSSizeLog(@"\t\timg buffer size is",imgBufferSize); 169 | CVOpenGLTextureRef cvTexRef = NULL; 170 | CVReturn err = kCVReturnSuccess; 171 | 172 | 173 | err = CVOpenGLTextureCacheCreateTextureFromImage(NULL,_textureCache,imgBufferRef,NULL,&cvTexRef); 174 | if (err != kCVReturnSuccess) { 175 | NSLog(@"\t\terr %d at CVOpenGLTextureCacheCreateTextureFromImage() in %s",err,__func__); 176 | } 177 | else { 178 | OSSpinLockLock(&propLock); 179 | if (propTexture != nil) { 180 | CVOpenGLTextureRelease(propTexture); 181 | propTexture = nil; 182 | } 183 | propTexture = cvTexRef; 184 | //CVOpenGLTextureRelease(cvTexRef); 185 | OSSpinLockUnlock(&propLock); 186 | } 187 | } 188 | CVOpenGLTextureCacheFlush(_textureCache,0); 189 | 190 | 191 | } 192 | 193 | 194 | /*===================================================================================*/ 195 | #pragma mark --------------------- key-val-ish 196 | /*------------------------------------*/ 197 | 198 | 199 | - (BOOL) running { 200 | BOOL returnMe; 201 | OSSpinLockLock(&propLock); 202 | returnMe = propRunning; 203 | OSSpinLockUnlock(&propLock); 204 | return returnMe; 205 | } 206 | - (void) setDelegate:(id)n { 207 | OSSpinLockLock(&propLock); 208 | propDelegate = n; 209 | OSSpinLockUnlock(&propLock); 210 | } 211 | - (NSArray *) arrayOfSourceMenuItems { 212 | NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; 213 | if (devices==nil || [devices count]<1) 214 | return nil; 215 | NSMutableArray *returnMe = [NSMutableArray arrayWithCapacity:0]; 216 | for (AVCaptureDevice *devicePtr in devices) { 217 | NSMenuItem *newItem = [[NSMenuItem alloc] initWithTitle:[devicePtr localizedName] action:nil keyEquivalent:@""]; 218 | NSString *uniqueID = [devicePtr uniqueID]; 219 | [newItem setRepresentedObject:uniqueID]; 220 | [returnMe addObject:newItem]; 221 | [newItem release]; 222 | } 223 | return returnMe; 224 | } 225 | - (CVOpenGLTextureRef) safelyGetRetainedTextureRef { 226 | CVOpenGLTextureRef returnMe = NULL; 227 | OSSpinLockLock(&propLock); 228 | if (propTexture != nil) { 229 | returnMe = propTexture; 230 | CVOpenGLTextureRetain(returnMe); 231 | } 232 | OSSpinLockUnlock(&propLock); 233 | return returnMe; 234 | } 235 | 236 | 237 | @end 238 | -------------------------------------------------------------------------------- /UVC Test App/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import "AVCaptureVideoSource.h" 5 | #import "CVGLView.h" 6 | 7 | 8 | 9 | 10 | @interface AppDelegate : NSObject { 11 | CVDisplayLinkRef displayLink; 12 | NSOpenGLContext *sharedContext; 13 | NSOpenGLPixelFormat *pixelFormat; 14 | 15 | AVCaptureVideoSource *vidSrc; // uses AVCapture API to get video from camera & play it back in the gl view 16 | VVUVCController *uvcController; // this is the example of how to use this class. ironic that it's such a small part of the demo app. 17 | 18 | IBOutlet NSPopUpButton *camPUB; // pop-up button with the list of available cameras 19 | IBOutlet CVGLView *glView; // the gl view used to display GL textures received from the camera 20 | } 21 | 22 | - (IBAction) camPUBUsed:(id)sender; 23 | - (void) renderCallback; 24 | 25 | - (void) populateCamPopUpButton; 26 | 27 | - (NSOpenGLContext *) sharedContext; 28 | - (NSOpenGLPixelFormat *) pixelFormat; 29 | 30 | @end 31 | 32 | 33 | 34 | CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext); 35 | -------------------------------------------------------------------------------- /UVC Test App/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | 4 | 5 | 6 | @implementation AppDelegate 7 | 8 | 9 | - (id) init { 10 | if (self = [super init]) { 11 | displayLink = nil; 12 | sharedContext = nil; 13 | pixelFormat = nil; 14 | vidSrc = nil; 15 | uvcController = nil; 16 | 17 | 18 | // generate the GL display mask for all displays 19 | CGError cgErr = kCGErrorSuccess; 20 | CGDirectDisplayID dspys[10]; 21 | CGDisplayCount count = 0; 22 | GLuint glDisplayMask = 0; 23 | cgErr = CGGetActiveDisplayList(10,dspys,&count); 24 | if (cgErr == kCGErrorSuccess) { 25 | int i; 26 | for (i=0;i 2 | #import 3 | 4 | 5 | 6 | 7 | @interface CVGLView : NSOpenGLView { 8 | IBOutlet id appDelegate; 9 | OSSpinLock renderLock; 10 | BOOL initialized; 11 | } 12 | 13 | + (NSRect) rectThatFitsRect:(NSRect)a inRect:(NSRect)b; 14 | - (void) drawTextureRef:(CVOpenGLTextureRef)n; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /UVC Test App/CVGLView.m: -------------------------------------------------------------------------------- 1 | #import "CVGLView.h" 2 | #import "AppDelegate.h" 3 | 4 | 5 | 6 | 7 | #define VVMINX(r) ((r.size.width>=0) ? (r.origin.x) : (r.origin.x+r.size.width)) 8 | #define VVMAXX(r) ((r.size.width>=0) ? (r.origin.x+r.size.width) : (r.origin.x)) 9 | #define VVMINY(r) ((r.size.height>=0) ? (r.origin.y) : (r.origin.y+r.size.height)) 10 | #define VVMAXY(r) ((r.size.height>=0) ? (r.origin.y+r.size.height) : (r.origin.y)) 11 | #define VVMIDX(r) (r.origin.x+(r.size.width/2.0)) 12 | #define VVMIDY(r) (r.origin.y+(r.size.height/2.0)) 13 | #define GLDRAWTEXQUADMACRO(texName,texTarget,texFlipped,src,dst) \ 14 | { \ 15 | GLuint localMacroTexTarget=texTarget; \ 16 | NSRect localMacroSrc=src; \ 17 | NSRect localMacroDst=dst; \ 18 | BOOL localMacroFlip=texFlipped; \ 19 | GLfloat vvMacroVerts[]={ \ 20 | VVMINX(localMacroDst), VVMINY(localMacroDst), 0.0, \ 21 | VVMAXX(localMacroDst), VVMINY(localMacroDst), 0.0, \ 22 | VVMAXX(localMacroDst), VVMAXY(localMacroDst), 0.0, \ 23 | VVMINX(localMacroDst), VVMAXY(localMacroDst), 0.0}; \ 24 | GLfloat vvMacroTexs[]={ \ 25 | VVMINX(localMacroSrc), (localMacroFlip ? VVMAXY(localMacroSrc) : VVMINY(localMacroSrc)), \ 26 | VVMAXX(localMacroSrc), (localMacroFlip ? VVMAXY(localMacroSrc) : VVMINY(localMacroSrc)), \ 27 | VVMAXX(localMacroSrc), (localMacroFlip ? VVMINY(localMacroSrc) : VVMAXY(localMacroSrc)), \ 28 | VVMINX(localMacroSrc), (localMacroFlip ? VVMINY(localMacroSrc) : VVMAXY(localMacroSrc))}; \ 29 | glVertexPointer(3,GL_FLOAT,0,vvMacroVerts); \ 30 | glTexCoordPointer(2,GL_FLOAT,0,vvMacroTexs); \ 31 | glBindTexture(localMacroTexTarget,texName); \ 32 | glDrawArrays(GL_QUADS,0,4); \ 33 | glBindTexture(localMacroTexTarget,0); \ 34 | } 35 | 36 | 37 | 38 | 39 | @implementation CVGLView 40 | 41 | 42 | + (NSRect) rectThatFitsRect:(NSRect)a inRect:(NSRect)b { 43 | NSRect returnMe = NSMakeRect(0,0,0,0); 44 | double bAspect = b.size.width/b.size.height; 45 | double aAspect = a.size.width/a.size.height; 46 | 47 | // if the rect i'm trying to fit stuff *into* is wider than the rect i'm resizing 48 | if (bAspect > aAspect) { 49 | returnMe.size.height = b.size.height; 50 | returnMe.size.width = returnMe.size.height * aAspect; 51 | } 52 | // else if the rect i'm resizing is wider than the rect it's going into 53 | else if (bAspect < aAspect) { 54 | returnMe.size.width = b.size.width; 55 | returnMe.size.height = returnMe.size.width / aAspect; 56 | } 57 | else { 58 | returnMe.size.width = b.size.width; 59 | returnMe.size.height = b.size.height; 60 | } 61 | returnMe.origin.x = (b.size.width-returnMe.size.width)/2.0+b.origin.x; 62 | returnMe.origin.y = (b.size.height-returnMe.size.height)/2.0+b.origin.y; 63 | 64 | return returnMe; 65 | } 66 | 67 | 68 | - (id) initWithFrame:(NSRect)f { 69 | if (self = [super initWithFrame:f]) { 70 | renderLock = OS_SPINLOCK_INIT; 71 | initialized = NO; 72 | return self; 73 | } 74 | [self release]; 75 | return nil; 76 | } 77 | - (id) initWithCoder:(NSCoder *)c { 78 | if (self = [super initWithCoder:c]) { 79 | renderLock = OS_SPINLOCK_INIT; 80 | initialized = NO; 81 | return self; 82 | } 83 | [self release]; 84 | return nil; 85 | } 86 | 87 | 88 | - (void) drawRect:(NSRect)r { 89 | OSSpinLockLock(&renderLock); 90 | if (!initialized) { 91 | NSOpenGLContext *sharedCtx = [appDelegate sharedContext]; 92 | NSOpenGLPixelFormat *pFmt = [appDelegate pixelFormat]; 93 | 94 | NSOpenGLContext *newCtx = [[NSOpenGLContext alloc] initWithFormat:pFmt shareContext:sharedCtx]; 95 | [self setOpenGLContext:newCtx]; 96 | [newCtx setView:self]; 97 | initialized = YES; 98 | } 99 | OSSpinLockUnlock(&renderLock); 100 | } 101 | - (void) drawTextureRef:(CVOpenGLTextureRef)n { 102 | if (n==nil) 103 | return; 104 | //NSLog(@"%s",__func__); 105 | 106 | OSSpinLockLock(&renderLock); 107 | 108 | CGLContextObj cgl_ctx = [[self openGLContext] CGLContextObj]; 109 | GLuint name = CVOpenGLTextureGetName(n); 110 | GLenum target = CVOpenGLTextureGetTarget(n); 111 | BOOL flipped = (CVOpenGLTextureIsFlipped(n)) ? YES : NO; 112 | GLfloat bl[2], br[2], tl[2], tr[2]; 113 | CVOpenGLTextureGetCleanTexCoords(n, bl, br, tr, tl); 114 | NSRect texRect = NSMakeRect(bl[0], bl[1], br[0]-bl[0], tr[1]-br[1]); 115 | if (texRect.size.height < 0) 116 | texRect = NSMakeRect(bl[0], tl[1], br[0]-bl[0], br[1]-tr[1]); 117 | //NSLog(@"\t\ttexRect is (%0.2f, %0.2f) : %0.2f x %0.2f",texRect.origin.x,texRect.origin.y,texRect.size.width,texRect.size.height); 118 | 119 | glEnableClientState(GL_VERTEX_ARRAY); 120 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 121 | glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST); 122 | glDisable(GL_DEPTH_TEST); 123 | glClearColor(0.0, 0.0, 0.0, 1.0); 124 | 125 | glEnable(target); 126 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 127 | 128 | // set up the view to draw 129 | NSRect bounds = [self bounds]; 130 | glMatrixMode(GL_MODELVIEW); 131 | glLoadIdentity(); 132 | glMatrixMode(GL_PROJECTION); 133 | glLoadIdentity(); 134 | glViewport(0, 0, (GLsizei) bounds.size.width, (GLsizei) bounds.size.height); 135 | glOrtho(bounds.origin.x, bounds.origin.x+bounds.size.width, bounds.origin.y, bounds.origin.y+bounds.size.height, 1.0, -1.0); 136 | glDisable(GL_BLEND); 137 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 138 | // clear the view 139 | glClearColor(0.0,0.0,0.0,0.0); 140 | glClear(GL_COLOR_BUFFER_BIT); 141 | 142 | // determine the rect that i need to draw the texture in 143 | NSRect dstRect = [CVGLView rectThatFitsRect:texRect inRect:bounds]; 144 | GLDRAWTEXQUADMACRO(name,target,flipped,texRect,dstRect); 145 | 146 | glFlush(); 147 | 148 | OSSpinLockUnlock(&renderLock); 149 | } 150 | 151 | 152 | @end 153 | -------------------------------------------------------------------------------- /UVC Test App/UVC Test App-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSCameraUsageDescription 6 | Access Camera to change its UVC parameters 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1 27 | LSMinimumSystemVersion 28 | ${MACOSX_DEPLOYMENT_TARGET} 29 | NSHumanReadableCopyright 30 | Copyright © 2014 Vidvox. All rights reserved. 31 | NSMainNibFile 32 | MainMenu 33 | NSPrincipalClass 34 | NSApplication 35 | 36 | 37 | -------------------------------------------------------------------------------- /UVC Test App/UVC Test App-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'UVC Test App' target in the 'UVC Test App' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /UVC Test App/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} 2 | {\colortbl;\red255\green255\blue255;} 3 | \paperw9840\paperh8400 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 5 | 6 | \f0\b\fs24 \cf0 Engineering: 7 | \b0 \ 8 | Some people\ 9 | \ 10 | 11 | \b Human Interface Design: 12 | \b0 \ 13 | Some other people\ 14 | \ 15 | 16 | \b Testing: 17 | \b0 \ 18 | Hopefully not nobody\ 19 | \ 20 | 21 | \b Documentation: 22 | \b0 \ 23 | Whoever\ 24 | \ 25 | 26 | \b With special thanks to: 27 | \b0 \ 28 | Mom\ 29 | } 30 | -------------------------------------------------------------------------------- /UVC Test App/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /UVC Test App/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // UVC Test App 4 | // 5 | // Created by bagheera on 9/26/14. 6 | // Copyright (c) 2014 Vidvox. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /VVUVCKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VVUVCKit.xcodeproj/xcshareddata/xcschemes/UVC Test App.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #import 8 | //#import 9 | #import "VVUVCKitStringAdditions.h" 10 | 11 | /** 12 | \defgroup VVUVCController 13 | */ 14 | 15 | 16 | /* 17 | @protocol VVUVCControllerDelegate 18 | - (void) VVUVCControllerParamsUpdated:(id)c; 19 | @end 20 | */ 21 | 22 | 23 | /** 24 | \ingroup VVUVCController 25 | Auto-exposure modes described by the USB spec, put in a typedef/enum for convenience 26 | */ 27 | typedef enum { 28 | UVC_AEMode_Undefined = 0x00, /// undefined auto exposure mode 29 | UVC_AEMode_Manual = 0x01, /// manual exposure, manual iris 30 | UVC_AEMode_Auto = 0x02, /// auto exposure, auto iris 31 | UVC_AEMode_ShutterPriority = 0x04, /// manual exposure, auto iris 32 | UVC_AEMode_AperturePriority = 0x08 /// auto exposure, manual iris 33 | } UVC_AEMode; 34 | 35 | 36 | /* this struct contains all the info necessary to get/set vals from a video control parameter (either terminal/hardware or 37 | processing/software)- but it does not contain info about the value at all! think of this struct as a sort of function 38 | description for the hardware which will be sent out directly via USB. instances of this struct are populated by values 39 | from the USB specification! */ 40 | typedef struct { 41 | int unit; // describes whether terminal/hardware or processing/software 42 | int selector; // the address of the "parameter" being changed- 43 | int intendedSize; 44 | BOOL hasMin; // whether or not the video control parameter described by this struct has a min val 45 | BOOL hasMax; // whether or not the video control parameter described by this struct has a max 46 | BOOL hasDef; // whether or not the video control parameter described by this struct has a default 47 | BOOL isSigned; // whether or not the video control parameter described by this struct is a signed val 48 | BOOL isRelative; // whether or not the video control parameter described by this struct is a relative val 49 | } uvc_control_info_t; 50 | 51 | 52 | /* these variables contain enough info to send data to/get data from the implied attribute. the 53 | variables are global to the class (the contents won't change from instance to instance), and 54 | conceptually act like function descriptions (instances of this class can pass references to these 55 | variables, which can be used to get/set values). these are populated when the class is 56 | initialized by values described in the USB specification. if uvc_control_info_t is a function 57 | description, these variables are essentially pointers to a bunch of different functions. */ 58 | extern uvc_control_info_t _scanCtrl; 59 | extern uvc_control_info_t _autoExposureModeCtrl; 60 | extern uvc_control_info_t _autoExposurePriorityCtrl; 61 | extern uvc_control_info_t _exposureTimeCtrl; 62 | extern uvc_control_info_t _irisCtrl; 63 | extern uvc_control_info_t _autoFocusCtrl; 64 | extern uvc_control_info_t _focusCtrl; 65 | extern uvc_control_info_t _zoomCtrl; 66 | extern uvc_control_info_t _panTiltCtrl; 67 | extern uvc_control_info_t _panTiltRelCtrl; 68 | extern uvc_control_info_t _rollCtrl; 69 | extern uvc_control_info_t _rollRelCtrl; 70 | 71 | extern uvc_control_info_t _backlightCtrl; 72 | extern uvc_control_info_t _brightCtrl; 73 | extern uvc_control_info_t _contrastCtrl; 74 | extern uvc_control_info_t _gainCtrl; 75 | extern uvc_control_info_t _powerLineCtrl; 76 | extern uvc_control_info_t _autoHueCtrl; 77 | extern uvc_control_info_t _hueCtrl; 78 | extern uvc_control_info_t _saturationCtrl; 79 | extern uvc_control_info_t _sharpnessCtrl; 80 | extern uvc_control_info_t _gammaCtrl; 81 | extern uvc_control_info_t _whiteBalanceAutoTempCtrl; 82 | extern uvc_control_info_t _whiteBalanceTempCtrl; 83 | 84 | 85 | /* this struct describes a parameter- it contains a pointer to the control info that describes 86 | which parameter, as well as the min/max/default/current value. an instance of this struct will 87 | contain the value of the parameter and the uvc_control_info_t struct necessary to communicate with 88 | this parameter in a camera. */ 89 | typedef struct { 90 | BOOL supported; // if YES, this parameter is supported. if NO, either the camera doesn't support this parameter, or the "inputTerminalID" or "processingUnitID" of the camera is wrong! 91 | long min; // the paramter's actual min val 92 | long max; // the parameter's actual max val 93 | long val; // the parameter's actual val 94 | long def; // the parameter's default val 95 | int actualSize; 96 | uvc_control_info_t *ctrlInfo; 97 | } uvc_param; 98 | 99 | 100 | 101 | 102 | 103 | /// An instance of VVUVCController will control the UVC params for a single USB video device. This is probably the only class you'll have to create or work with in this framework. 104 | /** 105 | \ingroup VVUVCController 106 | This is probably the only class you'll have to work with in this framework. The basic idea is that you create a VVUVCController for an enabled USB video device, and then either tell the controller to open its settings window or interact with it programmatically. If you're looking for a more "embedded" feel, you can remove the VVUVCController's "settingsView" from its superview and add it into your application's NSView hierarchy. 107 | */ 108 | @interface VVUVCController : NSObject { 109 | IOUSBInterfaceInterface190 **interface; 110 | UInt32 deviceLocationID; 111 | UInt8 interfaceNumber; // pulled from interface on generalInit! 112 | int inputTerminalID; // the "address" of the terminal unit, which handles hardware controls like aperture/focus. if this val is wrong, the hardware controls won't be available. 113 | int processingUnitID; // the "address" of the processing unit, which handles software controls like contrast/hue. if this val is wrong, the software controls won't be available. 114 | 115 | //id delegate; 116 | uvc_param scanningMode; 117 | uvc_param autoExposureMode; // mode functionality described by the type UVC_AEMode 118 | uvc_param autoExposurePriority; // if 1, framerate may be varied. if 0, framerate must remain constant. 119 | uvc_param exposureTime; 120 | uvc_param iris; 121 | uvc_param autoFocus; 122 | uvc_param focus; 123 | uvc_param zoom; 124 | uvc_param panTilt; 125 | uvc_param panTiltRel; 126 | uvc_param roll; 127 | uvc_param rollRel; 128 | 129 | uvc_param backlight; 130 | uvc_param bright; 131 | uvc_param contrast; 132 | uvc_param gain; 133 | uvc_param powerLine; 134 | uvc_param autoHue; 135 | uvc_param hue; 136 | uvc_param saturation; 137 | uvc_param sharpness; 138 | uvc_param gamma; 139 | uvc_param autoWhiteBalance; 140 | uvc_param whiteBalance; 141 | 142 | // this class has its own .nib which contains a UI for interacting with the class that may be opened directly in a window, or accessed as an NSView instance for use in other UIs/software 143 | NSNib *theNib; 144 | NSArray *nibTopLevelObjects; 145 | 146 | IBOutlet id uiCtrlr; // created & owned by the nib! 147 | IBOutlet NSWindow *settingsWindow; // by default, the UI is in a window (it's easiest to just open and close it) 148 | IBOutlet NSView *settingsView; // you can also access the view which contains the UI so you can embed it in other apps 149 | } 150 | 151 | /// Use this method to init an instance of VVUVCController from an NSString returned by the AVFoundation or QTCapture APIs as the device's unique ID. 152 | /** 153 | @param n The "deviceIDString" is a string returned by QuickTime and AVFoundation as the unique ID for the USB video device. Technically, this is a hex value with sixteen digits (16 hex digits = an unsigned 64-bit integer). The first 8 hex digits is the USB device's "locationID", the next 4 hex digits is the device's vendor ID, and the last 4 digits are the device's product ID. Only the locationID is needed to create the necessary USB interfaces... 154 | */ 155 | - (id) initWithDeviceIDString:(NSString *)n; 156 | /// Use this method to init an instance of VVUVCController from the USB location ID. 157 | /** 158 | @param locationID The location ID of the USB device you want this instance of VVUVCController to control. 159 | */ 160 | - (id) initWithLocationID:(UInt32)locationID; 161 | - (IOUSBInterfaceInterface190 **) _getControlInferaceWithDeviceInterface:(IOUSBDeviceInterface **)deviceInterface; 162 | - (void) generalInit; 163 | 164 | /// Returns a mutable dict representing the current state of the video input parameters 165 | - (NSMutableDictionary *) createSnapshot; 166 | /// Loads a saved state dict created with the "createSnapshot" method 167 | - (void) loadSnapshot:(NSDictionary *)s; 168 | 169 | - (BOOL) _sendControlRequest:(IOUSBDevRequest *)controlRequest; 170 | - (int) _requestValType:(int)requestType forControl:(const uvc_control_info_t *)ctrl returnVal:(void **)ret; 171 | - (BOOL) _setBytes:(void *)bytes sized:(int)size toControl:(const uvc_control_info_t *)ctrl; 172 | - (void) _populateAllParams; // populates all the uvc_param variables in this instance, loading their min/max/default vals and determining if they're supported or not 173 | - (void) _populateParam:(uvc_param *)param; 174 | - (BOOL) _pushParamToDevice:(uvc_param *)param; 175 | - (void) _resetParamToDefault:(uvc_param *)param; 176 | 177 | /// Resets the parameters to their default values. The default values are supplied by/stored in the device. 178 | - (void) resetParamsToDefaults; 179 | /// Opens a window with a GUI for interacting with the camera parameters 180 | - (void) openSettingsWindow; 181 | /// Closes the GUI window (if it's open). 182 | - (void) closeSettingsWindow; 183 | 184 | - (void) setInterlaced:(BOOL)n; 185 | - (BOOL) interlaced; 186 | - (BOOL) interlacedSupported; 187 | - (void) resetInterlaced; 188 | /// Sets the auto exposure mode using one of the basic auto exposure modes defined in the header (vals pulled from the USB spec) 189 | - (void) setAutoExposureMode:(UVC_AEMode)n; 190 | /// Gets the auto exposure mode 191 | - (UVC_AEMode) autoExposureMode; 192 | /// Whether or not this camera supports the use of alternate auto exposure modes 193 | - (BOOL) autoExposureModeSupported; 194 | /// Resets the auto exposure mode to the hardware-defined default 195 | - (void) resetAutoExposureMode; 196 | /// Sets whether or not auto exposure will be given priority 197 | - (void) setAutoExposurePriority:(BOOL)n; 198 | /// Gets whether or not the camera is giving auto exposure priority 199 | - (BOOL) autoExposurePriority; 200 | /// Whether or not this camera supports the use of auto exposure priority 201 | - (BOOL) autoExposurePrioritySupported; 202 | /// Resets the auto exposure priority to the hardware-defined default 203 | - (void) resetAutoExposurePriority; 204 | 205 | /// Sets the exposure time to the passed value 206 | - (void) setExposureTime:(long)n; 207 | /// Gets the current exposure time value being used by the camera 208 | - (long) exposureTime; 209 | /// Whether or not this camera supports the exposure time parameter 210 | - (BOOL) exposureTimeSupported; 211 | /// Resets the exposure time value to the hardware-defined default 212 | - (void) resetExposureTime; 213 | /// The min exposure time value 214 | - (long) minExposureTime; 215 | /// The max exposure time value 216 | - (long) maxExposureTime; 217 | /// Sets the iris to the passed value 218 | - (void) setIris:(long)n; 219 | /// Gets the current iris value being used by the camera 220 | - (long) iris; 221 | /// Whether or not this camera supports the iris parameter 222 | - (BOOL) irisSupported; 223 | /// Resets the iris value to the hardware-defined default 224 | - (void) resetIris; 225 | /// The min iris value 226 | - (long) minIris; 227 | /// The max iris value 228 | - (long) maxIris; 229 | /// Sets the auto focus to the passed value 230 | - (void) setAutoFocus:(BOOL)n; 231 | /// Gets the auto focus value being used by the camera 232 | - (BOOL) autoFocus; 233 | /// Whether or not this camera supports the auto focus parameter 234 | - (BOOL) autoFocusSupported; 235 | /// Resets the auto focus value to the hardware-defined default. 236 | - (void) resetAutoFocus; 237 | /// Sets the focus value 238 | - (void) setFocus:(long)n; 239 | /// Gets the focus value currently being used by the camera 240 | - (long) focus; 241 | /// Whether or not this camera supports the focus parameter 242 | - (BOOL) focusSupported; 243 | /// Resets the focus value to the hardware-defined default 244 | - (void) resetFocus; 245 | /// The min focus value 246 | - (long) minFocus; 247 | /// The max focus value 248 | - (long) maxFocus; 249 | /// Sets the zoom value 250 | - (void) setZoom:(long)n; 251 | /// Gets the current zoom value being used by the camera 252 | - (long) zoom; 253 | /// Whether or not this camera supports the zoom parameter 254 | - (BOOL) zoomSupported; 255 | /// Resets the zoom value to the hardware-defined default 256 | - (void) resetZoom; 257 | /// The min zoom value 258 | - (long) minZoom; 259 | /// The max zoom value 260 | - (long) maxZoom; 261 | 262 | // pan/tilt/roll aren't enabled 263 | - (BOOL) panSupported; 264 | - (BOOL) tiltSupported; 265 | - (BOOL) rollSupported; 266 | 267 | /// Sets the backlight to the passed value 268 | - (void) setBacklight:(long)n; 269 | /// Gets the backlight value currently being used by the camera 270 | - (long) backlight; 271 | /// Whether or not this camera supports the backlight parameter 272 | - (BOOL) backlightSupported; 273 | /// Resets the backlight value to the hardware-defined default 274 | - (void) resetBacklight; 275 | /// The min backlight value 276 | - (long) minBacklight; 277 | /// The max backlight value 278 | - (long) maxBacklight; 279 | /// Sets the bright value to the passed value 280 | - (void) setBright:(long)n; 281 | /// Gets the bright value currently being used by the camera 282 | - (long) bright; 283 | /// Whether or not this camera supports the bright parameter 284 | - (BOOL) brightSupported; 285 | /// Resets the bright parameter to the hardware-defined default 286 | - (void) resetBright; 287 | /// The min bright value 288 | - (long) minBright; 289 | /// The max bright value 290 | - (long) maxBright; 291 | /// Sets the contrast to the passed value 292 | - (void) setContrast:(long)n; 293 | /// Gets the contrast value currently being used by the camera 294 | - (long) contrast; 295 | /// Whether or not this camera supports the contrast parameter 296 | - (BOOL) contrastSupported; 297 | /// Resets the contrast to the hardware-defined default 298 | - (void) resetContrast; 299 | /// The min contrast value 300 | - (long) minContrast; 301 | /// The max contrast value 302 | - (long) maxContrast; 303 | /// Sets the gain to the passed value 304 | - (void) setGain:(long)n; 305 | /// Gets the gain value currently being used by the camera 306 | - (long) gain; 307 | /// Whether or not this camera supports the gain parameter 308 | - (BOOL) gainSupported; 309 | /// Resets the gain value to the hardware-defined default 310 | - (void) resetGain; 311 | /// The min gain value 312 | - (long) minGain; 313 | /// The max gain value 314 | - (long) maxGain; 315 | /// Sets the powerline to the passed value 316 | - (void) setPowerLine:(long)n; 317 | /// Gets the powerline value currently being used by the camera 318 | - (long) powerLine; 319 | /// Whether or not this camera supports the powerline parameter 320 | - (BOOL) powerLineSupported; 321 | /// Resets the powerline value to the hardware-defined default 322 | - (void) resetPowerLine; 323 | /// The min powerline value 324 | - (long) minPowerLine; 325 | /// The max powerline value 326 | - (long) maxPowerLine; 327 | /// Sets the auto hue to the passed value 328 | - (void) setAutoHue:(BOOL)n; 329 | /// The auto hue value currently being used by the camera 330 | - (BOOL) autoHue; 331 | /// Whether or not this camera supports the auto hue parameter 332 | - (BOOL) autoHueSupported; 333 | /// Resets the auto hue parameter to the hardware-defined default 334 | - (void) resetAutoHue; 335 | /// Sets the hue to the passed value 336 | - (void) setHue:(long)n; 337 | /// Gets the hue value currently being used by the camera 338 | - (long) hue; 339 | /// Whether or not this camera supports the hue parameter 340 | - (BOOL) hueSupported; 341 | /// Resets the hue parameter to the hardware-defined default 342 | - (void) resetHue; 343 | /// The min hue value 344 | - (long) minHue; 345 | /// The max hue value 346 | - (long) maxHue; 347 | /// Sets the saturation to the passed value 348 | - (void) setSaturation:(long)n; 349 | /// Gets the saturation value currently being used by the camera 350 | - (long) saturation; 351 | /// Whether or not this camera supports the saturation parameter 352 | - (BOOL) saturationSupported; 353 | /// Resets the saturation to the hardware-defined default 354 | - (void) resetSaturation; 355 | /// The min saturation value 356 | - (long) minSaturation; 357 | /// The max saturation value 358 | - (long) maxSaturation; 359 | /// Sets the sharpness to the passed value 360 | - (void) setSharpness:(long)n; 361 | /// Gets the sharpness value currently being used by the camera 362 | - (long) sharpness; 363 | /// Whether or not this camera supports the sharpness parameter 364 | - (BOOL) sharpnessSupported; 365 | /// Resets the sharpness to the hardware-defined default 366 | - (void) resetSharpness; 367 | /// The min sharpness value 368 | - (long) minSharpness; 369 | /// The max sharpness value 370 | - (long) maxSharpness; 371 | /// Sets the gamma to the passed value 372 | - (void) setGamma:(long)n; 373 | /// Gets the gamma value currently being used by the camera 374 | - (long) gamma; 375 | /// Whether or not this camera supports the gamma parameter 376 | - (BOOL) gammaSupported; 377 | /// Resets the gamma value to the hardware-defined default 378 | - (void) resetGamma; 379 | /// The min gamma value 380 | - (long) minGamma; 381 | /// The max gamma value 382 | - (long) maxGamma; 383 | /// Sets the auto white balance to the passed value 384 | - (void) setAutoWhiteBalance:(BOOL)n; 385 | /// Gets the auto white balance value currently being used by the camera 386 | - (BOOL) autoWhiteBalance; 387 | /// Whether or not this camera supports the auto white balance parameter 388 | - (BOOL) autoWhiteBalanceSupported; 389 | /// Resets the auto white balance to the hardware-defined default 390 | - (void) resetAutoWhiteBalance; 391 | /// Sets the white balance to the passed value 392 | - (void) setWhiteBalance:(long)n; 393 | /// Gets the white balance value currently being used by the camera 394 | - (long) whiteBalance; 395 | /// Whether or not this camera supports the white balance parameter 396 | - (BOOL) whiteBalanceSupported; 397 | /// Resets the white balance value to the hardware-defined default 398 | - (void) resetWhiteBalance; 399 | /// The min white balance value 400 | - (long) minWhiteBalance; 401 | /// The max white balance value 402 | - (long) maxWhiteBalance; 403 | 404 | 405 | @end 406 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 77 | 88 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCKit-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSHumanReadableCopyright 26 | Copyright © 2014 Vidvox. All rights reserved. 27 | NSPrincipalClass 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCKit-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'VVUVCKit' target in the 'VVUVCKit' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCKit.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | // this is the only class you should need to explicitly instantiate! 4 | #import "VVUVCController.h" 5 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCKitStringAdditions.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSString (VVUVCKitStringAdditions) 4 | 5 | - (BOOL) containsString:(NSString *)n; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCKitStringAdditions.m: -------------------------------------------------------------------------------- 1 | #import "VVUVCKitStringAdditions.h" 2 | 3 | @implementation NSString (VVUVCKitStringAdditions) 4 | 5 | - (BOOL) containsString:(NSString *)n { 6 | BOOL returnMe = NO; 7 | if (n != nil) { 8 | NSRange foundRange = [self rangeOfString:n]; 9 | if (foundRange.location!=NSNotFound && foundRange.length==[n length]) 10 | returnMe = YES; 11 | } 12 | return returnMe; 13 | } 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCUIController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "VVUVCUIElement.h" 3 | 4 | 5 | 6 | 7 | @interface VVUVCUIController : NSObject { 8 | IBOutlet id device; 9 | 10 | IBOutlet NSPopUpButton *autoExpButton; 11 | IBOutlet NSButton *expPriorityButton; 12 | IBOutlet NSButton *autoFocusButton; 13 | //IBOutlet NSSlider *panSlider; 14 | //IBOutlet NSSlider *tiltSlider; 15 | //IBOutlet NSSlider *rollSlider; 16 | 17 | IBOutlet NSButton *autoHueButton; 18 | IBOutlet NSButton *autoWBButton; 19 | 20 | IBOutlet VVUVCUIElement *expElement; 21 | IBOutlet VVUVCUIElement *irisElement; 22 | IBOutlet VVUVCUIElement *focusElement; 23 | IBOutlet VVUVCUIElement *zoomElement; 24 | 25 | IBOutlet VVUVCUIElement *backlightElement; 26 | IBOutlet VVUVCUIElement *brightElement; 27 | IBOutlet VVUVCUIElement *contrastElement; 28 | IBOutlet VVUVCUIElement *powerElement; 29 | IBOutlet VVUVCUIElement *gammaElement; 30 | IBOutlet VVUVCUIElement *hueElement; 31 | IBOutlet VVUVCUIElement *satElement; 32 | IBOutlet VVUVCUIElement *sharpElement; 33 | IBOutlet VVUVCUIElement *gainElement; 34 | IBOutlet VVUVCUIElement *wbElement; 35 | } 36 | 37 | - (IBAction) buttonUsed:(id)sender; 38 | - (IBAction) popUpButtonUsed:(id)sender; 39 | 40 | - (IBAction) resetToDefaults:(id)sender; 41 | 42 | - (void) _pushCameraControlStateToUI; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCUIController.m: -------------------------------------------------------------------------------- 1 | #import "VVUVCUIController.h" 2 | #import "VVUVCController.h" 3 | 4 | 5 | 6 | 7 | @implementation VVUVCUIController 8 | 9 | 10 | - (id) init { 11 | //NSLog(@"%s",__func__); 12 | if (self = [super init]) { 13 | return self; 14 | } 15 | [self release]; 16 | return nil; 17 | } 18 | - (void) awakeFromNib { 19 | [expElement setTitle:@"Exposure Time"]; 20 | [irisElement setTitle:@"Iris"]; 21 | [focusElement setTitle:@"Focus"]; 22 | [zoomElement setTitle:@"Zoom"]; 23 | 24 | [backlightElement setTitle:@"Backlight Compensation"]; 25 | [brightElement setTitle:@"Brightness"]; 26 | [contrastElement setTitle:@"Contrast"]; 27 | [gainElement setTitle:@"Gain"]; 28 | [powerElement setTitle:@"Power Line Frequency"]; 29 | [hueElement setTitle:@"Hue"]; 30 | [satElement setTitle:@"Saturation"]; 31 | [sharpElement setTitle:@"Sharpness"]; 32 | [gammaElement setTitle:@"Gamma"]; 33 | [wbElement setTitle:@"White Balance"]; 34 | } 35 | - (void) dealloc { 36 | [super dealloc]; 37 | } 38 | 39 | 40 | - (void) controlElementChanged:(id)sender { 41 | //NSLog(@"%s",__func__); 42 | if (sender == expElement) { 43 | [device setExposureTime:[sender val]]; 44 | } 45 | else if (sender == irisElement) { 46 | [device setIris:[sender val]]; 47 | } 48 | else if (sender == focusElement) { 49 | [device setFocus:[sender val]]; 50 | } 51 | else if (sender == zoomElement) { 52 | [device setZoom:[sender val]]; 53 | } 54 | else if (sender == backlightElement) { 55 | [device setBacklight:[sender val]]; 56 | } 57 | else if (sender == brightElement) { 58 | [device setBright:[sender val]]; 59 | } 60 | else if (sender == contrastElement) { 61 | [device setContrast:[sender val]]; 62 | } 63 | else if (sender == gainElement) { 64 | [device setGain:[sender val]]; 65 | } 66 | else if (sender == powerElement) { 67 | [device setPowerLine:[sender val]]; 68 | } 69 | else if (sender == hueElement) { 70 | [device setHue:[sender val]]; 71 | } 72 | else if (sender == satElement) { 73 | [device setSaturation:[sender val]]; 74 | } 75 | else if (sender == sharpElement) { 76 | [device setSharpness:[sender val]]; 77 | } 78 | else if (sender == gammaElement) { 79 | [device setGamma:[sender val]]; 80 | } 81 | else if (sender == wbElement) { 82 | [device setWhiteBalance:[sender val]]; 83 | } 84 | [self _pushCameraControlStateToUI]; 85 | } 86 | - (IBAction) buttonUsed:(id)sender { 87 | if (sender == expPriorityButton) { 88 | [device setAutoExposurePriority:([sender intValue]==NSOnState) ? YES : NO]; 89 | } 90 | else if (sender == autoFocusButton) { 91 | if ([sender intValue] == NSOnState) { 92 | [device setAutoFocus:YES]; 93 | } 94 | else { 95 | [device setAutoFocus:NO]; 96 | } 97 | [self _pushCameraControlStateToUI]; 98 | } 99 | else if (sender == autoHueButton) { 100 | if ([sender intValue] == NSOnState) { 101 | [device setAutoHue:YES]; 102 | } 103 | else { 104 | [device setAutoHue:NO]; 105 | } 106 | [self _pushCameraControlStateToUI]; 107 | } 108 | else if (sender == autoWBButton) { 109 | if ([sender intValue] == NSOnState) { 110 | [device setAutoWhiteBalance:YES]; 111 | } 112 | else { 113 | [device setAutoWhiteBalance:NO]; 114 | } 115 | [self _pushCameraControlStateToUI]; 116 | } 117 | } 118 | - (IBAction) popUpButtonUsed:(id)sender { 119 | //NSLog(@"%s ... %d",__func__,[sender indexOfSelectedItem]); 120 | if (sender == autoExpButton) { 121 | int selectedIndex = (int)[sender indexOfSelectedItem]; 122 | if (selectedIndex == 0) { 123 | [device setAutoExposureMode:UVC_AEMode_Manual]; 124 | } 125 | else if (selectedIndex == 1) { 126 | [device setAutoExposureMode:UVC_AEMode_Auto]; 127 | } 128 | else if (selectedIndex == 2) { 129 | [device setAutoExposureMode:UVC_AEMode_ShutterPriority]; 130 | } 131 | else if (selectedIndex == 3) { 132 | [device setAutoExposureMode:UVC_AEMode_AperturePriority]; 133 | } 134 | [self _pushCameraControlStateToUI]; 135 | } 136 | } 137 | 138 | 139 | - (IBAction) resetToDefaults:(id)sender { 140 | //NSLog(@"%s",__func__); 141 | [device resetParamsToDefaults]; 142 | [self _pushCameraControlStateToUI]; 143 | } 144 | 145 | 146 | - (void) _pushCameraControlStateToUI { 147 | //NSLog(@"%s",__func__); 148 | 149 | 150 | if ([device exposureTimeSupported]) { 151 | [expElement setMin:(int)[device minExposureTime]]; 152 | [expElement setMax:(int)[device maxExposureTime]]; 153 | [expElement setVal:(int)[device exposureTime]]; 154 | } 155 | [expElement setEnabled:[device exposureTimeSupported]]; 156 | 157 | if ([device irisSupported]) { 158 | [irisElement setMin:(int)[device minIris]]; 159 | [irisElement setMax:(int)[device maxIris]]; 160 | [irisElement setVal:(int)[device iris]]; 161 | } 162 | [irisElement setEnabled:[device irisSupported]]; 163 | 164 | if ([device zoomSupported]) { 165 | [zoomElement setMin:(int)[device minZoom]]; 166 | [zoomElement setMax:(int)[device maxZoom]]; 167 | [zoomElement setVal:(int)[device zoom]]; 168 | } 169 | [zoomElement setEnabled:[device zoomSupported]]; 170 | 171 | if ([device backlightSupported]) { 172 | [backlightElement setMin:(int)[device minBacklight]]; 173 | [backlightElement setMax:(int)[device maxBacklight]]; 174 | [backlightElement setVal:(int)[device backlight]]; 175 | } 176 | [backlightElement setEnabled:[device backlightSupported]]; 177 | 178 | if ([device brightSupported]) { 179 | [brightElement setMin:(int)[device minBright]]; 180 | [brightElement setMax:(int)[device maxBright]]; 181 | [brightElement setVal:(int)[device bright]]; 182 | } 183 | [brightElement setEnabled:[device brightSupported]]; 184 | 185 | if ([device contrastSupported]) { 186 | [contrastElement setMin:(int)[device minContrast]]; 187 | [contrastElement setMax:(int)[device maxContrast]]; 188 | [contrastElement setVal:(int)[device contrast]]; 189 | } 190 | [contrastElement setEnabled:[device contrastSupported]]; 191 | 192 | if ([device gainSupported]) { 193 | [gainElement setMin:(int)[device minGain]]; 194 | [gainElement setMax:(int)[device maxGain]]; 195 | [gainElement setVal:(int)[device gain]]; 196 | } 197 | [gainElement setEnabled:[device gainSupported]]; 198 | 199 | if ([device powerLineSupported]) { 200 | [powerElement setMin:(int)[device minPowerLine]]; 201 | [powerElement setMax:(int)[device maxPowerLine]]; 202 | [powerElement setVal:(int)[device powerLine]]; 203 | } 204 | [powerElement setEnabled:[device powerLineSupported]]; 205 | 206 | if ([device saturationSupported]) { 207 | [satElement setMin:(int)[device minSaturation]]; 208 | [satElement setMax:(int)[device maxSaturation]]; 209 | [satElement setVal:(int)[device saturation]]; 210 | } 211 | [satElement setEnabled:[device saturationSupported]]; 212 | 213 | if ([device sharpnessSupported]) { 214 | [sharpElement setMin:(int)[device minSharpness]]; 215 | [sharpElement setMax:(int)[device maxSharpness]]; 216 | [sharpElement setVal:(int)[device sharpness]]; 217 | } 218 | [sharpElement setEnabled:[device sharpnessSupported]]; 219 | 220 | if ([device gammaSupported]) { 221 | [gammaElement setMin:(int)[device minGamma]]; 222 | [gammaElement setMax:(int)[device maxGamma]]; 223 | [gammaElement setVal:(int)[device gamma]]; 224 | } 225 | 226 | [expPriorityButton setEnabled:[device autoExposurePrioritySupported]]; 227 | [expPriorityButton setIntValue:([device autoExposurePriority]) ? NSOnState : NSOffState]; 228 | 229 | [autoFocusButton setEnabled:([device autoFocusSupported]) ? YES : NO]; 230 | [autoFocusButton setIntValue:([device autoFocus]) ? NSOnState : NSOffState]; 231 | 232 | 233 | BOOL enableFocusElement = NO; 234 | if ([device autoFocusSupported]) { 235 | [autoFocusButton setEnabled:YES]; 236 | if ([device autoFocus]) { 237 | [autoFocusButton setIntValue:NSOnState]; 238 | } 239 | else { 240 | [autoFocusButton setIntValue:NSOffState]; 241 | if ([device focusSupported]) 242 | enableFocusElement = YES; 243 | } 244 | } 245 | else { 246 | [autoFocusButton setEnabled:NO]; 247 | [autoFocusButton setIntValue:NSOffState]; 248 | if ([device focusSupported]) 249 | enableFocusElement = YES; 250 | } 251 | [focusElement setEnabled:enableFocusElement]; 252 | if (enableFocusElement) { 253 | [focusElement setMin:(int)[device minFocus]]; 254 | [focusElement setMax:(int)[device maxFocus]]; 255 | [focusElement setVal:(int)[device focus]]; 256 | } else [focusElement setVal:0]; 257 | 258 | 259 | BOOL enableHueElement = NO; 260 | if ([device autoHueSupported]) { 261 | [autoHueButton setEnabled:YES]; 262 | if ([device autoHue]) { 263 | [autoHueButton setIntValue:NSOnState]; 264 | } 265 | else { 266 | [autoHueButton setIntValue:NSOffState]; 267 | if ([device hueSupported]) 268 | enableHueElement = YES; 269 | } 270 | } 271 | else { 272 | [autoHueButton setEnabled:NO]; 273 | [autoHueButton setIntValue:NSOffState]; 274 | if ([device hueSupported]) 275 | enableHueElement = YES; 276 | } 277 | [hueElement setEnabled:enableHueElement]; 278 | if (enableHueElement) { 279 | [hueElement setMin:(int)[device minHue]]; 280 | [hueElement setMax:(int)[device maxHue]]; 281 | [hueElement setVal:(int)[device hue]]; 282 | } else [hueElement setVal:0]; 283 | 284 | 285 | BOOL enableWBElement = NO; 286 | if ([device autoWhiteBalanceSupported]) { 287 | [autoWBButton setEnabled:YES]; 288 | if ([device autoWhiteBalance]) { 289 | [autoWBButton setIntValue:NSOnState]; 290 | } 291 | else { 292 | [autoWBButton setIntValue:NSOffState]; 293 | if ([device whiteBalanceSupported]) 294 | enableWBElement = YES; 295 | } 296 | } 297 | else { 298 | [autoWBButton setEnabled:NO]; 299 | [autoWBButton setIntValue:NSOffState]; 300 | if ([device whiteBalanceSupported]) 301 | enableWBElement = YES; 302 | } 303 | [wbElement setEnabled:enableWBElement]; 304 | if (enableWBElement) { 305 | [wbElement setMin:(int)[device minWhiteBalance]]; 306 | [wbElement setMax:(int)[device maxWhiteBalance]]; 307 | [wbElement setVal:(int)[device whiteBalance]]; 308 | } else [wbElement setVal:0]; 309 | 310 | 311 | UVC_AEMode aeMode = [device autoExposureMode]; 312 | switch (aeMode) { 313 | case UVC_AEMode_Undefined: // hide both 314 | [autoExpButton selectItemAtIndex:0]; 315 | [expElement setEnabled:NO]; 316 | [irisElement setEnabled:NO]; 317 | break; 318 | case UVC_AEMode_Manual: // show both 319 | [autoExpButton selectItemAtIndex:0]; 320 | [expElement setEnabled:(YES && [device exposureTimeSupported])]; 321 | [irisElement setEnabled:(YES && [device irisSupported])]; 322 | break; 323 | case UVC_AEMode_Auto: // hide both 324 | [autoExpButton selectItemAtIndex:1]; 325 | [expElement setEnabled:NO]; 326 | [irisElement setEnabled:NO]; 327 | [expElement setVal:0]; 328 | break; 329 | case UVC_AEMode_ShutterPriority: 330 | [autoExpButton selectItemAtIndex:2]; 331 | [expElement setEnabled:(YES && [device exposureTimeSupported])]; 332 | [irisElement setEnabled:NO]; 333 | break; 334 | case UVC_AEMode_AperturePriority: 335 | [autoExpButton selectItemAtIndex:3]; 336 | [expElement setEnabled:NO]; 337 | [irisElement setEnabled:(YES && [device irisSupported])]; 338 | [expElement setVal:0]; 339 | break; 340 | } 341 | } 342 | 343 | 344 | @end 345 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCUIElement.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | 5 | 6 | @protocol VVUVCUIElementDelegate 7 | - (void) controlElementChanged:(id)sender; 8 | @end 9 | 10 | 11 | 12 | 13 | @interface VVUVCUIElement : NSBox { 14 | IBOutlet id delegate; 15 | 16 | BOOL enabled; 17 | NSSlider *valSlider; 18 | NSTextField *valField; 19 | 20 | int val; 21 | int min; 22 | int max; 23 | } 24 | 25 | - (void) setEnabled:(BOOL)n; 26 | 27 | - (void) _resizeContents; 28 | 29 | - (void) uiItemUsed:(id)sender; 30 | 31 | @property (assign,readwrite) id delegate; 32 | @property (assign,readwrite) int val; 33 | @property (assign,readwrite) int min; 34 | @property (assign,readwrite) int max; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /VVUVCKit/VVUVCUIElement.m: -------------------------------------------------------------------------------- 1 | #import "VVUVCUIElement.h" 2 | 3 | 4 | 5 | 6 | @implementation VVUVCUIElement 7 | 8 | 9 | - (id) initWithFrame:(NSRect)f { 10 | if (self = [super initWithFrame:f]) { 11 | delegate = nil; 12 | enabled = YES; 13 | valSlider = nil; 14 | valField = nil; 15 | val = 0; 16 | min = 0; 17 | max = 0; 18 | //[[self titleCell] setControlSize:NSMiniControlSize]; 19 | [self setTitleFont:[NSFont systemFontOfSize:9]]; 20 | [self setBorderType:NSNoBorder]; 21 | [self setBoxType:NSBoxSecondary]; 22 | //[self setTitle:@"TestTitle"]; 23 | NSView *contentView = [self contentView]; 24 | 25 | valSlider = [[NSSlider alloc] initWithFrame:NSMakeRect(0,0,200,20)]; 26 | [[valSlider cell] setControlSize:NSMiniControlSize]; 27 | [valSlider setContinuous:YES]; 28 | [valSlider setTarget:self]; 29 | [valSlider setAction:@selector(uiItemUsed:)]; 30 | 31 | valField = [[NSTextField alloc] initWithFrame:NSMakeRect(0,0,200,20)]; 32 | //[[valField cell] setControlSize:NSMiniControlSize]; 33 | [valField setFont:[NSFont systemFontOfSize:9]]; 34 | NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 35 | [valField setFormatter:formatter]; 36 | [formatter release]; 37 | [valField setTarget:self]; 38 | [valField setAction:@selector(uiItemUsed:)]; 39 | 40 | [contentView addSubview:valSlider]; 41 | [contentView addSubview:valField]; 42 | [self _resizeContents]; 43 | return self; 44 | } 45 | [self release]; 46 | return nil; 47 | } 48 | - (void) dealloc { 49 | if (valSlider != nil) { 50 | [valSlider removeFromSuperview]; 51 | [valSlider release]; 52 | valSlider = nil; 53 | } 54 | if (valField != nil) { 55 | [valField removeFromSuperview]; 56 | [valField release]; 57 | valField = nil; 58 | } 59 | [super dealloc]; 60 | } 61 | 62 | 63 | - (void) setEnabled:(BOOL)n{ 64 | if (enabled == n) 65 | return; 66 | enabled = n; 67 | if (enabled) { 68 | [valSlider setEnabled:YES]; 69 | [valField setEnabled:YES]; 70 | } 71 | else { 72 | [valSlider setEnabled:NO]; 73 | [valField setEnabled:NO]; 74 | } 75 | } 76 | 77 | 78 | - (void) _resizeContents { 79 | //NSLog(@"%s",__func__); 80 | NSRect contentBounds = [[self contentView] bounds]; 81 | //NSLog(@"\t\tcontentBounds is (%f, %f) : %f x %f",contentBounds.origin.x,contentBounds.origin.y,contentBounds.size.width,contentBounds.size.height); 82 | NSRect sliderRect; 83 | NSRect txtRect = contentBounds; 84 | txtRect.size = NSMakeSize(50,16); 85 | sliderRect.size = NSMakeSize(contentBounds.size.width-txtRect.size.width-2, txtRect.size.height); 86 | sliderRect.origin = NSMakePoint(0,0); 87 | txtRect.origin = NSMakePoint(contentBounds.size.width-txtRect.size.width, 0); 88 | [valSlider setFrame:sliderRect]; 89 | [valField setFrame:txtRect]; 90 | //NSLog(@"\t\tslider rect is (%f, %f) : %f x %f",sliderRect.origin.x,sliderRect.origin.y,sliderRect.size.width,sliderRect.size.height); 91 | //NSLog(@"\t\ttext rect is (%f, %f) : %f x %f",txtRect.origin.x,txtRect.origin.y,txtRect.size.width,txtRect.size.height); 92 | [valSlider setAutoresizingMask:NSViewWidthSizable]; 93 | [valField setAutoresizingMask:NSViewMinXMargin]; 94 | } 95 | - (void) uiItemUsed:(id)sender { 96 | //NSLog(@"%s",__func__); 97 | if (sender == valSlider) { 98 | // update the val, then update the val field 99 | val = [valSlider intValue]; 100 | [valField setIntValue:val]; 101 | } 102 | else if (sender == valField) { 103 | // update the val, then update the val slider 104 | val = [valField intValue]; 105 | [valSlider setIntValue:val]; 106 | } 107 | // if there's a delegate, let it know that my val changed! 108 | if (delegate != nil) 109 | [delegate controlElementChanged:self]; 110 | } 111 | 112 | 113 | @synthesize delegate; 114 | - (void) setVal:(int)n { 115 | //NSLog(@"%s ... %@, %d",__func__,[self title],n); 116 | val = n; 117 | [valField setIntValue:n]; 118 | [valSlider setIntValue:n]; 119 | } 120 | - (int) val { 121 | return val; 122 | } 123 | - (void) setMin:(int)n { 124 | //NSLog(@"%s ... %@, %ld",__func__,[self title],n); 125 | min = n; 126 | NSNumberFormatter *fmt = [valField formatter]; 127 | [fmt setMinimum:[NSNumber numberWithInt:n]]; 128 | [valSlider setMinValue:n]; 129 | } 130 | - (int) min { 131 | return min; 132 | } 133 | - (void) setMax:(int)n { 134 | //NSLog(@"%s ... %@, %ld",__func__,[self title],n); 135 | max = n; 136 | NSNumberFormatter *fmt = [valField formatter]; 137 | [fmt setMaximum:[NSNumber numberWithInt:n]]; 138 | [valSlider setMaxValue:n]; 139 | } 140 | - (int) max { 141 | return max; 142 | } 143 | 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /VVUVCKit/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | --------------------------------------------------------------------------------