768 Commits
Author SHA1 Message Date
Stefanos Kornilios Mitsis Poiitidis 22e95de2d1 Merge pull request #572 from reicast/skmp/pandora-merge
pandora merge
2014-12-11 03:26:13 +01:00
Stefanos Kornilios Mitsis Poiitidis d5ddad53d1 Use XMLParser from master 2014-12-11 03:17:17 +01:00
Stefanos Kornilios Mitsis Poiitidis 4500cfb1d3 Remove white-space changes 2014-12-11 02:57:23 +01:00
Stefanos Kornilios Mitsis Poiitidis 63485e7a72 SetFloatStatusReg: support gcc for x86 2014-12-09 22:15:44 +01:00
Stefanos Kornilios Mitsis Poiitidis 77390f861e DSP only if HOST_NO_REC is not enabled 2014-12-09 22:15:00 +01:00
Stefanos Kornilios Mitsis Poiitidis 000f432548 No rend: fix process 2014-12-09 22:10:16 +01:00
Stefanos Kornilios Mitsis Poiitidis a4b3e8dc05 Auto detect gcc/vc 2014-12-09 22:09:51 +01:00
TwistedUmbrella f13d12a0b3 Merge pull request #564 from reicast/loungekatt
Add resources for error dialog, Disable test
2014-11-21 17:07:47 -05:00
TwistedUmbrella e4025420af Fix indentation issues when transferring code 2014-11-21 15:03:22 -05:00
TwistedUmbrella 4aa0bee20e Add lazy-load image library, Add github resources 2014-11-21 12:24:59 -05:00
TwistedUmbrella 6ba58fd695 Import debug tool git viewer and deprecate plugin 2014-11-21 12:24:59 -05:00
TwistedUmbrella 2c1b46dfd9 Update a stray translation for troubleshooting 2014-11-21 12:24:58 -05:00
TwistedUmbrella 4b58c695fc Allow default navigation to default to user folder 2014-11-21 12:24:58 -05:00
TwistedUmbrella 159d554c7d Fully unlink joystick config from compat & custom 2014-11-21 12:24:58 -05:00
TwistedUmbrella 612928fedf Add resources for error dialog, Disable test 2014-11-21 12:24:58 -05:00
Stefanos Kornilios Mitsis Poiitidis 9b38bcf079 Merge pull request #566 from reicast/r7-rc
Commits from r7-rc
2014-11-21 13:44:30 +02:00
TwistedUmbrella 4bd74aeebe Merge pull request #563 from reicast/loungekatt
Fix the display of messages within emu thread
2014-11-12 21:43:46 -05:00
TwistedUmbrella d26d4d4cfa Fix the display of messages within emu thread 2014-11-12 21:42:52 -05:00
Stefanos Kornilios Mitsis Poiitidis c2d1fbfdc2 WIP to get an alert dialog show
- new String() fails, somewhere deep on the android run-time, with no exception or some kind of logged error on my N4. WHY?
- The android debugger is a huge PITA.
- Eclipse is best left unused
2014-11-10 13:34:59 +01:00
Stefanos Kornilios Mitsis Poiitidis d1aa96d3e1 Improve error handling
Add coreMessage, die to EmuThread, propagate msgboxf to coreMessage
2014-11-10 05:28:52 +01:00
Stefanos Kornilios Mitsis Poiitidis ff4f5c21a8 Merge pull request #561 from reicast/skmp/travis-debug-cert
Merge skmp/travis-debug-cert
2014-11-07 04:06:28 +02:00
~skmp dc3575a2ef Create .android, mv is also better 2014-11-07 03:46:32 +02:00
~skmp 67b29e4923 Static debug cert 2014-11-07 03:39:40 +02:00
TwistedUmbrella dbc6f5a43c Merge pull request #557 from reicast/loungekatt
Fancy toast, Forgiving BIOS directory selection
2014-10-30 22:43:57 -04:00
Stefanos Kornilios Mitsis Poiitidis 28e9b27ec1 Increase travis to 2cpus
1.5VCPUs available according to docs, so this will help with build times (and also keep memory under control)
2014-10-30 11:44:05 +01:00
Stefanos Kornilios Mitsis Poiitidis c8540e5be9 Force -j1 on travis to avoid running out of memory 2014-10-30 11:12:52 +01:00
Stefanos Kornilios Mitsis Poiitidis bedb8564f2 Update ant/custom-build.xml to use env processor count (works windows), default to -j4, and also from env NDKBUILDOPT 2014-10-30 11:08:00 +01:00
TwistedUmbrella 5abd36612d Add resources for notification size limitations 2014-10-28 12:08:34 -04:00
TwistedUmbrella 49a44b3cb0 Fancy toast, Forgiving BIOS directory selection 2014-10-24 22:44:32 -04:00
Stefanos Kornilios Mitsis Poiitidis 157c837ec0 Merge branch 'skmp/gl3.1' 2014-10-22 14:42:02 +02:00
Stefanos Kornilios Mitsis Poiitidis 2b1aaf061d Isolate GLES, add DESKTOPGL option to core.mk 2014-10-22 14:39:07 +02:00
Stefanos Kornilios Mitsis Poiitidis e4844a37c3 Merge branch 'skmp/label_list_fix' 2014-10-22 14:15:40 +02:00
Stefanos Kornilios Mitsis Poiitidis 468b0109c8 Fix label array system 2014-10-22 14:11:39 +02:00
TwistedUmbrella 361e67e0a4 Merge pull request #554 from reicast/loungekatt
Workaround for relative path access restrictions
2014-10-20 00:04:00 -04:00
TwistedUmbrella 211fa6e3b1 Temporary disable of icons for Android L
java.lang.NullPointerException: Attempt to invoke virtual method
'boolean android.graphics.drawable.Drawable.canApplyTheme()' on a null
object reference

public boolean canApplyTheme () Added in API level 21
2014-10-19 09:43:06 -04:00
TwistedUmbrella 7d87829171 Workaround for relative path access restrictions 2014-10-19 08:08:54 -04:00
TwistedUmbrella da1a800797 Merge pull request #552 from reicast/loungekatt
BIOS Locator and fixes for KitKat Samsung directories
2014-10-16 15:09:58 -04:00
TwistedUmbrella 22adcee052 Implement functional locator and path navigation 2014-10-16 14:59:20 -04:00
TwistedUmbrella 88beeb147d Add a check for extSdCard mounts (Samsung) 2014-10-15 12:06:41 -04:00
TwistedUmbrella f84d31d84a Merge pull request #545 from reicast/loungekatt
Basic automated BIOS locator
2014-10-08 23:31:24 -04:00
TwistedUmbrella 1aa50faadf Basic automated BIOS locator
Requires BIOS still be in a “data” subfolder
2014-10-08 23:13:27 -04:00
TwistedUmbrella b18350652a Merge pull request #543 from reicast/loungekatt
Conversion to predefined menus to prevent scale issues
2014-10-08 21:47:39 -04:00
TwistedUmbrella 58d3c1a037 Fix alignment when restoring VMU to menu 2014-10-08 21:22:52 -04:00
TwistedUmbrella da03a6bbce Add main menu popup from predefined layout 2014-10-08 20:18:28 -04:00
TwistedUmbrella 81707ea383 Convert popup submenus to scrollable layouts 2014-10-07 01:30:12 -04:00
TwistedUmbrella af7fbf47c0 Switch to XML popup layouts to prevent size issues
This also adds text labels to the buttons for easier identification of
functionality
2014-10-06 14:22:50 -04:00
TwistedUmbrella 2280e67c44 Merge pull request #542 from LoungeKatt/master
Make sure menu items are visible in layout
2014-10-05 17:13:33 -04:00
TwistedUmbrella 151c754281 Make sure menu items are visible in layout 2014-10-05 17:13:02 -04:00
TwistedUmbrella b1575350d1 Merge pull request #541 from LoungeKatt/master
Update images with high res base graphic
2014-10-05 17:02:24 -04:00
TwistedUmbrella 6409215a1a Update images with high res base graphic 2014-10-05 17:01:23 -04:00
TwistedUmbrella cf57f7abb4 Merge pull request #539 from LoungeKatt/master
Move right stick toggle to options, Remove "exit" buttons
2014-10-05 16:33:53 -04:00
Stefanos Kornilios Mitsis Poiitidis 286d6372b5 Merge pull request #540 from reicast/skmp/gdtool
hash support on gdtool
2014-10-05 23:28:55 +03:00
TwistedUmbrella 26b669cc8d Move right stick setting to input options 2014-10-05 16:19:50 -04:00
Stefanos Kornilios Mitsis Poiitidis 97c487b06d Merge pull request #537 from LoungeKatt/master
Onscreen menu fixes and reduction
2014-10-05 23:15:05 +03:00
TwistedUmbrella 5156d04b76 More icon updates for additional placements 2014-10-05 14:13:12 -04:00
TwistedUmbrella 9ccaf18304 Modernize graphics to match site revision
Temporary resizes from Photoshop. Will be converted to vector graphic
for lossless resizing
2014-10-01 14:14:51 -04:00
TwistedUmbrella 0dba81b99a Move onscreen joystick config to configuration 2014-10-01 13:51:29 -04:00
TwistedUmbrella 7b615ad37c Add icon to for disk swap onscreen option 2014-10-01 13:46:38 -04:00
TwistedUmbrella 25c334e067 Merge pull request #536 from LoungeKatt/master
Update Moga lib, Refresh home between windows
2014-10-01 13:20:09 -04:00
TwistedUmbrella 846edc61d3 Update Moga lib, Refresh home between windows 2014-10-01 10:16:05 -04:00
Stefanos Kornilios Mitsis Poiitidis aa33d230e5 Merge branch 'master' into skmp/r7-sprint 2014-09-14 14:12:46 +03:00
TwistedUmbrella 1623086a48 Merge pull request #530 from LoungeKatt/master
Fix joystick dpad emulation, Refresh onscreen controls
2014-09-11 14:36:54 -04:00
TwistedUmbrella 0b2494b568 Fix onscreen control layout on layout change
Addresses https://github.com/reicast/reicast-emulator/issues/531
2014-09-11 01:14:20 -04:00
TwistedUmbrella f3fde06548 Unlink custom from JS-Dpad, Rename appropriately
The preference name was a little misleading. The preference has the
same functionality, but was named to imply an inverse functionality. It
is now disabled by default, which may need to be reversed if the number
of games requiring the feature to split the two controls is outweighed
by the number for which the feature disables joystick functionality.
2014-09-11 01:14:15 -04:00
Stefanos Kornilios Mitsis Poiitidis 51946d606a Merge branch 'master' into skmp/r7-sprint 2014-09-05 13:21:56 +03:00
Stefanos Kornilios Mitsis Poiitidis a674e6d61a Merge branch 'master' into skmp/r7-sprint 2014-09-05 13:20:31 +03:00
TwistedUmbrella 223f818a33 Merge pull request #523 from LoungeKatt/master
Support basic debug plugin when app unavailable
2014-08-31 08:35:47 -04:00
Stefanos Kornilios Mitsis Poiitidis 0825ca5a4b hash support on gdtool 2014-08-26 00:53:14 +03:00
Stefanos Kornilios Mitsis Poiitidis 3f53172873 Merge pull request #519 from lutris/master
Update README with Linux build instructions
2014-08-24 01:25:33 +03:00
ptitSeb 763e0948c0 Merge branch 'pandora' of https://github.com/reicast/emulator into pandora 2014-08-18 23:03:05 +02:00
Karen Tsai 2c651298d5 Updated iOS front end, removed low quality UI images. Need to make better ones using the Android UI images. 2014-08-18 22:56:35 +02:00
Karen Tsai bbe745da49 Massive build fix for iOS, ngen_arm.S (ARM JIT core) now compiles! The next goal… fix OGLES2. Because that’s completely broken. Also, updated .gitignore to properly ignore iOS build artifacts. 2014-08-18 22:54:08 +02:00
ptitSeb 3d8183bb86 Small update to Makefile 2014-08-18 22:50:33 +02:00
ptitSeb 0a17c4333a PANDORA: Options and GUI 2014-08-18 22:50:32 +02:00
TwistedUmbrella 3da30ba555 Disable internet components when detail option disabled 2014-08-18 22:41:17 +02:00
Stefanos Kornilios Mitsis Poiitidis 4f3cee2d87 Improve async/mt rendering & sync logic.
Should fix texture staging issues for now, without degrading performance
Fixes #49 (mvsc2, sf3, etc sprites)
2014-08-18 22:39:21 +02:00
TwistedUmbrella 8ebe44ea85 Preload game details to allow setting icons, faster loading 2014-08-18 22:35:25 +02:00
TwistedUmbrella a5ff5c9473 Async XML loading, Move XML methods to parser class 2014-08-18 22:33:05 +02:00
TwistedUmbrella 8c69e6142e Add a proper info API, but retain the requirements for now 2014-08-18 22:29:35 +02:00
TwistedUmbrella c1537ca3c8 Add game details as webpage popup during launch process
Currently supports games with standard naming (i.e. Dead or Alive 2) or
brackets for details (i.e. Dead or Alive 2 [NTSC-J])
2014-08-18 22:26:00 +02:00
Stefanos Kornilios Mitsis Poiitidis b55fbef3a6 Stored TA command stream persists on TA_LIST_INIT, until first actual write.
Fixes #141, "Main menus on POD and Speed Devil show up black"

Seems like the TA doesn't touch any of the memory structures before first write (and probably later on, but we're not gonna support corrupted ta streams for now)

According to p1pkin

«At least in SpeedDevils, at title screen game do a bit weird thing
 - Init TA context
 - Send lists to TA
 - Init the same context again
 - Start Render

so, if you are clear stored poly/vertex data at "TA_LIST_INIT" pvr2 reg write - you'll get black screen instead game title»
2014-08-18 22:22:30 +02:00
Stefanos Kornilios Mitsis Poiitidis 1cf68c7b38 Webui for linux 2014-08-18 22:21:18 +02:00
Stefanos Kornilios Mitsis Poiitidis 5e35e7f746 Initial webui code (that does nothing useful)
I plan to port over the existing nulldc debugger stuff to a webui so we can do remote debugging on android and more
2014-08-18 22:18:03 +02:00
Stefanos Kornilios Mitsis Poiitidis 778efcdf19 add libwebsocket 2014-08-18 22:15:27 +02:00
ptitSeb a56538babc PANDORA: Options and GUI 2014-08-18 21:58:46 +02:00
ptitSeb c4715150cc PANDORA: played with ccache 2014-08-18 21:58:45 +02:00
ptitSeb 15708686b9 Added back manual frameskip due to forum request 2014-08-18 21:57:16 +02:00
ptitSeb 229fa41b30 compilations fixes for Pandora 2014-08-18 21:57:15 +02:00
ptitSeb b7afa6a498 some fixes for Pandora 2014-08-18 21:57:15 +02:00
ptitSeb 6a9cdd7633 added frameskip back, has asked in openpandora forum 2014-08-18 21:57:14 +02:00
Stefanos Kornilios Mitsis Poiitidis 85d806c355 First idea for a gdrom tool 2014-08-18 21:56:04 +02:00
Karen Tsai ae91ea63e7 Removed more low-quality and unused UI images, updated emulator view controller. 2014-08-18 21:56:03 +02:00
Karen Tsai b4cc42bd2e Updated iOS front end, removed low quality UI images. Need to make better ones using the Android UI images. 2014-08-18 21:56:03 +02:00
AndroidGX 7e3ee8ca26 French translation update 2014-08-18 21:56:02 +02:00
TwistedUmbrella d31f324212 Add explicit casting for iOS, Import iOS EGL headers
EGL headers imported from https://github.com/alco/EGL_mac_ios for use
in iOS specialty directory
2014-08-18 21:56:02 +02:00
Karen Tsai 269ac637d3 …And fixed a typo that was somehow made during the process of cutting-and-pasting. 2014-08-18 21:56:01 +02:00
Karen Tsai bce423e877 Massive build fix for iOS, ngen_arm.S (ARM JIT core) now compiles! The next goal… fix OGLES2. Because that’s completely broken. Also, updated .gitignore to properly ignore iOS build artifacts. 2014-08-18 21:56:01 +02:00
TwistedUmbrella 2da588b7bb Attempt to avoid some contextual issues with info display 2014-08-18 21:56:00 +02:00
Luca1991 35b7ce464c Removed some unused localization strings (maybe used for debug purposes in the past??) that caused some compilation warnings 2014-08-18 21:56:00 +02:00
TwistedUmbrella b326bc2843 Proper immersive view for the main menu layouts 2014-08-18 21:55:59 +02:00
ptitSeb 01c419c63a Small update to Makefile 2014-08-18 21:55:59 +02:00
ptitSeb b5dcc93766 PANDORA: No mic on Pandora for now 2014-08-18 21:55:58 +02:00
ptitSeb aa80f4a852 PANDORA: Options and GUI 2014-08-18 21:55:57 +02:00
ptitSeb 4d8d5f68fc Fixed Pandora Makefile 2014-08-18 21:55:56 +02:00
Luca1991 9d6adf8221 Added Italian Localization 2014-08-18 21:54:31 +02:00
TwistedUmbrella 4058ecc737 Disable info display by default until internet check works 2014-08-18 21:54:31 +02:00
Stefanos Kornilios Mitsis Poiitidis 734db8a743 Split CFLAGS/CXXFLAGS on core.mk, warning fixes 2014-08-18 21:54:30 +02:00
Stefanos Kornilios Mitsis Poiitidis 5de530d68e Echo state on websocket, hack abit the nacl makefile 2014-08-18 21:54:30 +02:00
Luca1991 a711b4e0e3 CloudVMU tool added 2014-08-18 21:54:29 +02:00
Claus Østergaard 1414176b08 Update strings.xml 2014-08-18 21:54:27 +02:00
Bryan Barnes 546c010517 i loves me some markdown 2014-08-18 21:54:27 +02:00
Bryan Barnes b5d2811de4 build badge! 2014-08-18 21:54:26 +02:00
Bryan Barnes f5bfa82fbd updated apk path in travis.yml, not we just need a working host for uploading the builds 2014-08-18 21:54:26 +02:00
Bryan Barnes d4b76ff9e1 updated travis.yml with recent build steps 2014-08-18 21:54:26 +02:00
TwistedUmbrella b787f590d3 Remove some test changes, Use drawable swap function 2014-08-18 21:54:25 +02:00
TwistedUmbrella c2c7af68bf Compatibility with compilers on non-Ubuntu platforms 2014-08-18 21:54:25 +02:00
TwistedUmbrella ea1686df08 Add the preliminary menu option to swap a utopia disk 2014-08-18 21:54:24 +02:00
TwistedUmbrella 78a8a70073 Initial testing of "coverflow" integration for XMB menus 2014-08-18 21:54:24 +02:00
TwistedUmbrella 261cfb13f3 Get filename when info disabled, Regex to avoid invalids 2014-08-18 21:54:23 +02:00
Stefanos Kornilios Mitsis Poiitidis 66d8b96ae3 Cleanup textures after they are dead for a while 2014-08-18 21:54:23 +02:00
MrPsyMan e22fd18ff8 Please do a sanity test before pushing your changes.
I should also start following the above advice. :p

t/y!
2014-08-18 21:54:22 +02:00
AndroidGX 44e80be303 French update about strings.xml
(lines and things to match latest english original strings.xml file).
2014-08-18 21:54:22 +02:00
TwistedUmbrella c4a32e73c4 Disable internet components when detail option disabled 2014-08-18 21:54:22 +02:00
Stefanos Kornilios Mitsis Poiitidis 9d438c3ff3 Improve async/mt rendering & sync logic.
Should fix texture staging issues for now, without degrading performance
Fixes #49 (mvsc2, sf3, etc sprites)
2014-08-18 21:54:21 +02:00
TwistedUmbrella c332985bd1 Separate joystick and dpad by default when not configured 2014-08-18 21:54:21 +02:00
TwistedUmbrella 3da4c2eab1 Permission for verifying network connectivity 2014-08-18 21:54:20 +02:00
TwistedUmbrella 6676a3456f Preload game details to allow setting icons, faster loading 2014-08-18 21:54:20 +02:00
TwistedUmbrella 4490934188 Async XML loading, Move XML methods to parser class 2014-08-18 21:54:19 +02:00
TwistedUmbrella 5022831093 Make displaying game details in launcher a preference 2014-08-18 21:54:19 +02:00
TwistedUmbrella 554c86522e Add a proper info API, but retain the requirements for now 2014-08-18 21:54:18 +02:00
TwistedUmbrella 4743d8d31f Add game details as webpage popup during launch process
Currently supports games with standard naming (i.e. Dead or Alive 2) or
brackets for details (i.e. Dead or Alive 2 [NTSC-J])
2014-08-18 21:54:18 +02:00
Stefanos Kornilios Mitsis Poiitidis 59fbb66a66 Stored TA command stream persists on TA_LIST_INIT, until first actual write.
Fixes #141, "Main menus on POD and Speed Devil show up black"

Seems like the TA doesn't touch any of the memory structures before first write (and probably later on, but we're not gonna support corrupted ta streams for now)

According to p1pkin

«At least in SpeedDevils, at title screen game do a bit weird thing
 - Init TA context
 - Send lists to TA
 - Init the same context again
 - Start Render

so, if you are clear stored poly/vertex data at "TA_LIST_INIT" pvr2 reg write - you'll get black screen instead game title»
2014-08-18 21:54:17 +02:00
Stefanos Kornilios Mitsis Poiitidis bcf299cfd4 Ignore group_en bit (via p1pkin, should fix "18 Wheeler - Minimap tiles / not confined to map boundaries") 2014-08-18 21:54:17 +02:00
Stefanos Kornilios Mitsis Poiitidis 7e1f639d6f Webui for linux 2014-08-18 21:54:16 +02:00
Stefanos Kornilios Mitsis Poiitidis 7d35000c18 WEBUI for android 2014-08-18 21:54:16 +02:00
Stefanos Kornilios Mitsis Poiitidis 528d0c6d7a Initial webui code (that does nothing useful)
I plan to port over the existing nulldc debugger stuff to a webui so we can do remote debugging on android and more
2014-08-18 21:54:16 +02:00
Stefanos Kornilios Mitsis Poiitidis eb3f1ca687 Add more missing files 2014-08-18 21:54:15 +02:00
Stefanos Kornilios Mitsis Poiitidis 1a063b8f0d Add missing file 2014-08-18 21:54:15 +02:00
Stefanos Kornilios Mitsis Poiitidis 5cccea4a71 add libwebsocket 2014-08-18 21:54:14 +02:00
TwistedUmbrella 7bc1d7cdac Fix the typo now that it is actually being referenced 2014-08-18 21:54:13 +02:00
TwistedUmbrella fec60d0546 Summary check for intent data to support specific action 2014-08-18 21:54:13 +02:00
TwistedUmbrella 7f7387cf18 Remove unnecessary exposed intents, Add toast handler 2014-08-18 21:54:13 +02:00
TwistedUmbrella 66c1047427 Check for alternate joystick handlers (GameKeyboard, etc.)
Remove unused imports from various activities
Verify if gamekeyboard is being used to replace hardware
Configure stock controller layout as default
2014-08-18 21:54:12 +02:00
TwistedUmbrella cd06c05bef NativeActivity and navigational stability improvements
Improve shutdown when errors occur to prevent inability to restart
Reduce the context for launching activities to local application
Error checking when launching the native touchpad interface
2014-08-18 21:54:12 +02:00
ptitSeb b66de11664 PANDORA: No mic on Pandora for now 2014-08-18 21:54:11 +02:00
ptitSeb b0c222bdd6 PANDORA: Options and GUI 2014-08-18 21:53:38 +02:00
ptitSeb c2b2c7146b Fixed Pandora Makefile 2014-08-18 21:52:14 +02:00
ptitSeb 5548a9b6f8 PANDORA: played with ccache 2014-08-18 21:51:13 +02:00
ptitSeb e512eca05b Pandora Makefile change 2014-08-18 21:46:52 +02:00
ptitSeb 891c0011bb Added back manual frameskip due to forum request 2014-08-18 21:44:10 +02:00
ptitSeb 387bf0a960 compilations fixes for Pandora 2014-08-18 21:44:09 +02:00
ptitSeb 99389db89c some fixes for Pandora 2014-08-18 21:44:09 +02:00
ptitSeb 607b9c41a0 added frameskip back, has asked in openpandora forum 2014-08-18 21:44:08 +02:00
Stefanos Kornilios Mitsis Poiitidis c74215f1e8 First idea for a gdrom tool 2014-08-18 21:40:59 +02:00
Karen Tsai 126f65ec7a Removed more low-quality and unused UI images, updated emulator view controller. 2014-08-18 21:40:59 +02:00
Karen Tsai 80ff2c600a Updated iOS front end, removed low quality UI images. Need to make better ones using the Android UI images. 2014-08-18 21:40:58 +02:00
AndroidGX 0f3c95df4c French translation update 2014-08-18 21:40:57 +02:00
TwistedUmbrella c398edf22c Add explicit casting for iOS, Import iOS EGL headers
EGL headers imported from https://github.com/alco/EGL_mac_ios for use
in iOS specialty directory
2014-08-18 21:40:57 +02:00
Karen Tsai 2f846e912c …And fixed a typo that was somehow made during the process of cutting-and-pasting. 2014-08-18 21:40:56 +02:00
Karen Tsai f468fb0405 Massive build fix for iOS, ngen_arm.S (ARM JIT core) now compiles! The next goal… fix OGLES2. Because that’s completely broken. Also, updated .gitignore to properly ignore iOS build artifacts. 2014-08-18 21:40:56 +02:00
TwistedUmbrella cd4447dd4b Attempt to avoid some contextual issues with info display 2014-08-18 21:40:55 +02:00
Luca1991 21d787bdd0 Removed some unused localization strings (maybe used for debug purposes in the past??) that caused some compilation warnings 2014-08-18 21:40:55 +02:00
TwistedUmbrella 9c7c2b8637 Proper immersive view for the main menu layouts 2014-08-18 21:40:55 +02:00
ptitSeb 7c29dcc9af Small update to Makefile 2014-08-18 21:40:54 +02:00
ptitSeb 8dd98be0ee PANDORA: No mic on Pandora for now 2014-08-18 21:40:53 +02:00
ptitSeb dd6e7fae46 PANDORA: Options and GUI 2014-08-18 21:40:52 +02:00
ptitSeb b9690ae0be Fixed Pandora Makefile 2014-08-18 21:40:51 +02:00
Luca1991 d9c8074026 Added Italian Localization 2014-08-18 21:35:40 +02:00
TwistedUmbrella e4f227f213 Disable info display by default until internet check works 2014-08-18 21:35:40 +02:00
Stefanos Kornilios Mitsis Poiitidis 925535141a Split CFLAGS/CXXFLAGS on core.mk, warning fixes 2014-08-18 21:35:39 +02:00
Stefanos Kornilios Mitsis Poiitidis 9aa3b4b468 Echo state on websocket, hack abit the nacl makefile 2014-08-18 21:35:38 +02:00
Luca1991 2e8bb02fed CloudVMU tool added 2014-08-18 21:35:38 +02:00
Claus Østergaard ec218b5d60 Update strings.xml 2014-08-18 21:35:36 +02:00
Bryan Barnes 54ba0a06bf i loves me some markdown 2014-08-18 21:35:36 +02:00
Bryan Barnes a38c13c0da build badge! 2014-08-18 21:35:35 +02:00
Bryan Barnes 9c1532d45a updated apk path in travis.yml, not we just need a working host for uploading the builds 2014-08-18 21:35:35 +02:00
Bryan Barnes 1e7e66aaeb updated travis.yml with recent build steps 2014-08-18 21:35:34 +02:00
TwistedUmbrella 09949d8dda Remove some test changes, Use drawable swap function 2014-08-18 21:35:34 +02:00
TwistedUmbrella e8b30fb3d9 Compatibility with compilers on non-Ubuntu platforms 2014-08-18 21:35:33 +02:00
TwistedUmbrella e1b8463f10 Add the preliminary menu option to swap a utopia disk 2014-08-18 21:35:33 +02:00
TwistedUmbrella 8e7904b94b Initial testing of "coverflow" integration for XMB menus 2014-08-18 21:35:32 +02:00
TwistedUmbrella 8cfa6f856c Get filename when info disabled, Regex to avoid invalids 2014-08-18 21:35:32 +02:00
Stefanos Kornilios Mitsis Poiitidis 8e77ebce53 Cleanup textures after they are dead for a while 2014-08-18 21:35:32 +02:00
MrPsyMan 31acabbc8d Please do a sanity test before pushing your changes.
I should also start following the above advice. :p

t/y!
2014-08-18 21:35:31 +02:00
AndroidGX c6f955b6a6 French update about strings.xml
(lines and things to match latest english original strings.xml file).
2014-08-18 21:35:31 +02:00
TwistedUmbrella 038a310e7e Disable internet components when detail option disabled 2014-08-18 21:35:30 +02:00
Stefanos Kornilios Mitsis Poiitidis 5a3d19d743 Improve async/mt rendering & sync logic.
Should fix texture staging issues for now, without degrading performance
Fixes #49 (mvsc2, sf3, etc sprites)
2014-08-18 21:35:30 +02:00
TwistedUmbrella 0a98cb590a Separate joystick and dpad by default when not configured 2014-08-18 21:35:29 +02:00
TwistedUmbrella a3261aaa70 Permission for verifying network connectivity 2014-08-18 21:35:28 +02:00
TwistedUmbrella 09a70971af Preload game details to allow setting icons, faster loading 2014-08-18 21:35:28 +02:00
TwistedUmbrella 26a35e4937 Async XML loading, Move XML methods to parser class 2014-08-18 21:35:27 +02:00
TwistedUmbrella 26b3ea0b1c Make displaying game details in launcher a preference 2014-08-18 21:35:27 +02:00
TwistedUmbrella 9ef206b90b Add a proper info API, but retain the requirements for now 2014-08-18 21:35:27 +02:00
TwistedUmbrella 8ce9b2397f Add game details as webpage popup during launch process
Currently supports games with standard naming (i.e. Dead or Alive 2) or
brackets for details (i.e. Dead or Alive 2 [NTSC-J])
2014-08-18 21:35:26 +02:00
Stefanos Kornilios Mitsis Poiitidis fc48044323 Stored TA command stream persists on TA_LIST_INIT, until first actual write.
Fixes #141, "Main menus on POD and Speed Devil show up black"

Seems like the TA doesn't touch any of the memory structures before first write (and probably later on, but we're not gonna support corrupted ta streams for now)

According to p1pkin

«At least in SpeedDevils, at title screen game do a bit weird thing
 - Init TA context
 - Send lists to TA
 - Init the same context again
 - Start Render

so, if you are clear stored poly/vertex data at "TA_LIST_INIT" pvr2 reg write - you'll get black screen instead game title»
2014-08-18 21:35:26 +02:00
Stefanos Kornilios Mitsis Poiitidis ee81dd881e Ignore group_en bit (via p1pkin, should fix "18 Wheeler - Minimap tiles / not confined to map boundaries") 2014-08-18 21:35:25 +02:00
Stefanos Kornilios Mitsis Poiitidis 903b7b0240 Webui for linux 2014-08-18 21:35:25 +02:00
Stefanos Kornilios Mitsis Poiitidis 09f1805a9c WEBUI for android 2014-08-18 21:35:24 +02:00
Stefanos Kornilios Mitsis Poiitidis 80e42e6c25 Initial webui code (that does nothing useful)
I plan to port over the existing nulldc debugger stuff to a webui so we can do remote debugging on android and more
2014-08-18 21:35:24 +02:00
Stefanos Kornilios Mitsis Poiitidis 58a27e21e0 Add more missing files 2014-08-18 21:35:23 +02:00
Stefanos Kornilios Mitsis Poiitidis 9e2a116bfd Add missing file 2014-08-18 21:35:23 +02:00
Stefanos Kornilios Mitsis Poiitidis f51a461234 add libwebsocket 2014-08-18 21:35:22 +02:00
TwistedUmbrella acaaf41ad5 Fix the typo now that it is actually being referenced 2014-08-18 21:35:22 +02:00
TwistedUmbrella e9142787b8 Summary check for intent data to support specific action 2014-08-18 21:35:21 +02:00
TwistedUmbrella 88b56b02a6 Remove unnecessary exposed intents, Add toast handler 2014-08-18 21:35:21 +02:00
TwistedUmbrella 03d4f59a02 Check for alternate joystick handlers (GameKeyboard, etc.)
Remove unused imports from various activities
Verify if gamekeyboard is being used to replace hardware
Configure stock controller layout as default
2014-08-18 21:35:20 +02:00
TwistedUmbrella 437da8cd77 NativeActivity and navigational stability improvements
Improve shutdown when errors occur to prevent inability to restart
Reduce the context for launching activities to local application
Error checking when launching the native touchpad interface
2014-08-18 21:35:20 +02:00
ptitSeb 40a085b841 PANDORA: No mic on Pandora for now 2014-08-18 21:35:19 +02:00
ptitSeb 93c56d803c PANDORA: Options and GUI 2014-08-18 21:33:16 +02:00
ptitSeb 08b34969aa Fixed Pandora Makefile 2014-08-18 21:29:49 +02:00
ptitSeb cfb74c4ebf PANDORA: played with ccache 2014-08-18 21:29:48 +02:00
ptitSeb 32c0aa4ac3 Added back manual frameskip due to forum request 2014-08-18 21:26:03 +02:00
ptitSeb 8388210b2b compilations fixes for Pandora 2014-08-18 21:17:20 +02:00
ptitSeb 8ebf06e0da Merge remote-tracking branch 'origin/master' into pandora 2014-08-18 21:15:11 +02:00
TwistedUmbrella 115504ed50 Support basic debug plugin when app unavailable 2014-08-16 13:35:31 -04:00
Mathieu Comandon 04eb34adc6 Add linux build files to gitignore 2014-08-08 21:38:35 +02:00
Mathieu Comandon fa1c8bdb1c Update README with Linux build instructions 2014-08-08 21:27:59 +02:00
TwistedUmbrella bc6870a9ca Merge pull request #514 from LoungeKatt/master
Revert filesystem changes [testing], RS sensitivity, merge r7-sprint
2014-08-02 12:47:16 -04:00
TwistedUmbrella dcc5c6dce6 Merge pull request #505 from kitrio/patch-2
Update strings.xml
2014-08-02 12:45:15 -04:00
Stefanos Kornilios Mitsis Poiitidis 8dfc8f45f8 Add diagonials 2014-08-02 12:44:41 -04:00
Stefanos Kornilios Mitsis Poiitidis 5e66c99233 Fix immersive mode & gl resize
- Pass raw width & height to internal C/C++ code, so that resizes propagate
- Fixes input button & image missalignment on 4.4+
2014-08-02 12:44:30 -04:00
TwistedUmbrella dada5fb520 Retain permissions, Lower RS sensitivity limit 2014-07-29 20:24:42 -04:00
TwistedUmbrella e7037fe638 Revert "Add permissions and directory changes for KitKat"
This reverts commit 334431e786ccc0b822a06a339f20dd358c3ee580.
2014-07-29 20:24:30 -04:00
TwistedUmbrella 2cbf70b7c6 Revert "Rough draft of file handler for KitKat restrictions"
This reverts commit 512def9f1995777bc2960996b0960a6500e41d00.
2014-07-29 20:24:17 -04:00
TwistedUmbrella 38fedcab5f Revert "Revert the user directory after copy procedure"
This reverts commit f8f30cee1649240aef2c29e51aaee6bac34cccdb.
2014-07-29 20:23:47 -04:00
Stefanos Kornilios Mitsis Poiitidis 3ba9170ec8 Add diagonials 2014-07-26 11:53:18 +03:00
Stefanos Kornilios Mitsis Poiitidis 08bed69c95 Fix detected branch name
My git-fu needs some practice...
2014-07-24 16:58:59 +03:00
Stefanos Kornilios Mitsis Poiitidis a05760260e Move debugbreak to os module 2014-07-24 16:54:04 +03:00
Stefanos Kornilios Mitsis Poiitidis 55cc9d28db travis: keep commit branch 2014-07-24 16:43:03 +03:00
Stefanos Kornilios Mitsis Poiitidis 7d2a1d9556 Fix immersive mode & gl resize
- Pass raw width & height to internal C/C++ code, so that resizes propagate
- Fixes input button & image missalignment on 4.4+
2014-07-24 13:32:15 +03:00
Stefanos Kornilios Mitsis Poiitidis a3728d146f Update gitignore 2014-07-24 11:31:09 +03:00
TwistedUmbrella e2dc6725bb Merge pull request #510 from seanstar12/master
Added adjustable vibration duration
2014-07-17 02:07:23 -04:00
Sean Starnes e0e25d0668 Added adjustable vibration duration 2014-07-15 21:38:14 -05:00
TwistedUmbrella 1095ffbcf1 Merge pull request #508 from LoungeKatt/master
Rough draft of file handler for KitKat restrictions
2014-07-11 23:02:42 -04:00
TwistedUmbrella 307344a3ec Revert the user directory after copy procedure 2014-07-10 14:01:43 -04:00
TwistedUmbrella e30f181628 Rough draft of file handler for KitKat restrictions 2014-07-10 13:58:22 -04:00
TwistedUmbrella 823cd76345 Merge pull request #507 from LoungeKatt/master
Handle trigger inputs regardless of R stick config
2014-07-07 11:40:48 -04:00
TwistedUmbrella 3fbc58cf0f Handle trigger inputs regardless of R stick config 2014-07-07 11:37:25 -04:00
hooby3dfx d405d8157f Merge pull request #506 from hooby3dfx/master
minor tweak to mic support
2014-07-05 22:43:47 -04:00
kitrio e4deef3da2 Update strings.xml
improve korean translatation
2014-07-05 20:58:55 +09:00
Stefanos Kornilios Mitsis Poiitidis 531863bca4 Fix rendering: GL3+ needs VAO, initialize screen_width/screen_height
*yay* it works now *dances*
2014-06-27 00:51:57 +03:00
Stefanos Kornilios Mitsis Poiitidis 6d6cf7d055 Call correct Texture/texture2d 2014-06-25 22:47:40 +03:00
Stefanos Kornilios Mitsis Poiitidis a1dfeb19e1 Partial port to opengl.
I forgot how much opengl sucked, so I figured I might try a port.

Nvidia doesn't draw (must be some fragment binding issue?, randomlulz returns GL_INVALID on glAttribPtr as well)
Intel doesn't compile the shader (and the error message makes no real sense. wut?)
Amd driver simply crashes (wheehaa)

All and all, doesn't look like much has changed in opengl the past 10 years, apart from even uglier initialization and more fragmented specs ~
2014-06-25 22:47:39 +03:00
Stefanos Kornilios Mitsis Poiitidis 43def486b3 Merge pull request #501 from reicast/skmp/gdtool
Fix coreio/fclose leak, -info-basename option for gdtool
2014-06-25 17:55:58 +03:00
Stefanos Kornilios Mitsis Poiitidis ac31cced87 Remove dead code 2014-06-23 01:31:17 +03:00
Stefanos Kornilios Mitsis Poiitidis 0ae8e0ebc8 fclose properly, 0 on coreio_open fail 2014-06-23 01:31:04 +03:00
Stefanos Kornilios Mitsis Poiitidis 4084fd1ced gdtoo: file basename on json with -info-basename 2014-06-20 11:19:42 +03:00
Stefanos Kornilios Mitsis Poiitidis 4c67940eb5 Merge pull request #499 from reicast/skmp/gdtool
skmp/gdtool
2014-06-19 01:19:15 +03:00
Stefanos Kornilios Mitsis Poiitidis 2079ba2558 Add builds.reicast.com 2014-06-19 01:17:57 +03:00
Stefanos Kornilios Mitsis Poiitidis 0d3172fd69 Fix gdtool build, fseek bugfix for coreio 2014-06-19 00:38:31 +03:00
Stefanos Kornilios Mitsis Poiitidis e938844387 Windows: 720p window 2014-06-17 22:38:07 +03:00
Stefanos Kornilios Mitsis Poiitidis fa09664ce5 Merge pull request #498 from LoungeKatt/master
Add permissions and directory changes for KitKat
2014-06-17 15:36:23 +03:00
TwistedUmbrella fed435b4fb Add permissions and directory changes for KitKat 2014-06-17 06:30:28 -04:00
Stefanos Kornilios Mitsis Poiitidis 314298a4d9 Merge pull request #496 from reicast/gdtool-refactor
gdtool: better command line, stdin lists, cleanup
2014-06-13 19:02:21 +03:00
Stefanos Kornilios Mitsis Poiitidis 0ea8f2290a Travis-ci: enable notifications to irc 2014-06-13 19:00:10 +03:00
Stefanos Kornilios Mitsis Poiitidis d59197f843 gdtool: better command line, stdin lists, cleanup
Also, imgread const filenames and such
2014-06-13 18:41:48 +03:00
Stefanos Kornilios Mitsis Poiitidis 16bee22105 Merge pull request #491 from reicast/http-chd
Http chd wip
2014-06-11 18:00:09 +03:00
Stefanos Kornilios Mitsis Poiitidis 4fbfb3bed9 S3 deploy for travis, listing at builds.reicast.com ~ 2014-06-11 17:40:44 +04:00
MrPsyMan 7916cd63f3 Removed commit ed8c25ef7c as it causes compatibility problems. 2014-06-05 04:34:25 +03:00
MrPsyMan bf9275f3d0 Merge branch 'r7-rc' of https://github.com/reicast/reicast-emulator into r7-rc 2014-06-05 04:29:29 +03:00
MrPsyMan 101952c38b Reverted commit ed8c25ef7c as it creates compatibility issues. 2014-06-05 04:24:32 +03:00
TwistedUmbrella d73d899898 Merge pull request #486 from LoungeKatt/master
Merge settings and paths for simpler menu system
2014-06-02 13:06:12 -04:00
TwistedUmbrella f1bdc306e6 Relabel native interface to warn users that it lacks OSD 2014-06-02 13:02:24 -04:00
TwistedUmbrella 2a8b099ac5 Clear the image from memory before resizing it 2014-06-02 12:59:15 -04:00
Stefanos Kornilios Mitsis Poiitidis 8194c1e24a Added missing coreio/* files... 2014-06-01 13:54:11 +03:00
Stefanos Kornilios Mitsis Poiitidis 248bea39a9 Refactor coreio, fix for linux, make it build 2014-06-01 13:38:48 +03:00
ptitSeb ae5fa8c0e1 some fixes for Pandora 2014-05-27 22:00:17 +02:00
ptitSeb 5d9757ffef Merge branch 'r7-rc' of https://github.com/reicast/emulator into pandora
Conflicts:
	core/hw/pvr/Renderer_if.cpp
2014-05-27 19:55:53 +02:00
ptitSeb 9de2393bc0 added frameskip back, has asked in openpandora forum 2014-05-27 19:47:12 +02:00
TwistedUmbrella 0b5c991f0e Add wifi status permission for network availability 2014-05-27 01:58:48 -04:00
TwistedUmbrella 74ca093da3 Reduce, reuse, recycle (Even when it's a function) 2014-05-27 01:58:43 -04:00
TwistedUmbrella 4759b4fafb Add support for swapping BIOS files in local data folder 2014-05-27 01:58:43 -04:00
TwistedUmbrella b6aa26f5c9 Merge settings and paths for simpler menu system 2014-05-27 01:58:43 -04:00
Stefanos Kornilios Mitsis Poiitidis 2bd1c4c976 First idea for a gdrom tool 2014-05-26 15:35:41 +03:00
Karen Tsai 8ffb16df2b Removed more low-quality and unused UI images, updated emulator view controller. 2014-05-23 20:40:32 -04:00
Karen Tsai c5549a6106 Updated iOS front end, removed low quality UI images. Need to make better ones using the Android UI images. 2014-05-23 20:33:05 -04:00
TwistedUmbrella 24e9658a53 Merge pull request #487 from AndroidGX/patch-2
French translation update
2014-05-21 17:25:43 -04:00
AndroidGX ff65c9679c French translation update 2014-05-21 22:01:49 +02:00
Stefanos Kornilios Mitsis Poiitidis c6f62c66bd chd over http support (EXPERIMENTAL AND SLOW) 2014-05-21 20:07:59 +03:00
Karen Tsai 50b5fedc5f Merge pull request #485 from LoungeKatt/master
Add explicit casting for iOS, Import iOS EGL headers
2014-05-20 23:48:03 -04:00
TwistedUmbrella c3b1e1087e Add explicit casting for iOS, Import iOS EGL headers
EGL headers imported from https://github.com/alco/EGL_mac_ios for use
in iOS specialty directory
2014-05-20 23:45:38 -04:00
Karen Tsai 88d4e73f03 …And fixed a typo that was somehow made during the process of cutting-and-pasting. 2014-05-20 19:00:54 -04:00
Karen Tsai 370fa02b5c Massive build fix for iOS, ngen_arm.S (ARM JIT core) now compiles! The next goal… fix OGLES2. Because that’s completely broken. Also, updated .gitignore to properly ignore iOS build artifacts. 2014-05-20 18:58:41 -04:00
TwistedUmbrella 9e76688a6c Merge pull request #482 from LoungeKatt/master
Proper immersive view for the main menu layouts
2014-05-20 12:26:05 -04:00
TwistedUmbrella 2113dc503f Merge pull request #483 from Luca1991/master
Removed some unused localization strings
2014-05-20 12:25:26 -04:00
TwistedUmbrella 1d3a0a633b Attempt to avoid some contextual issues with info display 2014-05-20 12:24:23 -04:00
Luca1991 f993a1aea7 Removed some unused localization strings (maybe used for debug purposes in the past??) that caused some compilation warnings 2014-05-20 00:05:20 +02:00
TwistedUmbrella 45a3cff0d5 Proper immersive view for the main menu layouts 2014-05-19 14:20:06 -04:00
TwistedUmbrella 07c8e60ad7 Merge pull request #481 from Luca1991/master
Added Italian Localization
2014-05-18 16:49:22 -04:00
ptitSeb 937e28e04d rebasing 2014-05-18 20:10:00 +02:00
ptitSeb 948a3afcf6 Small update to Makefile 2014-05-18 20:08:18 +02:00
ptitSeb 2530cd330e PANDORA: No mic on Pandora for now 2014-05-18 20:07:15 +02:00
ptitSeb 3445276c60 PANDORA: Options and GUI 2014-05-18 20:04:46 +02:00
ptitSeb 260d9f7f57 Fixed Pandora Makefile 2014-05-18 19:58:28 +02:00
Luca1991 911bade123 Added Italian Localization 2014-05-18 18:38:05 +02:00
Stefanos Kornilios Mitsis Poiitidis aba6278213 Merge pull request #479 from LoungeKatt/master
Fixing the game info display
2014-05-15 15:52:18 -07:00
TwistedUmbrella 724109d02f Disable info display by default until internet check works 2014-05-15 09:32:43 -04:00
TwistedUmbrella ebeef1ddaf Merge pull request #474 from Luca1991/master
CloudVMU tool added
2014-05-13 19:03:57 -04:00
Stefanos Kornilios Mitsis Poiitidis f0b7d92262 Merge pull request #470 from coestergaard/patch-3
Update strings.xml
2014-05-12 20:55:29 +03:00
Stefanos Kornilios Mitsis Poiitidis ee2a1b7d20 Split CFLAGS/CXXFLAGS on core.mk, warning fixes 2014-05-12 20:53:43 +03:00
Stefanos Kornilios Mitsis Poiitidis 5f72bb34df Echo state on websocket, hack abit the nacl makefile 2014-05-12 20:53:42 +03:00
Luca1991 99e4f8b47f CloudVMU tool added 2014-05-11 18:53:28 +02:00
Claus Østergaard edfe1600ce Update strings.xml 2014-05-10 09:25:59 +02:00
Bryan Barnes ded16cf484 i loves me some markdown 2014-05-09 22:32:42 -04:00
Bryan Barnes b099888f5d build badge! 2014-05-09 22:31:05 -04:00
Bryan Barnes 868d77bf14 updated apk path in travis.yml, not we just need a working host for uploading the builds 2014-05-09 22:28:28 -04:00
Bryan Barnes 6241300c8f updated travis.yml with recent build steps 2014-05-09 22:16:29 -04:00
MrPsyMan aaf23eae46 Merge pull request #468 from LoungeKatt/master
Remove some test changes, Use drawable swap function
2014-05-09 22:05:38 +03:00
TwistedUmbrella 6ad8c9ac11 Remove some test changes, Use drawable swap function 2014-05-09 14:33:54 -04:00
MrPsyMan c01fad3f61 Merge pull request #460 from LoungeKatt/master
Get filename when info disabled, Regex to avoid invalids
2014-05-09 17:47:08 +03:00
TwistedUmbrella 9639e47802 Compatibility with compilers on non-Ubuntu platforms 2014-05-08 00:18:48 -04:00
TwistedUmbrella 64e50d0dab Add the preliminary menu option to swap a utopia disk 2014-05-08 00:02:42 -04:00
TwistedUmbrella c5c57b77ec Initial testing of "coverflow" integration for XMB menus 2014-05-08 00:02:42 -04:00
TwistedUmbrella 42f4085ed1 Get filename when info disabled, Regex to avoid invalids 2014-05-08 00:02:42 -04:00
Stefanos Kornilios Mitsis Poiitidis f1ef4877b8 Cleanup textures after they are dead for a while 2014-05-08 04:29:14 +03:00
MrPsyMan 2d8f2dd6b0 Please do a sanity test before pushing your changes.
I should also start following the above advice. :p

t/y!
2014-05-08 02:22:31 +03:00
Stefanos Kornilios Mitsis Poiitidis fee9e5123a Merge pull request #462 from AndroidGX/patch-1
French update about strings.xml
2014-05-07 14:28:14 +03:00
AndroidGX 150a129818 French update about strings.xml
(lines and things to match latest english original strings.xml file).
2014-05-05 22:40:24 +02:00
TwistedUmbrella aca3da42ab Merge pull request #457 from LoungeKatt/master
Temporary fix for names not matching requirements
2014-05-04 17:05:40 -04:00
TwistedUmbrella 933a36b5c4 Disable internet components when detail option disabled 2014-05-04 17:03:09 -04:00
Stefanos Kornilios Mitsis Poiitidis 411aade5e2 Improve async/mt rendering & sync logic.
Should fix texture staging issues for now, without degrading performance
Fixes #49 (mvsc2, sf3, etc sprites)
2014-05-02 03:45:31 +03:00
TwistedUmbrella a937428115 Merge pull request #440 from LoungeKatt/master
Add game information to launch process
2014-05-01 11:11:53 -04:00
TwistedUmbrella 4e40430a13 Separate joystick and dpad by default when not configured 2014-04-30 01:53:56 -04:00
TwistedUmbrella 122f1bbcb7 Permission for verifying network connectivity 2014-04-29 20:47:53 -04:00
TwistedUmbrella 8b76e84654 Preload game details to allow setting icons, faster loading 2014-04-29 20:33:25 -04:00
TwistedUmbrella 809a1afa28 Async XML loading, Move XML methods to parser class 2014-04-29 20:32:36 -04:00
TwistedUmbrella 5b94408a63 Make displaying game details in launcher a preference 2014-04-29 20:32:36 -04:00
TwistedUmbrella 4c965b883c Add a proper info API, but retain the requirements for now 2014-04-29 20:32:36 -04:00
TwistedUmbrella 9de771f30e Add game details as webpage popup during launch process
Currently supports games with standard naming (i.e. Dead or Alive 2) or
brackets for details (i.e. Dead or Alive 2 [NTSC-J])
2014-04-29 20:32:36 -04:00
Stefanos Kornilios Mitsis Poiitidis 207a063fa1 Merge branch 'master' of https://github.com/reicast/reicast-emulator 2014-04-25 19:58:30 +03:00
Stefanos Kornilios Mitsis Poiitidis 4492654a52 Stored TA command stream persists on TA_LIST_INIT, until first actual write.
Fixes #141, "Main menus on POD and Speed Devil show up black"

Seems like the TA doesn't touch any of the memory structures before first write (and probably later on, but we're not gonna support corrupted ta streams for now)

According to p1pkin

«At least in SpeedDevils, at title screen game do a bit weird thing
 - Init TA context
 - Send lists to TA
 - Init the same context again
 - Start Render

so, if you are clear stored poly/vertex data at "TA_LIST_INIT" pvr2 reg write - you'll get black screen instead game title»
2014-04-25 19:57:34 +03:00
Stefanos Kornilios Mitsis Poiitidis 35e357ad66 Ignore group_en bit (via p1pkin, should fix "18 Wheeler - Minimap tiles / not confined to map boundaries") 2014-04-25 19:52:27 +03:00
Stefanos Kornilios Mitsis Poiitidis 8081a3d06a Webui for linux 2014-04-25 06:26:36 +03:00
Stefanos Kornilios Mitsis Poiitidis 5fee692c31 WEBUI for android 2014-04-25 05:59:53 +03:00
Stefanos Kornilios Mitsis Poiitidis 5e25bfd507 Initial webui code (that does nothing useful)
I plan to port over the existing nulldc debugger stuff to a webui so we can do remote debugging on android and more
2014-04-23 00:04:22 +03:00
Stefanos Kornilios Mitsis Poiitidis 8b683a77a6 Add more missing files 2014-04-22 16:30:12 +03:00
Stefanos Kornilios Mitsis Poiitidis 4596bcc11b Add missing file 2014-04-22 16:23:20 +03:00
Stefanos Kornilios Mitsis Poiitidis 2f5bec2304 add libwebsocket 2014-04-22 16:15:54 +03:00
TwistedUmbrella 62cc877d69 Fix the typo now that it is actually being referenced 2014-04-07 16:28:24 -04:00
TwistedUmbrella 91800aec5e Summary check for intent data to support specific action 2014-04-07 04:47:55 -04:00
TwistedUmbrella 1e80306577 Remove unnecessary exposed intents, Add toast handler 2014-04-06 23:03:44 -04:00
TwistedUmbrella dafc502274 Check for alternate joystick handlers (GameKeyboard, etc.)
Remove unused imports from various activities
Verify if gamekeyboard is being used to replace hardware
Configure stock controller layout as default
2014-04-06 00:00:49 -04:00
TwistedUmbrella ea80157d2e NativeActivity and navigational stability improvements
Improve shutdown when errors occur to prevent inability to restart
Reduce the context for launching activities to local application
Error checking when launching the native touchpad interface
2014-04-05 13:25:42 -04:00
ptitSeb 7f2bf9432d Merge branch 'master' into pandora
Conflicts:
	core/hw/aica/sgc_if.cpp
	core/hw/maple/maple_devs.cpp
	core/sdl/main.cpp
2014-04-04 22:33:54 +02:00
TwistedUmbrella 014daafa2a Fix return intent from games, Fix touchscreen in native mode 2014-04-04 01:12:30 -04:00
TwistedUmbrella 0ba8350c3a Make sure the additional destroy code is actually executed 2014-04-03 16:59:37 -04:00
TwistedUmbrella 04db66dc6e Fix some build issues, Add an initialization stability check 2014-04-03 03:42:49 -04:00
TwistedUmbrella 9594444129 French language updates - @AndroidGX 2014-04-03 03:23:26 -04:00
TwistedUmbrella 9162a927c4 Handle explicit intent internally for single generic public intent
This will fix apps like Nostalgia crashing because of a “bug” that is
created when the intent is not specifically provided
2014-04-03 02:33:46 -04:00
TwistedUmbrella 164b93be98 Move joystick option below custom and compat requirements 2014-03-27 11:51:11 -04:00
TwistedUmbrella a1a3d02d2c Steps to prevent accidentally leaving linked options enabled 2014-03-26 21:41:26 -04:00
TwistedUmbrella f8a18c3abe Enable hardware accelerated view if GPU rendering enabled 2014-03-26 21:41:15 -04:00
Stefanos Kornilios Mitsis Poiitidis 9fbf7c972b Merge pull request #422 from coestergaard/patch-1
Updated to match latest English file
2014-03-26 11:45:04 +02:00
Claus Østergaard 71b5e7ae93 Updated to match latest English file 2014-03-25 18:47:33 +01:00
Stefanos Kornilios Mitsis Poiitidis 78f45da8da gles2 works w/ the correct packages 2014-03-24 23:20:21 +02:00
Stefanos Kornilios Mitsis Poiitidis 1d0a297a45 bugfix in libzip 2014-03-24 23:19:59 +02:00
Stefanos Kornilios Mitsis Poiitidis e356515198 compiles for lin86 (no rendering yet) 2014-03-20 17:13:53 +02:00
TwistedUmbrella a687285c81 Decide parameters based on activity rather than application 2014-03-18 16:09:18 -04:00
MrPsyMan ecbe828cfa Previous commit was one byte short. 2014-03-15 13:51:16 +02:00
MrPsyMan 6b4deb4b16 Implemented a very basic form of GD-ROM Sense. Only disc swap related Sense currently works. Added some very basic disc swap handling on x86/Windows (press "0">Cancel to remove disc, then "0" again and select the new disc).
Notes:
Disc swapping should work on .gdi files (probably .chd files too).
Swapping with .cdi files is not currently supported because we currently create inaccurate TOC for them.
Only x86/Windows has a disc swap handler right now (ie: you can't swap on Android).
2014-03-15 13:42:17 +02:00
Stefanos Kornilios Mitsis Poiitidis e6ac0e4918 Merge branch 'master' of https://github.com/reicast/reicast-emulator 2014-03-13 21:49:12 +02:00
Stefanos Kornilios Mitsis Poiitidis 5fd8eb8903 widescreen compitable bg clear (fixes widescreen mode) 2014-03-13 21:49:02 +02:00
TwistedUmbrella f2622f07bb Verify if compatibility mode requires the joystick - D-pad hack 2014-03-12 11:19:02 -04:00
Bryan Barnes fbf049cff1 tweaked mic for better voice input - need to test 2014-03-11 22:31:46 -04:00
Bryan Barnes b64dab5e01 added sdk note to readme 2014-03-11 22:30:14 -04:00
TwistedUmbrella 6097b6f5b0 Fix a preference typo and references for pre API 11 missing 2014-03-09 10:53:13 -04:00
Lioncash cc1fdb28db Fix a tiny typo in the missing BIOS message. 2014-03-08 18:32:38 -05:00
Lioncash d2524dea99 Merge pull request #401 from lioncash/fix-filebrowser
Fix case where the file list would cause a crash.
2014-03-08 17:17:39 -05:00
Lioncash 35cd0e1d38 Fix file list crash.
Fixes a stupid oversight that is entirely my fault.
2014-03-08 17:14:36 -05:00
TwistedUmbrella 27ee791d71 This should get the menus back to working properly again 2014-03-08 14:55:30 -05:00
TwistedUmbrella 2b9926d397 Remove unused functions, libs, imports, etc for externals 2014-03-06 06:08:51 -05:00
TwistedUmbrella 73c75b7a79 Pulling out all the resources being hosted privately 2014-03-06 05:13:32 -05:00
Lioncash acd0c58979 [Android] Remove unused imports. 2014-03-06 04:59:59 -05:00
Lioncash 3640293f40 [Android] Join a duplicate if statement in InputFragment's MOGAListener. 2014-03-06 04:54:55 -05:00
Lioncash c354e09676 [Android] Make MOGAInput's activity context private.
Also make the class final.
2014-03-06 04:41:32 -05:00
TwistedUmbrella 8dc18039be Merge pull request #400 from 0002647302/master
isEmpty() is an API 9 + call. Currently we still support 8+
2014-03-06 04:38:09 -05:00
TwistedUmbrella db1f4d24c5 isEmpty() is an API 9 + call. Currently we still support 8+ 2014-03-06 04:36:52 -05:00
TwistedUmbrella 03231f51f2 Merge pull request #399 from 0002647302/master
Remove the git display from the main interface, It is debug
2014-03-06 04:32:41 -05:00
TwistedUmbrella c29dd5d60b Remove the git display from the main interface, It is debug 2014-03-06 04:32:17 -05:00
Lioncash e9891118f7 [Android] Kill off unnecessary getString calls. 2014-03-06 04:28:47 -05:00
Lioncash 08d40fe44f [Android] Simplify display metrics retrieval in Config.java. 2014-03-06 04:11:29 -05:00
TwistedUmbrella 4b98fe2cb5 Merge pull request #398 from 0002647302/master
This is cleanup after recent changes
2014-03-06 04:08:43 -05:00
TwistedUmbrella 6da7b865d9 [Android] Clean up for things only being done halfway.
Changing from a collection to an array back to a collection was just
adding a lot of unnecessary overhead. This removes that pointless
process and adds the previous changes to the second activity for
handling controllers.
2014-03-06 04:05:29 -05:00
Lioncash d085678817 [Android] Tiny cleanup to InputFragment.java.
Mild side-cleanup to OptionsFragment.java. Purely minor.
2014-03-06 04:04:36 -05:00
Lioncash 1439200253 [Android] Clean up InputModFragment.java
Replace parentActivity calls to getResources with just a direct call.
Replace hardcoded strings.
Remove pointless String.valueOf calls.
Remove the parentActivity. Again, this is totally unnecessary.
2014-03-06 03:56:10 -05:00
Lioncash a6bfd58a00 [Android] Clean up ConfigureFragment.java.
Call getResources directly.
Kill off parentActivity class variable. Absolutely pointless if it's used only in one method.

Fix up the atrocious line breaks.
2014-03-06 03:43:09 -05:00
TwistedUmbrella f7a651f2a7 Update the listing for the buildbot now that it is all in-app 2014-03-06 03:35:44 -05:00
Lioncash d90243a2c9 [Android] Replace string .equals("") tests in conditionals with .isEmpty() 2014-03-06 03:28:15 -05:00
Lioncash 7924f11284 [Android] Turns out some other class variables were able to be made private too in FileBrowser.java.
Removed the privacy level specifiers in the interface OnItemSelectedListener. public is implicit for any interface method.
2014-03-06 03:17:48 -05:00
TwistedUmbrella 0e7fb27a8d Refactor in @hooby3dfx FPS color choice, Remove alpha 2014-03-06 03:15:25 -05:00
Lioncash 9937875d38 [Android] Make the DirSort class a private static final class in FileBrowser.java.
It's used nowhere else and leaving it as package local is just stupid.
2014-03-06 03:14:44 -05:00
Lioncash 2e3bb791ab [Android] Bump the Eclipse config for the android app to be compliant with 1.6
Sorta weird this wasn't already set to this, considering Android uses 1.6 (and a hacky/crappy syntax only version of 1.7 if you consider 4.4+)
2014-03-06 03:12:20 -05:00
Lioncash 19b23a411f [Android] Convert some for loops to foreach loops in FileBrowser.java.
Also make an anonymous class method parameter more readable. Anything is better than arg[x].
2014-03-06 03:04:42 -05:00
Lioncash 6e65e8d565 [Android] Use File's getPath() and not toString() to communicate intent in saveScreenshot().
Both do the exact same thing, but one is way more indicative of intent here.

Also removed an unnecessary flush. This happens upon calling .close.
2014-03-06 02:42:35 -05:00
Karen Tsai c2b4f6b799 Merge branch 'master' of https://github.com/reicast/reicast-emulator 2014-03-06 02:38:19 -05:00
Karen Tsai ccea066331 Fixed the About view. Again. 2014-03-06 02:38:06 -05:00
Lioncash 586c30b383 Remove a totally pointless null comparison in MainActivity.java.
Also kill off a case where null literally won't happen in FileBrowser.java.
2014-03-06 02:37:38 -05:00
Karen Tsai a7df171c0c Made the menu button actually functional, fixed one of the menu buttons which was somehow misplaced off to the right, Git information now appears in the Version UILabel, the About screen is now somewhat functional, cleaned up the Settings page, changed the Paths page so that we aren’t yelling at the poor user in all caps. 2014-03-06 02:30:54 -05:00
Lioncash 37eb9d26c8 Kill off some checking for Integer being null in GL2JNIActivity.java. These will never be null, since the functions return a primitive int. 2014-03-06 02:19:30 -05:00
Lioncash 6e3ab6d62c Fix tab/space mismatches in the Android project. 2014-03-06 02:09:57 -05:00
Lioncash 6c123ad04b Replace some Integer.valueOf calls with Integer.parseInt in ConfigureFragment.java. Boxing to an Integer isn't necessary here. 2014-03-06 01:58:05 -05:00
Karen Tsai 72c40fa61a Changed “Sound” to “Disable Sound” in the iOS UI for consistency with the Android UI. 2014-03-06 01:55:06 -05:00
Karen Tsai a147b1023d Added a bunch of placeholder-quality images to the iOS UI from the Android UI. I’ll fix them tomorrow. 2014-03-06 01:52:04 -05:00
Lioncash d19e258ba1 Externalize some strings from the Android MainActivity java file and put them in the XML.
Also changed the error title of the AlertDialog depending on whether the Flash ROM or BIOS are missing.
2014-03-06 01:41:42 -05:00
Karen Tsai 1c30ca0dbf Revised and updated the Japanese localisation. 2014-03-06 01:10:07 -05:00
Karen Tsai 20b9239602 Revised English localisation. 2014-03-06 01:08:51 -05:00
Karen Tsai c583c59073 Fixed the side drawer identifiers so now the buttons actually well, work. 2014-03-05 23:04:45 -05:00
Karen Tsai 0529078510 Added various images used by the frontend, added buttons. (The emulator view won’t be horizontal in the future). 2014-03-05 22:59:43 -05:00
Karen Tsai 48522a747f Changed iOS target to iOS 5.0, removed arm64 slice, modified README.md, added an initial iOS frontend, added empty subclasses, added debugging entitlements plist to fix lldb, recreated the entire xcodeproj (it was somewhat required), removed iPad storyboard, removed code-signing requirements, modified AppDelegate to fix view controller status bar tint colors for iOS 7 and 6. 2014-03-05 22:26:47 -05:00
Karen Tsai b7e9802e06 Added more filetypes to gitignore, mostly build artifacts that should never be checked into version control. 2014-03-05 19:32:42 -05:00
Karen Tsai ec08d462b5 Added iOS artifacts to .gitignore. 2014-03-05 19:29:34 -05:00
Stefanos Kornilios Mitsis Poiitidis ebe56d6778 Add mips support (woohoo makefiles are a mess nao) 2014-03-05 12:24:03 +02:00
Stefanos Kornilios Mitsis Poiitidis 7d32a66044 Fix win86 default 2014-03-05 12:22:26 +02:00
TwistedUmbrella f2961bd779 Merge pull request #385 from 0002647302/master
Invert the native activity preference until adjusted for x86
2014-03-05 04:56:13 -05:00
TwistedUmbrella 39a0417d5b Import Google Services, Clean up the debug tool for builds 2014-03-04 15:50:16 -05:00
TwistedUmbrella 256347d947 Submit a local test of the git-based build update downloads 2014-03-04 15:15:12 -05:00
TwistedUmbrella 3bb036741b Gather most of the basic preferences as referenced statics 2014-03-04 09:28:22 -05:00
TwistedUmbrella 8d8cf6da00 Incremental submission of the static pref reference transition 2014-03-04 09:01:09 -05:00
TwistedUmbrella 6a757bb43e Fix compiling the secondary library, Begin prefs integration 2014-03-04 08:48:41 -05:00
TwistedUmbrella 0567e8a117 Invert the native activity preference until adjusted for x86 2014-03-04 08:05:36 -05:00
TwistedUmbrella 31d6b7e3f1 Merge pull request #384 from reicast/native
Pulling more changes from the Native branch
2014-03-04 03:56:47 -05:00
TwistedUmbrella 0847b8b7e6 Restore the configuration loading to the original placement 2014-03-04 03:53:12 -05:00
TwistedUmbrella 0c012d4e8e Merge pull request #382 from reicast/native
Native
2014-03-04 03:43:17 -05:00
TwistedUmbrella 788e48bde3 Kinda defeats the purpose of visual differentiation with this
Can’t really tell a local build from a stock build if they both have
the same label. Be gone you!
2014-03-04 03:40:16 -05:00
TwistedUmbrella 3954d719f5 Streamline the build process to prevent possibility for errors 2014-03-04 03:32:12 -05:00
TwistedUmbrella ba9094747f Clean up the results of a blind copy-paste implementation 2014-03-03 20:30:34 -05:00
TwistedUmbrella a6407a52b4 Relocate the entire logging process to prevent any issues 2014-03-03 20:24:02 -05:00
TwistedUmbrella f3f172c64d Merge pull request #378 from reicast/native
Integrate an inline messaging system using Android GCM
2014-03-03 17:39:23 -05:00
TwistedUmbrella 97fb628797 This may help reduce the possibility for error in the Mogas 2014-03-03 17:38:17 -05:00
TwistedUmbrella 8a34119c5d Missed that secondary platform-dependent command call 2014-03-03 17:36:01 -05:00
TwistedUmbrella deba6cbcd1 Fix automated NDK build on windows, Add x86 to touchpad 2014-03-03 17:31:09 -05:00
TwistedUmbrella b14440970b Fix the server counterpart to be able to use JSON parsing 2014-03-03 16:40:29 -05:00
TwistedUmbrella 20291c57e8 Add the option to disable the debug message notifications 2014-03-03 15:08:37 -05:00
TwistedUmbrella 60df320f4c Add expanded message when clicking on an individual item 2014-03-03 11:58:29 -05:00
TwistedUmbrella ad4ecbab0e Integrate an inline messaging system using Android GCM 2014-03-03 11:40:49 -05:00
Stefanos Kornilios Mitsis Poiitidis 78ad0d6044 Merge branch 'master' of https://github.com/reicast/reicast-emulator 2014-03-03 14:18:13 +02:00
Stefanos Kornilios Mitsis Poiitidis ac2501549f Initial support for android-x86 (no idea if this actually works)
This is ugly, done via HOST_NO_REC, NOT_ARM. Only if I had merged the clean-makefiles work before rls... Oh well.
2014-03-03 14:06:00 +02:00
TwistedUmbrella 9d248886ba Merge pull request #376 from reicast/native
Fixes, Updates, Documentation, Etc
2014-03-03 02:53:47 -05:00
TwistedUmbrella 504bf1b299 Merge pull request #359 from ramersonw/patch-2
Added some missing strings
2014-03-03 02:53:28 -05:00
TwistedUmbrella d6369f9d04 Reverse the notation about commenting the NDK_VERSION 2014-03-02 23:54:16 -05:00
TwistedUmbrella 8047074982 Let them reboot if they ignore the warning. At least we tried 2014-03-02 23:44:31 -05:00
TwistedUmbrella ee88660820 Add the controller interface platform to the readme as well 2014-03-02 23:40:30 -05:00
TwistedUmbrella 843d667740 Clean up the Moga interface to begin diagnosing breakage 2014-03-02 23:36:52 -05:00
TwistedUmbrella 2f902ed5e2 Notify users of an unsupported kernel, Pending version ID 2014-03-02 23:26:50 -05:00
TwistedUmbrella 4c034740ea Reference strings over hardcoded text, More documentation 2014-03-02 22:49:31 -05:00
TwistedUmbrella a33eb1dc77 Notify about data folder being implied, Despite the summary 2014-03-02 05:42:23 -05:00
TwistedUmbrella d320b4a82e Merge pull request #361 from reicast/native
Native - This should start to resolve controller issues
2014-03-02 00:55:57 -05:00
TwistedUmbrella cf7ccb77d4 Integrate screenshot into the Native interface, Small cleanup 2014-03-01 23:47:01 -05:00
Bryan Barnes 65f967dc22 added menu option to take a screenshot 2014-03-01 23:46:52 -05:00
TwistedUmbrella 40c4570271 Add an override for the native interface to be user disabled 2014-03-01 21:14:30 -05:00
TwistedUmbrella 4b148a7055 Fix Jelly Bean black screen issues by falling back to default 2014-03-01 21:05:04 -05:00
TwistedUmbrella 34c9e6f6ea Integrate broadcast selection menu into the configuration 2014-03-01 21:02:51 -05:00
Stefanos Kornilios Mitsis Poiitidis 1698b21ac6 Fix windows building 2014-03-01 22:07:28 +02:00
TwistedUmbrella 5438e15bf4 Minimize the required modification for inverted audio prefs 2014-03-01 08:30:36 -05:00
TwistedUmbrella 2a150ef61c Refactor @ptitSeb PANDORA: Options and GUI - NoSound 2014-03-01 07:38:54 -05:00
ptitSeb 54e3a0e4e0 PANDORA: Options and GUI 2014-03-01 07:38:40 -05:00
TwistedUmbrella ca3de641e2 Add a shared uid package that enables and disables debug 2014-03-01 02:09:00 -05:00
ptitSeb 1c813524b4 PANDORA: No mic on Pandora for now 2014-02-28 23:46:08 +01:00
ptitSeb c806c30937 Merge branch 'master' into pandora 2014-02-28 22:47:42 +01:00
ptitSeb 4719756522 PANDORA: Options and GUI 2014-02-28 22:42:32 +01:00
ramersonw 93829978f2 Removed strings that don't need a translation 2014-02-28 12:01:22 -02:00
TwistedUmbrella 839ddd0c40 Refactor the Dpad Joystick toggle for purposely invalid input 2014-02-28 05:51:08 -05:00
TwistedUmbrella 1440b0ef6c Fall back to actual key values for key not being "emulated" 2014-02-28 01:17:50 -05:00
TwistedUmbrella 4903152e18 Prevent the loop of errors resulting in an ANR. Crash instead 2014-02-28 01:17:36 -05:00
TwistedUmbrella ba6cb99c2e Set the screen width and height using the scaled screen dpi 2014-02-28 01:16:11 -05:00
TwistedUmbrella 82de3d2249 Prevent the right stick from canceling out the normal triggers 2014-02-28 00:34:24 -05:00
TwistedUmbrella 386a28e79f The Moga interface doesn't really need to mirror the primary 2014-02-27 20:47:38 -05:00
TwistedUmbrella d45603c2e0 At this point, everyone should be pretty comfortable with it 2014-02-27 20:47:22 -05:00
TwistedUmbrella 4d3ccfe5bf Have non-translated strings prompt as errors to be removed 2014-02-27 20:46:09 -05:00
ramersonw 6701025187 Added some missing strings 2014-02-27 14:29:26 -02:00
TwistedUmbrella 35840a1eda Merge pull request #356 from ThePlayground/master
Create a new branch for working on NativeActivity
2014-02-26 22:55:21 -05:00
TwistedUmbrella 5eea059b09 Remove comments for resolved issues and added methods 2014-02-26 22:49:14 -05:00
TwistedUmbrella ebeb0d0551 Automate the inclusion of the secondary native library build 2014-02-26 22:44:20 -05:00
TwistedUmbrella a75307240d Begin merging in NativeActive and compatibility fallback - r7 2014-02-26 22:26:33 -05:00
TwistedUmbrella b95826d4d3 Merge pull request #353 from ThePlayground/master
All possible last minute changes and cleanup before release
2014-02-26 22:24:53 -05:00
TwistedUmbrella f670a39787 All possible last minute changes and cleanup before release 2014-02-26 22:24:34 -05:00
TwistedUmbrella 21a8a54f88 Merge pull request #351 from ThePlayground/master
This pull is any last minute changes and fixes
2014-02-26 22:03:00 -05:00
TwistedUmbrella bac4ee15ec Sort out double negatives, Add javadoc information
Sort out all the double negatives and get the menu running

Prevent frameskip from exceeding or going below bounds

Fix some inverted parameters, Enable javadoc variable lists
2014-02-26 21:19:06 -05:00
Claus Østergaard 4e92bfa5c1 Update strings.xml 2014-02-26 21:05:28 -05:00
Bryan Barnes 44cffbb4c4 faster popup animation, hide rate me menu item on ouya 2014-02-26 21:03:48 -05:00
TwistedUmbrella 8ce6a9e539 Cleanup and finalize the new "visibility optimized" menus
Add an option to open the menu with "Menu", Select compat

Don't prevent select mapping, Switch to local context, Anim

Import French Submission @AndroidGX

Fix a merge issue for settings not yet available to the user

faster popup animation, hide rate me menu item on ouya

Update strings.xml

Kill the application properly, Check for Rating, Popup anim

Add a small buffer to the VMU, Fix the configuration menu

This really was a good idea if I could quit inverting the logic

Sound config options are misleading due to inverted function

It is my own fault for wanting it to make sense in GL2JNIView at the cost of not making since anywhere else

Toggle sound independently, Implement Fastforward instead

Add generic boost menu option, Fix sound menu icon state

 Repurpose thread priority as boost option, Disable triggered

Account for when sound is fully disabled and cannot be set

It gets confusing when enabled is false and disabled is true
2014-02-26 20:58:23 -05:00
TwistedUmbrella 7ec35ef3c2 Merge pull request #330 from ThePlayground/master
makes r3 be start button, allows menu button to work
2014-02-25 02:03:58 -05:00
TwistedUmbrella ea329b064e makes r3 be start button, allows menu button to work 2014-02-25 02:03:17 -05:00
TwistedUmbrella da60601205 Merge pull request #328 from ThePlayground/master
Fix the mapping to avoid dealing with OUYA default configs
2014-02-25 01:58:45 -05:00
TwistedUmbrella 478f8586bb Make the menu look a little bit neater on entry / exit function 2014-02-25 01:58:20 -05:00
TwistedUmbrella ef2fe430ff Fix the mapping to avoid dealing with OUYA default configs 2014-02-24 23:57:18 -05:00
Bryan Barnes 8249d2dc28 toned the ouya fix down slightly 2014-02-24 23:51:58 -05:00
Bryan Barnes f1b384ac2e ouya again 2014-02-24 23:43:40 -05:00
TwistedUmbrella 3f4a97ecc1 Merge pull request #326 from ThePlayground/master
Revert "Let's let Moga start actually handling Moga events, Fix Rjoy"
2014-02-24 23:18:46 -05:00
TwistedUmbrella c013264a28 Tone down how much Moga handles on its own quite yet :/ 2014-02-24 23:18:27 -05:00
TwistedUmbrella 631c5bae5b Merge pull request #323 from ThePlayground/master
Let's let Moga start actually handling Moga events, Fix Rjoy
2014-02-24 23:07:34 -05:00
TwistedUmbrella 9927a8dae0 Fix a linked casting issue that requires Activity over Context 2014-02-24 23:01:24 -05:00
TwistedUmbrella 7158b640c9 Let the submission fail to avoid introducing possible issues 2014-02-24 22:45:40 -05:00
TwistedUmbrella fa2b229c95 Let's let Moga start actually handling Moga events, Fix Rjoy 2014-02-24 22:23:04 -05:00
TwistedUmbrella 326fcec485 Merge pull request #317 from ThePlayground/master
Right stick mapping options, Logging fixes, Menu notices
2014-02-24 20:54:42 -05:00
TwistedUmbrella 06c3ded68e Fix all the merge derps generated by https://github.com/reicast/reicast-emulator/pull/320 2014-02-24 20:48:50 -05:00
TwistedUmbrella 0b7a2cfd86 Handle emulated keycodes through standard handler's calls 2014-02-24 20:40:11 -05:00
TwistedUmbrella 0a95f966d5 Another instance of controller simplification, Not-static class 2014-02-24 20:40:11 -05:00
TwistedUmbrella 6d82495ed5 This will at least solve the Spanish issue until it is complete 2014-02-24 20:40:06 -05:00
TwistedUmbrella 5f9c75a414 Remove a check when motion is motion, recognized or not 2014-02-24 20:40:02 -05:00
TwistedUmbrella b1bcef83ea Support deprecated platforms, Bring Moga into Gamepads 2014-02-24 20:40:02 -05:00
TwistedUmbrella 3d7b8570b6 Support "Select" as menu, Mapping, "Menu" hardware key 2014-02-24 20:39:55 -05:00
TwistedUmbrella 88eea7f0e9 Fix an issue with importing unmerged changes from pull 2014-02-24 20:39:42 -05:00
TwistedUmbrella f536c67f26 Force the keys to be mapped, even if the system already is 2014-02-24 20:39:42 -05:00
TwistedUmbrella d53fb51d25 Update the label to prevent attempting to continue mapping 2014-02-24 20:39:42 -05:00
TwistedUmbrella a2b8aba035 Add a notice about the OUYA R3 being the onscreen menu 2014-02-24 20:39:42 -05:00
TwistedUmbrella 985297183a Remove the handler for the logging function as is unneeded 2014-02-24 20:39:35 -05:00
TwistedUmbrella 11cc6e6ccf Attempt to preserve EGL context when an activity is paused 2014-02-24 20:39:35 -05:00
TwistedUmbrella 5c0601dd2e Add support to use the right joystick as A / B, L1 / R2 trigger 2014-02-24 20:39:35 -05:00
hooby3dfx 339ed77516 Merge pull request #320 from hooby3dfx/master
merging this in to get the ouya stuff all together and i wanted to fix the strings build break.
also that toast is silly.
sorry that this will give you a conflict for automerge but youre a big boy :)
2014-02-24 20:19:56 -05:00
Bryan Barnes 02193e2441 ouya fixes, no more menu toast, got rid of spanish in polish 2014-02-24 20:13:28 -05:00
hooby3dfx 04617a9b0c Merge pull request #321 from Elwood89/patch-1
Update strings.xml (polish translation)
2014-02-24 20:09:42 -05:00
hooby3dfx 095841ff5b Merge pull request #322 from coestergaard/master
Danish translation added
2014-02-24 20:08:52 -05:00
Claus Østergaard a9dc01de57 Update strings.xml
Should probably not have been translated.
2014-02-25 00:10:00 +01:00
Claus Østergaard 51e5db0d50 Update strings.xml 2014-02-25 00:03:47 +01:00
Claus Østergaard 5e53dba12c Create danish translation 2014-02-24 23:12:41 +01:00
Elwood89 47d8e667e7 Update strings.xml
There are many special letters in PL, are these supported?
2014-02-24 16:08:47 +01:00
TwistedUmbrella c9a10451b7 Throw in some labels as an added bonus just in case 2014-02-22 18:40:23 -05:00
TwistedUmbrella eaac86808f LOGS HERE! GET YOUR LOGS HERE, PEOPLE! 2014-02-22 18:34:00 -05:00
hooby3dfx eddea4395c Merge pull request #315 from hooby3dfx/master
fixed editvjoy crash
2014-02-22 18:19:52 -05:00
Bryan Barnes 0a45f17839 fixed editvjoy crash 2014-02-22 18:19:17 -05:00
hooby3dfx cdb5d004d1 Merge pull request #308 from hooby3dfx/master
moved push of emu cfg settings to one location, fixed vmu lcd crashes, fixed first key not registered/drop to bios from game launch when no buttons are pressed.
2014-02-22 18:02:16 -05:00
Bryan Barnes 948118b8de initialize conroller codes so they work on first push and first game boot doesnt drop to bios! 2014-02-22 12:21:29 -05:00
Bryan Barnes 31bd0f5742 fixed the bios crash plague, it was a jni issue with the vmu lcd. the way we cache jnienv is messy/lucky. 2014-02-22 11:30:03 -05:00
Bryan Barnes 7ecf7d5727 moved push cgf to before init (was screwing up dynarec option), also changed depth back to 24 bit 2014-02-21 23:31:40 -05:00
Bryan Barnes be3ce5492d moved push of emu cfg settings to where it normally is in the init process; fixes rtc. minor cfg load/save cleanup. 2014-02-21 23:31:39 -05:00
TwistedUmbrella 85367467d6 Allow Ant to use the existing NDK path variable inline
“ndk.dir” has to be manually set in the local.properties file
“android update project” only covers auto-import of the sdk
2014-02-21 23:22:27 -05:00
TwistedUmbrella faa14cdfec Let's build everything with a single magical command 2014-02-21 23:12:23 -05:00
TwistedUmbrella a39eff8bd0 Prevent a possible break in controller layouts 2014-02-21 22:31:00 -05:00
TwistedUmbrella 93f2ea362d Remove unused functions, Use Xperia Play gamepad menu 2014-02-21 19:28:32 -05:00
TwistedUmbrella f68fbef987 Simplify and subclass the controller mapping 2014-02-21 19:24:55 -05:00
TwistedUmbrella 052fd88b32 Fix custom mapping for L and R triggers 2014-02-21 19:19:49 -05:00
TwistedUmbrella b82b965a96 Fix epoch calculation, verified by @ppsspp213 2014-02-20 16:40:58 -05:00
TwistedUmbrella 8655cae995 Removing the beta link to allow relocation [Part 2] 2014-02-19 01:48:46 -05:00
TwistedUmbrella da4b94f787 Removing the beta link to allow relocation [Part 1] 2014-02-19 01:48:11 -05:00
TwistedUmbrella 7ac2698f70 Merge pull request #306 from NoblesseOblige/master
Let the system display all stack trace indexes and sort itself
2014-02-18 18:48:24 -05:00
TwistedUmbrella 7f1f97c68f Let the system display all stack trace indexes and sort itself 2014-02-18 18:47:42 -05:00
TwistedUmbrella 0db807a17a Merge pull request #305 from Karaulov/patch-3
Update ru strings.xml #4
2014-02-18 16:55:44 -05:00
Karaulov 93bbffadb6 Update strings.xml 2014-02-19 00:03:41 +03:00
TwistedUmbrella 44b8937a4f Merge pull request #304 from NoblesseOblige/master
More logging stuff to ensure we get logs
2014-02-18 13:52:50 -05:00
TwistedUmbrella e5b9a879f5 Begin the process of documenting using the Eclipse dialogs 2014-02-18 13:51:47 -05:00
TwistedUmbrella ba6b83e824 Implement a hander to display toast messages on UI thread 2014-02-17 21:03:32 -05:00
TwistedUmbrella b92d826284 Check internet and notify user of log location if unavailable 2014-02-17 18:11:31 -05:00
TwistedUmbrella 818f58d07b Merge pull request #302 from winder/master
Fixed start button mapping for PS3 controller.
2014-02-17 15:19:18 -05:00
TwistedUmbrella 8b8e36edf9 Merge pull request #297 from NoblesseOblige/master
Stock-piling changes until they need to be merged
2014-02-17 15:18:57 -05:00
Will Winder 64108864a7 Fixed start button mapping for PS3 controller. 2014-02-17 15:12:11 -05:00
TwistedUmbrella f599fcf2f4 Xperia Play - Simplify button check but don't convert for GB
In Gingerbread, the difference between back and O was whether or not
the Alt key was pressed at the same time in code. Until GB is supported
for the Xperia Play, there is no real purpose in adding the custom key
quite yet.
2014-02-17 12:23:16 -05:00
TwistedUmbrella be1c4374fa Verify the FPS display reads as null to prevent misfired view 2014-02-17 12:12:40 -05:00
TwistedUmbrella ccd4157aff Add basic parameters from the emulator to the edit screen 2014-02-17 12:12:40 -05:00
TwistedUmbrella 65c1b947a4 Add render depth to available options to provide fps boost 2014-02-17 12:12:40 -05:00
TwistedUmbrella da7c82c02d Temporarily map start button for PS3 and Xbox360 [Testing] 2014-02-17 12:12:09 -05:00
TwistedUmbrella 88f0b8b6c2 Add low-level OUYA detection, Handle menu with R3 button 2014-02-17 12:12:09 -05:00
TwistedUmbrella aa9f842110 Add a text outline to allow visibility when view matches text 2014-02-17 12:12:09 -05:00
hooby3dfx 0f96a5a47b Merge pull request #295 from hooby3dfx/master
Fix galaxy tab crash on back button, keep transparent popup background.
2014-02-17 12:06:57 -05:00
Bryan Barnes c45eb4e8d0 fraps style fps 2014-02-16 16:43:29 -05:00
Bryan Barnes a3d1a2a16e fix for galaxy tab back button crash 2014-02-16 15:01:16 -05:00
Bryan Barnes f8e23a2b1c fixed gb crash, print out full stack trace, explicitly transparent backgrounds in popups 2014-02-16 15:01:16 -05:00
TwistedUmbrella ec13746af7 Merge pull request #294 from LoungeKatt/master
If this doesn't fix game loading, the bug was already there
2014-02-16 14:04:32 -05:00
TwistedUmbrella f5586ba47f This will allow error reporting before attempting to load GUI 2014-02-16 14:03:23 -05:00
TwistedUmbrella 17b1d51f4b Merge pull request #287 from LoungeKatt/master
@hooby3dfx This should get what you are looking for
2014-02-16 12:33:02 -05:00
TwistedUmbrella 7321808090 Because the Droid X can't live up to the Xperia Play for ctx 2014-02-16 12:07:54 -05:00
TwistedUmbrella e7a0e78803 Updated for JVM 1.6 as per discussion on StackOverflow
http://stackoverflow.com/questions/115008/how-can-we-print-line-numbers-
to-the-log-in-java
2014-02-16 11:52:21 -05:00
TwistedUmbrella 39ad0ac92d Yeah, the GPU has nothing to do with sound. Nice try, tho! 2014-02-16 01:48:55 -05:00
TwistedUmbrella ffdf036684 Update the logs to include the trace line number [hopefully] 2014-02-16 01:47:06 -05:00
TwistedUmbrella 540fd32089 Merge pull request #285 from LoungeKatt/master
Clean up the layouts and separate paths sections cleanly
2014-02-15 22:30:22 -05:00
TwistedUmbrella 10a8a15cd3 Clean up the layouts and separate paths sections cleanly
See ya when r6 hits Google Play ;)
2014-02-15 22:29:24 -05:00
TwistedUmbrella 1ded3dffdd Merge pull request #284 from LoungeKatt/master
Eclipse pretends it is fixing an unclosed layout with excess
2014-02-15 21:31:44 -05:00
TwistedUmbrella b5004bc5b5 Eclipse pretends it is fixing an unclosed layout with excess 2014-02-15 21:31:31 -05:00
TwistedUmbrella 3bdb4fafe9 Merge pull request #282 from LoungeKatt/master
Error reporting and handling updates
2014-02-15 16:16:04 -05:00
TwistedUmbrella 14b4ed6bdf Remove deprecated call to load unused configuration files 2014-02-15 16:07:26 -05:00
TwistedUmbrella e700972350 Fix a sneaky layout trying to avoid being part of the tables 2014-02-15 16:05:54 -05:00
TwistedUmbrella 6bc6328a25 I could have sworn there was a negative AND a positive... 2014-02-15 16:05:54 -05:00
TwistedUmbrella b546e7a75d Handle crashes more gracefully and allow opting out report 2014-02-15 16:05:54 -05:00
TwistedUmbrella 16702f9c38 Fix the formatting on the configuration page to reduce size 2014-02-15 16:05:54 -05:00
TwistedUmbrella d3d6c100dc Merge pull request #283 from hooby3dfx/master
idleskip should default to true
2014-02-15 16:03:46 -05:00
Bryan Barnes 90db7054a4 idleskip should default to true 2014-02-15 15:22:27 -05:00
TwistedUmbrella 65db3bedf2 Merge pull request #278 from LoungeKatt/master
Integrate a semi-accurate FPS display option into settings
2014-02-15 12:47:42 -05:00
TwistedUmbrella 5a741af03d Enable unstable optimization by default to prevent crackling 2014-02-15 11:46:47 -05:00
TwistedUmbrella e308c0b5c7 Update all language translations with new revision text item 2014-02-15 10:53:13 -05:00
TwistedUmbrella b31297e452 Update the about display to handle beta versions correctly 2014-02-15 10:46:50 -05:00
TwistedUmbrella c318eb8bda Update the region values to specify the game region codes
@ppsspp213 change adjusted to work with the way the application
displays and uses the array values.
2014-02-15 10:46:20 -05:00
TwistedUmbrella 8469baa39e Clean up the FPS view to support variable text size change 2014-02-14 21:30:04 -05:00
TwistedUmbrella 3ab88a71ab Updated Chinese - https://github.com/reicast/reicast-emulator/issues/275 2014-02-14 21:04:47 -05:00
TwistedUmbrella 8a48d95370 Integrate a semi-accurate FPS display option into settings 2014-02-14 20:54:04 -05:00
TwistedUmbrella 30f06e699c Merge pull request #276 from Karaulov/patch-2
Update RU strings.xml #3
2014-02-14 12:13:32 -05:00
Karaulov 875bd15750 Update RU strings.xml #3 2014-02-14 15:44:06 +03:00
TwistedUmbrella fad989a19a Merge pull request #274 from ppsspp213/patch-1
Update strings.xml
2014-02-14 01:54:42 -05:00
ppsspp213 98eec3e49f Update strings.xml
Typo's
2014-02-14 06:39:39 +00:00
TwistedUmbrella 10b9df33ea Merge pull request #272 from LoungeKatt/master
A very solid collaborative menu implementation
2014-02-14 01:13:04 -05:00
TwistedUmbrella 3595152cc4 Center the VMU display, Subclass the "other" popup menus 2014-02-14 01:11:38 -05:00
Bryan Barnes 208aa20c18 vmu lcd toggle working 2014-02-14 01:11:30 -05:00
TwistedUmbrella ecc122f0c4 This is as close as it'll get to toggling from the menu for now 2014-02-13 21:40:08 -05:00
TwistedUmbrella 6b5c041725 Add the option to "pop out" the VMU, Check popUp for null 2014-02-13 20:30:55 -05:00
TwistedUmbrella da9faf7efb Enable free-floating VMU to allow for bigger size parameters 2014-02-13 15:57:35 -05:00
TwistedUmbrella bf5f59833a Add a category for peripherals to support growing numbers 2014-02-13 05:56:03 -05:00
TwistedUmbrella 734f03bfcd Tag all the garbage collection with the relevant API direction 2014-02-13 05:55:52 -05:00
TwistedUmbrella df50719777 Add an option to enable ongoing VMU display, First in menu 2014-02-13 05:54:19 -05:00
TwistedUmbrella b98b087435 Merge pull request #270 from hooby3dfx/vmu_support
on screen vmu :)
2014-02-13 05:52:15 -05:00
TwistedUmbrella ee254ea23d Merge pull request #271 from NoblesseOblige/master
Handle the core popUp directly, but pass others to handler
2014-02-13 03:19:35 -05:00
TwistedUmbrella fd69686f78 Handle the core popUp directly, but pass others to handler 2014-02-13 03:19:10 -05:00
TwistedUmbrella b8335773d3 Merge pull request #269 from NoblesseOblige/master
@hooby3dfx has issues, but @LoungeKatt has pull requests. I win!
2014-02-13 02:42:58 -05:00
TwistedUmbrella c3a7260dc1 Moving the dismissal call to prevent an inevitable merge fail 2014-02-13 02:42:41 -05:00
Bryan Barnes 52199df953 vmu :)
Conflicts:
	shell/android/jni/src/Android.cpp
	shell/android/src/com/reicast/emulator/emu/GL2JNIActivity.java
	shell/android/src/com/reicast/emulator/emu/JNIdc.java
2014-02-13 02:17:13 -05:00
TwistedUmbrella 60d3521d47 Rename the file to avoid confusion with proprietary app files 2014-02-13 01:21:35 -05:00
TwistedUmbrella 9281d2f2ad Append the memory allocation table to error log submission 2014-02-13 00:52:13 -05:00
TwistedUmbrella 4d322feacc In case of a memory allocation failure, print current readout 2014-02-13 00:45:17 -05:00
TwistedUmbrella d9233b3440 Account for devices with small screens and stock DPI sets 2014-02-12 22:13:00 -05:00
TwistedUmbrella 89ab2420c9 Fix an issue with popup definition coming after vector calls 2014-02-12 20:08:24 -05:00
TwistedUmbrella 5485f2f16e Handle irrational decision to run screaming from file listing 2014-02-12 19:42:56 -05:00
TwistedUmbrella 188d7cbe4f Handle the popup navigation through buttons for the lazy 2014-02-12 19:34:37 -05:00
TwistedUmbrella 3f62290596 Merge pull request #268 from NoblesseOblige/master
More optimizations and stability stuff (Yah!!)
2014-02-12 18:19:52 -05:00
TwistedUmbrella bf6fd5fd09 Don't know about you, but I keep accidentally closing emu
This also removes the debug preference, since this menu is no longer
visible until pressed. If someone presses it by accident, they would
have probably enabled it by accident as well. Nothing dangerous is in
there anyway.
2014-02-12 17:56:54 -05:00
TwistedUmbrella dd78ed1c88 Stop redrawing the popup, Change enable state dynamically 2014-02-12 17:42:58 -05:00
TwistedUmbrella a28c50a13d Only use reflection method when API is unavailable for call 2014-02-12 17:21:25 -05:00
TwistedUmbrella 4782c144f0 Add the thread priority to prevent unused sound thread use 2014-02-12 16:40:40 -05:00
TwistedUmbrella e4c0e8ec61 Merge pull request #267 from NoblesseOblige/master
Massive cleanup and organization of processes by function
2014-02-12 16:18:12 -05:00
TwistedUmbrella 4368f327ae Add permanent sound option, Split debug into menu, Clean 2014-02-12 16:17:45 -05:00
TwistedUmbrella 24c4c04945 Allow menu interaction before immersive overlay recedes 2014-02-12 02:32:49 -05:00
TwistedUmbrella 1e798727d3 Reduce the number of packages, Input is really emu stuff 2014-02-11 23:41:56 -05:00
TwistedUmbrella eb1772ec2c Realign the native interface with the Java app counterpart 2014-02-11 23:38:46 -05:00
TwistedUmbrella 87e409b3cc Massive cleanup and organization of processes by function 2014-02-11 23:25:46 -05:00
TwistedUmbrella 853db5110e Merge pull request #266 from NoblesseOblige/master
If you can't combine the activity, share the static functions
2014-02-11 22:58:24 -05:00
TwistedUmbrella ec57499863 Account for the default value of unset boolean being false 2014-02-11 22:55:55 -05:00
TwistedUmbrella 1e6c050d3d Finish subclassing VJoy, EGL, OSD, Add runtime muting 2014-02-11 22:30:51 -05:00
TwistedUmbrella 858bd2c40b If you can't combine the activity, share the static functions 2014-02-11 21:22:25 -05:00
TwistedUmbrella f59da370b5 Merge pull request #260 from hooby3dfx/master
push the input data from java to c on each event
2014-02-11 21:22:16 -05:00
TwistedUmbrella d68e72b37b Merge pull request #261 from NoblesseOblige/master
Added support for immersive mode on KitKat devices [Rehash]
2014-02-11 10:24:47 -05:00
TwistedUmbrella 147e948b37 Move the non-dynamic popup back to the hosting activity 2014-02-11 10:23:09 -05:00
TwistedUmbrella e668e8068c Begin setting up generic iPhone shell configuration for emu 2014-02-10 21:14:06 -05:00
Matteo Hausner 20fb9db652 Added support for immersive mode on KitKat devices [Rehash] 2014-02-10 21:11:03 -05:00
TwistedUmbrella 9af23e0276 Merge pull request #257 from NoblesseOblige/master
Add reicast to the Sony Xperia Play games launcher menu
2014-02-10 13:25:26 -05:00
TwistedUmbrella 4c6bc0349f Add reicast to the Sony Xperia Play games launcher menu 2014-02-10 13:25:00 -05:00
TwistedUmbrella 37d9060b17 Merge pull request #249 from NoblesseOblige/master
Cleaning up and enhancing the runtime configuration menu
2014-02-10 07:34:04 -05:00
Bryan Barnes e46993f96c push the input data from java to c on each event 2014-02-09 22:44:53 -05:00
TwistedUmbrella 7f095cdb2d Render configuration file obsolete to prevent load corruption 2014-02-09 22:16:09 -05:00
TwistedUmbrella 5511bee9ef Sometimes you have to break some eggs to find a chicken 2014-02-09 21:33:31 -05:00
TwistedUmbrella af3e064269 Convert Android config to GUI, stop wasting CPU on files 2014-02-09 21:30:42 -05:00
TwistedUmbrella 8332d171da The string comparison does not process correctly, Use int 2014-02-09 21:29:12 -05:00
TwistedUmbrella 0ee5b52b52 Make static references to static variables to avoid local sets 2014-02-09 16:14:19 -05:00
TwistedUmbrella cb522d8352 Back up configuration when writing to prevent failure loss
The configuration is not always being properly written to the file.
This method will ensure the original user configuration (especially
when manually modified) is not lost in the process.
2014-02-09 15:51:46 -05:00
TwistedUmbrella ae6d694c52 Fix and simplify the new subclassing of the popup menus 2014-02-09 15:01:26 -05:00
TwistedUmbrella e70b71828c Subclass all popup menus to reduce clutter in GL2JNIView 2014-02-09 14:38:49 -05:00
TwistedUmbrella 7cd08c13ed Add runtime configuration for toggling the LimitPFS option
There ya go @hooby3dfx. I hope it’s everything you dreamed it would be
;)
2014-02-09 11:26:04 -05:00
TwistedUmbrella 94879b0cac Repurpose fast forward as actual frame skipping options 2014-02-09 11:09:42 -05:00
TwistedUmbrella 7a1323699a Merge pull request #245 from NoblesseOblige/master
Runtime config, Key code cleanup, Software rendering
2014-02-09 08:54:28 -05:00
TwistedUmbrella 81466f1591 Support Xperia Play hardware L1 / R1 through custom keys 2014-02-09 01:24:18 -05:00
TwistedUmbrella 153af36869 Make sure them menu button gets passed to OSD menus 2014-02-09 01:16:53 -05:00
TwistedUmbrella 66d0312f37 Add a configuration option to enable forced software render 2014-02-09 01:11:59 -05:00
TwistedUmbrella b728b0dfb5 Add a back option to the configuration, Close closes menu 2014-02-08 21:59:42 -05:00
TwistedUmbrella 631b4aaeea Add separate configuration popup to reduce origin clutter 2014-02-08 21:43:49 -05:00
TwistedUmbrella 83b94874a3 Add widescreen emu toggle, Get current config on app load 2014-02-08 21:43:41 -05:00
TwistedUmbrella 5ca3b4e3dc Theoretically this will add live control over frame skipping 2014-02-08 21:43:32 -05:00
TwistedUmbrella 8db0f80602 Assign native number values to Android key code variables 2014-02-08 21:43:24 -05:00
TwistedUmbrella 55d5e31a55 Merge pull request #242 from NoblesseOblige/master
@hooby3dfx Fixed cfg, localized time -|- Simplify logs, Xperia Play fixed
2014-02-08 09:55:18 -05:00
TwistedUmbrella 77bcb8de7f Fix immersive mode to automatically handle focus changes 2014-02-08 09:41:20 -05:00
TwistedUmbrella ed633dc37b Prevent keyboard / keypad opening from resetting activities 2014-02-08 08:25:52 -05:00
Bryan Barnes 61c0c39300 fix build break 2014-02-08 07:50:40 -05:00
TwistedUmbrella ddfa2ebbe3 Override the back button on Xperia Play to prevent exiting 2014-02-08 07:46:42 -05:00
TwistedUmbrella ba8d7dbde6 Xperia play does not differentiate the back key from triangle
http://developer.sonymobile.com/2011/02/13/xperia-play-game-keys/
2014-02-08 07:46:29 -05:00
TwistedUmbrella a3ea5bfe31 @hooby3dfx Localized dreamtime utility to get RTC string 2014-02-08 02:27:45 -05:00
TwistedUmbrella 6564f70cbc Boolean valueOf expects "true" or "false", so compare string 2014-02-08 02:27:45 -05:00
TwistedUmbrella f69ced47e4 Update the log generation to prevent redundant lib entries 2014-02-08 02:27:45 -05:00
hooby3dfx 747652677f Merge pull request #241 from NoblesseOblige/icons
Icons
2014-02-08 01:55:16 -05:00
hooby3dfx 5e10391508 Merge pull request #236 from hooby3dfx/master
Icons and less confusing popup menu
2014-02-07 23:23:01 -05:00
TwistedUmbrella dc606a83a1 Merge pull request #235 from NoblesseOblige/master
Shorten the procedure to edit config, Handle config issues
2014-02-07 13:36:53 -05:00
TwistedUmbrella 42019289c2 Further automating the log submission process for testers 2014-02-07 13:29:21 -05:00
TwistedUmbrella efd7183985 Assign icons, Remove unused option, Clear up description 2014-02-07 01:12:23 -05:00
TwistedUmbrella 0915a12d72 Higher res icons, Add default PSD for future icon additions 2014-02-07 01:12:14 -05:00
Bryan Barnes b5684e9498 hide crazy popup icons by default
can be enabled in settings
2014-02-07 00:34:04 -05:00
Bryan Barnes 564bb6837f vmu swap icon
AMERICA
2014-02-07 00:12:58 -05:00
Bryan Barnes 96c9a03374 mic icon
so sick
2014-02-06 23:20:01 -05:00
TwistedUmbrella 436fd57609 Shorten the procedure to edit config, Handle config issues 2014-02-06 20:52:08 -05:00
TwistedUmbrella 04addad42d Merge pull request #230 from Karaulov/patch-1
Update RU translate, strings.xml
2014-02-06 12:59:40 -05:00
TwistedUmbrella 19dc9e2247 Merge pull request #232 from hooby3dfx/vmu_swap
VMU swap
2014-02-06 12:54:21 -05:00
Bryan Barnes 76852783a7 its verking!
tested in bios only
2014-02-06 00:02:53 -05:00
TwistedUmbrella bf4e05391c Merge pull request #227 from NoblesseOblige/master
Cleanup and optimizations stuff
2014-02-05 18:31:32 -05:00
TwistedUmbrella 92f6ad350f Test Dreamcast time conversion using AICA RTC definition 2014-02-05 13:57:22 -05:00
TwistedUmbrella 98bc58215d Update the selector colors with the new "reicast" theming 2014-02-05 13:40:53 -05:00
TwistedUmbrella 8bf4e150d3 Update the logging function to account for Jelly Bean MR2 2014-02-05 12:28:00 -05:00
TwistedUmbrella de21b3d45c Fix BIOS clock prompting for setting on every startup 2014-02-05 12:27:55 -05:00
TwistedUmbrella 5536f580e4 Move the non-configuration settings to experimental header 2014-02-05 12:27:55 -05:00
Karaulov 7e43deb868 Update strings.xml 2014-02-05 13:53:41 +03:00
Karaulov 50844c5e4c Update RU translate, strings.xml
Request an update Russian translation, made ​​by myself manually.
2014-02-05 10:22:25 +03:00
Bryan Barnes 96ffc3a524 mic notes, wip vmu swap 2014-02-05 01:00:09 -05:00
hooby3dfx 4b32807c28 Merge pull request #229 from hooby3dfx/master
tweak to make dpad work again
2014-02-04 21:55:55 -08:00
Bryan Barnes 2e294c4642 tweak to make dpad work again 2014-02-05 00:54:56 -05:00
TwistedUmbrella d214a50905 Merge pull request #225 from NoblesseOblige/master
Set title when going backwards, Attempt focusable menus
2014-02-03 22:13:31 -08:00
TwistedUmbrella 2520685509 Support both methods of EGL context depending on prefs 2014-02-04 01:02:58 -05:00
TwistedUmbrella 862aab542f Add a failsafe to verify that GLES 3 exists before testing it 2014-02-04 00:01:23 -05:00
TwistedUmbrella 46577c0957 Custom selectors for menu, Redirect issue logging to paste 2014-02-03 23:45:15 -05:00
TwistedUmbrella 67616a60ce Set title when going backwards, Attempt focusable menus 2014-02-03 22:56:38 -05:00
Stefanos Kornilios Mitsis Poiitidis 310906d1b5 Merge pull request #222 from NoblesseOblige/master
The next batch of minor changes that make up a single pull
2014-02-03 13:44:29 -08:00
TwistedUmbrella 46a4312d73 @AndroidGX French translation updates 2014-02-03 16:39:35 -05:00
TwistedUmbrella d85de18b31 Add the form URL for translation submission to README 2014-02-03 15:32:59 -05:00
TwistedUmbrella 5ceb1cab7b Merge pull request #221 from NoblesseOblige/master
Add a handler to grab uncaught exceptions for issue report
2014-02-03 12:01:25 -08:00
TwistedUmbrella 5f8f4f9e3b Add a handler to grab uncaught exceptions to submit later 2014-02-03 14:55:30 -05:00
TwistedUmbrella 362c652d6c Merge pull request #219 from NoblesseOblige/master
Fix menu titles, Expand menu touch area, Add async logs
2014-02-03 10:13:37 -08:00
TwistedUmbrella 7944355f10 Traditional Chinese @weihan1102, Updated menu text size 2014-02-03 13:06:44 -05:00
TwistedUmbrella e315c8c2ee Update translations for new menu options [Need verification] 2014-02-03 13:05:34 -05:00
TwistedUmbrella a3c1734d94 Fix menu titles, Expand menu touch area, Add async logs 2014-02-03 12:22:27 -05:00
TwistedUmbrella 7211873442 Merge pull request #215 from NoblesseOblige/master
Menus, layouts, and languages. It's a regular party.
2014-02-02 23:41:57 -08:00
TwistedUmbrella e6fb44fba4 Update RTC value with Android UTC time every BIOS run 2014-02-03 02:41:09 -05:00
TwistedUmbrella 896c5d79c7 Update menu background to prevent undesired stretching 2014-02-03 02:09:29 -05:00
TwistedUmbrella e04e39fa90 Add Traditional, @weihan1102 Simplified Chinese update 2014-02-03 01:12:24 -05:00
TwistedUmbrella c9c71028a9 Update the modified drawer menu with a pretty background 2014-02-03 00:39:16 -05:00
TwistedUmbrella 15c6e731b5 Convert to unified menu layout, Add @hooby3dfx focusable
Applied the focusable to the switches, which worked.
Applied the focusable to the list items, which seems to not have
worked. Also added the state drawable, but so far it has not allowed
scrolling the list on Nvidia Shield.
2014-02-03 00:03:57 -05:00
Stefanos Kornilios Mitsis Poiitidis 1d9ec43b22 Merge pull request #109 from hooby3dfx/microphone_support
Microphone support. YARLY.
2014-02-02 19:00:37 -08:00
Bryan Barnes f571b187b0 Addressed review points
-cleanup vmu that gets replaced by the mic
-got rid of confusing old commented code
-stopped big memory leak if mic data was not getting read but it was
recording
2014-02-02 21:40:18 -05:00
TwistedUmbrella 5022ae4bd6 Merge pull request #213 from NoblesseOblige/master
@hooby3dfx Now you can scroll like the rest of us, hooray!
2014-02-02 17:26:42 -08:00
TwistedUmbrella 60de1f6c25 @hooby3dfx Now you can scroll like the rest of us, hooray! 2014-02-02 20:26:11 -05:00
TwistedUmbrella 2716bdcee8 Merge pull request #212 from ramersonw/patch-1
Fixed some typos and added more strings
2014-02-02 16:11:57 -08:00
ramersonw 250443b172 Fixed some typos and added more strings 2014-02-02 21:31:09 -02:00
TwistedUmbrella ca49ddb369 Merge pull request #211 from NoblesseOblige/master
A few reflection calls reference API 19, so we need Kitkat
2014-02-02 13:57:16 -08:00
TwistedUmbrella 4a89d5a75b A few reflection calls reference API 19, so we need Kitkat 2014-02-02 16:54:59 -05:00
TwistedUmbrella 754106a6f7 Merge pull request #210 from NoblesseOblige/master
Add note to the README about SDK platform requirement
2014-02-02 13:51:29 -08:00
TwistedUmbrella 6dd721e97f Add note to the README about SDK platform requirement 2014-02-02 16:50:57 -05:00
TwistedUmbrella a0ff5d68fd Merge pull request #208 from NoblesseOblige/master
Microphone (Squashed by major revision)
2014-02-02 13:01:48 -08:00
TwistedUmbrella 35ad9bfdee Fix compatibility with older Android versions with least effort 2014-02-02 16:01:16 -05:00
TwistedUmbrella 20422ef8c4 Remove a merge conflict generated on Github 2014-02-02 13:51:53 -05:00
TwistedUmbrella 75c2ae1e55 Merge pull request #206 from NoblesseOblige/master
Import mod of Jeremy Feinstein's SlidingMenu, EGL Mods
2014-02-02 10:50:15 -08:00
TwistedUmbrella 4c0491552f Clean up some misfired error logs, Always check KHR ES3 2014-02-02 12:46:46 -05:00
Bryan Barnes 6df7f8912c Prevent non-mic devices from doing this 2014-02-02 12:10:40 -05:00
TwistedUmbrella 4045b9a15f Remove untranslated strings, Add generic Korean resource 2014-02-02 01:03:38 -05:00
Bryan Barnes 3e33efa3ca learning the hard way
root cause found (i think). lesson: java functions called via jni dont
handle exceptions/tell you what happens when they crash.
2014-02-01 22:36:47 -05:00
TwistedUmbrella 5bc849f3f0 Add the Open GL ES View errors to the debug log output 2014-02-01 18:00:27 -05:00
TwistedUmbrella 8a9a5af00d Import mod of Jeremy Feinstein's SlidingMenu, EGL Mods
Clean up the menu or at least reduce the number of shells

Build native library against the same API base as shell app

Update Khronos source to newest stable, Reference EGL14

Add margins, Restore lost identifiers, Update tested devices

Adjust drawer menu handle to prevent unintentional launch

Revise EGL handling to check multiple contexts to configure

Update README to include information about translating

Add native library handling to the debug, Enable log reading

Adjust drawer menu touch area, Fix L / R assignment calls

Remove some merge junk from trying to resolve git issues
2014-02-01 18:00:14 -05:00
Bryan Barnes 2403d13440 umm
ok its one of those things where the logging makes it work!
not sure whats up, but without the additional logging it crashes.
2014-02-01 14:05:09 -05:00
Bryan Barnes 208bcc0d79 its verking!
figured out issue, made mic setup simpler
2014-02-01 13:52:36 -05:00
Bryan Barnes f3416fda81 grr
managed to add some instability, investigating
2014-02-01 12:37:04 -05:00
TwistedUmbrella 036be4085a Merge pull request #203 from maximu/patch-3
Update spanish translate string
2014-02-01 08:05:45 -08:00
Bryan Barnes 5b9dbd9fa3 This is ready to go
-Added config to input fragment
-Reduced logging
-Init the mic at the right time during startup so that port 2 either
gets vmu or mic
-Has not been tested on device without mic
-Needs more testing in games
2014-02-01 10:44:06 -05:00
Carlos Estrague 191a5dfcdf Update spanish translate string
Small changes in the spanish translation
2014-02-01 11:25:13 +01:00
Bryan Barnes 7e8bc2972b merge from master
i hope
2014-01-31 20:32:46 -05:00
Bryan Barnes 0c11acb931 better conformity to spec 2014-01-31 20:31:42 -05:00
Bryan Barnes e1970cf01d notes and manifest tweak 2014-01-31 20:31:42 -05:00
Bryan Barnes 800526ddcd progress
-some cleanup
-handling of retransmit
-got rid of needless sleeping in record thread
-some latency handling
2014-01-31 20:30:46 -05:00
hooby3dfx d839e8d70d minor hygiene 2014-01-31 20:30:45 -05:00
Bryan Barnes 841ed659ae AWWWW YEA
SOMEONE TRY THIS
2014-01-31 20:30:45 -05:00
Bryan Barnes b24e401e2f oh snap gets further!
jni local reference table overflow
2014-01-31 20:30:45 -05:00
Bryan Barnes 18e5bd7c95 almost working
crashes - need to figure out jni thread crap
2014-01-31 20:30:44 -05:00
Bryan Barnes babaf41482 mic device figured out?
i have satisfied seaman.
its just constantly polling for data.
next step: pipe in some audio!
2014-01-31 20:25:20 -05:00
hooby3dfx 8284f55b68 initial dox 2014-01-31 20:25:19 -05:00
hooby3dfx 1cb31dd932 logging changes
trying to hone in on commands going in and out
2014-01-31 20:25:19 -05:00
hooby3dfx 252df2cc95 Holy Seaman, batman!
Seaman will load :)
2014-01-31 20:25:18 -05:00
TwistedUmbrella c4dc18f1c1 Merge pull request #198 from NoblesseOblige/master
Remove deprecated string resources to prevent build error
2014-01-30 11:33:42 -08:00
TwistedUmbrella c94dd2e223 Remove deprecated string resources to prevent build error 2014-01-30 14:32:31 -05:00
TwistedUmbrella d6c8429446 Merge pull request #197 from NoblesseOblige/master
Updates for recent commit and repository changes
2014-01-30 07:13:28 -08:00
TwistedUmbrella 79bca874b7 @AndroidGX French Translation updates 2014-01-30 10:12:11 -05:00
TwistedUmbrella fd17b52792 Move to official repository for branch with default category
Since the about section can only track the default branch, the default
branch can be tracked locally. The androidui branch requires a mirror
with androidui set as default.
2014-01-30 10:07:58 -05:00
TwistedUmbrella 14b5f9ef06 Merge pull request #195 from NoblesseOblige/master
Squash changes from andoidui into single commit
2014-01-30 06:20:26 -08:00
TwistedUmbrella ae5394f6b6 Squash changes from andoidui into single commit
Integrate previously locked settings with valid user warning

Put a note about the beta compile link in the README.md

Add a super fancy about that supports Github commit logs

Revise about with git log, Highlight current build in commits

Check for a null value when getting the current commit sha

Chinese Simplified Translation from @weihan1102

Rename Simplified Chinese res folder for proper complie

Add links to the website and beta compile site from about

Add option for custom mapping to set joystick to non-dpad

Fix a missing check for the user saved value of the A button

The Moga only operates one way, there is no variation test

Add region values, Set cable to match formatting of others

Reduce the number of random string array calls, jsCompat

It was unnecessary to keep getting the array, It was even less
necessary to keep getting the preference values. The port
identification letters are set multi-lingual values.

Label the about links to prevent any confusion (Not mirrors)

Missing a check on the motion events to determine compat

Add a check to verify Kitkat, Remove the standard override

The new API verification complains about the Override, so this is a
preventative step for if and when it is updated. It may also prevent
some issues with compatibility.

Run organize imports to reduce the amount of excess code

Add a controller option to go to custom layout from selection

Prevent a leak where multiple items were highlighted in list

@AndroidGX French Translation resources
2014-01-30 09:18:45 -05:00
Matteo Hausner 3beb22b25c Merge pull request #186 from bwRavencl/german-translation
German translation
2014-01-29 13:55:15 -08:00
Matteo Hausner 00f55b5b4b Removed 'images' and 'nav_drawer_icons' sections from all string resources but the default one 2014-01-29 22:42:51 +01:00
Matteo Hausner 34ca48a484 Some German translations fixes 2014-01-29 22:40:11 +01:00
Matteo Hausner 50466eb9ec Added German translation 2014-01-29 22:27:15 +01:00
Matteo Hausner 0d91b53706 Merge pull request #183 from bwRavencl/immersive-mode
Immersive mode
2014-01-29 11:58:15 -08:00
Matteo Hausner 57212196fb Added support for immersive mode on KitKat devices 2014-01-29 20:27:08 +01:00
Matteo Hausner d032bc4a24 Removed hello_world from Russion translation 2014-01-29 19:49:52 +01:00
TwistedUmbrella 5771dedac8 Merge pull request #181 from ramersonw/master
Updated portuguese translation
2014-01-29 06:03:10 -08:00
ramersonw 4dac3a6800 Updated portuguese translation 2014-01-29 11:58:48 -02:00
TwistedUmbrella 84326bb12a Merge pull request #161 from MrYadro/master
Initial Russian translation & TravisCI support
2014-01-28 07:08:53 -08:00
TwistedUmbrella 1543474366 Remove all the auto RTF garbage from Strings.txt 2014-01-27 09:55:50 -05:00
TwistedUmbrella cbfda5a767 Merge pull request #166 from NoblesseOblige/master
More progress on simulated L / R, Translation shells, Custom input updates
2014-01-27 06:52:01 -08:00
TwistedUmbrella b41bb39c0e Merge pull request #159 from NoblesseOblige/master
Moga updates, Memory handling, UI issues, Config
2014-01-27 00:59:26 -08:00
Yaroslav 5a955dac3d Initial Russian translation & TravisCI support 2014-01-26 20:32:17 +07:00
ptitSeb c655c51da2 Fixed Pandora Makefile 2014-01-23 09:19:09 +01:00
ptitSeb faaa8d3630 Merge branch 'master' of https://github.com/reicast/emulator into pandora
Conflicts:
	shell/pandora/Makefile
2014-01-23 09:09:23 +01:00
ptitSeb b7177e742a PANDORA: played with ccache 2014-01-23 09:06:35 +01:00
332 changed files with 51528 additions and 7558 deletions

No files matched your search

+41
View File
@@ -8,3 +8,44 @@ obj/
newdc/android/libnewdc/bin/libnewdc.jar
newdc/android/libnewdc/bin/classes/com/example/newdc/JNIdc.class
shell/android/assets/build
shell/android/tools
# iOS/Xcode general stuff
.DS_Store
*/build/*
**/build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
profile
*.moved-aside
DerivedData
.idea/
*.hmap
emulator.xccheckout
reicast.xccheckout
build/*
*.so
*Karen_angelXwind*
local.properties
ant.properties
*build_obj
Workdir/data
Workdir/reicast*
Workdir/vmu*
Workdir/webui*
Workdir/emu.cfg
Workdir/lib*ant.properties
# Linux stuff
shell/lin86/.map
shell/lin86/nosym-reicast.elf
shell/lin86/reicast.elf
+55
View File
@@ -0,0 +1,55 @@
notifications:
irc: chat.freenode.net#reicast
language: cpp
compiler: gcc
before_install:
- openssl aes-256-cbc -K $encrypted_c726d225a9d9_key -iv $encrypted_c726d225a9d9_iv
-in debug.keystore.enc -out debug.keystore -d
- sudo apt-get install aria2 -qq
- download_extract() { aria2c -x 16 $1 -o $2 && tar -xf $2; }
- download_extract_zip() { aria2c -x 16 $1 -o $2 && unzip -qq $2; }
- sudo apt-get -qq update
- sudo apt-get -qq -y install openjdk-7-jdk ant lib32z1-dev lib32stdc++6
- GIT_HASH=`git log --pretty=format:'%h' -n 1`
- GIT_BUILD=`git describe --all`-$GIT_HASH
install:
- download_extract http://dl.google.com/android/ndk/android-ndk-r9c-linux-x86_64.tar.bz2
android-ndk-r9c-linux-x86_64.tar.bz2
- download_extract_zip http://dl.google.com/android/adt/adt-bundle-linux-x86_64-20131030.zip
adt-bundle-linux-x86_64-20131030.zip
- mv android-ndk-r9c android-ndk
- mv adt-bundle-linux-x86_64-20131030/sdk/ android-sdk
- rm android-ndk-r9c-linux-x86_64.tar.bz2
- rm adt-bundle-linux-x86_64-20131030.zip
- export ANDROID_HOME=$(pwd)/android-sdk
- export NDK=$(pwd)/android-ndk
- export ANDROID_NDK=$(pwd)/android-ndk
- export PATH=${PATH}:$ANDROID_HOME/tools
- export PATH=${PATH}:$ANDROID_HOME/platform-tools
- export PATH=${PATH}:$NDK
- mkdir -p ~/.android
- mv debug.keystore ~/.android/debug.keystore
before_script:
script:
- cd shell/android
- android update project -p . --target "android-19"
- export NUMBER_OF_PROCESSORS=2
- ant debug
before_deploy:
- cd ../../
- mkdir -p artifacts/$GIT_BUILD/
- cp shell/android/bin/reicast-debug.apk artifacts/$GIT_BUILD/reicast-android-debug-$GIT_HASH.apk
deploy:
provider: s3
access_key_id: AKIAJR5J3OHAQUP5BHHQ
secret_access_key:
secure: dDmBiadS1cc2XCWWDZ1kwZGIoLkwEOLsdi5nzVdn1dHMsEKxN3u+3WFuuOfJHZYcdrtN7VhojCarPa+eGDDeiVme4m3y+QKMbI9lecHX9+t4jDNUyYep5TpeIVUkZ7fj4JsMi7U9/YFBTg7QnqvVsMAHE9vobkvjegjAYToBrlM=
bucket: reicast-builds
local-dir: artifacts
upload-dir: builds
skip_cleanup: true
on:
all_branches: true
repo: reicast/reicast-emulator
after_deploy:
- echo "done"
+98 -18
View File
@@ -1,8 +1,8 @@
reicast
===========
reicast is a sega dreamcast emulator
reicast is a multi-platform Sega Dreamcast emulator.
This is developer oriented resource, if you just want bins head over to http://reicast.com
This is a developer-oriented resource, if you just want bins head over to http://reicast.com/
Caution
-------
@@ -16,29 +16,91 @@ If you are interested into further porting/adapting/whatever, *please* don't for
Let's try to keep everything under a single project :)
To build for android
Building for Android
--------------------
Tools required:
* Latest Android SDK and NDK (duh)
* Latest Android SDK
- http://developer.android.com/sdk/index.html
* NDK r8b or newer
- https://developer.android.com/tools/sdk/ndk/index.html
- If are not using r9c+, comment the "NDK_TOOLCHAIN_VERSION := 4.8" in shell/android/jni/Application.mk and shell/android/xperia/jni/Application.mk
* Android 4.4 (API 19) & Android 2.3.1 (API 9)
- http://developer.android.com/sdk/installing/adding-packages.html
- note that API 9 is hidden (you must check to show obsolete in SDK manager)
* Ant
- http://ant.apache.org/
From project root directory:
```
cd shell\android
android update project -p .
export ANDROID_NDK=/ # Type the full path to your NDK here
ndk-build -j 4
cd shell/android/
android update project -p . --target "android-19"
ant debug
```
Building for iOS
----------------
Tools required:
* Latest Xcode
- https://developer.apple.com/xcode/downloads/
* An iOS device (reicast will not compile for the iOS Simulator)
* iOS 5.x ~ 7.x
* iOSOpenDev if developing without an official Apple certificate
- http://iosopendev.com/download/
From project root directory:
```
cd shell/ios/
xcodebuild -configuration Release
```
Building for Linux
------------------
The code is only currently compatible with 32bit architectures so you will need
to install 32bit libs to build reicast.
Requirements:
* build-essential
* libasound
* libegl1-mesa-dev
* libgles2-mesa-dev
* libasound2-dev
To build the project, go to shell/lin86 and run make
Translations
------------
New and updated translations are always appreciated!
All we ask is that you not use “regional” phrases that may not be generally understood.
Translations can be submitted as a pull request
Beta versions
-------------
[![Build Status](https://travis-ci.org/reicast/reicast-emulator.svg?branch=master)](https://travis-ci.org/reicast/reicast-emulator)
Official builds from the reicast ci service can be found at http://builds.reicast.com/
Additional builds (iOS & android) can be found at [angelxwind's](http://reicast.angelxwind.net/) buildbot
Donations and stuff
-------------------
Well, glad you liked the project so far!
We're currently short on hardware
We're currently short on hardware.
If you would like to donate some devices, get in touch at team@reicast.com. GLES3 capable stuff, some mainstream hardware and rarities would be extremely appreciated.
If you would like to donate some devices, get in touch at team@reicast.com.
GLES3 capable stuff, some mainstream hardware and rarities would be extremely
appreciated.
Keep in mind we're located in Greece for the most part
This has been tested/developed on
@@ -48,33 +110,51 @@ This has been tested/developed on
* Some Chinese tablet
* OUYA
* Various development boards
* gcw zero
* GCW Zero
We had to buy all of these, except the gcw zero and a beaglebone which were donated (thanks! You rock!)
We had to buy all of these, except the GCW Zero and a BeagleBone which were
donated (Thanks! You rock!)
Apart from that, we don't accept monetary donations right now.
We also don't plan to be releasing a premium version at any store.
Most of the project has been developed by drk||Raziel (aka, skmp, drk, Raz, etc) but it has been based on the
works of multiple people. It would be extremely unfair to charge for it and get all the credit :)
Most of the project has been developed by drk||Raziel (aka, skmp, drk, Raz,
etc) but it has been based on the works of multiple people. It would be
extremely unfair to charge for it and get all the credit :)
We're planning for an indiegogo campaign later on to help with sustained
development and running costs, so follow @reicastdc on twitter for updates
We're planning for an indiegogo campaign later on to help with sustained development and running costs, so follow @reicastdc on twitter for updates
Other Testing
-------------
These devices are tested by Karen/angelXwind:
* Apple iPhone 4 GSM Rev0 (N90AP)
* Apple iPhone 4 CDMA (N92AP)
* Apple iPod touch 4 (N81AP)
* Apple iPod touch 3G (N18AP)
* Apple iPhone 3GS (N88AP)
* Sony Xperia X10a (es209ra)
* Amazon Kindle Fire HD 7 (tate-pvt-08)
These devices are tested by contributors regularly:
* Nvidia Shield
* Nexus 5 / 7
* Xperia Play
Team
----
You can check the currently active committers on [the pretty graphs page](https://github.com/reicast/reicast-emulator/graphs/contributors)
Chat on freenode #reicast.
Our IRC channel is [#reicast @ chat.freenode.net](irc://chat.freenode.net/reicast).
The original reicast team consisted of drk||Raziel (mostly just writing code), PsyMan (debugging/testing and everything else) and a little bit of gb_away
The original reicast team consisted of drk||Raziel (mostly just writing code),
PsyMan (debugging/testing and everything else) and a little bit of gb_away
Special thanks
--------------
In previous iterations a lot of people have worked on this, notably David Miller (aka, ZeZu), the nullDC team, friends from #pcsx2 and all over the world :)
In previous iterations a lot of people have worked on this, notably David
Miller (aka, ZeZu), the nullDC team, friends from #pcsx2 and all over the world :)
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/reicast/reicast-emulator/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
+398
View File
@@ -0,0 +1,398 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8 http-equiv="Content-Language" content="en"/>
<title>Minimal Websocket test app</title>
<style type="text/css">
div.title { font-size:18pt; font: Arial; font-weight:normal; text-align:center; color:#000000; }
.browser { font-size:18pt; font: Arial; font-weight:normal; text-align:center; color:#ffff00; vertical-align:middle; text-align:center; background:#d0b070; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px;}
.group2 { width:600px; vertical-align:middle; text-align:center; background:#f0f0e0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; }
.explain { vertical-align:middle; text-align:center; background:#f0f0c0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; color:#404000; }
.content { vertical-align:top; text-align:center; background:#fffff0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; }
.canvas { vertical-align:top; text-align:center; background:#efefd0; padding:12px; -webkit-border-radius:10px; -moz-border-radius:10px; border-radius:10px; }
</style>
</head>
<body>
<header></header>
<article>
<table><tr><td>
<table width="100%"><tr><td valign=middle align=center><a href="http://libwebsockets.org"><img src="/libwebsockets.org-logo.png"></a></td><td>
<section class="browser">Detected Browser: <div id=brow>...</div></section></td></tr></table>
</td></tr><tr><td>
<section id="increment" class="group2">
<div class="title">libwebsockets "dumb-increment-protocol"</div>
<table><tr><td>
<table class="content" width="200px">
<tr><td align=center><input type=button id=offset value="Reset counter" onclick="reset();" ></td></tr>
<tr><td width=200px align=center><div id=number> </div></td></tr>
<tr><td id=wsdi_statustd align=center class="explain"><div id=wsdi_status>Not initialized</div></td></tr>
</tr>
</table>
</td><td class="explain">
The incrementing number is coming from the server and is individual for
each connection to the server... try opening a second browser window.
<br/><br/>
The button zeros just this connection's number.
<br/><br/>
</td></tr></table>
</section>
<br>
<section id="mirror" class="group2">
<div class="title">libwebsockets "lws-mirror-protocol"</div>
<div class="explain">
Use the mouse to draw on the canvas below -- all other browser windows open
on this page see your drawing in realtime and you can see any of theirs as
well.
<br/><br/>
The lws-mirror protocol doesn't interpret what is being sent to it, it just
re-sends it to every other websocket it has a connection with using that
protocol, including the guy who sent the packet.
<br/><br/>
<b>libwebsockets-test-client</b> joins in by spamming circles on to this shared canvas when
run.
</div>
<table class="content">
<tr>
<td>Drawing color:
<select id="color" onchange="update_color();">
<option value=#000000>Black</option>
<option value=#0000ff>Blue</option>
<option value=#20ff20>Green</option>
<option value=#802020>Dark Red</option>
</select>
</td>
<td id=wslm_statustd align=center class="explain"><div id=wslm_status>Not initialized</div></td>
</tr>
<tr>
<td colspan=2 width=500 class="content">
<div id="wslm_drawing">
</div></td>
</tr>
</table>
</section>
</td></tr><tr><td>
Looking for support? <a href="http://libwebsockets.org">http://libwebsockets.org</a><br/>
Join the mailing list: ​<a href="http://ml.libwebsockets.org/mailman/listinfo/libwebsockets">http://ml.libwebsockets.org/mailman/listinfo/libwebsockets</a>
</td></tr></table>
</article>
<script>
/* BrowserDetect came from http://www.quirksmode.org/js/detect.html */
var BrowserDetect = {
init: function () {
this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
this.version = this.searchVersion(navigator.userAgent)
|| this.searchVersion(navigator.appVersion)
|| "an unknown version";
this.OS = this.searchString(this.dataOS) || "an unknown OS";
},
searchString: function (data) {
for (var i=0;i<data.length;i++) {
var dataString = data[i].string;
var dataProp = data[i].prop;
this.versionSearchString = data[i].versionSearch || data[i].identity;
if (dataString) {
if (dataString.indexOf(data[i].subString) != -1)
return data[i].identity;
}
else if (dataProp)
return data[i].identity;
}
},
searchVersion: function (dataString) {
var index = dataString.indexOf(this.versionSearchString);
if (index == -1) return;
return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
},
dataBrowser: [
{
string: navigator.userAgent,
subString: "Chrome",
identity: "Chrome"
},
{ string: navigator.userAgent,
subString: "OmniWeb",
versionSearch: "OmniWeb/",
identity: "OmniWeb"
},
{
string: navigator.vendor,
subString: "Apple",
identity: "Safari",
versionSearch: "Version"
},
{
prop: window.opera,
identity: "Opera",
versionSearch: "Version"
},
{
string: navigator.vendor,
subString: "iCab",
identity: "iCab"
},
{
string: navigator.vendor,
subString: "KDE",
identity: "Konqueror"
},
{
string: navigator.userAgent,
subString: "Firefox",
identity: "Firefox"
},
{
string: navigator.vendor,
subString: "Camino",
identity: "Camino"
},
{ // for newer Netscapes (6+)
string: navigator.userAgent,
subString: "Netscape",
identity: "Netscape"
},
{
string: navigator.userAgent,
subString: "MSIE",
identity: "Explorer",
versionSearch: "MSIE"
},
{
string: navigator.userAgent,
subString: "Gecko",
identity: "Mozilla",
versionSearch: "rv"
},
{ // for older Netscapes (4-)
string: navigator.userAgent,
subString: "Mozilla",
identity: "Netscape",
versionSearch: "Mozilla"
}
],
dataOS : [
{
string: navigator.platform,
subString: "Win",
identity: "Windows"
},
{
string: navigator.platform,
subString: "Mac",
identity: "Mac"
},
{
string: navigator.userAgent,
subString: "iPhone",
identity: "iPhone/iPod"
},
{
string: navigator.platform,
subString: "Linux",
identity: "Linux"
}
]
};
BrowserDetect.init();
document.getElementById("brow").textContent = " " + BrowserDetect.browser + " "
+ BrowserDetect.version +" " + BrowserDetect.OS +" ";
var pos = 0;
function get_appropriate_ws_url()
{
var pcol;
var u = document.URL;
/*
* We open the websocket encrypted if this page came on an
* https:// url itself, otherwise unencrypted
*/
if (u.substring(0, 5) == "https") {
pcol = "wss://";
u = u.substr(8);
} else {
pcol = "ws://";
if (u.substring(0, 4) == "http")
u = u.substr(7);
}
u = u.split('/');
/* + "/xxx" bit is for IE10 workaround */
return pcol + u[0] + "/xxx";
}
document.getElementById("number").textContent = get_appropriate_ws_url();
/* dumb increment protocol */
var socket_di;
if (typeof MozWebSocket != "undefined") {
socket_di = new MozWebSocket(get_appropriate_ws_url(),
"dumb-increment-protocol");
} else {
socket_di = new WebSocket(get_appropriate_ws_url(),
"dumb-increment-protocol");
}
try {
socket_di.onopen = function() {
document.getElementById("wsdi_statustd").style.backgroundColor = "#40ff40";
document.getElementById("wsdi_status").textContent = " websocket connection opened ";
}
socket_di.onmessage =function got_packet(msg) {
document.getElementById("number").textContent = msg.data + "\n";
}
socket_di.onclose = function(){
document.getElementById("wsdi_statustd").style.backgroundColor = "#ff4040";
document.getElementById("wsdi_status").textContent = " websocket connection CLOSED ";
}
} catch(exception) {
alert('<p>Error' + exception);
}
function reset() {
socket_di.send("reset\n");
}
/* lws-mirror protocol */
var down = 0;
var no_last = 1;
var last_x = 0, last_y = 0;
var ctx;
var socket_lm;
var color = "#000000";
if (typeof MozWebSocket != "undefined") {
socket_lm = new MozWebSocket(get_appropriate_ws_url(),
"lws-mirror-protocol");
} else {
socket_lm = new WebSocket(get_appropriate_ws_url(),
"lws-mirror-protocol");
}
try {
socket_lm.onopen = function() {
document.getElementById("wslm_statustd").style.backgroundColor = "#40ff40";
document.getElementById("wslm_status").textContent = " websocket connection opened ";
}
socket_lm.onmessage =function got_packet(msg) {
j = msg.data.split(';');
f = 0;
while (f < j.length - 1) {
i = j[f].split(' ');
if (i[0] == 'd') {
ctx.strokeStyle = i[1];
ctx.beginPath();
ctx.moveTo(+(i[2]), +(i[3]));
ctx.lineTo(+(i[4]), +(i[5]));
ctx.stroke();
}
if (i[0] == 'c') {
ctx.strokeStyle = i[1];
ctx.beginPath();
ctx.arc(+(i[2]), +(i[3]), +(i[4]), 0, Math.PI*2, true);
ctx.stroke();
}
f++;
}
}
socket_lm.onclose = function(){
document.getElementById("wslm_statustd").style.backgroundColor = "#ff4040";
document.getElementById("wslm_status").textContent = " websocket connection CLOSED ";
}
} catch(exception) {
alert('<p>Error' + exception);
}
var canvas = document.createElement('canvas');
canvas.height = 300;
canvas.width = 480;
ctx = canvas.getContext("2d");
document.getElementById('wslm_drawing').appendChild(canvas);
canvas.addEventListener('mousemove', ev_mousemove, false);
canvas.addEventListener('mousedown', ev_mousedown, false);
canvas.addEventListener('mouseup', ev_mouseup, false);
offsetX = offsetY = 0;
element = canvas;
if (element.offsetParent) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
function update_color() {
color = document.getElementById("color").value;
}
function ev_mousedown (ev) {
down = 1;
}
function ev_mouseup(ev) {
down = 0;
no_last = 1;
}
function ev_mousemove (ev) {
var x, y;
if (ev.offsetX) {
x = ev.offsetX;
y = ev.offsetY;
} else {
x = ev.layerX - offsetX;
y = ev.layerY - offsetY;
}
if (!down)
return;
if (no_last) {
no_last = 0;
last_x = x;
last_y = y;
return;
}
socket_lm.send("d " + color + " " + last_x + " " + last_y + " " + x + ' ' + y + ';');
last_x = x;
last_y = y;
}
</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

+18 -8
View File
@@ -34,6 +34,7 @@
//HOST_OS
#define OS_WINDOWS 0x10000001
#define OS_LINUX 0x10000002
#define OS_DARWIN 0x10000003
//HOST_CPU
#define CPU_X86 0x20000001
@@ -44,31 +45,40 @@
#define COMPILER_VC 0x30000001
#define COMPILER_GCC 0x30000002
///
#if (!defined(TARGET_WIN86) && !defined(TARGET_BEAGLE) && !defined(TARGET_NACL32) && !defined(TARGET_GCW0) && !defined(TARGET_PANDORA))
#if defined(_WIN32) && !defined(TARGET_WIN86)
#define TARGET_WIN86
#endif
#ifdef __GNUC__
#define BUILD_COMPILER COMPILER_GCC
#else
#define BUILD_COMPILER COMPILER_VC
#endif
#ifdef TARGET_WIN86
#define HOST_OS OS_WINDOWS
#define HOST_CPU CPU_X86
#define BUILD_COMPILER COMPILER_VC
#elif TARGET_PANDORA
#define HOST_OS OS_LINUX
#define HOST_CPU CPU_ARM
#define BUILD_COMPILER COMPILER_GCC
#elif TARGET_BEAGLE
#elif TARGET_LINUX_ARMELv7
#define HOST_OS OS_LINUX
#define HOST_CPU CPU_ARM
#define BUILD_COMPILER COMPILER_GCC
#elif TARGET_LINUX_x86
#define HOST_OS OS_LINUX
#define HOST_CPU CPU_X86
#elif TARGET_LINUX_MIPS
#define HOST_OS OS_LINUX
#define HOST_CPU CPU_MIPS
#elif TARGET_GCW0
#define HOST_OS OS_LINUX
#define HOST_CPU CPU_MIPS
#define BUILD_COMPILER COMPILER_GCC
#elif TARGET_NACL32
#define HOST_OS OS_LINUX
#define HOST_CPU CPU_X86
#define BUILD_COMPILER COMPILER_GCC
#elif TARGET_IPHONE
#define HOST_OS OS_DARWIN
#define HOST_CPU CPU_ARM
#else
#error Invalid Target: TARGET_* not defined
#endif
+40 -8
View File
@@ -8,9 +8,19 @@ RZDCY_SRC_DIR ?= $(call my-dir)
RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ \
hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/interpr/ hw/sh4/modules/ plugins/ profiler/ oslib/ \
hw/extdev/ hw/arm/ imgread/ linux/ ./ deps/zlib/ deps/chdr/ deps/crypto/ deps/libelf/ deps/chdpsr/ arm_emitter/ \
hw/extdev/ hw/arm/ imgread/ linux/ ./ deps/coreio/ deps/zlib/ deps/chdr/ deps/crypto/ deps/libelf/ deps/chdpsr/ arm_emitter/ \
deps/libzip/ deps/libpng/ rend/
ifdef WEBUI
RZDCY_MODULES += webui/
RZDCY_MODULES += deps/libwebsocket/
ifdef FOR_ANDROID
RZDCY_MODULES += deps/ifaddrs/
endif
endif
ifndef NO_REC
RZDCY_MODULES += hw/sh4/dyna/
endif
@@ -42,17 +52,39 @@ RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(w
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.S))
ifdef FOR_PANDORA
RZDCY_CXXFLAGS := \
RZDCY_CFLAGS := \
$(CFLAGS) -c -g -O3 -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps \
-DRELEASE -DPANDORA\
-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp \
-frename-registers -fsingle-precision-constant -ffast-math \
-ftree-vectorize -fomit-frame-pointer -fno-exceptions -fno-rtti -std=gnu++11
-ftree-vectorize -fomit-frame-pointer
RZDCY_CFLAGS += -march=armv7-a -mtune=cortex-a8 -mfpu=neon
RZDCY_CFLAGS += -DTARGET_LINUX_ARMELv7
else
RZDCY_CXXFLAGS := \
RZDCY_CFLAGS := \
$(CFLAGS) -c -g -O3 -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps \
-D_ANDROID -DRELEASE -DTARGET_BEAGLE\
-march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16 \
-D_ANDROID -DRELEASE\
-frename-registers -fsingle-precision-constant -ffast-math \
-ftree-vectorize -fomit-frame-pointer -fno-exceptions -fno-rtti -std=gnu++11
endif
-ftree-vectorize -fomit-frame-pointer
ifndef NOT_ARM
RZDCY_CFLAGS += -march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16
RZDCY_CFLAGS += -DTARGET_LINUX_ARMELv7
else
ifndef ISMIPS
RZDCY_CFLAGS += -DTARGET_LINUX_x86
else
RZDCY_CFLAGS += -DTARGET_LINUX_MIPS
endif
endif
endif
ifdef NO_REC
RZDCY_CFLAGS += -DHOST_NO_REC
endif
ifndef DESKTOPGL
RZDCY_CFLAGS += -DGLES
endif
RZDCY_CXXFLAGS := $(RZDCY_CFLAGS) -fno-exceptions -fno-rtti -std=gnu++11
+2 -2
View File
@@ -42,8 +42,8 @@ unsigned long track_mode;
void CDI_read_track (FILE *fsource, image_s *image, track_s *track)
{
char TRACK_START_MARK[10] = { 0, 0, 0x01, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF };
char current_start_mark[10];
unsigned char TRACK_START_MARK[10] = { 0, 0, 0x01, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF };
unsigned char current_start_mark[10];
fread(&temp_value, 4, 1, fsource);
if (temp_value != 0)
+1
View File
@@ -43,6 +43,7 @@
#define __CHD_H__
#include "coretypes.h"
#include "deps/coreio/coreio.h"
/***************************************************************************
+4 -20
View File
@@ -302,22 +302,6 @@ static const codec_interface codec_interfaces[] =
},
};
int core_fread(FILE* f, void* buff, size_t len)
{
return fread(buff,1,len,f);
}
size_t core_fsize(FILE* f)
{
size_t p=ftell(f);
fseek(f,0,SEEK_END);
size_t rv=ftell(f);
fseek(f,p,SEEK_SET);
return rv;
}
#define core_fseek fseek
#define MIN min
#define MAX max
/***************************************************************************
@@ -593,7 +577,7 @@ chd_error chd_open(const wchar *filename, int mode, chd_file *parent, chd_file *
}
/* open the file */
file=fopen(filename, "rb");
file=core_fopen(filename);
if (file == 0)
{
err = CHDERR_FILE_NOT_FOUND;
@@ -610,7 +594,7 @@ chd_error chd_open(const wchar *filename, int mode, chd_file *parent, chd_file *
cleanup:
if ((err != CHDERR_NONE) && (file != NULL))
fclose(file);
core_fclose(file);
return err;
}
@@ -653,7 +637,7 @@ void chd_close(chd_file *chd)
/* close the file */
if (chd->owns_file && chd->file != NULL)
fclose(chd->file);
core_fclose(chd->file);
if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks);
@@ -807,7 +791,7 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex,
/* read the metadata */
outputlen = min(outputlen, metaentry.length);
fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET);
core_fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET);
count = core_fread(chd->file, output, outputlen);
if (count != outputlen)
return CHDERR_READ_ERROR;
-2
View File
@@ -15,6 +15,4 @@ typedef s8 INT8;
#define INLINE inline
#endif
#define core_file FILE
#define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0]))
+265
View File
@@ -0,0 +1,265 @@
#include "coreio.h"
#include <time.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#pragma comment (lib, "wsock32.lib")
#include <string>
#include <sstream>
#if HOST_OS == OS_LINUX
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <linux/tcp.h>
#include <netdb.h>
#include <unistd.h>
#endif
size_t HTTP_GET(string host, int port,string path, size_t offs, size_t len, void* pdata){
string request;
string response;
struct sockaddr_in serveraddr;
int sock;
std::stringstream request2;
if (len) {
request2 << "GET " << path << " HTTP/1.1"<<endl;
request2 << "User-Agent: reicastdc" << endl;
//request2 << "" << endl;
request2 << "Host: " << host << endl;
request2 << "Accept: */*" << endl;
request2 << "Range: bytes=" << offs << "-" << (offs + len-1) << endl;
request2 << endl;
}
else {
request2 << "HEAD " << path << " HTTP/1.1"<<endl;
request2 << "User-Agent: reicastdc" << endl;
//request2 << "" << endl;
request2 << "Host: " << host << endl;
request2 << endl;
}
request = request2.str();
//init winsock
static bool init = false;
if (!init) {
#if HOST_OS == OS_WINDOWS
static WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
die("WSAStartup fail");
#endif
init = true;
}
//open socket
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
return -1;
//connect
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = *(int*)gethostbyname( host.c_str() )->h_addr_list[0];
serveraddr.sin_port = htons((unsigned short) port);
if (connect(sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
return -1;
#if HOST_OS == OS_WINDOWS
BOOL v = TRUE;
#else
int v = 1;
#endif
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&v, sizeof(v));
//send request
if (send(sock, request.c_str(), request.length(), 0) != request.length())
return -1;
/*
//get response
response = "";
resp_leng= BUFFERSIZE;
*/
/*
parse headers ..
*/
size_t content_length = 0;
size_t rv = content_length;
for (;;) {
stringstream ss;
for (;;) {
char t;
if (recv(sock, &t, 1, 0) <= 0)
goto _cleanup;
if (t != '\n'){
ss << t;
continue;
}
string ln = ss.str();
if (ln.size() == 1)
goto _data;
string CL = "Content-Length:";
if (ln.substr(0, CL.size()) == CL) {
sscanf(ln.substr(CL.size(), ln.npos).c_str(),"%d", &content_length);
}
break;
}
}
_data:
if (len == 0) {
}
else {
verify(len == content_length);
u8* ptr = (u8*)pdata;
do
{
int rcv = recv(sock, (char*)ptr, len, 0);
verify(rcv > 0 && len>= rcv);
len -= rcv;
ptr += rcv;
}
while (len >0);
}
_cleanup:
//disconnect
#if HOST_OS == OS_WINDOWS
closesocket(sock);
#else
close(sock);
#endif
/*
//cleanup
WSACleanup();
*/
return rv;
}
struct CORE_FILE {
FILE* f;
string path;
size_t seek_ptr;
string host;
int port;
};
core_file* core_fopen(const char* filename)
{
string p = filename;
CORE_FILE* rv = new CORE_FILE();
rv->f = 0;
rv->path = p;
if (p.substr(0,7)=="http://") {
rv->host = p.substr(7,p.npos);
rv->host = rv->host.substr(0, rv->host.find_first_of("/"));
rv->path = p.substr(p.find("/", 7), p.npos);
rv->port = 80;
size_t pos = rv->host.find_first_of(":");
if (pos != rv->host.npos) {
string port = rv->host.substr(pos, rv->host.npos );
rv->host = rv->host.substr(0, rv->host.find_first_of(":"));
sscanf(port.c_str(),"%d",&rv->port);
}
} else {
rv->f = fopen(filename, "rb");
if (!rv->f) {
delete rv;
return 0;
}
}
return (core_file*)rv;
}
size_t core_fseek(core_file* fc, size_t offs, size_t origin) {
CORE_FILE* f = (CORE_FILE*)fc;
if (origin == SEEK_SET)
f->seek_ptr = offs;
else if (origin == SEEK_CUR)
f->seek_ptr += offs;
else
die("Invalid code path");
if (f->f)
fseek(f->f, f->seek_ptr, SEEK_SET);
return 0;
}
int core_fread(core_file* fc, void* buff, size_t len)
{
CORE_FILE* f = (CORE_FILE*)fc;
if (f->f) {
fread(buff,1,len,f->f);
} else {
HTTP_GET(f->host, f->port, f->path, f->seek_ptr, len, buff);
}
f->seek_ptr += len;
return len;
}
int core_fclose(core_file* fc)
{
CORE_FILE* f = (CORE_FILE*)fc;
if (f->f) {
fclose(f->f);
}
else {
}
delete f;
return 0;
}
size_t core_fsize(core_file* fc)
{
CORE_FILE* f = (CORE_FILE*)fc;
if (f->f) {
size_t p=ftell(f->f);
fseek(f->f,0,SEEK_END);
size_t rv=ftell(f->f);
fseek(f->f,p,SEEK_SET);
return rv;
}
else {
return HTTP_GET(f->host, f->port, f->path, 0, 0,0);
}
}
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include "types.h"
//#define core_file FILE
typedef void* core_file;
core_file* core_fopen(const char* filename);
size_t core_fseek(core_file* fc, size_t offs, size_t origin);
int core_fread(core_file* fc, void* buff, size_t len);
int core_fclose(core_file* fc);
size_t core_fsize(core_file* fc);
+161
View File
@@ -0,0 +1,161 @@
/*********************************************************************
* Filename: sha256.c
* Author: Brad Conte (brad AT bradconte.com)
* Copyright:
* Disclaimer: This code is presented "as is" without any guarantees.
* Details: Implementation of the SHA-256 hashing algorithm.
SHA-256 is one of the three algorithms in the SHA2
specification. The others, SHA-384 and SHA-512, are not
offered in this implementation.
Algorithm specification can be found here:
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
This implementation uses little endian byte order.
*********************************************************************/
/*************************** HEADER FILES ***************************/
#include <stdlib.h>
#include <memory.h>
#include "sha256.h"
#define WORD uint32_t
#define BYTE uint8_t
/****************************** MACROS ******************************/
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
/**************************** VARIABLES *****************************/
static const WORD k[64] = {
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};
/*********************** FUNCTION DEFINITIONS ***********************/
void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
{
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
for (i = 0, j = 0; i < 16; ++i, j += 4)
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
for ( ; i < 64; ++i)
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
f = ctx->state[5];
g = ctx->state[6];
h = ctx->state[7];
for (i = 0; i < 64; ++i) {
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
t2 = EP0(a) + MAJ(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
ctx->state[5] += f;
ctx->state[6] += g;
ctx->state[7] += h;
}
void sha256_init(SHA256_CTX *ctx)
{
ctx->datalen = 0;
ctx->bitlen = 0;
ctx->state[0] = 0x6a09e667;
ctx->state[1] = 0xbb67ae85;
ctx->state[2] = 0x3c6ef372;
ctx->state[3] = 0xa54ff53a;
ctx->state[4] = 0x510e527f;
ctx->state[5] = 0x9b05688c;
ctx->state[6] = 0x1f83d9ab;
ctx->state[7] = 0x5be0cd19;
}
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
{
WORD i;
for (i = 0; i < len; ++i) {
ctx->data[ctx->datalen] = data[i];
ctx->datalen++;
if (ctx->datalen == 64) {
sha256_transform(ctx, ctx->data);
ctx->bitlen += 512;
ctx->datalen = 0;
}
}
}
void sha256_final(SHA256_CTX *ctx, BYTE hash[])
{
WORD i;
i = ctx->datalen;
// Pad whatever data is left in the buffer.
if (ctx->datalen < 56) {
ctx->data[i++] = 0x80;
while (i < 56)
ctx->data[i++] = 0x00;
}
else {
ctx->data[i++] = 0x80;
while (i < 64)
ctx->data[i++] = 0x00;
sha256_transform(ctx, ctx->data);
memset(ctx->data, 0, 56);
}
// Append to the padding the total message's length in bits and transform.
ctx->bitlen += ctx->datalen * 8;
ctx->data[63] = (BYTE)(ctx->bitlen);
ctx->data[62] = (BYTE)(ctx->bitlen >> 8);
ctx->data[61] = (BYTE)(ctx->bitlen >> 16);
ctx->data[60] = (BYTE)(ctx->bitlen >> 24);
ctx->data[59] = (BYTE)(ctx->bitlen >> 32);
ctx->data[58] = (BYTE)(ctx->bitlen >> 40);
ctx->data[57] = (BYTE)(ctx->bitlen >> 48);
ctx->data[56] = (BYTE)(ctx->bitlen >> 56);
sha256_transform(ctx, ctx->data);
// Since this implementation uses little endian byte ordering and SHA uses big endian,
// reverse all the bytes when copying the final state to the output hash.
for (i = 0; i < 4; ++i) {
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
}
}
+37
View File
@@ -0,0 +1,37 @@
/*********************************************************************
* Filename: sha256.h
* Author: Brad Conte (brad AT bradconte.com)
* Copyright:
* Disclaimer: This code is presented "as is" without any guarantees.
* Details: Defines the API for the corresponding SHA1 implementation.
*********************************************************************/
#ifndef SHA256_H
#define SHA256_H
/*************************** HEADER FILES ***************************/
#include <stddef.h>
#include <stdint.h>
/****************************** MACROS ******************************/
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
/**************************** DATA TYPES ****************************/
/*
typedef uint8_t BYTE; // 8-bit byte
typedef uint32_t WORD; // 32-bit word, change to "long" for 16-bit machines
*/
typedef struct {
uint8_t data[64];
uint32_t datalen;
uint64_t bitlen;
uint32_t state[8];
} SHA256_CTX;
/*********************** FUNCTION DECLARATIONS **********************/
void sha256_init(SHA256_CTX *ctx);
void sha256_update(SHA256_CTX *ctx, const uint8_t data[], size_t len);
void sha256_final(SHA256_CTX *ctx, uint8_t hash[]);
#endif // SHA256_H
+6
View File
@@ -0,0 +1,6 @@
android-ifaddrs
===============
An implementation of getifaddrs() for Android, since the NDK does not natively support it.
Works just like you would expect on regular Linux. License information is present in each file (BSD license).
+658
View File
@@ -0,0 +1,658 @@
/*
Copyright (c) 2013, Kenneth MacKay
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ifaddrs.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
typedef struct NetlinkList
{
struct NetlinkList *m_next;
struct nlmsghdr *m_data;
unsigned int m_size;
} NetlinkList;
static int netlink_socket(void)
{
int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if(l_socket < 0)
{
return -1;
}
struct sockaddr_nl l_addr;
memset(&l_addr, 0, sizeof(l_addr));
l_addr.nl_family = AF_NETLINK;
if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
{
close(l_socket);
return -1;
}
return l_socket;
}
static int netlink_send(int p_socket, int p_request)
{
char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))];
memset(l_buffer, 0, sizeof(l_buffer));
struct nlmsghdr *l_hdr = (struct nlmsghdr *)l_buffer;
struct rtgenmsg *l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
l_hdr->nlmsg_type = p_request;
l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
l_hdr->nlmsg_pid = 0;
l_hdr->nlmsg_seq = p_socket;
l_msg->rtgen_family = AF_UNSPEC;
struct sockaddr_nl l_addr;
memset(&l_addr, 0, sizeof(l_addr));
l_addr.nl_family = AF_NETLINK;
return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
}
static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
{
struct msghdr l_msg;
struct iovec l_iov = { p_buffer, p_len };
struct sockaddr_nl l_addr;
int l_result;
for(;;)
{
l_msg.msg_name = (void *)&l_addr;
l_msg.msg_namelen = sizeof(l_addr);
l_msg.msg_iov = &l_iov;
l_msg.msg_iovlen = 1;
l_msg.msg_control = NULL;
l_msg.msg_controllen = 0;
l_msg.msg_flags = 0;
int l_result = recvmsg(p_socket, &l_msg, 0);
if(l_result < 0)
{
if(errno == EINTR)
{
continue;
}
return -2;
}
if(l_msg.msg_flags & MSG_TRUNC)
{ // buffer was too small
return -1;
}
return l_result;
}
}
static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done)
{
size_t l_size = 4096;
void *l_buffer = NULL;
for(;;)
{
free(l_buffer);
l_buffer = malloc(l_size);
if (l_buffer == NULL)
{
return NULL;
}
int l_read = netlink_recv(p_socket, l_buffer, l_size);
*p_size = l_read;
if(l_read == -2)
{
free(l_buffer);
return NULL;
}
if(l_read >= 0)
{
pid_t l_pid = getpid();
struct nlmsghdr *l_hdr;
for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
{
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
if(l_hdr->nlmsg_type == NLMSG_DONE)
{
*p_done = 1;
break;
}
if(l_hdr->nlmsg_type == NLMSG_ERROR)
{
free(l_buffer);
return NULL;
}
}
return l_buffer;
}
l_size *= 2;
}
}
static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
{
NetlinkList *l_item = malloc(sizeof(NetlinkList));
if (l_item == NULL)
{
return NULL;
}
l_item->m_next = NULL;
l_item->m_data = p_data;
l_item->m_size = p_size;
return l_item;
}
static void freeResultList(NetlinkList *p_list)
{
NetlinkList *l_cur;
while(p_list)
{
l_cur = p_list;
p_list = p_list->m_next;
free(l_cur->m_data);
free(l_cur);
}
}
static NetlinkList *getResultList(int p_socket, int p_request)
{
if(netlink_send(p_socket, p_request) < 0)
{
return NULL;
}
NetlinkList *l_list = NULL;
NetlinkList *l_end = NULL;
int l_size;
int l_done = 0;
while(!l_done)
{
struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done);
if(!l_hdr)
{ // error
freeResultList(l_list);
return NULL;
}
NetlinkList *l_item = newListItem(l_hdr, l_size);
if (!l_item)
{
freeResultList(l_list);
return NULL;
}
if(!l_list)
{
l_list = l_item;
}
else
{
l_end->m_next = l_item;
}
l_end = l_item;
}
return l_list;
}
static size_t maxSize(size_t a, size_t b)
{
return (a > b ? a : b);
}
static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
{
switch(p_family)
{
case AF_INET:
return sizeof(struct sockaddr_in);
case AF_INET6:
return sizeof(struct sockaddr_in6);
case AF_PACKET:
return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
default:
return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
}
}
static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
{
switch(p_family)
{
case AF_INET:
memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
break;
case AF_INET6:
memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
break;
case AF_PACKET:
memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
break;
default:
memcpy(p_dest->sa_data, p_data, p_size);
break;
}
p_dest->sa_family = p_family;
}
static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
{
if(!*p_resultList)
{
*p_resultList = p_entry;
}
else
{
struct ifaddrs *l_cur = *p_resultList;
while(l_cur->ifa_next)
{
l_cur = l_cur->ifa_next;
}
l_cur->ifa_next = p_entry;
}
}
static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
{
struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
size_t l_nameSize = 0;
size_t l_addrSize = 0;
size_t l_dataSize = 0;
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
struct rtattr *l_rta;
for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
{
void *l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
switch(l_rta->rta_type)
{
case IFLA_ADDRESS:
case IFLA_BROADCAST:
l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
break;
case IFLA_IFNAME:
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
break;
case IFLA_STATS:
l_dataSize += NLMSG_ALIGN(l_rtaSize);
break;
default:
break;
}
}
struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
if (l_entry == NULL)
{
return -1;
}
memset(l_entry, 0, sizeof(struct ifaddrs));
l_entry->ifa_name = "";
char *l_index = ((char *)l_entry) + sizeof(struct ifaddrs);
char *l_name = l_index + sizeof(int);
char *l_addr = l_name + l_nameSize;
char *l_data = l_addr + l_addrSize;
// save the interface index so we can look it up when handling the addresses.
memcpy(l_index, &l_info->ifi_index, sizeof(int));
l_entry->ifa_flags = l_info->ifi_flags;
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
{
void *l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
switch(l_rta->rta_type)
{
case IFLA_ADDRESS:
case IFLA_BROADCAST:
{
size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
if(l_rta->rta_type == IFLA_ADDRESS)
{
l_entry->ifa_addr = (struct sockaddr *)l_addr;
}
else
{
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
}
l_addr += NLMSG_ALIGN(l_addrLen);
break;
}
case IFLA_IFNAME:
strncpy(l_name, l_rtaData, l_rtaDataSize);
l_name[l_rtaDataSize] = '\0';
l_entry->ifa_name = l_name;
break;
case IFLA_STATS:
memcpy(l_data, l_rtaData, l_rtaDataSize);
l_entry->ifa_data = l_data;
break;
default:
break;
}
}
addToEnd(p_resultList, l_entry);
return 0;
}
static struct ifaddrs *findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks)
{
int l_num = 0;
struct ifaddrs *l_cur = *p_links;
while(l_cur && l_num < p_numLinks)
{
char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs);
int l_index;
memcpy(&l_index, l_indexPtr, sizeof(int));
if(l_index == p_index)
{
return l_cur;
}
l_cur = l_cur->ifa_next;
++l_num;
}
return NULL;
}
static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks)
{
struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks);
size_t l_nameSize = 0;
size_t l_addrSize = 0;
int l_addedNetmask = 0;
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
struct rtattr *l_rta;
for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
{
void *l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
if(l_info->ifa_family == AF_PACKET)
{
continue;
}
switch(l_rta->rta_type)
{
case IFA_ADDRESS:
case IFA_LOCAL:
if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
{ // make room for netmask
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
l_addedNetmask = 1;
}
case IFA_BROADCAST:
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
break;
case IFA_LABEL:
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
break;
default:
break;
}
}
struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
if (l_entry == NULL)
{
return -1;
}
memset(l_entry, 0, sizeof(struct ifaddrs));
l_entry->ifa_name = (l_interface ? l_interface->ifa_name : "");
char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
char *l_addr = l_name + l_nameSize;
l_entry->ifa_flags = l_info->ifa_flags;
if(l_interface)
{
l_entry->ifa_flags |= l_interface->ifa_flags;
}
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
{
void *l_rtaData = RTA_DATA(l_rta);
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
switch(l_rta->rta_type)
{
case IFA_ADDRESS:
case IFA_BROADCAST:
case IFA_LOCAL:
{
size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
if(l_info->ifa_family == AF_INET6)
{
if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
{
((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
}
}
if(l_rta->rta_type == IFA_ADDRESS)
{ // apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address
if(l_entry->ifa_addr)
{
l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
}
else
{
l_entry->ifa_addr = (struct sockaddr *)l_addr;
}
}
else if(l_rta->rta_type == IFA_LOCAL)
{
if(l_entry->ifa_addr)
{
l_entry->ifa_dstaddr = l_entry->ifa_addr;
}
l_entry->ifa_addr = (struct sockaddr *)l_addr;
}
else
{
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
}
l_addr += NLMSG_ALIGN(l_addrLen);
break;
}
case IFA_LABEL:
strncpy(l_name, l_rtaData, l_rtaDataSize);
l_name[l_rtaDataSize] = '\0';
l_entry->ifa_name = l_name;
break;
default:
break;
}
}
if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
{
unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
char l_mask[16] = {0};
unsigned i;
for(i=0; i<(l_prefix/8); ++i)
{
l_mask[i] = 0xff;
}
if(l_prefix % 8)
{
l_mask[i] = 0xff << (8 - (l_prefix % 8));
}
makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
l_entry->ifa_netmask = (struct sockaddr *)l_addr;
}
addToEnd(p_resultList, l_entry);
return 0;
}
static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList)
{
int l_numLinks = 0;
pid_t l_pid = getpid();
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
{
unsigned int l_nlsize = p_netlinkList->m_size;
struct nlmsghdr *l_hdr;
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
{
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
if(l_hdr->nlmsg_type == NLMSG_DONE)
{
break;
}
if(l_hdr->nlmsg_type == RTM_NEWLINK)
{
if(interpretLink(l_hdr, p_resultList) == -1)
{
return -1;
}
++l_numLinks;
}
}
}
return l_numLinks;
}
static int interpretAddrs(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks)
{
pid_t l_pid = getpid();
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
{
unsigned int l_nlsize = p_netlinkList->m_size;
struct nlmsghdr *l_hdr;
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
{
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
if(l_hdr->nlmsg_type == NLMSG_DONE)
{
break;
}
if(l_hdr->nlmsg_type == RTM_NEWADDR)
{
if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1)
{
return -1;
}
}
}
}
return 0;
}
int getifaddrs(struct ifaddrs **ifap)
{
if(!ifap)
{
return -1;
}
*ifap = NULL;
int l_socket = netlink_socket();
if(l_socket < 0)
{
return -1;
}
NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK);
if(!l_linkResults)
{
close(l_socket);
return -1;
}
NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR);
if(!l_addrResults)
{
close(l_socket);
freeResultList(l_linkResults);
return -1;
}
int l_result = 0;
int l_numLinks = interpretLinks(l_socket, l_linkResults, ifap);
if(l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1)
{
l_result = -1;
}
freeResultList(l_linkResults);
freeResultList(l_addrResults);
close(l_socket);
return l_result;
}
void freeifaddrs(struct ifaddrs *ifa)
{
struct ifaddrs *l_cur;
while(ifa)
{
l_cur = ifa;
ifa = ifa->ifa_next;
free(l_cur);
}
}
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright (c) 1995, 1999
* Berkeley Software Design, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
*/
#ifndef _IFADDRS_H_
#define _IFADDRS_H_
struct ifaddrs {
struct ifaddrs *ifa_next;
char *ifa_name;
unsigned int ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
void *ifa_data;
};
/*
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
* to be included it must be included before this header file.
*/
#ifndef ifa_broadaddr
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
#endif
#include <sys/cdefs.h>
__BEGIN_DECLS
extern int getifaddrs(struct ifaddrs **ifap);
extern void freeifaddrs(struct ifaddrs *ifa);
__END_DECLS
#endif
+526
View File
@@ -0,0 +1,526 @@
Libwebsockets and included programs are provided under the terms of the GNU
Library General Public License (LGPL) 2.1, with the following exceptions:
1) Static linking of programs with the libwebsockets library does not
constitute a derivative work and does not require the author to provide
source code for the program, use the shared libwebsockets libraries, or
link their program against a user-supplied version of libwebsockets.
If you link the program to a modified version of libwebsockets, then the
changes to libwebsockets must be provided under the terms of the LGPL in
sections 1, 2, and 4.
2) You do not have to provide a copy of the libwebsockets license with
programs that are linked to the libwebsockets library, nor do you have to
identify the libwebsockets license in your program or documentation as
required by section 6 of the LGPL.
However, programs must still identify their use of libwebsockets. The
following example statement can be included in user documentation to
satisfy this requirement:
"[program] is based in part on the work of the libwebsockets project
(http://libwebsockets.org)"
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
+20
View File
@@ -0,0 +1,20 @@
This is the libwebsockets C library for lightweight websocket clients and
servers. For support, visit
http://libwebsockets.org
and consider joining the project mailing list at
http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
You can get the latest version of the library from git
http://git.libwebsockets.org
https://github.com/warmcat/libwebsockets
for more information:
README.build - information on building the library
README.coding - information for writing code using the library
README.test-apps - information about the test apps built with the library
+93
View File
@@ -0,0 +1,93 @@
/*
* This code originally came from here
*
* http://base64.sourceforge.net/b64.c
*
* with the following license:
*
* LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the
* Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall
* be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* VERSION HISTORY:
* Bob Trower 08/04/01 -- Create Version 0.00.00B
*
* I cleaned it up quite a bit to match the (linux kernel) style of the rest
* of libwebsockets; this version is under LGPL2 like the rest of libwebsockets
* since he explictly allows sublicensing, but I give the URL above so you can
* get the original with Bob's super-liberal terms directly if you prefer.
*/
#include <stdio.h>
#include <string.h>
#include "private-libwebsockets.h"
static const char encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz0123456789+/";
static const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW"
"$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
LWS_VISIBLE int
lws_b64_encode_string(const char *in, int in_len, char *out, int out_size)
{
unsigned char triple[3];
int i;
int len;
int line = 0;
int done = 0;
while (in_len) {
len = 0;
for (i = 0; i < 3; i++) {
if (in_len) {
triple[i] = *in++;
len++;
in_len--;
} else
triple[i] = 0;
}
if (!len)
continue;
if (done + 4 >= out_size)
return -1;
*out++ = encode[triple[0] >> 2];
*out++ = encode[((triple[0] & 0x03) << 4) |
((triple[1] & 0xf0) >> 4)];
*out++ = (len > 1 ? encode[((triple[1] & 0x0f) << 2) |
((triple[2] & 0xc0) >> 6)] : '=');
*out++ = (len > 2 ? encode[triple[2] & 0x3f] : '=');
done += 4;
line += 4;
}
if (done + 1 >= out_size)
return -1;
*out++ = '\0';
return done;
}
+441
View File
@@ -0,0 +1,441 @@
#include "private-libwebsockets.h"
struct libwebsocket *libwebsocket_client_connect_2(
struct libwebsocket_context *context,
struct libwebsocket *wsi
) {
struct libwebsocket_pollfd pfd;
#ifdef LWS_USE_IPV6
struct sockaddr_in6 server_addr6;
struct sockaddr_in6 client_addr6;
struct addrinfo hints, *result;
#endif
struct sockaddr_in server_addr4;
struct sockaddr_in client_addr4;
struct hostent *server_hostent;
struct sockaddr *v;
int n;
int plen = 0;
const char *ads;
lwsl_client("libwebsocket_client_connect_2\n");
/*
* proxy?
*/
if (context->http_proxy_port) {
plen = sprintf((char *)context->service_buffer,
"CONNECT %s:%u HTTP/1.0\x0d\x0a"
"User-agent: libwebsockets\x0d\x0a"
/*Proxy-authorization: basic aGVsbG86d29ybGQ= */
"\x0d\x0a",
lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS),
wsi->u.hdr.ah->c_port);
ads = context->http_proxy_address;
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context))
server_addr6.sin6_port = htons(context->http_proxy_port);
else
#endif
server_addr4.sin_port = htons(context->http_proxy_port);
} else {
ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS);
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context))
server_addr6.sin6_port = htons(wsi->u.hdr.ah->c_port);
else
#endif
server_addr4.sin_port = htons(wsi->u.hdr.ah->c_port);
}
/*
* prepare the actual connection (to the proxy, if any)
*/
lwsl_client("libwebsocket_client_connect_2: address %s\n", ads);
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) {
memset(&hints, 0, sizeof(struct addrinfo));
n = getaddrinfo(ads, NULL, &hints, &result);
if (n) {
#ifdef _WIN32
lwsl_err("getaddrinfo: %ls\n", gai_strerrorW(n));
#else
lwsl_err("getaddrinfo: %s\n", gai_strerror(n));
#endif
goto oom4;
}
server_addr6.sin6_family = AF_INET6;
switch (result->ai_family) {
case AF_INET:
/* map IPv4 to IPv6 */
bzero((char *)&server_addr6.sin6_addr,
sizeof(struct in6_addr));
server_addr6.sin6_addr.s6_addr[10] = 0xff;
server_addr6.sin6_addr.s6_addr[11] = 0xff;
memcpy(&server_addr6.sin6_addr.s6_addr[12],
&((struct sockaddr_in *)result->ai_addr)->sin_addr,
sizeof(struct in_addr));
break;
case AF_INET6:
memcpy(&server_addr6.sin6_addr,
&((struct sockaddr_in6 *)result->ai_addr)->sin6_addr,
sizeof(struct in6_addr));
break;
default:
lwsl_err("Unknown address family\n");
freeaddrinfo(result);
goto oom4;
}
freeaddrinfo(result);
} else
#endif
{
server_hostent = gethostbyname(ads);
if (!server_hostent) {
lwsl_err("Unable to get host name from %s\n", ads);
goto oom4;
}
server_addr4.sin_family = AF_INET;
server_addr4.sin_addr =
*((struct in_addr *)server_hostent->h_addr);
bzero(&server_addr4.sin_zero, 8);
}
if (wsi->sock < 0) {
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context))
wsi->sock = socket(AF_INET6, SOCK_STREAM, 0);
else
#endif
wsi->sock = socket(AF_INET, SOCK_STREAM, 0);
if (wsi->sock < 0) {
lwsl_warn("Unable to open socket\n");
goto oom4;
}
if (lws_plat_set_socket_options(context, wsi->sock)) {
lwsl_err("Failed to set wsi socket options\n");
compatible_close(wsi->sock);
goto oom4;
}
wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT;
insert_wsi_socket_into_fds(context, wsi);
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE,
AWAITING_TIMEOUT);
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) {
v = (struct sockaddr *)&client_addr6;
n = sizeof(client_addr6);
bzero((char *)v, n);
client_addr6.sin6_family = AF_INET6;
} else
#endif
{
v = (struct sockaddr *)&client_addr4;
n = sizeof(client_addr4);
bzero((char *)v, n);
client_addr4.sin_family = AF_INET;
}
if (context->iface) {
if (interface_to_sa(context, context->iface,
(struct sockaddr_in *)v, n) < 0) {
lwsl_err("Unable to find interface %s\n",
context->iface);
compatible_close(wsi->sock);
goto failed;
}
if (bind(wsi->sock, v, n) < 0) {
lwsl_err("Error binding to interface %s",
context->iface);
compatible_close(wsi->sock);
goto failed;
}
}
}
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) {
v = (struct sockaddr *)&server_addr6;
n = sizeof(struct sockaddr_in6);
} else
#endif
{
v = (struct sockaddr *)&server_addr4;
n = sizeof(struct sockaddr);
}
if (connect(wsi->sock, v, n) == -1 || LWS_ERRNO == LWS_EISCONN) {
if (LWS_ERRNO == LWS_EALREADY || LWS_ERRNO == LWS_EINPROGRESS
|| LWS_ERRNO == LWS_EWOULDBLOCK) {
lwsl_client("nonblocking connect retry\n");
/*
* must do specifically a POLLOUT poll to hear
* about the connect completion
*/
if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
goto oom4;
return wsi;
}
if (LWS_ERRNO != LWS_EISCONN) {
lwsl_debug("Connect failed errno=%d\n", LWS_ERRNO);
goto failed;
}
}
lwsl_client("connected\n");
/* we are connected to server, or proxy */
if (context->http_proxy_port) {
/* OK from now on we talk via the proxy, so connect to that */
/*
* (will overwrite existing pointer,
* leaving old string/frag there but unreferenced)
*/
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS,
context->http_proxy_address))
goto failed;
wsi->u.hdr.ah->c_port = context->http_proxy_port;
n = send(wsi->sock, context->service_buffer, plen, MSG_NOSIGNAL);
if (n < 0) {
lwsl_debug("ERROR writing to proxy socket\n");
goto failed;
}
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE,
AWAITING_TIMEOUT);
wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY;
return wsi;
}
/*
* provoke service to issue the handshake directly
* we need to do it this way because in the proxy case, this is the
* next state and executed only if and when we get a good proxy
* response inside the state machine... but notice in SSL case this
* may not have sent anything yet with 0 return, and won't until some
* many retries from main loop. To stop that becoming endless,
* cover with a timeout.
*/
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, AWAITING_TIMEOUT);
wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE;
pfd.fd = wsi->sock;
pfd.revents = LWS_POLLIN;
n = libwebsocket_service_fd(context, &pfd);
if (n < 0)
goto failed;
if (n) /* returns 1 on failure after closing wsi */
return NULL;
return wsi;
oom4:
free(wsi->u.hdr.ah);
free(wsi);
return NULL;
failed:
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return NULL;
}
/**
* libwebsocket_client_connect() - Connect to another websocket server
* @context: Websocket context
* @address: Remote server address, eg, "myserver.com"
* @port: Port to connect to on the remote server, eg, 80
* @ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
* signed certs
* @path: Websocket path on server
* @host: Hostname on server
* @origin: Socket origin name
* @protocol: Comma-separated list of protocols being asked for from
* the server, or just one. The server will pick the one it
* likes best.
* @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
* protocol supported, or the specific protocol ordinal
*
* This function creates a connection to a remote server
*/
LWS_VISIBLE struct libwebsocket *
libwebsocket_client_connect(struct libwebsocket_context *context,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one)
{
struct libwebsocket *wsi;
wsi = (struct libwebsocket *) malloc(sizeof(struct libwebsocket));
if (wsi == NULL)
goto bail;
memset(wsi, 0, sizeof(*wsi));
wsi->sock = -1;
/* -1 means just use latest supported */
if (ietf_version_or_minus_one == -1)
ietf_version_or_minus_one = SPEC_LATEST_SUPPORTED;
wsi->ietf_spec_revision = ietf_version_or_minus_one;
wsi->user_space = NULL;
wsi->state = WSI_STATE_CLIENT_UNCONNECTED;
wsi->protocol = NULL;
wsi->pending_timeout = NO_PENDING_TIMEOUT;
#ifdef LWS_OPENSSL_SUPPORT
wsi->use_ssl = ssl_connection;
#else
if (ssl_connection) {
lwsl_err("libwebsockets not configured for ssl\n");
goto bail;
}
#endif
if (lws_allocate_header_table(wsi))
goto bail;
/*
* we're not necessarily in a position to action these right away,
* stash them... we only need during connect phase so u.hdr is fine
*/
wsi->u.hdr.ah->c_port = port;
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
goto bail1;
/* these only need u.hdr lifetime as well */
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, path))
goto bail1;
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
goto bail1;
if (origin)
if (lws_hdr_simple_create(wsi,
_WSI_TOKEN_CLIENT_ORIGIN, origin))
goto bail1;
/*
* this is a list of protocols we tell the server we're okay with
* stash it for later when we compare server response with it
*/
if (protocol)
if (lws_hdr_simple_create(wsi,
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS, protocol))
goto bail1;
wsi->protocol = &context->protocols[0];
/*
* Check with each extension if it is able to route and proxy this
* connection for us. For example, an extension like x-google-mux
* can handle this and then we don't need an actual socket for this
* connection.
*/
if (lws_ext_callback_for_each_extension_type(context, wsi,
LWS_EXT_CALLBACK_CAN_PROXY_CLIENT_CONNECTION,
(void *)address, port) > 0) {
lwsl_client("libwebsocket_client_connect: ext handling conn\n");
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_AWAITING_EXTENSION_CONNECT_RESPONSE,
AWAITING_TIMEOUT);
wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT;
return wsi;
}
lwsl_client("libwebsocket_client_connect: direct conn\n");
return libwebsocket_client_connect_2(context, wsi);
bail1:
free(wsi->u.hdr.ah);
bail:
free(wsi);
return NULL;
}
/**
* libwebsocket_client_connect_extended() - Connect to another websocket server
* @context: Websocket context
* @address: Remote server address, eg, "myserver.com"
* @port: Port to connect to on the remote server, eg, 80
* @ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self
* signed certs
* @path: Websocket path on server
* @host: Hostname on server
* @origin: Socket origin name
* @protocol: Comma-separated list of protocols being asked for from
* the server, or just one. The server will pick the one it
* likes best.
* @ietf_version_or_minus_one: -1 to ask to connect using the default, latest
* protocol supported, or the specific protocol ordinal
* @userdata: Pre-allocated user data
*
* This function creates a connection to a remote server
*/
LWS_VISIBLE struct libwebsocket *
libwebsocket_client_connect_extended(struct libwebsocket_context *context,
const char *address,
int port,
int ssl_connection,
const char *path,
const char *host,
const char *origin,
const char *protocol,
int ietf_version_or_minus_one,
void *userdata)
{
struct libwebsocket *ws =
libwebsocket_client_connect(context, address, port,
ssl_connection, path, host, origin, protocol,
ietf_version_or_minus_one);
if (ws && !ws->user_space && userdata)
ws->user_space = userdata ;
return ws ;
}
+402
View File
@@ -0,0 +1,402 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
int libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c)
{
int callback_action = LWS_CALLBACK_CLIENT_RECEIVE;
int handled;
struct lws_tokens eff_buf;
int m;
switch (wsi->lws_rx_parse_state) {
case LWS_RXPS_NEW:
switch (wsi->ietf_spec_revision) {
case 13:
wsi->u.ws.opcode = c & 0xf;
wsi->u.ws.rsv = (c & 0x70);
wsi->u.ws.final = !!((c >> 7) & 1);
switch (wsi->u.ws.opcode) {
case LWS_WS_OPCODE_07__TEXT_FRAME:
case LWS_WS_OPCODE_07__BINARY_FRAME:
wsi->u.ws.frame_is_binary = wsi->u.ws.opcode ==
LWS_WS_OPCODE_07__BINARY_FRAME;
break;
}
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
break;
default:
lwsl_err("unknown spec version %02d\n",
wsi->ietf_spec_revision);
break;
}
break;
case LWS_RXPS_04_FRAME_HDR_LEN:
wsi->u.ws.this_frame_masked = !!(c & 0x80);
switch (c & 0x7f) {
case 126:
/* control frames are not allowed to have big lengths */
if (wsi->u.ws.opcode & 8)
goto illegal_ctl_length;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
break;
case 127:
/* control frames are not allowed to have big lengths */
if (wsi->u.ws.opcode & 8)
goto illegal_ctl_length;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
break;
default:
wsi->u.ws.rx_packet_length = c;
if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else {
if (c)
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
else {
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
}
break;
}
break;
case LWS_RXPS_04_FRAME_HDR_LEN16_2:
wsi->u.ws.rx_packet_length = c << 8;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
break;
case LWS_RXPS_04_FRAME_HDR_LEN16_1:
wsi->u.ws.rx_packet_length |= c;
if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else {
if (wsi->u.ws.rx_packet_length)
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
else {
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
}
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_8:
if (c & 0x80) {
lwsl_warn("b63 of length must be zero\n");
/* kill the connection */
return -1;
}
#if defined __LP64__
wsi->u.ws.rx_packet_length = ((size_t)c) << 56;
#else
wsi->u.ws.rx_packet_length = 0;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_7:
#if defined __LP64__
wsi->u.ws.rx_packet_length |= ((size_t)c) << 48;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_6:
#if defined __LP64__
wsi->u.ws.rx_packet_length |= ((size_t)c) << 40;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_5:
#if defined __LP64__
wsi->u.ws.rx_packet_length |= ((size_t)c) << 32;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_4:
wsi->u.ws.rx_packet_length |= ((size_t)c) << 24;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_3:
wsi->u.ws.rx_packet_length |= ((size_t)c) << 16;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_2:
wsi->u.ws.rx_packet_length |= ((size_t)c) << 8;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_1:
wsi->u.ws.rx_packet_length |= (size_t)c;
if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else {
if (wsi->u.ws.rx_packet_length)
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
else {
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
}
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
wsi->u.ws.frame_masking_nonce_04[0] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
wsi->u.ws.frame_masking_nonce_04[1] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
wsi->u.ws.frame_masking_nonce_04[2] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
wsi->u.ws.frame_masking_nonce_04[3] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
if (wsi->u.ws.rx_packet_length)
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
else {
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
break;
case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
if (!wsi->u.ws.rx_user_buffer)
lwsl_err("NULL client rx_user_buffer\n");
if ((!wsi->u.ws.this_frame_masked) || wsi->u.ws.all_zero_nonce)
wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
(wsi->u.ws.rx_user_buffer_head++)] = c;
else
wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
(wsi->u.ws.rx_user_buffer_head++)] =
c ^ wsi->u.ws.frame_masking_nonce_04[
(wsi->u.ws.frame_mask_index++) & 3];
if (--wsi->u.ws.rx_packet_length == 0) {
/* spill because we have the whole frame */
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
/*
* if there's no protocol max frame size given, we are
* supposed to default to LWS_MAX_SOCKET_IO_BUF
*/
if (!wsi->protocol->rx_buffer_size &&
wsi->u.ws.rx_user_buffer_head !=
LWS_MAX_SOCKET_IO_BUF)
break;
else
if (wsi->protocol->rx_buffer_size &&
wsi->u.ws.rx_user_buffer_head !=
wsi->protocol->rx_buffer_size)
break;
/* spill because we filled our rx buffer */
spill:
handled = 0;
/*
* is this frame a control packet we should take care of at this
* layer? If so service it and hide it from the user callback
*/
switch (wsi->u.ws.opcode) {
case LWS_WS_OPCODE_07__CLOSE:
/* is this an acknowledgement of our close? */
if (wsi->state == WSI_STATE_AWAITING_CLOSE_ACK) {
/*
* fine he has told us he is closing too, let's
* finish our close
*/
lwsl_parser("seen server's close ack\n");
return -1;
}
lwsl_parser("client sees server close len = %d\n",
wsi->u.ws.rx_user_buffer_head);
/*
* parrot the close packet payload back
* we do not care about how it went, we are closing
* immediately afterwards
*/
libwebsocket_write(wsi, (unsigned char *)
&wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING],
wsi->u.ws.rx_user_buffer_head, LWS_WRITE_CLOSE);
wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY;
/* close the connection */
return -1;
case LWS_WS_OPCODE_07__PING:
lwsl_info("client received ping, doing pong\n");
/*
* parrot the ping packet payload back as a pong
* !!! this may block or have partial write or fail
* !!! very unlikely if the ping size is small
*/
libwebsocket_write(wsi, (unsigned char *)
&wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING],
wsi->u.ws.rx_user_buffer_head,
LWS_WRITE_PONG);
handled = 1;
break;
case LWS_WS_OPCODE_07__PONG:
lwsl_info("client receied pong\n");
lwsl_hexdump(&wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING],
wsi->u.ws.rx_user_buffer_head);
/* issue it */
callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG;
break;
case LWS_WS_OPCODE_07__CONTINUATION:
case LWS_WS_OPCODE_07__TEXT_FRAME:
case LWS_WS_OPCODE_07__BINARY_FRAME:
break;
default:
lwsl_parser("Reserved opc 0x%2X\n", wsi->u.ws.opcode);
/*
* It's something special we can't understand here.
* Pass the payload up to the extension's parsing
* state machine.
*/
eff_buf.token = &wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING];
eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
if (lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX,
&eff_buf, 0) <= 0) { /* not handle or fail */
lwsl_ext("Unhandled ext opc 0x%x\n",
wsi->u.ws.opcode);
wsi->u.ws.rx_user_buffer_head = 0;
return 0;
}
handled = 1;
break;
}
/*
* No it's real payload, pass it up to the user callback.
* It's nicely buffered with the pre-padding taken care of
* so it can be sent straight out again using libwebsocket_write
*/
if (handled)
goto already_done;
eff_buf.token = &wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING];
eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
if (lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_PAYLOAD_RX,
&eff_buf, 0) < 0) /* fail */
return -1;
if (eff_buf.token_len <= 0 &&
callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG)
goto already_done;
eff_buf.token[eff_buf.token_len] = '\0';
if (!wsi->protocol->callback)
goto already_done;
if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG)
lwsl_info("Client doing pong callback\n");
m = wsi->protocol->callback(
wsi->protocol->owning_server,
wsi,
(enum libwebsocket_callback_reasons)callback_action,
wsi->user_space,
eff_buf.token,
eff_buf.token_len);
/* if user code wants to close, let caller know */
if (m)
return 1;
already_done:
wsi->u.ws.rx_user_buffer_head = 0;
break;
default:
lwsl_err("client rx illegal state\n");
return 1;
}
return 0;
illegal_ctl_length:
lwsl_warn("Control frame asking for extended length is illegal\n");
/* kill the connection */
return -1;
}
+954
View File
@@ -0,0 +1,954 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
int lws_handshake_client(struct libwebsocket *wsi, unsigned char **buf, size_t len)
{
int n;
switch (wsi->mode) {
case LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY:
case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE:
case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY:
case LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT:
case LWS_CONNMODE_WS_CLIENT:
for (n = 0; n < len; n++)
if (libwebsocket_client_rx_sm(wsi, *(*buf)++)) {
lwsl_debug("client_rx_sm failed\n");
return 1;
}
return 0;
default:
break;
}
return 0;
}
int lws_client_socket_service(struct libwebsocket_context *context,
struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd)
{
int n;
char *p = (char *)&context->service_buffer[0];
int len;
unsigned char c;
switch (wsi->mode) {
case LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT:
/*
* we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
* timeout protection set in client-handshake.c
*/
if (libwebsocket_client_connect_2(context, wsi) == NULL) {
/* closed */
lwsl_client("closed\n");
return -1;
}
/* either still pending connection, or changed mode */
return 0;
case LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY:
/* handle proxy hung up on us */
if (pollfd->revents & LWS_POLLHUP) {
lwsl_warn("Proxy connection %p (fd=%d) dead\n",
(void *)wsi, pollfd->fd);
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return 0;
}
n = recv(wsi->sock, context->service_buffer,
sizeof(context->service_buffer), 0);
if (n < 0) {
if (LWS_ERRNO == LWS_EAGAIN) {
lwsl_debug(
"Proxy read returned EAGAIN... retrying\n");
return 0;
}
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
lwsl_err("ERROR reading from proxy socket\n");
return 0;
}
context->service_buffer[13] = '\0';
if (strcmp((char *)context->service_buffer, "HTTP/1.0 200 ")) {
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
lwsl_err("ERROR proxy: %s\n", context->service_buffer);
return 0;
}
/* clear his proxy connection timeout */
libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
/* fallthru */
case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE:
/*
* we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
* timeout protection set in client-handshake.c
*/
/*
* take care of our libwebsocket_callback_on_writable
* happening at a time when there's no real connection yet
*/
if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
return -1;
#ifdef LWS_OPENSSL_SUPPORT
/* we can retry this... just cook the SSL BIO the first time */
if (wsi->use_ssl && !wsi->ssl) {
const char *hostname = lws_hdr_simple_ptr(wsi,
_WSI_TOKEN_CLIENT_PEER_ADDRESS);
wsi->ssl = SSL_new(context->ssl_client_ctx);
#ifndef USE_CYASSL
SSL_set_mode(wsi->ssl,
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif
/*
* use server name indication (SNI), if supported,
* when establishing connection
*/
#ifdef USE_CYASSL
#ifdef CYASSL_SNI_HOST_NAME
CyaSSL_UseSNI(wsi->ssl, CYASSL_SNI_HOST_NAME,
hostname, strlen(hostname));
#endif
#else
SSL_set_tlsext_host_name(wsi->ssl, hostname);
#endif
#ifdef USE_CYASSL
/*
* CyaSSL does certificate verification differently
* from OpenSSL.
* If we should ignore the certificate, we need to set
* this before SSL_new and SSL_connect is called.
* Otherwise the connect will simply fail with error
* code -155
*/
if (wsi->use_ssl == 2)
CyaSSL_set_verify(wsi->ssl,
SSL_VERIFY_NONE, NULL);
#endif /* USE_CYASSL */
wsi->client_bio =
BIO_new_socket(wsi->sock, BIO_NOCLOSE);
SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
#ifdef USE_CYASSL
CyaSSL_set_using_nonblock(wsi->ssl, 1);
#else
BIO_set_nbio(wsi->client_bio, 1); /* nonblocking */
#endif
SSL_set_ex_data(wsi->ssl,
openssl_websocket_private_data_index,
context);
}
if (wsi->use_ssl) {
lws_latency_pre(context, wsi);
n = SSL_connect(wsi->ssl);
lws_latency(context, wsi,
"SSL_connect LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE",
n, n > 0);
if (n < 0) {
n = SSL_get_error(wsi->ssl, n);
if (n == SSL_ERROR_WANT_READ ||
n == SSL_ERROR_WANT_WRITE) {
/*
* wants us to retry connect due to
* state of the underlying ssl layer...
* but since it may be stalled on
* blocked write, no incoming data may
* arrive to trigger the retry.
* Force (possibly many times if the SSL
* state persists in returning the
* condition code, but other sockets
* are getting serviced inbetweentimes)
* us to get called back when writable.
*/
lwsl_info(
"SSL_connect WANT_... retrying\n");
libwebsocket_callback_on_writable(
context, wsi);
wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SSL;
return 0; /* no error */
}
n = -1;
}
if (n <= 0) {
/*
* retry if new data comes until we
* run into the connection timeout or win
*/
n = ERR_get_error();
if (n != SSL_ERROR_NONE) {
lwsl_err("SSL connect error %lu: %s\n",
n,
ERR_error_string(n,
(char *)context->service_buffer));
return 0;
}
}
} else
wsi->ssl = NULL;
/* fallthru */
case LWS_CONNMODE_WS_CLIENT_WAITING_SSL:
if (wsi->use_ssl) {
if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_SSL) {
lws_latency_pre(context, wsi);
n = SSL_connect(wsi->ssl);
lws_latency(context, wsi,
"SSL_connect LWS_CONNMODE_WS_CLIENT_WAITING_SSL",
n, n > 0);
if (n < 0) {
n = SSL_get_error(wsi->ssl, n);
if (n == SSL_ERROR_WANT_READ ||
n == SSL_ERROR_WANT_WRITE) {
/*
* wants us to retry connect due to
* state of the underlying ssl layer...
* but since it may be stalled on
* blocked write, no incoming data may
* arrive to trigger the retry.
* Force (possibly many times if the SSL
* state persists in returning the
* condition code, but other sockets
* are getting serviced inbetweentimes)
* us to get called back when writable.
*/
lwsl_info(
"SSL_connect WANT_... retrying\n");
libwebsocket_callback_on_writable(
context, wsi);
wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SSL;
return 0; /* no error */
}
n = -1;
}
if (n <= 0) {
/*
* retry if new data comes until we
* run into the connection timeout or win
*/
n = ERR_get_error();
if (n != SSL_ERROR_NONE) {
lwsl_err("SSL connect error %lu: %s\n",
n,
ERR_error_string(n,
(char *)context->service_buffer));
return 0;
}
}
}
#ifndef USE_CYASSL
/*
* See comment above about CyaSSL certificate
* verification
*/
lws_latency_pre(context, wsi);
n = SSL_get_verify_result(wsi->ssl);
lws_latency(context, wsi,
"SSL_get_verify_result LWS_CONNMODE..HANDSHAKE",
n, n > 0);
if ((n != X509_V_OK) && (
n != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
wsi->use_ssl != 2)) {
lwsl_err(
"server's cert didn't look good %d\n", n);
libwebsocket_close_and_free_session(context,
wsi, LWS_CLOSE_STATUS_NOSTATUS);
return 0;
}
#endif /* USE_CYASSL */
} else
wsi->ssl = NULL;
#endif
wsi->mode = LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2;
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND,
AWAITING_TIMEOUT);
/* fallthru */
case LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2:
p = libwebsockets_generate_client_handshake(context, wsi, p);
if (p == NULL) {
lwsl_err("Failed to generate handshake for client\n");
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return 0;
}
/* send our request to the server */
lws_latency_pre(context, wsi);
n = lws_ssl_capable_write(wsi, context->service_buffer, p - (char *)context->service_buffer);
lws_latency(context, wsi, "send lws_issue_raw", n, n == p - (char *)context->service_buffer);
switch (n) {
case LWS_SSL_CAPABLE_ERROR:
lwsl_debug("ERROR writing to client socket\n");
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return 0;
case LWS_SSL_CAPABLE_MORE_SERVICE:
libwebsocket_callback_on_writable(context, wsi);
break;
}
wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
wsi->u.hdr.lextable_pos = 0;
wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY;
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
AWAITING_TIMEOUT);
break;
case LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY:
/* handle server hung up on us */
if (pollfd->revents & LWS_POLLHUP) {
lwsl_debug("Server connection %p (fd=%d) dead\n",
(void *)wsi, pollfd->fd);
goto bail3;
}
if (!(pollfd->revents & LWS_POLLIN))
break;
/* interpret the server response */
/*
* HTTP/1.1 101 Switching Protocols
* Upgrade: websocket
* Connection: Upgrade
* Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
* Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
* Sec-WebSocket-Protocol: chat
*/
/*
* we have to take some care here to only take from the
* socket bytewise. The browser may (and has been seen to
* in the case that onopen() performs websocket traffic)
* coalesce both handshake response and websocket traffic
* in one packet, since at that point the connection is
* definitively ready from browser pov.
*/
len = 1;
while (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE &&
len > 0) {
n = lws_ssl_capable_read(wsi, &c, 1);
lws_latency(context, wsi, "send lws_issue_raw", n, n == 1);
switch (n) {
case LWS_SSL_CAPABLE_ERROR:
goto bail3;
case LWS_SSL_CAPABLE_MORE_SERVICE:
return 0;
}
if (libwebsocket_parse(wsi, c)) {
lwsl_warn("problems parsing header\n");
goto bail3;
}
}
/*
* hs may also be coming in multiple packets, there is a 5-sec
* libwebsocket timeout still active here too, so if parsing did
* not complete just wait for next packet coming in this state
*/
if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
break;
/*
* otherwise deal with the handshake. If there's any
* packet traffic already arrived we'll trigger poll() again
* right away and deal with it that way
*/
return lws_client_interpret_server_handshake(context, wsi);
bail3:
lwsl_info(
"closing connection at LWS_CONNMODE...SERVER_REPLY\n");
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return -1;
case LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT:
lwsl_ext("LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT\n");
break;
case LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD:
lwsl_ext("LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD\n");
break;
default:
break;
}
return 0;
}
/*
* In-place str to lower case
*/
static void
strtolower(char *s)
{
while (*s) {
*s = tolower((int)*s);
s++;
}
}
int
lws_client_interpret_server_handshake(struct libwebsocket_context *context,
struct libwebsocket *wsi)
{
const char *pc;
int okay = 0;
char *p;
int len;
#ifndef LWS_NO_EXTENSIONS
char ext_name[128];
struct libwebsocket_extension *ext;
void *v;
int more = 1;
const char *c;
#endif
int n;
int close_reason = LWS_CLOSE_STATUS_PROTOCOL_ERR;
/*
* well, what the server sent looked reasonable for syntax.
* Now let's confirm it sent all the necessary headers
*/
if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) {
lwsl_info("no ACCEPT\n");
goto bail3;
}
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP);
if (!p) {
lwsl_info("no URI\n");
goto bail3;
}
if (p && strncmp(p, "101", 3)) {
lwsl_warn(
"lws_client_handshake: got bad HTTP response '%s'\n", p);
goto bail3;
}
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE);
if (!p) {
lwsl_info("no UPGRADE\n");
goto bail3;
}
strtolower(p);
if (strcmp(p, "websocket")) {
lwsl_warn(
"lws_client_handshake: got bad Upgrade header '%s'\n", p);
goto bail3;
}
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_CONNECTION);
if (!p) {
lwsl_info("no Connection hdr\n");
goto bail3;
}
strtolower(p);
if (strcmp(p, "upgrade")) {
lwsl_warn("lws_client_int_s_hs: bad header %s\n", p);
goto bail3;
}
pc = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
if (pc == NULL)
lwsl_parser("lws_client_int_s_hs: no protocol list\n");
else
lwsl_parser("lws_client_int_s_hs: protocol list '%s'\n", pc);
/*
* confirm the protocol the server wants to talk was in the list
* of protocols we offered
*/
len = lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL);
if (!len) {
lwsl_info("lws_client_int_s_hs: WSI_TOKEN_PROTOCOL is null\n");
/*
* no protocol name to work from,
* default to first protocol
*/
wsi->protocol = &context->protocols[0];
goto check_extensions;
}
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL);
len = strlen(p);
while (*pc && !okay) {
if (!strncmp(pc, p, len) &&
(pc[len] == ',' || pc[len] == '\0')) {
okay = 1;
continue;
}
while (*pc && *pc != ',')
pc++;
while (*pc && *pc != ' ')
pc++;
}
if (!okay) {
lwsl_err("lws_client_int_s_hs: got bad protocol %s\n", p);
goto bail2;
}
/*
* identify the selected protocol struct and set it
*/
n = 0;
wsi->protocol = NULL;
while (context->protocols[n].callback && !wsi->protocol) {
if (strcmp(p, context->protocols[n].name) == 0) {
wsi->protocol = &context->protocols[n];
break;
}
n++;
}
if (wsi->protocol == NULL) {
lwsl_err("lws_client_int_s_hs: fail protocol %s\n", p);
goto bail2;
}
check_extensions:
#ifndef LWS_NO_EXTENSIONS
/* instantiate the accepted extensions */
if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS)) {
lwsl_ext("no client extenstions allowed by server\n");
goto check_accept;
}
/*
* break down the list of server accepted extensions
* and go through matching them or identifying bogons
*/
if (lws_hdr_copy(wsi, (char *)context->service_buffer,
sizeof(context->service_buffer), WSI_TOKEN_EXTENSIONS) < 0) {
lwsl_warn("ext list from server failed to copy\n");
goto bail2;
}
c = (char *)context->service_buffer;
n = 0;
while (more) {
if (*c && (*c != ',' && *c != ' ' && *c != '\t')) {
ext_name[n] = *c++;
if (n < sizeof(ext_name) - 1)
n++;
continue;
}
ext_name[n] = '\0';
if (!*c)
more = 0;
else {
c++;
if (!n)
continue;
}
/* check we actually support it */
lwsl_ext("checking client ext %s\n", ext_name);
n = 0;
ext = wsi->protocol->owning_server->extensions;
while (ext && ext->callback) {
if (strcmp(ext_name, ext->name)) {
ext++;
continue;
}
n = 1;
lwsl_ext("instantiating client ext %s\n", ext_name);
/* instantiate the extension on this conn */
wsi->active_extensions_user[
wsi->count_active_extensions] =
malloc(ext->per_session_data_size);
if (wsi->active_extensions_user[
wsi->count_active_extensions] == NULL) {
lwsl_err("Out of mem\n");
goto bail2;
}
memset(wsi->active_extensions_user[
wsi->count_active_extensions], 0,
ext->per_session_data_size);
wsi->active_extensions[
wsi->count_active_extensions] = ext;
/* allow him to construct his context */
ext->callback(wsi->protocol->owning_server,
ext, wsi,
LWS_EXT_CALLBACK_CLIENT_CONSTRUCT,
wsi->active_extensions_user[
wsi->count_active_extensions],
NULL, 0);
wsi->count_active_extensions++;
ext++;
}
if (n == 0) {
lwsl_warn("Unknown ext '%s'!\n", ext_name);
goto bail2;
}
n = 0;
}
check_accept:
#endif
/*
* Confirm his accept token is the one we precomputed
*/
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_ACCEPT);
if (strcmp(p, wsi->u.hdr.ah->initial_handshake_hash_base64)) {
lwsl_warn("lws_client_int_s_hs: accept %s wrong vs %s\n", p,
wsi->u.hdr.ah->initial_handshake_hash_base64);
goto bail2;
}
/* allocate the per-connection user memory (if any) */
if (libwebsocket_ensure_user_space(wsi)) {
lwsl_err("Problem allocating wsi user mem\n");
goto bail2;
}
/*
* we seem to be good to go, give client last chance to check
* headers and OK it
*/
wsi->protocol->callback(context, wsi,
LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH,
wsi->user_space, NULL, 0);
/* clear his proxy connection timeout */
libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
/* free up his parsing allocations */
if (wsi->u.hdr.ah)
free(wsi->u.hdr.ah);
/* mark him as being alive */
wsi->state = WSI_STATE_ESTABLISHED;
wsi->mode = LWS_CONNMODE_WS_CLIENT;
/* union transition */
memset(&wsi->u, 0, sizeof(wsi->u));
wsi->u.ws.rxflow_change_to = LWS_RXFLOW_ALLOW;
/*
* create the frame buffer for this connection according to the
* size mentioned in the protocol definition. If 0 there, then
* use a big default for compatibility
*/
n = wsi->protocol->rx_buffer_size;
if (!n)
n = LWS_MAX_SOCKET_IO_BUF;
n += LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING;
wsi->u.ws.rx_user_buffer = malloc(n);
if (!wsi->u.ws.rx_user_buffer) {
lwsl_err("Out of Mem allocating rx buffer %d\n", n);
goto bail2;
}
lwsl_info("Allocating client RX buffer %d\n", n);
if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) {
lwsl_warn("Failed to set SNDBUF to %d", n);
goto bail3;
}
lwsl_debug("handshake OK for protocol %s\n", wsi->protocol->name);
/* call him back to inform him he is up */
wsi->protocol->callback(context, wsi,
LWS_CALLBACK_CLIENT_ESTABLISHED,
wsi->user_space, NULL, 0);
#ifndef LWS_NO_EXTENSIONS
/*
* inform all extensions, not just active ones since they
* already know
*/
ext = context->extensions;
while (ext && ext->callback) {
v = NULL;
for (n = 0; n < wsi->count_active_extensions; n++)
if (wsi->active_extensions[n] == ext)
v = wsi->active_extensions_user[n];
ext->callback(context, ext, wsi,
LWS_EXT_CALLBACK_ANY_WSI_ESTABLISHED, v, NULL, 0);
ext++;
}
#endif
return 0;
bail3:
free(wsi->u.ws.rx_user_buffer);
wsi->u.ws.rx_user_buffer = NULL;
close_reason = LWS_CLOSE_STATUS_NOSTATUS;
bail2:
if (wsi->protocol)
wsi->protocol->callback(context, wsi,
LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
wsi->user_space, NULL, 0);
lwsl_info("closing connection due to bail2 connection error\n");
/* free up his parsing allocations */
if (wsi->u.hdr.ah)
free(wsi->u.hdr.ah);
libwebsocket_close_and_free_session(context, wsi, close_reason);
return 1;
}
char *
libwebsockets_generate_client_handshake(struct libwebsocket_context *context,
struct libwebsocket *wsi, char *pkt)
{
char buf[128];
char hash[20];
char key_b64[40];
char *p = pkt;
int n;
#ifndef LWS_NO_EXTENSIONS
struct libwebsocket_extension *ext;
int ext_count = 0;
#endif
/*
* create the random key
*/
n = libwebsockets_get_random(context, hash, 16);
if (n != 16) {
lwsl_err("Unable to read from random dev %s\n",
SYSTEM_RANDOM_FILEPATH);
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return NULL;
}
lws_b64_encode_string(hash, 16, key_b64, sizeof(key_b64));
/*
* 00 example client handshake
*
* GET /socket.io/websocket HTTP/1.1
* Upgrade: WebSocket
* Connection: Upgrade
* Host: 127.0.0.1:9999
* Origin: http://127.0.0.1
* Sec-WebSocket-Key1: 1 0 2#0W 9 89 7 92 ^
* Sec-WebSocket-Key2: 7 7Y 4328 B2v[8(z1
* Cookie: socketio=websocket
*
* (Á®Ä0¶†≥
*
* 04 example client handshake
*
* GET /chat HTTP/1.1
* Host: server.example.com
* Upgrade: websocket
* Connection: Upgrade
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
* Sec-WebSocket-Origin: http://example.com
* Sec-WebSocket-Protocol: chat, superchat
* Sec-WebSocket-Version: 4
*/
p += sprintf(p, "GET %s HTTP/1.1\x0d\x0a",
lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI));
p += sprintf(p,
"Pragma: no-cache\x0d\x0a""Cache-Control: no-cache\x0d\x0a");
p += sprintf(p, "Host: %s\x0d\x0a",
lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST));
p += sprintf(p,
"Upgrade: websocket\x0d\x0a""Connection: Upgrade\x0d\x0a""Sec-WebSocket-Key: ");
strcpy(p, key_b64);
p += strlen(key_b64);
p += sprintf(p, "\x0d\x0a");
if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN))
p += sprintf(p, "Origin: http://%s\x0d\x0a",
lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN));
if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS))
p += sprintf(p, "Sec-WebSocket-Protocol: %s\x0d\x0a",
lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS));
/* tell the server what extensions we could support */
p += sprintf(p, "Sec-WebSocket-Extensions: ");
#ifndef LWS_NO_EXTENSIONS
ext = context->extensions;
while (ext && ext->callback) {
n = lws_ext_callback_for_each_extension_type(context, wsi,
LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION,
(char *)ext->name, 0);
if (n) { /* an extension vetos us */
lwsl_ext("ext %s vetoed\n", (char *)ext->name);
ext++;
continue;
}
n = context->protocols[0].callback(context, wsi,
LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED,
wsi->user_space, (char *)ext->name, 0);
/*
* zero return from callback means
* go ahead and allow the extension,
* it's what we get if the callback is
* unhandled
*/
if (n) {
ext++;
continue;
}
/* apply it */
if (ext_count)
*p++ = ',';
p += sprintf(p, "%s", ext->name);
ext_count++;
ext++;
}
#endif
p += sprintf(p, "\x0d\x0a");
if (wsi->ietf_spec_revision)
p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a",
wsi->ietf_spec_revision);
/* give userland a chance to append, eg, cookies */
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,
NULL, &p, (pkt + sizeof(context->service_buffer)) - p - 12);
p += sprintf(p, "\x0d\x0a");
/* prepare the expected server accept response */
key_b64[39] = '\0'; /* enforce composed length below buf sizeof */
n = sprintf(buf, "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", key_b64);
SHA1((unsigned char *)buf, n, (unsigned char *)hash);
lws_b64_encode_string(hash, 20,
wsi->u.hdr.ah->initial_handshake_hash_base64,
sizeof(wsi->u.hdr.ah->initial_handshake_hash_base64));
return p;
}
+4
View File
@@ -0,0 +1,4 @@
#include "build.h"
#define LWS_BUILTIN_GETIFADDRS
#define LWS_NO_DAEMONIZE
+340
View File
@@ -0,0 +1,340 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
#ifndef LWS_BUILD_HASH
#define LWS_BUILD_HASH "unknown-build-hash"
#endif
static const char *library_version = LWS_LIBRARY_VERSION " " LWS_BUILD_HASH;
/**
* lws_get_library_version: get version and git hash library built from
*
* returns a const char * to a string like "1.1 178d78c"
* representing the library version followed by the git head hash it
* was built from
*/
LWS_VISIBLE const char *
lws_get_library_version(void)
{
return library_version;
}
/**
* libwebsocket_create_context() - Create the websocket handler
* @info: pointer to struct with parameters
*
* This function creates the listening socket (if serving) and takes care
* of all initialization in one step.
*
* After initialization, it returns a struct libwebsocket_context * that
* represents this server. After calling, user code needs to take care
* of calling libwebsocket_service() with the context pointer to get the
* server's sockets serviced. This must be done in the same process
* context as the initialization call.
*
* The protocol callback functions are called for a handful of events
* including http requests coming in, websocket connections becoming
* established, and data arriving; it's also called periodically to allow
* async transmission.
*
* HTTP requests are sent always to the FIRST protocol in @protocol, since
* at that time websocket protocol has not been negotiated. Other
* protocols after the first one never see any HTTP callack activity.
*
* The server created is a simple http server by default; part of the
* websocket standard is upgrading this http connection to a websocket one.
*
* This allows the same server to provide files like scripts and favicon /
* images or whatever over http and dynamic data over websockets all in
* one place; they're all handled in the user callback.
*/
LWS_VISIBLE struct libwebsocket_context *
libwebsocket_create_context(struct lws_context_creation_info *info)
{
struct libwebsocket_context *context = NULL;
char *p;
int pid_daemon = get_daemonize_pid();
lwsl_notice("Initial logging level %d\n", log_level);
lwsl_notice("Library version: %s\n", library_version);
#ifdef LWS_USE_IPV6
if (!(info->options & LWS_SERVER_OPTION_DISABLE_IPV6))
lwsl_notice("IPV6 compiled in and enabled\n");
else
lwsl_notice("IPV6 compiled in but disabled\n");
#else
lwsl_notice("IPV6 not compiled in\n");
#endif
lws_feature_status_libev(info);
lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN);
lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS);
lwsl_info(" SPEC_LATEST_SUPPORTED: %u\n", SPEC_LATEST_SUPPORTED);
lwsl_info(" AWAITING_TIMEOUT: %u\n", AWAITING_TIMEOUT);
lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH);
lwsl_info(" LWS_MAX_ZLIB_CONN_BUFFER: %u\n", LWS_MAX_ZLIB_CONN_BUFFER);
if (lws_plat_context_early_init())
return NULL;
context = (struct libwebsocket_context *)
malloc(sizeof(struct libwebsocket_context));
if (!context) {
lwsl_err("No memory for websocket context\n");
return NULL;
}
memset(context, 0, sizeof(*context));
if (pid_daemon) {
context->started_with_parent = pid_daemon;
lwsl_notice(" Started with daemon pid %d\n", pid_daemon);
}
context->listen_service_extraseen = 0;
context->protocols = info->protocols;
context->listen_port = info->port;
context->http_proxy_port = 0;
context->http_proxy_address[0] = '\0';
context->options = info->options;
context->iface = info->iface;
/* to reduce this allocation, */
context->max_fds = getdtablesize();
lwsl_notice(" static allocation: %u + (%u x %u fds) = %u bytes\n",
sizeof(struct libwebsocket_context),
sizeof(struct libwebsocket_pollfd) +
sizeof(struct libwebsocket *),
context->max_fds,
sizeof(struct libwebsocket_context) +
((sizeof(struct libwebsocket_pollfd) +
sizeof(struct libwebsocket *)) *
context->max_fds));
context->fds = (struct libwebsocket_pollfd *)
malloc(sizeof(struct libwebsocket_pollfd) *
context->max_fds);
if (context->fds == NULL) {
lwsl_err("Unable to allocate fds array for %d connections\n",
context->max_fds);
free(context);
return NULL;
}
context->lws_lookup = (struct libwebsocket **)
malloc(sizeof(struct libwebsocket *) * context->max_fds);
if (context->lws_lookup == NULL) {
lwsl_err(
"Unable to allocate lws_lookup array for %d connections\n",
context->max_fds);
free(context->fds);
free(context);
return NULL;
}
memset(context->lws_lookup, 0, sizeof(struct libwebsocket *) *
context->max_fds);
if (lws_plat_init_fd_tables(context)) {
free(context->lws_lookup);
free(context->fds);
free(context);
return NULL;
}
lws_context_init_extensions(info, context);
context->user_space = info->user;
strcpy(context->canonical_hostname, "unknown");
lws_server_get_canonical_hostname(context, info);
/* split the proxy ads:port if given */
if (info->http_proxy_address) {
strncpy(context->http_proxy_address, info->http_proxy_address,
sizeof(context->http_proxy_address) - 1);
context->http_proxy_address[
sizeof(context->http_proxy_address) - 1] = '\0';
context->http_proxy_port = info->http_proxy_port;
} else {
#ifdef HAVE_GETENV
p = getenv("http_proxy");
if (p) {
strncpy(context->http_proxy_address, p,
sizeof(context->http_proxy_address) - 1);
context->http_proxy_address[
sizeof(context->http_proxy_address) - 1] = '\0';
p = strchr(context->http_proxy_address, ':');
if (p == NULL) {
lwsl_err("http_proxy needs to be ads:port\n");
goto bail;
}
*p = '\0';
context->http_proxy_port = atoi(p + 1);
}
#endif
}
if (context->http_proxy_address[0])
lwsl_notice(" Proxy %s:%u\n",
context->http_proxy_address,
context->http_proxy_port);
lwsl_notice(
" per-conn mem: %u + %u headers + protocol rx buf\n",
sizeof(struct libwebsocket),
sizeof(struct allocated_headers));
if (lws_context_init_server_ssl(info, context))
goto bail;
if (lws_context_init_client_ssl(info, context))
goto bail;
if (lws_context_init_server(info, context))
goto bail;
/*
* drop any root privs for this process
* to listen on port < 1023 we would have needed root, but now we are
* listening, we don't want the power for anything else
*/
lws_plat_drop_app_privileges(info);
/* initialize supported protocols */
for (context->count_protocols = 0;
info->protocols[context->count_protocols].callback;
context->count_protocols++) {
lwsl_parser(" Protocol: %s\n",
info->protocols[context->count_protocols].name);
info->protocols[context->count_protocols].owning_server =
context;
info->protocols[context->count_protocols].protocol_index =
context->count_protocols;
/*
* inform all the protocols that they are doing their one-time
* initialization if they want to
*/
info->protocols[context->count_protocols].callback(context,
NULL, LWS_CALLBACK_PROTOCOL_INIT, NULL, NULL, 0);
}
/*
* give all extensions a chance to create any per-context
* allocations they need
*/
if (info->port != CONTEXT_PORT_NO_LISTEN) {
if (lws_ext_callback_for_each_extension_type(context, NULL,
LWS_EXT_CALLBACK_SERVER_CONTEXT_CONSTRUCT,
NULL, 0) < 0)
goto bail;
} else
if (lws_ext_callback_for_each_extension_type(context, NULL,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_CONSTRUCT,
NULL, 0) < 0)
goto bail;
return context;
bail:
libwebsocket_context_destroy(context);
return NULL;
}
/**
* libwebsocket_context_destroy() - Destroy the websocket context
* @context: Websocket context
*
* This function closes any active connections and then frees the
* context. After calling this, any further use of the context is
* undefined.
*/
LWS_VISIBLE void
libwebsocket_context_destroy(struct libwebsocket_context *context)
{
int n;
struct libwebsocket_protocols *protocol = context->protocols;
lwsl_notice("%s\n", __func__);
#ifdef LWS_LATENCY
if (context->worst_latency_info[0])
lwsl_notice("Worst latency: %s\n", context->worst_latency_info);
#endif
for (n = 0; n < context->fds_count; n++) {
struct libwebsocket *wsi =
context->lws_lookup[context->fds[n].fd];
if (!wsi)
continue;
libwebsocket_close_and_free_session(context,
wsi, LWS_CLOSE_STATUS_NOSTATUS /* no protocol close */);
n--;
}
/*
* give all extensions a chance to clean up any per-context
* allocations they might have made
*/
if (context->listen_port) {
if (lws_ext_callback_for_each_extension_type(context, NULL,
LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, NULL, 0) < 0)
return;
} else
if (lws_ext_callback_for_each_extension_type(context, NULL,
LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, NULL, 0) < 0)
return;
/*
* inform all the protocols that they are done and will have no more
* callbacks
*/
while (protocol->callback) {
protocol->callback(context, NULL, LWS_CALLBACK_PROTOCOL_DESTROY,
NULL, NULL, 0);
protocol++;
}
lws_plat_context_early_destroy(context);
lws_ssl_context_destroy(context);
if (context->fds)
free(context->fds);
if (context->lws_lookup)
free(context->lws_lookup);
lws_plat_context_late_destroy(context);
free(context);
}
@@ -0,0 +1,294 @@
#include "private-libwebsockets.h"
#include "extension-deflate-frame.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define LWS_ZLIB_WINDOW_BITS 15
#define LWS_ZLIB_MEMLEVEL 8
int lws_extension_callback_deflate_frame(
struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len)
{
struct lws_ext_deflate_frame_conn *conn =
(struct lws_ext_deflate_frame_conn *)user;
struct lws_tokens *eff_buf = (struct lws_tokens *)in;
size_t current_payload, remaining_payload, total_payload;
int n;
size_t len_so_far;
switch (reason) {
/*
* for deflate-frame, both client and server sides act the same
*/
case LWS_EXT_CALLBACK_CLIENT_CONSTRUCT:
case LWS_EXT_CALLBACK_CONSTRUCT:
conn->zs_in.zalloc = conn->zs_out.zalloc = Z_NULL;
conn->zs_in.zfree = conn->zs_out.zfree = Z_NULL;
conn->zs_in.opaque = conn->zs_out.opaque = Z_NULL;
n = inflateInit2(&conn->zs_in, -LWS_ZLIB_WINDOW_BITS);
if (n != Z_OK) {
lwsl_ext("deflateInit returned %d\n", n);
return 1;
}
n = deflateInit2(&conn->zs_out,
(context->listen_port ?
DEFLATE_FRAME_COMPRESSION_LEVEL_SERVER :
DEFLATE_FRAME_COMPRESSION_LEVEL_CLIENT),
Z_DEFLATED,
-LWS_ZLIB_WINDOW_BITS, LWS_ZLIB_MEMLEVEL,
Z_DEFAULT_STRATEGY);
if (n != Z_OK) {
lwsl_ext("deflateInit2 returned %d\n", n);
return 1;
}
conn->buf_pre_used = 0;
conn->buf_pre_length = 0;
conn->buf_in_length = sizeof(conn->buf_in);
conn->buf_out_length = sizeof(conn->buf_out);
conn->compressed_out = 0;
conn->buf_pre = NULL;
conn->buf_in = (unsigned char *)
malloc(LWS_SEND_BUFFER_PRE_PADDING +
conn->buf_in_length +
LWS_SEND_BUFFER_POST_PADDING);
if (!conn->buf_in)
goto bail;
conn->buf_out = (unsigned char *)
malloc(LWS_SEND_BUFFER_PRE_PADDING +
conn->buf_out_length +
LWS_SEND_BUFFER_POST_PADDING);
if (!conn->buf_out)
goto bail;
lwsl_ext("zlibs constructed\n");
break;
bail:
lwsl_err("Out of mem\n");
(void)inflateEnd(&conn->zs_in);
(void)deflateEnd(&conn->zs_out);
return -1;
case LWS_EXT_CALLBACK_DESTROY:
if (conn->buf_pre)
free(conn->buf_pre);
free(conn->buf_in);
free(conn->buf_out);
conn->buf_pre_used = 0;
conn->buf_pre_length = 0;
conn->buf_in_length = 0;
conn->buf_out_length = 0;
conn->compressed_out = 0;
(void)inflateEnd(&conn->zs_in);
(void)deflateEnd(&conn->zs_out);
lwsl_ext("zlibs destructed\n");
break;
case LWS_EXT_CALLBACK_PAYLOAD_RX:
if (!(wsi->u.ws.rsv & 0x40))
return 0;
/*
* inflate the incoming payload
*/
current_payload = eff_buf->token_len;
remaining_payload = wsi->u.ws.rx_packet_length;
if (remaining_payload) {
total_payload = conn->buf_pre_used +
current_payload +
remaining_payload;
if (conn->buf_pre_length < total_payload) {
conn->buf_pre_length = total_payload;
if (conn->buf_pre)
free(conn->buf_pre);
conn->buf_pre =
(unsigned char *)malloc(total_payload + 4);
if (!conn->buf_pre) {
lwsl_err("Out of memory\n");
return -1;
}
}
memcpy(conn->buf_pre + conn->buf_pre_used,
eff_buf->token, current_payload);
conn->buf_pre_used += current_payload;
eff_buf->token = NULL;
eff_buf->token_len = 0;
return 0;
}
if (conn->buf_pre_used) {
total_payload = conn->buf_pre_used +
current_payload;
memcpy(conn->buf_pre + conn->buf_pre_used,
eff_buf->token, current_payload);
conn->buf_pre_used = 0;
conn->zs_in.next_in = conn->buf_pre;
} else {
total_payload = current_payload;
conn->zs_in.next_in = (unsigned char *)eff_buf->token;
}
conn->zs_in.next_in[total_payload + 0] = 0;
conn->zs_in.next_in[total_payload + 1] = 0;
conn->zs_in.next_in[total_payload + 2] = 0xff;
conn->zs_in.next_in[total_payload + 3] = 0xff;
conn->zs_in.avail_in = total_payload + 4;
conn->zs_in.next_out =
conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING;
conn->zs_in.avail_out = conn->buf_in_length;
while (1) {
n = inflate(&conn->zs_in, Z_SYNC_FLUSH);
switch (n) {
case Z_NEED_DICT:
case Z_STREAM_ERROR:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
/*
* screwed.. close the connection...
* we will get a destroy callback to take care
* of closing nicely
*/
lwsl_info("zlib error inflate %d: %s\n",
n, conn->zs_in.msg);
return -1;
}
if (conn->zs_in.avail_out)
break;
len_so_far = conn->zs_in.next_out -
(conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING);
conn->buf_in_length *= 2;
if (conn->buf_in_length > LWS_MAX_ZLIB_CONN_BUFFER) {
lwsl_ext("zlib in buffer hit limit %u\n",
LWS_MAX_ZLIB_CONN_BUFFER);
return -1;
}
conn->buf_in = (unsigned char *)realloc(conn->buf_in,
LWS_SEND_BUFFER_PRE_PADDING +
conn->buf_in_length +
LWS_SEND_BUFFER_POST_PADDING);
if (!conn->buf_in) {
lwsl_err("Out of memory\n");
return -1;
}
lwsl_debug(
"deflate-frame ext RX did realloc to %ld\n",
conn->buf_in_length);
conn->zs_in.next_out = conn->buf_in +
LWS_SEND_BUFFER_PRE_PADDING + len_so_far;
conn->zs_in.avail_out =
conn->buf_in_length - len_so_far;
}
/* rewrite the buffer pointers and length */
eff_buf->token =
(char *)(conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING);
eff_buf->token_len = (int)(conn->zs_in.next_out -
(conn->buf_in + LWS_SEND_BUFFER_PRE_PADDING));
return 0;
case LWS_EXT_CALLBACK_PAYLOAD_TX:
/*
* deflate the outgoing payload
*/
current_payload = eff_buf->token_len;
conn->zs_out.next_in = (unsigned char *)eff_buf->token;
conn->zs_out.avail_in = current_payload;
conn->zs_out.next_out =
conn->buf_out + LWS_SEND_BUFFER_PRE_PADDING;
conn->zs_out.avail_out = conn->buf_out_length;
while (1) {
n = deflate(&conn->zs_out, Z_SYNC_FLUSH);
if (n == Z_STREAM_ERROR) {
/*
* screwed.. close the connection... we will
* get a destroy callback to take care of
* closing nicely
*/
lwsl_ext("zlib error deflate\n");
return -1;
}
if (conn->zs_out.avail_out)
break;
len_so_far = (conn->zs_out.next_out -
(conn->buf_out +
LWS_SEND_BUFFER_PRE_PADDING));
conn->buf_out_length *= 2;
if (conn->buf_out_length > LWS_MAX_ZLIB_CONN_BUFFER) {
lwsl_ext("zlib out hit limit %u\n",
LWS_MAX_ZLIB_CONN_BUFFER);
return -1;
}
conn->buf_out = (unsigned char *)realloc(
conn->buf_out,
LWS_SEND_BUFFER_PRE_PADDING +
conn->buf_out_length +
LWS_SEND_BUFFER_POST_PADDING);
if (!conn->buf_out) {
lwsl_err("Out of memory\n");
return -1;
}
lwsl_debug(
"deflate-frame ext TX did realloc to %ld\n",
conn->buf_in_length);
conn->zs_out.next_out = (conn->buf_out +
LWS_SEND_BUFFER_PRE_PADDING + len_so_far);
conn->zs_out.avail_out =
(conn->buf_out_length - len_so_far);
}
conn->compressed_out = 1;
/* rewrite the buffer pointers and length */
eff_buf->token = (char *)(conn->buf_out +
LWS_SEND_BUFFER_PRE_PADDING);
eff_buf->token_len = (int)(conn->zs_out.next_out -
(conn->buf_out + LWS_SEND_BUFFER_PRE_PADDING)) - 4;
return 0;
case LWS_EXT_CALLBACK_PACKET_TX_PRESEND:
if (conn->compressed_out) {
conn->compressed_out = 0;
*((unsigned char *)eff_buf->token) |= 0x40;
}
break;
case LWS_EXT_CALLBACK_CHECK_OK_TO_PROPOSE_EXTENSION:
/* Avoid x-webkit-deflate-frame extension on client */
if (!strcmp((char *)in, "x-webkit-deflate-frame"))
return 1;
break;
default:
break;
}
return 0;
}
@@ -0,0 +1,25 @@
#include "deps/zlib/zlib.h"
#define DEFLATE_FRAME_COMPRESSION_LEVEL_SERVER 1
#define DEFLATE_FRAME_COMPRESSION_LEVEL_CLIENT Z_DEFAULT_COMPRESSION
struct lws_ext_deflate_frame_conn {
z_stream zs_in;
z_stream zs_out;
size_t buf_pre_used;
size_t buf_pre_length;
size_t buf_in_length;
size_t buf_out_length;
int compressed_out;
unsigned char *buf_pre;
unsigned char *buf_in;
unsigned char *buf_out;
};
extern int lws_extension_callback_deflate_frame(
struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);
@@ -0,0 +1,166 @@
#include "private-libwebsockets.h"
#include "extension-deflate-stream.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define LWS_ZLIB_WINDOW_BITS 15
#define LWS_ZLIB_MEMLEVEL 8
int lws_extension_callback_deflate_stream(
struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len)
{
struct lws_ext_deflate_stream_conn *conn =
(struct lws_ext_deflate_stream_conn *)user;
int n;
struct lws_tokens *eff_buf = (struct lws_tokens *)in;
switch (reason) {
/*
* for deflate-stream, both client and server sides act the same
*/
case LWS_EXT_CALLBACK_CLIENT_CONSTRUCT:
case LWS_EXT_CALLBACK_CONSTRUCT:
conn->zs_in.zalloc = conn->zs_out.zalloc = Z_NULL;
conn->zs_in.zfree = conn->zs_out.zfree = Z_NULL;
conn->zs_in.opaque = conn->zs_out.opaque = Z_NULL;
n = inflateInit2(&conn->zs_in, -LWS_ZLIB_WINDOW_BITS);
if (n != Z_OK) {
lwsl_err("deflateInit returned %d\n", n);
return 1;
}
n = deflateInit2(&conn->zs_out,
DEFLATE_STREAM_COMPRESSION_LEVEL, Z_DEFLATED,
-LWS_ZLIB_WINDOW_BITS, LWS_ZLIB_MEMLEVEL,
Z_DEFAULT_STRATEGY);
if (n != Z_OK) {
lwsl_err("deflateInit returned %d\n", n);
return 1;
}
lwsl_ext("zlibs constructed\n");
conn->remaining_in = 0;
break;
case LWS_EXT_CALLBACK_DESTROY:
(void)inflateEnd(&conn->zs_in);
(void)deflateEnd(&conn->zs_out);
lwsl_ext("zlibs destructed\n");
break;
case LWS_EXT_CALLBACK_PACKET_RX_PREPARSE:
/*
* inflate the incoming compressed data
* Notice, length may be 0 and pointer NULL
* in the case we are flushing with nothing new coming in
*/
if (conn->remaining_in) {
conn->zs_in.next_in = conn->buf_in;
conn->zs_in.avail_in = conn->remaining_in;
conn->remaining_in = 0;
} else {
conn->zs_in.next_in = (unsigned char *)eff_buf->token;
conn->zs_in.avail_in = eff_buf->token_len;
}
conn->zs_in.next_out = conn->buf_out;
conn->zs_in.avail_out = sizeof(conn->buf_out);
n = inflate(&conn->zs_in, Z_SYNC_FLUSH);
switch (n) {
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
/*
* screwed.. close the connection... we will get a
* destroy callback to take care of closing nicely
*/
lwsl_err("zlib error inflate %d\n", n);
return -1;
}
/* rewrite the buffer pointers and length */
eff_buf->token = (char *)conn->buf_out;
eff_buf->token_len =
sizeof(conn->buf_out) - conn->zs_in.avail_out;
/* copy avail data if not consumed */
if (conn->zs_in.avail_in > 0) {
conn->remaining_in = conn->zs_in.avail_in;
memcpy(conn->buf_in, conn->zs_in.next_in,
conn->zs_in.avail_in);
return 1;
}
/*
* if we filled the output buffer, signal that we likely have
* more and need to be called again
*/
if (eff_buf->token_len == sizeof(conn->buf_out))
return 1;
/* we don't need calling again until new input data comes */
return 0;
case LWS_EXT_CALLBACK_FLUSH_PENDING_TX:
case LWS_EXT_CALLBACK_PACKET_TX_PRESEND:
/*
* deflate the outgoing compressed data
*/
conn->zs_out.next_in = (unsigned char *)eff_buf->token;
conn->zs_out.avail_in = eff_buf->token_len;
conn->zs_out.next_out = conn->buf_out;
conn->zs_out.avail_out = sizeof(conn->buf_out);
n = Z_PARTIAL_FLUSH;
if (reason == LWS_EXT_CALLBACK_FLUSH_PENDING_TX)
n = Z_FULL_FLUSH;
n = deflate(&conn->zs_out, n);
if (n == Z_STREAM_ERROR) {
/*
* screwed.. close the connection... we will get a
* destroy callback to take care of closing nicely
*/
lwsl_ext("zlib error deflate\n");
return -1;
}
/* rewrite the buffer pointers and length */
eff_buf->token = (char *)conn->buf_out;
eff_buf->token_len =
sizeof(conn->buf_out) - conn->zs_out.avail_out;
/*
* if we filled the output buffer, signal that we likely have
* more and need to be called again... even in deflate case
* we might sometimes need to spill more than came in
*/
if (eff_buf->token_len == sizeof(conn->buf_out))
return 1;
/* we don't need calling again until new input data comes */
return 0;
default:
break;
}
return 0;
}
@@ -0,0 +1,20 @@
#include "deps/zlib/zlib.h"
#define DEFLATE_STREAM_CHUNK 128
#define DEFLATE_STREAM_COMPRESSION_LEVEL 1
struct lws_ext_deflate_stream_conn {
z_stream zs_in;
z_stream zs_out;
int remaining_in;
unsigned char buf_in[LWS_MAX_SOCKET_IO_BUF];
unsigned char buf_out[LWS_MAX_SOCKET_IO_BUF];
};
extern int lws_extension_callback_deflate_stream(
struct libwebsocket_context *context,
struct libwebsocket_extension *ext,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons reason,
void *user, void *in, size_t len);
+206
View File
@@ -0,0 +1,206 @@
#include "private-libwebsockets.h"
#include "extension-deflate-frame.h"
#include "extension-deflate-stream.h"
struct libwebsocket_extension libwebsocket_internal_extensions[] = {
#ifdef LWS_EXT_DEFLATE_STREAM
{
"deflate-stream",
lws_extension_callback_deflate_stream,
sizeof(struct lws_ext_deflate_stream_conn)
},
#else
{
"x-webkit-deflate-frame",
lws_extension_callback_deflate_frame,
sizeof(struct lws_ext_deflate_frame_conn)
},
{
"deflate-frame",
lws_extension_callback_deflate_frame,
sizeof(struct lws_ext_deflate_frame_conn)
},
#endif
{ /* terminator */
NULL, NULL, 0
}
};
LWS_VISIBLE void
lws_context_init_extensions(struct lws_context_creation_info *info,
struct libwebsocket_context *context)
{
context->extensions = info->extensions;
lwsl_info(" LWS_MAX_EXTENSIONS_ACTIVE: %u\n", LWS_MAX_EXTENSIONS_ACTIVE);
}
LWS_VISIBLE struct libwebsocket_extension *libwebsocket_get_internal_extensions()
{
return libwebsocket_internal_extensions;
}
/* 0 = nobody had nonzero return, 1 = somebody had positive return, -1 = fail */
int lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason,
void *arg, int len)
{
int n, m, handled = 0;
for (n = 0; n < wsi->count_active_extensions; n++) {
m = wsi->active_extensions[n]->callback(
wsi->protocol->owning_server,
wsi->active_extensions[n], wsi,
reason,
wsi->active_extensions_user[n],
arg, len);
if (m < 0) {
lwsl_ext(
"Extension '%s' failed to handle callback %d!\n",
wsi->active_extensions[n]->name, reason);
return -1;
}
if (m > handled)
handled = m;
}
return handled;
}
int lws_ext_callback_for_each_extension_type(
struct libwebsocket_context *context, struct libwebsocket *wsi,
int reason, void *arg, int len)
{
int n = 0, m, handled = 0;
struct libwebsocket_extension *ext = context->extensions;
while (ext && ext->callback && !handled) {
m = ext->callback(context, ext, wsi, reason,
(void *)(long)n, arg, len);
if (m < 0) {
lwsl_ext(
"Extension '%s' failed to handle callback %d!\n",
wsi->active_extensions[n]->name, reason);
return -1;
}
if (m)
handled = 1;
ext++;
n++;
}
return 0;
}
int
lws_issue_raw_ext_access(struct libwebsocket *wsi,
unsigned char *buf, size_t len)
{
int ret;
struct lws_tokens eff_buf;
int m;
int n;
eff_buf.token = (char *)buf;
eff_buf.token_len = len;
/*
* while we have original buf to spill ourselves, or extensions report
* more in their pipeline
*/
ret = 1;
while (ret == 1) {
/* default to nobody has more to spill */
ret = 0;
/* show every extension the new incoming data */
m = lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_PACKET_TX_PRESEND, &eff_buf, 0);
if (m < 0)
return -1;
if (m) /* handled */
ret = 1;
if ((char *)buf != eff_buf.token)
/*
* extension recreated it:
* need to buffer this if not all sent
*/
wsi->u.ws.clean_buffer = 0;
/* assuming they left us something to send, send it */
if (eff_buf.token_len) {
n = lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
eff_buf.token_len);
if (n < 0) {
lwsl_info("closing from ext access\n");
return -1;
}
/* always either sent it all or privately buffered */
}
lwsl_parser("written %d bytes to client\n", eff_buf.token_len);
/* no extension has more to spill? Then we can go */
if (!ret)
break;
/* we used up what we had */
eff_buf.token = NULL;
eff_buf.token_len = 0;
/*
* Did that leave the pipe choked?
* Or we had to hold on to some of it?
*/
if (!lws_send_pipe_choked(wsi) && !wsi->truncated_send_len)
/* no we could add more, lets's do that */
continue;
lwsl_debug("choked\n");
/*
* Yes, he's choked. Don't spill the rest now get a callback
* when he is ready to send and take care of it there
*/
libwebsocket_callback_on_writable(
wsi->protocol->owning_server, wsi);
wsi->extension_data_pending = 1;
ret = 0;
}
return len;
}
int
lws_any_extension_handled(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons r,
void *v, size_t len)
{
int n;
int handled = 0;
/* maybe an extension will take care of it for us */
for (n = 0; n < wsi->count_active_extensions && !handled; n++) {
if (!wsi->active_extensions[n]->callback)
continue;
handled |= wsi->active_extensions[n]->callback(context,
wsi->active_extensions[n], wsi,
r, wsi->active_extensions_user[n], v, len);
}
return handled;
}
+171
View File
@@ -0,0 +1,171 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2013 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
/*
* -04 of the protocol (actually the 80th version) has a radically different
* handshake. The 04 spec gives the following idea
*
* The handshake from the client looks as follows:
*
* GET /chat HTTP/1.1
* Host: server.example.com
* Upgrade: websocket
* Connection: Upgrade
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
* Sec-WebSocket-Origin: http://example.com
* Sec-WebSocket-Protocol: chat, superchat
* Sec-WebSocket-Version: 4
*
* The handshake from the server looks as follows:
*
* HTTP/1.1 101 Switching Protocols
* Upgrade: websocket
* Connection: Upgrade
* Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo=
* Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC==
* Sec-WebSocket-Protocol: chat
*/
/*
* We have to take care about parsing because the headers may be split
* into multiple fragments. They may contain unknown headers with arbitrary
* argument lengths. So, we parse using a single-character at a time state
* machine that is completely independent of packet size.
*/
LWS_VISIBLE int
libwebsocket_read(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned char *buf, size_t len)
{
size_t n;
switch (wsi->state) {
case WSI_STATE_HTTP_BODY:
http_postbody:
while (len--) {
if (wsi->u.http.content_length_seen >= wsi->u.http.content_length)
break;
wsi->u.http.post_buffer[wsi->u.http.body_index++] = *buf++;
wsi->u.http.content_length_seen++;
n = wsi->protocol->rx_buffer_size;
if (!n)
n = LWS_MAX_SOCKET_IO_BUF;
if (wsi->u.http.body_index != n &&
wsi->u.http.content_length_seen != wsi->u.http.content_length)
continue;
if (wsi->protocol->callback) {
n = wsi->protocol->callback(
wsi->protocol->owning_server, wsi,
LWS_CALLBACK_HTTP_BODY,
wsi->user_space, wsi->u.http.post_buffer,
wsi->u.http.body_index);
wsi->u.http.body_index = 0;
if (n)
goto bail;
}
if (wsi->u.http.content_length_seen == wsi->u.http.content_length) {
/* he sent the content in time */
libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
n = wsi->protocol->callback(
wsi->protocol->owning_server, wsi,
LWS_CALLBACK_HTTP_BODY_COMPLETION,
wsi->user_space, NULL, 0);
wsi->u.http.body_index = 0;
if (n)
goto bail;
}
}
/*
* we need to spill here so everything is seen in the case
* there is no content-length
*/
if (wsi->u.http.body_index && wsi->protocol->callback) {
n = wsi->protocol->callback(
wsi->protocol->owning_server, wsi,
LWS_CALLBACK_HTTP_BODY,
wsi->user_space, wsi->u.http.post_buffer,
wsi->u.http.body_index);
wsi->u.http.body_index = 0;
if (n)
goto bail;
}
break;
case WSI_STATE_HTTP_ISSUING_FILE:
case WSI_STATE_HTTP:
wsi->state = WSI_STATE_HTTP_HEADERS;
wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
wsi->u.hdr.lextable_pos = 0;
/* fallthru */
case WSI_STATE_HTTP_HEADERS:
lwsl_parser("issuing %d bytes to parser\n", (int)len);
if (lws_handshake_client(wsi, &buf, len))
goto bail;
switch (lws_handshake_server(context, wsi, &buf, len)) {
case 1:
goto bail;
case 2:
goto http_postbody;
}
break;
case WSI_STATE_AWAITING_CLOSE_ACK:
case WSI_STATE_ESTABLISHED:
if (lws_handshake_client(wsi, &buf, len))
goto bail;
switch (wsi->mode) {
case LWS_CONNMODE_WS_SERVING:
if (libwebsocket_interpret_incoming_packet(wsi, buf, len) < 0) {
lwsl_info("interpret_incoming_packet has bailed\n");
goto bail;
}
break;
}
break;
default:
lwsl_err("libwebsocket_read: Unhandled state\n");
break;
}
return 0;
bail:
lwsl_debug("closing connection at libwebsocket_read bail:\n");
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return -1;
}
+287
View File
@@ -0,0 +1,287 @@
/* pos 0000: 0 */ 0x67 /* 'g' */, 0x25, 0x00 /* (to 0x0025 state 1) */,
0x70 /* 'p' */, 0x27, 0x00 /* (to 0x002A state 5) */,
0x68 /* 'h' */, 0x30, 0x00 /* (to 0x0036 state 10) */,
0x63 /* 'c' */, 0x39, 0x00 /* (to 0x0042 state 15) */,
0x73 /* 's' */, 0x54, 0x00 /* (to 0x0060 state 26) */,
0x75 /* 'u' */, 0x93, 0x00 /* (to 0x00A2 state 56) */,
0x6F /* 'o' */, 0x99, 0x00 /* (to 0x00AB state 64) */,
0x0D /* '.' */, 0xA5, 0x00 /* (to 0x00BA state 77) */,
0x61 /* 'a' */, 0xDC, 0x00 /* (to 0x00F4 state 127) */,
0x69 /* 'i' */, 0xED, 0x00 /* (to 0x0108 state 134) */,
0x64 /* 'd' */, 0x5A, 0x01 /* (to 0x0178 state 225) */,
0x72 /* 'r' */, 0x5D, 0x01 /* (to 0x017E state 230) */,
0x08, /* fail */
/* pos 0025: 1 */ 0xE5 /* 'e' -> */,
/* pos 0026: 2 */ 0xF4 /* 't' -> */,
/* pos 0027: 3 */ 0xA0 /* ' ' -> */,
/* pos 0028: 4 */ 0x00, 0x00 /* - terminal marker 0 - */,
/* pos 002a: 5 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x0031 state 6) */,
0x72 /* 'r' */, 0x09, 0x01 /* (to 0x0136 state 171) */,
0x08, /* fail */
/* pos 0031: 6 */ 0xF3 /* 's' -> */,
/* pos 0032: 7 */ 0xF4 /* 't' -> */,
/* pos 0033: 8 */ 0xA0 /* ' ' -> */,
/* pos 0034: 9 */ 0x00, 0x01 /* - terminal marker 1 - */,
/* pos 0036: 10 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x003D state 11) */,
0x74 /* 't' */, 0xB2, 0x00 /* (to 0x00EB state 119) */,
0x08, /* fail */
/* pos 003d: 11 */ 0xF3 /* 's' -> */,
/* pos 003e: 12 */ 0xF4 /* 't' -> */,
/* pos 003f: 13 */ 0xBA /* ':' -> */,
/* pos 0040: 14 */ 0x00, 0x02 /* - terminal marker 2 - */,
/* pos 0042: 15 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x0049 state 16) */,
0x61 /* 'a' */, 0xF8, 0x00 /* (to 0x013D state 177) */,
0x08, /* fail */
/* pos 0049: 16 */ 0x6E /* 'n' */, 0x07, 0x00 /* (to 0x0050 state 17) */,
0x6F /* 'o' */, 0x0D, 0x01 /* (to 0x0159 state 203) */,
0x08, /* fail */
/* pos 0050: 17 */ 0x6E /* 'n' */, 0x07, 0x00 /* (to 0x0057 state 18) */,
0x74 /* 't' */, 0x0C, 0x01 /* (to 0x015F state 208) */,
0x08, /* fail */
/* pos 0057: 18 */ 0xE5 /* 'e' -> */,
/* pos 0058: 19 */ 0xE3 /* 'c' -> */,
/* pos 0059: 20 */ 0xF4 /* 't' -> */,
/* pos 005a: 21 */ 0xE9 /* 'i' -> */,
/* pos 005b: 22 */ 0xEF /* 'o' -> */,
/* pos 005c: 23 */ 0xEE /* 'n' -> */,
/* pos 005d: 24 */ 0xBA /* ':' -> */,
/* pos 005e: 25 */ 0x00, 0x03 /* - terminal marker 3 - */,
/* pos 0060: 26 */ 0xE5 /* 'e' -> */,
/* pos 0061: 27 */ 0xE3 /* 'c' -> */,
/* pos 0062: 28 */ 0xAD /* '-' -> */,
/* pos 0063: 29 */ 0xF7 /* 'w' -> */,
/* pos 0064: 30 */ 0xE5 /* 'e' -> */,
/* pos 0065: 31 */ 0xE2 /* 'b' -> */,
/* pos 0066: 32 */ 0xF3 /* 's' -> */,
/* pos 0067: 33 */ 0xEF /* 'o' -> */,
/* pos 0068: 34 */ 0xE3 /* 'c' -> */,
/* pos 0069: 35 */ 0xEB /* 'k' -> */,
/* pos 006a: 36 */ 0xE5 /* 'e' -> */,
/* pos 006b: 37 */ 0xF4 /* 't' -> */,
/* pos 006c: 38 */ 0xAD /* '-' -> */,
/* pos 006d: 39 */ 0x6B /* 'k' */, 0x19, 0x00 /* (to 0x0086 state 40) */,
0x70 /* 'p' */, 0x28, 0x00 /* (to 0x0098 state 47) */,
0x64 /* 'd' */, 0x40, 0x00 /* (to 0x00B3 state 71) */,
0x76 /* 'v' */, 0x49, 0x00 /* (to 0x00BF state 80) */,
0x6F /* 'o' */, 0x4F, 0x00 /* (to 0x00C8 state 88) */,
0x65 /* 'e' */, 0x54, 0x00 /* (to 0x00D0 state 95) */,
0x61 /* 'a' */, 0x5D, 0x00 /* (to 0x00DC state 106) */,
0x6E /* 'n' */, 0x62, 0x00 /* (to 0x00E4 state 113) */,
0x08, /* fail */
/* pos 0086: 40 */ 0xE5 /* 'e' -> */,
/* pos 0087: 41 */ 0xF9 /* 'y' -> */,
/* pos 0088: 42 */ 0x31 /* '1' */, 0x0A, 0x00 /* (to 0x0092 state 43) */,
0x32 /* '2' */, 0x0A, 0x00 /* (to 0x0095 state 45) */,
0x3A /* ':' */, 0x2F, 0x00 /* (to 0x00BD state 79) */,
0x08, /* fail */
/* pos 0092: 43 */ 0xBA /* ':' -> */,
/* pos 0093: 44 */ 0x00, 0x04 /* - terminal marker 4 - */,
/* pos 0095: 45 */ 0xBA /* ':' -> */,
/* pos 0096: 46 */ 0x00, 0x05 /* - terminal marker 5 - */,
/* pos 0098: 47 */ 0xF2 /* 'r' -> */,
/* pos 0099: 48 */ 0xEF /* 'o' -> */,
/* pos 009a: 49 */ 0xF4 /* 't' -> */,
/* pos 009b: 50 */ 0xEF /* 'o' -> */,
/* pos 009c: 51 */ 0xE3 /* 'c' -> */,
/* pos 009d: 52 */ 0xEF /* 'o' -> */,
/* pos 009e: 53 */ 0xEC /* 'l' -> */,
/* pos 009f: 54 */ 0xBA /* ':' -> */,
/* pos 00a0: 55 */ 0x00, 0x06 /* - terminal marker 6 - */,
/* pos 00a2: 56 */ 0xF0 /* 'p' -> */,
/* pos 00a3: 57 */ 0xE7 /* 'g' -> */,
/* pos 00a4: 58 */ 0xF2 /* 'r' -> */,
/* pos 00a5: 59 */ 0xE1 /* 'a' -> */,
/* pos 00a6: 60 */ 0xE4 /* 'd' -> */,
/* pos 00a7: 61 */ 0xE5 /* 'e' -> */,
/* pos 00a8: 62 */ 0xBA /* ':' -> */,
/* pos 00a9: 63 */ 0x00, 0x07 /* - terminal marker 7 - */,
/* pos 00ab: 64 */ 0xF2 /* 'r' -> */,
/* pos 00ac: 65 */ 0xE9 /* 'i' -> */,
/* pos 00ad: 66 */ 0xE7 /* 'g' -> */,
/* pos 00ae: 67 */ 0xE9 /* 'i' -> */,
/* pos 00af: 68 */ 0xEE /* 'n' -> */,
/* pos 00b0: 69 */ 0xBA /* ':' -> */,
/* pos 00b1: 70 */ 0x00, 0x08 /* - terminal marker 8 - */,
/* pos 00b3: 71 */ 0xF2 /* 'r' -> */,
/* pos 00b4: 72 */ 0xE1 /* 'a' -> */,
/* pos 00b5: 73 */ 0xE6 /* 'f' -> */,
/* pos 00b6: 74 */ 0xF4 /* 't' -> */,
/* pos 00b7: 75 */ 0xBA /* ':' -> */,
/* pos 00b8: 76 */ 0x00, 0x09 /* - terminal marker 9 - */,
/* pos 00ba: 77 */ 0x8A /* '.' -> */,
/* pos 00bb: 78 */ 0x00, 0x0A /* - terminal marker 10 - */,
/* pos 00bd: 79 */ 0x00, 0x0B /* - terminal marker 11 - */,
/* pos 00bf: 80 */ 0xE5 /* 'e' -> */,
/* pos 00c0: 81 */ 0xF2 /* 'r' -> */,
/* pos 00c1: 82 */ 0xF3 /* 's' -> */,
/* pos 00c2: 83 */ 0xE9 /* 'i' -> */,
/* pos 00c3: 84 */ 0xEF /* 'o' -> */,
/* pos 00c4: 85 */ 0xEE /* 'n' -> */,
/* pos 00c5: 86 */ 0xBA /* ':' -> */,
/* pos 00c6: 87 */ 0x00, 0x0C /* - terminal marker 12 - */,
/* pos 00c8: 88 */ 0xF2 /* 'r' -> */,
/* pos 00c9: 89 */ 0xE9 /* 'i' -> */,
/* pos 00ca: 90 */ 0xE7 /* 'g' -> */,
/* pos 00cb: 91 */ 0xE9 /* 'i' -> */,
/* pos 00cc: 92 */ 0xEE /* 'n' -> */,
/* pos 00cd: 93 */ 0xBA /* ':' -> */,
/* pos 00ce: 94 */ 0x00, 0x0D /* - terminal marker 13 - */,
/* pos 00d0: 95 */ 0xF8 /* 'x' -> */,
/* pos 00d1: 96 */ 0xF4 /* 't' -> */,
/* pos 00d2: 97 */ 0xE5 /* 'e' -> */,
/* pos 00d3: 98 */ 0xEE /* 'n' -> */,
/* pos 00d4: 99 */ 0xF3 /* 's' -> */,
/* pos 00d5: 100 */ 0xE9 /* 'i' -> */,
/* pos 00d6: 101 */ 0xEF /* 'o' -> */,
/* pos 00d7: 102 */ 0xEE /* 'n' -> */,
/* pos 00d8: 103 */ 0xF3 /* 's' -> */,
/* pos 00d9: 104 */ 0xBA /* ':' -> */,
/* pos 00da: 105 */ 0x00, 0x0E /* - terminal marker 14 - */,
/* pos 00dc: 106 */ 0xE3 /* 'c' -> */,
/* pos 00dd: 107 */ 0xE3 /* 'c' -> */,
/* pos 00de: 108 */ 0xE5 /* 'e' -> */,
/* pos 00df: 109 */ 0xF0 /* 'p' -> */,
/* pos 00e0: 110 */ 0xF4 /* 't' -> */,
/* pos 00e1: 111 */ 0xBA /* ':' -> */,
/* pos 00e2: 112 */ 0x00, 0x0F /* - terminal marker 15 - */,
/* pos 00e4: 113 */ 0xEF /* 'o' -> */,
/* pos 00e5: 114 */ 0xEE /* 'n' -> */,
/* pos 00e6: 115 */ 0xE3 /* 'c' -> */,
/* pos 00e7: 116 */ 0xE5 /* 'e' -> */,
/* pos 00e8: 117 */ 0xBA /* ':' -> */,
/* pos 00e9: 118 */ 0x00, 0x10 /* - terminal marker 16 - */,
/* pos 00eb: 119 */ 0xF4 /* 't' -> */,
/* pos 00ec: 120 */ 0xF0 /* 'p' -> */,
/* pos 00ed: 121 */ 0xAF /* '/' -> */,
/* pos 00ee: 122 */ 0xB1 /* '1' -> */,
/* pos 00ef: 123 */ 0xAE /* '.' -> */,
/* pos 00f0: 124 */ 0xB1 /* '1' -> */,
/* pos 00f1: 125 */ 0xA0 /* ' ' -> */,
/* pos 00f2: 126 */ 0x00, 0x11 /* - terminal marker 17 - */,
/* pos 00f4: 127 */ 0x63 /* 'c' */, 0x07, 0x00 /* (to 0x00FB state 128) */,
0x75 /* 'u' */, 0x54, 0x00 /* (to 0x014B state 190) */,
0x08, /* fail */
/* pos 00fb: 128 */ 0xE3 /* 'c' -> */,
/* pos 00fc: 129 */ 0xE5 /* 'e' -> */,
/* pos 00fd: 130 */ 0xF0 /* 'p' -> */,
/* pos 00fe: 131 */ 0xF4 /* 't' -> */,
/* pos 00ff: 132 */ 0x3A /* ':' */, 0x07, 0x00 /* (to 0x0106 state 133) */,
0x2D /* '-' */, 0x19, 0x00 /* (to 0x011B state 152) */,
0x08, /* fail */
/* pos 0106: 133 */ 0x00, 0x12 /* - terminal marker 18 - */,
/* pos 0108: 134 */ 0xE6 /* 'f' -> */,
/* pos 0109: 135 */ 0xAD /* '-' -> */,
/* pos 010a: 136 */ 0xED /* 'm' -> */,
/* pos 010b: 137 */ 0xEF /* 'o' -> */,
/* pos 010c: 138 */ 0xE4 /* 'd' -> */,
/* pos 010d: 139 */ 0xE9 /* 'i' -> */,
/* pos 010e: 140 */ 0xE6 /* 'f' -> */,
/* pos 010f: 141 */ 0xE9 /* 'i' -> */,
/* pos 0110: 142 */ 0xE5 /* 'e' -> */,
/* pos 0111: 143 */ 0xE4 /* 'd' -> */,
/* pos 0112: 144 */ 0xAD /* '-' -> */,
/* pos 0113: 145 */ 0xF3 /* 's' -> */,
/* pos 0114: 146 */ 0xE9 /* 'i' -> */,
/* pos 0115: 147 */ 0xEE /* 'n' -> */,
/* pos 0116: 148 */ 0xE3 /* 'c' -> */,
/* pos 0117: 149 */ 0xE5 /* 'e' -> */,
/* pos 0118: 150 */ 0xBA /* ':' -> */,
/* pos 0119: 151 */ 0x00, 0x13 /* - terminal marker 19 - */,
/* pos 011b: 152 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x0122 state 153) */,
0x6C /* 'l' */, 0x0E, 0x00 /* (to 0x012C state 162) */,
0x08, /* fail */
/* pos 0122: 153 */ 0xEE /* 'n' -> */,
/* pos 0123: 154 */ 0xE3 /* 'c' -> */,
/* pos 0124: 155 */ 0xEF /* 'o' -> */,
/* pos 0125: 156 */ 0xE4 /* 'd' -> */,
/* pos 0126: 157 */ 0xE9 /* 'i' -> */,
/* pos 0127: 158 */ 0xEE /* 'n' -> */,
/* pos 0128: 159 */ 0xE7 /* 'g' -> */,
/* pos 0129: 160 */ 0xBA /* ':' -> */,
/* pos 012a: 161 */ 0x00, 0x14 /* - terminal marker 20 - */,
/* pos 012c: 162 */ 0xE1 /* 'a' -> */,
/* pos 012d: 163 */ 0xEE /* 'n' -> */,
/* pos 012e: 164 */ 0xE7 /* 'g' -> */,
/* pos 012f: 165 */ 0xF5 /* 'u' -> */,
/* pos 0130: 166 */ 0xE1 /* 'a' -> */,
/* pos 0131: 167 */ 0xE7 /* 'g' -> */,
/* pos 0132: 168 */ 0xE5 /* 'e' -> */,
/* pos 0133: 169 */ 0xBA /* ':' -> */,
/* pos 0134: 170 */ 0x00, 0x15 /* - terminal marker 21 - */,
/* pos 0136: 171 */ 0xE1 /* 'a' -> */,
/* pos 0137: 172 */ 0xE7 /* 'g' -> */,
/* pos 0138: 173 */ 0xED /* 'm' -> */,
/* pos 0139: 174 */ 0xE1 /* 'a' -> */,
/* pos 013a: 175 */ 0xBA /* ':' -> */,
/* pos 013b: 176 */ 0x00, 0x16 /* - terminal marker 22 - */,
/* pos 013d: 177 */ 0xE3 /* 'c' -> */,
/* pos 013e: 178 */ 0xE8 /* 'h' -> */,
/* pos 013f: 179 */ 0xE5 /* 'e' -> */,
/* pos 0140: 180 */ 0xAD /* '-' -> */,
/* pos 0141: 181 */ 0xE3 /* 'c' -> */,
/* pos 0142: 182 */ 0xEF /* 'o' -> */,
/* pos 0143: 183 */ 0xEE /* 'n' -> */,
/* pos 0144: 184 */ 0xF4 /* 't' -> */,
/* pos 0145: 185 */ 0xF2 /* 'r' -> */,
/* pos 0146: 186 */ 0xEF /* 'o' -> */,
/* pos 0147: 187 */ 0xEC /* 'l' -> */,
/* pos 0148: 188 */ 0xBA /* ':' -> */,
/* pos 0149: 189 */ 0x00, 0x17 /* - terminal marker 23 - */,
/* pos 014b: 190 */ 0xF4 /* 't' -> */,
/* pos 014c: 191 */ 0xE8 /* 'h' -> */,
/* pos 014d: 192 */ 0xEF /* 'o' -> */,
/* pos 014e: 193 */ 0xF2 /* 'r' -> */,
/* pos 014f: 194 */ 0xE9 /* 'i' -> */,
/* pos 0150: 195 */ 0xFA /* 'z' -> */,
/* pos 0151: 196 */ 0xE1 /* 'a' -> */,
/* pos 0152: 197 */ 0xF4 /* 't' -> */,
/* pos 0153: 198 */ 0xE9 /* 'i' -> */,
/* pos 0154: 199 */ 0xEF /* 'o' -> */,
/* pos 0155: 200 */ 0xEE /* 'n' -> */,
/* pos 0156: 201 */ 0xBA /* ':' -> */,
/* pos 0157: 202 */ 0x00, 0x18 /* - terminal marker 24 - */,
/* pos 0159: 203 */ 0xEB /* 'k' -> */,
/* pos 015a: 204 */ 0xE9 /* 'i' -> */,
/* pos 015b: 205 */ 0xE5 /* 'e' -> */,
/* pos 015c: 206 */ 0xBA /* ':' -> */,
/* pos 015d: 207 */ 0x00, 0x19 /* - terminal marker 25 - */,
/* pos 015f: 208 */ 0xE5 /* 'e' -> */,
/* pos 0160: 209 */ 0xEE /* 'n' -> */,
/* pos 0161: 210 */ 0xF4 /* 't' -> */,
/* pos 0162: 211 */ 0xAD /* '-' -> */,
/* pos 0163: 212 */ 0x6C /* 'l' */, 0x07, 0x00 /* (to 0x016A state 213) */,
0x74 /* 't' */, 0x0C, 0x00 /* (to 0x0172 state 220) */,
0x08, /* fail */
/* pos 016a: 213 */ 0xE5 /* 'e' -> */,
/* pos 016b: 214 */ 0xEE /* 'n' -> */,
/* pos 016c: 215 */ 0xE7 /* 'g' -> */,
/* pos 016d: 216 */ 0xF4 /* 't' -> */,
/* pos 016e: 217 */ 0xE8 /* 'h' -> */,
/* pos 016f: 218 */ 0xBA /* ':' -> */,
/* pos 0170: 219 */ 0x00, 0x1A /* - terminal marker 26 - */,
/* pos 0172: 220 */ 0xF9 /* 'y' -> */,
/* pos 0173: 221 */ 0xF0 /* 'p' -> */,
/* pos 0174: 222 */ 0xE5 /* 'e' -> */,
/* pos 0175: 223 */ 0xBA /* ':' -> */,
/* pos 0176: 224 */ 0x00, 0x1B /* - terminal marker 27 - */,
/* pos 0178: 225 */ 0xE1 /* 'a' -> */,
/* pos 0179: 226 */ 0xF4 /* 't' -> */,
/* pos 017a: 227 */ 0xE5 /* 'e' -> */,
/* pos 017b: 228 */ 0xBA /* ':' -> */,
/* pos 017c: 229 */ 0x00, 0x1C /* - terminal marker 28 - */,
/* pos 017e: 230 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x0185 state 231) */,
0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x018B state 236) */,
0x08, /* fail */
/* pos 0185: 231 */ 0xEE /* 'n' -> */,
/* pos 0186: 232 */ 0xE7 /* 'g' -> */,
/* pos 0187: 233 */ 0xE5 /* 'e' -> */,
/* pos 0188: 234 */ 0xBA /* ':' -> */,
/* pos 0189: 235 */ 0x00, 0x1D /* - terminal marker 29 - */,
/* pos 018b: 236 */ 0xE6 /* 'f' -> */,
/* pos 018c: 237 */ 0xE5 /* 'e' -> */,
/* pos 018d: 238 */ 0xF2 /* 'r' -> */,
/* pos 018e: 239 */ 0xE5 /* 'e' -> */,
/* pos 018f: 240 */ 0xF2 /* 'r' -> */,
/* pos 0190: 241 */ 0xBA /* ':' -> */,
/* pos 0191: 242 */ 0x00, 0x1E /* - terminal marker 30 - */,
/* total size 403 bytes */
+766
View File
@@ -0,0 +1,766 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
#if HOST_OS == OS_WINDOWS
#pragma comment(lib, "Ws2_32.lib")
#endif
int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE;
static void (*lwsl_emit)(int level, const char *line) = lwsl_emit_stderr;
static const char * const log_level_names[] = {
"ERR",
"WARN",
"NOTICE",
"INFO",
"DEBUG",
"PARSER",
"HEADER",
"EXTENSION",
"CLIENT",
"LATENCY",
};
void
libwebsocket_close_and_free_session(struct libwebsocket_context *context,
struct libwebsocket *wsi, enum lws_close_status reason)
{
int n, m, ret;
int old_state;
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
LWS_SEND_BUFFER_POST_PADDING];
struct lws_tokens eff_buf;
if (!wsi)
return;
old_state = wsi->state;
switch (old_state) {
case WSI_STATE_DEAD_SOCKET:
return;
/* we tried the polite way... */
case WSI_STATE_AWAITING_CLOSE_ACK:
goto just_kill_connection;
case WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE:
if (wsi->truncated_send_len) {
libwebsocket_callback_on_writable(context, wsi);
return;
}
lwsl_info("wsi %p completed WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
goto just_kill_connection;
default:
if (wsi->truncated_send_len) {
lwsl_info("wsi %p entering WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
wsi->state = WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE;
return;
}
break;
}
wsi->u.ws.close_reason = reason;
if (wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT ||
wsi->mode == LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE) {
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_CLIENT_CONNECTION_ERROR, NULL, NULL, 0);
free(wsi->u.hdr.ah);
goto just_kill_connection;
}
if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) {
if (wsi->u.http.post_buffer) {
free(wsi->u.http.post_buffer);
wsi->u.http.post_buffer = NULL;
}
if (wsi->u.http.fd != LWS_INVALID_FILE) {
lwsl_debug("closing http file\n");
compatible_file_close(wsi->u.http.fd);
wsi->u.http.fd = LWS_INVALID_FILE;
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
}
}
/*
* are his extensions okay with him closing? Eg he might be a mux
* parent and just his ch1 aspect is closing?
*/
if (lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_CHECK_OK_TO_REALLY_CLOSE, NULL, 0) > 0) {
lwsl_ext("extension vetoed close\n");
return;
}
/*
* flush any tx pending from extensions, since we may send close packet
* if there are problems with send, just nuke the connection
*/
do {
ret = 0;
eff_buf.token = NULL;
eff_buf.token_len = 0;
/* show every extension the new incoming data */
m = lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_FLUSH_PENDING_TX, &eff_buf, 0);
if (m < 0) {
lwsl_ext("Extension reports fatal error\n");
goto just_kill_connection;
}
if (m)
/*
* at least one extension told us he has more
* to spill, so we will go around again after
*/
ret = 1;
/* assuming they left us something to send, send it */
if (eff_buf.token_len)
if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
eff_buf.token_len) != eff_buf.token_len) {
lwsl_debug("close: ext spill failed\n");
goto just_kill_connection;
}
} while (ret);
/*
* signal we are closing, libsocket_write will
* add any necessary version-specific stuff. If the write fails,
* no worries we are closing anyway. If we didn't initiate this
* close, then our state has been changed to
* WSI_STATE_RETURNED_CLOSE_ALREADY and we will skip this.
*
* Likewise if it's a second call to close this connection after we
* sent the close indication to the peer already, we are in state
* WSI_STATE_AWAITING_CLOSE_ACK and will skip doing this a second time.
*/
if (old_state == WSI_STATE_ESTABLISHED &&
reason != LWS_CLOSE_STATUS_NOSTATUS) {
lwsl_debug("sending close indication...\n");
/* make valgrind happy */
memset(buf, 0, sizeof(buf));
n = libwebsocket_write(wsi,
&buf[LWS_SEND_BUFFER_PRE_PADDING + 2],
0, LWS_WRITE_CLOSE);
if (n >= 0) {
/*
* we have sent a nice protocol level indication we
* now wish to close, we should not send anything more
*/
wsi->state = WSI_STATE_AWAITING_CLOSE_ACK;
/*
* ...and we should wait for a reply for a bit
* out of politeness
*/
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_CLOSE_ACK, 1);
lwsl_debug("sent close indication, awaiting ack\n");
return;
}
lwsl_info("close: sending close packet failed, hanging up\n");
/* else, the send failed and we should just hang up */
}
just_kill_connection:
lwsl_debug("close: just_kill_connection\n");
/*
* we won't be servicing or receiving anything further from this guy
* delete socket from the internal poll list if still present
*/
remove_wsi_socket_from_fds(context, wsi);
wsi->state = WSI_STATE_DEAD_SOCKET;
if ((old_state == WSI_STATE_ESTABLISHED ||
wsi->mode == LWS_CONNMODE_WS_SERVING ||
wsi->mode == LWS_CONNMODE_WS_CLIENT)) {
if (wsi->u.ws.rx_user_buffer) {
free(wsi->u.ws.rx_user_buffer);
wsi->u.ws.rx_user_buffer = NULL;
}
if (wsi->u.ws.rxflow_buffer) {
free(wsi->u.ws.rxflow_buffer);
wsi->u.ws.rxflow_buffer = NULL;
}
if (wsi->truncated_send_malloc) {
/* not going to be completed... nuke it */
free(wsi->truncated_send_malloc);
wsi->truncated_send_malloc = NULL;
wsi->truncated_send_len = 0;
}
}
/* tell the user it's all over for this guy */
if (wsi->protocol && wsi->protocol->callback &&
((old_state == WSI_STATE_ESTABLISHED) ||
(old_state == WSI_STATE_RETURNED_CLOSE_ALREADY) ||
(old_state == WSI_STATE_AWAITING_CLOSE_ACK))) {
lwsl_debug("calling back CLOSED\n");
wsi->protocol->callback(context, wsi, LWS_CALLBACK_CLOSED,
wsi->user_space, NULL, 0);
} else if (wsi->mode == LWS_CONNMODE_HTTP_SERVING_ACCEPTED) {
lwsl_debug("calling back CLOSED_HTTP\n");
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0 );
} else
lwsl_debug("not calling back closed\n");
/* deallocate any active extension contexts */
if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_DESTROY, NULL, 0) < 0)
lwsl_warn("extension destruction failed\n");
#ifndef LWS_NO_EXTENSIONS
for (n = 0; n < wsi->count_active_extensions; n++)
free(wsi->active_extensions_user[n]);
#endif
/*
* inform all extensions in case they tracked this guy out of band
* even though not active on him specifically
*/
if (lws_ext_callback_for_each_extension_type(context, wsi,
LWS_EXT_CALLBACK_DESTROY_ANY_WSI_CLOSING, NULL, 0) < 0)
lwsl_warn("ext destroy wsi failed\n");
/* lwsl_info("closing fd=%d\n", wsi->sock); */
if (!lws_ssl_close(wsi) && wsi->sock >= 0) {
n = shutdown(wsi->sock, SHUT_RDWR);
if (n)
lwsl_debug("closing: shutdown ret %d\n", LWS_ERRNO);
n = compatible_close(wsi->sock);
if (n)
lwsl_debug("closing: close ret %d\n", LWS_ERRNO);
}
/* outermost destroy notification for wsi (user_space still intact) */
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_WSI_DESTROY, wsi->user_space, NULL, 0);
if (wsi->protocol && wsi->protocol->per_session_data_size &&
wsi->user_space) /* user code may own */
free(wsi->user_space);
free(wsi);
}
/**
* libwebsockets_get_peer_addresses() - Get client address information
* @context: Libwebsockets context
* @wsi: Local struct libwebsocket associated with
* @fd: Connection socket descriptor
* @name: Buffer to take client address name
* @name_len: Length of client address name buffer
* @rip: Buffer to take client address IP qotted quad
* @rip_len: Length of client address IP buffer
*
* This function fills in @name and @rip with the name and IP of
* the client connected with socket descriptor @fd. Names may be
* truncated if there is not enough room. If either cannot be
* determined, they will be returned as valid zero-length strings.
*/
LWS_VISIBLE void
libwebsockets_get_peer_addresses(struct libwebsocket_context *context,
struct libwebsocket *wsi, int fd, char *name, int name_len,
char *rip, int rip_len)
{
socklen_t len;
#ifdef LWS_USE_IPV6
struct sockaddr_in6 sin6;
#endif
struct sockaddr_in sin4;
struct hostent *host;
struct hostent *host1;
char ip[128];
unsigned char *p;
int n;
#ifdef AF_LOCAL
struct sockaddr_un *un;
#endif
int ret = -1;
rip[0] = '\0';
name[0] = '\0';
lws_latency_pre(context, wsi);
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) {
len = sizeof(sin6);
if (getpeername(fd, (struct sockaddr *) &sin6, &len) < 0) {
lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
goto bail;
}
if (!lws_plat_inet_ntop(AF_INET6, &sin6.sin6_addr, rip, rip_len)) {
lwsl_err("inet_ntop", strerror(LWS_ERRNO));
goto bail;
}
// Strip off the IPv4 to IPv6 header if one exists
if (strncmp(rip, "::ffff:", 7) == 0)
memmove(rip, rip + 7, strlen(rip) - 6);
getnameinfo((struct sockaddr *)&sin6,
sizeof(struct sockaddr_in6), name,
name_len, NULL, 0, 0);
} else
#endif
{
len = sizeof(sin4);
if (getpeername(fd, (struct sockaddr *) &sin4, &len) < 0) {
lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO));
goto bail;
}
host = gethostbyaddr((char *) &sin4.sin_addr,
sizeof(sin4.sin_addr), AF_INET);
if (host == NULL) {
lwsl_warn("gethostbyaddr: %s\n", strerror(LWS_ERRNO));
goto bail;
}
strncpy(name, host->h_name, name_len);
name[name_len - 1] = '\0';
host1 = gethostbyname(host->h_name);
if (host1 == NULL)
goto bail;
p = (unsigned char *)host1;
n = 0;
while (p != NULL) {
p = (unsigned char *)host1->h_addr_list[n++];
if (p == NULL)
continue;
if ((host1->h_addrtype != AF_INET)
#ifdef AF_LOCAL
&& (host1->h_addrtype != AF_LOCAL)
#endif
)
continue;
if (host1->h_addrtype == AF_INET)
sprintf(ip, "%u.%u.%u.%u",
p[0], p[1], p[2], p[3]);
#ifdef AF_LOCAL
else {
un = (struct sockaddr_un *)p;
strncpy(ip, un->sun_path, sizeof(ip) - 1);
ip[sizeof(ip) - 1] = '\0';
}
#endif
p = NULL;
strncpy(rip, ip, rip_len);
rip[rip_len - 1] = '\0';
}
}
ret = 0;
bail:
lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1);
}
/**
* libwebsocket_context_user() - get the user data associated with the context
* @context: Websocket context
*
* This returns the optional user allocation that can be attached to
* the context the sockets live in at context_create time. It's a way
* to let all sockets serviced in the same context share data without
* using globals statics in the user code.
*/
LWS_EXTERN void *
libwebsocket_context_user(struct libwebsocket_context *context)
{
return context->user_space;
}
/**
* libwebsocket_callback_all_protocol() - Callback all connections using
* the given protocol with the given reason
*
* @protocol: Protocol whose connections will get callbacks
* @reason: Callback reason index
*/
LWS_VISIBLE int
libwebsocket_callback_all_protocol(
const struct libwebsocket_protocols *protocol, int reason)
{
struct libwebsocket_context *context = protocol->owning_server;
int n;
struct libwebsocket *wsi;
for (n = 0; n < context->fds_count; n++) {
wsi = context->lws_lookup[context->fds[n].fd];
if (!wsi)
continue;
if (wsi->protocol == protocol)
protocol->callback(context, wsi,
reason, wsi->user_space, NULL, 0);
}
return 0;
}
/**
* libwebsocket_set_timeout() - marks the wsi as subject to a timeout
*
* You will not need this unless you are doing something special
*
* @wsi: Websocket connection instance
* @reason: timeout reason
* @secs: how many seconds
*/
LWS_VISIBLE void
libwebsocket_set_timeout(struct libwebsocket *wsi,
enum pending_timeout reason, int secs)
{
time_t now;
time(&now);
wsi->pending_timeout_limit = now + secs;
wsi->pending_timeout = reason;
}
/**
* libwebsocket_get_socket_fd() - returns the socket file descriptor
*
* You will not need this unless you are doing something special
*
* @wsi: Websocket connection instance
*/
LWS_VISIBLE int
libwebsocket_get_socket_fd(struct libwebsocket *wsi)
{
return wsi->sock;
}
#ifdef LWS_LATENCY
void
lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi,
const char *action, int ret, int completed)
{
unsigned long long u;
char buf[256];
u = time_in_microseconds();
if (!action) {
wsi->latency_start = u;
if (!wsi->action_start)
wsi->action_start = u;
return;
}
if (completed) {
if (wsi->action_start == wsi->latency_start)
sprintf(buf,
"Completion first try lat %luus: %p: ret %d: %s\n",
u - wsi->latency_start,
(void *)wsi, ret, action);
else
sprintf(buf,
"Completion %luus: lat %luus: %p: ret %d: %s\n",
u - wsi->action_start,
u - wsi->latency_start,
(void *)wsi, ret, action);
wsi->action_start = 0;
} else
sprintf(buf, "lat %luus: %p: ret %d: %s\n",
u - wsi->latency_start, (void *)wsi, ret, action);
if (u - wsi->latency_start > context->worst_latency) {
context->worst_latency = u - wsi->latency_start;
strcpy(context->worst_latency_info, buf);
}
lwsl_latency("%s", buf);
}
#endif
/**
* libwebsocket_rx_flow_control() - Enable and disable socket servicing for
* receieved packets.
*
* If the output side of a server process becomes choked, this allows flow
* control for the input side.
*
* @wsi: Websocket connection instance to get callback for
* @enable: 0 = disable read servicing for this connection, 1 = enable
*/
LWS_VISIBLE int
libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable)
{
if (enable == (wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW))
return 0;
lwsl_info("libwebsocket_rx_flow_control(0x%p, %d)\n", wsi, enable);
wsi->u.ws.rxflow_change_to = LWS_RXFLOW_PENDING_CHANGE | !!enable;
return 0;
}
/**
* libwebsocket_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive
*
* When the user server code realizes it can accept more input, it can
* call this to have the RX flow restriction removed from all connections using
* the given protocol.
*
* @protocol: all connections using this protocol will be allowed to receive
*/
LWS_VISIBLE void
libwebsocket_rx_flow_allow_all_protocol(
const struct libwebsocket_protocols *protocol)
{
struct libwebsocket_context *context = protocol->owning_server;
int n;
struct libwebsocket *wsi;
for (n = 0; n < context->fds_count; n++) {
wsi = context->lws_lookup[context->fds[n].fd];
if (!wsi)
continue;
if (wsi->protocol == protocol)
libwebsocket_rx_flow_control(wsi, LWS_RXFLOW_ALLOW);
}
}
/**
* libwebsocket_canonical_hostname() - returns this host's hostname
*
* This is typically used by client code to fill in the host parameter
* when making a client connection. You can only call it after the context
* has been created.
*
* @context: Websocket context
*/
LWS_VISIBLE extern const char *
libwebsocket_canonical_hostname(struct libwebsocket_context *context)
{
return (const char *)context->canonical_hostname;
}
int user_callback_handle_rxflow(callback_function callback_function,
struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len)
{
int n;
n = callback_function(context, wsi, reason, user, in, len);
if (!n)
n = _libwebsocket_rx_flow_control(wsi);
return n;
}
/**
* libwebsocket_set_proxy() - Setups proxy to libwebsocket_context.
* @context: pointer to struct libwebsocket_context you want set proxy to
* @proxy: pointer to c string containing proxy in format address:port
*
* Returns 0 if proxy string was parsed and proxy was setup.
* Returns -1 if @proxy is NULL or has incorrect format.
*
* This is only required if your OS does not provide the http_proxy
* enviroment variable (eg, OSX)
*
* IMPORTANT! You should call this function right after creation of the
* libwebsocket_context and before call to connect. If you call this
* function after connect behavior is undefined.
* This function will override proxy settings made on libwebsocket_context
* creation with genenv() call.
*/
LWS_VISIBLE int
libwebsocket_set_proxy(struct libwebsocket_context *context, const char *proxy)
{
char *p;
if (!proxy)
return -1;
strncpy(context->http_proxy_address, proxy,
sizeof(context->http_proxy_address) - 1);
context->http_proxy_address[
sizeof(context->http_proxy_address) - 1] = '\0';
p = strchr(context->http_proxy_address, ':');
if (!p) {
lwsl_err("http_proxy needs to be ads:port\n");
return -1;
}
*p = '\0';
context->http_proxy_port = atoi(p + 1);
lwsl_notice(" Proxy %s:%u\n", context->http_proxy_address,
context->http_proxy_port);
return 0;
}
/**
* libwebsockets_get_protocol() - Returns a protocol pointer from a websocket
* connection.
* @wsi: pointer to struct websocket you want to know the protocol of
*
*
* Some apis can act on all live connections of a given protocol,
* this is how you can get a pointer to the active protocol if needed.
*/
LWS_VISIBLE const struct libwebsocket_protocols *
libwebsockets_get_protocol(struct libwebsocket *wsi)
{
return wsi->protocol;
}
LWS_VISIBLE int
libwebsocket_is_final_fragment(struct libwebsocket *wsi)
{
return wsi->u.ws.final;
}
LWS_VISIBLE unsigned char
libwebsocket_get_reserved_bits(struct libwebsocket *wsi)
{
return wsi->u.ws.rsv;
}
int
libwebsocket_ensure_user_space(struct libwebsocket *wsi)
{
if (!wsi->protocol)
return 1;
/* allocate the per-connection user memory (if any) */
if (wsi->protocol->per_session_data_size && !wsi->user_space) {
wsi->user_space = malloc(
wsi->protocol->per_session_data_size);
if (wsi->user_space == NULL) {
lwsl_err("Out of memory for conn user space\n");
return 1;
}
memset(wsi->user_space, 0,
wsi->protocol->per_session_data_size);
}
return 0;
}
LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line)
{
char buf[300];
unsigned long long now;
int n;
buf[0] = '\0';
for (n = 0; n < LLL_COUNT; n++)
if (level == (1 << n)) {
now = time_in_microseconds() / 100;
sprintf(buf, "[%lu:%04d] %s: ", (unsigned long) now / 10000,
(int)(now % 10000), log_level_names[n]);
break;
}
fprintf(stderr, "%s%s", buf, line);
}
LWS_VISIBLE void _lws_log(int filter, const char *format, ...)
{
char buf[256];
va_list ap;
if (!(log_level & filter))
return;
va_start(ap, format);
vsnprintf(buf, sizeof(buf), format, ap);
buf[sizeof(buf) - 1] = '\0';
va_end(ap);
lwsl_emit(filter, buf);
}
/**
* lws_set_log_level() - Set the logging bitfield
* @level: OR together the LLL_ debug contexts you want output from
* @log_emit_function: NULL to leave it as it is, or a user-supplied
* function to perform log string emission instead of
* the default stderr one.
*
* log level defaults to "err", "warn" and "notice" contexts enabled and
* emission on stderr.
*/
LWS_VISIBLE void lws_set_log_level(int level, void (*log_emit_function)(int level,
const char *line))
{
log_level = level;
if (log_emit_function)
lwsl_emit = log_emit_function;
}
File diff suppressed because it is too large. Load diff
+396
View File
@@ -0,0 +1,396 @@
#include "private-libwebsockets.h"
#include "build.h"
#if HOST_OS != OS_WINDOWS
/*
* included from libwebsockets.c for unix builds
*/
unsigned long long time_in_microseconds(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000000) + tv.tv_usec;
}
LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context,
void *buf, int len)
{
return read(context->fd_random, (char *)buf, len);
}
LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi)
{
struct libwebsocket_pollfd fds;
/* treat the fact we got a truncated send pending as if we're choked */
if (wsi->truncated_send_len)
return 1;
fds.fd = wsi->sock;
fds.events = POLLOUT;
fds.revents = 0;
if (poll(&fds, 1, 0) != 1)
return 1;
if ((fds.revents & POLLOUT) == 0)
return 1;
/* okay to send another packet without blocking */
return 0;
}
LWS_VISIBLE int
lws_poll_listen_fd(struct libwebsocket_pollfd *fd)
{
return poll(fd, 1, 0);
}
/*
* This is just used to interrupt poll waiting
* we don't have to do anything with it.
*/
static void lws_sigusr2(int sig)
{
}
/**
* libwebsocket_cancel_service() - Cancel servicing of pending websocket activity
* @context: Websocket context
*
* This function let a call to libwebsocket_service() waiting for a timeout
* immediately return.
*/
LWS_VISIBLE void
libwebsocket_cancel_service(struct libwebsocket_context *context)
{
char buf = 0;
if (write(context->dummy_pipe_fds[1], &buf, sizeof(buf)) != 1)
lwsl_err("Cannot write to dummy pipe");
}
LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
{
/*
int syslog_level = LOG_DEBUG;
switch (level) {
case LLL_ERR:
syslog_level = LOG_ERR;
break;
case LLL_WARN:
syslog_level = LOG_WARNING;
break;
case LLL_NOTICE:
syslog_level = LOG_NOTICE;
break;
case LLL_INFO:
syslog_level = LOG_INFO;
break;
}
*/
printf("%s", line);
}
LWS_VISIBLE int
lws_plat_service(struct libwebsocket_context *context, int timeout_ms)
{
int n;
int m;
char buf;
/* stay dead once we are dead */
if (!context)
return 1;
lws_libev_run(context);
context->service_tid = context->protocols[0].callback(context, NULL,
LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
n = poll(context->fds, context->fds_count, timeout_ms);
context->service_tid = 0;
if (n == 0) /* poll timeout */ {
libwebsocket_service_fd(context, NULL);
return 0;
}
if (n < 0) {
if (LWS_ERRNO != LWS_EINTR)
return -1;
return 0;
}
/* any socket with events to service? */
for (n = 0; n < context->fds_count; n++) {
if (!context->fds[n].revents)
continue;
if (context->fds[n].fd == context->dummy_pipe_fds[0]) {
if (read(context->fds[n].fd, &buf, 1) != 1)
lwsl_err("Cannot read from dummy pipe.");
continue;
}
m = libwebsocket_service_fd(context, &context->fds[n]);
if (m < 0)
return -1;
/* if something closed, retry this slot */
if (m)
n--;
}
return 0;
}
LWS_VISIBLE int
lws_plat_set_socket_options(struct libwebsocket_context *context, int fd)
{
int optval = 1;
socklen_t optlen = sizeof(optval);
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
struct protoent *tcp_proto;
#endif
if (context->ka_time) {
/* enable keepalive on this socket */
optval = 1;
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
(const void *)&optval, optlen) < 0)
return 1;
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__CYGWIN__)
/*
* didn't find a way to set these per-socket, need to
* tune kernel systemwide values
*/
#else
/* set the keepalive conditions we want on it too */
optval = context->ka_time;
if (setsockopt(fd, IPPROTO_IP, TCP_KEEPIDLE,
(const void *)&optval, optlen) < 0)
return 1;
optval = context->ka_interval;
if (setsockopt(fd, IPPROTO_IP, TCP_KEEPINTVL,
(const void *)&optval, optlen) < 0)
return 1;
optval = context->ka_probes;
if (setsockopt(fd, IPPROTO_IP, TCP_KEEPCNT,
(const void *)&optval, optlen) < 0)
return 1;
#endif
}
/* Disable Nagle */
optval = 1;
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *)&optval, optlen);
#else
tcp_proto = getprotobyname("TCP");
setsockopt(fd, tcp_proto->p_proto, TCP_NODELAY, &optval, optlen);
#endif
/* We are nonblocking... */
fcntl(fd, F_SETFL, O_NONBLOCK);
return 0;
}
LWS_VISIBLE void
lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
{
if (info->gid != -1)
if (setgid(info->gid))
lwsl_warn("setgid: %s\n", strerror(LWS_ERRNO));
if (info->uid != -1)
if (setuid(info->uid))
lwsl_warn("setuid: %s\n", strerror(LWS_ERRNO));
}
LWS_VISIBLE int
lws_plat_init_fd_tables(struct libwebsocket_context *context)
{
if (lws_libev_init_fd_table(context))
/* libev handled it instead */
return 0;
if (pipe(context->dummy_pipe_fds)) {
lwsl_err("Unable to create pipe\n");
return 1;
}
/* use the read end of pipe as first item */
context->fds[0].fd = context->dummy_pipe_fds[0];
context->fds[0].events = LWS_POLLIN;
context->fds[0].revents = 0;
context->fds_count = 1;
context->fd_random = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY);
if (context->fd_random < 0) {
lwsl_err("Unable to open random device %s %d\n",
SYSTEM_RANDOM_FILEPATH, context->fd_random);
return 1;
}
return 0;
}
static void sigpipe_handler(int x)
{
}
LWS_VISIBLE int
lws_plat_context_early_init(void)
{
sigset_t mask;
signal(SIGUSR2, lws_sigusr2);
sigemptyset(&mask);
sigaddset(&mask, SIGUSR2);
sigprocmask(SIG_BLOCK, &mask, NULL);
signal(SIGPIPE, sigpipe_handler);
return 0;
}
LWS_VISIBLE void
lws_plat_context_early_destroy(struct libwebsocket_context *context)
{
}
LWS_VISIBLE void
lws_plat_context_late_destroy(struct libwebsocket_context *context)
{
close(context->dummy_pipe_fds[0]);
close(context->dummy_pipe_fds[1]);
close(context->fd_random);
}
/* cast a struct sockaddr_in6 * into addr for ipv6 */
LWS_VISIBLE int
interface_to_sa(struct libwebsocket_context *context,
const char *ifname, struct sockaddr_in *addr, size_t addrlen)
{
int rc = -1;
struct ifaddrs *ifr;
struct ifaddrs *ifc;
#ifdef LWS_USE_IPV6
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
#endif
getifaddrs(&ifr);
for (ifc = ifr; ifc != NULL && rc; ifc = ifc->ifa_next) {
if (!ifc->ifa_addr)
continue;
lwsl_info(" interface %s vs %s\n", ifc->ifa_name, ifname);
if (strcmp(ifc->ifa_name, ifname))
continue;
switch (ifc->ifa_addr->sa_family) {
case AF_INET:
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) {
/* map IPv4 to IPv6 */
bzero((char *)&addr6->sin6_addr,
sizeof(struct in6_addr));
addr6->sin6_addr.s6_addr[10] = 0xff;
addr6->sin6_addr.s6_addr[11] = 0xff;
memcpy(&addr6->sin6_addr.s6_addr[12],
&((struct sockaddr_in *)ifc->ifa_addr)->sin_addr,
sizeof(struct in_addr));
} else
#endif
memcpy(addr,
(struct sockaddr_in *)ifc->ifa_addr,
sizeof(struct sockaddr_in));
break;
#ifdef LWS_USE_IPV6
case AF_INET6:
if (rc >= 0)
break;
memcpy(&addr6->sin6_addr,
&((struct sockaddr_in6 *)ifc->ifa_addr)->sin6_addr,
sizeof(struct in6_addr));
break;
#endif
default:
continue;
}
rc = 0;
}
freeifaddrs(ifr);
return rc;
}
LWS_VISIBLE void
lws_plat_insert_socket_into_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi)
{
lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_READ);
context->fds[context->fds_count++].revents = 0;
}
LWS_VISIBLE void
lws_plat_delete_socket_from_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi, int m)
{
}
LWS_VISIBLE void
lws_plat_service_periodic(struct libwebsocket_context *context)
{
/* if our parent went down, don't linger around */
if (context->started_with_parent &&
kill(context->started_with_parent, 0) < 0)
kill(getpid(), SIGTERM);
}
LWS_VISIBLE int
lws_plat_change_pollfd(struct libwebsocket_context *context,
struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd)
{
return 0;
}
LWS_VISIBLE int
lws_plat_open_file(const char* filename, unsigned long* filelen)
{
struct stat stat_buf;
int ret = open(filename, O_RDONLY);
if (ret < 0)
return LWS_INVALID_FILE;
fstat(ret, &stat_buf);
*filelen = stat_buf.st_size;
return ret;
}
#ifdef LWS_USE_IPV6
LWS_VISIBLE const char *
lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
{
return inet_ntop(af, src, dst, cnt);
}
#endif
#endif
+365
View File
@@ -0,0 +1,365 @@
#include "private-libwebsockets.h"
#include "build.h"
#if HOST_OS == OS_WINDOWS
unsigned long long
time_in_microseconds()
{
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
FILETIME filetime;
ULARGE_INTEGER datetime;
#ifdef _WIN32_WCE
GetCurrentFT(&filetime);
#else
GetSystemTimeAsFileTime(&filetime);
#endif
/*
* As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a
* ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can
* prevent alignment faults on 64-bit Windows).
*/
memcpy(&datetime, &filetime, sizeof(datetime));
/* Windows file times are in 100s of nanoseconds. */
return (datetime.QuadPart - DELTA_EPOCH_IN_MICROSECS) / 10;
}
#ifdef _WIN32_WCE
time_t time(time_t *t)
{
time_t ret = time_in_microseconds() / 1000000;
*t = ret;
return ret;
}
#endif
LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context,
void *buf, int len)
{
int n;
char *p = (char *)buf;
for (n = 0; n < len; n++)
p[n] = (unsigned char)rand();
return n;
}
LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi)
{
return wsi->sock_send_blocking;
}
LWS_VISIBLE int lws_poll_listen_fd(struct libwebsocket_pollfd *fd)
{
fd_set readfds;
struct timeval tv = { 0, 0 };
assert(fd->events == LWS_POLLIN);
FD_ZERO(&readfds);
FD_SET(fd->fd, &readfds);
return select(fd->fd + 1, &readfds, NULL, NULL, &tv);
}
/**
* libwebsocket_cancel_service() - Cancel servicing of pending websocket activity
* @context: Websocket context
*
* This function let a call to libwebsocket_service() waiting for a timeout
* immediately return.
*/
LWS_VISIBLE void
libwebsocket_cancel_service(struct libwebsocket_context *context)
{
WSASetEvent(context->events[0]);
}
LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
{
lwsl_emit_stderr(level, line);
}
LWS_VISIBLE int
lws_plat_service(struct libwebsocket_context *context, int timeout_ms)
{
int n;
int i;
DWORD ev;
WSANETWORKEVENTS networkevents;
struct libwebsocket_pollfd *pfd;
/* stay dead once we are dead */
if (context == NULL)
return 1;
context->service_tid = context->protocols[0].callback(context, NULL,
LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
for (i = 0; i < context->fds_count; ++i) {
pfd = &context->fds[i];
if (pfd->fd == context->listen_service_fd)
continue;
if (pfd->events & LWS_POLLOUT) {
if (context->lws_lookup[pfd->fd]->sock_send_blocking)
continue;
pfd->revents = LWS_POLLOUT;
n = libwebsocket_service_fd(context, pfd);
if (n < 0)
return n;
}
}
ev = WSAWaitForMultipleEvents(context->fds_count + 1,
context->events, FALSE, timeout_ms, FALSE);
context->service_tid = 0;
if (ev == WSA_WAIT_TIMEOUT) {
libwebsocket_service_fd(context, NULL);
return 0;
}
if (ev == WSA_WAIT_EVENT_0) {
WSAResetEvent(context->events[0]);
return 0;
}
if (ev < WSA_WAIT_EVENT_0 || ev > WSA_WAIT_EVENT_0 + context->fds_count)
return -1;
pfd = &context->fds[ev - WSA_WAIT_EVENT_0 - 1];
if (WSAEnumNetworkEvents(pfd->fd,
context->events[ev - WSA_WAIT_EVENT_0],
&networkevents) == SOCKET_ERROR) {
lwsl_err("WSAEnumNetworkEvents() failed with error %d\n",
LWS_ERRNO);
return -1;
}
pfd->revents = networkevents.lNetworkEvents;
if (pfd->revents & LWS_POLLOUT)
context->lws_lookup[pfd->fd]->sock_send_blocking = FALSE;
return libwebsocket_service_fd(context, pfd);
}
LWS_VISIBLE int
lws_plat_set_socket_options(struct libwebsocket_context *context, int fd)
{
int optval = 1;
int optlen = sizeof(optval);
u_long optl = 1;
DWORD dwBytesRet;
struct tcp_keepalive alive;
struct protoent *tcp_proto;
if (context->ka_time) {
/* enable keepalive on this socket */
optval = 1;
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
(const char *)&optval, optlen) < 0)
return 1;
alive.onoff = TRUE;
alive.keepalivetime = context->ka_time;
alive.keepaliveinterval = context->ka_interval;
if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),
NULL, 0, &dwBytesRet, NULL, NULL))
return 1;
}
/* Disable Nagle */
optval = 1;
tcp_proto = getprotobyname("TCP");
setsockopt(fd, tcp_proto->p_proto, TCP_NODELAY, (const char *)&optval, optlen);
/* We are nonblocking... */
ioctlsocket(fd, FIONBIO, &optl);
return 0;
}
LWS_VISIBLE void
lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
{
}
LWS_VISIBLE int
lws_plat_init_fd_tables(struct libwebsocket_context *context)
{
context->events = (WSAEVENT *)malloc(sizeof(WSAEVENT) *
(context->max_fds + 1));
if (context->events == NULL) {
lwsl_err("Unable to allocate events array for %d connections\n",
context->max_fds);
return 1;
}
context->fds_count = 0;
context->events[0] = WSACreateEvent();
context->fd_random = 0;
return 0;
}
LWS_VISIBLE int
lws_plat_context_early_init(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
/* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (!err)
return 0;
/*
* Tell the user that we could not find a usable
* Winsock DLL
*/
lwsl_err("WSAStartup failed with error: %d\n", err);
return 1;
}
LWS_VISIBLE void
lws_plat_context_early_destroy(struct libwebsocket_context *context)
{
if (context->events) {
WSACloseEvent(context->events[0]);
free(context->events);
}
}
LWS_VISIBLE void
lws_plat_context_late_destroy(struct libwebsocket_context *context)
{
WSACleanup();
}
LWS_VISIBLE int
interface_to_sa(struct libwebsocket_context *context,
const char *ifname, struct sockaddr_in *addr, size_t addrlen)
{
return -1;
}
LWS_VISIBLE void
lws_plat_insert_socket_into_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi)
{
context->fds[context->fds_count++].revents = 0;
context->events[context->fds_count] = WSACreateEvent();
WSAEventSelect(wsi->sock, context->events[context->fds_count], LWS_POLLIN);
}
LWS_VISIBLE void
lws_plat_delete_socket_from_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi, int m)
{
WSACloseEvent(context->events[m + 1]);
context->events[m + 1] = context->events[context->fds_count + 1];
}
LWS_VISIBLE void
lws_plat_service_periodic(struct libwebsocket_context *context)
{
}
LWS_VISIBLE int
lws_plat_change_pollfd(struct libwebsocket_context *context,
struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd)
{
long networkevents = LWS_POLLOUT | LWS_POLLHUP;
if ((pfd->events & LWS_POLLIN))
networkevents |= LWS_POLLIN;
if (WSAEventSelect(wsi->sock,
context->events[wsi->position_in_fds_table + 1],
networkevents) != SOCKET_ERROR)
return 0;
lwsl_err("WSAEventSelect() failed with error %d\n", LWS_ERRNO);
return 1;
}
LWS_VISIBLE HANDLE
lws_plat_open_file(const char* filename, unsigned long* filelen)
{
HANDLE ret;
WCHAR buffer[MAX_PATH];
MultiByteToWideChar(CP_UTF8, 0, filename, -1, buffer,
sizeof(buffer) / sizeof(buffer[0]));
ret = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (ret != LWS_INVALID_FILE)
*filelen = GetFileSize(ret, NULL);
return ret;
}
LWS_VISIBLE const char *
lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
{
WCHAR *buffer;
DWORD bufferlen = cnt;
BOOL ok = FALSE;
buffer = malloc(bufferlen);
if (!buffer) {
lwsl_err("Out of memory\n");
return NULL;
}
if (af == AF_INET) {
struct sockaddr_in srcaddr;
bzero(&srcaddr, sizeof(srcaddr));
srcaddr.sin_family = AF_INET;
memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr));
if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen))
ok = TRUE;
#ifdef LWS_USE_IPV6
} else if (af == AF_INET6) {
struct sockaddr_in6 srcaddr;
bzero(&srcaddr, sizeof(srcaddr));
srcaddr.sin6_family = AF_INET6;
memcpy(&(srcaddr.sin6_addr), src, sizeof(srcaddr.sin6_addr));
if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen))
ok = TRUE;
#endif
} else
lwsl_err("Unsupported type\n");
if (!ok) {
int rv = WSAGetLastError();
lwsl_err("WSAAddressToString() : %d\n", rv);
} else {
if (WideCharToMultiByte(CP_ACP, 0, buffer, bufferlen, dst, cnt, 0, NULL) <= 0)
ok = FALSE;
}
free(buffer);
return ok ? dst : NULL;
}
#endif
+174
View File
@@ -0,0 +1,174 @@
/* config.h.in. Generated from configure.ac by autoheader. */
#ifndef WIN32
#define _DEBUG
#endif
/* Define to 1 to use CyaSSL as a replacement for OpenSSL.
* LWS_OPENSSL_SUPPORT needs to be set also for this to work. */
/* #undef USE_CYASSL */
/* The Libwebsocket version */
#define LWS_LIBRARY_VERSION "1.3"
/* The current git commit hash that we're building from */
#define LWS_BUILD_HASH "c11b847"
/* Build with OpenSSL support */
/* #undef LWS_OPENSSL_SUPPORT */
/* The client should load and trust CA root certs it finds in the OS */
/* #undef LWS_SSL_CLIENT_USE_OS_CA_CERTS */
/* Sets the path where the client certs should be installed. */
#define LWS_OPENSSL_CLIENT_CERTS "../share"
/* Turn off websocket extensions */
/* #undef LWS_NO_EXTENSIONS */
/* Enable libev io loop */
/* #undef LWS_USE_LIBEV */
/* Build with support for ipv6 */
/* #undef LWS_USE_IPV6 */
/* Build with support for HTTP2 */
/* #undef LWS_USE_HTTP2 */
/* Turn on latency measuring code */
/* #undef LWS_LATENCY */
/* Don't build the daemonizeation api */
#define LWS_NO_DAEMONIZE
/* Build without server support */
/* #undef LWS_NO_SERVER */
/* Build without client support */
/* #undef LWS_NO_CLIENT */
/* If we should compile with MinGW support */
/* #undef LWS_MINGW_SUPPORT */
/* Use the BSD getifaddrs that comes with libwebsocket, for uclibc support */
#define LWS_BUILTIN_GETIFADDRS
/* Define to 1 if you have the `bzero' function. */
/* #undef HAVE_BZERO */
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H
/* Define to 1 if you have the `fork' function. */
/* #undef HAVE_FORK */
/* Define to 1 if you have the `getenv’ function. */
#define HAVE_GETENV
/* Define to 1 if you have the <in6addr.h> header file. */
/* #undef HAVE_IN6ADDR_H */
/* Define to 1 if you have the <inttypes.h> header file. */
/* #undef HAVE_INTTYPES_H */
/* Define to 1 if you have the `ssl' library (-lssl). */
/* #undef HAVE_LIBSSL */
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET
/* Define to 1 if you have the <netinet/in.h> header file. */
/* #undef HAVE_NETINET_IN_H */
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#define HAVE_REALLOC
/* Define to 1 if you have the `socket' function. */
/* #undef HAVE_SOCKET */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H
/* Define to 1 if you have the <sys/prctl.h> header file. */
/* #undef HAVE_SYS_PRCTL_H */
/* Define to 1 if you have the <sys/socket.h> header file. */
/* #undef HAVE_SYS_SOCKET_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define to 1 if you have the `vfork' function. */
/* #undef HAVE_VFORK */
/* Define to 1 if you have the <vfork.h> header file. */
/* #undef HAVE_VFORK_H */
/* Define to 1 if `fork' works. */
#define HAVE_WORKING_FORK
/* Define to 1 if `vfork' works. */
#define HAVE_WORKING_VFORK
/* Define to 1 if you have the <zlib.h> header file. */
/* #undef HAVE_ZLIB_H */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR // We're not using libtool
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS
/* Version number of package */
#define VERSION
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to `int' if <sys/types.h> does not define. */
#define pid_t
/* Define to rpl_realloc if the replacement function should be used. */
/* #undef realloc */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to 1 if we have getifaddrs */
/* #undef HAVE_GETIFADDRS */
/* Define as `fork' if `vfork' does not work. */
/* #undef vfork */
/* Define if the inline keyword doesn't exist. */
#define inline
+571
View File
@@ -0,0 +1,571 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
static int
libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi)
{
int n;
/* fetch the per-frame nonce */
n = libwebsockets_get_random(wsi->protocol->owning_server,
wsi->u.ws.frame_masking_nonce_04, 4);
if (n != 4) {
lwsl_parser("Unable to read from random device %s %d\n",
SYSTEM_RANDOM_FILEPATH, n);
return 1;
}
/* start masking from first byte of masking key buffer */
wsi->u.ws.frame_mask_index = 0;
return 0;
}
#ifdef _DEBUG
LWS_VISIBLE void lwsl_hexdump(void *vbuf, size_t len)
{
int n;
int m;
int start;
unsigned char *buf = (unsigned char *)vbuf;
char line[80];
char *p;
lwsl_parser("\n");
for (n = 0; n < len;) {
start = n;
p = line;
p += sprintf(p, "%04X: ", start);
for (m = 0; m < 16 && n < len; m++)
p += sprintf(p, "%02X ", buf[n++]);
while (m++ < 16)
p += sprintf(p, " ");
p += sprintf(p, " ");
for (m = 0; m < 16 && (start + m) < len; m++) {
if (buf[start + m] >= ' ' && buf[start + m] < 127)
*p++ = buf[start + m];
else
*p++ = '.';
}
while (m++ < 16)
*p++ = ' ';
*p++ = '\n';
*p = '\0';
lwsl_debug("%s", line);
}
lwsl_debug("\n");
}
#endif
/*
* notice this returns number of bytes consumed, or -1
*/
int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
{
struct libwebsocket_context *context = wsi->protocol->owning_server;
int n;
size_t real_len = len;
int m;
if (!len)
return 0;
/* just ignore sends after we cleared the truncation buffer */
if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE &&
!wsi->truncated_send_len)
return len;
if (wsi->truncated_send_len && (buf < wsi->truncated_send_malloc ||
buf > (wsi->truncated_send_malloc +
wsi->truncated_send_len +
wsi->truncated_send_offset))) {
lwsl_err("****** %x Sending new, pending truncated ...\n", wsi);
assert(0);
}
m = lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_PACKET_TX_DO_SEND, &buf, len);
if (m < 0)
return -1;
if (m) /* handled */ {
n = m;
goto handle_truncated_send;
}
if (wsi->sock < 0)
lwsl_warn("** error invalid sock but expected to send\n");
/*
* nope, send it on the socket directly
*/
lws_latency_pre(context, wsi);
n = lws_ssl_capable_write(wsi, buf, len);
lws_latency(context, wsi, "send lws_issue_raw", n, n == len);
switch (n) {
case LWS_SSL_CAPABLE_ERROR:
return -1;
case LWS_SSL_CAPABLE_MORE_SERVICE:
/* nothing got sent, not fatal, retry the whole thing later */
n = 0;
break;
}
handle_truncated_send:
/*
* we were already handling a truncated send?
*/
if (wsi->truncated_send_len) {
lwsl_info("***** %x partial send moved on by %d (vs %d)\n",
wsi, n, real_len);
wsi->truncated_send_offset += n;
wsi->truncated_send_len -= n;
if (!wsi->truncated_send_len) {
lwsl_info("***** %x partial send completed\n", wsi);
/* done with it, but don't free it */
n = real_len;
if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
lwsl_info("***** %x signalling to close now\n", wsi);
return -1; /* retry closing now */
}
}
/* always callback on writeable */
libwebsocket_callback_on_writable(
wsi->protocol->owning_server, wsi);
return n;
}
if (n == real_len)
/* what we just sent went out cleanly */
return n;
if (n && wsi->u.ws.clean_buffer)
/*
* This buffer unaffected by extension rewriting.
* It means the user code is expected to deal with
* partial sends. (lws knows the header was already
* sent, so on next send will just resume sending
* payload)
*/
return n;
/*
* Newly truncated send. Buffer the remainder (it will get
* first priority next time the socket is writable)
*/
lwsl_info("***** %x new partial sent %d from %d total\n",
wsi, n, real_len);
/*
* - if we still have a suitable malloc lying around, use it
* - or, if too small, reallocate it
* - or, if no buffer, create it
*/
if (!wsi->truncated_send_malloc ||
real_len - n > wsi->truncated_send_allocation) {
if (wsi->truncated_send_malloc)
free(wsi->truncated_send_malloc);
wsi->truncated_send_allocation = real_len - n;
wsi->truncated_send_malloc = malloc(real_len - n);
if (!wsi->truncated_send_malloc) {
lwsl_err("truncated send: unable to malloc %d\n",
real_len - n);
return -1;
}
}
wsi->truncated_send_offset = 0;
wsi->truncated_send_len = real_len - n;
memcpy(wsi->truncated_send_malloc, buf + n, real_len - n);
/* since something buffered, force it to get another chance to send */
libwebsocket_callback_on_writable(wsi->protocol->owning_server, wsi);
return real_len;
}
/**
* libwebsocket_write() - Apply protocol then write data to client
* @wsi: Websocket instance (available from user callback)
* @buf: The data to send. For data being sent on a websocket
* connection (ie, not default http), this buffer MUST have
* LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer
* and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid
* in the buffer after (buf + len). This is so the protocol
* header and trailer data can be added in-situ.
* @len: Count of the data bytes in the payload starting from buf
* @protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one
* of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate
* data on a websockets connection. Remember to allow the extra
* bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT
* are used.
*
* This function provides the way to issue data back to the client
* for both http and websocket protocols.
*
* In the case of sending using websocket protocol, be sure to allocate
* valid storage before and after buf as explained above. This scheme
* allows maximum efficiency of sending data and protocol in a single
* packet while not burdening the user code with any protocol knowledge.
*
* Return may be -1 for a fatal error needing connection close, or a
* positive number reflecting the amount of bytes actually sent. This
* can be less than the requested number of bytes due to OS memory
* pressure at any given time.
*/
LWS_VISIBLE int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
size_t len, enum libwebsocket_write_protocol protocol)
{
int n;
int pre = 0;
int post = 0;
int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT;
unsigned char *dropmask = NULL;
unsigned char is_masked_bit = 0;
size_t orig_len = len;
struct lws_tokens eff_buf;
if (len == 0 && protocol != LWS_WRITE_CLOSE &&
protocol != LWS_WRITE_PING && protocol != LWS_WRITE_PONG) {
lwsl_warn("zero length libwebsocket_write attempt\n");
return 0;
}
if (protocol == LWS_WRITE_HTTP)
goto send_raw;
/* websocket protocol, either binary or text */
if (wsi->state != WSI_STATE_ESTABLISHED)
return -1;
/* if we are continuing a frame that already had its header done */
if (wsi->u.ws.inside_frame)
goto do_more_inside_frame;
/* if he wants all partials buffered, never have a clean_buffer */
wsi->u.ws.clean_buffer = !wsi->protocol->no_buffer_all_partial_tx;
/*
* give a chance to the extensions to modify payload
* pre-TX mangling is not allowed to truncate
*/
eff_buf.token = (char *)buf;
eff_buf.token_len = len;
switch (protocol) {
case LWS_WRITE_PING:
case LWS_WRITE_PONG:
case LWS_WRITE_CLOSE:
break;
default:
if (lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_PAYLOAD_TX, &eff_buf, 0) < 0)
return -1;
}
/*
* an extension did something we need to keep... for example, if
* compression extension, it has already updated its state according
* to this being issued
*/
if ((char *)buf != eff_buf.token)
/*
* extension recreated it:
* need to buffer this if not all sent
*/
wsi->u.ws.clean_buffer = 0;
buf = (unsigned char *)eff_buf.token;
len = eff_buf.token_len;
switch (wsi->ietf_spec_revision) {
case 13:
if (masked7) {
pre += 4;
dropmask = &buf[0 - pre];
is_masked_bit = 0x80;
}
switch (protocol & 0xf) {
case LWS_WRITE_TEXT:
n = LWS_WS_OPCODE_07__TEXT_FRAME;
break;
case LWS_WRITE_BINARY:
n = LWS_WS_OPCODE_07__BINARY_FRAME;
break;
case LWS_WRITE_CONTINUATION:
n = LWS_WS_OPCODE_07__CONTINUATION;
break;
case LWS_WRITE_CLOSE:
n = LWS_WS_OPCODE_07__CLOSE;
/*
* 06+ has a 2-byte status code in network order
* we can do this because we demand post-buf
*/
if (wsi->u.ws.close_reason) {
/* reason codes count as data bytes */
buf -= 2;
buf[0] = wsi->u.ws.close_reason >> 8;
buf[1] = wsi->u.ws.close_reason;
len += 2;
}
break;
case LWS_WRITE_PING:
n = LWS_WS_OPCODE_07__PING;
break;
case LWS_WRITE_PONG:
n = LWS_WS_OPCODE_07__PONG;
break;
default:
lwsl_warn("lws_write: unknown write opc / protocol\n");
return -1;
}
if (!(protocol & LWS_WRITE_NO_FIN))
n |= 1 << 7;
if (len < 126) {
pre += 2;
buf[-pre] = n;
buf[-pre + 1] = len | is_masked_bit;
} else {
if (len < 65536) {
pre += 4;
buf[-pre] = n;
buf[-pre + 1] = 126 | is_masked_bit;
buf[-pre + 2] = len >> 8;
buf[-pre + 3] = len;
} else {
pre += 10;
buf[-pre] = n;
buf[-pre + 1] = 127 | is_masked_bit;
#if defined __LP64__
buf[-pre + 2] = (len >> 56) & 0x7f;
buf[-pre + 3] = len >> 48;
buf[-pre + 4] = len >> 40;
buf[-pre + 5] = len >> 32;
#else
buf[-pre + 2] = 0;
buf[-pre + 3] = 0;
buf[-pre + 4] = 0;
buf[-pre + 5] = 0;
#endif
buf[-pre + 6] = len >> 24;
buf[-pre + 7] = len >> 16;
buf[-pre + 8] = len >> 8;
buf[-pre + 9] = len;
}
}
break;
}
do_more_inside_frame:
/*
* Deal with masking if we are in client -> server direction and
* the protocol demands it
*/
if (wsi->mode == LWS_CONNMODE_WS_CLIENT) {
if (!wsi->u.ws.inside_frame)
if (libwebsocket_0405_frame_mask_generate(wsi)) {
lwsl_err("frame mask generation failed\n");
return -1;
}
/*
* in v7, just mask the payload
*/
if (dropmask) { /* never set if already inside frame */
for (n = 4; n < (int)len + 4; n++)
dropmask[n] = dropmask[n] ^
wsi->u.ws.frame_masking_nonce_04[
(wsi->u.ws.frame_mask_index++) & 3];
/* copy the frame nonce into place */
memcpy(dropmask, wsi->u.ws.frame_masking_nonce_04, 4);
}
}
send_raw:
switch (protocol) {
case LWS_WRITE_CLOSE:
/* lwsl_hexdump(&buf[-pre], len + post); */
case LWS_WRITE_HTTP:
case LWS_WRITE_PONG:
case LWS_WRITE_PING:
return lws_issue_raw(wsi, (unsigned char *)buf - pre,
len + pre + post);
default:
break;
}
wsi->u.ws.inside_frame = 1;
/*
* give any active extensions a chance to munge the buffer
* before send. We pass in a pointer to an lws_tokens struct
* prepared with the default buffer and content length that's in
* there. Rather than rewrite the default buffer, extensions
* that expect to grow the buffer can adapt .token to
* point to their own per-connection buffer in the extension
* user allocation. By default with no extensions or no
* extension callback handling, just the normal input buffer is
* used then so it is efficient.
*
* callback returns 1 in case it wants to spill more buffers
*
* This takes care of holding the buffer if send is incomplete, ie,
* if wsi->u.ws.clean_buffer is 0 (meaning an extension meddled with
* the buffer). If wsi->u.ws.clean_buffer is 1, it will instead
* return to the user code how much OF THE USER BUFFER was consumed.
*/
n = lws_issue_raw_ext_access(wsi, buf - pre, len + pre + post);
if (n <= 0)
return n;
if (n == len + pre + post) {
/* everything in the buffer was handled (or rebuffered...) */
wsi->u.ws.inside_frame = 0;
return orig_len;
}
/*
* it is how many bytes of user buffer got sent... may be < orig_len
* in which case callback when writable has already been arranged
* and user code can call libwebsocket_write() again with the rest
* later.
*/
return n - (pre + post);
}
LWS_VISIBLE int libwebsockets_serve_http_file_fragment(
struct libwebsocket_context *context, struct libwebsocket *wsi)
{
int n;
int m;
while (!lws_send_pipe_choked(wsi)) {
if (wsi->truncated_send_len) {
if (lws_issue_raw(wsi, wsi->truncated_send_malloc +
wsi->truncated_send_offset,
wsi->truncated_send_len) < 0) {
lwsl_info("closing from libwebsockets_serve_http_file_fragment\n");
return -1;
}
continue;
}
if (wsi->u.http.filepos == wsi->u.http.filelen)
goto all_sent;
compatible_file_read(n, wsi->u.http.fd, context->service_buffer,
sizeof(context->service_buffer));
if (n < 0)
return -1; /* caller will close */
if (n) {
m = libwebsocket_write(wsi, context->service_buffer, n,
LWS_WRITE_HTTP);
if (m < 0)
return -1;
wsi->u.http.filepos += m;
if (m != n)
/* adjust for what was not sent */
compatible_file_seek_cur(wsi->u.http.fd, m - n);
}
all_sent:
if (!wsi->truncated_send_len &&
wsi->u.http.filepos == wsi->u.http.filelen) {
wsi->state = WSI_STATE_HTTP;
if (wsi->protocol->callback)
/* ignore callback returned value */
user_callback_handle_rxflow(
wsi->protocol->callback, context, wsi,
LWS_CALLBACK_HTTP_FILE_COMPLETION,
wsi->user_space, NULL, 0);
return 1; /* >0 indicates completed */
}
}
lwsl_info("choked before able to send whole file (post)\n");
libwebsocket_callback_on_writable(context, wsi);
return 0; /* indicates further processing must be done */
}
LWS_VISIBLE int
lws_ssl_capable_read_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len)
{
int n;
n = recv(wsi->sock, buf, len, 0);
if (n >= 0)
return n;
lwsl_warn("error on reading from skt\n");
return LWS_SSL_CAPABLE_ERROR;
}
LWS_VISIBLE int
lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len)
{
int n;
n = send(wsi->sock, buf, len, 0);
if (n >= 0)
return n;
if (LWS_ERRNO == LWS_EAGAIN ||
LWS_ERRNO == LWS_EWOULDBLOCK ||
LWS_ERRNO == LWS_EINTR) {
if (LWS_ERRNO == LWS_EWOULDBLOCK)
lws_set_blocking_send(wsi);
return LWS_SSL_CAPABLE_MORE_SERVICE;
}
lwsl_debug("ERROR writing len %d to skt %d\n", len, n);
return LWS_SSL_CAPABLE_ERROR;
}
+973
View File
@@ -0,0 +1,973 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2013 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
unsigned char lextable[] = {
#include "lextable.h"
};
#define FAIL_CHAR 0x08
int lextable_decode(int pos, char c)
{
c = tolower(c);
while (1) {
if (lextable[pos] & (1 << 7)) { /* 1-byte, fail on mismatch */
if ((lextable[pos] & 0x7f) != c)
return -1;
/* fall thru */
pos++;
if (lextable[pos] == FAIL_CHAR)
return -1;
return pos;
}
/* b7 = 0, end or 3-byte */
if (lextable[pos] < FAIL_CHAR) /* terminal marker */
return pos;
if (lextable[pos] == c) /* goto */
return pos + (lextable[pos + 1]) +
(lextable[pos + 2] << 8);
/* fall thru goto */
pos += 3;
/* continue */
}
}
int lws_allocate_header_table(struct libwebsocket *wsi)
{
wsi->u.hdr.ah = malloc(sizeof(*wsi->u.hdr.ah));
if (wsi->u.hdr.ah == NULL) {
lwsl_err("Out of memory\n");
return -1;
}
memset(wsi->u.hdr.ah->frag_index, 0, sizeof(wsi->u.hdr.ah->frag_index));
wsi->u.hdr.ah->next_frag_index = 0;
wsi->u.hdr.ah->pos = 0;
return 0;
}
LWS_VISIBLE int lws_hdr_total_length(struct libwebsocket *wsi, enum lws_token_indexes h)
{
int n;
int len = 0;
n = wsi->u.hdr.ah->frag_index[h];
if (!n)
return 0;
do {
len += wsi->u.hdr.ah->frags[n].len;
n = wsi->u.hdr.ah->frags[n].next_frag_index;
} while (n);
return len;
}
LWS_VISIBLE int lws_hdr_copy(struct libwebsocket *wsi, char *dest, int len,
enum lws_token_indexes h)
{
int toklen = lws_hdr_total_length(wsi, h);
int n;
if (toklen >= len)
return -1;
n = wsi->u.hdr.ah->frag_index[h];
if (!n)
return 0;
do {
strcpy(dest,
&wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]);
dest += wsi->u.hdr.ah->frags[n].len;
n = wsi->u.hdr.ah->frags[n].next_frag_index;
} while (n);
return toklen;
}
char *lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h)
{
int n;
n = wsi->u.hdr.ah->frag_index[h];
if (!n)
return NULL;
return &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset];
}
int lws_hdr_simple_create(struct libwebsocket *wsi,
enum lws_token_indexes h, const char *s)
{
wsi->u.hdr.ah->next_frag_index++;
if (wsi->u.hdr.ah->next_frag_index ==
sizeof(wsi->u.hdr.ah->frags) / sizeof(wsi->u.hdr.ah->frags[0])) {
lwsl_warn("More hdr frags than we can deal with, dropping\n");
return -1;
}
wsi->u.hdr.ah->frag_index[h] = wsi->u.hdr.ah->next_frag_index;
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].offset =
wsi->u.hdr.ah->pos;
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len = 0;
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].next_frag_index =
0;
do {
if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) {
lwsl_err("Ran out of header data space\n");
return -1;
}
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = *s;
if (*s)
wsi->u.hdr.ah->frags[
wsi->u.hdr.ah->next_frag_index].len++;
} while (*s++);
return 0;
}
static char char_to_hex(const char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
static int issue_char(struct libwebsocket *wsi, unsigned char c)
{
if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) {
lwsl_warn("excessive header content\n");
return -1;
}
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c;
if (c)
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++;
return 0;
}
int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
{
int n;
switch (wsi->u.hdr.parser_state) {
case WSI_TOKEN_GET_URI:
case WSI_TOKEN_POST_URI:
case WSI_TOKEN_HOST:
case WSI_TOKEN_CONNECTION:
case WSI_TOKEN_KEY1:
case WSI_TOKEN_KEY2:
case WSI_TOKEN_PROTOCOL:
case WSI_TOKEN_UPGRADE:
case WSI_TOKEN_ORIGIN:
case WSI_TOKEN_SWORIGIN:
case WSI_TOKEN_DRAFT:
case WSI_TOKEN_CHALLENGE:
case WSI_TOKEN_KEY:
case WSI_TOKEN_VERSION:
case WSI_TOKEN_ACCEPT:
case WSI_TOKEN_NONCE:
case WSI_TOKEN_EXTENSIONS:
case WSI_TOKEN_HTTP:
case WSI_TOKEN_HTTP_ACCEPT:
case WSI_TOKEN_HTTP_IF_MODIFIED_SINCE:
case WSI_TOKEN_HTTP_ACCEPT_ENCODING:
case WSI_TOKEN_HTTP_ACCEPT_LANGUAGE:
case WSI_TOKEN_HTTP_PRAGMA:
case WSI_TOKEN_HTTP_CACHE_CONTROL:
case WSI_TOKEN_HTTP_AUTHORIZATION:
case WSI_TOKEN_HTTP_COOKIE:
case WSI_TOKEN_HTTP_CONTENT_LENGTH:
case WSI_TOKEN_HTTP_CONTENT_TYPE:
case WSI_TOKEN_HTTP_DATE:
case WSI_TOKEN_HTTP_RANGE:
case WSI_TOKEN_HTTP_REFERER:
lwsl_parser("WSI_TOK_(%d) '%c'\n", wsi->u.hdr.parser_state, c);
/* collect into malloc'd buffers */
/* optional initial space swallow */
if (!wsi->u.hdr.ah->frags[wsi->u.hdr.ah->frag_index[
wsi->u.hdr.parser_state]].len && c == ' ')
break;
if ((wsi->u.hdr.parser_state != WSI_TOKEN_GET_URI) && (wsi->u.hdr.parser_state != WSI_TOKEN_POST_URI))
goto check_eol;
/* special URI processing... end at space */
if (c == ' ') {
/* enforce starting with / */
if (!wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len)
if (issue_char(wsi, '/') < 0)
return -1;
c = '\0';
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
goto spill;
}
/* special URI processing... convert %xx */
switch (wsi->u.hdr.ues) {
case URIES_IDLE:
if (c == '%') {
wsi->u.hdr.ues = URIES_SEEN_PERCENT;
goto swallow;
}
break;
case URIES_SEEN_PERCENT:
if (char_to_hex(c) < 0) {
/* regurgitate */
if (issue_char(wsi, '%') < 0)
return -1;
wsi->u.hdr.ues = URIES_IDLE;
/* continue on to assess c */
break;
}
wsi->u.hdr.esc_stash = c;
wsi->u.hdr.ues = URIES_SEEN_PERCENT_H1;
goto swallow;
case URIES_SEEN_PERCENT_H1:
if (char_to_hex(c) < 0) {
/* regurgitate */
issue_char(wsi, '%');
wsi->u.hdr.ues = URIES_IDLE;
/* regurgitate + assess */
if (libwebsocket_parse(wsi, wsi->u.hdr.esc_stash) < 0)
return -1;
/* continue on to assess c */
break;
}
c = (char_to_hex(wsi->u.hdr.esc_stash) << 4) |
char_to_hex(c);
wsi->u.hdr.ues = URIES_IDLE;
break;
}
/*
* special URI processing...
* convert /.. or /... or /../ etc to /
* convert /./ to /
* convert // or /// etc to /
* leave /.dir or whatever alone
*/
switch (wsi->u.hdr.ups) {
case URIPS_IDLE:
/* issue the first / always */
if (c == '/')
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
break;
case URIPS_SEEN_SLASH:
/* swallow subsequent slashes */
if (c == '/')
goto swallow;
/* track and swallow the first . after / */
if (c == '.') {
wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT;
goto swallow;
} else
wsi->u.hdr.ups = URIPS_IDLE;
break;
case URIPS_SEEN_SLASH_DOT:
/* swallow second . */
if (c == '.') {
/*
* back up one dir level if possible
* safe against header fragmentation because
* the method URI can only be in 1 fragment
*/
if (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len > 2) {
wsi->u.hdr.ah->pos--;
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len--;
do {
wsi->u.hdr.ah->pos--;
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len--;
} while (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len > 1 &&
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos] != '/');
}
wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT;
goto swallow;
}
/* change /./ to / */
if (c == '/') {
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
goto swallow;
}
/* it was like /.dir ... regurgitate the . */
wsi->u.hdr.ups = URIPS_IDLE;
issue_char(wsi, '.');
break;
case URIPS_SEEN_SLASH_DOT_DOT:
/* swallow prior .. chars and any subsequent . */
if (c == '.')
goto swallow;
/* last issued was /, so another / == // */
if (c == '/')
goto swallow;
else /* last we issued was / so SEEN_SLASH */
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
break;
case URIPS_ARGUMENTS:
/* leave them alone */
break;
}
check_eol:
/* bail at EOL */
if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE &&
c == '\x0d') {
c = '\0';
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
lwsl_parser("*\n");
}
if (c == '?') { /* start of URI arguments */
/* seal off uri header */
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0';
/* move to using WSI_TOKEN_HTTP_URI_ARGS */
wsi->u.hdr.ah->next_frag_index++;
wsi->u.hdr.ah->frags[
wsi->u.hdr.ah->next_frag_index].offset =
wsi->u.hdr.ah->pos;
wsi->u.hdr.ah->frags[
wsi->u.hdr.ah->next_frag_index].len = 0;
wsi->u.hdr.ah->frags[
wsi->u.hdr.ah->next_frag_index].next_frag_index = 0;
wsi->u.hdr.ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] =
wsi->u.hdr.ah->next_frag_index;
/* defeat normal uri path processing */
wsi->u.hdr.ups = URIPS_ARGUMENTS;
goto swallow;
}
spill:
if (issue_char(wsi, c) < 0)
return -1;
swallow:
/* per-protocol end of headers management */
if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
goto set_parsing_complete;
break;
/* collecting and checking a name part */
case WSI_TOKEN_NAME_PART:
lwsl_parser("WSI_TOKEN_NAME_PART '%c'\n", c);
wsi->u.hdr.lextable_pos =
lextable_decode(wsi->u.hdr.lextable_pos, c);
if (wsi->u.hdr.lextable_pos < 0) {
/* this is not a header we know about */
if (wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI] || wsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI] ||
wsi->u.hdr.ah->frag_index[WSI_TOKEN_HTTP]) {
/*
* altready had the method, no idea what
* this crap is, ignore
*/
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
break;
}
/*
* hm it's an unknown http method in fact,
* treat as dangerous
*/
lwsl_info("Unknown method - dropping\n");
return -1;
}
if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) {
/* terminal state */
n = (lextable[wsi->u.hdr.lextable_pos] << 8) | lextable[wsi->u.hdr.lextable_pos + 1];
lwsl_parser("known hdr %d\n", n);
if (n == WSI_TOKEN_GET_URI &&
wsi->u.hdr.ah->frag_index[WSI_TOKEN_GET_URI]) {
lwsl_warn("Duplicated GET\n");
return -1;
} else if (n == WSI_TOKEN_POST_URI &&
wsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI]) {
lwsl_warn("Duplicated POST\n");
return -1;
}
/*
* WSORIGIN is protocol equiv to ORIGIN,
* JWebSocket likes to send it, map to ORIGIN
*/
if (n == WSI_TOKEN_SWORIGIN)
n = WSI_TOKEN_ORIGIN;
wsi->u.hdr.parser_state = (enum lws_token_indexes)
(WSI_TOKEN_GET_URI + n);
if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
goto set_parsing_complete;
goto start_fragment;
}
break;
start_fragment:
wsi->u.hdr.ah->next_frag_index++;
if (wsi->u.hdr.ah->next_frag_index ==
sizeof(wsi->u.hdr.ah->frags) /
sizeof(wsi->u.hdr.ah->frags[0])) {
lwsl_warn("More hdr frags than we can deal with\n");
return -1;
}
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].offset =
wsi->u.hdr.ah->pos;
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len = 0;
wsi->u.hdr.ah->frags[
wsi->u.hdr.ah->next_frag_index].next_frag_index = 0;
n = wsi->u.hdr.ah->frag_index[wsi->u.hdr.parser_state];
if (!n) { /* first fragment */
wsi->u.hdr.ah->frag_index[wsi->u.hdr.parser_state] =
wsi->u.hdr.ah->next_frag_index;
break;
}
/* continuation */
while (wsi->u.hdr.ah->frags[n].next_frag_index)
n = wsi->u.hdr.ah->frags[n].next_frag_index;
wsi->u.hdr.ah->frags[n].next_frag_index =
wsi->u.hdr.ah->next_frag_index;
if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) {
lwsl_warn("excessive header content\n");
return -1;
}
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = ' ';
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++;
break;
/* skipping arg part of a name we didn't recognize */
case WSI_TOKEN_SKIPPING:
lwsl_parser("WSI_TOKEN_SKIPPING '%c'\n", c);
if (c == '\x0d')
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
break;
case WSI_TOKEN_SKIPPING_SAW_CR:
lwsl_parser("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c);
if (c == '\x0a') {
wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
wsi->u.hdr.lextable_pos = 0;
} else
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
break;
/* we're done, ignore anything else */
case WSI_PARSING_COMPLETE:
lwsl_parser("WSI_PARSING_COMPLETE '%c'\n", c);
break;
default: /* keep gcc happy */
break;
}
return 0;
set_parsing_complete:
if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION))
wsi->ietf_spec_revision =
atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION));
lwsl_parser("v%02d hdrs completed\n", wsi->ietf_spec_revision);
}
wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE;
wsi->hdr_parsing_completed = 1;
return 0;
}
/**
* lws_frame_is_binary: true if the current frame was sent in binary mode
*
* @wsi: the connection we are inquiring about
*
* This is intended to be called from the LWS_CALLBACK_RECEIVE callback if
* it's interested to see if the frame it's dealing with was sent in binary
* mode.
*/
LWS_VISIBLE int lws_frame_is_binary(struct libwebsocket *wsi)
{
return wsi->u.ws.frame_is_binary;
}
int
libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c)
{
int n;
struct lws_tokens eff_buf;
int ret = 0;
switch (wsi->lws_rx_parse_state) {
case LWS_RXPS_NEW:
switch (wsi->ietf_spec_revision) {
case 13:
/*
* no prepended frame key any more
*/
wsi->u.ws.all_zero_nonce = 1;
goto handle_first;
default:
lwsl_warn("lws_rx_sm: unknown spec version %d\n",
wsi->ietf_spec_revision);
break;
}
break;
case LWS_RXPS_04_MASK_NONCE_1:
wsi->u.ws.frame_masking_nonce_04[1] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_2;
break;
case LWS_RXPS_04_MASK_NONCE_2:
wsi->u.ws.frame_masking_nonce_04[2] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_3;
break;
case LWS_RXPS_04_MASK_NONCE_3:
wsi->u.ws.frame_masking_nonce_04[3] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
/*
* start from the zero'th byte in the XOR key buffer since
* this is the start of a frame with a new key
*/
wsi->u.ws.frame_mask_index = 0;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1;
break;
/*
* 04 logical framing from the spec (all this is masked when incoming
* and has to be unmasked)
*
* We ignore the possibility of extension data because we don't
* negotiate any extensions at the moment.
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-------+-+-------------+-------------------------------+
* |F|R|R|R| opcode|R| Payload len | Extended payload length |
* |I|S|S|S| (4) |S| (7) | (16/63) |
* |N|V|V|V| |V| | (if payload len==126/127) |
* | |1|2|3| |4| | |
* +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
* | Extended payload length continued, if payload len == 127 |
* + - - - - - - - - - - - - - - - +-------------------------------+
* | | Extension data |
* +-------------------------------+ - - - - - - - - - - - - - - - +
* : :
* +---------------------------------------------------------------+
* : Application data :
* +---------------------------------------------------------------+
*
* We pass payload through to userland as soon as we get it, ignoring
* FIN. It's up to userland to buffer it up if it wants to see a
* whole unfragmented block of the original size (which may be up to
* 2^63 long!)
*/
case LWS_RXPS_04_FRAME_HDR_1:
handle_first:
wsi->u.ws.opcode = c & 0xf;
wsi->u.ws.rsv = c & 0x70;
wsi->u.ws.final = !!((c >> 7) & 1);
switch (wsi->u.ws.opcode) {
case LWS_WS_OPCODE_07__TEXT_FRAME:
case LWS_WS_OPCODE_07__BINARY_FRAME:
wsi->u.ws.frame_is_binary =
wsi->u.ws.opcode == LWS_WS_OPCODE_07__BINARY_FRAME;
break;
}
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
break;
case LWS_RXPS_04_FRAME_HDR_LEN:
wsi->u.ws.this_frame_masked = !!(c & 0x80);
switch (c & 0x7f) {
case 126:
/* control frames are not allowed to have big lengths */
if (wsi->u.ws.opcode & 8)
goto illegal_ctl_length;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
break;
case 127:
/* control frames are not allowed to have big lengths */
if (wsi->u.ws.opcode & 8)
goto illegal_ctl_length;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
break;
default:
wsi->u.ws.rx_packet_length = c & 0x7f;
if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else
if (wsi->u.ws.rx_packet_length)
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
else {
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
break;
}
break;
case LWS_RXPS_04_FRAME_HDR_LEN16_2:
wsi->u.ws.rx_packet_length = c << 8;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
break;
case LWS_RXPS_04_FRAME_HDR_LEN16_1:
wsi->u.ws.rx_packet_length |= c;
if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_8:
if (c & 0x80) {
lwsl_warn("b63 of length must be zero\n");
/* kill the connection */
return -1;
}
#if defined __LP64__
wsi->u.ws.rx_packet_length = ((size_t)c) << 56;
#else
wsi->u.ws.rx_packet_length = 0;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_7:
#if defined __LP64__
wsi->u.ws.rx_packet_length |= ((size_t)c) << 48;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_6:
#if defined __LP64__
wsi->u.ws.rx_packet_length |= ((size_t)c) << 40;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_5:
#if defined __LP64__
wsi->u.ws.rx_packet_length |= ((size_t)c) << 32;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_4:
wsi->u.ws.rx_packet_length |= ((size_t)c) << 24;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_3:
wsi->u.ws.rx_packet_length |= ((size_t)c) << 16;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_2:
wsi->u.ws.rx_packet_length |= ((size_t)c) << 8;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_1:
wsi->u.ws.rx_packet_length |= ((size_t)c);
if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
wsi->u.ws.frame_masking_nonce_04[0] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
wsi->u.ws.frame_masking_nonce_04[1] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
wsi->u.ws.frame_masking_nonce_04[2] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
wsi->u.ws.frame_masking_nonce_04[3] = c;
if (c)
wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
wsi->u.ws.frame_mask_index = 0;
if (wsi->u.ws.rx_packet_length == 0) {
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
break;
case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
if (!wsi->u.ws.rx_user_buffer)
lwsl_err("NULL user buffer...\n");
if (wsi->u.ws.all_zero_nonce)
wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
(wsi->u.ws.rx_user_buffer_head++)] = c;
else
wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
(wsi->u.ws.rx_user_buffer_head++)] =
c ^ wsi->u.ws.frame_masking_nonce_04[
(wsi->u.ws.frame_mask_index++) & 3];
if (--wsi->u.ws.rx_packet_length == 0) {
/* spill because we have the whole frame */
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
/*
* if there's no protocol max frame size given, we are
* supposed to default to LWS_MAX_SOCKET_IO_BUF
*/
if (!wsi->protocol->rx_buffer_size &&
wsi->u.ws.rx_user_buffer_head !=
LWS_MAX_SOCKET_IO_BUF)
break;
else
if (wsi->protocol->rx_buffer_size &&
wsi->u.ws.rx_user_buffer_head !=
wsi->protocol->rx_buffer_size)
break;
/* spill because we filled our rx buffer */
spill:
/*
* is this frame a control packet we should take care of at this
* layer? If so service it and hide it from the user callback
*/
lwsl_parser("spill on %s\n", wsi->protocol->name);
switch (wsi->u.ws.opcode) {
case LWS_WS_OPCODE_07__CLOSE:
/* is this an acknowledgement of our close? */
if (wsi->state == WSI_STATE_AWAITING_CLOSE_ACK) {
/*
* fine he has told us he is closing too, let's
* finish our close
*/
lwsl_parser("seen client close ack\n");
return -1;
}
lwsl_parser("server sees client close packet\n");
/* parrot the close packet payload back */
n = libwebsocket_write(wsi, (unsigned char *)
&wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING],
wsi->u.ws.rx_user_buffer_head,
LWS_WRITE_CLOSE);
if (n < 0)
lwsl_info("write of close ack failed %d\n", n);
wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY;
/* close the connection */
return -1;
case LWS_WS_OPCODE_07__PING:
lwsl_info("received %d byte ping, sending pong\n",
wsi->u.ws.rx_user_buffer_head);
lwsl_hexdump(&wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING],
wsi->u.ws.rx_user_buffer_head);
/* parrot the ping packet payload back as a pong */
n = libwebsocket_write(wsi, (unsigned char *)
&wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
wsi->u.ws.rx_user_buffer_head, LWS_WRITE_PONG);
if (n < 0)
return -1;
/* ... then just drop it */
wsi->u.ws.rx_user_buffer_head = 0;
return 0;
case LWS_WS_OPCODE_07__PONG:
/* ... then just drop it */
wsi->u.ws.rx_user_buffer_head = 0;
return 0;
case LWS_WS_OPCODE_07__TEXT_FRAME:
case LWS_WS_OPCODE_07__BINARY_FRAME:
case LWS_WS_OPCODE_07__CONTINUATION:
break;
default:
lwsl_parser("passing opc %x up to exts\n",
wsi->u.ws.opcode);
/*
* It's something special we can't understand here.
* Pass the payload up to the extension's parsing
* state machine.
*/
eff_buf.token = &wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING];
eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
if (lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_EXTENDED_PAYLOAD_RX,
&eff_buf, 0) <= 0) /* not handle or fail */
lwsl_ext("ext opc opcode 0x%x unknown\n",
wsi->u.ws.opcode);
wsi->u.ws.rx_user_buffer_head = 0;
return 0;
}
/*
* No it's real payload, pass it up to the user callback.
* It's nicely buffered with the pre-padding taken care of
* so it can be sent straight out again using libwebsocket_write
*/
eff_buf.token = &wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING];
eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
if (lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_PAYLOAD_RX, &eff_buf, 0) < 0)
return -1;
if (eff_buf.token_len > 0) {
eff_buf.token[eff_buf.token_len] = '\0';
if (wsi->protocol->callback)
ret = user_callback_handle_rxflow(
wsi->protocol->callback,
wsi->protocol->owning_server,
wsi, LWS_CALLBACK_RECEIVE,
wsi->user_space,
eff_buf.token,
eff_buf.token_len);
else
lwsl_err("No callback on payload spill!\n");
}
wsi->u.ws.rx_user_buffer_head = 0;
break;
}
return ret;
illegal_ctl_length:
lwsl_warn("Control frame with xtended length is illegal\n");
/* kill the connection */
return -1;
}
/**
* libwebsockets_remaining_packet_payload() - Bytes to come before "overall"
* rx packet is complete
* @wsi: Websocket instance (available from user callback)
*
* This function is intended to be called from the callback if the
* user code is interested in "complete packets" from the client.
* libwebsockets just passes through payload as it comes and issues a buffer
* additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE
* callback handler can use this API to find out if the buffer it has just
* been given is the last piece of a "complete packet" from the client --
* when that is the case libwebsockets_remaining_packet_payload() will return
* 0.
*
* Many protocols won't care becuse their packets are always small.
*/
LWS_VISIBLE size_t
libwebsockets_remaining_packet_payload(struct libwebsocket *wsi)
{
return wsi->u.ws.rx_packet_length;
}
+239
View File
@@ -0,0 +1,239 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
int
insert_wsi_socket_into_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi)
{
struct libwebsocket_pollargs pa = { wsi->sock, LWS_POLLIN, 0 };
if (context->fds_count >= context->max_fds) {
lwsl_err("Too many fds (%d)\n", context->max_fds);
return 1;
}
if (wsi->sock >= context->max_fds) {
lwsl_err("Socket fd %d is too high (%d)\n",
wsi->sock, context->max_fds);
return 1;
}
assert(wsi);
assert(wsi->sock >= 0);
lwsl_info("insert_wsi_socket_into_fds: wsi=%p, sock=%d, fds pos=%d\n",
wsi, wsi->sock, context->fds_count);
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_LOCK_POLL,
wsi->user_space, (void *) &pa, 0);
context->lws_lookup[wsi->sock] = wsi;
wsi->position_in_fds_table = context->fds_count;
context->fds[context->fds_count].fd = wsi->sock;
context->fds[context->fds_count].events = LWS_POLLIN;
lws_plat_insert_socket_into_fds(context, wsi);
/* external POLL support via protocol 0 */
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_ADD_POLL_FD,
wsi->user_space, (void *) &pa, 0);
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_UNLOCK_POLL,
wsi->user_space, (void *)&pa, 0);
return 0;
}
int
remove_wsi_socket_from_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi)
{
int m;
struct libwebsocket_pollargs pa = { wsi->sock, 0, 0 };
lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE);
if (!--context->fds_count) {
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_LOCK_POLL,
wsi->user_space, (void *) &pa, 0);
goto do_ext;
}
if (wsi->sock > context->max_fds) {
lwsl_err("Socket fd %d too high (%d)\n",
wsi->sock, context->max_fds);
return 1;
}
lwsl_info("%s: wsi=%p, sock=%d, fds pos=%d\n", __func__,
wsi, wsi->sock, wsi->position_in_fds_table);
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_LOCK_POLL,
wsi->user_space, (void *)&pa, 0);
m = wsi->position_in_fds_table; /* replace the contents for this */
/* have the last guy take up the vacant slot */
context->fds[m] = context->fds[context->fds_count];
lws_plat_delete_socket_from_fds(context, wsi, m);
/*
* end guy's fds_lookup entry remains unchanged
* (still same fd pointing to same wsi)
*/
/* end guy's "position in fds table" changed */
context->lws_lookup[context->fds[context->fds_count].fd]->
position_in_fds_table = m;
/* deletion guy's lws_lookup entry needs nuking */
context->lws_lookup[wsi->sock] = NULL;
/* removed wsi has no position any more */
wsi->position_in_fds_table = -1;
do_ext:
/* remove also from external POLL support via protocol 0 */
if (wsi->sock) {
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_DEL_POLL_FD, wsi->user_space,
(void *) &pa, 0);
}
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_UNLOCK_POLL,
wsi->user_space, (void *) &pa, 0);
return 0;
}
int
lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or)
{
struct libwebsocket_context *context = wsi->protocol->owning_server;
int tid;
int sampled_tid;
struct libwebsocket_pollfd *pfd;
struct libwebsocket_pollargs pa;
pfd = &context->fds[wsi->position_in_fds_table];
pa.fd = wsi->sock;
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_LOCK_POLL, wsi->user_space, (void *) &pa, 0);
pa.prev_events = pfd->events;
pa.events = pfd->events = (pfd->events & ~_and) | _or;
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_CHANGE_MODE_POLL_FD,
wsi->user_space, (void *) &pa, 0);
/*
* if we changed something in this pollfd...
* ... and we're running in a different thread context
* than the service thread...
* ... and the service thread is waiting ...
* then cancel it to force a restart with our changed events
*/
if (pa.prev_events != pa.events) {
if (lws_plat_change_pollfd(context, wsi, pfd)) {
lwsl_info("%s failed\n", __func__);
return 1;
}
sampled_tid = context->service_tid;
if (sampled_tid) {
tid = context->protocols[0].callback(context, NULL,
LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0);
if (tid != sampled_tid)
libwebsocket_cancel_service(context);
}
}
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_UNLOCK_POLL, wsi->user_space, (void *) &pa, 0);
return 0;
}
/**
* libwebsocket_callback_on_writable() - Request a callback when this socket
* becomes able to be written to without
* blocking
*
* @context: libwebsockets context
* @wsi: Websocket connection instance to get callback for
*/
LWS_VISIBLE int
libwebsocket_callback_on_writable(struct libwebsocket_context *context,
struct libwebsocket *wsi)
{
if (lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_REQUEST_ON_WRITEABLE, NULL, 0))
return 1;
if (wsi->position_in_fds_table < 0) {
lwsl_err("%s: failed to find socket %d\n", __func__, wsi->sock);
return -1;
}
if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
return -1;
lws_libev_io(context, wsi, LWS_EV_START | LWS_EV_WRITE);
return 1;
}
/**
* libwebsocket_callback_on_writable_all_protocol() - Request a callback for
* all connections using the given protocol when it
* becomes possible to write to each socket without
* blocking in turn.
*
* @protocol: Protocol whose connections will get callbacks
*/
LWS_VISIBLE int
libwebsocket_callback_on_writable_all_protocol(
const struct libwebsocket_protocols *protocol)
{
struct libwebsocket_context *context = protocol->owning_server;
int n;
struct libwebsocket *wsi;
for (n = 0; n < context->fds_count; n++) {
wsi = context->lws_lookup[context->fds[n].fd];
if (!wsi)
continue;
if (wsi->protocol == protocol)
libwebsocket_callback_on_writable(context, wsi);
}
return 0;
}
@@ -0,0 +1,917 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2013 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "build.h"
/* The Libwebsocket version */
#define LWS_LIBRARY_VERSION "1.3"
/* The current git commit hash that we're building from */
#define LWS_BUILD_HASH "c11b847"
/* System introspection configs */
#ifdef CMAKE_BUILD
#include "lws_config.h"
#else
#if HOST_OS == OS_WINDOWS
#define inline __inline
#else /* not WIN32 */
#include "config.h"
#endif /* not WIN32 */
#endif /* not CMAKE */
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <limits.h>
#include <stdarg.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if defined(WIN32) || defined(_WIN32)
#define LWS_NO_DAEMONIZE
#define LWS_ERRNO WSAGetLastError()
#define LWS_EAGAIN WSAEWOULDBLOCK
#define LWS_EALREADY WSAEALREADY
#define LWS_EINPROGRESS WSAEINPROGRESS
#define LWS_EINTR WSAEINTR
#define LWS_EISCONN WSAEISCONN
#define LWS_EWOULDBLOCK WSAEWOULDBLOCK
#define LWS_POLLHUP (FD_CLOSE)
#define LWS_POLLIN (FD_READ | FD_ACCEPT)
#define LWS_POLLOUT (FD_WRITE)
#define MSG_NOSIGNAL 0
#define SHUT_RDWR SD_BOTH
#define SOL_TCP IPPROTO_TCP
#define compatible_close(fd) closesocket(fd)
#define compatible_file_close(fd) CloseHandle(fd)
#define compatible_file_seek_cur(fd, offset) SetFilePointer(fd, offset, NULL, FILE_CURRENT)
#define compatible_file_read(amount, fd, buf, len) {\
DWORD _amount; \
if (!ReadFile(fd, buf, len, &_amount, NULL)) \
amount = -1; \
else \
amount = _amount; \
}
#define lws_set_blocking_send(wsi) wsi->sock_send_blocking = TRUE
#include <winsock2.h>
#include <windows.h>
#include <tchar.h>
#ifdef HAVE_IN6ADDR_H
#include <in6addr.h>
#endif
#include <mstcpip.h>
#ifndef __func__
#define __func__ __FUNCTION__
#endif
#ifdef _WIN32_WCE
#define vsnprintf _vsnprintf
#endif
#define LWS_INVALID_FILE INVALID_HANDLE_VALUE
#else /* not windows --> */
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <signal.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifdef LWS_BUILTIN_GETIFADDRS
#include "deps/ifaddrs/ifaddrs.h"
#else
#include <ifaddrs.h>
#endif
//#include <sys/syslog.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <netdb.h>
#ifndef LWS_NO_FORK
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#endif
#endif
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <poll.h>
#ifdef LWS_USE_LIBEV
#include <ev.h>
#endif /* LWS_USE_LIBEV */
#include <sys/mman.h>
#include <sys/time.h>
#define LWS_ERRNO errno
#define LWS_EAGAIN EAGAIN
#define LWS_EALREADY EALREADY
#define LWS_EINPROGRESS EINPROGRESS
#define LWS_EINTR EINTR
#define LWS_EISCONN EISCONN
#define LWS_EWOULDBLOCK EWOULDBLOCK
#define LWS_INVALID_FILE -1
#define LWS_POLLHUP (POLLHUP|POLLERR)
#define LWS_POLLIN (POLLIN)
#define LWS_POLLOUT (POLLOUT)
#define compatible_close(fd) close(fd)
#define compatible_file_close(fd) close(fd)
#define compatible_file_seek_cur(fd, offset) lseek(fd, offset, SEEK_CUR)
#define compatible_file_read(amount, fd, buf, len) \
amount = read(fd, buf, len);
#define lws_set_blocking_send(wsi)
#endif
#ifndef HAVE_BZERO
#define bzero(b, len) (memset((b), '\0', (len)), (void) 0)
#endif
#ifndef HAVE_STRERROR
#define strerror(x) ""
#endif
#ifdef LWS_OPENSSL_SUPPORT
#ifdef USE_CYASSL
#include <cyassl/openssl/ssl.h>
#include <cyassl/error.h>
unsigned char *
SHA1(const unsigned char *d, size_t n, unsigned char *md);
#else
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#endif /* not USE_CYASSL */
#endif
#include "libwebsockets.h"
#if defined(WIN32) || defined(_WIN32)
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */
#endif
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif
typedef unsigned __int64 u_int64_t;
#undef __P
#ifndef __P
#if __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
#else
#include <sys/stat.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#if defined(__APPLE__)
#include <machine/endian.h>
#elif defined(__FreeBSD__)
#include <sys/endian.h>
#elif defined(__linux__)
#include <endian.h>
#endif
#if !defined(BYTE_ORDER)
# define BYTE_ORDER __BYTE_ORDER
#endif
#if !defined(LITTLE_ENDIAN)
# define LITTLE_ENDIAN __LITTLE_ENDIAN
#endif
#if !defined(BIG_ENDIAN)
# define BIG_ENDIAN __BIG_ENDIAN
#endif
#endif
/*
* Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag,
* but happily have something equivalent in the SO_NOSIGPIPE flag.
*/
#ifdef __APPLE__
#define MSG_NOSIGNAL SO_NOSIGPIPE
#endif
#ifndef LWS_MAX_HEADER_LEN
#define LWS_MAX_HEADER_LEN 1024
#endif
#ifndef LWS_MAX_PROTOCOLS
#define LWS_MAX_PROTOCOLS 5
#endif
#ifndef LWS_MAX_EXTENSIONS_ACTIVE
#define LWS_MAX_EXTENSIONS_ACTIVE 3
#endif
#ifndef SPEC_LATEST_SUPPORTED
#define SPEC_LATEST_SUPPORTED 13
#endif
#ifndef AWAITING_TIMEOUT
#define AWAITING_TIMEOUT 5
#endif
#ifndef CIPHERS_LIST_STRING
#define CIPHERS_LIST_STRING "DEFAULT"
#endif
#ifndef LWS_SOMAXCONN
#define LWS_SOMAXCONN SOMAXCONN
#endif
#define MAX_WEBSOCKET_04_KEY_LEN 128
#define LWS_MAX_SOCKET_IO_BUF 4096
#ifndef SYSTEM_RANDOM_FILEPATH
#define SYSTEM_RANDOM_FILEPATH "/dev/urandom"
#endif
#ifndef LWS_MAX_ZLIB_CONN_BUFFER
#define LWS_MAX_ZLIB_CONN_BUFFER (64 * 1024)
#endif
/*
* if not in a connection storm, check for incoming
* connections this many normal connection services
*/
#define LWS_LISTEN_SERVICE_MODULO 10
enum lws_websocket_opcodes_07 {
LWS_WS_OPCODE_07__CONTINUATION = 0,
LWS_WS_OPCODE_07__TEXT_FRAME = 1,
LWS_WS_OPCODE_07__BINARY_FRAME = 2,
LWS_WS_OPCODE_07__NOSPEC__MUX = 7,
/* control extensions 8+ */
LWS_WS_OPCODE_07__CLOSE = 8,
LWS_WS_OPCODE_07__PING = 9,
LWS_WS_OPCODE_07__PONG = 0xa,
};
enum lws_connection_states {
WSI_STATE_HTTP,
WSI_STATE_HTTP_ISSUING_FILE,
WSI_STATE_HTTP_HEADERS,
WSI_STATE_HTTP_BODY,
WSI_STATE_DEAD_SOCKET,
WSI_STATE_ESTABLISHED,
WSI_STATE_CLIENT_UNCONNECTED,
WSI_STATE_RETURNED_CLOSE_ALREADY,
WSI_STATE_AWAITING_CLOSE_ACK,
WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE,
};
enum lws_rx_parse_state {
LWS_RXPS_NEW,
LWS_RXPS_04_MASK_NONCE_1,
LWS_RXPS_04_MASK_NONCE_2,
LWS_RXPS_04_MASK_NONCE_3,
LWS_RXPS_04_FRAME_HDR_1,
LWS_RXPS_04_FRAME_HDR_LEN,
LWS_RXPS_04_FRAME_HDR_LEN16_2,
LWS_RXPS_04_FRAME_HDR_LEN16_1,
LWS_RXPS_04_FRAME_HDR_LEN64_8,
LWS_RXPS_04_FRAME_HDR_LEN64_7,
LWS_RXPS_04_FRAME_HDR_LEN64_6,
LWS_RXPS_04_FRAME_HDR_LEN64_5,
LWS_RXPS_04_FRAME_HDR_LEN64_4,
LWS_RXPS_04_FRAME_HDR_LEN64_3,
LWS_RXPS_04_FRAME_HDR_LEN64_2,
LWS_RXPS_04_FRAME_HDR_LEN64_1,
LWS_RXPS_07_COLLECT_FRAME_KEY_1,
LWS_RXPS_07_COLLECT_FRAME_KEY_2,
LWS_RXPS_07_COLLECT_FRAME_KEY_3,
LWS_RXPS_07_COLLECT_FRAME_KEY_4,
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED
};
enum connection_mode {
LWS_CONNMODE_HTTP_SERVING,
LWS_CONNMODE_HTTP_SERVING_ACCEPTED, /* actual HTTP service going on */
LWS_CONNMODE_PRE_WS_SERVING_ACCEPT,
LWS_CONNMODE_WS_SERVING,
LWS_CONNMODE_WS_CLIENT,
/* transient, ssl delay hiding */
LWS_CONNMODE_SSL_ACK_PENDING,
/* transient modes */
LWS_CONNMODE_WS_CLIENT_WAITING_CONNECT,
LWS_CONNMODE_WS_CLIENT_WAITING_PROXY_REPLY,
LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE,
LWS_CONNMODE_WS_CLIENT_ISSUE_HANDSHAKE2,
LWS_CONNMODE_WS_CLIENT_WAITING_SSL,
LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY,
LWS_CONNMODE_WS_CLIENT_WAITING_EXTENSION_CONNECT,
LWS_CONNMODE_WS_CLIENT_PENDING_CANDIDATE_CHILD,
/* special internal types */
LWS_CONNMODE_SERVER_LISTENER,
};
enum {
LWS_RXFLOW_ALLOW = (1 << 0),
LWS_RXFLOW_PENDING_CHANGE = (1 << 1),
};
struct libwebsocket_protocols;
struct libwebsocket;
#ifdef LWS_USE_LIBEV
struct lws_io_watcher {
struct ev_io watcher;
struct libwebsocket_context* context;
};
struct lws_signal_watcher {
struct ev_signal watcher;
struct libwebsocket_context* context;
};
#endif /* LWS_USE_LIBEV */
struct libwebsocket_context {
#ifdef _WIN32
WSAEVENT *events;
#endif
struct libwebsocket_pollfd *fds;
struct libwebsocket **lws_lookup; /* fd to wsi */
int fds_count;
#ifdef LWS_USE_LIBEV
struct ev_loop* io_loop;
struct lws_io_watcher w_accept;
struct lws_signal_watcher w_sigint;
#endif /* LWS_USE_LIBEV */
int max_fds;
int listen_port;
const char *iface;
char http_proxy_address[128];
char canonical_hostname[128];
unsigned int http_proxy_port;
unsigned int options;
time_t last_timeout_check_s;
/*
* usable by anything in the service code, but only if the scope
* does not last longer than the service action (since next service
* of any socket can likewise use it and overwrite)
*/
unsigned char service_buffer[LWS_MAX_SOCKET_IO_BUF];
int started_with_parent;
int fd_random;
int listen_service_modulo;
int listen_service_count;
int listen_service_fd;
int listen_service_extraseen;
/*
* set to the Thread ID that's doing the service loop just before entry
* to poll indicates service thread likely idling in poll()
* volatile because other threads may check it as part of processing
* for pollfd event change.
*/
volatile int service_tid;
#ifndef _WIN32
int dummy_pipe_fds[2];
#endif
int ka_time;
int ka_probes;
int ka_interval;
#ifdef LWS_LATENCY
unsigned long worst_latency;
char worst_latency_info[256];
#endif
#ifdef LWS_OPENSSL_SUPPORT
int use_ssl;
int allow_non_ssl_on_ssl_port;
SSL_CTX *ssl_ctx;
SSL_CTX *ssl_client_ctx;
#endif
struct libwebsocket_protocols *protocols;
int count_protocols;
#ifndef LWS_NO_EXTENSIONS
struct libwebsocket_extension *extensions;
#endif
void *user_space;
};
enum {
LWS_EV_READ = (1 << 0),
LWS_EV_WRITE = (1 << 1),
LWS_EV_START = (1 << 2),
LWS_EV_STOP = (1 << 3),
};
#ifdef LWS_USE_LIBEV
#define LWS_LIBEV_ENABLED(context) (context->options & LWS_SERVER_OPTION_LIBEV)
LWS_EXTERN void lws_feature_status_libev(struct lws_context_creation_info *info);
LWS_EXTERN void
lws_libev_accept(struct libwebsocket_context *context,
struct libwebsocket *new_wsi, int accept_fd);
LWS_EXTERN void
lws_libev_io(struct libwebsocket_context *context,
struct libwebsocket *wsi, int flags);
LWS_EXTERN int
lws_libev_init_fd_table(struct libwebsocket_context *context);
LWS_EXTERN void
lws_libev_run(struct libwebsocket_context *context);
#else
#define LWS_LIBEV_ENABLED(context) (0)
#define lws_feature_status_libev(_a) \
lwsl_notice("libev support not compiled in\n")
#define lws_libev_accept(_a, _b, _c) (0)
#define lws_libev_io(_a, _b, _c) (0)
#define lws_libev_init_fd_table(_a) (0)
#define lws_libev_run(_a) (0)
#endif
#ifdef LWS_USE_IPV6
#define LWS_IPV6_ENABLED(context) (!(context->options & LWS_SERVER_OPTION_DISABLE_IPV6))
#else
#define LWS_IPV6_ENABLED(context) (0)
#endif
enum uri_path_states {
URIPS_IDLE,
URIPS_SEEN_SLASH,
URIPS_SEEN_SLASH_DOT,
URIPS_SEEN_SLASH_DOT_DOT,
URIPS_ARGUMENTS,
};
enum uri_esc_states {
URIES_IDLE,
URIES_SEEN_PERCENT,
URIES_SEEN_PERCENT_H1,
};
/*
* This is totally opaque to code using the library. It's exported as a
* forward-reference pointer-only declaration; the user can use the pointer with
* other APIs to get information out of it.
*/
struct lws_fragments {
unsigned short offset;
unsigned short len;
unsigned char next_frag_index;
};
struct allocated_headers {
unsigned short next_frag_index;
unsigned short pos;
unsigned char frag_index[WSI_TOKEN_COUNT];
struct lws_fragments frags[WSI_TOKEN_COUNT * 2];
char data[LWS_MAX_HEADER_LEN];
#ifndef LWS_NO_CLIENT
char initial_handshake_hash_base64[30];
unsigned short c_port;
#endif
};
struct _lws_http_mode_related {
struct allocated_headers *ah; /* mirroring _lws_header_related */
#if defined(WIN32) || defined(_WIN32)
HANDLE fd;
#else
int fd;
#endif
unsigned long filepos;
unsigned long filelen;
int content_length;
int content_length_seen;
int body_index;
unsigned char *post_buffer;
};
struct _lws_header_related {
struct allocated_headers *ah;
short lextable_pos;
unsigned char parser_state; /* enum lws_token_indexes */
enum uri_path_states ups;
enum uri_esc_states ues;
char esc_stash;
};
struct _lws_websocket_related {
char *rx_user_buffer;
int rx_user_buffer_head;
unsigned char frame_masking_nonce_04[4];
unsigned char frame_mask_index;
size_t rx_packet_length;
unsigned char opcode;
unsigned int final:1;
unsigned char rsv;
unsigned int frame_is_binary:1;
unsigned int all_zero_nonce:1;
short close_reason; /* enum lws_close_status */
unsigned char *rxflow_buffer;
int rxflow_len;
int rxflow_pos;
unsigned int rxflow_change_to:2;
unsigned int this_frame_masked:1;
unsigned int inside_frame:1; /* next write will be more of frame */
unsigned int clean_buffer:1; /* buffer not rewritten by extension */
};
struct libwebsocket {
/* lifetime members */
#ifdef LWS_USE_LIBEV
struct lws_io_watcher w_read;
struct lws_io_watcher w_write;
#endif /* LWS_USE_LIBEV */
const struct libwebsocket_protocols *protocol;
#ifndef LWS_NO_EXTENSIONS
struct libwebsocket_extension *
active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE];
unsigned char count_active_extensions;
unsigned int extension_data_pending:1;
#endif
unsigned char ietf_spec_revision;
char mode; /* enum connection_mode */
char state; /* enum lws_connection_states */
char lws_rx_parse_state; /* enum lws_rx_parse_state */
char rx_frame_type; /* enum libwebsocket_write_protocol */
unsigned int hdr_parsing_completed:1;
char pending_timeout; /* enum pending_timeout */
time_t pending_timeout_limit;
int sock;
int position_in_fds_table;
#ifdef LWS_LATENCY
unsigned long action_start;
unsigned long latency_start;
#endif
/* truncated send handling */
unsigned char *truncated_send_malloc; /* non-NULL means buffering in progress */
unsigned int truncated_send_allocation; /* size of malloc */
unsigned int truncated_send_offset; /* where we are in terms of spilling */
unsigned int truncated_send_len; /* how much is buffered */
void *user_space;
/* members with mutually exclusive lifetimes are unionized */
union u {
struct _lws_http_mode_related http;
struct _lws_header_related hdr;
struct _lws_websocket_related ws;
} u;
#ifdef LWS_OPENSSL_SUPPORT
SSL *ssl;
BIO *client_bio;
unsigned int use_ssl:2;
#endif
#ifdef _WIN32
BOOL sock_send_blocking;
#endif
};
LWS_EXTERN int log_level;
LWS_EXTERN void
libwebsocket_close_and_free_session(struct libwebsocket_context *context,
struct libwebsocket *wsi, enum lws_close_status);
LWS_EXTERN int
remove_wsi_socket_from_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi);
#ifndef LWS_LATENCY
static inline void lws_latency(struct libwebsocket_context *context,
struct libwebsocket *wsi, const char *action,
int ret, int completion) { while (0); }
static inline void lws_latency_pre(struct libwebsocket_context *context,
struct libwebsocket *wsi) { while (0); }
#else
#define lws_latency_pre(_context, _wsi) lws_latency(_context, _wsi, NULL, 0, 0)
extern void
lws_latency(struct libwebsocket_context *context,
struct libwebsocket *wsi, const char *action,
int ret, int completion);
#endif
LWS_EXTERN int
libwebsocket_client_rx_sm(struct libwebsocket *wsi, unsigned char c);
LWS_EXTERN int
libwebsocket_parse(struct libwebsocket *wsi, unsigned char c);
LWS_EXTERN int
lws_b64_selftest(void);
LWS_EXTERN struct libwebsocket *
wsi_from_fd(struct libwebsocket_context *context, int fd);
LWS_EXTERN int
insert_wsi_socket_into_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_EXTERN int
lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len);
LWS_EXTERN int
libwebsocket_service_timeout_check(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned int sec);
LWS_EXTERN struct libwebsocket *
libwebsocket_client_connect_2(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_EXTERN struct libwebsocket *
libwebsocket_create_new_server_wsi(struct libwebsocket_context *context);
LWS_EXTERN char *
libwebsockets_generate_client_handshake(struct libwebsocket_context *context,
struct libwebsocket *wsi, char *pkt);
LWS_EXTERN int
lws_handle_POLLOUT_event(struct libwebsocket_context *context,
struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd);
/*
* EXTENSIONS
*/
#ifndef LWS_NO_EXTENSIONS
LWS_VISIBLE void
lws_context_init_extensions(struct lws_context_creation_info *info,
struct libwebsocket_context *context);
LWS_EXTERN int
lws_any_extension_handled(struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_extension_callback_reasons r,
void *v, size_t len);
LWS_EXTERN int
lws_ext_callback_for_each_active(struct libwebsocket *wsi, int reason,
void *buf, int len);
LWS_EXTERN int
lws_ext_callback_for_each_extension_type(
struct libwebsocket_context *context, struct libwebsocket *wsi,
int reason, void *arg, int len);
#else
#define lws_any_extension_handled(_a, _b, _c, _d, _e) (0)
#define lws_ext_callback_for_each_active(_a, _b, _c, _d) (0)
#define lws_ext_callback_for_each_extension_type(_a, _b, _c, _d, _e) (0)
#define lws_issue_raw_ext_access lws_issue_raw
#define lws_context_init_extensions(_a, _b)
#endif
LWS_EXTERN int
lws_client_interpret_server_handshake(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_EXTERN int
libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c);
LWS_EXTERN int
lws_issue_raw_ext_access(struct libwebsocket *wsi,
unsigned char *buf, size_t len);
LWS_EXTERN int
_libwebsocket_rx_flow_control(struct libwebsocket *wsi);
LWS_EXTERN int
user_callback_handle_rxflow(callback_function,
struct libwebsocket_context *context,
struct libwebsocket *wsi,
enum libwebsocket_callback_reasons reason, void *user,
void *in, size_t len);
LWS_EXTERN int
lws_plat_set_socket_options(struct libwebsocket_context *context, int fd);
LWS_EXTERN int
lws_allocate_header_table(struct libwebsocket *wsi);
LWS_EXTERN char *
lws_hdr_simple_ptr(struct libwebsocket *wsi, enum lws_token_indexes h);
LWS_EXTERN int
lws_hdr_simple_create(struct libwebsocket *wsi,
enum lws_token_indexes h, const char *s);
LWS_EXTERN int
libwebsocket_ensure_user_space(struct libwebsocket *wsi);
LWS_EXTERN int
lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or);
#ifndef LWS_NO_SERVER
int lws_context_init_server(struct lws_context_creation_info *info,
struct libwebsocket_context *context);
LWS_EXTERN int handshake_0405(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_EXTERN int
libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
unsigned char *buf, size_t len);
LWS_EXTERN void
lws_server_get_canonical_hostname(struct libwebsocket_context *context,
struct lws_context_creation_info *info);
#else
#define lws_context_init_server(_a, _b) (0)
#define libwebsocket_interpret_incoming_packet(_a, _b, _c) (0)
#define lws_server_get_canonical_hostname(_a, _b)
#endif
#ifndef LWS_NO_DAEMONIZE
LWS_EXTERN int get_daemonize_pid();
#else
#define get_daemonize_pid() (0)
#endif
LWS_EXTERN int interface_to_sa(struct libwebsocket_context *context,
const char *ifname, struct sockaddr_in *addr, size_t addrlen);
LWS_EXTERN void lwsl_emit_stderr(int level, const char *line);
#ifdef _WIN32
LWS_EXTERN HANDLE lws_plat_open_file(const char* filename, unsigned long* filelen);
#else
LWS_EXTERN int lws_plat_open_file(const char* filename, unsigned long* filelen);
#endif
enum lws_ssl_capable_status {
LWS_SSL_CAPABLE_ERROR = -1,
LWS_SSL_CAPABLE_MORE_SERVICE = -2,
};
#ifndef LWS_OPENSSL_SUPPORT
#define LWS_SSL_ENABLED(context) (0)
unsigned char *
SHA1(const unsigned char *d, size_t n, unsigned char *md);
#define lws_context_init_server_ssl(_a, _b) (0)
#define lws_ssl_destroy(_a)
#define lws_context_init_http2_ssl(_a)
#define lws_ssl_pending(_a) (0)
#define lws_ssl_capable_read lws_ssl_capable_read_no_ssl
#define lws_ssl_capable_write lws_ssl_capable_write_no_ssl
#define lws_server_socket_service_ssl(_a, _b, _c, _d, _e) (0)
#define lws_ssl_close(_a) (0)
#define lws_ssl_context_destroy(_a)
#else
#define LWS_SSL_ENABLED(context) (context->use_ssl)
LWS_EXTERN int lws_ssl_pending(struct libwebsocket *wsi);
LWS_EXTERN int openssl_websocket_private_data_index;
LWS_EXTERN int
lws_ssl_capable_read(struct libwebsocket *wsi, unsigned char *buf, int len);
LWS_EXTERN int
lws_ssl_capable_write(struct libwebsocket *wsi, unsigned char *buf, int len);
LWS_EXTERN int
lws_server_socket_service_ssl(struct libwebsocket_context *context,
struct libwebsocket **wsi, struct libwebsocket *new_wsi,
int accept_fd, struct libwebsocket_pollfd *pollfd);
LWS_EXTERN int
lws_ssl_close(struct libwebsocket *wsi);
LWS_EXTERN void
lws_ssl_context_destroy(struct libwebsocket_context *context);
#ifndef LWS_NO_SERVER
LWS_EXTERN int
lws_context_init_server_ssl(struct lws_context_creation_info *info,
struct libwebsocket_context *context);
#else
#define lws_context_init_server_ssl(_a, _b) (0)
#endif
LWS_EXTERN void
lws_ssl_destroy(struct libwebsocket_context *context);
/* HTTP2-related */
#ifdef LWS_USE_HTTP2
LWS_EXTERN void
lws_context_init_http2_ssl(struct libwebsocket_context *context);
#else
#define lws_context_init_http2_ssl(_a)
#endif
#endif
LWS_EXTERN int
lws_ssl_capable_read_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len);
LWS_EXTERN int
lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len);
#ifndef LWS_NO_CLIENT
LWS_EXTERN int lws_client_socket_service(
struct libwebsocket_context *context,
struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd);
#ifdef LWS_OPENSSL_SUPPORT
LWS_EXTERN int lws_context_init_client_ssl(struct lws_context_creation_info *info,
struct libwebsocket_context *context);
#else
#define lws_context_init_client_ssl(_a, _b) (0)
#endif
LWS_EXTERN int lws_handshake_client(struct libwebsocket *wsi, unsigned char **buf, size_t len);
LWS_EXTERN void
libwebsockets_decode_ssl_error(void);
#else
#define lws_context_init_client_ssl(_a, _b) (0)
#define lws_handshake_client(_a, _b, _c) (0)
#endif
#ifndef LWS_NO_SERVER
LWS_EXTERN int lws_server_socket_service(
struct libwebsocket_context *context,
struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd);
LWS_EXTERN int _libwebsocket_rx_flow_control(struct libwebsocket *wsi);
LWS_EXTERN int lws_handshake_server(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned char **buf, size_t len);
#else
#define lws_server_socket_service(_a, _b, _c) (0)
#define _libwebsocket_rx_flow_control(_a) (0)
#define lws_handshake_server(_a, _b, _c, _d) (0)
#endif
/*
* lws_plat_
*/
LWS_EXTERN void
lws_plat_delete_socket_from_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi, int m);
LWS_EXTERN void
lws_plat_insert_socket_into_fds(struct libwebsocket_context *context,
struct libwebsocket *wsi);
LWS_EXTERN void
lws_plat_service_periodic(struct libwebsocket_context *context);
LWS_EXTERN int
lws_plat_change_pollfd(struct libwebsocket_context *context,
struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd);
LWS_EXTERN int
lws_plat_context_early_init(void);
LWS_EXTERN void
lws_plat_context_early_destroy(struct libwebsocket_context *context);
LWS_EXTERN void
lws_plat_context_late_destroy(struct libwebsocket_context *context);
LWS_EXTERN int
lws_poll_listen_fd(struct libwebsocket_pollfd *fd);
LWS_EXTERN int
lws_plat_service(struct libwebsocket_context *context, int timeout_ms);
LWS_EXTERN int
lws_plat_init_fd_tables(struct libwebsocket_context *context);
LWS_EXTERN void
lws_plat_drop_app_privileges(struct lws_context_creation_info *info);
LWS_EXTERN unsigned long long
time_in_microseconds(void);
LWS_EXTERN const char *
lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt);
+280
View File
@@ -0,0 +1,280 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2013 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
#define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); }
#ifndef LWS_NO_EXTENSIONS
LWS_VISIBLE int
lws_extension_server_handshake(struct libwebsocket_context *context,
struct libwebsocket *wsi, char **p)
{
int n;
char *c;
char ext_name[128];
struct libwebsocket_extension *ext;
int ext_count = 0;
int more = 1;
/*
* Figure out which extensions the client has that we want to
* enable on this connection, and give him back the list
*/
if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS))
return 0;
/*
* break down the list of client extensions
* and go through them
*/
if (lws_hdr_copy(wsi, (char *)context->service_buffer,
sizeof(context->service_buffer),
WSI_TOKEN_EXTENSIONS) < 0)
return 1;
c = (char *)context->service_buffer;
lwsl_parser("WSI_TOKEN_EXTENSIONS = '%s'\n", c);
wsi->count_active_extensions = 0;
n = 0;
while (more) {
if (*c && (*c != ',' && *c != ' ' && *c != '\t')) {
ext_name[n] = *c++;
if (n < sizeof(ext_name) - 1)
n++;
continue;
}
ext_name[n] = '\0';
if (!*c)
more = 0;
else {
c++;
if (!n)
continue;
}
/* check a client's extension against our support */
ext = wsi->protocol->owning_server->extensions;
while (ext && ext->callback) {
if (strcmp(ext_name, ext->name)) {
ext++;
continue;
}
/*
* oh, we do support this one he
* asked for... but let's ask user
* code if it's OK to apply it on this
* particular connection + protocol
*/
n = wsi->protocol->owning_server->
protocols[0].callback(
wsi->protocol->owning_server,
wsi,
LWS_CALLBACK_CONFIRM_EXTENSION_OKAY,
wsi->user_space, ext_name, 0);
/*
* zero return from callback means
* go ahead and allow the extension,
* it's what we get if the callback is
* unhandled
*/
if (n) {
ext++;
continue;
}
/* apply it */
if (ext_count)
*(*p)++ = ',';
else
LWS_CPYAPP(*p,
"\x0d\x0aSec-WebSocket-Extensions: ");
*p += sprintf(*p, "%s", ext_name);
ext_count++;
/* instantiate the extension on this conn */
wsi->active_extensions_user[
wsi->count_active_extensions] =
malloc(ext->per_session_data_size);
if (wsi->active_extensions_user[
wsi->count_active_extensions] == NULL) {
lwsl_err("Out of mem\n");
return 1;
}
memset(wsi->active_extensions_user[
wsi->count_active_extensions], 0,
ext->per_session_data_size);
wsi->active_extensions[
wsi->count_active_extensions] = ext;
/* allow him to construct his context */
ext->callback(wsi->protocol->owning_server,
ext, wsi,
LWS_EXT_CALLBACK_CONSTRUCT,
wsi->active_extensions_user[
wsi->count_active_extensions], NULL, 0);
wsi->count_active_extensions++;
lwsl_parser("count_active_extensions <- %d\n",
wsi->count_active_extensions);
ext++;
}
n = 0;
}
return 0;
}
#endif
int
handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi)
{
unsigned char hash[20];
int n;
char *response;
char *p;
int accept_len;
if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST) ||
!lws_hdr_total_length(wsi, WSI_TOKEN_KEY)) {
lwsl_parser("handshake_04 missing pieces\n");
/* completed header processing, but missing some bits */
goto bail;
}
if (lws_hdr_total_length(wsi, WSI_TOKEN_KEY) >=
MAX_WEBSOCKET_04_KEY_LEN) {
lwsl_warn("Client key too long %d\n", MAX_WEBSOCKET_04_KEY_LEN);
goto bail;
}
/*
* since key length is restricted above (currently 128), cannot
* overflow
*/
n = sprintf((char *)context->service_buffer,
"%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
lws_hdr_simple_ptr(wsi, WSI_TOKEN_KEY));
SHA1(context->service_buffer, n, hash);
accept_len = lws_b64_encode_string((char *)hash, 20,
(char *)context->service_buffer,
sizeof(context->service_buffer));
if (accept_len < 0) {
lwsl_warn("Base64 encoded hash too long\n");
goto bail;
}
/* allocate the per-connection user memory (if any) */
if (libwebsocket_ensure_user_space(wsi))
goto bail;
/* create the response packet */
/* make a buffer big enough for everything */
response = (char *)context->service_buffer + MAX_WEBSOCKET_04_KEY_LEN;
p = response;
LWS_CPYAPP(p, "HTTP/1.1 101 Switching Protocols\x0d\x0a"
"Upgrade: WebSocket\x0d\x0a"
"Connection: Upgrade\x0d\x0a"
"Sec-WebSocket-Accept: ");
strcpy(p, (char *)context->service_buffer);
p += accept_len;
if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL)) {
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: ");
n = lws_hdr_copy(wsi, p, 128, WSI_TOKEN_PROTOCOL);
if (n < 0)
goto bail;
p += n;
}
#ifndef LWS_NO_EXTENSIONS
/*
* Figure out which extensions the client has that we want to
* enable on this connection, and give him back the list
*/
if (lws_extension_server_handshake(context, wsi, &p))
goto bail;
#endif
/* end of response packet */
LWS_CPYAPP(p, "\x0d\x0a\x0d\x0a");
if (!lws_any_extension_handled(context, wsi,
LWS_EXT_CALLBACK_HANDSHAKE_REPLY_TX,
response, p - response)) {
/* okay send the handshake response accepting the connection */
lwsl_parser("issuing resp pkt %d len\n", (int)(p - response));
#ifdef DEBUG
fwrite(response, 1, p - response, stderr);
#endif
n = libwebsocket_write(wsi, (unsigned char *)response,
p - response, LWS_WRITE_HTTP);
if (n != (p - response)) {
lwsl_debug("handshake_0405: ERROR writing to socket\n");
goto bail;
}
}
/* alright clean up and set ourselves into established state */
wsi->state = WSI_STATE_ESTABLISHED;
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
/* notify user code that we're ready to roll */
if (wsi->protocol->callback)
wsi->protocol->callback(wsi->protocol->owning_server,
wsi, LWS_CALLBACK_ESTABLISHED,
wsi->user_space, NULL, 0);
return 0;
bail:
/* free up his parsing allocations */
if (wsi->u.hdr.ah)
free(wsi->u.hdr.ah);
return -1;
}
+868
View File
@@ -0,0 +1,868 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2013 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
int lws_context_init_server(struct lws_context_creation_info *info,
struct libwebsocket_context *context)
{
int n;
int sockfd;
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
int opt = 1;
struct libwebsocket *wsi;
#ifdef LWS_USE_IPV6
struct sockaddr_in6 serv_addr6;
#endif
struct sockaddr_in serv_addr4;
struct sockaddr *v;
/* set up our external listening socket we serve on */
if (info->port == CONTEXT_PORT_NO_LISTEN)
return 0;
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context))
sockfd = socket(AF_INET6, SOCK_STREAM, 0);
else
#endif
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
lwsl_err("ERROR opening socket\n");
return 1;
}
/*
* allow us to restart even if old sockets in TIME_WAIT
*/
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
(const void *)&opt, sizeof(opt));
lws_plat_set_socket_options(context, sockfd);
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(context)) {
v = (struct sockaddr *)&serv_addr6;
n = sizeof(struct sockaddr_in6);
bzero((char *) &serv_addr6, sizeof(serv_addr6));
serv_addr6.sin6_addr = in6addr_any;
serv_addr6.sin6_family = AF_INET6;
serv_addr6.sin6_port = htons(info->port);
} else
#endif
{
v = (struct sockaddr *)&serv_addr4;
n = sizeof(serv_addr4);
bzero((char *) &serv_addr4, sizeof(serv_addr4));
serv_addr4.sin_addr.s_addr = INADDR_ANY;
serv_addr4.sin_family = AF_INET;
serv_addr4.sin_port = htons(info->port);
if (info->iface) {
if (interface_to_sa(context, info->iface,
(struct sockaddr_in *)v, n) < 0) {
lwsl_err("Unable to find interface %s\n",
info->iface);
compatible_close(sockfd);
return 1;
}
}
} /* ipv4 */
n = bind(sockfd, v, n);
if (n < 0) {
lwsl_err("ERROR on binding to port %d (%d %d)\n",
info->port, n, LWS_ERRNO);
compatible_close(sockfd);
return 1;
}
if (getsockname(sockfd, (struct sockaddr *)&sin, &len) == -1)
lwsl_warn("getsockname: %s\n", strerror(LWS_ERRNO));
else
info->port = ntohs(sin.sin_port);
context->listen_port = info->port;
wsi = (struct libwebsocket *)malloc(sizeof(struct libwebsocket));
if (wsi == NULL) {
lwsl_err("Out of mem\n");
compatible_close(sockfd);
return 1;
}
memset(wsi, 0, sizeof(struct libwebsocket));
wsi->sock = sockfd;
wsi->mode = LWS_CONNMODE_SERVER_LISTENER;
insert_wsi_socket_into_fds(context, wsi);
context->listen_service_modulo = LWS_LISTEN_SERVICE_MODULO;
context->listen_service_count = 0;
context->listen_service_fd = sockfd;
listen(sockfd, LWS_SOMAXCONN);
lwsl_notice(" Listening on port %d\n", info->port);
return 0;
}
int
_libwebsocket_rx_flow_control(struct libwebsocket *wsi)
{
struct libwebsocket_context *context = wsi->protocol->owning_server;
/* there is no pending change */
if (!(wsi->u.ws.rxflow_change_to & LWS_RXFLOW_PENDING_CHANGE))
return 0;
/* stuff is still buffered, not ready to really accept new input */
if (wsi->u.ws.rxflow_buffer) {
/* get ourselves called back to deal with stashed buffer */
libwebsocket_callback_on_writable(context, wsi);
return 0;
}
/* pending is cleared, we can change rxflow state */
wsi->u.ws.rxflow_change_to &= ~LWS_RXFLOW_PENDING_CHANGE;
lwsl_info("rxflow: wsi %p change_to %d\n", wsi,
wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW);
/* adjust the pollfd for this wsi */
if (wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW) {
if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) {
lwsl_info("%s: fail\n", __func__);
return -1;
}
} else
if (lws_change_pollfd(wsi, LWS_POLLIN, 0))
return -1;
return 0;
}
int lws_handshake_server(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned char **buf, size_t len)
{
struct allocated_headers *ah;
char *uri_ptr = NULL;
int uri_len = 0;
char content_length_str[32];
int n;
/* LWS_CONNMODE_WS_SERVING */
while (len--) {
if (libwebsocket_parse(wsi, *(*buf)++)) {
lwsl_info("libwebsocket_parse failed\n");
goto bail_nuke_ah;
}
if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
continue;
lwsl_parser("libwebsocket_parse sees parsing complete\n");
wsi->mode = LWS_CONNMODE_PRE_WS_SERVING_ACCEPT;
libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
/* is this websocket protocol or normal http 1.0? */
if (!lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE) ||
!lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION)) {
/* it's not websocket.... shall we accept it as http? */
if (!lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) &&
!lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
lwsl_warn("Missing URI in HTTP request\n");
goto bail_nuke_ah;
}
if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) &&
lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
lwsl_warn("GET and POST methods?\n");
goto bail_nuke_ah;
}
if (libwebsocket_ensure_user_space(wsi))
goto bail_nuke_ah;
if (lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI)) {
uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI);
uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI);
lwsl_info("HTTP GET request for '%s'\n",
lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI));
}
if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
lwsl_info("HTTP POST request for '%s'\n",
lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI));
uri_ptr = lws_hdr_simple_ptr(wsi, WSI_TOKEN_POST_URI);
uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI);
}
/*
* Hm we still need the headers so the
* callback can look at leaders like the URI, but we
* need to transition to http union state.... hold a
* copy of u.hdr.ah and deallocate afterwards
*/
ah = wsi->u.hdr.ah;
/* union transition */
memset(&wsi->u, 0, sizeof(wsi->u));
wsi->mode = LWS_CONNMODE_HTTP_SERVING_ACCEPTED;
wsi->state = WSI_STATE_HTTP;
wsi->u.http.fd = LWS_INVALID_FILE;
/* expose it at the same offset as u.hdr */
wsi->u.http.ah = ah;
/* HTTP header had a content length? */
wsi->u.http.content_length = 0;
if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI))
wsi->u.http.content_length = 100 * 1024 * 1024;
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
lws_hdr_copy(wsi, content_length_str,
sizeof(content_length_str) - 1,
WSI_TOKEN_HTTP_CONTENT_LENGTH);
wsi->u.http.content_length = atoi(content_length_str);
}
if (wsi->u.http.content_length > 0) {
wsi->u.http.body_index = 0;
n = wsi->protocol->rx_buffer_size;
if (!n)
n = LWS_MAX_SOCKET_IO_BUF;
wsi->u.http.post_buffer = malloc(n);
if (!wsi->u.http.post_buffer) {
lwsl_err("Unable to allocate post buffer\n");
n = -1;
goto cleanup;
}
}
n = 0;
if (wsi->protocol->callback)
n = wsi->protocol->callback(context, wsi,
LWS_CALLBACK_FILTER_HTTP_CONNECTION,
wsi->user_space, uri_ptr, uri_len);
if (!n) {
/*
* if there is content supposed to be coming,
* put a timeout on it having arrived
*/
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_HTTP_CONTENT,
AWAITING_TIMEOUT);
if (wsi->protocol->callback)
n = wsi->protocol->callback(context, wsi,
LWS_CALLBACK_HTTP,
wsi->user_space, uri_ptr, uri_len);
}
cleanup:
/* now drop the header info we kept a pointer to */
if (ah)
free(ah);
/* not possible to continue to use past here */
wsi->u.http.ah = NULL;
if (n) {
lwsl_info("LWS_CALLBACK_HTTP closing\n");
return 1; /* struct ah ptr already nuked */
}
/*
* (if callback didn't start sending a file)
* deal with anything else as body, whether
* there was a content-length or not
*/
if (wsi->state != WSI_STATE_HTTP_ISSUING_FILE)
wsi->state = WSI_STATE_HTTP_BODY;
return 2; /* goto http_postbody; */
}
if (!wsi->protocol)
lwsl_err("NULL protocol at libwebsocket_read\n");
/*
* It's websocket
*
* Make sure user side is happy about protocol
*/
while (wsi->protocol->callback) {
if (!lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL)) {
if (wsi->protocol->name == NULL)
break;
} else
if (wsi->protocol->name && strcmp(
lws_hdr_simple_ptr(wsi,
WSI_TOKEN_PROTOCOL),
wsi->protocol->name) == 0)
break;
wsi->protocol++;
}
/* we didn't find a protocol he wanted? */
if (wsi->protocol->callback == NULL) {
if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL) ==
NULL) {
lwsl_info("no protocol -> prot 0 handler\n");
wsi->protocol = &context->protocols[0];
} else {
lwsl_err("Req protocol %s not supported\n",
lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL));
goto bail_nuke_ah;
}
}
/* allocate wsi->user storage */
if (libwebsocket_ensure_user_space(wsi))
goto bail_nuke_ah;
/*
* Give the user code a chance to study the request and
* have the opportunity to deny it
*/
if ((wsi->protocol->callback)(wsi->protocol->owning_server, wsi,
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
wsi->user_space,
lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL), 0)) {
lwsl_warn("User code denied connection\n");
goto bail_nuke_ah;
}
/*
* Perform the handshake according to the protocol version the
* client announced
*/
switch (wsi->ietf_spec_revision) {
case 13:
lwsl_parser("lws_parse calling handshake_04\n");
if (handshake_0405(context, wsi)) {
lwsl_info("hs0405 has failed the connection\n");
goto bail_nuke_ah;
}
break;
default:
lwsl_warn("Unknown client spec version %d\n",
wsi->ietf_spec_revision);
goto bail_nuke_ah;
}
/* drop the header info -- no bail_nuke_ah after this */
if (wsi->u.hdr.ah)
free(wsi->u.hdr.ah);
wsi->mode = LWS_CONNMODE_WS_SERVING;
/* union transition */
memset(&wsi->u, 0, sizeof(wsi->u));
wsi->u.ws.rxflow_change_to = LWS_RXFLOW_ALLOW;
/*
* create the frame buffer for this connection according to the
* size mentioned in the protocol definition. If 0 there, use
* a big default for compatibility
*/
n = wsi->protocol->rx_buffer_size;
if (!n)
n = LWS_MAX_SOCKET_IO_BUF;
n += LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING;
wsi->u.ws.rx_user_buffer = malloc(n);
if (!wsi->u.ws.rx_user_buffer) {
lwsl_err("Out of Mem allocating rx buffer %d\n", n);
return 1;
}
lwsl_info("Allocating RX buffer %d\n", n);
if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) {
lwsl_warn("Failed to set SNDBUF to %d", n);
return 1;
}
lwsl_parser("accepted v%02d connection\n",
wsi->ietf_spec_revision);
} /* while all chars are handled */
return 0;
bail_nuke_ah:
/* drop the header info */
if (wsi->u.hdr.ah)
free(wsi->u.hdr.ah);
return 1;
}
struct libwebsocket *
libwebsocket_create_new_server_wsi(struct libwebsocket_context *context)
{
struct libwebsocket *new_wsi;
new_wsi = (struct libwebsocket *)malloc(sizeof(struct libwebsocket));
if (new_wsi == NULL) {
lwsl_err("Out of memory for new connection\n");
return NULL;
}
memset(new_wsi, 0, sizeof(struct libwebsocket));
new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
/* intialize the instance struct */
new_wsi->state = WSI_STATE_HTTP;
new_wsi->mode = LWS_CONNMODE_HTTP_SERVING;
new_wsi->hdr_parsing_completed = 0;
if (lws_allocate_header_table(new_wsi)) {
free(new_wsi);
return NULL;
}
/*
* these can only be set once the protocol is known
* we set an unestablished connection's protocol pointer
* to the start of the supported list, so it can look
* for matching ones during the handshake
*/
new_wsi->protocol = context->protocols;
new_wsi->user_space = NULL;
new_wsi->ietf_spec_revision = 0;
/*
* outermost create notification for wsi
* no user_space because no protocol selection
*/
context->protocols[0].callback(context, new_wsi,
LWS_CALLBACK_WSI_CREATE, NULL, NULL, 0);
return new_wsi;
}
int lws_server_socket_service(struct libwebsocket_context *context,
struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd)
{
struct libwebsocket *new_wsi = NULL;
int accept_fd = 0;
socklen_t clilen;
struct sockaddr_in cli_addr;
int n;
int len;
switch (wsi->mode) {
case LWS_CONNMODE_HTTP_SERVING:
case LWS_CONNMODE_HTTP_SERVING_ACCEPTED:
/* handle http headers coming in */
/* pending truncated sends have uber priority */
if (wsi->truncated_send_malloc) {
if (pollfd->revents & LWS_POLLOUT)
if (lws_issue_raw(wsi, wsi->truncated_send_malloc +
wsi->truncated_send_offset,
wsi->truncated_send_len) < 0) {
lwsl_info("closing from socket service\n");
return -1;
}
/*
* we can't afford to allow input processing send
* something new, so spin around he event loop until
* he doesn't have any partials
*/
break;
}
/* any incoming data ready? */
if (pollfd->revents & LWS_POLLIN) {
len = lws_ssl_capable_read(wsi,
context->service_buffer,
sizeof(context->service_buffer));
switch (len) {
case 0:
lwsl_info("lws_server_skt_srv: read 0 len\n");
/* lwsl_info(" state=%d\n", wsi->state); */
if (!wsi->hdr_parsing_completed)
free(wsi->u.hdr.ah);
/* fallthru */
case LWS_SSL_CAPABLE_ERROR:
libwebsocket_close_and_free_session(
context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return 0;
case LWS_SSL_CAPABLE_MORE_SERVICE:
break;
}
/* just ignore incoming if waiting for close */
if (wsi->state != WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
/* hm this may want to send (via HTTP callback for example) */
n = libwebsocket_read(context, wsi,
context->service_buffer, len);
if (n < 0)
/* we closed wsi */
return 0;
/* hum he may have used up the writability above */
break;
}
}
/* this handles POLLOUT for http serving fragments */
if (!(pollfd->revents & LWS_POLLOUT))
break;
/* one shot */
if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
goto fail;
lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_WRITE);
if (wsi->state != WSI_STATE_HTTP_ISSUING_FILE) {
n = user_callback_handle_rxflow(
wsi->protocol->callback,
wsi->protocol->owning_server,
wsi, LWS_CALLBACK_HTTP_WRITEABLE,
wsi->user_space,
NULL,
0);
if (n < 0)
libwebsocket_close_and_free_session(
context, wsi, LWS_CLOSE_STATUS_NOSTATUS);
break;
}
/* nonzero for completion or error */
if (libwebsockets_serve_http_file_fragment(context, wsi))
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
break;
case LWS_CONNMODE_SERVER_LISTENER:
/* pollin means a client has connected to us then */
if (!(pollfd->revents & LWS_POLLIN))
break;
/* listen socket got an unencrypted connection... */
clilen = sizeof(cli_addr);
lws_latency_pre(context, wsi);
accept_fd = accept(pollfd->fd, (struct sockaddr *)&cli_addr,
&clilen);
lws_latency(context, wsi,
"unencrypted accept LWS_CONNMODE_SERVER_LISTENER",
accept_fd, accept_fd >= 0);
if (accept_fd < 0) {
if (LWS_ERRNO == LWS_EAGAIN || LWS_ERRNO == LWS_EWOULDBLOCK) {
lwsl_debug("accept asks to try again\n");
break;
}
lwsl_warn("ERROR on accept: %s\n", strerror(LWS_ERRNO));
break;
}
lws_plat_set_socket_options(context, accept_fd);
/*
* look at who we connected to and give user code a chance
* to reject based on client IP. There's no protocol selected
* yet so we issue this to protocols[0]
*/
if ((context->protocols[0].callback)(context, wsi,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
NULL, (void *)(long)accept_fd, 0)) {
lwsl_debug("Callback denied network connection\n");
compatible_close(accept_fd);
break;
}
new_wsi = libwebsocket_create_new_server_wsi(context);
if (new_wsi == NULL) {
compatible_close(accept_fd);
break;
}
new_wsi->sock = accept_fd;
/* the transport is accepted... give him time to negotiate */
libwebsocket_set_timeout(new_wsi,
PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
AWAITING_TIMEOUT);
/*
* A new connection was accepted. Give the user a chance to
* set properties of the newly created wsi. There's no protocol
* selected yet so we issue this to protocols[0]
*/
(context->protocols[0].callback)(context, new_wsi,
LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED, NULL, NULL, 0);
lws_libev_accept(context, new_wsi, accept_fd);
if (!LWS_SSL_ENABLED(context)) {
lwsl_debug("accepted new conn port %u on fd=%d\n",
ntohs(cli_addr.sin_port), accept_fd);
insert_wsi_socket_into_fds(context, new_wsi);
}
break;
default:
break;
}
if (lws_server_socket_service_ssl(context, &wsi, new_wsi, accept_fd, pollfd))
goto fail;
return 0;
fail:
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
return 1;
}
static const char *err400[] = {
"Bad Request",
"Unauthorized",
"Payment Required",
"Forbidden",
"Not Found",
"Method Not Allowed",
"Not Acceptable",
"Proxy Auth Required",
"Request Timeout",
"Conflict",
"Gone",
"Length Required",
"Precondition Failed",
"Request Entity Too Large",
"Request URI too Long",
"Unsupported Media Type",
"Requested Range Not Satisfiable",
"Expectation Failed"
};
static const char *err500[] = {
"Internal Server Error",
"Not Implemented",
"Bad Gateway",
"Service Unavailable",
"Gateway Timeout",
"HTTP Version Not Supported"
};
/**
* libwebsockets_return_http_status() - Return simple http status
* @context: libwebsockets context
* @wsi: Websocket instance (available from user callback)
* @code: Status index, eg, 404
* @html_body: User-readable HTML description, or NULL
*
* Helper to report HTTP errors back to the client cleanly and
* consistently
*/
LWS_VISIBLE int libwebsockets_return_http_status(
struct libwebsocket_context *context, struct libwebsocket *wsi,
unsigned int code, const char *html_body)
{
int n, m;
const char *description = "";
if (!html_body)
html_body = "";
if (code >= 400 && code < (400 + ARRAY_SIZE(err400)))
description = err400[code - 400];
if (code >= 500 && code < (500 + ARRAY_SIZE(err500)))
description = err500[code - 500];
n = sprintf((char *)context->service_buffer,
"HTTP/1.0 %u %s\x0d\x0a"
"Server: libwebsockets\x0d\x0a"
"Content-Type: text/html\x0d\x0a\x0d\x0a"
"<h1>%u %s</h1>%s",
code, description, code, description, html_body);
lwsl_info((const char *)context->service_buffer);
m = libwebsocket_write(wsi, context->service_buffer, n, LWS_WRITE_HTTP);
return m;
}
/**
* libwebsockets_serve_http_file() - Send a file back to the client using http
* @context: libwebsockets context
* @wsi: Websocket instance (available from user callback)
* @file: The file to issue over http
* @content_type: The http content type, eg, text/html
* @other_headers: NULL or pointer to \0-terminated other header string
*
* This function is intended to be called from the callback in response
* to http requests from the client. It allows the callback to issue
* local files down the http link in a single step.
*
* Returning <0 indicates error and the wsi should be closed. Returning
* >0 indicates the file was completely sent and the wsi should be closed.
* ==0 indicates the file transfer is started and needs more service later,
* the wsi should be left alone.
*/
LWS_VISIBLE int libwebsockets_serve_http_file(
struct libwebsocket_context *context,
struct libwebsocket *wsi, const char *file,
const char *content_type, const char *other_headers)
{
unsigned char *p = context->service_buffer;
int ret = 0;
int n;
wsi->u.http.fd = lws_plat_open_file(file, &wsi->u.http.filelen);
if (wsi->u.http.fd == LWS_INVALID_FILE) {
lwsl_err("Unable to open '%s'\n", file);
libwebsockets_return_http_status(context, wsi,
HTTP_STATUS_NOT_FOUND, NULL);
return -1;
}
p += sprintf((char *)p,
"HTTP/1.0 200 OK\x0d\x0aServer: libwebsockets\x0d\x0a""Content-Type: %s\x0d\x0a",
content_type);
if (other_headers) {
n = strlen(other_headers);
memcpy(p, other_headers, n);
p += n;
}
p += sprintf((char *)p,
"Content-Length: %lu\x0d\x0a\x0d\x0a", wsi->u.http.filelen);
ret = libwebsocket_write(wsi, context->service_buffer,
p - context->service_buffer, LWS_WRITE_HTTP);
if (ret != (p - context->service_buffer)) {
lwsl_err("_write returned %d from %d\n", ret, (p - context->service_buffer));
return -1;
}
wsi->u.http.filepos = 0;
wsi->state = WSI_STATE_HTTP_ISSUING_FILE;
return libwebsockets_serve_http_file_fragment(context, wsi);
}
int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
unsigned char *buf, size_t len)
{
size_t n = 0;
int m;
#if 0
lwsl_parser("received %d byte packet\n", (int)len);
lwsl_hexdump(buf, len);
#endif
/* let the rx protocol state machine have as much as it needs */
while (n < len) {
/*
* we were accepting input but now we stopped doing so
*/
if (!(wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW)) {
/* his RX is flowcontrolled, don't send remaining now */
if (!wsi->u.ws.rxflow_buffer) {
/* a new rxflow, buffer it and warn caller */
lwsl_info("new rxflow input buffer len %d\n",
len - n);
wsi->u.ws.rxflow_buffer =
(unsigned char *)malloc(len - n);
wsi->u.ws.rxflow_len = len - n;
wsi->u.ws.rxflow_pos = 0;
memcpy(wsi->u.ws.rxflow_buffer,
buf + n, len - n);
} else
/* rxflow while we were spilling prev rxflow */
lwsl_info("stalling in existing rxflow buf\n");
return 1;
}
/* account for what we're using in rxflow buffer */
if (wsi->u.ws.rxflow_buffer)
wsi->u.ws.rxflow_pos++;
/* process the byte */
m = libwebsocket_rx_sm(wsi, buf[n++]);
if (m < 0)
return -1;
}
return 0;
}
LWS_VISIBLE void
lws_server_get_canonical_hostname(struct libwebsocket_context *context,
struct lws_context_creation_info *info)
{
if (info->options & LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME)
return;
/* find canonical hostname */
gethostname((char *)context->canonical_hostname,
sizeof(context->canonical_hostname) - 1);
lwsl_notice(" canonical_hostname = %s\n", context->canonical_hostname);
}
+514
View File
@@ -0,0 +1,514 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
int
lws_handle_POLLOUT_event(struct libwebsocket_context *context,
struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd)
{
int n;
struct lws_tokens eff_buf;
int ret;
int m;
int handled = 0;
/* pending truncated sends have uber priority */
if (wsi->truncated_send_len) {
if (lws_issue_raw(wsi, wsi->truncated_send_malloc +
wsi->truncated_send_offset,
wsi->truncated_send_len) < 0) {
lwsl_info("lws_handle_POLLOUT_event signalling to close\n");
return -1;
}
/* leave POLLOUT active either way */
return 0;
} else
if (wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
lwsl_info("***** %x signalling to close in POLLOUT handler\n", wsi);
return -1; /* retry closing now */
}
m = lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_IS_WRITEABLE,
NULL, 0);
if (handled == 1)
goto notify_action;
#ifndef LWS_NO_EXTENSIONS
if (!wsi->extension_data_pending || handled == 2)
goto user_service;
#endif
/*
* check in on the active extensions, see if they
* had pending stuff to spill... they need to get the
* first look-in otherwise sequence will be disordered
*
* NULL, zero-length eff_buf means just spill pending
*/
ret = 1;
while (ret == 1) {
/* default to nobody has more to spill */
ret = 0;
eff_buf.token = NULL;
eff_buf.token_len = 0;
/* give every extension a chance to spill */
m = lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
&eff_buf, 0);
if (m < 0) {
lwsl_err("ext reports fatal error\n");
return -1;
}
if (m)
/*
* at least one extension told us he has more
* to spill, so we will go around again after
*/
ret = 1;
/* assuming they gave us something to send, send it */
if (eff_buf.token_len) {
n = lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
eff_buf.token_len);
if (n < 0) {
lwsl_info("closing from POLLOUT spill\n");
return -1;
}
/*
* Keep amount spilled small to minimize chance of this
*/
if (n != eff_buf.token_len) {
lwsl_err("Unable to spill ext %d vs %s\n",
eff_buf.token_len, n);
return -1;
}
} else
continue;
/* no extension has more to spill */
if (!ret)
continue;
/*
* There's more to spill from an extension, but we just sent
* something... did that leave the pipe choked?
*/
if (!lws_send_pipe_choked(wsi))
/* no we could add more */
continue;
lwsl_info("choked in POLLOUT service\n");
/*
* Yes, he's choked. Leave the POLLOUT masked on so we will
* come back here when he is unchoked. Don't call the user
* callback to enforce ordering of spilling, he'll get called
* when we come back here and there's nothing more to spill.
*/
return 0;
}
#ifndef LWS_NO_EXTENSIONS
wsi->extension_data_pending = 0;
user_service:
#endif
/* one shot */
if (pollfd) {
if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
return 1;
lws_libev_io(context, wsi, LWS_EV_STOP | LWS_EV_WRITE);
}
notify_action:
if (wsi->mode == LWS_CONNMODE_WS_CLIENT)
n = LWS_CALLBACK_CLIENT_WRITEABLE;
else
n = LWS_CALLBACK_SERVER_WRITEABLE;
return user_callback_handle_rxflow(wsi->protocol->callback, context,
wsi, (enum libwebsocket_callback_reasons) n,
wsi->user_space, NULL, 0);
}
int
libwebsocket_service_timeout_check(struct libwebsocket_context *context,
struct libwebsocket *wsi, unsigned int sec)
{
/*
* if extensions want in on it (eg, we are a mux parent)
* give them a chance to service child timeouts
*/
if (lws_ext_callback_for_each_active(wsi, LWS_EXT_CALLBACK_1HZ, NULL, sec) < 0)
return 0;
if (!wsi->pending_timeout)
return 0;
/*
* if we went beyond the allowed time, kill the
* connection
*/
if (sec > wsi->pending_timeout_limit) {
lwsl_info("TIMEDOUT WAITING on %d\n", wsi->pending_timeout);
libwebsocket_close_and_free_session(context,
wsi, LWS_CLOSE_STATUS_NOSTATUS);
return 1;
}
return 0;
}
/**
* libwebsocket_service_fd() - Service polled socket with something waiting
* @context: Websocket context
* @pollfd: The pollfd entry describing the socket fd and which events
* happened.
*
* This function takes a pollfd that has POLLIN or POLLOUT activity and
* services it according to the state of the associated
* struct libwebsocket.
*
* The one call deals with all "service" that might happen on a socket
* including listen accepts, http files as well as websocket protocol.
*
* If a pollfd says it has something, you can just pass it to
* libwebsocket_serice_fd() whether it is a socket handled by lws or not.
* If it sees it is a lws socket, the traffic will be handled and
* pollfd->revents will be zeroed now.
*
* If the socket is foreign to lws, it leaves revents alone. So you can
* see if you should service yourself by checking the pollfd revents
* after letting lws try to service it.
*/
LWS_VISIBLE int
libwebsocket_service_fd(struct libwebsocket_context *context,
struct libwebsocket_pollfd *pollfd)
{
struct libwebsocket *wsi;
int n;
int m;
int listen_socket_fds_index = 0;
time_t now;
int timed_out = 0;
int our_fd = 0;
char draining_flow = 0;
int more;
struct lws_tokens eff_buf;
if (context->listen_service_fd)
listen_socket_fds_index = context->lws_lookup[
context->listen_service_fd]->position_in_fds_table;
/*
* you can call us with pollfd = NULL to just allow the once-per-second
* global timeout checks; if less than a second since the last check
* it returns immediately then.
*/
time(&now);
/* TODO: if using libev, we should probably use timeout watchers... */
if (context->last_timeout_check_s != now) {
context->last_timeout_check_s = now;
lws_plat_service_periodic(context);
/* global timeout check once per second */
if (pollfd)
our_fd = pollfd->fd;
for (n = 0; n < context->fds_count; n++) {
m = context->fds[n].fd;
wsi = context->lws_lookup[m];
if (!wsi)
continue;
if (libwebsocket_service_timeout_check(context, wsi, now))
/* he did time out... */
if (m == our_fd) {
/* it was the guy we came to service! */
timed_out = 1;
/* mark as handled */
pollfd->revents = 0;
}
}
}
/* the socket we came to service timed out, nothing to do */
if (timed_out)
return 0;
/* just here for timeout management? */
if (pollfd == NULL)
return 0;
/* no, here to service a socket descriptor */
wsi = context->lws_lookup[pollfd->fd];
if (wsi == NULL)
/* not lws connection ... leave revents alone and return */
return 0;
/*
* so that caller can tell we handled, past here we need to
* zero down pollfd->revents after handling
*/
/*
* deal with listen service piggybacking
* every listen_service_modulo services of other fds, we
* sneak one in to service the listen socket if there's anything waiting
*
* To handle connection storms, as found in ab, if we previously saw a
* pending connection here, it causes us to check again next time.
*/
if (context->listen_service_fd && pollfd !=
&context->fds[listen_socket_fds_index]) {
context->listen_service_count++;
if (context->listen_service_extraseen ||
context->listen_service_count ==
context->listen_service_modulo) {
context->listen_service_count = 0;
m = 1;
if (context->listen_service_extraseen > 5)
m = 2;
while (m--) {
/*
* even with extpoll, we prepared this
* internal fds for listen
*/
n = lws_poll_listen_fd(&context->fds[listen_socket_fds_index]);
if (n > 0) { /* there's a conn waiting for us */
libwebsocket_service_fd(context,
&context->
fds[listen_socket_fds_index]);
context->listen_service_extraseen++;
} else {
if (context->listen_service_extraseen)
context->
listen_service_extraseen--;
break;
}
}
}
}
/* handle session socket closed */
if ((!(pollfd->revents & LWS_POLLIN)) &&
(pollfd->revents & LWS_POLLHUP)) {
lwsl_debug("Session Socket %p (fd=%d) dead\n",
(void *)wsi, pollfd->fd);
goto close_and_handled;
}
/* okay, what we came here to do... */
switch (wsi->mode) {
case LWS_CONNMODE_HTTP_SERVING:
case LWS_CONNMODE_HTTP_SERVING_ACCEPTED:
case LWS_CONNMODE_SERVER_LISTENER:
case LWS_CONNMODE_SSL_ACK_PENDING:
n = lws_server_socket_service(context, wsi, pollfd);
if (n < 0)
goto close_and_handled;
goto handled;
case LWS_CONNMODE_WS_SERVING:
case LWS_CONNMODE_WS_CLIENT:
/* the guy requested a callback when it was OK to write */
if ((pollfd->revents & LWS_POLLOUT) &&
(wsi->state == WSI_STATE_ESTABLISHED ||
wsi->state == WSI_STATE_FLUSHING_STORED_SEND_BEFORE_CLOSE) &&
lws_handle_POLLOUT_event(context, wsi, pollfd)) {
lwsl_info("libwebsocket_service_fd: closing\n");
goto close_and_handled;
}
if (wsi->u.ws.rxflow_buffer &&
(wsi->u.ws.rxflow_change_to & LWS_RXFLOW_ALLOW)) {
lwsl_info("draining rxflow\n");
/* well, drain it */
eff_buf.token = (char *)wsi->u.ws.rxflow_buffer +
wsi->u.ws.rxflow_pos;
eff_buf.token_len = wsi->u.ws.rxflow_len -
wsi->u.ws.rxflow_pos;
draining_flow = 1;
goto drain;
}
/* any incoming data ready? */
if (!(pollfd->revents & LWS_POLLIN))
break;
read_pending:
eff_buf.token_len = lws_ssl_capable_read(wsi,
context->service_buffer,
sizeof(context->service_buffer));
switch (eff_buf.token_len) {
case 0:
lwsl_info("service_fd: closing due to 0 length read\n");
goto close_and_handled;
case LWS_SSL_CAPABLE_ERROR:
n = 0;
goto handled;
case LWS_SSL_CAPABLE_MORE_SERVICE:
goto close_and_handled;
}
/*
* give any active extensions a chance to munge the buffer
* before parse. We pass in a pointer to an lws_tokens struct
* prepared with the default buffer and content length that's in
* there. Rather than rewrite the default buffer, extensions
* that expect to grow the buffer can adapt .token to
* point to their own per-connection buffer in the extension
* user allocation. By default with no extensions or no
* extension callback handling, just the normal input buffer is
* used then so it is efficient.
*/
eff_buf.token = (char *)context->service_buffer;
drain:
do {
more = 0;
m = lws_ext_callback_for_each_active(wsi,
LWS_EXT_CALLBACK_PACKET_RX_PREPARSE, &eff_buf, 0);
if (m < 0)
goto close_and_handled;
if (m)
more = 1;
/* service incoming data */
if (eff_buf.token_len) {
n = libwebsocket_read(context, wsi,
(unsigned char *)eff_buf.token,
eff_buf.token_len);
if (n < 0) {
/* we closed wsi */
n = 0;
goto handled;
}
}
eff_buf.token = NULL;
eff_buf.token_len = 0;
} while (more);
if (draining_flow && wsi->u.ws.rxflow_buffer &&
wsi->u.ws.rxflow_pos == wsi->u.ws.rxflow_len) {
lwsl_info("flow buffer: drained\n");
free(wsi->u.ws.rxflow_buffer);
wsi->u.ws.rxflow_buffer = NULL;
/* having drained the rxflow buffer, can rearm POLLIN */
n = _libwebsocket_rx_flow_control(wsi); /* n ignored, needed for NO_SERVER case */
}
if (lws_ssl_pending(wsi))
goto read_pending;
break;
default:
#ifdef LWS_NO_CLIENT
break;
#else
n = lws_client_socket_service(context, wsi, pollfd);
goto handled;
#endif
}
n = 0;
goto handled;
close_and_handled:
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
n = 1;
handled:
pollfd->revents = 0;
return n;
}
/**
* libwebsocket_service() - Service any pending websocket activity
* @context: Websocket context
* @timeout_ms: Timeout for poll; 0 means return immediately if nothing needed
* service otherwise block and service immediately, returning
* after the timeout if nothing needed service.
*
* This function deals with any pending websocket traffic, for three
* kinds of event. It handles these events on both server and client
* types of connection the same.
*
* 1) Accept new connections to our context's server
*
* 2) Call the receive callback for incoming frame data received by
* server or client connections.
*
* You need to call this service function periodically to all the above
* functions to happen; if your application is single-threaded you can
* just call it in your main event loop.
*
* Alternatively you can fork a new process that asynchronously handles
* calling this service in a loop. In that case you are happy if this
* call blocks your thread until it needs to take care of something and
* would call it with a large nonzero timeout. Your loop then takes no
* CPU while there is nothing happening.
*
* If you are calling it in a single-threaded app, you don't want it to
* wait around blocking other things in your loop from happening, so you
* would call it with a timeout_ms of 0, so it returns immediately if
* nothing is pending, or as soon as it services whatever was pending.
*/
LWS_VISIBLE int
libwebsocket_service(struct libwebsocket_context *context, int timeout_ms)
{
return lws_plat_service(context, timeout_ms);
}
+301
View File
@@ -0,0 +1,301 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
* based on: http://csrc.nist.gov/fips/fip180-1.txt
* implemented by Jun-ichiro itojun Itoh <[email protected]>
*/
#include "private-libwebsockets.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
struct sha1_ctxt {
union {
unsigned char b8[20];
unsigned int b32[5];
} h;
union {
unsigned char b8[8];
u_int64_t b64[1];
} c;
union {
unsigned char b8[64];
unsigned int b32[16];
} m;
unsigned char count;
};
/* sanity check */
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN)
# define unsupported 1
#elif BYTE_ORDER != BIG_ENDIAN
# if BYTE_ORDER != LITTLE_ENDIAN
# define unsupported 1
# endif
#endif
#ifndef unsupported
/* constant table */
static const unsigned int _K[] =
{ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
#define K(t) _K[(t) / 20]
#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
#define F1(b, c, d) (((b) ^ (c)) ^ (d))
#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
#define F3(b, c, d) (((b) ^ (c)) ^ (d))
#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
#define H(n) (ctxt->h.b32[(n)])
#define COUNT (ctxt->count)
#define BCOUNT (ctxt->c.b64[0] / 8)
#define W(n) (ctxt->m.b32[(n)])
#define PUTBYTE(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
ctxt->c.b64[0] += 8; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
#define PUTPAD(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
static void sha1_step __P((struct sha1_ctxt *));
static void
sha1_step(struct sha1_ctxt *ctxt)
{
unsigned int a, b, c, d, e, tmp;
size_t t, s;
#if BYTE_ORDER == LITTLE_ENDIAN
struct sha1_ctxt tctxt;
memcpy(&tctxt.m.b8[0], &ctxt->m.b8[0], 64);
ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
#endif
a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
for (t = 0; t < 20; t++) {
s = t & 0x0f;
if (t >= 16)
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 20; t < 40; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 40; t < 60; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 60; t < 80; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^
W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
H(0) = H(0) + a;
H(1) = H(1) + b;
H(2) = H(2) + c;
H(3) = H(3) + d;
H(4) = H(4) + e;
bzero(&ctxt->m.b8[0], 64);
}
/*------------------------------------------------------------*/
static void
sha1_init(struct sha1_ctxt *ctxt)
{
bzero(ctxt, sizeof(struct sha1_ctxt));
H(0) = 0x67452301;
H(1) = 0xefcdab89;
H(2) = 0x98badcfe;
H(3) = 0x10325476;
H(4) = 0xc3d2e1f0;
}
void
sha1_pad(struct sha1_ctxt *ctxt)
{
size_t padlen; /*pad length in bytes*/
size_t padstart;
PUTPAD(0x80);
padstart = COUNT % 64;
padlen = 64 - padstart;
if (padlen < 8) {
bzero(&ctxt->m.b8[padstart], padlen);
COUNT += padlen;
COUNT %= 64;
sha1_step(ctxt);
padstart = COUNT % 64; /* should be 0 */
padlen = 64 - padstart; /* should be 64 */
}
bzero(&ctxt->m.b8[padstart], padlen - 8);
COUNT += (padlen - 8);
COUNT %= 64;
#if BYTE_ORDER == BIG_ENDIAN
PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
#else
PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
#endif
}
void
sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len)
{
size_t gaplen;
size_t gapstart;
size_t off;
size_t copysiz;
off = 0;
while (off < len) {
gapstart = COUNT % 64;
gaplen = 64 - gapstart;
copysiz = (gaplen < len - off) ? gaplen : len - off;
memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz);
COUNT += copysiz;
COUNT %= 64;
ctxt->c.b64[0] += copysiz * 8;
if (COUNT % 64 == 0)
sha1_step(ctxt);
off += copysiz;
}
}
void
sha1_result(struct sha1_ctxt *ctxt, void *digest0)
{
unsigned char *digest;
digest = (unsigned char *)digest0;
sha1_pad(ctxt);
#if BYTE_ORDER == BIG_ENDIAN
memcpy(digest, &ctxt->h.b8[0], 20);
#else
digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
#endif
}
/*
* This should look and work like the libcrypto implementation
*/
unsigned char *
SHA1(const unsigned char *d, size_t n, unsigned char *md)
{
struct sha1_ctxt ctx;
sha1_init(&ctx);
sha1_loop(&ctx, d, n);
sha1_result(&ctx, (void *)md);
return md;
}
#endif /*unsupported*/
+1 -1
View File
@@ -475,7 +475,7 @@ _zip_d2u_time(int dtime, int ddate)
{
struct tm tm;
memset(&tm, sizeof(tm), 0);
memset(&tm, 0, sizeof(tm));
/* let mktime decide if DST is in effect */
tm.tm_isdst = -1;
+1 -1
View File
@@ -232,7 +232,7 @@ void x86_block::ApplyPatches(u8* base)
x86_block::x86_block()
{
_patches=new vector<code_patch>;
_labels=new vector<code_patch>;
_labels=new vector<x86_Label*>;
opcode_count=0;
}
x86_block::~x86_block()
+1 -1
View File
@@ -5,7 +5,7 @@
ALIGN(4096) dsp_t dsp;
#if HOST_OS==OS_WINDOWS
#if HOST_OS==OS_WINDOWS && !defined(HOST_NO_REC)
#include "emitter/x86_emitter.h"
const bool SUPPORT_NOFL=false;
Regular → Executable
+6 -2
View File
@@ -17,7 +17,6 @@
#endif
//Sound generation, mixin, and channel regs emulation
//x.15
s32 volume_lut[16];
//255 -> mute
@@ -1289,7 +1288,7 @@ void AICA_Sample32()
pl=mixl;
pr=mixr;
WriteSample(mixr,mixl);
if (!settings.aica.NoSound) WriteSample(mixr,mixl);
}
}
@@ -1335,6 +1334,11 @@ void AICA_Sample()
}
}
if (settings.aica.NoSound)
{
return;
}
//Mono !
if (CommonData->Mono)
{
+4 -4
View File
@@ -789,7 +789,7 @@ u32 DYNACALL DoMemOp(u32 addr,u32 data)
{
u32 rv=0;
#if HOST_CPU==CPU_X86
#if HOST_CPU==CPU_X86 && !defined(HOST_NO_REC)
addr=virt_arm_reg(0);
data=virt_arm_reg(1);
#endif
@@ -809,7 +809,7 @@ u32 DYNACALL DoMemOp(u32 addr,u32 data)
arm_WriteMem32(addr,data);
}
#if HOST_CPU==CPU_X86
#if HOST_CPU==CPU_X86 && !defined(HOST_NO_REC)
virt_arm_reg(0)=rv;
#endif
@@ -817,7 +817,7 @@ u32 DYNACALL DoMemOp(u32 addr,u32 data)
}
//findfirstset -- used in LDM/STM handling
#if HOST_CPU==CPU_X86
#if HOST_CPU==CPU_X86 && BUILD_COMPILER != COMPILER_GCC
#include <intrin.h>
u32 findfirstset(u32 v)
@@ -2086,7 +2086,7 @@ void FlushCache()
#if HOST_CPU==CPU_X86
#if HOST_CPU==CPU_X86 && HOST_OS == OS_WINDOWS
#include <Windows.h>
+32 -12
View File
@@ -19,6 +19,11 @@
int gdrom_schid;
//Sense: ASC - ASCQ - Key
signed int sns_asc=0;
signed int sns_ascq=0;
signed int sns_key=0;
enum gd_states
{
//Generic
@@ -447,7 +452,11 @@ void gd_process_ata_cmd()
{
//Any ATA command clears these bits, unless aborted/error :p
Error.ABRT=0;
GDStatus.CHECK=0;
if (sns_key==0x0 || sns_key==0xB)
GDStatus.CHECK=0;
else
GDStatus.CHECK=1;
switch(ata_cmd.command)
{
@@ -464,7 +473,7 @@ void gd_process_ata_cmd()
//the above comment is from a wrong place in the docs ...
Error.ABRT=1;
//Error.Sense=0x00; //fixme ?
Error.Sense=sns_key;
GDStatus.BSY=0;
GDStatus.CHECK=1;
@@ -519,12 +528,18 @@ void gd_process_ata_cmd()
void gd_process_spi_cmd()
{
printf_spi("Sense: %02x %02x %02x \n", sns_asc, sns_ascq, sns_key);
printf_spi("SPI command %02x;",packet_cmd.data_8[0]);
printf_spi("Params: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \n",
packet_cmd.data_8[0], packet_cmd.data_8[1], packet_cmd.data_8[2], packet_cmd.data_8[3], packet_cmd.data_8[4], packet_cmd.data_8[5],
packet_cmd.data_8[6], packet_cmd.data_8[7], packet_cmd.data_8[8], packet_cmd.data_8[9], packet_cmd.data_8[10], packet_cmd.data_8[11] );
GDStatus.CHECK=0;
if (sns_key==0x0 || sns_key==0xB)
GDStatus.CHECK=0;
else
GDStatus.CHECK=1;
switch(packet_cmd.data_8[0])
{
@@ -672,18 +687,22 @@ void gd_process_spi_cmd()
case SPI_REQ_ERROR:
printf_spicmd("SPI_REQ_ERROR\n");
printf("GDROM: Unhandled Sega SPI frame: SPI_REQ_ERROR\n");
//printf("GDROM: Unhandled Sega SPI frame: SPI_REQ_ERROR\n");
u8 resp[10];
resp[0]=0xF0;
resp[1]=0;
resp[2]= SecNumber.Status==GD_BUSY ? 2:0;//sense
resp[2]=sns_key;//sense
resp[3]=0;
resp[4]=resp[5]=resp[6]=resp[7]=0; //Command Specific Information
resp[8]=0;//Additional Sense Code
resp[9]=0;//Additional Sense Code Qualifier
resp[8]=sns_asc;//Additional Sense Code
resp[9]=sns_ascq;//Additional Sense Code Qualifier
gd_spi_pio_end(resp,packet_cmd.data_8[4]);
sns_key=0;
sns_asc=0;
sns_ascq=0;
//GDStatus.CHECK=0;
break;
case SPI_REQ_SES:
@@ -915,8 +934,8 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
if(2!=sz)
printf("GDROM: Bad size on DATA REG Read\n");
if (gd_state == gds_pio_send_data)
{
//if (gd_state == gds_pio_send_data)
//{
if (pio_buff.index == pio_buff.size)
{
printf("GDROM: Illegal Read From DATA (underflow)\n");
@@ -935,9 +954,9 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
return rv;
}
}
else
printf("GDROM: Illegal Read From DATA (wrong mode)\n");
//}
//else
// printf("GDROM: Illegal Read From DATA (wrong mode)\n");
return 0;
@@ -947,6 +966,7 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
case GD_ERROR_Read:
printf_rm("GDROM: Read from ERROR Register\n");
Error.Sense=sns_key;
return Error.full;
case GD_IREASON_Read:
+197 -3
View File
@@ -5,6 +5,14 @@
#include "maple_cfg.h"
#include <time.h>
#if _ANDROID
#include <android/log.h>
#include <jni.h>
#else
#define LOGW printf
#define LOGI printf
#endif
#include "deps/zlib/zlib.h"
const char* maple_sega_controller_name = "Dreamcast Controller";
@@ -225,7 +233,7 @@ struct maple_sega_controller: maple_base
return MDRS_DataTransfer;
default:
printf("UNKOWN MAPLE COMMAND %d\n",cmd);
//printf("UNKOWN MAPLE COMMAND %d\n",cmd);
return MDRE_UnknownFunction;
}
}
@@ -539,6 +547,9 @@ struct maple_sega_vmu: maple_base
}
}
config->SetImage(lcd_data_decoded);
#ifndef TARGET_PANDORA
push_vmu_screen(lcd_data_decoded);
#endif
#if 0
// Update LCD window
if (!dev->lcd.visible)
@@ -644,13 +655,193 @@ struct maple_sega_vmu: maple_base
default:
printf("Unknown MAPLE COMMAND %d\n",cmd);
//printf("Unknown MAPLE COMMAND %d\n",cmd);
return MDRE_UnknownCmd;
}
}
};
#endif
struct maple_microphone: maple_base
{
u8 micdata[SIZE_OF_MIC_DATA];
virtual void OnSetup()
{
memset(micdata,0,sizeof(micdata));
}
virtual u32 dma(u32 cmd)
{
//printf("maple_microphone::dma Called 0x%X;Command %d\n",this->maple_port,cmd);
//LOGD("maple_microphone::dma Called 0x%X;Command %d\n",this->maple_port,cmd);
switch (cmd)
{
case MDC_DeviceRequest:
LOGI("maple_microphone::dma MDC_DeviceRequest");
//this was copied from the controller case with just the id and name replaced!
//caps
//4
w32(MFID_4_Mic);
//struct data
//3*4
w32( 0xfe060f00);
w32( 0);
w32( 0);
//1 area code
w8(0xFF);
//1 direction
w8(0);
//30
wstr(maple_sega_mic_name,30);
//60
wstr(maple_sega_brand,60);
//2
w16(0x01AE);
//2
w16(0x01F4);
return MDRS_DeviceStatus;
case MDCF_GetCondition:
{
LOGI("maple_microphone::dma MDCF_GetCondition");
//this was copied from the controller case with just the id replaced!
//PlainJoystickState pjs;
//config->GetInput(&pjs);
//caps
//4
w32(MFID_4_Mic);
//state data
//2 key code
//w16(pjs.kcode);
//triggers
//1 R
//w8(pjs.trigger[PJTI_R]);
//1 L
//w8(pjs.trigger[PJTI_L]);
//joyx
//1
//w8(pjs.joy[PJAI_X1]);
//joyy
//1
//w8(pjs.joy[PJAI_Y1]);
//not used
//1
w8(0x80);
//1
w8(0x80);
}
return MDRS_DataTransfer;
case MDC_DeviceReset:
//uhhh do nothing?
LOGI("maple_microphone::dma MDC_DeviceReset");
return MDRS_DeviceReply;
case MDCF_MICControl:
{
//LOGD("maple_microphone::dma handling MDCF_MICControl %d\n",cmd);
//MONEY
u32 function=r32();
//LOGD("maple_microphone::dma MDCF_MICControl function (1st word) %#010x\n", function);
//LOGD("maple_microphone::dma MDCF_MICControl words: %d\n", dma_count_in);
switch(function)
{
case MFID_4_Mic:
{
//MAGIC HERE
//http://dcemulation.org/phpBB/viewtopic.php?f=34&t=69600
// <3 <3 BlueCrab <3 <3
/*
2nd word What it does:
0x0000??03 Sets the amplifier gain, ?? can be from 00 to 1F
0x0f = default
0x00008002 Enables recording
0x00000001 Returns sampled data while recording is enabled
While not enabled, returns status of the mic.
0x00000002 Disables recording
*
*/
u32 secondword=r32();
//LOGD("maple_microphone::dma MDCF_MICControl subcommand (2nd word) %#010x\n", subcommand);
u32 subcommand = secondword & 0xFF; //just get last byte for now, deal with params later
//LOGD("maple_microphone::dma MDCF_MICControl (3rd word) %#010x\n", r32());
//LOGD("maple_microphone::dma MDCF_MICControl (4th word) %#010x\n", r32());
switch(subcommand)
{
case 0x01:
{
//LOGI("maple_microphone::dma MDCF_MICControl someone wants some data! (2nd word) %#010x\n", secondword);
w32(MFID_4_Mic);
//from what i can tell this is up to spec but results in transmit again
//w32(secondword);
//32 bit header
w8(0x04);//status (just the bit for recording)
w8(0x0f);//gain (default)
w8(0);//exp ?
#ifndef TARGET_PANDORA
if(get_mic_data(micdata)){
w8(240);//ct (240 samples)
wptr(micdata, SIZE_OF_MIC_DATA);
}else
#endif
{
w8(0);
}
return MDRS_DataTransfer;
}
case 0x02:
LOGI("maple_microphone::dma MDCF_MICControl toggle recording %#010x\n",secondword);
return MDRS_DeviceReply;
case 0x03:
LOGI("maple_microphone::dma MDCF_MICControl set gain %#010x\n",secondword);
return MDRS_DeviceReply;
case MDRE_TransminAgain:
LOGW("maple_microphone::dma MDCF_MICControl MDRE_TransminAgain");
//apparently this doesnt matter
//wptr(micdata, SIZE_OF_MIC_DATA);
return MDRS_DeviceReply;//MDRS_DataTransfer;
default:
LOGW("maple_microphone::dma UNHANDLED secondword %#010x\n",secondword);
break;
}
}
default:
LOGW("maple_microphone::dma UNHANDLED function %#010x\n",function);
break;
}
}
default:
LOGW("maple_microphone::dma UNHANDLED MAPLE COMMAND %d\n",cmd);
return MDRE_UnknownFunction;
}
}
};
maple_device* maple_Create(MapleDeviceType type)
{
maple_device* rv=0;
@@ -659,6 +850,9 @@ maple_device* maple_Create(MapleDeviceType type)
case MDT_SegaController:
rv=new maple_sega_controller();
break;
case MDT_Microphone:
rv=new maple_microphone();
break;
#ifdef HAS_VMU
case MDT_SegaVMU:
rv = new maple_sega_vmu();
@@ -670,4 +864,4 @@ maple_device* maple_Create(MapleDeviceType type)
}
return rv;
}
}
Regular → Executable
+7 -1
View File
@@ -5,6 +5,7 @@ enum MapleDeviceType
{
MDT_SegaController,
MDT_SegaVMU,
MDT_Microphone,
MDT_Count
};
@@ -27,4 +28,9 @@ struct maple_device
virtual u32 Dma(u32 Command,u32* buffer_in,u32 buffer_in_len,u32* buffer_out,u32& buffer_out_len)=0;
};
maple_device* maple_Create(MapleDeviceType type);
maple_device* maple_Create(MapleDeviceType type);
#define SIZE_OF_MIC_DATA 480 //ALSO DEFINED IN SipEmulator.java
#ifndef TARGET_PANDORA
int get_mic_data(u8* buffer); //implemented in Android.cpp
int push_vmu_screen(u8* buffer); //implemented in Android.cpp
#endif
+3 -3
View File
@@ -561,8 +561,8 @@ error:
fd = ashmem_create_region(0,RAM_SIZE + VRAM_SIZE +ARAM_SIZE);
if (false)//this causes writebacks to flash -> slow and stuttery
{
fd = open("/data/data/com.example.droidcast/dcnzorz_mem",O_CREAT|O_RDWR|O_TRUNC,S_IRWXU|S_IRWXG|S_IRWXO);
unlink("/data/data/com.example.droidcast/dcnzorz_mem");
fd = open("/data/data/com.reicast.emulator/files/dcnzorz_mem",O_CREAT|O_RDWR|O_TRUNC,S_IRWXU|S_IRWXG|S_IRWXO);
unlink("/data/data/com.reicast.emulator/files/dcnzorz_mem");
}
#endif
@@ -571,7 +571,7 @@ error:
u32 sz= 512*1024*1024 + sizeof(Sh4RCB) + ARAM_SIZE + 0x10000;
void* rv=mmap(0, sz, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
munmap(rv,sz);
return (u8*)rv + 0x10000 - u32(rv)%0x10000;//align to 64 KB (Needed for linaro mmap not to extend to next region)
return (u8*)rv + 0x10000 - unat(rv)%0x10000;//align to 64 KB (Needed for linaro mmap not to extend to next region)
}
#endif
+77 -17
View File
@@ -2,12 +2,69 @@
#include "ta.h"
#include "hw/pvr/pvr_mem.h"
/*
rendv3 ideas
- multiple backends
- ESish
- OpenGL ES2.0
- OpenGL ES3.0
- OpenGL 3.1
- OpenGL 4.x
- Direct3D 10+ ?
- correct memory ordering model
- resource pools
- threaded ta
- threaded rendering
- rtts
- framebuffers
- overlays
PHASES
- TA submition (memops, dma)
- TA parsing (defered, rend thread)
- CORE render (in-order, defered, rend thread)
submition is done in-order
- Partial handling of TA values
- Gotchas with TA contexts
parsing is done on demand and out-of-order, and might be skipped
- output is only consumed by renderer
render is queued on RENDER_START, and won't stall the emulation or might be skipped
- VRAM integrity is an issue with out-of-order or delayed rendering.
- selective vram snapshots require ta parsing to complete in order with REND_START / REND_END
Complications
- For some apis (gles2, maybe gl31) texture allocation needs to happen on the gpu thread
- multiple versions of different time snapshots of the same texture are required
- ta parsing vs frameskip logic
Texture versioning and staging
A memory copy of the texture can be used to temporary store the texture before upload to vram
This can be moved to another thread
If the api supports async resource creation, we don't need the extra copy
Texcache lookups need to be versioned
rendv2x hacks
- Only a single pending render. Any renders while still pending are dropped (before parsing)
- wait and block for parse/texcache. Render is async
*/
u32 VertexCount=0;
u32 FrameCount=0;
u32 FrameCount=1;
Renderer* rend;
cResetEvent rs(false,true);
cResetEvent re(false,true);
int max_idx,max_mvo,max_op,max_pt,max_tr,max_vtx,max_modt, ovrn;
@@ -19,26 +76,23 @@ void SetREP(TA_context* cntx);
bool rend_single_frame()
{
//wait render start only if no frame pending
_pvrrc = DequeueRender();
while (!_pvrrc)
do
{
rs.Wait();
_pvrrc = DequeueRender();
}
while (!_pvrrc);
bool do_swp=false;
bool proc = rend->Process(_pvrrc);
re.Set();
do_swp=rend->Render();
bool do_swp = proc && rend->Render();
if (do_swp)
{
//OSD_DRAW();
}
rend->DrawOSD();
//clear up & free data ..
tactx_Recycle(_pvrrc);
FinishRender(_pvrrc);
_pvrrc=0;
return do_swp;
@@ -89,9 +143,11 @@ void* rend_thread(void* p)
cThread rthd(rend_thread,0);
bool pend_rend = false;
void rend_start_render()
{
pend_rend = false;
bool is_rtt=(FB_W_SOF1& 0x1000000)!=0;
TA_context* ctx = tactx_Pop(CORE_CURRENT_CTX);
@@ -122,8 +178,10 @@ void rend_start_render()
#if HOST_OS==OS_WINDOWS && 0
printf("max: idx: %d, vtx: %d, op: %d, pt: %d, tr: %d, mvo: %d, modt: %d, ov: %d\n", max_idx, max_vtx, max_op, max_pt, max_tr, max_mvo, max_modt, ovrn);
#endif
QueueRender(ctx);
rs.Set();
if (QueueRender(ctx)) {
rs.Set();
pend_rend = true;
}
}
else
{
@@ -137,12 +195,14 @@ void rend_start_render()
void rend_end_render()
{
#if 0 //also disabled the printf, it takes quite some time ...
#if HOST_OS!=OS_WINDOWS && !defined(_ANDROID)
#if 1 //also disabled the printf, it takes quite some time ...
#if HOST_OS!=OS_WINDOWS && !(defined(_ANDROID) || defined(TARGET_PANDORA))
if (!re.state) printf("Render > Extended time slice ...\n");
#endif
rend_end_wait();
#endif
if (pend_rend)
re.Wait();
}
/*
+3
View File
@@ -32,9 +32,12 @@ struct Renderer
virtual void Term()=0;
virtual bool Process(TA_context* ctx)=0;
virtual bool Render()=0;
virtual void Present()=0;
virtual void DrawOSD() { }
};
Regular → Executable
+8 -1
View File
@@ -179,12 +179,19 @@ int spg_line_sched(int tag, int cycl, int jit)
full_rps=(spd_fps+fskip/ts);
#ifdef TARGET_PANDORA
sprintf(fpsStr,"CPU: %4.2f V: %4.2f (%s%s%4.2f) R: %4.2f+%4.2f",
spd_cpu*100/200,spd_vbs,
mode,res,fullvbs,
spd_fps,fskip/ts);
#else
sprintf(fpsStr,"%s/%c - %4.2f (%4.2f) - %4.2f - V: %4.2f (%.2f, %s%s%4.2f) R: %4.2f+%4.2f VTX: %4.2f%c",
VER_SHORTNAME,'n',mspdf,speed_load_mspdf,spd_cpu*100/200,spd_vbs,
spd_vbs/full_rps,mode,res,fullvbs,
spd_fps,fskip/ts
,mv,mv_c);
#endif
fskip=0;
os_SetWindowText(fpsStr);
+1 -1
View File
@@ -264,7 +264,7 @@ void ta_vtx_ListCont()
void ta_vtx_ListInit()
{
SetCurrentTARC(TA_ISP_BASE);
ta_tad.Clear();
ta_tad.ClearPartial();
ta_cur_state=TAS_NS;
}
+34 -12
View File
@@ -4,6 +4,9 @@
extern u32 fskip;
extern u32 FrameCount;
int frameskip=0;
bool FrameSkipping=false; // global switch to enable/disable frameskip
TA_context* ta_ctx;
tad_context ta_tad;
@@ -32,14 +35,13 @@ void SetCurrentTARC(u32 addr)
//clear context
ta_ctx=0;
ta_tad.thd_data=0;
ta_tad.thd_root=0;
ta_tad.Reset(0);
}
}
bool TryDecodeTARC()
{
verify(ta_ctx);
verify((int)ta_ctx);
if (vd_ctx == 0)
{
@@ -47,7 +49,7 @@ bool TryDecodeTARC()
vd_ctx->rend.proc_start = vd_ctx->rend.proc_end + 32;
vd_ctx->rend.proc_end = vd_ctx->tad.thd_data;
vd_ctx->rend_inuse.Lock();
vd_rc = vd_ctx->rend;
@@ -60,7 +62,7 @@ bool TryDecodeTARC()
void VDecEnd()
{
verify(vd_ctx);
verify((int)vd_ctx);
vd_ctx->rend = vd_rc;
@@ -72,27 +74,37 @@ void VDecEnd()
cMutex mtx_rqueue;
TA_context* rqueue;
void QueueRender(TA_context* ctx)
bool QueueRender(TA_context* ctx)
{
verify(ctx != 0);
if (FrameSkipping && frameskip) {
frameskip=1-frameskip;
tactx_Recycle(ctx);
fskip++;
return false;
}
if (rqueue) {
tactx_Recycle(ctx);
fskip++;
return false;
}
mtx_rqueue.Lock();
TA_context* old = rqueue;
rqueue=ctx;
mtx_rqueue.Unlock();
if (old)
{
tactx_Recycle(old);
fskip++;
}
verify(!old);
return true;
}
TA_context* DequeueRender()
{
mtx_rqueue.Lock();
TA_context* rv = rqueue;
rqueue = 0;
mtx_rqueue.Unlock();
if (rv)
@@ -101,6 +113,16 @@ TA_context* DequeueRender()
return rv;
}
void FinishRender(TA_context* ctx)
{
verify(rqueue == ctx);
mtx_rqueue.Lock();
rqueue = 0;
mtx_rqueue.Unlock();
tactx_Recycle(ctx);
}
cMutex mtx_pool;
vector<TA_context*> ctx_pool;
+27 -6
View File
@@ -20,6 +20,8 @@ struct PolyParam
//lets see what more :)
u32 texid;
TSP tsp;
TCW tcw;
PCW pcw;
@@ -46,11 +48,29 @@ struct tad_context
{
u8* thd_data;
u8* thd_root;
u8* thd_old_data;
void Clear()
{
thd_data=thd_root;
thd_old_data = thd_data = thd_root;
}
void ClearPartial()
{
thd_old_data = thd_data;
thd_data = thd_root;
}
u8* End()
{
return thd_data == thd_root ? thd_old_data : thd_data;
}
void Reset(u8* ptr)
{
thd_data = thd_root = thd_old_data = ptr;
}
};
struct rend_context
@@ -126,12 +146,12 @@ struct TA_context
void MarkRend()
{
rend.proc_start = rend.proc_end;
rend.proc_end = tad.thd_data;
rend.proc_start = tad.thd_root;
rend.proc_end = tad.End();
}
void Alloc()
{
tad.thd_root=tad.thd_data=(u8*)malloc(2*1024*1024);
tad.Reset((u8*)malloc(2*1024*1024));
rend.verts.InitBytes(1024*1024,&rend.Overrun); //up to 1 mb of vtx data/frame = ~ 38k vtx/frame
rend.idx.Init(60*1024,&rend.Overrun); //up to 60K indexes ( idx have stripification overhead )
@@ -150,7 +170,7 @@ struct TA_context
tad.Clear();
rend_inuse.Lock();
rend.Clear();
rend.proc_end = rend.proc_start = tad.thd_data;
rend.proc_end = rend.proc_start = tad.thd_root;
rend_inuse.Unlock();
}
@@ -188,8 +208,9 @@ void tactx_Recycle(TA_context* poped_ctx);
#define TACTX_NONE (0xFFFFFFFF)
void SetCurrentTARC(u32 addr);
void QueueRender(TA_context* ctx);
bool QueueRender(TA_context* ctx);
TA_context* DequeueRender();
void FinishRender(TA_context* ctx);
bool TryDecodeTARC();
void VDecEnd();
+29 -8
View File
@@ -8,6 +8,7 @@
#include "ta.h"
#include "ta_ctx.h"
#include "pvr_mem.h"
#include "rend/gles/gles.h"
#include "Renderer_if.h"
u32 ta_type_lut[256];
@@ -376,7 +377,9 @@ strip_end:
}
public:
#define group_EN() if (data->pcw.Group_En){ TileClipMode(data->pcw.User_Clip);}
//Group_En bit seems ignored, thanks p1pkin
#define group_EN() /*if (data->pcw.Group_En) */{ TileClipMode(data->pcw.User_Clip);}
static Ta_Dma* TACALL ta_main(Ta_Dma* data,Ta_Dma* data_end)
{
do
@@ -786,11 +789,18 @@ public:
}
d_pp->first=vdrc.idx.used();
d_pp->count=0;
d_pp->isp=pp->isp;
d_pp->tsp=pp->tsp;
d_pp->tcw=pp->tcw;
d_pp->pcw=pp->pcw;
d_pp->tileclip=tileclip_val;
d_pp->texid = -1;
if (d_pp->pcw.Texture) {
d_pp->texid = GetTexture(d_pp->tsp,d_pp->tcw);
}
}
}
@@ -1181,6 +1191,12 @@ public:
d_pp->pcw=spr->pcw;
d_pp->tileclip=tileclip_val;
d_pp->texid = -1;
if (d_pp->pcw.Texture) {
d_pp->texid = GetTexture(d_pp->tsp,d_pp->tcw);
}
SFaceBaseColor=spr->BaseCol;
SFaceOffsColor=spr->OffsCol;
}
@@ -1392,6 +1408,9 @@ FifoSplitter<0> TAFifo0;
int ta_parse_cnt = 0;
/*
Also: gotta stage textures here
*/
bool ta_parse_vdrc(TA_context* ctx)
{
bool rv=false;
@@ -1539,6 +1558,8 @@ void FillBGP(TA_context* ctx)
u32 vertex_ptr=strip_vert_num*strip_vs+strip_base +3*4;
//now , all the info is ready :p
bgpp->texid = -1;
bgpp->isp.full=vri(strip_base);
bgpp->tsp.full=vri(strip_base+4);
bgpp->tcw.full=vri(strip_base+8);
@@ -1564,21 +1585,21 @@ void FillBGP(TA_context* ctx)
float ZV=0;
cv[0].x=0;
cv[0].y=0;
cv[0].x=-2000;
cv[0].y=-2000;
cv[0].z=ISP_BACKGND_D.f;
cv[1].x=640*scale_x;
cv[1].x=640*scale_x + 2000;
cv[1].y=0;
cv[1].z=ISP_BACKGND_D.f;
cv[2].x=0;
cv[2].y=480;
cv[2].x=-2000;
cv[2].y=480+2000;
cv[2].z=ISP_BACKGND_D.f;
cv[3]=cv[2];
cv[3].x=640*scale_x;
cv[3].y=480;
cv[3].x=640*scale_x+2000;
cv[3].y=480+2000;
cv[3].z=ISP_BACKGND_D.f;
}
+1 -1
View File
@@ -1169,7 +1169,7 @@ _end:
//Small-n-simple idle loop detector :p
if (state.info.has_readm && !state.info.has_writem && !state.info.has_fpu && blk->guest_opcodes<6)
{
if ((blk->BlockType==BET_Cond_0 || blk->BlockType==BET_Cond_1) && blk->BranchBlock<=blk->addr)
if (blk->BlockType==BET_Cond_0 || blk->BlockType==BET_Cond_1 && blk->BranchBlock<=blk->addr)
{
blk->guest_cycles*=3;
}
+1 -1
View File
@@ -304,7 +304,7 @@ void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc)
rbi=bm_GetStaleBlock(code);
}
verify(rbi);
verify((int)rbi);
u32 bcls=BET_GET_CLS(rbi->BlockType);
+2 -2
View File
@@ -68,7 +68,7 @@ struct RegAlloc
nreg=(nreg_t)-1;
nregf=(nregf_t)-1;
RegAccess ra={pos,mode};
RegAccess ra={static_cast<u32>(pos),mode};
accesses.push_back(ra);
}
@@ -87,7 +87,7 @@ struct RegAlloc
end=pos;
if (mode&AM_WRITE)
writeback=true;
RegAccess ra={pos,mode};
RegAccess ra={static_cast<u32>(pos),mode};
accesses.push_back(ra);
}
+9 -5
View File
@@ -75,17 +75,21 @@ void SetFloatStatusReg()
//TODO: Implement this (needed for SOTB)
#if HOST_CPU==CPU_X86 && HOST_OS==OS_WINDOWS
#if HOST_CPU==CPU_X86
if (fpscr.RM==1) //if round to 0 , set the flag
temp|=(3<<13);
if (fpscr.DN) //denormals are considered 0
temp|=(1<<15);
_asm
{
ldmxcsr temp; //load the float status :)
}
#if BUILD_COMPILER == COMPILER_VC
_asm
{
ldmxcsr temp; //load the float status :)
}
#else
asm("ldmxcsr %0" : : "m"(temp));
#endif
#elif HOST_CPU==CPU_ARM
static const unsigned int x = 0x04086060;
unsigned int y = 0x02000000;
-1
View File
@@ -1,4 +1,3 @@
#pragma once
#include "types.h"
#include "sh4_rom.h"
+1 -1
View File
@@ -6,7 +6,7 @@
#include "deps/chdpsr/cdipsr.h"
Disc* cdi_parse(wchar* file)
Disc* cdi_parse(const wchar* file)
{
FILE* fsource=fopen(file,"rb");
+5 -3
View File
@@ -17,7 +17,7 @@ struct CHDDisc : Disc
hunk_mem=0;
}
bool TryOpen(wchar* file);
bool TryOpen(const wchar* file);
~CHDDisc()
{
@@ -64,7 +64,7 @@ struct CHDTrack : TrackFile
}
};
bool CHDDisc::TryOpen(wchar* file)
bool CHDDisc::TryOpen(const wchar* file)
{
chd_error err=chd_open(file,CHD_OPEN_READ,0,&chd);
@@ -141,7 +141,9 @@ bool CHDDisc::TryOpen(wchar* file)
if (total_frames!=549300 || tracks.size()<3)
{
printf("WARNING: chd: Total frames is wrong: %d frames in %d tracks\n",total_frames,tracks.size());
#ifndef NOT_REICAST
msgboxf("This is an improper dump!",MBX_ICONEXCLAMATION);
#endif
return false;
}
@@ -151,7 +153,7 @@ bool CHDDisc::TryOpen(wchar* file)
}
Disc* chd_parse(wchar* file)
Disc* chd_parse(const wchar* file)
{
CHDDisc* rv = new CHDDisc();
+96 -7
View File
@@ -1,17 +1,16 @@
#include "common.h"
Disc* chd_parse(wchar* file);
Disc* gdi_parse(wchar* file);
Disc* cdi_parse(wchar* file);
Disc* chd_parse(const wchar* file);
Disc* gdi_parse(const wchar* file);
Disc* cdi_parse(const wchar* file);
#if HOST_OS==OS_WINDOWS
Disc* ioctl_parse(wchar* file);
Disc* ioctl_parse(const wchar* file);
#endif
u32 NullDriveDiscType;
Disc* disc;
Disc*(*drivers[])(wchar* path)=
Disc*(*drivers[])(const wchar* path)=
{
chd_parse,
gdi_parse,
@@ -26,8 +25,12 @@ u8 q_subchannel[96];
void PatchRegion_0(u8* sector,int size)
{
#ifndef NOT_REICAST
if (settings.imgread.PatchRegion==0)
return;
#else
return;
#endif
u8* usersect=sector;
@@ -42,8 +45,12 @@ void PatchRegion_0(u8* sector,int size)
}
void PatchRegion_6(u8* sector,int size)
{
#ifndef NOT_REICAST
if (settings.imgread.PatchRegion==0)
return;
#else
return;
#endif
u8* usersect=sector;
@@ -122,18 +129,29 @@ bool ConvertSector(u8* in_buff , u8* out_buff , int from , int to,int sector)
return true;
}
Disc* OpenDisc(const wchar* fn)
{
Disc* rv;
for (int i=0;drivers[i] && !(rv=drivers[i](fn));i++) ;
return rv;
}
bool InitDrive_(wchar* fn)
{
TermDrive();
//try all drivers
for (int i=0;drivers[i] && !(disc=drivers[i](fn));i++) ;
disc = OpenDisc(fn);
if (disc!=0)
{
printf("gdrom: Opened image \"%s\"\n",fn);
NullDriveDiscType=Busy;
#ifndef NOT_REICAST
libCore_gdrom_disc_change();
#endif
// Sleep(400); //busy for a bit // what, really ?
return true;
}
@@ -145,6 +163,7 @@ bool InitDrive_(wchar* fn)
return false;
}
#ifndef NOT_REICAST
bool InitDrive(u32 fileflags)
{
if (settings.imgread.LoadDefaultImage)
@@ -169,6 +188,10 @@ bool InitDrive(u32 fileflags)
if (gfrv == 0)
{
NullDriveDiscType=NoDisk;
gd_setdisc();
sns_asc=0x29;
sns_ascq=0x00;
sns_key=0x6;
return true;
}
else if (gfrv == -1)
@@ -182,6 +205,11 @@ bool InitDrive(u32 fileflags)
if (!InitDrive_(fn))
{
//msgboxf("Selected image failed to load",MBX_ICONERROR);
NullDriveDiscType=NoDisk;
gd_setdisc();
sns_asc=0x29;
sns_ascq=0x00;
sns_key=0x6;
return true;
}
else
@@ -190,6 +218,67 @@ bool InitDrive(u32 fileflags)
}
}
bool DiscSwap(u32 fileflags)
{
if (settings.imgread.LoadDefaultImage)
{
printf("Loading default image \"%s\"\n",settings.imgread.DefaultImage);
if (!InitDrive_(settings.imgread.DefaultImage))
{
msgboxf("Default image \"%s\" failed to load",MBX_ICONERROR);
return false;
}
else
return true;
}
wchar fn[512];
strcpy(fn,settings.imgread.LastImage);
#ifdef BUILD_DREAMCAST
int gfrv=GetFile(fn,0,fileflags);
#else
int gfrv=0;
#endif
if (gfrv == 0)
{
NullDriveDiscType=Open;
gd_setdisc();
sns_asc=0x28;
sns_ascq=0x00;
sns_key=0x6;
return true;
}
else if (gfrv == -1)
{
sns_asc=0x28;
sns_ascq=0x00;
sns_key=0x6;
return false;
}
strcpy(settings.imgread.LastImage,fn);
SaveSettings();
if (!InitDrive_(fn))
{
//msgboxf("Selected image failed to load",MBX_ICONERROR);
NullDriveDiscType=Open;
gd_setdisc();
sns_asc=0x28;
sns_ascq=0x00;
sns_key=0x6;
return true;
}
else
{
sns_asc=0x28;
sns_ascq=0x00;
sns_key=0x6;
return true;
}
}
#endif
void TermDrive()
{
if (disc!=0)
+11 -2
View File
@@ -82,6 +82,11 @@ bool ConvertSector(u8* in_buff , u8* out_buff , int from , int to,int sector);
bool InitDrive(u32 fileflags=0);
void TermDrive();
bool DiscSwap(u32 fileflags=0);
extern signed int sns_asc;
extern signed int sns_ascq;
extern signed int sns_key;
void PatchRegion_0(u8* sector,int size);
void PatchRegion_6(u8* sector,int size);
@@ -235,7 +240,7 @@ struct Disc
{
u32 fmt=tracks[i].CTRL==4?2048:2352;
char fsto[1024];
sprintf(fsto,"%s%s%d.img",path.c_str(),"track",i);
sprintf(fsto,"%s%s%d.img",path.c_str(),".track",i);
FILE* fo=fopen(fsto,"wb");
@@ -252,6 +257,8 @@ struct Disc
extern Disc* disc;
Disc* OpenDisc(const wchar* fn);
struct RawTrackFile : TrackFile
{
FILE* file;
@@ -292,4 +299,6 @@ struct RawTrackFile : TrackFile
}
};
DiscType GuessDiscType(bool m1, bool m2, bool da);
DiscType GuessDiscType(bool m1, bool m2, bool da);
extern void gd_setdisc();
+2 -2
View File
@@ -1,7 +1,7 @@
#include "common.h"
#include <ctype.h>
Disc* load_gdi(char* file)
Disc* load_gdi(const char* file)
{
u32 iso_tc;
Disc* disc = new Disc();
@@ -75,7 +75,7 @@ Disc* load_gdi(char* file)
}
Disc* gdi_parse(char* file)
Disc* gdi_parse(const char* file)
{
size_t len=strlen(file);
if (len>4)
+1 -1
View File
@@ -363,7 +363,7 @@ void PhysicalTrack::Read(u32 FAD,u8* dst,SectorFormat* sector_type,u8* subcode,S
}
Disc* ioctl_parse(wchar* file)
Disc* ioctl_parse(const wchar* file)
{
if (strlen(file)==3 && GetDriveType(file)==DRIVE_CDROM)
+329
View File
@@ -0,0 +1,329 @@
/* -*- mode: c; tab-width: 8; -*- */
/* vi: set sw=4 ts=8: */
/* Reference version of egl.h for EGL 1.4.
* $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
*/
/*
** Copyright (c) 2007-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
#ifndef __egl_h_
#define __egl_h_
/* All platform-dependent types and macro boilerplate (such as EGLAPI
* and EGLAPIENTRY) should go in eglplatform.h.
*/
#include <APPLE/eglplatform.h>
#ifdef __cplusplus
extern "C" {
#endif
/* EGL Types */
/* EGLint is defined in eglplatform.h */
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void *EGLConfig;
typedef void *EGLContext;
typedef void *EGLDisplay;
typedef void *EGLSurface;
typedef void *EGLClientBuffer;
/* EGL Versioning */
#define EGL_VERSION_1_0 1
#define EGL_VERSION_1_1 1
#define EGL_VERSION_1_2 1
#define EGL_VERSION_1_3 1
#define EGL_VERSION_1_4 1
/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
* enums are assigned unique values starting at 0x3000.
*/
/* EGL aliases */
#define EGL_FALSE 0
#define EGL_TRUE 1
/* Out-of-band handle values */
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
#define EGL_NO_CONTEXT ((EGLContext)0)
#define EGL_NO_DISPLAY ((EGLDisplay)0)
#define EGL_NO_SURFACE ((EGLSurface)0)
/* Out-of-band attribute value */
#define EGL_DONT_CARE ((EGLint)-1)
/* Errors / GetError return values */
#define EGL_SUCCESS 0x3000
#define EGL_NOT_INITIALIZED 0x3001
#define EGL_BAD_ACCESS 0x3002
#define EGL_BAD_ALLOC 0x3003
#define EGL_BAD_ATTRIBUTE 0x3004
#define EGL_BAD_CONFIG 0x3005
#define EGL_BAD_CONTEXT 0x3006
#define EGL_BAD_CURRENT_SURFACE 0x3007
#define EGL_BAD_DISPLAY 0x3008
#define EGL_BAD_MATCH 0x3009
#define EGL_BAD_NATIVE_PIXMAP 0x300A
#define EGL_BAD_NATIVE_WINDOW 0x300B
#define EGL_BAD_PARAMETER 0x300C
#define EGL_BAD_SURFACE 0x300D
#define EGL_CONTEXT_LOST 0x300E /* EGL 1.1 - IMG_power_management */
/* Reserved 0x300F-0x301F for additional errors */
/* Config attributes */
#define EGL_BUFFER_SIZE 0x3020
#define EGL_ALPHA_SIZE 0x3021
#define EGL_BLUE_SIZE 0x3022
#define EGL_GREEN_SIZE 0x3023
#define EGL_RED_SIZE 0x3024
#define EGL_DEPTH_SIZE 0x3025
#define EGL_STENCIL_SIZE 0x3026
#define EGL_CONFIG_CAVEAT 0x3027
#define EGL_CONFIG_ID 0x3028
#define EGL_LEVEL 0x3029
#define EGL_MAX_PBUFFER_HEIGHT 0x302A
#define EGL_MAX_PBUFFER_PIXELS 0x302B
#define EGL_MAX_PBUFFER_WIDTH 0x302C
#define EGL_NATIVE_RENDERABLE 0x302D
#define EGL_NATIVE_VISUAL_ID 0x302E
#define EGL_NATIVE_VISUAL_TYPE 0x302F
#define EGL_SAMPLES 0x3031
#define EGL_SAMPLE_BUFFERS 0x3032
#define EGL_SURFACE_TYPE 0x3033
#define EGL_TRANSPARENT_TYPE 0x3034
#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
#define EGL_TRANSPARENT_RED_VALUE 0x3037
#define EGL_NONE 0x3038 /* Attrib list terminator */
#define EGL_BIND_TO_TEXTURE_RGB 0x3039
#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
#define EGL_MIN_SWAP_INTERVAL 0x303B
#define EGL_MAX_SWAP_INTERVAL 0x303C
#define EGL_LUMINANCE_SIZE 0x303D
#define EGL_ALPHA_MASK_SIZE 0x303E
#define EGL_COLOR_BUFFER_TYPE 0x303F
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_MATCH_NATIVE_PIXMAP 0x3041 /* Pseudo-attribute (not queryable) */
#define EGL_CONFORMANT 0x3042
/* Reserved 0x3041-0x304F for additional config attributes */
/* Config attribute values */
#define EGL_SLOW_CONFIG 0x3050 /* EGL_CONFIG_CAVEAT value */
#define EGL_NON_CONFORMANT_CONFIG 0x3051 /* EGL_CONFIG_CAVEAT value */
#define EGL_TRANSPARENT_RGB 0x3052 /* EGL_TRANSPARENT_TYPE value */
#define EGL_RGB_BUFFER 0x308E /* EGL_COLOR_BUFFER_TYPE value */
#define EGL_LUMINANCE_BUFFER 0x308F /* EGL_COLOR_BUFFER_TYPE value */
/* More config attribute values, for EGL_TEXTURE_FORMAT */
#define EGL_NO_TEXTURE 0x305C
#define EGL_TEXTURE_RGB 0x305D
#define EGL_TEXTURE_RGBA 0x305E
#define EGL_TEXTURE_2D 0x305F
/* Config attribute mask bits */
#define EGL_PBUFFER_BIT 0x0001 /* EGL_SURFACE_TYPE mask bits */
#define EGL_PIXMAP_BIT 0x0002 /* EGL_SURFACE_TYPE mask bits */
#define EGL_WINDOW_BIT 0x0004 /* EGL_SURFACE_TYPE mask bits */
#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 /* EGL_SURFACE_TYPE mask bits */
#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 /* EGL_SURFACE_TYPE mask bits */
#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */
#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */
#define EGL_OPENGL_ES_BIT 0x0001 /* EGL_RENDERABLE_TYPE mask bits */
#define EGL_OPENVG_BIT 0x0002 /* EGL_RENDERABLE_TYPE mask bits */
#define EGL_OPENGL_ES2_BIT 0x0004 /* EGL_RENDERABLE_TYPE mask bits */
#define EGL_OPENGL_BIT 0x0008 /* EGL_RENDERABLE_TYPE mask bits */
/* QueryString targets */
#define EGL_VENDOR 0x3053
#define EGL_VERSION 0x3054
#define EGL_EXTENSIONS 0x3055
#define EGL_CLIENT_APIS 0x308D
/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
#define EGL_HEIGHT 0x3056
#define EGL_WIDTH 0x3057
#define EGL_LARGEST_PBUFFER 0x3058
#define EGL_TEXTURE_FORMAT 0x3080
#define EGL_TEXTURE_TARGET 0x3081
#define EGL_MIPMAP_TEXTURE 0x3082
#define EGL_MIPMAP_LEVEL 0x3083
#define EGL_RENDER_BUFFER 0x3086
#define EGL_VG_COLORSPACE 0x3087
#define EGL_VG_ALPHA_FORMAT 0x3088
#define EGL_HORIZONTAL_RESOLUTION 0x3090
#define EGL_VERTICAL_RESOLUTION 0x3091
#define EGL_PIXEL_ASPECT_RATIO 0x3092
#define EGL_SWAP_BEHAVIOR 0x3093
#define EGL_MULTISAMPLE_RESOLVE 0x3099
/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
#define EGL_BACK_BUFFER 0x3084
#define EGL_SINGLE_BUFFER 0x3085
/* OpenVG color spaces */
#define EGL_VG_COLORSPACE_sRGB 0x3089 /* EGL_VG_COLORSPACE value */
#define EGL_VG_COLORSPACE_LINEAR 0x308A /* EGL_VG_COLORSPACE value */
/* OpenVG alpha formats */
#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B /* EGL_ALPHA_FORMAT value */
#define EGL_VG_ALPHA_FORMAT_PRE 0x308C /* EGL_ALPHA_FORMAT value */
/* Constant scale factor by which fractional display resolutions &
* aspect ratio are scaled when queried as integer values.
*/
#define EGL_DISPLAY_SCALING 10000
/* Unknown display resolution/aspect ratio */
#define EGL_UNKNOWN ((EGLint)-1)
/* Back buffer swap behaviors */
#define EGL_BUFFER_PRESERVED 0x3094 /* EGL_SWAP_BEHAVIOR value */
#define EGL_BUFFER_DESTROYED 0x3095 /* EGL_SWAP_BEHAVIOR value */
/* CreatePbufferFromClientBuffer buffer types */
#define EGL_OPENVG_IMAGE 0x3096
/* QueryContext targets */
#define EGL_CONTEXT_CLIENT_TYPE 0x3097
/* CreateContext attributes */
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
/* Multisample resolution behaviors */
#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A /* EGL_MULTISAMPLE_RESOLVE value */
#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B /* EGL_MULTISAMPLE_RESOLVE value */
/* BindAPI/QueryAPI targets */
#define EGL_OPENGL_ES_API 0x30A0
#define EGL_OPENVG_API 0x30A1
#define EGL_OPENGL_API 0x30A2
/* GetCurrentSurface targets */
#define EGL_DRAW 0x3059
#define EGL_READ 0x305A
/* WaitNative engines */
#define EGL_CORE_NATIVE_ENGINE 0x305B
/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
#define EGL_COLORSPACE EGL_VG_COLORSPACE
#define EGL_ALPHA_FORMAT EGL_VG_ALPHA_FORMAT
#define EGL_COLORSPACE_sRGB EGL_VG_COLORSPACE_sRGB
#define EGL_COLORSPACE_LINEAR EGL_VG_COLORSPACE_LINEAR
#define EGL_ALPHA_FORMAT_NONPRE EGL_VG_ALPHA_FORMAT_NONPRE
#define EGL_ALPHA_FORMAT_PRE EGL_VG_ALPHA_FORMAT_PRE
/* EGL extensions must request enum blocks from the Khronos
* API Registrar, who maintains the enumerant registry. Submit
* a bug in Khronos Bugzilla against task "Registry".
*/
/* EGL Functions */
EGLAPI EGLint EGLAPIENTRY eglGetError(void);
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
EGLint config_size, EGLint *num_config);
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size,
EGLint *num_config);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
EGLint attribute, EGLint *value);
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType win,
const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
EGLNativePixmapType pixmap,
const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
EGLint attribute, EGLint value);
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
EGLContext share_context,
const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
EGLSurface read, EGLContext ctx);
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
EGLNativePixmapType target);
/* This is a generic function pointer type, whose name indicates it must
* be cast to the proper type *and calling convention* before use.
*/
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
/* Now, define eglGetProcAddress using the generic function ptr. type */
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
eglGetProcAddress(const char *procname);
#ifdef __cplusplus
}
#endif
#endif /* __egl_h_ */
+124
View File
@@ -0,0 +1,124 @@
#ifndef __eglplatform_h_
#define __eglplatform_h_
/*
** Copyright (c) 2007-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Platform-specific types and definitions for egl.h
* $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $
*
* Adopters may modify khrplatform.h and this file to suit their platform.
* You are encouraged to submit all modifications to the Khronos group so that
* they can be included in future versions of this file. Please submit changes
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
* by filing a bug against product "EGL" component "Registry".
*/
#include <APPLE/khrplatform.h>
/* Macros used in EGL function prototype declarations.
*
* EGL functions should be prototyped as:
*
* EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
*
* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
*/
#ifndef EGLAPI
#define EGLAPI KHRONOS_APICALL
#endif
#ifndef EGLAPIENTRY
#define EGLAPIENTRY KHRONOS_APIENTRY
#endif
#define EGLAPIENTRYP EGLAPIENTRY*
/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
* are aliases of window-system-dependent types, such as X Display * or
* Windows Device Context. They must be defined in platform-specific
* code below. The EGL-prefixed versions of Native*Type are the same
* types, renamed in EGL 1.3 so all types in the API start with "EGL".
*
* Khronos STRONGLY RECOMMENDS that you use the default definitions
* provided below, since these changes affect both binary and source
* portability of applications using EGL running on different EGL
* implementations.
*/
#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
typedef HWND EGLNativeWindowType;
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
typedef int EGLNativeDisplayType;
typedef void *EGLNativeWindowType;
typedef void *EGLNativePixmapType;
#elif defined(__unix__)
/* X11 (tentative) */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
typedef Display *EGLNativeDisplayType;
typedef Pixmap EGLNativePixmapType;
typedef Window EGLNativeWindowType;
#elif defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) )
// this line is taken from the TargetConditionals.h file in any on the iOS or Mac OS X platforms
struct appleEGLWindow;
typedef int EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef struct appleEGLWindow *EGLNativeWindowType;
#else
#error "Platform not recognized"
#endif
/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
typedef EGLNativeDisplayType NativeDisplayType;
typedef EGLNativePixmapType NativePixmapType;
typedef EGLNativeWindowType NativeWindowType;
/* Define EGLint. This must be a signed integral type large enough to contain
* all legal attribute names and values passed into and out of EGL, whether
* their type is boolean, bitmask, enumerant (symbolic constant), integer,
* handle, or other. While in general a 32-bit integer will suffice, if
* handles are 64 bit types, then EGLint should be defined as a signed 64-bit
* integer type.
*/
typedef khronos_int32_t EGLint;
#endif /* __eglplatform_h */
+269
View File
@@ -0,0 +1,269 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by sending them to the public Khronos Bugzilla
* (http://khronos.org/bugzilla) by filing a bug against product
* "Khronos (general)" component "Registry".
*
* A predefined template which fills in some of the bug fields can be
* reached using http://tinyurl.com/khrplatform-h-bugreport, but you
* must create a Bugzilla login first.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */
+131 -131
View File
@@ -5,27 +5,27 @@
*/
/*
** Copyright (c) 2007-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
** Copyright (c) 2007-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
#ifndef __egl_h_
#define __egl_h_
@@ -39,41 +39,41 @@
extern "C" {
#endif
/* EGL Types */
/* EGLint is defined in eglplatform.h */
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void *EGLConfig;
typedef void *EGLContext;
typedef void *EGLDisplay;
typedef void *EGLSurface;
typedef void *EGLClientBuffer;
/* EGL Types */
/* EGLint is defined in eglplatform.h */
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void *EGLConfig;
typedef void *EGLContext;
typedef void *EGLDisplay;
typedef void *EGLSurface;
typedef void *EGLClientBuffer;
/* EGL Versioning */
/* EGL Versioning */
#define EGL_VERSION_1_0 1
#define EGL_VERSION_1_1 1
#define EGL_VERSION_1_2 1
#define EGL_VERSION_1_3 1
#define EGL_VERSION_1_4 1
/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
* enums are assigned unique values starting at 0x3000.
*/
/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
* enums are assigned unique values starting at 0x3000.
*/
/* EGL aliases */
/* EGL aliases */
#define EGL_FALSE 0
#define EGL_TRUE 1
/* Out-of-band handle values */
/* Out-of-band handle values */
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
#define EGL_NO_CONTEXT ((EGLContext)0)
#define EGL_NO_DISPLAY ((EGLDisplay)0)
#define EGL_NO_SURFACE ((EGLSurface)0)
/* Out-of-band attribute value */
/* Out-of-band attribute value */
#define EGL_DONT_CARE ((EGLint)-1)
/* Errors / GetError return values */
/* Errors / GetError return values */
#define EGL_SUCCESS 0x3000
#define EGL_NOT_INITIALIZED 0x3001
#define EGL_BAD_ACCESS 0x3002
@@ -90,9 +90,9 @@ typedef void *EGLClientBuffer;
#define EGL_BAD_SURFACE 0x300D
#define EGL_CONTEXT_LOST 0x300E /* EGL 1.1 - IMG_power_management */
/* Reserved 0x300F-0x301F for additional errors */
/* Reserved 0x300F-0x301F for additional errors */
/* Config attributes */
/* Config attributes */
#define EGL_BUFFER_SIZE 0x3020
#define EGL_ALPHA_SIZE 0x3021
#define EGL_BLUE_SIZE 0x3022
@@ -128,22 +128,22 @@ typedef void *EGLClientBuffer;
#define EGL_MATCH_NATIVE_PIXMAP 0x3041 /* Pseudo-attribute (not queryable) */
#define EGL_CONFORMANT 0x3042
/* Reserved 0x3041-0x304F for additional config attributes */
/* Reserved 0x3041-0x304F for additional config attributes */
/* Config attribute values */
/* Config attribute values */
#define EGL_SLOW_CONFIG 0x3050 /* EGL_CONFIG_CAVEAT value */
#define EGL_NON_CONFORMANT_CONFIG 0x3051 /* EGL_CONFIG_CAVEAT value */
#define EGL_TRANSPARENT_RGB 0x3052 /* EGL_TRANSPARENT_TYPE value */
#define EGL_RGB_BUFFER 0x308E /* EGL_COLOR_BUFFER_TYPE value */
#define EGL_LUMINANCE_BUFFER 0x308F /* EGL_COLOR_BUFFER_TYPE value */
/* More config attribute values, for EGL_TEXTURE_FORMAT */
/* More config attribute values, for EGL_TEXTURE_FORMAT */
#define EGL_NO_TEXTURE 0x305C
#define EGL_TEXTURE_RGB 0x305D
#define EGL_TEXTURE_RGBA 0x305E
#define EGL_TEXTURE_2D 0x305F
/* Config attribute mask bits */
/* Config attribute mask bits */
#define EGL_PBUFFER_BIT 0x0001 /* EGL_SURFACE_TYPE mask bits */
#define EGL_PIXMAP_BIT 0x0002 /* EGL_SURFACE_TYPE mask bits */
#define EGL_WINDOW_BIT 0x0004 /* EGL_SURFACE_TYPE mask bits */
@@ -157,13 +157,13 @@ typedef void *EGLClientBuffer;
#define EGL_OPENGL_ES2_BIT 0x0004 /* EGL_RENDERABLE_TYPE mask bits */
#define EGL_OPENGL_BIT 0x0008 /* EGL_RENDERABLE_TYPE mask bits */
/* QueryString targets */
/* QueryString targets */
#define EGL_VENDOR 0x3053
#define EGL_VERSION 0x3054
#define EGL_EXTENSIONS 0x3055
#define EGL_CLIENT_APIS 0x308D
/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
#define EGL_HEIGHT 0x3056
#define EGL_WIDTH 0x3057
#define EGL_LARGEST_PBUFFER 0x3058
@@ -180,56 +180,56 @@ typedef void *EGLClientBuffer;
#define EGL_SWAP_BEHAVIOR 0x3093
#define EGL_MULTISAMPLE_RESOLVE 0x3099
/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
#define EGL_BACK_BUFFER 0x3084
#define EGL_SINGLE_BUFFER 0x3085
/* OpenVG color spaces */
/* OpenVG color spaces */
#define EGL_VG_COLORSPACE_sRGB 0x3089 /* EGL_VG_COLORSPACE value */
#define EGL_VG_COLORSPACE_LINEAR 0x308A /* EGL_VG_COLORSPACE value */
/* OpenVG alpha formats */
/* OpenVG alpha formats */
#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B /* EGL_ALPHA_FORMAT value */
#define EGL_VG_ALPHA_FORMAT_PRE 0x308C /* EGL_ALPHA_FORMAT value */
/* Constant scale factor by which fractional display resolutions &
* aspect ratio are scaled when queried as integer values.
*/
/* Constant scale factor by which fractional display resolutions &
* aspect ratio are scaled when queried as integer values.
*/
#define EGL_DISPLAY_SCALING 10000
/* Unknown display resolution/aspect ratio */
/* Unknown display resolution/aspect ratio */
#define EGL_UNKNOWN ((EGLint)-1)
/* Back buffer swap behaviors */
/* Back buffer swap behaviors */
#define EGL_BUFFER_PRESERVED 0x3094 /* EGL_SWAP_BEHAVIOR value */
#define EGL_BUFFER_DESTROYED 0x3095 /* EGL_SWAP_BEHAVIOR value */
/* CreatePbufferFromClientBuffer buffer types */
/* CreatePbufferFromClientBuffer buffer types */
#define EGL_OPENVG_IMAGE 0x3096
/* QueryContext targets */
/* QueryContext targets */
#define EGL_CONTEXT_CLIENT_TYPE 0x3097
/* CreateContext attributes */
/* CreateContext attributes */
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
/* Multisample resolution behaviors */
/* Multisample resolution behaviors */
#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A /* EGL_MULTISAMPLE_RESOLVE value */
#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B /* EGL_MULTISAMPLE_RESOLVE value */
/* BindAPI/QueryAPI targets */
/* BindAPI/QueryAPI targets */
#define EGL_OPENGL_ES_API 0x30A0
#define EGL_OPENVG_API 0x30A1
#define EGL_OPENGL_API 0x30A2
/* GetCurrentSurface targets */
/* GetCurrentSurface targets */
#define EGL_DRAW 0x3059
#define EGL_READ 0x305A
/* WaitNative engines */
/* WaitNative engines */
#define EGL_CORE_NATIVE_ENGINE 0x305B
/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
#define EGL_COLORSPACE EGL_VG_COLORSPACE
#define EGL_ALPHA_FORMAT EGL_VG_ALPHA_FORMAT
#define EGL_COLORSPACE_sRGB EGL_VG_COLORSPACE_sRGB
@@ -237,93 +237,93 @@ typedef void *EGLClientBuffer;
#define EGL_ALPHA_FORMAT_NONPRE EGL_VG_ALPHA_FORMAT_NONPRE
#define EGL_ALPHA_FORMAT_PRE EGL_VG_ALPHA_FORMAT_PRE
/* EGL extensions must request enum blocks from the Khronos
* API Registrar, who maintains the enumerant registry. Submit
* a bug in Khronos Bugzilla against task "Registry".
*/
/* EGL extensions must request enum blocks from the Khronos
* API Registrar, who maintains the enumerant registry. Submit
* a bug in Khronos Bugzilla against task "Registry".
*/
/* EGL Functions */
/* EGL Functions */
EGLAPI EGLint EGLAPIENTRY eglGetError(void);
EGLAPI EGLint EGLAPIENTRY eglGetError(void);
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
EGLint config_size, EGLint *num_config);
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size,
EGLint *num_config);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
EGLint config_size, EGLint *num_config);
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size,
EGLint *num_config);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
EGLint attribute, EGLint *value);
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType win,
const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
EGLNativePixmapType pixmap,
const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
EGLint attribute, EGLint *value);
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
EGLNativeWindowType win,
const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
EGLNativePixmapType pixmap,
const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
EGLint attribute, EGLint value);
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
EGLint attribute, EGLint value);
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
EGLContext share_context,
const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
EGLSurface read, EGLContext ctx);
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
EGLNativePixmapType target);
/* This is a generic function pointer type, whose name indicates it must
* be cast to the proper type *and calling convention* before use.
*/
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
/* Now, define eglGetProcAddress using the generic function ptr. type */
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
eglGetProcAddress(const char *procname);
EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
EGLContext share_context,
const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
EGLSurface read, EGLContext ctx);
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
EGLNativePixmapType target);
/* This is a generic function pointer type, whose name indicates it must
* be cast to the proper type *and calling convention* before use.
*/
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
/* Now, define eglGetProcAddress using the generic function ptr. type */
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
eglGetProcAddress(const char *procname);
#ifdef __cplusplus
}
#endif
#endif /* __egl_h_ */
#endif /* __egl_h_ */
+590 -268
View File
@@ -5,331 +5,653 @@
extern "C" {
#endif
/*
** Copyright (c) 2007-2010 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** Copyright (c) 2013 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 24902 $ on $Date: 2014-01-20 15:18:48 -0800 (Mon, 20 Jan 2014) $
*/
#include <EGL/eglplatform.h>
/*************************************************************/
#define EGL_EGLEXT_VERSION 20140120
/* Header file version number */
/* Current version at http://www.khronos.org/registry/egl/ */
/* $Revision: 15052 $ on $Date: 2011-07-06 17:43:46 -0700 (Wed, 06 Jul 2011) $ */
#define EGL_EGLEXT_VERSION 10
/* Generated C header for:
* API: egl
* Versions considered: .*
* Versions emitted: _nomatch_^
* Default extensions included: egl
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef EGL_KHR_cl_event
#define EGL_KHR_cl_event 1
#define EGL_CL_EVENT_HANDLE_KHR 0x309C
#define EGL_SYNC_CL_EVENT_KHR 0x30FE
#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF
#endif /* EGL_KHR_cl_event */
#ifndef EGL_KHR_cl_event2
#define EGL_KHR_cl_event2 1
typedef void *EGLSyncKHR;
typedef intptr_t EGLAttribKHR;
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
#endif
#endif /* EGL_KHR_cl_event2 */
#ifndef EGL_KHR_client_get_all_proc_addresses
#define EGL_KHR_client_get_all_proc_addresses 1
#endif /* EGL_KHR_client_get_all_proc_addresses */
#ifndef EGL_KHR_config_attribs
#define EGL_KHR_config_attribs 1
#define EGL_CONFORMANT_KHR 0x3042 /* EGLConfig attribute */
#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 /* EGL_SURFACE_TYPE bitfield */
#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 /* EGL_SURFACE_TYPE bitfield */
#endif
#define EGL_CONFORMANT_KHR 0x3042
#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020
#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040
#endif /* EGL_KHR_config_attribs */
#ifndef EGL_KHR_lock_surface
#define EGL_KHR_lock_surface 1
#define EGL_READ_SURFACE_BIT_KHR 0x0001 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 /* EGL_SURFACE_TYPE bitfield */
#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 /* EGL_SURFACE_TYPE bitfield */
#define EGL_MATCH_FORMAT_KHR 0x3043 /* EGLConfig attribute */
#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 /* EGL_MATCH_FORMAT_KHR value */
#define EGL_FORMAT_RGB_565_KHR 0x30C1 /* EGL_MATCH_FORMAT_KHR value */
#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 /* EGL_MATCH_FORMAT_KHR value */
#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 /* EGL_MATCH_FORMAT_KHR value */
#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 /* eglLockSurfaceKHR attribute */
#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 /* eglLockSurfaceKHR attribute */
#define EGL_BITMAP_POINTER_KHR 0x30C6 /* eglQuerySurface attribute */
#define EGL_BITMAP_PITCH_KHR 0x30C7 /* eglQuerySurface attribute */
#define EGL_BITMAP_ORIGIN_KHR 0x30C8 /* eglQuerySurface attribute */
#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 /* eglQuerySurface attribute */
#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA /* eglQuerySurface attribute */
#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB /* eglQuerySurface attribute */
#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC /* eglQuerySurface attribute */
#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD /* eglQuerySurface attribute */
#define EGL_LOWER_LEFT_KHR 0x30CE /* EGL_BITMAP_ORIGIN_KHR value */
#define EGL_UPPER_LEFT_KHR 0x30CF /* EGL_BITMAP_ORIGIN_KHR value */
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface);
#endif
#ifndef EGL_KHR_create_context
#define EGL_KHR_create_context 1
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
#define EGL_CONTEXT_FLAGS_KHR 0x30FC
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
#endif /* EGL_KHR_create_context */
#ifndef EGL_KHR_image
#define EGL_KHR_image 1
#define EGL_NATIVE_PIXMAP_KHR 0x30B0 /* eglCreateImageKHR target */
typedef void *EGLImageKHR;
#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
#endif
#ifndef EGL_KHR_fence_sync
#define EGL_KHR_fence_sync 1
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
#define EGL_SYNC_CONDITION_KHR 0x30F8
#define EGL_SYNC_FENCE_KHR 0x30F9
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_KHR_fence_sync */
#ifndef EGL_KHR_vg_parent_image
#define EGL_KHR_vg_parent_image 1
#define EGL_VG_PARENT_IMAGE_KHR 0x30BA /* eglCreateImageKHR target */
#endif
#ifndef EGL_KHR_get_all_proc_addresses
#define EGL_KHR_get_all_proc_addresses 1
#endif /* EGL_KHR_get_all_proc_addresses */
#ifndef EGL_KHR_gl_texture_2D_image
#define EGL_KHR_gl_texture_2D_image 1
#define EGL_GL_TEXTURE_2D_KHR 0x30B1 /* eglCreateImageKHR target */
#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC /* eglCreateImageKHR attribute */
#endif
#ifndef EGL_KHR_gl_texture_cubemap_image
#define EGL_KHR_gl_texture_cubemap_image 1
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 /* eglCreateImageKHR target */
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 /* eglCreateImageKHR target */
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 /* eglCreateImageKHR target */
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 /* eglCreateImageKHR target */
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 /* eglCreateImageKHR target */
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 /* eglCreateImageKHR target */
#endif
#ifndef EGL_KHR_gl_texture_3D_image
#define EGL_KHR_gl_texture_3D_image 1
#define EGL_GL_TEXTURE_3D_KHR 0x30B2 /* eglCreateImageKHR target */
#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD /* eglCreateImageKHR attribute */
#endif
#ifndef EGL_KHR_gl_colorspace
#define EGL_KHR_gl_colorspace 1
#define EGL_GL_COLORSPACE_KHR 0x309D
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A
#endif /* EGL_KHR_gl_colorspace */
#ifndef EGL_KHR_gl_renderbuffer_image
#define EGL_KHR_gl_renderbuffer_image 1
#define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */
#endif
#define EGL_GL_RENDERBUFFER_KHR 0x30B9
#endif /* EGL_KHR_gl_renderbuffer_image */
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
#ifndef EGL_KHR_reusable_sync
#define EGL_KHR_reusable_sync 1
#ifndef EGL_KHR_gl_texture_2D_image
#define EGL_KHR_gl_texture_2D_image 1
#define EGL_GL_TEXTURE_2D_KHR 0x30B1
#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
#endif /* EGL_KHR_gl_texture_2D_image */
typedef void* EGLSyncKHR;
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
#ifndef EGL_KHR_gl_texture_3D_image
#define EGL_KHR_gl_texture_3D_image 1
#define EGL_GL_TEXTURE_3D_KHR 0x30B2
#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD
#endif /* EGL_KHR_gl_texture_3D_image */
#define EGL_SYNC_STATUS_KHR 0x30F1
#define EGL_SIGNALED_KHR 0x30F2
#define EGL_UNSIGNALED_KHR 0x30F3
#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
#define EGL_CONDITION_SATISFIED_KHR 0x30F6
#define EGL_SYNC_TYPE_KHR 0x30F7
#define EGL_SYNC_REUSABLE_KHR 0x30FA
#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 /* eglClientWaitSyncKHR <flags> bitfield */
#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
#ifndef EGL_KHR_gl_texture_cubemap_image
#define EGL_KHR_gl_texture_cubemap_image 1
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8
#endif /* EGL_KHR_gl_texture_cubemap_image */
#ifndef EGL_KHR_image
#define EGL_KHR_image 1
typedef void *EGLImageKHR;
#define EGL_NATIVE_PIXMAP_KHR 0x30B0
#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
#endif
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
#endif
#endif /* EGL_KHR_image */
#ifndef EGL_KHR_image_base
#define EGL_KHR_image_base 1
/* Most interfaces defined by EGL_KHR_image_pixmap above */
#define EGL_IMAGE_PRESERVED_KHR 0x30D2 /* eglCreateImageKHR attribute */
#endif
#define EGL_IMAGE_PRESERVED_KHR 0x30D2
#endif /* EGL_KHR_image_base */
#ifndef EGL_KHR_image_pixmap
#define EGL_KHR_image_pixmap 1
/* Interfaces defined by EGL_KHR_image above */
#endif
#endif /* EGL_KHR_image_pixmap */
#ifndef EGL_IMG_context_priority
#define EGL_IMG_context_priority 1
#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
#ifndef EGL_KHR_lock_surface
#define EGL_KHR_lock_surface 1
#define EGL_READ_SURFACE_BIT_KHR 0x0001
#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
#define EGL_LOCK_SURFACE_BIT_KHR 0x0080
#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
#define EGL_MATCH_FORMAT_KHR 0x3043
#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
#define EGL_FORMAT_RGB_565_KHR 0x30C1
#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
#define EGL_FORMAT_RGBA_8888_KHR 0x30C3
#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
#define EGL_BITMAP_POINTER_KHR 0x30C6
#define EGL_BITMAP_PITCH_KHR 0x30C7
#define EGL_BITMAP_ORIGIN_KHR 0x30C8
#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
#define EGL_LOWER_LEFT_KHR 0x30CE
#define EGL_UPPER_LEFT_KHR 0x30CF
typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface);
#endif
#endif /* EGL_KHR_lock_surface */
#ifndef EGL_KHR_lock_surface2
#define EGL_KHR_lock_surface2 1
#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
#endif
#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
#endif /* EGL_KHR_lock_surface2 */
#ifndef EGL_NV_coverage_sample
#define EGL_NV_coverage_sample 1
#define EGL_COVERAGE_BUFFERS_NV 0x30E0
#define EGL_COVERAGE_SAMPLES_NV 0x30E1
#endif
#ifndef EGL_NV_depth_nonlinear
#define EGL_NV_depth_nonlinear 1
#define EGL_DEPTH_ENCODING_NV 0x30E2
#define EGL_DEPTH_ENCODING_NONE_NV 0
#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
#endif
#if KHRONOS_SUPPORT_INT64 /* EGLTimeNV requires 64-bit uint support */
#ifndef EGL_NV_sync
#define EGL_NV_sync 1
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
#define EGL_SYNC_STATUS_NV 0x30E7
#define EGL_SIGNALED_NV 0x30E8
#define EGL_UNSIGNALED_NV 0x30E9
#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
#define EGL_ALREADY_SIGNALED_NV 0x30EA
#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
#define EGL_CONDITION_SATISFIED_NV 0x30EC
#define EGL_SYNC_TYPE_NV 0x30ED
#define EGL_SYNC_CONDITION_NV 0x30EE
#define EGL_SYNC_FENCE_NV 0x30EF
#define EGL_NO_SYNC_NV ((EGLSyncNV)0)
typedef void* EGLSyncNV;
typedef khronos_utime_nanoseconds_t EGLTimeNV;
#ifndef EGL_KHR_lock_surface3
#define EGL_KHR_lock_surface3 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
EGLBoolean eglDestroySyncNV (EGLSyncNV sync);
EGLBoolean eglFenceNV (EGLSyncNV sync);
EGLint eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
EGLBoolean eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
EGLBoolean eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
#endif
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
#endif
#endif /* EGL_KHR_lock_surface3 */
#if KHRONOS_SUPPORT_INT64 /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */
#ifndef EGL_KHR_fence_sync
#define EGL_KHR_fence_sync 1
/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
#define EGL_SYNC_CONDITION_KHR 0x30F8
#define EGL_SYNC_FENCE_KHR 0x30F9
#endif
#endif
#ifndef EGL_HI_clientpixmap
#define EGL_HI_clientpixmap 1
/* Surface Attribute */
#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
/*
* Structure representing a client pixmap
* (pixmap's data is in client-space memory).
*/
struct EGLClientPixmapHI
{
void* pData;
EGLint iWidth;
EGLint iHeight;
EGLint iStride;
};
#ifndef EGL_KHR_reusable_sync
#define EGL_KHR_reusable_sync 1
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_SYNC_STATUS_KHR 0x30F1
#define EGL_SIGNALED_KHR 0x30F2
#define EGL_UNSIGNALED_KHR 0x30F3
#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
#define EGL_CONDITION_SATISFIED_KHR 0x30F6
#define EGL_SYNC_TYPE_KHR 0x30F7
#define EGL_SYNC_REUSABLE_KHR 0x30FA
#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
#endif /* EGL_HI_clientpixmap */
#ifndef EGL_HI_colorformats
#define EGL_HI_colorformats 1
/* Config Attribute */
#define EGL_COLOR_FORMAT_HI 0x8F70
/* Color Formats */
#define EGL_COLOR_RGB_HI 0x8F71
#define EGL_COLOR_RGBA_HI 0x8F72
#define EGL_COLOR_ARGB_HI 0x8F73
#endif /* EGL_HI_colorformats */
#ifndef EGL_MESA_drm_image
#define EGL_MESA_drm_image 1
#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* CreateDRMImageMESA attribute */
#define EGL_DRM_BUFFER_USE_MESA 0x31D1 /* CreateDRMImageMESA attribute */
#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 /* EGL_IMAGE_FORMAT_MESA attribute value */
#define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */
#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 /* EGL_DRM_BUFFER_USE_MESA bits */
#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 /* EGL_DRM_BUFFER_USE_MESA bits */
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync);
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
#endif
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_KHR_reusable_sync */
#ifndef EGL_NV_post_sub_buffer
#define EGL_NV_post_sub_buffer 1
#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
#ifndef EGL_KHR_stream
#define EGL_KHR_stream 1
typedef void *EGLStreamKHR;
typedef khronos_uint64_t EGLuint64KHR;
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
#define EGL_PRODUCER_FRAME_KHR 0x3212
#define EGL_CONSUMER_FRAME_KHR 0x3213
#define EGL_STREAM_STATE_KHR 0x3214
#define EGL_STREAM_STATE_CREATED_KHR 0x3215
#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
#define EGL_BAD_STREAM_KHR 0x321B
#define EGL_BAD_STATE_KHR 0x321C
typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
#endif
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_KHR_stream */
#ifndef EGL_KHR_stream_consumer_gltexture
#define EGL_KHR_stream_consumer_gltexture 1
#ifdef EGL_KHR_stream
#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream);
#endif
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_consumer_gltexture */
#ifndef EGL_KHR_stream_cross_process_fd
#define EGL_KHR_stream_cross_process_fd 1
typedef int EGLNativeFileDescriptorKHR;
#ifdef EGL_KHR_stream
#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1))
typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream);
EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
#endif
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_cross_process_fd */
#ifndef EGL_KHR_stream_fifo
#define EGL_KHR_stream_fifo 1
#ifdef EGL_KHR_stream
#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
#define EGL_STREAM_TIME_NOW_KHR 0x31FD
#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
#endif
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_fifo */
#ifndef EGL_KHR_stream_producer_aldatalocator
#define EGL_KHR_stream_producer_aldatalocator 1
#ifdef EGL_KHR_stream
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_producer_aldatalocator */
#ifndef EGL_KHR_stream_producer_eglsurface
#define EGL_KHR_stream_producer_eglsurface 1
#ifdef EGL_KHR_stream
#define EGL_STREAM_BIT_KHR 0x0800
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
#endif
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_producer_eglsurface */
#ifndef EGL_KHR_surfaceless_context
#define EGL_KHR_surfaceless_context 1
#endif /* EGL_KHR_surfaceless_context */
#ifndef EGL_KHR_vg_parent_image
#define EGL_KHR_vg_parent_image 1
#define EGL_VG_PARENT_IMAGE_KHR 0x30BA
#endif /* EGL_KHR_vg_parent_image */
#ifndef EGL_KHR_wait_sync
#define EGL_KHR_wait_sync 1
typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
#endif
#endif /* EGL_KHR_wait_sync */
#ifndef EGL_ANDROID_blob_cache
#define EGL_ANDROID_blob_cache 1
typedef khronos_ssize_t EGLsizeiANDROID;
typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
#endif
#endif /* EGL_ANDROID_blob_cache */
#ifndef EGL_ANDROID_framebuffer_target
#define EGL_ANDROID_framebuffer_target 1
#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
#endif /* EGL_ANDROID_framebuffer_target */
#ifndef EGL_ANDROID_image_native_buffer
#define EGL_ANDROID_image_native_buffer 1
#define EGL_NATIVE_BUFFER_ANDROID 0x3140
#endif /* EGL_ANDROID_image_native_buffer */
#ifndef EGL_ANDROID_native_fence_sync
#define EGL_ANDROID_native_fence_sync 1
#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync);
#endif
#endif /* EGL_ANDROID_native_fence_sync */
#ifndef EGL_ANDROID_recordable
#define EGL_ANDROID_recordable 1
#define EGL_RECORDABLE_ANDROID 0x3142
#endif /* EGL_ANDROID_recordable */
#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
#define EGL_ANGLE_d3d_share_handle_client_buffer 1
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
#ifndef EGL_ANGLE_query_surface_pointer
#define EGL_ANGLE_query_surface_pointer 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
#endif
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
#endif
#endif /* EGL_ANGLE_query_surface_pointer */
#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
#ifndef EGL_ARM_pixmap_multisample_discard
#define EGL_ARM_pixmap_multisample_discard 1
#define EGL_DISCARD_SAMPLES_ARM 0x3286
#endif /* EGL_ARM_pixmap_multisample_discard */
#ifndef EGL_EXT_buffer_age
#define EGL_EXT_buffer_age 1
#define EGL_BUFFER_AGE_EXT 0x313D
#endif /* EGL_EXT_buffer_age */
#ifndef EGL_EXT_client_extensions
#define EGL_EXT_client_extensions 1
#endif /* EGL_EXT_client_extensions */
#ifndef EGL_EXT_create_context_robustness
#define EGL_EXT_create_context_robustness 1
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
#endif /* EGL_EXT_create_context_robustness */
#ifndef EGL_EXT_image_dma_buf_import
#define EGL_EXT_image_dma_buf_import 1
#define EGL_LINUX_DMA_BUF_EXT 0x3270
#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B
#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C
#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
#define EGL_ITU_REC601_EXT 0x327F
#define EGL_ITU_REC709_EXT 0x3280
#define EGL_ITU_REC2020_EXT 0x3281
#define EGL_YUV_FULL_RANGE_EXT 0x3282
#define EGL_YUV_NARROW_RANGE_EXT 0x3283
#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284
#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285
#endif /* EGL_EXT_image_dma_buf_import */
#ifndef EGL_EXT_multiview_window
#define EGL_EXT_multiview_window 1
#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
#endif /* EGL_EXT_multiview_window */
#ifndef EGL_EXT_platform_base
#define EGL_EXT_platform_base 1
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
#endif
#endif /* EGL_EXT_platform_base */
#ifndef EGL_EXT_platform_wayland
#define EGL_EXT_platform_wayland 1
#define EGL_PLATFORM_WAYLAND_EXT 0x31D8
#endif /* EGL_EXT_platform_wayland */
#ifndef EGL_EXT_platform_x11
#define EGL_EXT_platform_x11 1
#define EGL_PLATFORM_X11_EXT 0x31D5
#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
#endif /* EGL_EXT_platform_x11 */
#ifndef EGL_EXT_protected_surface
#define EGL_EXT_protected_surface 1
#define EGL_PROTECTED_CONTENT_EXT 0x32C0
#endif /* EGL_EXT_protected_surface */
#ifndef EGL_EXT_swap_buffers_with_damage
#define EGL_EXT_swap_buffers_with_damage 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#endif
#endif /* EGL_EXT_swap_buffers_with_damage */
#ifndef EGL_HI_clientpixmap
#define EGL_HI_clientpixmap 1
struct EGLClientPixmapHI {
void *pData;
EGLint iWidth;
EGLint iHeight;
EGLint iStride;
};
#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
#endif
#endif /* EGL_HI_clientpixmap */
#ifndef EGL_HI_colorformats
#define EGL_HI_colorformats 1
#define EGL_COLOR_FORMAT_HI 0x8F70
#define EGL_COLOR_RGB_HI 0x8F71
#define EGL_COLOR_RGBA_HI 0x8F72
#define EGL_COLOR_ARGB_HI 0x8F73
#endif /* EGL_HI_colorformats */
#ifndef EGL_IMG_context_priority
#define EGL_IMG_context_priority 1
#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
#endif /* EGL_IMG_context_priority */
#ifndef EGL_MESA_drm_image
#define EGL_MESA_drm_image 1
#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
#define EGL_DRM_BUFFER_USE_MESA 0x31D1
#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
#define EGL_DRM_BUFFER_MESA 0x31D3
#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001
#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
#endif
#endif /* EGL_MESA_drm_image */
#ifndef EGL_MESA_platform_gbm
#define EGL_MESA_platform_gbm 1
#define EGL_PLATFORM_GBM_MESA 0x31D7
#endif /* EGL_MESA_platform_gbm */
#ifndef EGL_NV_3dvision_surface
#define EGL_NV_3dvision_surface 1
#define EGL_AUTO_STEREO_NV 0x3136
#endif /* EGL_NV_3dvision_surface */
#ifndef EGL_NV_coverage_sample
#define EGL_NV_coverage_sample 1
#define EGL_COVERAGE_BUFFERS_NV 0x30E0
#define EGL_COVERAGE_SAMPLES_NV 0x30E1
#endif /* EGL_NV_coverage_sample */
#ifndef EGL_NV_coverage_sample_resolve
#define EGL_NV_coverage_sample_resolve 1
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
#endif
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
#endif /* EGL_NV_coverage_sample_resolve */
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
#ifndef EGL_NV_depth_nonlinear
#define EGL_NV_depth_nonlinear 1
#define EGL_DEPTH_ENCODING_NV 0x30E2
#define EGL_DEPTH_ENCODING_NONE_NV 0
#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
#endif /* EGL_NV_depth_nonlinear */
#ifndef EGL_NV_native_query
#define EGL_NV_native_query 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
#endif
#endif /* EGL_NV_native_query */
#ifndef EGL_NV_post_convert_rounding
#define EGL_NV_post_convert_rounding 1
#endif /* EGL_NV_post_convert_rounding */
#ifndef EGL_NV_post_sub_buffer
#define EGL_NV_post_sub_buffer 1
#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
#endif
#endif /* EGL_NV_post_sub_buffer */
#ifndef EGL_NV_stream_sync
#define EGL_NV_stream_sync 1
#define EGL_SYNC_NEW_FRAME_NV 0x321F
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
#endif
#endif /* EGL_NV_stream_sync */
#ifndef EGL_NV_sync
#define EGL_NV_sync 1
typedef void *EGLSyncNV;
typedef khronos_utime_nanoseconds_t EGLTimeNV;
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
#define EGL_SYNC_STATUS_NV 0x30E7
#define EGL_SIGNALED_NV 0x30E8
#define EGL_UNSIGNALED_NV 0x30E9
#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
#define EGL_ALREADY_SIGNALED_NV 0x30EA
#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
#define EGL_CONDITION_SATISFIED_NV 0x30EC
#define EGL_SYNC_TYPE_NV 0x30ED
#define EGL_SYNC_CONDITION_NV 0x30EE
#define EGL_SYNC_FENCE_NV 0x30EF
#define EGL_NO_SYNC_NV ((EGLSyncNV)0)
typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync);
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
#endif
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_NV_sync */
#ifndef EGL_NV_system_time
#define EGL_NV_system_time 1
typedef khronos_utime_nanoseconds_t EGLuint64NV;
typedef khronos_utime_nanoseconds_t EGLuint64NV;
#ifdef KHRONOS_SUPPORT_INT64
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV(void);
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV(void);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void);
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
#endif
#endif
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_NV_system_time */
#ifdef __cplusplus
}
#endif
#endif
#endif
+33 -23
View File
@@ -2,30 +2,30 @@
#define __eglplatform_h_
/*
** Copyright (c) 2007-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
** Copyright (c) 2007-2013 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Platform-specific types and definitions for egl.h
* $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $
* $Revision: 23432 $ on $Date: 2013-10-09 00:57:24 -0700 (Wed, 09 Oct 2013) $
*
* Adopters may modify khrplatform.h and this file to suit their platform.
* You are encouraged to submit all modifications to the Khronos group so that
@@ -83,6 +83,16 @@ typedef int EGLNativeDisplayType;
typedef void *EGLNativeWindowType;
typedef void *EGLNativePixmapType;
#elif defined(__ANDROID__) || defined(ANDROID)
#include <android/native_window.h>
struct egl_native_pixmap_t;
typedef struct ANativeWindow* EGLNativeWindowType;
typedef struct egl_native_pixmap_t* EGLNativePixmapType;
typedef void* EGLNativeDisplayType;
#elif defined(__unix__)
/* X11 (tentative) */
@@ -112,4 +122,4 @@ typedef EGLNativeWindowType NativeWindowType;
*/
typedef khronos_int32_t EGLint;
#endif /* __eglplatform_h */
#endif /* __eglplatform_h */
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+244 -340
View File
@@ -1,56 +1,83 @@
#ifndef __gl2_h_
#define __gl2_h_
/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */
#include <GLES2/gl2platform.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* This document is licensed under the SGI Free Software B License Version
* 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
*/
/*
** Copyright (c) 2013 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 24614 $ on $Date: 2013-12-30 04:44:46 -0800 (Mon, 30 Dec 2013) $
*/
/*-------------------------------------------------------------------------
* Data type definitions
*-----------------------------------------------------------------------*/
#include <GLES2/gl2platform.h>
typedef void GLvoid;
typedef char GLchar;
typedef unsigned int GLenum;
typedef unsigned char GLboolean;
typedef unsigned int GLbitfield;
typedef khronos_int8_t GLbyte;
typedef short GLshort;
typedef int GLint;
typedef int GLsizei;
typedef khronos_uint8_t GLubyte;
typedef unsigned short GLushort;
typedef unsigned int GLuint;
typedef khronos_float_t GLfloat;
typedef khronos_float_t GLclampf;
typedef khronos_int32_t GLfixed;
/* Generated on date 20131230 */
/* GL types for handling large vertex buffer objects */
typedef khronos_intptr_t GLintptr;
typedef khronos_ssize_t GLsizeiptr;
/* Generated C header for:
* API: gles2
* Profile: common
* Versions considered: 2\.[0-9]
* Versions emitted: .*
* Default extensions included: None
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
/* OpenGL ES core versions */
#define GL_ES_VERSION_2_0 1
/* ClearBufferMask */
#ifndef GL_ES_VERSION_2_0
#define GL_ES_VERSION_2_0 1
#include <KHR/khrplatform.h>
typedef khronos_int8_t GLbyte;
typedef khronos_float_t GLclampf;
typedef khronos_int32_t GLfixed;
typedef short GLshort;
typedef unsigned short GLushort;
typedef void GLvoid;
typedef struct __GLsync *GLsync;
typedef khronos_int64_t GLint64;
typedef khronos_uint64_t GLuint64;
typedef unsigned int GLenum;
typedef unsigned int GLuint;
typedef char GLchar;
typedef khronos_float_t GLfloat;
typedef khronos_ssize_t GLsizeiptr;
typedef khronos_intptr_t GLintptr;
typedef unsigned int GLbitfield;
typedef int GLint;
typedef unsigned char GLboolean;
typedef int GLsizei;
typedef khronos_uint8_t GLubyte;
#define GL_DEPTH_BUFFER_BIT 0x00000100
#define GL_STENCIL_BUFFER_BIT 0x00000400
#define GL_COLOR_BUFFER_BIT 0x00004000
/* Boolean */
#define GL_FALSE 0
#define GL_TRUE 1
/* BeginMode */
#define GL_POINTS 0x0000
#define GL_LINES 0x0001
#define GL_LINE_LOOP 0x0002
@@ -58,18 +85,6 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_TRIANGLES 0x0004
#define GL_TRIANGLE_STRIP 0x0005
#define GL_TRIANGLE_FAN 0x0006
/* AlphaFunction (not supported in ES20) */
/* GL_NEVER */
/* GL_LESS */
/* GL_EQUAL */
/* GL_LEQUAL */
/* GL_GREATER */
/* GL_NOTEQUAL */
/* GL_GEQUAL */
/* GL_ALWAYS */
/* BlendingFactorDest */
#define GL_ZERO 0
#define GL_ONE 1
#define GL_SRC_COLOR 0x0300
@@ -78,29 +93,15 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_DST_ALPHA 0x0304
#define GL_ONE_MINUS_DST_ALPHA 0x0305
/* BlendingFactorSrc */
/* GL_ZERO */
/* GL_ONE */
#define GL_DST_COLOR 0x0306
#define GL_ONE_MINUS_DST_COLOR 0x0307
#define GL_SRC_ALPHA_SATURATE 0x0308
/* GL_SRC_ALPHA */
/* GL_ONE_MINUS_SRC_ALPHA */
/* GL_DST_ALPHA */
/* GL_ONE_MINUS_DST_ALPHA */
/* BlendEquationSeparate */
#define GL_FUNC_ADD 0x8006
#define GL_BLEND_EQUATION 0x8009
#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */
#define GL_BLEND_EQUATION_RGB 0x8009
#define GL_BLEND_EQUATION_ALPHA 0x883D
/* BlendSubtract */
#define GL_FUNC_SUBTRACT 0x800A
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
/* Separate Blend Functions */
#define GL_BLEND_DST_RGB 0x80C8
#define GL_BLEND_SRC_RGB 0x80C9
#define GL_BLEND_DST_ALPHA 0x80CA
@@ -110,38 +111,19 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_CONSTANT_ALPHA 0x8003
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
#define GL_BLEND_COLOR 0x8005
/* Buffer Objects */
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_ARRAY_BUFFER_BINDING 0x8894
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
#define GL_STREAM_DRAW 0x88E0
#define GL_STATIC_DRAW 0x88E4
#define GL_DYNAMIC_DRAW 0x88E8
#define GL_BUFFER_SIZE 0x8764
#define GL_BUFFER_USAGE 0x8765
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
/* CullFaceMode */
#define GL_FRONT 0x0404
#define GL_BACK 0x0405
#define GL_FRONT_AND_BACK 0x0408
/* DepthFunction */
/* GL_NEVER */
/* GL_LESS */
/* GL_EQUAL */
/* GL_LEQUAL */
/* GL_GREATER */
/* GL_NOTEQUAL */
/* GL_GEQUAL */
/* GL_ALWAYS */
/* EnableCap */
#define GL_TEXTURE_2D 0x0DE1
#define GL_CULL_FACE 0x0B44
#define GL_BLEND 0x0BE2
@@ -152,19 +134,13 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_POLYGON_OFFSET_FILL 0x8037
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
#define GL_SAMPLE_COVERAGE 0x80A0
/* ErrorCode */
#define GL_NO_ERROR 0
#define GL_INVALID_ENUM 0x0500
#define GL_INVALID_VALUE 0x0501
#define GL_INVALID_OPERATION 0x0502
#define GL_OUT_OF_MEMORY 0x0505
/* FrontFaceDirection */
#define GL_CW 0x0900
#define GL_CCW 0x0901
/* GetPName */
#define GL_LINE_WIDTH 0x0B21
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
@@ -191,7 +167,6 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
#define GL_VIEWPORT 0x0BA2
#define GL_SCISSOR_BOX 0x0C10
/* GL_SCISSOR_TEST */
#define GL_COLOR_CLEAR_VALUE 0x0C22
#define GL_COLOR_WRITEMASK 0x0C23
#define GL_UNPACK_ALIGNMENT 0x0CF5
@@ -206,32 +181,18 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_DEPTH_BITS 0x0D56
#define GL_STENCIL_BITS 0x0D57
#define GL_POLYGON_OFFSET_UNITS 0x2A00
/* GL_POLYGON_OFFSET_FILL */
#define GL_POLYGON_OFFSET_FACTOR 0x8038
#define GL_TEXTURE_BINDING_2D 0x8069
#define GL_SAMPLE_BUFFERS 0x80A8
#define GL_SAMPLES 0x80A9
#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
/* GetTextureParameter */
/* GL_TEXTURE_MAG_FILTER */
/* GL_TEXTURE_MIN_FILTER */
/* GL_TEXTURE_WRAP_S */
/* GL_TEXTURE_WRAP_T */
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
/* HintMode */
#define GL_DONT_CARE 0x1100
#define GL_FASTEST 0x1101
#define GL_NICEST 0x1102
/* HintTarget */
#define GL_GENERATE_MIPMAP_HINT 0x8192
/* DataType */
#define GL_GENERATE_MIPMAP_HINT 0x8192
#define GL_BYTE 0x1400
#define GL_UNSIGNED_BYTE 0x1401
#define GL_SHORT 0x1402
@@ -240,44 +201,35 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_UNSIGNED_INT 0x1405
#define GL_FLOAT 0x1406
#define GL_FIXED 0x140C
/* PixelFormat */
#define GL_DEPTH_COMPONENT 0x1902
#define GL_ALPHA 0x1906
#define GL_RGB 0x1907
#define GL_RGBA 0x1908
#define GL_LUMINANCE 0x1909
#define GL_LUMINANCE_ALPHA 0x190A
/* PixelType */
/* GL_UNSIGNED_BYTE */
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
/* Shaders */
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_MAX_VERTEX_ATTRIBS 0x8869
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
#define GL_MAX_VARYING_VECTORS 0x8DFC
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_MAX_VERTEX_ATTRIBS 0x8869
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
#define GL_MAX_VARYING_VECTORS 0x8DFC
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
#define GL_SHADER_TYPE 0x8B4F
#define GL_DELETE_STATUS 0x8B80
#define GL_LINK_STATUS 0x8B82
#define GL_VALIDATE_STATUS 0x8B83
#define GL_ATTACHED_SHADERS 0x8B85
#define GL_ACTIVE_UNIFORMS 0x8B86
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
#define GL_ACTIVE_ATTRIBUTES 0x8B89
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GL_CURRENT_PROGRAM 0x8B8D
/* StencilFunction */
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
#define GL_SHADER_TYPE 0x8B4F
#define GL_DELETE_STATUS 0x8B80
#define GL_LINK_STATUS 0x8B82
#define GL_VALIDATE_STATUS 0x8B83
#define GL_ATTACHED_SHADERS 0x8B85
#define GL_ACTIVE_UNIFORMS 0x8B86
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
#define GL_ACTIVE_ATTRIBUTES 0x8B89
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GL_CURRENT_PROGRAM 0x8B8D
#define GL_NEVER 0x0200
#define GL_LESS 0x0201
#define GL_EQUAL 0x0202
@@ -286,9 +238,6 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_NOTEQUAL 0x0205
#define GL_GEQUAL 0x0206
#define GL_ALWAYS 0x0207
/* StencilOp */
/* GL_ZERO */
#define GL_KEEP 0x1E00
#define GL_REPLACE 0x1E01
#define GL_INCR 0x1E02
@@ -296,35 +245,21 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_INVERT 0x150A
#define GL_INCR_WRAP 0x8507
#define GL_DECR_WRAP 0x8508
/* StringName */
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
#define GL_VERSION 0x1F02
#define GL_EXTENSIONS 0x1F03
/* TextureMagFilter */
#define GL_NEAREST 0x2600
#define GL_LINEAR 0x2601
/* TextureMinFilter */
/* GL_NEAREST */
/* GL_LINEAR */
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
/* TextureParameterName */
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_TEXTURE_WRAP_S 0x2802
#define GL_TEXTURE_WRAP_T 0x2803
/* TextureTarget */
/* GL_TEXTURE_2D */
#define GL_TEXTURE 0x1702
#define GL_TEXTURE_CUBE_MAP 0x8513
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
@@ -334,8 +269,6 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
/* TextureUnit */
#define GL_TEXTURE0 0x84C0
#define GL_TEXTURE1 0x84C1
#define GL_TEXTURE2 0x84C2
@@ -369,13 +302,9 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_TEXTURE30 0x84DE
#define GL_TEXTURE31 0x84DF
#define GL_ACTIVE_TEXTURE 0x84E0
/* TextureWrapMode */
#define GL_REPEAT 0x2901
#define GL_CLAMP_TO_EDGE 0x812F
#define GL_MIRRORED_REPEAT 0x8370
/* Uniform Types */
#define GL_FLOAT_VEC2 0x8B50
#define GL_FLOAT_VEC3 0x8B51
#define GL_FLOAT_VEC4 0x8B52
@@ -391,49 +320,34 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_FLOAT_MAT4 0x8B5C
#define GL_SAMPLER_2D 0x8B5E
#define GL_SAMPLER_CUBE 0x8B60
/* Vertex Arrays */
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
/* Read Format */
#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
/* Shader Source */
#define GL_COMPILE_STATUS 0x8B81
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_SHADER_SOURCE_LENGTH 0x8B88
#define GL_SHADER_COMPILER 0x8DFA
/* Shader Binary */
#define GL_SHADER_BINARY_FORMATS 0x8DF8
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
/* Shader Precision-Specified Types */
#define GL_LOW_FLOAT 0x8DF0
#define GL_MEDIUM_FLOAT 0x8DF1
#define GL_HIGH_FLOAT 0x8DF2
#define GL_LOW_INT 0x8DF3
#define GL_MEDIUM_INT 0x8DF4
#define GL_HIGH_INT 0x8DF5
/* Framebuffer Object. */
#define GL_FRAMEBUFFER 0x8D40
#define GL_RENDERBUFFER 0x8D41
#define GL_RGBA4 0x8056
#define GL_RGB5_A1 0x8057
#define GL_RGB565 0x8D62
#define GL_DEPTH_COMPONENT16 0x81A5
#define GL_STENCIL_INDEX 0x1901
#define GL_STENCIL_INDEX8 0x8D48
#define GL_RENDERBUFFER_WIDTH 0x8D42
#define GL_RENDERBUFFER_HEIGHT 0x8D43
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
@@ -443,179 +357,169 @@ typedef khronos_ssize_t GLsizeiptr;
#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
#define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_DEPTH_ATTACHMENT 0x8D00
#define GL_STENCIL_ATTACHMENT 0x8D20
#define GL_NONE 0
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
#define GL_FRAMEBUFFER_BINDING 0x8CA6
#define GL_RENDERBUFFER_BINDING 0x8CA7
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
/*-------------------------------------------------------------------------
* GL core functions.
*-----------------------------------------------------------------------*/
GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name);
GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode );
GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth);
GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers);
GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers);
GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers);
GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures);
GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar);
GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
GL_APICALL void GL_APIENTRY glFinish (void);
GL_APICALL void GL_APIENTRY glFlush (void);
GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers);
GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers);
GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers);
GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures);
GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name);
GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params);
GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params);
GL_APICALL GLenum GL_APIENTRY glGetError (void);
GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params);
GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name);
GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params);
GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params);
GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params);
GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name);
GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params);
GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params);
GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer);
GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params);
GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params);
GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x);
GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v);
GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x);
GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v);
GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y);
GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v);
GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y);
GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v);
GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z);
GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v);
GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z);
GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v);
GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v);
GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w);
GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v);
GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x);
GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values);
GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y);
GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values);
GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z);
GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values);
GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values);
GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode);
GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d);
GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
GL_APICALL void GL_APIENTRY glFinish (void);
GL_APICALL void GL_APIENTRY glFlush (void);
GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
GL_APICALL GLenum GL_APIENTRY glGetError (void);
GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data);
GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name);
GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0);
GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0);
GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
#endif /* GL_ES_VERSION_2_0 */
#ifdef __cplusplus
}
#endif
#endif /* __gl2_h_ */
#endif
+1358 -1054
View File
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -1,7 +1,7 @@
#ifndef __gl2platform_h_
#define __gl2platform_h_
/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */
/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */
/*
* This document is licensed under the SGI Free Software B License Version
@@ -27,4 +27,4 @@
#define GL_APIENTRY KHRONOS_APIENTRY
#endif
#endif /* __gl2platform_h_ */
#endif /* __gl2platform_h_ */
File diff suppressed because it is too large. Load diff
+939
View File
@@ -0,0 +1,939 @@
#ifndef __gl3_h_
#define __gl3_h_
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2013 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 24614 $ on $Date: 2013-12-30 04:44:46 -0800 (Mon, 30 Dec 2013) $
*/
#include <GLES3/gl3platform.h>
/* Generated on date 20131230 */
/* Generated C header for:
* API: gles2
* Profile: common
* Versions considered: [23]\.[0-9]
* Versions emitted: .*
* Default extensions included: None
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef GL_ES_VERSION_2_0
#define GL_ES_VERSION_2_0 1
#include <KHR/khrplatform.h>
typedef khronos_int8_t GLbyte;
typedef khronos_float_t GLclampf;
typedef khronos_int32_t GLfixed;
typedef short GLshort;
typedef unsigned short GLushort;
typedef void GLvoid;
typedef struct __GLsync *GLsync;
typedef khronos_int64_t GLint64;
typedef khronos_uint64_t GLuint64;
typedef unsigned int GLenum;
typedef unsigned int GLuint;
typedef char GLchar;
typedef khronos_float_t GLfloat;
typedef khronos_ssize_t GLsizeiptr;
typedef khronos_intptr_t GLintptr;
typedef unsigned int GLbitfield;
typedef int GLint;
typedef unsigned char GLboolean;
typedef int GLsizei;
typedef khronos_uint8_t GLubyte;
#define GL_DEPTH_BUFFER_BIT 0x00000100
#define GL_STENCIL_BUFFER_BIT 0x00000400
#define GL_COLOR_BUFFER_BIT 0x00004000
#define GL_FALSE 0
#define GL_TRUE 1
#define GL_POINTS 0x0000
#define GL_LINES 0x0001
#define GL_LINE_LOOP 0x0002
#define GL_LINE_STRIP 0x0003
#define GL_TRIANGLES 0x0004
#define GL_TRIANGLE_STRIP 0x0005
#define GL_TRIANGLE_FAN 0x0006
#define GL_ZERO 0
#define GL_ONE 1
#define GL_SRC_COLOR 0x0300
#define GL_ONE_MINUS_SRC_COLOR 0x0301
#define GL_SRC_ALPHA 0x0302
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_DST_ALPHA 0x0304
#define GL_ONE_MINUS_DST_ALPHA 0x0305
#define GL_DST_COLOR 0x0306
#define GL_ONE_MINUS_DST_COLOR 0x0307
#define GL_SRC_ALPHA_SATURATE 0x0308
#define GL_FUNC_ADD 0x8006
#define GL_BLEND_EQUATION 0x8009
#define GL_BLEND_EQUATION_RGB 0x8009
#define GL_BLEND_EQUATION_ALPHA 0x883D
#define GL_FUNC_SUBTRACT 0x800A
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
#define GL_BLEND_DST_RGB 0x80C8
#define GL_BLEND_SRC_RGB 0x80C9
#define GL_BLEND_DST_ALPHA 0x80CA
#define GL_BLEND_SRC_ALPHA 0x80CB
#define GL_CONSTANT_COLOR 0x8001
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
#define GL_CONSTANT_ALPHA 0x8003
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
#define GL_BLEND_COLOR 0x8005
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_ARRAY_BUFFER_BINDING 0x8894
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
#define GL_STREAM_DRAW 0x88E0
#define GL_STATIC_DRAW 0x88E4
#define GL_DYNAMIC_DRAW 0x88E8
#define GL_BUFFER_SIZE 0x8764
#define GL_BUFFER_USAGE 0x8765
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
#define GL_FRONT 0x0404
#define GL_BACK 0x0405
#define GL_FRONT_AND_BACK 0x0408
#define GL_TEXTURE_2D 0x0DE1
#define GL_CULL_FACE 0x0B44
#define GL_BLEND 0x0BE2
#define GL_DITHER 0x0BD0
#define GL_STENCIL_TEST 0x0B90
#define GL_DEPTH_TEST 0x0B71
#define GL_SCISSOR_TEST 0x0C11
#define GL_POLYGON_OFFSET_FILL 0x8037
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
#define GL_SAMPLE_COVERAGE 0x80A0
#define GL_NO_ERROR 0
#define GL_INVALID_ENUM 0x0500
#define GL_INVALID_VALUE 0x0501
#define GL_INVALID_OPERATION 0x0502
#define GL_OUT_OF_MEMORY 0x0505
#define GL_CW 0x0900
#define GL_CCW 0x0901
#define GL_LINE_WIDTH 0x0B21
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
#define GL_CULL_FACE_MODE 0x0B45
#define GL_FRONT_FACE 0x0B46
#define GL_DEPTH_RANGE 0x0B70
#define GL_DEPTH_WRITEMASK 0x0B72
#define GL_DEPTH_CLEAR_VALUE 0x0B73
#define GL_DEPTH_FUNC 0x0B74
#define GL_STENCIL_CLEAR_VALUE 0x0B91
#define GL_STENCIL_FUNC 0x0B92
#define GL_STENCIL_FAIL 0x0B94
#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
#define GL_STENCIL_REF 0x0B97
#define GL_STENCIL_VALUE_MASK 0x0B93
#define GL_STENCIL_WRITEMASK 0x0B98
#define GL_STENCIL_BACK_FUNC 0x8800
#define GL_STENCIL_BACK_FAIL 0x8801
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
#define GL_STENCIL_BACK_REF 0x8CA3
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
#define GL_VIEWPORT 0x0BA2
#define GL_SCISSOR_BOX 0x0C10
#define GL_COLOR_CLEAR_VALUE 0x0C22
#define GL_COLOR_WRITEMASK 0x0C23
#define GL_UNPACK_ALIGNMENT 0x0CF5
#define GL_PACK_ALIGNMENT 0x0D05
#define GL_MAX_TEXTURE_SIZE 0x0D33
#define GL_MAX_VIEWPORT_DIMS 0x0D3A
#define GL_SUBPIXEL_BITS 0x0D50
#define GL_RED_BITS 0x0D52
#define GL_GREEN_BITS 0x0D53
#define GL_BLUE_BITS 0x0D54
#define GL_ALPHA_BITS 0x0D55
#define GL_DEPTH_BITS 0x0D56
#define GL_STENCIL_BITS 0x0D57
#define GL_POLYGON_OFFSET_UNITS 0x2A00
#define GL_POLYGON_OFFSET_FACTOR 0x8038
#define GL_TEXTURE_BINDING_2D 0x8069
#define GL_SAMPLE_BUFFERS 0x80A8
#define GL_SAMPLES 0x80A9
#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
#define GL_DONT_CARE 0x1100
#define GL_FASTEST 0x1101
#define GL_NICEST 0x1102
#define GL_GENERATE_MIPMAP_HINT 0x8192
#define GL_BYTE 0x1400
#define GL_UNSIGNED_BYTE 0x1401
#define GL_SHORT 0x1402
#define GL_UNSIGNED_SHORT 0x1403
#define GL_INT 0x1404
#define GL_UNSIGNED_INT 0x1405
#define GL_FLOAT 0x1406
#define GL_FIXED 0x140C
#define GL_DEPTH_COMPONENT 0x1902
#define GL_ALPHA 0x1906
#define GL_RGB 0x1907
#define GL_RGBA 0x1908
#define GL_LUMINANCE 0x1909
#define GL_LUMINANCE_ALPHA 0x190A
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_MAX_VERTEX_ATTRIBS 0x8869
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
#define GL_MAX_VARYING_VECTORS 0x8DFC
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
#define GL_SHADER_TYPE 0x8B4F
#define GL_DELETE_STATUS 0x8B80
#define GL_LINK_STATUS 0x8B82
#define GL_VALIDATE_STATUS 0x8B83
#define GL_ATTACHED_SHADERS 0x8B85
#define GL_ACTIVE_UNIFORMS 0x8B86
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
#define GL_ACTIVE_ATTRIBUTES 0x8B89
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GL_CURRENT_PROGRAM 0x8B8D
#define GL_NEVER 0x0200
#define GL_LESS 0x0201
#define GL_EQUAL 0x0202
#define GL_LEQUAL 0x0203
#define GL_GREATER 0x0204
#define GL_NOTEQUAL 0x0205
#define GL_GEQUAL 0x0206
#define GL_ALWAYS 0x0207
#define GL_KEEP 0x1E00
#define GL_REPLACE 0x1E01
#define GL_INCR 0x1E02
#define GL_DECR 0x1E03
#define GL_INVERT 0x150A
#define GL_INCR_WRAP 0x8507
#define GL_DECR_WRAP 0x8508
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
#define GL_VERSION 0x1F02
#define GL_EXTENSIONS 0x1F03
#define GL_NEAREST 0x2600
#define GL_LINEAR 0x2601
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_TEXTURE_WRAP_S 0x2802
#define GL_TEXTURE_WRAP_T 0x2803
#define GL_TEXTURE 0x1702
#define GL_TEXTURE_CUBE_MAP 0x8513
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
#define GL_TEXTURE0 0x84C0
#define GL_TEXTURE1 0x84C1
#define GL_TEXTURE2 0x84C2
#define GL_TEXTURE3 0x84C3
#define GL_TEXTURE4 0x84C4
#define GL_TEXTURE5 0x84C5
#define GL_TEXTURE6 0x84C6
#define GL_TEXTURE7 0x84C7
#define GL_TEXTURE8 0x84C8
#define GL_TEXTURE9 0x84C9
#define GL_TEXTURE10 0x84CA
#define GL_TEXTURE11 0x84CB
#define GL_TEXTURE12 0x84CC
#define GL_TEXTURE13 0x84CD
#define GL_TEXTURE14 0x84CE
#define GL_TEXTURE15 0x84CF
#define GL_TEXTURE16 0x84D0
#define GL_TEXTURE17 0x84D1
#define GL_TEXTURE18 0x84D2
#define GL_TEXTURE19 0x84D3
#define GL_TEXTURE20 0x84D4
#define GL_TEXTURE21 0x84D5
#define GL_TEXTURE22 0x84D6
#define GL_TEXTURE23 0x84D7
#define GL_TEXTURE24 0x84D8
#define GL_TEXTURE25 0x84D9
#define GL_TEXTURE26 0x84DA
#define GL_TEXTURE27 0x84DB
#define GL_TEXTURE28 0x84DC
#define GL_TEXTURE29 0x84DD
#define GL_TEXTURE30 0x84DE
#define GL_TEXTURE31 0x84DF
#define GL_ACTIVE_TEXTURE 0x84E0
#define GL_REPEAT 0x2901
#define GL_CLAMP_TO_EDGE 0x812F
#define GL_MIRRORED_REPEAT 0x8370
#define GL_FLOAT_VEC2 0x8B50
#define GL_FLOAT_VEC3 0x8B51
#define GL_FLOAT_VEC4 0x8B52
#define GL_INT_VEC2 0x8B53
#define GL_INT_VEC3 0x8B54
#define GL_INT_VEC4 0x8B55
#define GL_BOOL 0x8B56
#define GL_BOOL_VEC2 0x8B57
#define GL_BOOL_VEC3 0x8B58
#define GL_BOOL_VEC4 0x8B59
#define GL_FLOAT_MAT2 0x8B5A
#define GL_FLOAT_MAT3 0x8B5B
#define GL_FLOAT_MAT4 0x8B5C
#define GL_SAMPLER_2D 0x8B5E
#define GL_SAMPLER_CUBE 0x8B60
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
#define GL_COMPILE_STATUS 0x8B81
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_SHADER_SOURCE_LENGTH 0x8B88
#define GL_SHADER_COMPILER 0x8DFA
#define GL_SHADER_BINARY_FORMATS 0x8DF8
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
#define GL_LOW_FLOAT 0x8DF0
#define GL_MEDIUM_FLOAT 0x8DF1
#define GL_HIGH_FLOAT 0x8DF2
#define GL_LOW_INT 0x8DF3
#define GL_MEDIUM_INT 0x8DF4
#define GL_HIGH_INT 0x8DF5
#define GL_FRAMEBUFFER 0x8D40
#define GL_RENDERBUFFER 0x8D41
#define GL_RGBA4 0x8056
#define GL_RGB5_A1 0x8057
#define GL_RGB565 0x8D62
#define GL_DEPTH_COMPONENT16 0x81A5
#define GL_STENCIL_INDEX8 0x8D48
#define GL_RENDERBUFFER_WIDTH 0x8D42
#define GL_RENDERBUFFER_HEIGHT 0x8D43
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
#define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_DEPTH_ATTACHMENT 0x8D00
#define GL_STENCIL_ATTACHMENT 0x8D20
#define GL_NONE 0
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
#define GL_FRAMEBUFFER_BINDING 0x8CA6
#define GL_RENDERBUFFER_BINDING 0x8CA7
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode);
GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d);
GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
GL_APICALL void GL_APIENTRY glFinish (void);
GL_APICALL void GL_APIENTRY glFlush (void);
GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
GL_APICALL GLenum GL_APIENTRY glGetError (void);
GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data);
GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name);
GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0);
GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0);
GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
#endif /* GL_ES_VERSION_2_0 */
#ifndef GL_ES_VERSION_3_0
#define GL_ES_VERSION_3_0 1
typedef unsigned short GLhalf;
#define GL_READ_BUFFER 0x0C02
#define GL_UNPACK_ROW_LENGTH 0x0CF2
#define GL_UNPACK_SKIP_ROWS 0x0CF3
#define GL_UNPACK_SKIP_PIXELS 0x0CF4
#define GL_PACK_ROW_LENGTH 0x0D02
#define GL_PACK_SKIP_ROWS 0x0D03
#define GL_PACK_SKIP_PIXELS 0x0D04
#define GL_COLOR 0x1800
#define GL_DEPTH 0x1801
#define GL_STENCIL 0x1802
#define GL_RED 0x1903
#define GL_RGB8 0x8051
#define GL_RGBA8 0x8058
#define GL_RGB10_A2 0x8059
#define GL_TEXTURE_BINDING_3D 0x806A
#define GL_UNPACK_SKIP_IMAGES 0x806D
#define GL_UNPACK_IMAGE_HEIGHT 0x806E
#define GL_TEXTURE_3D 0x806F
#define GL_TEXTURE_WRAP_R 0x8072
#define GL_MAX_3D_TEXTURE_SIZE 0x8073
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#define GL_MAX_ELEMENTS_VERTICES 0x80E8
#define GL_MAX_ELEMENTS_INDICES 0x80E9
#define GL_TEXTURE_MIN_LOD 0x813A
#define GL_TEXTURE_MAX_LOD 0x813B
#define GL_TEXTURE_BASE_LEVEL 0x813C
#define GL_TEXTURE_MAX_LEVEL 0x813D
#define GL_MIN 0x8007
#define GL_MAX 0x8008
#define GL_DEPTH_COMPONENT24 0x81A6
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
#define GL_TEXTURE_COMPARE_MODE 0x884C
#define GL_TEXTURE_COMPARE_FUNC 0x884D
#define GL_CURRENT_QUERY 0x8865
#define GL_QUERY_RESULT 0x8866
#define GL_QUERY_RESULT_AVAILABLE 0x8867
#define GL_BUFFER_MAPPED 0x88BC
#define GL_BUFFER_MAP_POINTER 0x88BD
#define GL_STREAM_READ 0x88E1
#define GL_STREAM_COPY 0x88E2
#define GL_STATIC_READ 0x88E5
#define GL_STATIC_COPY 0x88E6
#define GL_DYNAMIC_READ 0x88E9
#define GL_DYNAMIC_COPY 0x88EA
#define GL_MAX_DRAW_BUFFERS 0x8824
#define GL_DRAW_BUFFER0 0x8825
#define GL_DRAW_BUFFER1 0x8826
#define GL_DRAW_BUFFER2 0x8827
#define GL_DRAW_BUFFER3 0x8828
#define GL_DRAW_BUFFER4 0x8829
#define GL_DRAW_BUFFER5 0x882A
#define GL_DRAW_BUFFER6 0x882B
#define GL_DRAW_BUFFER7 0x882C
#define GL_DRAW_BUFFER8 0x882D
#define GL_DRAW_BUFFER9 0x882E
#define GL_DRAW_BUFFER10 0x882F
#define GL_DRAW_BUFFER11 0x8830
#define GL_DRAW_BUFFER12 0x8831
#define GL_DRAW_BUFFER13 0x8832
#define GL_DRAW_BUFFER14 0x8833
#define GL_DRAW_BUFFER15 0x8834
#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
#define GL_SAMPLER_3D 0x8B5F
#define GL_SAMPLER_2D_SHADOW 0x8B62
#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
#define GL_PIXEL_PACK_BUFFER 0x88EB
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
#define GL_FLOAT_MAT2x3 0x8B65
#define GL_FLOAT_MAT2x4 0x8B66
#define GL_FLOAT_MAT3x2 0x8B67
#define GL_FLOAT_MAT3x4 0x8B68
#define GL_FLOAT_MAT4x2 0x8B69
#define GL_FLOAT_MAT4x3 0x8B6A
#define GL_SRGB 0x8C40
#define GL_SRGB8 0x8C41
#define GL_SRGB8_ALPHA8 0x8C43
#define GL_COMPARE_REF_TO_TEXTURE 0x884E
#define GL_MAJOR_VERSION 0x821B
#define GL_MINOR_VERSION 0x821C
#define GL_NUM_EXTENSIONS 0x821D
#define GL_RGBA32F 0x8814
#define GL_RGB32F 0x8815
#define GL_RGBA16F 0x881A
#define GL_RGB16F 0x881B
#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
#define GL_MAX_VARYING_COMPONENTS 0x8B4B
#define GL_TEXTURE_2D_ARRAY 0x8C1A
#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
#define GL_R11F_G11F_B10F 0x8C3A
#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
#define GL_RGB9_E5 0x8C3D
#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
#define GL_RASTERIZER_DISCARD 0x8C89
#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
#define GL_INTERLEAVED_ATTRIBS 0x8C8C
#define GL_SEPARATE_ATTRIBS 0x8C8D
#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
#define GL_RGBA32UI 0x8D70
#define GL_RGB32UI 0x8D71
#define GL_RGBA16UI 0x8D76
#define GL_RGB16UI 0x8D77
#define GL_RGBA8UI 0x8D7C
#define GL_RGB8UI 0x8D7D
#define GL_RGBA32I 0x8D82
#define GL_RGB32I 0x8D83
#define GL_RGBA16I 0x8D88
#define GL_RGB16I 0x8D89
#define GL_RGBA8I 0x8D8E
#define GL_RGB8I 0x8D8F
#define GL_RED_INTEGER 0x8D94
#define GL_RGB_INTEGER 0x8D98
#define GL_RGBA_INTEGER 0x8D99
#define GL_SAMPLER_2D_ARRAY 0x8DC1
#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
#define GL_UNSIGNED_INT_VEC2 0x8DC6
#define GL_UNSIGNED_INT_VEC3 0x8DC7
#define GL_UNSIGNED_INT_VEC4 0x8DC8
#define GL_INT_SAMPLER_2D 0x8DCA
#define GL_INT_SAMPLER_3D 0x8DCB
#define GL_INT_SAMPLER_CUBE 0x8DCC
#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
#define GL_BUFFER_ACCESS_FLAGS 0x911F
#define GL_BUFFER_MAP_LENGTH 0x9120
#define GL_BUFFER_MAP_OFFSET 0x9121
#define GL_DEPTH_COMPONENT32F 0x8CAC
#define GL_DEPTH32F_STENCIL8 0x8CAD
#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
#define GL_FRAMEBUFFER_DEFAULT 0x8218
#define GL_FRAMEBUFFER_UNDEFINED 0x8219
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
#define GL_DEPTH_STENCIL 0x84F9
#define GL_UNSIGNED_INT_24_8 0x84FA
#define GL_DEPTH24_STENCIL8 0x88F0
#define GL_UNSIGNED_NORMALIZED 0x8C17
#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
#define GL_READ_FRAMEBUFFER 0x8CA8
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
#define GL_RENDERBUFFER_SAMPLES 0x8CAB
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
#define GL_COLOR_ATTACHMENT1 0x8CE1
#define GL_COLOR_ATTACHMENT2 0x8CE2
#define GL_COLOR_ATTACHMENT3 0x8CE3
#define GL_COLOR_ATTACHMENT4 0x8CE4
#define GL_COLOR_ATTACHMENT5 0x8CE5
#define GL_COLOR_ATTACHMENT6 0x8CE6
#define GL_COLOR_ATTACHMENT7 0x8CE7
#define GL_COLOR_ATTACHMENT8 0x8CE8
#define GL_COLOR_ATTACHMENT9 0x8CE9
#define GL_COLOR_ATTACHMENT10 0x8CEA
#define GL_COLOR_ATTACHMENT11 0x8CEB
#define GL_COLOR_ATTACHMENT12 0x8CEC
#define GL_COLOR_ATTACHMENT13 0x8CED
#define GL_COLOR_ATTACHMENT14 0x8CEE
#define GL_COLOR_ATTACHMENT15 0x8CEF
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
#define GL_MAX_SAMPLES 0x8D57
#define GL_HALF_FLOAT 0x140B
#define GL_MAP_READ_BIT 0x0001
#define GL_MAP_WRITE_BIT 0x0002
#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
#define GL_RG 0x8227
#define GL_RG_INTEGER 0x8228
#define GL_R8 0x8229
#define GL_RG8 0x822B
#define GL_R16F 0x822D
#define GL_R32F 0x822E
#define GL_RG16F 0x822F
#define GL_RG32F 0x8230
#define GL_R8I 0x8231
#define GL_R8UI 0x8232
#define GL_R16I 0x8233
#define GL_R16UI 0x8234
#define GL_R32I 0x8235
#define GL_R32UI 0x8236
#define GL_RG8I 0x8237
#define GL_RG8UI 0x8238
#define GL_RG16I 0x8239
#define GL_RG16UI 0x823A
#define GL_RG32I 0x823B
#define GL_RG32UI 0x823C
#define GL_VERTEX_ARRAY_BINDING 0x85B5
#define GL_R8_SNORM 0x8F94
#define GL_RG8_SNORM 0x8F95
#define GL_RGB8_SNORM 0x8F96
#define GL_RGBA8_SNORM 0x8F97
#define GL_SIGNED_NORMALIZED 0x8F9C
#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
#define GL_COPY_READ_BUFFER 0x8F36
#define GL_COPY_WRITE_BUFFER 0x8F37
#define GL_COPY_READ_BUFFER_BINDING 0x8F36
#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
#define GL_UNIFORM_BUFFER 0x8A11
#define GL_UNIFORM_BUFFER_BINDING 0x8A28
#define GL_UNIFORM_BUFFER_START 0x8A29
#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
#define GL_UNIFORM_TYPE 0x8A37
#define GL_UNIFORM_SIZE 0x8A38
#define GL_UNIFORM_NAME_LENGTH 0x8A39
#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
#define GL_UNIFORM_OFFSET 0x8A3B
#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
#define GL_INVALID_INDEX 0xFFFFFFFFu
#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
#define GL_OBJECT_TYPE 0x9112
#define GL_SYNC_CONDITION 0x9113
#define GL_SYNC_STATUS 0x9114
#define GL_SYNC_FLAGS 0x9115
#define GL_SYNC_FENCE 0x9116
#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
#define GL_UNSIGNALED 0x9118
#define GL_SIGNALED 0x9119
#define GL_ALREADY_SIGNALED 0x911A
#define GL_TIMEOUT_EXPIRED 0x911B
#define GL_CONDITION_SATISFIED 0x911C
#define GL_WAIT_FAILED 0x911D
#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
#define GL_ANY_SAMPLES_PASSED 0x8C2F
#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
#define GL_SAMPLER_BINDING 0x8919
#define GL_RGB10_A2UI 0x906F
#define GL_TEXTURE_SWIZZLE_R 0x8E42
#define GL_TEXTURE_SWIZZLE_G 0x8E43
#define GL_TEXTURE_SWIZZLE_B 0x8E44
#define GL_TEXTURE_SWIZZLE_A 0x8E45
#define GL_GREEN 0x1904
#define GL_BLUE 0x1905
#define GL_INT_2_10_10_10_REV 0x8D9F
#define GL_TRANSFORM_FEEDBACK 0x8E22
#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
#define GL_PROGRAM_BINARY_LENGTH 0x8741
#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
#define GL_PROGRAM_BINARY_FORMATS 0x87FF
#define GL_COMPRESSED_R11_EAC 0x9270
#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
#define GL_COMPRESSED_RG11_EAC 0x9272
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
#define GL_COMPRESSED_RGB8_ETC2 0x9274
#define GL_COMPRESSED_SRGB8_ETC2 0x9275
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
#define GL_MAX_ELEMENT_INDEX 0x8D6B
#define GL_NUM_SAMPLE_COUNTS 0x9380
#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
GL_APICALL void GL_APIENTRY glReadBuffer (GLenum mode);
GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
GL_APICALL void GL_APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint *ids);
GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);
GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id);
GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id);
GL_APICALL void GL_APIENTRY glEndQuery (GLenum target);
GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);
GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target);
GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params);
GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);
GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
GL_APICALL void *GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);
GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array);
GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array);
GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);
GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode);
GL_APICALL void GL_APIENTRY glEndTransformFeedback (void);
GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);
GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);
GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);
GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);
GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);
GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);
GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0);
GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);
GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);
GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);
GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);
GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);
GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);
GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);
GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);
GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);
GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
GL_APICALL const GLubyte *GL_APIENTRY glGetStringi (GLenum name, GLuint index);
GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);
GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags);
GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync);
GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync);
GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data);
GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);
GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);
GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler);
GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler);
GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);
GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);
GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);
GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);
GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);
GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);
GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id);
GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);
GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);
GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id);
GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void);
GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void);
GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);
GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments);
GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
#endif /* GL_ES_VERSION_3_0 */
#ifdef __cplusplus
}
#endif
#endif
+30
View File
@@ -0,0 +1,30 @@
#ifndef __gl3platform_h_
#define __gl3platform_h_
/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */
/*
* This document is licensed under the SGI Free Software B License Version
* 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
*/
/* Platform-specific types and definitions for OpenGL ES 3.X gl3.h
*
* Adopters may modify khrplatform.h and this file to suit their platform.
* You are encouraged to submit all modifications to the Khronos group so that
* they can be included in future versions of this file. Please submit changes
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
* by filing a bug against product "OpenGL-ES" component "Registry".
*/
#include <KHR/khrplatform.h>
#ifndef GL_APICALL
#define GL_APICALL KHRONOS_APICALL
#endif
#ifndef GL_APIENTRY
#define GL_APIENTRY KHRONOS_APIENTRY
#endif
#endif /* __gl3platform_h_ */
+37 -24
View File
@@ -2,31 +2,31 @@
#define __khrplatform_h_
/*
** Copyright (c) 2008-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
** Copyright (c) 2008-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
* $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
@@ -112,7 +112,7 @@
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
@@ -221,10 +221,23 @@ typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
@@ -266,4 +279,4 @@ typedef enum {
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */
#endif /* __khrplatform_h_ */
+5
View File
@@ -26,6 +26,8 @@
#if !defined(ANDROID)
#include <linux/joystick.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
#ifdef TARGET_PANDORA
@@ -717,3 +719,6 @@ u32 os_Push(void* frame, u32 samples, bool wait)
return 1;
}
#endif
int get_mic_data(u8* buffer) { return 0; }
int push_vmu_screen(u8* buffer) { return 0; }
+43
View File
@@ -34,9 +34,21 @@ struct sigcontext uc_mcontext;
#if HOST_CPU == CPU_ARM
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.arm_pc)
#elif HOST_CPU == CPU_MIPS
#ifdef _ANDROID
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.sc_pc)
#else
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.pc)
#endif
#elif HOST_CPU == CPU_X86
#ifdef _ANDROID
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.eip)
#else
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EIP])
#endif
#else
#error fix ->pc support
#endif
#include "hw/sh4/dyna/ngen.h"
@@ -155,12 +167,43 @@ void VArray2::LockRegion(u32 offset,u32 size)
}
}
void print_mem_addr()
{
FILE *ifp, *ofp;
char *mode = "r";
char outputFilename[] = "/data/data/com.reicast.emulator/files/mem_alloc.txt";
ifp = fopen("/proc/self/maps", mode);
if (ifp == NULL) {
fprintf(stderr, "Can't open input file /proc/self/maps!\n");
exit(1);
}
ofp = fopen(outputFilename, "w");
if (ofp == NULL) {
fprintf(stderr, "Can't open output file %s!\n",
outputFilename);
exit(1);
}
char line [ 512 ];
while (fgets(line, sizeof line, ifp) != NULL) {
fprintf(ofp, "%s", line);
}
fclose(ifp);
fclose(ofp);
}
void VArray2::UnLockRegion(u32 offset,u32 size)
{
u32 inpage=offset & PAGE_MASK;
u32 rv=mprotect (data+offset-inpage, size+inpage, PROT_READ | PROT_WRITE);
if (rv!=0)
{
print_mem_addr();
printf("mprotect(%08X,%08X,RW) failed: %d | %d\n",data+offset-inpage,size+inpage,rv,errno);
die("mprotect failed ..\n");
}
+15 -2
View File
@@ -58,11 +58,21 @@ typedef struct ucontext_t
#if HOST_CPU == CPU_ARM
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.arm_pc)
#elif HOST_CPU == CPU_MIPS
#ifdef _ANDROID
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.sc_pc)
#else
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.pc)
#endif
#elif HOST_CPU == CPU_X86
#ifdef _ANDROID
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.eip)
#else
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EIP])
#endif
#else
#error fix ->pc support
#endif
/**
@file CallStack_Android.h
@@ -275,7 +285,10 @@ void* prof(void *ptr)
//Write shrec syms file !
prof_head(prof_out, "jitsym", "SH4");
#if !defined(HOST_NO_REC)
sh4_jitsym(prof_out);
#endif
//Write arm7rec syms file ! -> to do
//prof_head(prof_out,"jitsym","ARM7");
+23 -5
View File
@@ -12,6 +12,8 @@
#include "hw/maple/maple_cfg.h"
#include "hw/sh4/sh4_mem.h"
#include "webui/server.h"
settings_t settings;
/*
@@ -41,7 +43,7 @@ int GetFile(char *szFileName, char *szParse=0,u32 flags=0)
if (strcmp(szFileName,"null")==0)
{
#if defined(OMAP4)
strcpy(szFileName,GetPath("gdimage/crazy_taxi.chd").c_str());
strcpy(szFileName,GetPath("/gdimage/crazy_taxi.chd").c_str());
#else
#if HOST_OS==OS_WINDOWS
OPENFILENAME ofn;
@@ -64,7 +66,7 @@ int GetFile(char *szFileName, char *szParse=0,u32 flags=0)
//strcpy(szFileName,ofn.lpstrFile);
}
#else
strcpy(szFileName,GetPath("discs/game.gdi").c_str());
strcpy(szFileName,GetPath("/discs/game.gdi").c_str());
#endif
#endif
}
@@ -127,6 +129,17 @@ void plugins_Reset(bool Manual)
}
void* webui_th(void* p)
{
#if (HOST_OS == OS_WINDOWS || HOST_OS == OS_LINUX) && !defined(TARGET_PANDORA)
webui_start();
#endif
return 0;
}
cThread webui_thd(&webui_th,0);
int dc_init(int argc,wchar* argv[])
{
setbuf(stdin,0);
@@ -138,18 +151,18 @@ int dc_init(int argc,wchar* argv[])
return -1;
}
webui_thd.Start();
if(ParseCommandLine(argc,argv))
{
return 69;
}
if(!cfgOpen())
{
msgboxf("Unable to open config file",MBX_ICONERROR);
return -4;
}
LoadSettings();
#ifndef _ANDROID
os_CreateWindow();
#endif
@@ -207,21 +220,25 @@ void dc_term()
plugins_Term();
_vmem_release();
#ifndef _ANDROID
SaveSettings();
#endif
SaveRomFiles(GetPath("/data/"));
}
void LoadSettings()
{
#ifndef _ANDROID
settings.dynarec.Enable = cfgLoadInt("config","Dynarec.Enabled", 1)!=0;
settings.dynarec.idleskip = cfgLoadInt("config","Dynarec.idleskip",1)!=0;
settings.dynarec.unstable_opt = cfgLoadInt("config","Dynarec.unstable-opt",0);
settings.dreamcast.cable = cfgLoadInt("config","Dreamcast.Cable", 3);
settings.dreamcast.cable = cfgLoadInt("config","Dreamcast.Cable",3);
settings.dreamcast.RTC = cfgLoadInt("config","Dreamcast.RTC",GetRTC_now());
settings.dreamcast.region = cfgLoadInt("config","Dreamcast.Region",3);
settings.dreamcast.broadcast = cfgLoadInt("config","Dreamcast.Broadcast",4);
settings.aica.LimitFPS = cfgLoadInt("config","aica.LimitFPS",1);
settings.aica.NoBatch = cfgLoadInt("config","aica.NoBatch",0);
settings.aica.NoSound = cfgLoadInt("config","aica.NoSound",0);
settings.rend.UseMipmaps = cfgLoadInt("config","rend.UseMipmaps",1);
settings.rend.WideScreen = cfgLoadInt("config","rend.WideScreen",0);
@@ -229,6 +246,7 @@ void LoadSettings()
settings.pvr.ta_skip = cfgLoadInt("config","ta.skip",0);
settings.pvr.rend = cfgLoadInt("config","pvr.rend",0);
#endif
#if (HOST_OS != OS_LINUX || defined(_ANDROID) || defined(TARGET_PANDORA))
settings.aica.BufferSize=2048;
+3 -1
View File
@@ -28,4 +28,6 @@ u32 INLINE bitscanrev(u32 v)
}
//FIX ME
#define __assume(x)
#define __assume(x)
void os_DebugBreak();
+19
View File
@@ -41,7 +41,11 @@ MOV R1, #1
B _Z8YUV_dataPjj
TAWriteSQ_vram: @vram write ..
#ifdef TARGET_IPHONE
bkpt #0
#else
bkpt
#endif
ubfx r0,r3,#5,#18 @ get vram offset
add r3,r1,#0x04000000 @ get vram ptr from r1, part 1
add r3,#512 @ get ram ptr from r1, part 2
@@ -157,13 +161,23 @@ arm_compilecode:
bl CompileCode
b arm_dispatch
#ifdef TARGET_IPHONE
Xarm_Reg: .word arm_Reg
XEntryPoints: .word EntryPoints
#endif
.global arm_mainloop
arm_mainloop: @(cntx,lookup_base,cycles)
push {r4,r5,r8,r9,lr}
#ifdef TARGET_IPHONE
ldr r8,Xarm_Reg @load cntx
ldr r4,XEntryPoints @load lookup base
#else
ldr r8,=arm_Reg @load cntx
ldr r4,=EntryPoints @load lookup base
#endif
ldr r5,[r8,#192] @load cycle count
add r5,r0 @add cycles for this timeslice
@@ -172,7 +186,12 @@ push {r4,r5,r8,r9,lr}
.global arm_dispatch
arm_dispatch:
#ifdef TARGET_IPHONE
ldrd r0,r1,[r8,#184] @load: Next PC, interrupt
#else
ldrd r0,[r8,#184] @load: Next PC, interrupt
#endif
ubfx r2,r0,#2,#19
cmp r1,#0
bne arm_dofiq
+5
View File
@@ -76,6 +76,11 @@ struct d3d11 : Renderer
void Resize(int w, int h) { }
void Term() { }
bool Process(TA_context* ctx)
{
return true;
}
bool Render()
{
if (!pvrrc.isRTT)
+30 -28
View File
@@ -81,11 +81,11 @@ u32 gcflip;
static struct
{
TSP tsp;
TCW tcw;
//TCW tcw;
PCW pcw;
ISP_TSP isp;
u32 clipmode;
u32 texture_enabled;
//u32 texture_enabled;
u32 stencil_modvol_on;
u32 program;
GLuint texture;
@@ -95,11 +95,11 @@ static struct
program=~0;
texture=~0;
tsp.full = ~gp->tsp.full;
tcw.full = ~gp->tcw.full;
//tcw.full = ~gp->tcw.full;
pcw.full = ~gp->pcw.full;
isp.full = ~gp->isp.full;
clipmode=0xFFFFFFFF;
texture_enabled=~gp->pcw.Texture;
// texture_enabled=~gp->pcw.Texture;
stencil_modvol_on=false;
}
} cache;
@@ -194,36 +194,29 @@ __forceinline
glStencilFunc(GL_ALWAYS,stencil,stencil);
}
if ((gp->tcw.full != cache.tcw.full) || (gp->tsp.full!=cache.tsp.full) || (cache.texture_enabled!= gp->pcw.Texture))
if (gp->texid != cache.texture)
{
cache.tcw=gp->tcw;
cache.texture_enabled = gp->pcw.Texture;
if (gp->pcw.Texture)
{
GLuint tex=GetTexture(gp->tsp,gp->tcw);
if (tex!=cache.texture)
{
glBindTexture(GL_TEXTURE_2D,tex);
cache.texture=tex;
}
cache.texture=gp->texid;
if (gp->texid != -1) {
//verify(glIsTexture(gp->texid));
glBindTexture(GL_TEXTURE_2D, gp->texid);
}
}
if (gp->tsp.full!=cache.tsp.full)
if (gp->tsp.full!=cache.tsp.full)
{
cache.tsp=gp->tsp;
if (Type==ListType_Translucent)
{
cache.tsp=gp->tsp;
if (Type==ListType_Translucent)
{
glBlendFunc(SrcBlendGL[gp->tsp.SrcInstr],DstBlendGL[gp->tsp.DstInstr]);
glBlendFunc(SrcBlendGL[gp->tsp.SrcInstr],DstBlendGL[gp->tsp.DstInstr]);
#ifdef WEIRD_SLOWNESS
//SGX seems to be super slow with discard enabled blended pixels
//can't cache this -- due to opengl shader api
bool clip_alpha_on_zero=gp->tsp.SrcInstr==4 && (gp->tsp.DstInstr==1 || gp->tsp.DstInstr==5);
glUniform1f(CurrentShader->cp_AlphaTestValue,clip_alpha_on_zero?(1/255.f):(-2.f));
//SGX seems to be super slow with discard enabled blended pixels
//can't cache this -- due to opengl shader api
bool clip_alpha_on_zero=gp->tsp.SrcInstr==4 && (gp->tsp.DstInstr==1 || gp->tsp.DstInstr==5);
glUniform1f(CurrentShader->cp_AlphaTestValue,clip_alpha_on_zero?(1/255.f):(-2.f));
#endif
}
}
}
@@ -720,7 +713,7 @@ void GenSorted()
if (idx!=pid /* && !PP_EQ(&pp_base[pid],&pp_base[idx]) */ )
{
SortTrigDrawParam stdp={pp_base + pid, i*3, 0};
SortTrigDrawParam stdp={pp_base + pid, (u16)(i*3), 0};
if (idx!=-1)
{
@@ -911,8 +904,13 @@ void SetMVS_Mode(u32 mv_mode,ISP_Modvol ispc)
}
}
void SetupMainVBO()
{
#ifndef GLES
glBindVertexArray(gl.vbo.vao);
#endif
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.geometry); glCheck();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs); glCheck();
@@ -932,6 +930,10 @@ void SetupMainVBO()
void SetupModvolVBO()
{
#ifndef GLES
glBindVertexArray(gl.vbo.vao);
#endif
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.modvols); glCheck();
//setup vertex buffers attrib pointers
+417 -55
View File
@@ -15,6 +15,11 @@
int fbdev = -1;
#endif
#ifndef GLES
#include <GL3/gl3w.c>
#pragma comment(lib,"Opengl32.lib")
#endif
/*
GL|ES 2
Slower, smaller subset of gl2
@@ -57,25 +62,36 @@ float fb_scale_x,fb_scale_y;
volatile bool render_restart = false;
#ifndef GLES
#define attr "in"
#define vary "out"
#else
#define attr "attribute"
#define vary "varying"
#endif
#if 1
//Fragment and vertex shaders code
//pretty much 1:1 copy of the d3d ones for now
const char* VertexShaderSource = "\
const char* VertexShaderSource =
#ifndef GLES
"#version 140 \n"
#endif
"\
/* Vertex constants*/ \n\
uniform highp vec4 scale; \n\
uniform highp vec4 depth_scale; \n\
uniform highp float sp_FOG_DENSITY; \n\
/* Vertex output */ \n\
attribute highp vec4 in_pos; \n\
attribute lowp vec4 in_base; \n\
attribute lowp vec4 in_offs; \n\
attribute mediump vec2 in_uv; \n\
/* Transformed input */ \n\
varying lowp vec4 vtx_base; \n\
varying lowp vec4 vtx_offs; \n\
varying mediump vec2 vtx_uv; \n\
varying highp vec3 vtx_xyz; \n\
/* Vertex input */ \n\
" attr " highp vec4 in_pos; \n\
" attr " lowp vec4 in_base; \n\
" attr " lowp vec4 in_offs; \n\
" attr " mediump vec2 in_uv; \n\
/* output */ \n\
" vary " lowp vec4 vtx_base; \n\
" vary " lowp vec4 vtx_offs; \n\
" vary " mediump vec2 vtx_uv; \n\
" vary " highp vec3 vtx_xyz; \n\
void main() \n\
{ \n\
vtx_base=in_base; \n\
@@ -199,7 +215,22 @@ lowp float fog_mode2(highp float invW) \n\
} \n\
*/
const char* PixelPipelineShader = "\
#ifndef GLES
#define FRAGCOL "FragColor"
#define TEXLOOKUP "texture"
#define vary "in"
#else
#define FRAGCOL "gl_FragColor"
#define TEXLOOKUP "texture2D"
#endif
const char* PixelPipelineShader =
#ifndef GLES
"#version 140 \n"
"out vec4 FragColor; \n"
#endif
"\
\
#define cp_AlphaTest %d \n\
#define pp_ClipTestMode %d.0 \n\
@@ -217,10 +248,10 @@ uniform lowp vec3 sp_FOG_COL_RAM,sp_FOG_COL_VERT; \n\
uniform highp vec2 sp_LOG_FOG_COEFS; \n\
uniform sampler2D tex,fog_table; \n\
/* Vertex input*/ \n\
varying lowp vec4 vtx_base; \n\
varying lowp vec4 vtx_offs; \n\
varying mediump vec2 vtx_uv; \n\
varying highp vec3 vtx_xyz; \n\
" vary " lowp vec4 vtx_base; \n\
" vary " lowp vec4 vtx_offs; \n\
" vary " mediump vec2 vtx_uv; \n\
" vary " highp vec3 vtx_xyz; \n\
lowp float fog_mode2(highp float val) \n\
{ \n\
highp float fog_idx=clamp(val,0.0,127.99); \n\
@@ -237,7 +268,7 @@ void main() \n\
#endif\n\
#if pp_Texture==1 \n\
{ \n\
lowp vec4 texcol=texture2D(tex,vtx_uv); \n\
lowp vec4 texcol=" TEXLOOKUP "(tex,vtx_uv); \n\
\n\
#if pp_IgnoreTexA==1 \n\
texcol.a=1.0; \n\
@@ -284,27 +315,37 @@ void main() \n\
if (cp_AlphaTestValue>color.a) discard;\n\
#endif \n\
//color.rgb=vec3(vtx_xyz.z/255.0);\n\
gl_FragColor=color; \n\
" FRAGCOL "=color; \n\
}";
const char* ModifierVolumeShader = " \
const char* ModifierVolumeShader =
#ifndef GLES
"#version 140 \n"
"out vec4 FragColor; \n"
#endif
" \
uniform lowp float sp_ShaderColor; \n\
/* Vertex input*/ \n\
void main() \n\
{ \n\
gl_FragColor=vec4(0.0, 0.0, 0.0, sp_ShaderColor); \n\
" FRAGCOL "=vec4(0.0, 0.0, 0.0, sp_ShaderColor); \n\
}";
const char* OSD_Shader = " \
varying lowp vec4 vtx_base; \n\
varying mediump vec2 vtx_uv; \n\
const char* OSD_Shader =
#ifndef GLES
"#version 140 \n"
"out vec4 FragColor; \n"
#endif
" \
" vary " lowp vec4 vtx_base; \n\
" vary " mediump vec2 vtx_uv; \n\
/* Vertex input*/ \n\
uniform sampler2D tex; \n\
void main() \n\
{ \n\
mediump vec2 uv=vtx_uv; \n\
uv.y=1.0-uv.y; \n\
gl_FragColor=vtx_base*texture2D(tex,uv); \n\n\
" FRAGCOL "=vtx_base*" TEXLOOKUP "(tex,uv.st); \n\n\
}";
@@ -313,12 +354,13 @@ gl_ctx gl;
int screen_width;
int screen_height;
#ifdef GLES
// Create a basic GLES context
bool gl_init(EGLNativeWindowType wind, EGLNativeDisplayType disp)
bool gl_init(void* wind, void* disp)
{
#if !defined(_ANDROID)
gl.setup.native_wind=wind;
gl.setup.native_disp=disp;
gl.setup.native_wind=(EGLNativeWindowType)wind;
gl.setup.native_disp=(EGLNativeDisplayType)disp;
//try to get a display
gl.setup.display = eglGetDisplay(gl.setup.native_disp);
@@ -427,6 +469,135 @@ void gl_term()
gl.setup.display=0;
#endif
}
#else
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_SWAP_METHOD_ARB 0x2007
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_SWAP_EXCHANGE_ARB 0x2028
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define ERROR_INVALID_VERSION_ARB 0x2095
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats,
int *piFormats, UINT *nNumFormats);
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
HDC ourWindowHandleToDeviceContext;
bool gl_init(void* hwnd, void* hdc)
{
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags
PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette.
32, //Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, //Number of bits for the depthbuffer
8, //Number of bits for the stencilbuffer
0, //Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
/*HDC*/ ourWindowHandleToDeviceContext = (HDC)hdc;//GetDC((HWND)hwnd);
int letWindowsChooseThisPixelFormat;
letWindowsChooseThisPixelFormat = ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd);
SetPixelFormat(ourWindowHandleToDeviceContext,letWindowsChooseThisPixelFormat, &pfd);
HGLRC ourOpenGLRenderingContext = wglCreateContext(ourWindowHandleToDeviceContext);
wglMakeCurrent (ourWindowHandleToDeviceContext, ourOpenGLRenderingContext);
bool rv = true;
if (rv) {
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
if(!wglChoosePixelFormatARB)
{
return false;
}
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
if(!wglCreateContextAttribsARB)
{
return false;
}
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
if(!wglSwapIntervalEXT)
{
return false;
}
int attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 1,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
};
HGLRC m_hrc = wglCreateContextAttribsARB(ourWindowHandleToDeviceContext,0, attribs);
if (m_hrc)
wglMakeCurrent(ourWindowHandleToDeviceContext,m_hrc);
else
rv = false;
wglDeleteContext(ourOpenGLRenderingContext);
}
if (rv) {
rv = gl3wInit() != -1 && gl3wIsSupported(3, 1);
}
RECT r;
GetClientRect((HWND)hwnd, &r);
screen_width = r.right - r.left;
screen_height = r.bottom - r.top;
return rv;
}
#include <Wingdi.h>
void gl_swap()
{
wglSwapLayerBuffers(ourWindowHandleToDeviceContext,WGL_SWAP_MAIN_PLANE);
//SwapBuffers(ourWindowHandleToDeviceContext);
}
#endif
struct ShaderUniforms_t
@@ -509,6 +680,10 @@ GLuint gl_CompileAndLink(const char* VertexShader, const char* FragmentShader)
glBindAttribLocation(program, VERTEX_COL_OFFS_ARRAY, "in_offs");
glBindAttribLocation(program, VERTEX_UV_ARRAY, "in_uv");
#ifndef GLES
glBindFragDataLocation(program, 0, "FragColor");
#endif
glLinkProgram(program);
GLint result;
@@ -610,9 +785,20 @@ bool CompilePipelineShader( PipelineShader* s)
}
GLuint osd_tex;
#ifdef TARGET_PANDORA
GLuint osd_font;
#endif
bool gl_create_resources()
{
#ifndef GLES
//create vao
//This is really not "proper", vaos are suposed to be defined once
//i keep updating the same one to make the es2 code work in 3.1 context
glGenVertexArrays(1, &gl.vbo.vao);
#endif
//create vbos
glGenBuffers(1, &gl.vbo.geometry);
glGenBuffers(1, &gl.vbo.modvols);
@@ -686,12 +872,14 @@ bool gl_create_resources()
int w, h;
osd_tex=loadPNG(GetPath("/data/buttons.png"),w,h);
#ifdef TARGET_PANDORA
osd_font=loadPNG(GetPath("/font2.png"),w,h);
#endif
return true;
}
//create a basic gles context
bool gl_init(EGLNativeWindowType wind, EGLNativeDisplayType disp);
bool gl_init(void* wind, void* disp);
//swap buffers
void gl_swap();
@@ -707,19 +895,21 @@ bool gl_create_resources();
bool gles_init()
{
if (!gl_init((EGLNativeWindowType)libPvr_GetRenderTarget(),
(EGLNativeDisplayType)libPvr_GetRenderSurface()))
if (!gl_init((void*)libPvr_GetRenderTarget(),
(void*)libPvr_GetRenderSurface()))
return false;
if (!gl_create_resources())
return false;
#ifdef GLES
#ifdef TARGET_PANDORA
fbdev=open("/dev/fb0", O_RDONLY);
#else
eglSwapInterval(gl.setup.display,1);
#endif
#endif
//clean up all buffers ...
for (int i=0;i<10;i++)
@@ -897,12 +1087,120 @@ static void ClearBG()
void DrawButton2(float* xy, bool state) { DrawButton(xy,state?0:255); }
#ifdef TARGET_PANDORA
static void DrawCenteredText(float yy, float scale, int transparency, const char* text)
// Draw a centered text. Font is loaded from font2.png file. Each char is 16*16 size, so scale it down so it's not too big
// Transparency 255=opaque, 0=not visible
{
Vertex vtx;
vtx.z=1;
float w=float(strlen(text)*14)*scale;
float x=320-w/2.0f;
float y=yy;
float h=16.0f*scale;
w=14.0f*scale;
float step=32.0f/512.0f;
float step2=4.0f/512.0f;
if (transparency<0) transparency=0;
if (transparency>255) transparency=255;
for (int i=0; i<strlen(text); i++) {
int c=text[i];
float u=float(c%16);
float v=float(c/16);
vtx.col[0]=vtx.col[1]=vtx.col[2]=255;
vtx.col[3]=transparency;
vtx.x=x; vtx.y=y;
vtx.u=u*step+step2; vtx.v=v*step+step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x+w; vtx.y=y;
vtx.u=u*step+step-step2; vtx.v=v*step+step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x; vtx.y=y+h;
vtx.u=u*step+step2; vtx.v=v*step+step-step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x+w; vtx.y=y+h;
vtx.u=u*step+step-step2; vtx.v=v*step+step-step2;
*pvrrc.verts.Append()=vtx;
x+=w;
osd_count+=4;
}
}
static void DrawRightedText(float yy, float scale, int transparency, const char* text)
// Draw a text right justified. Font is loaded from font2.png file. Each char is 16*16 size, so scale it down so it's not too big
// Transparency 255=opaque, 0=not visible
{
Vertex vtx;
vtx.z=1;
float w=float(strlen(text)*14)*scale;
float x=640-w;
float y=yy;
float h=16.0f*scale;
w=14.0f*scale;
float step=32.0f/512.0f;
float step2=4.0f/512.0f;
if (transparency<0) transparency=0;
if (transparency>255) transparency=255;
for (int i=0; i<strlen(text); i++) {
int c=text[i];
float u=float(c%16);
float v=float(c/16);
vtx.col[0]=vtx.col[1]=vtx.col[2]=255;
vtx.col[3]=transparency;
vtx.x=x; vtx.y=y;
vtx.u=u*step+step2; vtx.v=v*step+step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x+w; vtx.y=y;
vtx.u=u*step+step-step2; vtx.v=v*step+step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x; vtx.y=y+h;
vtx.u=u*step+step2; vtx.v=v*step+step-step2;
*pvrrc.verts.Append()=vtx;
vtx.x=x+w; vtx.y=y+h;
vtx.u=u*step+step-step2; vtx.v=v*step+step-step2;
*pvrrc.verts.Append()=vtx;
x+=w;
osd_count+=4;
}
}
#endif
#ifdef TARGET_PANDORA
char OSD_Info[128];
int OSD_Delay=0;
char OSD_Counters[256];
int OSD_Counter=0;
#endif
static void OSD_HOOK()
{
osd_base=pvrrc.verts.used();
osd_count=0;
#ifndef TARGET_PANDORA
DrawButton2(vjoy_pos[0],kcode[0]&key_CONT_DPAD_LEFT);
DrawButton2(vjoy_pos[1],kcode[0]&key_CONT_DPAD_UP);
DrawButton2(vjoy_pos[2],kcode[0]&key_CONT_DPAD_RIGHT);
@@ -921,15 +1219,29 @@ static void OSD_HOOK()
DrawButton2(vjoy_pos[11],1);
DrawButton2(vjoy_pos[12],0);
#endif
#ifdef TARGET_PANDORA
if (OSD_Delay) {
DrawCenteredText(400, 1.0f, (OSD_Delay<255)?OSD_Delay:255, OSD_Info);
OSD_Delay--; //*TODO* Delay should be in ms, not in ticks...
}
if (OSD_Counter) {
DrawRightedText(20, 1.0f, 255, OSD_Counters);
}
#endif
}
extern GLuint osd_tex;
#ifdef TARGET_PANDORA
extern GLuint osd_font;
#endif
#define OSD_TEX_W 512
#define OSD_TEX_H 256
void OSD_DRAW()
{
#ifndef TARGET_PANDORA
if (osd_tex)
{
float u=0;
@@ -959,7 +1271,7 @@ void OSD_DRAW()
glUseProgram(gl.OSD_SHADER.program);
//reset rendering scale
/*
float dc_width=640;
float dc_height=480;
@@ -973,7 +1285,7 @@ void OSD_DRAW()
ShaderUniforms.scale_coefs[3]=-1;
glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
*/
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
@@ -990,21 +1302,78 @@ void OSD_DRAW()
for (int i=0;i<dfa;i++)
glDrawArrays(GL_TRIANGLE_STRIP,osd_base+i*4,4);
}
#endif
#ifdef TARGET_PANDORA
if (osd_font)
{
float u=0;
float v=0;
verify(glIsProgram(gl.OSD_SHADER.program));
float dc_width=640;
float dc_height=480;
float dc2s_scale_h=screen_height/480.0f;
float ds2s_offs_x=(screen_width-dc2s_scale_h*640)/2;
glBindTexture(GL_TEXTURE_2D,osd_font);
glUseProgram(gl.OSD_SHADER.program);
/*
//-1 -> too much to left
ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h);
ShaderUniforms.scale_coefs[1]=-2/dc_height;
ShaderUniforms.scale_coefs[2]=1-2*ds2s_offs_x/(screen_width);
ShaderUniforms.scale_coefs[3]=-1;
glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
*/
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
glDepthFunc(GL_ALWAYS);
glDisable(GL_CULL_FACE);
glDisable(GL_SCISSOR_TEST);
int dfa=osd_count/4;
for (int i=0;i<dfa;i++)
glDrawArrays(GL_TRIANGLE_STRIP,osd_base+i*4,4);
}
#endif
}
bool ProcessFrame(TA_context* ctx)
{
//disable RTTs for now ..
if (ctx->rend.isRTT)
return false;
ctx->rend_inuse.Lock();
ctx->MarkRend();
if (!ta_parse_vdrc(ctx))
return false;
CollectCleanup();
return true;
}
bool RenderFrame()
{
bool is_rtt=pvrrc.isRTT;//(FB_W_SOF1& 0x1000000)!=0;
DoCleanup();
//disable RTTs for now ..
if (is_rtt)
return false;
_pvrrc->rend_inuse.Lock();
_pvrrc->MarkRend();
if (!ta_parse_vdrc(_pvrrc))
return false;
bool is_rtt=pvrrc.isRTT;
OSD_HOOK();
@@ -1405,19 +1774,12 @@ struct glesrend : Renderer
void Resize(int w, int h) { }
void Term() { }
bool Render()
{
bool do_swp=RenderFrame();
if (do_swp)
{
OSD_DRAW();
}
return do_swp;
}
bool Process(TA_context* ctx) { return ProcessFrame(ctx); }
bool Render() { return RenderFrame(); }
void Present() { gl_swap(); }
void DrawOSD() { OSD_DRAW(); }
};
Regular → Executable
+23 -6
View File
@@ -1,9 +1,17 @@
#pragma once
#include "rend/rend.h"
#ifdef GLES
#ifdef TARGET_IPHONE //apple-specific ogles2 headers
#include <APPLE/egl.h>
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#else
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#endif
#ifndef GL_NV_draw_path
//IMGTEC GLES emulation
@@ -11,9 +19,14 @@
#pragma comment(lib,"libGLESv2.lib")
#else /* NV gles emulation*/
#pragma comment(lib,"libGLES20.lib")
#endif
#define glCheck() false
#else
#include <GL3/gl3w.h>
#endif
#define glCheck() verify(glGetError()==GL_NO_ERROR)
#define eglCheck() false
#define VERTEX_POS_ARRAY 0
@@ -21,10 +34,6 @@
#define VERTEX_COL_OFFS_ARRAY 2
#define VERTEX_UV_ARRAY 3
#ifdef TARGET_PANDORA
#define WEIRD_SLOWNESS
#endif
//vertex types
extern u32 gcflip;
@@ -48,6 +57,7 @@ struct PipelineShader
struct gl_ctx
{
#ifdef GLES
struct
{
EGLNativeWindowType native_wind;
@@ -56,6 +66,7 @@ struct gl_ctx
EGLSurface surface;
EGLContext context;
} setup;
#endif
struct
{
@@ -75,6 +86,9 @@ struct gl_ctx
struct
{
GLuint geometry,modvols,idxs,idxs2;
#ifndef GLES
GLuint vao;
#endif
} vbo;
@@ -84,6 +98,9 @@ struct gl_ctx
extern gl_ctx gl;
GLuint GetTexture(TSP tsp,TCW tcw);
void CollectCleanup();
void DoCleanup();
void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt);
int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode,
u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset,
+36 -4
View File
@@ -78,7 +78,7 @@ struct TextureCacheData
PvrTexInfo* tex;
TexConvFP* texconv;
bool dirty;
u32 dirty;
vram_block* lock_block;
u32 Lookups;
@@ -128,7 +128,7 @@ struct TextureCacheData
//Reset state info ..
Lookups=0;
Updates=0;
dirty=true;
dirty=FrameCount;
lock_block=0;
//decode info from tsp/tcw into the texture struct
@@ -145,7 +145,9 @@ struct TextureCacheData
SetRepeatMode(GL_TEXTURE_WRAP_S,tsp.ClampU,tsp.FlipU); // glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (tsp.ClampU ? GL_CLAMP_TO_EDGE : (tsp.FlipU ? GL_MIRRORED_REPEAT : GL_REPEAT))) ;
SetRepeatMode(GL_TEXTURE_WRAP_T,tsp.ClampV,tsp.FlipV); // glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (tsp.ClampV ? GL_CLAMP_TO_EDGE : (tsp.FlipV ? GL_MIRRORED_REPEAT : GL_REPEAT))) ;
#ifdef GLES
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
#endif
//set texture filter mode
if ( tsp.FilterMode == 0 )
@@ -242,7 +244,7 @@ struct TextureCacheData
{
//texture state tracking stuff
Updates++;
dirty=false;
dirty=0;
GLuint textype=tex->type;
@@ -344,7 +346,11 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
m_i32TexSize by m_i32TexSize.
*/
#ifdef GLES
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, fbw, fbh);
#else
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbw, fbh);
#endif
glGenRenderbuffers(1, &rv.stencilb);
glBindRenderbuffer(GL_RENDERBUFFER, rv.stencilb);
@@ -419,6 +425,32 @@ GLuint GetTexture(TSP tsp,TCW tcw)
return tf->texID;
}
void CollectCleanup() {
vector<u64> list;
u32 TargetFrame = max((u32)120,FrameCount) - 120;
for (TexCacheIter i=TexCache.begin();i!=TexCache.end();i++)
{
if ( i->second.dirty && i->second.dirty < TargetFrame) {
list.push_back(i->first);
}
if (list.size() > 5)
break;
}
for (size_t i=0; i<list.size(); i++) {
//printf("Deleting %d\n",TexCache[list[i]].texID);
TexCache[list[i]].Delete();
TexCache.erase(list[i]);
}
}
void DoCleanup() {
}
void killtex()
{
for (TexCacheIter i=TexCache.begin();i!=TexCache.end();i++)
@@ -432,7 +464,7 @@ void killtex()
void rend_text_invl(vram_block* bl)
{
TextureCacheData* tcd = (TextureCacheData*)bl->userdata;
tcd->dirty=true;
tcd->dirty=FrameCount;
tcd->lock_block=0;
libCore_vramlock_Unlock_block_wb(bl);
Loaded 100 of 332 files, more files were not shown because too many files have changed in this diff. Show more