app.odin 87 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233
  1. // machine generated, do not edit
  2. package sokol_app
  3. /*
  4. sokol_app.h -- cross-platform application wrapper
  5. Project URL: https://github.com/floooh/sokol
  6. Do this:
  7. #define SOKOL_IMPL or
  8. #define SOKOL_APP_IMPL
  9. before you include this file in *one* C or C++ file to create the
  10. implementation.
  11. In the same place define one of the following to select the 3D-API
  12. which should be initialized by sokol_app.h (this must also match
  13. the backend selected for sokol_gfx.h if both are used in the same
  14. project):
  15. #define SOKOL_GLCORE
  16. #define SOKOL_GLES3
  17. #define SOKOL_D3D11
  18. #define SOKOL_METAL
  19. #define SOKOL_WGPU
  20. #define SOKOL_NOAPI
  21. Optionally provide the following defines with your own implementations:
  22. SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
  23. SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
  24. SOKOL_WIN32_FORCE_MAIN - define this on Win32 to add a main() entry point
  25. SOKOL_WIN32_FORCE_WINMAIN - define this on Win32 to add a WinMain() entry point (enabled by default unless
  26. SOKOL_WIN32_FORCE_MAIN or SOKOL_NO_ENTRY is defined)
  27. SOKOL_NO_ENTRY - define this if sokol_app.h shouldn't "hijack" the main() function
  28. SOKOL_APP_API_DECL - public function declaration prefix (default: extern)
  29. SOKOL_API_DECL - same as SOKOL_APP_API_DECL
  30. SOKOL_API_IMPL - public function implementation prefix (default: -)
  31. Optionally define the following to force debug checks and validations
  32. even in release mode:
  33. SOKOL_DEBUG - by default this is defined if NDEBUG is not defined
  34. If sokol_app.h is compiled as a DLL, define the following before
  35. including the declaration or implementation:
  36. SOKOL_DLL
  37. On Windows, SOKOL_DLL will define SOKOL_APP_API_DECL as __declspec(dllexport)
  38. or __declspec(dllimport) as needed.
  39. if SOKOL_WIN32_FORCE_MAIN and SOKOL_WIN32_FORCE_WINMAIN are both defined,
  40. it is up to the developer to define the desired subsystem.
  41. On Linux, SOKOL_GLCORE can use either GLX or EGL.
  42. GLX is default, set SOKOL_FORCE_EGL to override.
  43. For example code, see https://github.com/floooh/sokol-samples/tree/master/sapp
  44. Portions of the Windows and Linux GL initialization, event-, icon- etc... code
  45. have been taken from GLFW (http://www.glfw.org/).
  46. iOS onscreen keyboard support 'inspired' by libgdx.
  47. Link with the following system libraries:
  48. - on macOS:
  49. - all backends: Foundation, Cocoa, QuartzCore
  50. - with SOKOL_METAL: Metal, MetalKit
  51. - with SOKOL_GLCORE: OpenGL
  52. - with SOKOL_WGPU: a WebGPU implementation library (tested with webgpu_dawn)
  53. - on iOS:
  54. - all backends: Foundation, UIKit
  55. - with SOKOL_METAL: Metal, MetalKit
  56. - with SOKOL_GLES3: OpenGLES, GLKit
  57. - on Linux:
  58. - all backends: X11, Xi, Xcursor, dl, pthread, m
  59. - with SOKOL_GLCORE: GL
  60. - with SOKOL_GLES3: GLESv2
  61. - with SOKOL_WGPU: a WebGPU implementation library (tested with webgpu_dawn)
  62. - with EGL: EGL
  63. - on Android: GLESv3, EGL, log, android
  64. - on Windows:
  65. - with MSVC or Clang: library dependencies are defined via `#pragma comment`
  66. - with SOKOL_WGPU: a WebGPU implementation library (tested with webgpu_dawn)
  67. - with MINGW/MSYS2 gcc:
  68. - compile with '-mwin32' so that _WIN32 is defined
  69. - link with the following libs: -lkernel32 -luser32 -lshell32
  70. - additionally with the GL backend: -lgdi32
  71. - additionally with the D3D11 backend: -ld3d11 -ldxgi
  72. On Linux, you also need to use the -pthread compiler and linker option, otherwise weird
  73. things will happen, see here for details: https://github.com/floooh/sokol/issues/376
  74. On macOS and iOS, the implementation must be compiled as Objective-C.
  75. On Emscripten:
  76. - for WebGL2: add the linker option `-s USE_WEBGL2=1`
  77. - for WebGPU: compile and link with `--use-port=emdawnwebgpu`
  78. (for more exotic situations read: https://dawn.googlesource.com/dawn/+/refs/heads/main/src/emdawnwebgpu/pkg/README.md)
  79. FEATURE OVERVIEW
  80. ================
  81. sokol_app.h provides a minimalistic cross-platform API which
  82. implements the 'application-wrapper' parts of a 3D application:
  83. - a common application entry function
  84. - creates a window and 3D-API context/device with a swapchain
  85. surface, depth-stencil-buffer surface and optionally MSAA surface
  86. - makes the rendered frame visible
  87. - provides keyboard-, mouse- and low-level touch-events
  88. - platforms: MacOS, iOS, HTML5, Win32, Linux/RaspberryPi, Android
  89. - 3D-APIs: Metal, D3D11, GL4.1, GL4.3, GLES3, WebGL2, WebGPU, NOAPI
  90. FEATURE/PLATFORM MATRIX
  91. =======================
  92. | Windows | macOS | Linux | iOS | Android | HTML5
  93. --------------------+---------+-------+-------+-------+---------+--------
  94. gl 4.x | YES | YES | YES | --- | --- | ---
  95. gles3/webgl2 | --- | --- | YES(2)| YES | YES | YES
  96. metal | --- | YES | --- | YES | --- | ---
  97. d3d11 | YES | --- | --- | --- | --- | ---
  98. webgpu | YES(4) | YES(4)| YES(4)| NO | NO | YES
  99. noapi | YES | TODO | TODO | --- | TODO | ---
  100. KEY_DOWN | YES | YES | YES | SOME | TODO | YES
  101. KEY_UP | YES | YES | YES | SOME | TODO | YES
  102. CHAR | YES | YES | YES | YES | TODO | YES
  103. MOUSE_DOWN | YES | YES | YES | --- | --- | YES
  104. MOUSE_UP | YES | YES | YES | --- | --- | YES
  105. MOUSE_SCROLL | YES | YES | YES | --- | --- | YES
  106. MOUSE_MOVE | YES | YES | YES | --- | --- | YES
  107. MOUSE_ENTER | YES | YES | YES | --- | --- | YES
  108. MOUSE_LEAVE | YES | YES | YES | --- | --- | YES
  109. TOUCHES_BEGAN | --- | --- | --- | YES | YES | YES
  110. TOUCHES_MOVED | --- | --- | --- | YES | YES | YES
  111. TOUCHES_ENDED | --- | --- | --- | YES | YES | YES
  112. TOUCHES_CANCELLED | --- | --- | --- | YES | YES | YES
  113. RESIZED | YES | YES | YES | YES | YES | YES
  114. ICONIFIED | YES | YES | YES | --- | --- | ---
  115. RESTORED | YES | YES | YES | --- | --- | ---
  116. FOCUSED | YES | YES | YES | --- | --- | YES
  117. UNFOCUSED | YES | YES | YES | --- | --- | YES
  118. SUSPENDED | --- | --- | --- | YES | YES | TODO
  119. RESUMED | --- | --- | --- | YES | YES | TODO
  120. QUIT_REQUESTED | YES | YES | YES | --- | --- | YES
  121. IME | TODO | TODO? | TODO | ??? | TODO | ???
  122. key repeat flag | YES | YES | YES | --- | --- | YES
  123. windowed | YES | YES | YES | --- | --- | YES
  124. fullscreen | YES | YES | YES | YES | YES | YES(3)
  125. mouse hide | YES | YES | YES | --- | --- | YES
  126. mouse lock | YES | YES | YES | --- | --- | YES
  127. set cursor type | YES | YES | YES | --- | --- | YES
  128. screen keyboard | --- | --- | --- | YES | TODO | YES
  129. swap interval | YES | YES | YES | YES | TODO | YES
  130. high-dpi | YES | YES | TODO | YES | YES | YES
  131. clipboard | YES | YES | YES | --- | --- | YES
  132. MSAA | YES | YES | YES | YES | YES | YES
  133. drag'n'drop | YES | YES | YES | --- | --- | YES
  134. window icon | YES | YES(1)| YES | --- | --- | YES
  135. (1) macOS has no regular window icons, instead the dock icon is changed
  136. (2) supported with EGL only (not GLX)
  137. (3) fullscreen in the browser not supported on iphones
  138. (4) WebGPU on native desktop platforms should be considered experimental
  139. and mainly useful for debugging and benchmarking
  140. STEP BY STEP
  141. ============
  142. --- Add a sokol_main() function to your code which returns a sapp_desc structure
  143. with initialization parameters and callback function pointers. This
  144. function is called very early, usually at the start of the
  145. platform's entry function (e.g. main or WinMain). You should do as
  146. little as possible here, since the rest of your code might be called
  147. from another thread (this depends on the platform):
  148. sapp_desc sokol_main(int argc, char* argv[]) {
  149. return (sapp_desc) {
  150. .width = 640,
  151. .height = 480,
  152. .init_cb = my_init_func,
  153. .frame_cb = my_frame_func,
  154. .cleanup_cb = my_cleanup_func,
  155. .event_cb = my_event_func,
  156. ...
  157. };
  158. }
  159. To get any logging output in case of errors you need to provide a log
  160. callback. The easiest way is via sokol_log.h:
  161. #include "sokol_log.h"
  162. sapp_desc sokol_main(int argc, char* argv[]) {
  163. return (sapp_desc) {
  164. ...
  165. .logger.func = slog_func,
  166. };
  167. }
  168. There are many more setup parameters, but these are the most important.
  169. For a complete list search for the sapp_desc structure declaration
  170. below.
  171. DO NOT call any sokol-app function from inside sokol_main(), since
  172. sokol-app will not be initialized at this point.
  173. The .width and .height parameters are the preferred size of the 3D
  174. rendering canvas. The actual size may differ from this depending on
  175. platform and other circumstances. Also the canvas size may change at
  176. any time (for instance when the user resizes the application window,
  177. or rotates the mobile device). You can just keep .width and .height
  178. zero-initialized to open a default-sized window (what "default-size"
  179. exactly means is platform-specific, but usually it's a size that covers
  180. most of, but not all, of the display).
  181. All provided function callbacks will be called from the same thread,
  182. but this may be different from the thread where sokol_main() was called.
  183. .init_cb (void (*)(void))
  184. This function is called once after the application window,
  185. 3D rendering context and swap chain have been created. The
  186. function takes no arguments and has no return value.
  187. .frame_cb (void (*)(void))
  188. This is the per-frame callback, which is usually called 60
  189. times per second. This is where your application would update
  190. most of its state and perform all rendering.
  191. .cleanup_cb (void (*)(void))
  192. The cleanup callback is called once right before the application
  193. quits.
  194. .event_cb (void (*)(const sapp_event* event))
  195. The event callback is mainly for input handling, but is also
  196. used to communicate other types of events to the application. Keep the
  197. event_cb struct member zero-initialized if your application doesn't require
  198. event handling.
  199. As you can see, those 'standard callbacks' don't have a user_data
  200. argument, so any data that needs to be preserved between callbacks
  201. must live in global variables. If keeping state in global variables
  202. is not an option, there's an alternative set of callbacks with
  203. an additional user_data pointer argument:
  204. .user_data (void*)
  205. The user-data argument for the callbacks below
  206. .init_userdata_cb (void (*)(void* user_data))
  207. .frame_userdata_cb (void (*)(void* user_data))
  208. .cleanup_userdata_cb (void (*)(void* user_data))
  209. .event_userdata_cb (void(*)(const sapp_event* event, void* user_data))
  210. The function sapp_userdata() can be used to query the user_data
  211. pointer provided in the sapp_desc struct.
  212. You can also call sapp_query_desc() to get a copy of the
  213. original sapp_desc structure.
  214. NOTE that there's also an alternative compile mode where sokol_app.h
  215. doesn't "hijack" the main() function. Search below for SOKOL_NO_ENTRY.
  216. --- Implement the initialization callback function (init_cb), this is called
  217. once after the rendering surface, 3D API and swap chain have been
  218. initialized by sokol_app. All sokol-app functions can be called
  219. from inside the initialization callback, the most useful functions
  220. at this point are:
  221. int sapp_width(void)
  222. int sapp_height(void)
  223. Returns the current width and height of the default framebuffer in pixels,
  224. this may change from one frame to the next, and it may be different
  225. from the initial size provided in the sapp_desc struct.
  226. float sapp_widthf(void)
  227. float sapp_heightf(void)
  228. These are alternatives to sapp_width() and sapp_height() which return
  229. the default framebuffer size as float values instead of integer. This
  230. may help to prevent casting back and forth between int and float
  231. in more strongly typed languages than C and C++.
  232. double sapp_frame_duration(void)
  233. Returns the frame duration in seconds averaged over a number of
  234. frames to smooth out any jittering spikes.
  235. int sapp_color_format(void)
  236. int sapp_depth_format(void)
  237. The color and depth-stencil pixelformats of the default framebuffer,
  238. as integer values which are compatible with sokol-gfx's
  239. sg_pixel_format enum (so that they can be plugged directly in places
  240. where sg_pixel_format is expected). Possible values are:
  241. 23 == SG_PIXELFORMAT_RGBA8
  242. 28 == SG_PIXELFORMAT_BGRA8
  243. 42 == SG_PIXELFORMAT_DEPTH
  244. 43 == SG_PIXELFORMAT_DEPTH_STENCIL
  245. int sapp_sample_count(void)
  246. Return the MSAA sample count of the default framebuffer.
  247. const void* sapp_metal_get_device(void)
  248. const void* sapp_metal_get_current_drawable(void)
  249. const void* sapp_metal_get_depth_stencil_texture(void)
  250. const void* sapp_metal_get_msaa_color_texture(void)
  251. If the Metal backend has been selected, these functions return pointers
  252. to various Metal API objects required for rendering, otherwise
  253. they return a null pointer. These void pointers are actually
  254. Objective-C ids converted with a (ARC) __bridge cast so that
  255. the ids can be tunneled through C code. Also note that the returned
  256. pointers may change from one frame to the next, only the Metal device
  257. object is guaranteed to stay the same.
  258. const void* sapp_macos_get_window(void)
  259. On macOS, get the NSWindow object pointer, otherwise a null pointer.
  260. Before being used as Objective-C object, the void* must be converted
  261. back with a (ARC) __bridge cast.
  262. const void* sapp_ios_get_window(void)
  263. On iOS, get the UIWindow object pointer, otherwise a null pointer.
  264. Before being used as Objective-C object, the void* must be converted
  265. back with a (ARC) __bridge cast.
  266. const void* sapp_d3d11_get_device(void)
  267. const void* sapp_d3d11_get_device_context(void)
  268. const void* sapp_d3d11_get_render_view(void)
  269. const void* sapp_d3d11_get_resolve_view(void);
  270. const void* sapp_d3d11_get_depth_stencil_view(void)
  271. Similar to the sapp_metal_* functions, the sapp_d3d11_* functions
  272. return pointers to D3D11 API objects required for rendering,
  273. only if the D3D11 backend has been selected. Otherwise they
  274. return a null pointer. Note that the returned pointers to the
  275. render-target-view and depth-stencil-view may change from one
  276. frame to the next!
  277. const void* sapp_win32_get_hwnd(void)
  278. On Windows, get the window's HWND, otherwise a null pointer. The
  279. HWND has been cast to a void pointer in order to be tunneled
  280. through code which doesn't include Windows.h.
  281. const void* sapp_x11_get_window(void)
  282. On Linux, get the X11 Window, otherwise a null pointer. The
  283. Window has been cast to a void pointer in order to be tunneled
  284. through code which doesn't include X11/Xlib.h.
  285. const void* sapp_x11_get_display(void)
  286. On Linux, get the X11 Display, otherwise a null pointer. The
  287. Display has been cast to a void pointer in order to be tunneled
  288. through code which doesn't include X11/Xlib.h.
  289. const void* sapp_wgpu_get_device(void)
  290. const void* sapp_wgpu_get_render_view(void)
  291. const void* sapp_wgpu_get_resolve_view(void)
  292. const void* sapp_wgpu_get_depth_stencil_view(void)
  293. These are the WebGPU-specific functions to get the WebGPU
  294. objects and values required for rendering. If sokol_app.h
  295. is not compiled with SOKOL_WGPU, these functions return null.
  296. uint32_t sapp_gl_get_framebuffer(void)
  297. This returns the 'default framebuffer' of the GL context.
  298. Typically this will be zero.
  299. int sapp_gl_get_major_version(void)
  300. int sapp_gl_get_minor_version(void)
  301. bool sapp_gl_is_gles(void)
  302. Returns the major and minor version of the GL context and
  303. whether the GL context is a GLES context
  304. const void* sapp_android_get_native_activity(void);
  305. On Android, get the native activity ANativeActivity pointer, otherwise
  306. a null pointer.
  307. --- Implement the frame-callback function, this function will be called
  308. on the same thread as the init callback, but might be on a different
  309. thread than the sokol_main() function. Note that the size of
  310. the rendering framebuffer might have changed since the frame callback
  311. was called last. Call the functions sapp_width() and sapp_height()
  312. each frame to get the current size.
  313. --- Optionally implement the event-callback to handle input events.
  314. sokol-app provides the following type of input events:
  315. - a 'virtual key' was pressed down or released
  316. - a single text character was entered (provided as UTF-32 encoded
  317. UNICODE code point)
  318. - a mouse button was pressed down or released (left, right, middle)
  319. - mouse-wheel or 2D scrolling events
  320. - the mouse was moved
  321. - the mouse has entered or left the application window boundaries
  322. - low-level, portable multi-touch events (began, moved, ended, cancelled)
  323. - the application window was resized, iconified or restored
  324. - the application was suspended or restored (on mobile platforms)
  325. - the user or application code has asked to quit the application
  326. - a string was pasted to the system clipboard
  327. - one or more files have been dropped onto the application window
  328. To explicitly 'consume' an event and prevent that the event is
  329. forwarded for further handling to the operating system, call
  330. sapp_consume_event() from inside the event handler (NOTE that
  331. this behaviour is currently only implemented for some HTML5
  332. events, support for other platforms and event types will
  333. be added as needed, please open a GitHub ticket and/or provide
  334. a PR if needed).
  335. NOTE: Do *not* call any 3D API rendering functions in the event
  336. callback function, since the 3D API context may not be active when the
  337. event callback is called (it may work on some platforms and 3D APIs,
  338. but not others, and the exact behaviour may change between
  339. sokol-app versions).
  340. --- Implement the cleanup-callback function, this is called once
  341. after the user quits the application (see the section
  342. "APPLICATION QUIT" for detailed information on quitting
  343. behaviour, and how to intercept a pending quit - for instance to show a
  344. "Really Quit?" dialog box). Note that the cleanup-callback isn't
  345. guaranteed to be called on the web and mobile platforms.
  346. MOUSE CURSOR TYPE AND VISIBILITY
  347. ================================
  348. You can show and hide the mouse cursor with
  349. void sapp_show_mouse(bool show)
  350. And to get the current shown status:
  351. bool sapp_mouse_shown(void)
  352. NOTE that hiding the mouse cursor is different and independent from
  353. the MOUSE/POINTER LOCK feature which will also hide the mouse pointer when
  354. active (MOUSE LOCK is described below).
  355. To change the mouse cursor to one of several predefined types, call
  356. the function:
  357. void sapp_set_mouse_cursor(sapp_mouse_cursor cursor)
  358. Setting the default mouse cursor SAPP_MOUSECURSOR_DEFAULT will restore
  359. the standard look.
  360. To get the currently active mouse cursor type, call:
  361. sapp_mouse_cursor sapp_get_mouse_cursor(void)
  362. MOUSE LOCK (AKA POINTER LOCK, AKA MOUSE CAPTURE)
  363. ================================================
  364. In normal mouse mode, no mouse movement events are reported when the
  365. mouse leaves the windows client area or hits the screen border (whether
  366. it's one or the other depends on the platform), and the mouse move events
  367. (SAPP_EVENTTYPE_MOUSE_MOVE) contain absolute mouse positions in
  368. framebuffer pixels in the sapp_event items mouse_x and mouse_y, and
  369. relative movement in framebuffer pixels in the sapp_event items mouse_dx
  370. and mouse_dy.
  371. To get continuous mouse movement (also when the mouse leaves the window
  372. client area or hits the screen border), activate mouse-lock mode
  373. by calling:
  374. sapp_lock_mouse(true)
  375. When mouse lock is activated, the mouse pointer is hidden, the
  376. reported absolute mouse position (sapp_event.mouse_x/y) appears
  377. frozen, and the relative mouse movement in sapp_event.mouse_dx/dy
  378. no longer has a direct relation to framebuffer pixels but instead
  379. uses "raw mouse input" (what "raw mouse input" exactly means also
  380. differs by platform).
  381. To deactivate mouse lock and return to normal mouse mode, call
  382. sapp_lock_mouse(false)
  383. And finally, to check if mouse lock is currently active, call
  384. if (sapp_mouse_locked()) { ... }
  385. Note that mouse-lock state may not change immediately after sapp_lock_mouse(true/false)
  386. is called, instead on some platforms the actual state switch may be delayed
  387. to the end of the current frame or even to a later frame.
  388. The mouse may also be unlocked automatically without calling sapp_lock_mouse(false),
  389. most notably when the application window becomes inactive.
  390. On the web platform there are further restrictions to be aware of, caused
  391. by the limitations of the HTML5 Pointer Lock API:
  392. - sapp_lock_mouse(true) can be called at any time, but it will
  393. only take effect in a 'short-lived input event handler of a specific
  394. type', meaning when one of the following events happens:
  395. - SAPP_EVENTTYPE_MOUSE_DOWN
  396. - SAPP_EVENTTYPE_MOUSE_UP
  397. - SAPP_EVENTTYPE_MOUSE_SCROLL
  398. - SAPP_EVENTTYPE_KEY_UP
  399. - SAPP_EVENTTYPE_KEY_DOWN
  400. - The mouse lock/unlock action on the web platform is asynchronous,
  401. this means that sapp_mouse_locked() won't immediately return
  402. the new status after calling sapp_lock_mouse(), instead the
  403. reported status will only change when the pointer lock has actually
  404. been activated or deactivated in the browser.
  405. - On the web, mouse lock can be deactivated by the user at any time
  406. by pressing the Esc key. When this happens, sokol_app.h behaves
  407. the same as if sapp_lock_mouse(false) is called.
  408. For things like camera manipulation it's most straightforward to lock
  409. and unlock the mouse right from the sokol_app.h event handler, for
  410. instance the following code enters and leaves mouse lock when the
  411. left mouse button is pressed and released, and then uses the relative
  412. movement information to manipulate a camera (taken from the
  413. cgltf-sapp.c sample in the sokol-samples repository
  414. at https://github.com/floooh/sokol-samples):
  415. static void input(const sapp_event* ev) {
  416. switch (ev->type) {
  417. case SAPP_EVENTTYPE_MOUSE_DOWN:
  418. if (ev->mouse_button == SAPP_MOUSEBUTTON_LEFT) {
  419. sapp_lock_mouse(true);
  420. }
  421. break;
  422. case SAPP_EVENTTYPE_MOUSE_UP:
  423. if (ev->mouse_button == SAPP_MOUSEBUTTON_LEFT) {
  424. sapp_lock_mouse(false);
  425. }
  426. break;
  427. case SAPP_EVENTTYPE_MOUSE_MOVE:
  428. if (sapp_mouse_locked()) {
  429. cam_orbit(&state.camera, ev->mouse_dx * 0.25f, ev->mouse_dy * 0.25f);
  430. }
  431. break;
  432. default:
  433. break;
  434. }
  435. }
  436. For a 'first person shooter mouse' the following code inside the sokol-app event handler
  437. is recommended somewhere in your frame callback:
  438. if (!sapp_mouse_locked()) {
  439. sapp_lock_mouse(true);
  440. }
  441. CLIPBOARD SUPPORT
  442. =================
  443. Applications can send and receive UTF-8 encoded text data from and to the
  444. system clipboard. By default, clipboard support is disabled and
  445. must be enabled at startup via the following sapp_desc struct
  446. members:
  447. sapp_desc.enable_clipboard - set to true to enable clipboard support
  448. sapp_desc.clipboard_size - size of the internal clipboard buffer in bytes
  449. Enabling the clipboard will dynamically allocate a clipboard buffer
  450. for UTF-8 encoded text data of the requested size in bytes, the default
  451. size is 8 KBytes. Strings that don't fit into the clipboard buffer
  452. (including the terminating zero) will be silently clipped, so it's
  453. important that you provide a big enough clipboard size for your
  454. use case.
  455. To send data to the clipboard, call sapp_set_clipboard_string() with
  456. a pointer to an UTF-8 encoded, null-terminated C-string.
  457. NOTE that on the HTML5 platform, sapp_set_clipboard_string() must be
  458. called from inside a 'short-lived event handler', and there are a few
  459. other HTML5-specific caveats to workaround. You'll basically have to
  460. tinker until it works in all browsers :/ (maybe the situation will
  461. improve when all browsers agree on and implement the new
  462. HTML5 navigator.clipboard API).
  463. To get data from the clipboard, check for the SAPP_EVENTTYPE_CLIPBOARD_PASTED
  464. event in your event handler function, and then call sapp_get_clipboard_string()
  465. to obtain the pasted UTF-8 encoded text.
  466. NOTE that behaviour of sapp_get_clipboard_string() is slightly different
  467. depending on platform:
  468. - on the HTML5 platform, the internal clipboard buffer will only be updated
  469. right before the SAPP_EVENTTYPE_CLIPBOARD_PASTED event is sent,
  470. and sapp_get_clipboard_string() will simply return the current content
  471. of the clipboard buffer
  472. - on 'native' platforms, the call to sapp_get_clipboard_string() will
  473. update the internal clipboard buffer with the most recent data
  474. from the system clipboard
  475. Portable code should check for the SAPP_EVENTTYPE_CLIPBOARD_PASTED event,
  476. and then call sapp_get_clipboard_string() right in the event handler.
  477. The SAPP_EVENTTYPE_CLIPBOARD_PASTED event will be generated by sokol-app
  478. as follows:
  479. - on macOS: when the Cmd+V key is pressed down
  480. - on HTML5: when the browser sends a 'paste' event to the global 'window' object
  481. - on all other platforms: when the Ctrl+V key is pressed down
  482. DRAG AND DROP SUPPORT
  483. =====================
  484. PLEASE NOTE: the drag'n'drop feature works differently on WASM/HTML5
  485. and on the native desktop platforms (Win32, Linux and macOS) because
  486. of security-related restrictions in the HTML5 drag'n'drop API. The
  487. WASM/HTML5 specifics are described at the end of this documentation
  488. section:
  489. Like clipboard support, drag'n'drop support must be explicitly enabled
  490. at startup in the sapp_desc struct.
  491. sapp_desc sokol_main(void) {
  492. return (sapp_desc) {
  493. .enable_dragndrop = true, // default is false
  494. ...
  495. };
  496. }
  497. You can also adjust the maximum number of files that are accepted
  498. in a drop operation, and the maximum path length in bytes if needed:
  499. sapp_desc sokol_main(void) {
  500. return (sapp_desc) {
  501. .enable_dragndrop = true, // default is false
  502. .max_dropped_files = 8, // default is 1
  503. .max_dropped_file_path_length = 8192, // in bytes, default is 2048
  504. ...
  505. };
  506. }
  507. When drag'n'drop is enabled, the event callback will be invoked with an
  508. event of type SAPP_EVENTTYPE_FILES_DROPPED whenever the user drops files on
  509. the application window.
  510. After the SAPP_EVENTTYPE_FILES_DROPPED is received, you can query the
  511. number of dropped files, and their absolute paths by calling separate
  512. functions:
  513. void on_event(const sapp_event* ev) {
  514. if (ev->type == SAPP_EVENTTYPE_FILES_DROPPED) {
  515. // the mouse position where the drop happened
  516. float x = ev->mouse_x;
  517. float y = ev->mouse_y;
  518. // get the number of files and their paths like this:
  519. const int num_dropped_files = sapp_get_num_dropped_files();
  520. for (int i = 0; i < num_dropped_files; i++) {
  521. const char* path = sapp_get_dropped_file_path(i);
  522. ...
  523. }
  524. }
  525. }
  526. The returned file paths are UTF-8 encoded strings.
  527. You can call sapp_get_num_dropped_files() and sapp_get_dropped_file_path()
  528. anywhere, also outside the event handler callback, but be aware that the
  529. file path strings will be overwritten with the next drop operation.
  530. In any case, sapp_get_dropped_file_path() will never return a null pointer,
  531. instead an empty string "" will be returned if the drag'n'drop feature
  532. hasn't been enabled, the last drop-operation failed, or the file path index
  533. is out of range.
  534. Drag'n'drop caveats:
  535. - if more files are dropped in a single drop-action
  536. than sapp_desc.max_dropped_files, the additional
  537. files will be silently ignored
  538. - if any of the file paths is longer than
  539. sapp_desc.max_dropped_file_path_length (in number of bytes, after UTF-8
  540. encoding) the entire drop operation will be silently ignored (this
  541. needs some sort of error feedback in the future)
  542. - no mouse positions are reported while the drag is in
  543. process, this may change in the future
  544. Drag'n'drop on HTML5/WASM:
  545. The HTML5 drag'n'drop API doesn't return file paths, but instead
  546. black-box 'file objects' which must be used to load the content
  547. of dropped files. This is the reason why sokol_app.h adds two
  548. HTML5-specific functions to the drag'n'drop API:
  549. uint32_t sapp_html5_get_dropped_file_size(int index)
  550. Returns the size in bytes of a dropped file.
  551. void sapp_html5_fetch_dropped_file(const sapp_html5_fetch_request* request)
  552. Asynchronously loads the content of a dropped file into a
  553. provided memory buffer (which must be big enough to hold
  554. the file content)
  555. To start loading the first dropped file after an SAPP_EVENTTYPE_FILES_DROPPED
  556. event is received:
  557. sapp_html5_fetch_dropped_file(&(sapp_html5_fetch_request){
  558. .dropped_file_index = 0,
  559. .callback = fetch_cb
  560. .buffer = {
  561. .ptr = buf,
  562. .size = sizeof(buf)
  563. },
  564. .user_data = ...
  565. });
  566. Make sure that the memory pointed to by 'buf' stays valid until the
  567. callback function is called!
  568. As result of the asynchronous loading operation (no matter if succeeded or
  569. failed) the 'fetch_cb' function will be called:
  570. void fetch_cb(const sapp_html5_fetch_response* response) {
  571. // IMPORTANT: check if the loading operation actually succeeded:
  572. if (response->succeeded) {
  573. // the size of the loaded file:
  574. const size_t num_bytes = response->data.size;
  575. // and the pointer to the data (same as 'buf' in the fetch-call):
  576. const void* ptr = response->data.ptr;
  577. } else {
  578. // on error check the error code:
  579. switch (response->error_code) {
  580. case SAPP_HTML5_FETCH_ERROR_BUFFER_TOO_SMALL:
  581. ...
  582. break;
  583. case SAPP_HTML5_FETCH_ERROR_OTHER:
  584. ...
  585. break;
  586. }
  587. }
  588. }
  589. Check the droptest-sapp example for a real-world example which works
  590. both on native platforms and the web:
  591. https://github.com/floooh/sokol-samples/blob/master/sapp/droptest-sapp.c
  592. HIGH-DPI RENDERING
  593. ==================
  594. You can set the sapp_desc.high_dpi flag during initialization to request
  595. a full-resolution framebuffer on HighDPI displays. The default behaviour
  596. is sapp_desc.high_dpi=false, this means that the application will
  597. render to a lower-resolution framebuffer on HighDPI displays and the
  598. rendered content will be upscaled by the window system composer.
  599. In a HighDPI scenario, you still request the same window size during
  600. sokol_main(), but the framebuffer sizes returned by sapp_width()
  601. and sapp_height() will be scaled up according to the DPI scaling
  602. ratio.
  603. Note that on some platforms the DPI scaling factor may change at any
  604. time (for instance when a window is moved from a high-dpi display
  605. to a low-dpi display).
  606. To query the current DPI scaling factor, call the function:
  607. float sapp_dpi_scale(void);
  608. For instance on a Retina Mac, returning the following sapp_desc
  609. struct from sokol_main():
  610. sapp_desc sokol_main(void) {
  611. return (sapp_desc) {
  612. .width = 640,
  613. .height = 480,
  614. .high_dpi = true,
  615. ...
  616. };
  617. }
  618. ...the functions the functions sapp_width(), sapp_height()
  619. and sapp_dpi_scale() will return the following values:
  620. sapp_width: 1280
  621. sapp_height: 960
  622. sapp_dpi_scale: 2.0
  623. If the high_dpi flag is false, or you're not running on a Retina display,
  624. the values would be:
  625. sapp_width: 640
  626. sapp_height: 480
  627. sapp_dpi_scale: 1.0
  628. If the window is moved from the Retina display to a low-dpi external display,
  629. the values would change as follows:
  630. sapp_width: 1280 => 640
  631. sapp_height: 960 => 480
  632. sapp_dpi_scale: 2.0 => 1.0
  633. Currently there is no event associated with a DPI change, but an
  634. SAPP_EVENTTYPE_RESIZED will be sent as a side effect of the
  635. framebuffer size changing.
  636. Per-monitor DPI is currently supported on macOS and Windows.
  637. APPLICATION QUIT
  638. ================
  639. Without special quit handling, a sokol_app.h application will quit
  640. 'gracefully' when the user clicks the window close-button unless a
  641. platform's application model prevents this (e.g. on web or mobile).
  642. 'Graceful exit' means that the application-provided cleanup callback will
  643. be called before the application quits.
  644. On native desktop platforms sokol_app.h provides more control over the
  645. application-quit-process. It's possible to initiate a 'programmatic quit'
  646. from the application code, and a quit initiated by the application user can
  647. be intercepted (for instance to show a custom dialog box).
  648. This 'programmatic quit protocol' is implemented through 3 functions
  649. and 1 event:
  650. - sapp_quit(): This function simply quits the application without
  651. giving the user a chance to intervene. Usually this might
  652. be called when the user clicks the 'Ok' button in a 'Really Quit?'
  653. dialog box
  654. - sapp_request_quit(): Calling sapp_request_quit() will send the
  655. event SAPP_EVENTTYPE_QUIT_REQUESTED to the applications event handler
  656. callback, giving the user code a chance to intervene and cancel the
  657. pending quit process (for instance to show a 'Really Quit?' dialog
  658. box). If the event handler callback does nothing, the application
  659. will be quit as usual. To prevent this, call the function
  660. sapp_cancel_quit() from inside the event handler.
  661. - sapp_cancel_quit(): Cancels a pending quit request, either initiated
  662. by the user clicking the window close button, or programmatically
  663. by calling sapp_request_quit(). The only place where calling this
  664. function makes sense is from inside the event handler callback when
  665. the SAPP_EVENTTYPE_QUIT_REQUESTED event has been received.
  666. - SAPP_EVENTTYPE_QUIT_REQUESTED: this event is sent when the user
  667. clicks the window's close button or application code calls the
  668. sapp_request_quit() function. The event handler callback code can handle
  669. this event by calling sapp_cancel_quit() to cancel the quit.
  670. If the event is ignored, the application will quit as usual.
  671. On the web platform, the quit behaviour differs from native platforms,
  672. because of web-specific restrictions:
  673. A `programmatic quit` initiated by calling sapp_quit() or
  674. sapp_request_quit() will work as described above: the cleanup callback is
  675. called, platform-specific cleanup is performed (on the web
  676. this means that JS event handlers are unregistered), and then
  677. the request-animation-loop will be exited. However that's all. The
  678. web page itself will continue to exist (e.g. it's not possible to
  679. programmatically close the browser tab).
  680. On the web it's also not possible to run custom code when the user
  681. closes a browser tab, so it's not possible to prevent this with a
  682. fancy custom dialog box.
  683. Instead the standard "Leave Site?" dialog box can be activated (or
  684. deactivated) with the following function:
  685. sapp_html5_ask_leave_site(bool ask);
  686. The initial state of the associated internal flag can be provided
  687. at startup via sapp_desc.html5.ask_leave_site.
  688. This feature should only be used sparingly in critical situations - for
  689. instance when the user would loose data - since popping up modal dialog
  690. boxes is considered quite rude in the web world. Note that there's no way
  691. to customize the content of this dialog box or run any code as a result
  692. of the user's decision. Also note that the user must have interacted with
  693. the site before the dialog box will appear. These are all security measures
  694. to prevent fishing.
  695. The Dear ImGui HighDPI sample contains example code of how to
  696. implement a 'Really Quit?' dialog box with Dear ImGui (native desktop
  697. platforms only), and for showing the hardwired "Leave Site?" dialog box
  698. when running on the web platform:
  699. https://floooh.github.io/sokol-html5/wasm/imgui-highdpi-sapp.html
  700. FULLSCREEN
  701. ==========
  702. If the sapp_desc.fullscreen flag is true, sokol-app will try to create
  703. a fullscreen window on platforms with a 'proper' window system
  704. (mobile devices will always use fullscreen). The implementation details
  705. depend on the target platform, in general sokol-app will use a
  706. 'soft approach' which doesn't interfere too much with the platform's
  707. window system (for instance borderless fullscreen window instead of
  708. a 'real' fullscreen mode). Such details might change over time
  709. as sokol-app is adapted for different needs.
  710. The most important effect of fullscreen mode to keep in mind is that
  711. the requested canvas width and height will be ignored for the initial
  712. window size, calling sapp_width() and sapp_height() will instead return
  713. the resolution of the fullscreen canvas (however the provided size
  714. might still be used for the non-fullscreen window, in case the user can
  715. switch back from fullscreen- to windowed-mode).
  716. To toggle fullscreen mode programmatically, call sapp_toggle_fullscreen().
  717. To check if the application window is currently in fullscreen mode,
  718. call sapp_is_fullscreen().
  719. On the web, sapp_desc.fullscreen will have no effect, and the application
  720. will always start in non-fullscreen mode. Call sapp_toggle_fullscreen()
  721. from within or 'near' an input event to switch to fullscreen programatically.
  722. Note that on the web, the fullscreen state may change back to windowed at
  723. any time (either because the browser had rejected switching into fullscreen,
  724. or the user leaves fullscreen via Esc), this means that the result
  725. of sapp_is_fullscreen() may change also without calling sapp_toggle_fullscreen()!
  726. WINDOW ICON SUPPORT
  727. ===================
  728. Some sokol_app.h backends allow to change the window icon programmatically:
  729. - on Win32: the small icon in the window's title bar, and the
  730. bigger icon in the task bar
  731. - on Linux: highly dependent on the used window manager, but usually
  732. the window's title bar icon and/or the task bar icon
  733. - on HTML5: the favicon shown in the page's browser tab
  734. - on macOS: the application icon shown in the dock, but only
  735. for currently running applications
  736. NOTE that it is not possible to set the actual application icon which is
  737. displayed by the operating system on the desktop or 'home screen'. Those
  738. icons must be provided 'traditionally' through operating-system-specific
  739. resources which are associated with the application (sokol_app.h might
  740. later support setting the window icon from platform specific resource data
  741. though).
  742. There are two ways to set the window icon:
  743. - at application start in the sokol_main() function by initializing
  744. the sapp_desc.icon nested struct
  745. - or later by calling the function sapp_set_icon()
  746. As a convenient shortcut, sokol_app.h comes with a builtin default-icon
  747. (a rainbow-colored 'S', which at least looks a bit better than the Windows
  748. default icon for applications), which can be activated like this:
  749. At startup in sokol_main():
  750. sapp_desc sokol_main(...) {
  751. return (sapp_desc){
  752. ...
  753. icon.sokol_default = true
  754. };
  755. }
  756. Or later by calling:
  757. sapp_set_icon(&(sapp_icon_desc){ .sokol_default = true });
  758. NOTE that a completely zero-initialized sapp_icon_desc struct will not
  759. update the window icon in any way. This is an 'escape hatch' so that you
  760. can handle the window icon update yourself (or if you do this already,
  761. sokol_app.h won't get in your way, in this case just leave the
  762. sapp_desc.icon struct zero-initialized).
  763. Providing your own icon images works exactly like in GLFW (down to the
  764. data format):
  765. You provide one or more 'candidate images' in different sizes, and the
  766. sokol_app.h platform backends pick the best match for the specific backend
  767. and icon type.
  768. For each candidate image, you need to provide:
  769. - the width in pixels
  770. - the height in pixels
  771. - and the actual pixel data in RGBA8 pixel format (e.g. 0xFFCC8844
  772. on a little-endian CPU means: alpha=0xFF, blue=0xCC, green=0x88, red=0x44)
  773. For instance, if you have 3 candidate images (small, medium, big) of
  774. sizes 16x16, 32x32 and 64x64 the corresponding sapp_icon_desc struct is setup
  775. like this:
  776. // the actual pixel data (RGBA8, origin top-left)
  777. const uint32_t small[16][16] = { ... };
  778. const uint32_t medium[32][32] = { ... };
  779. const uint32_t big[64][64] = { ... };
  780. const sapp_icon_desc icon_desc = {
  781. .images = {
  782. { .width = 16, .height = 16, .pixels = SAPP_RANGE(small) },
  783. { .width = 32, .height = 32, .pixels = SAPP_RANGE(medium) },
  784. // ...or without the SAPP_RANGE helper macro:
  785. { .width = 64, .height = 64, .pixels = { .ptr=big, .size=sizeof(big) } }
  786. }
  787. };
  788. An sapp_icon_desc struct initialized like this can then either be applied
  789. at application start in sokol_main:
  790. sapp_desc sokol_main(...) {
  791. return (sapp_desc){
  792. ...
  793. icon = icon_desc
  794. };
  795. }
  796. ...or later by calling sapp_set_icon():
  797. sapp_set_icon(&icon_desc);
  798. Some window icon caveats:
  799. - once the window icon has been updated, there's no way to go back to
  800. the platform's default icon, this is because some platforms (Linux
  801. and HTML5) don't switch the icon visual back to the default even if
  802. the custom icon is deleted or removed
  803. - on HTML5, if the sokol_app.h icon doesn't show up in the browser
  804. tab, check that there's no traditional favicon 'link' element
  805. is defined in the page's index.html, sokol_app.h will only
  806. append a new favicon link element, but not delete any manually
  807. defined favicon in the page
  808. For an example and test of the window icon feature, check out the
  809. 'icon-sapp' sample on the sokol-samples git repository.
  810. ONSCREEN KEYBOARD
  811. =================
  812. On some platforms which don't provide a physical keyboard, sokol-app
  813. can display the platform's integrated onscreen keyboard for text
  814. input. To request that the onscreen keyboard is shown, call
  815. sapp_show_keyboard(true);
  816. Likewise, to hide the keyboard call:
  817. sapp_show_keyboard(false);
  818. Note that onscreen keyboard functionality is no longer supported
  819. on the browser platform (the previous hacks and workarounds to make browser
  820. keyboards work for on web applications that don't use HTML UIs
  821. never really worked across browsers).
  822. INPUT EVENT BUBBLING ON THE WEB PLATFORM
  823. ========================================
  824. By default, input event bubbling on the web platform is configured in
  825. a way that makes the most sense for 'full-canvas' apps that cover the
  826. entire browser client window area:
  827. - mouse, touch and wheel events do not bubble up, this prevents various
  828. ugly side events, like:
  829. - HTML text overlays being selected on double- or triple-click into
  830. the canvas
  831. - 'scroll bumping' even when the canvas covers the entire client area
  832. - key_up/down events for 'character keys' *do* bubble up (otherwise
  833. the browser will not generate UNICODE character events)
  834. - all other key events *do not* bubble up by default (this prevents side effects
  835. like F1 opening help, or F7 starting 'caret browsing')
  836. - character events do not bubble up (although I haven't noticed any side effects
  837. otherwise)
  838. Event bubbling can be enabled for input event categories during initialization
  839. in the sapp_desc struct:
  840. sapp_desc sokol_main(int argc, char* argv[]) {
  841. return (sapp_desc){
  842. //...
  843. .html5 = {
  844. .bubble_mouse_events = true,
  845. .bubble_touch_events = true,
  846. .bubble_wheel_events = true,
  847. .bubble_key_events = true,
  848. .bubble_char_events = true,
  849. }
  850. };
  851. }
  852. This basically opens the floodgates and lets *all* input events bubble up to the browser.
  853. To prevent individual events from bubbling, call sapp_consume_event() from within
  854. the sokol_app.h event callback when that specific event is reported.
  855. SETTING THE CANVAS OBJECT ON THE WEB PLATFORM
  856. =============================================
  857. On the web, sokol_app.h and the Emscripten SDK functions need to find
  858. the WebGL/WebGPU canvas intended for rendering and attaching event
  859. handlers. This can happen in four ways:
  860. 1. do nothing and just set the id of the canvas object to 'canvas' (preferred)
  861. 2. via a CSS Selector string (preferred)
  862. 3. by setting the `Module.canvas` property to the canvas object
  863. 4. by adding the canvas object to the global variable `specialHTMLTargets[]`
  864. (this is a special variable used by the Emscripten runtime to lookup
  865. event target objects for which document.querySelector() cannot be used)
  866. The easiest way is to just name your canvas object 'canvas':
  867. <canvas id="canvas" ...></canvas>
  868. This works because the default css selector string used by sokol_app.h
  869. is '#canvas'.
  870. If you name your canvas differently, you need to communicate that name to
  871. sokol_app.h via `sapp_desc.html5.canvas_selector` as a regular css selector
  872. string that's compatible with `document.querySelector()`. E.g. if your canvas
  873. object looks like this:
  874. <canvas id="bla" ...></canvas>
  875. The `sapp_desc.html5.canvas_selector` string must be set to '#bla':
  876. .html5.canvas_selector = "#bla"
  877. If the canvas object cannot be looked up via `document.querySelector()` you
  878. need to use one of the alternative methods, both involve the special
  879. Emscripten runtime `Module` object which is usually setup in the index.html
  880. like this before the WASM blob is loaded and instantiated:
  881. <script type='text/javascript'>
  882. var Module = {
  883. // ...
  884. };
  885. </script>
  886. The first option is to set the `Module.canvas` property to your canvas object:
  887. <script type='text/javascript'>
  888. var Module = {
  889. canvas: my_canvas_object,
  890. };
  891. </script>
  892. When sokol_app.h initializes, it will check the global Module object whether
  893. a `Module.canvas` property exists and is an object. This method will add
  894. a new entry to the `specialHTMLTargets[]` object
  895. The other option is to add the canvas under a name chosen by you to the
  896. special `specialHTMLTargets[]` map, which is used by the Emscripten runtime
  897. to lookup 'event target objects' which are not visible to `document.querySelector()`.
  898. Note that `specialHTMLTargets[]` must be updated after the Emscripten runtime
  899. has started but before the WASM code is running. A good place for this is
  900. the special `Module.preRun` array in index.html:
  901. <script type='text/javascript'>
  902. var Module = {
  903. preRun: [
  904. () => {
  905. specialHTMLTargets['my_canvas'] = my_canvas_object;
  906. }
  907. ],
  908. };
  909. </script>
  910. In that case, pass the same string to sokol_app.h which is used as key
  911. in the specialHTMLTargets[] map:
  912. .html5.canvas_selector = "my_canvas"
  913. If sokol_app.h can't find your canvas for some reason check for warning
  914. messages on the browser console.
  915. OPTIONAL: DON'T HIJACK main() (#define SOKOL_NO_ENTRY)
  916. ======================================================
  917. NOTE: SOKOL_NO_ENTRY and sapp_run() is currently not supported on Android.
  918. In its default configuration, sokol_app.h "hijacks" the platform's
  919. standard main() function. This was done because different platforms
  920. have different entry point conventions which are not compatible with
  921. C's main() (for instance WinMain on Windows has completely different
  922. arguments). However, this "main hijacking" posed a problem for
  923. usage scenarios like integrating sokol_app.h with other languages than
  924. C or C++, so an alternative SOKOL_NO_ENTRY mode has been added
  925. in which the user code provides the platform's main function:
  926. - define SOKOL_NO_ENTRY before including the sokol_app.h implementation
  927. - do *not* provide a sokol_main() function
  928. - instead provide the standard main() function of the platform
  929. - from the main function, call the function ```sapp_run()``` which
  930. takes a pointer to an ```sapp_desc``` structure.
  931. - from here on```sapp_run()``` takes over control and calls the provided
  932. init-, frame-, event- and cleanup-callbacks just like in the default model.
  933. sapp_run() behaves differently across platforms:
  934. - on some platforms, sapp_run() will return when the application quits
  935. - on other platforms, sapp_run() will never return, even when the
  936. application quits (the operating system is free to simply terminate
  937. the application at any time)
  938. - on Emscripten specifically, sapp_run() will return immediately while
  939. the frame callback keeps being called
  940. This different behaviour of sapp_run() essentially means that there shouldn't
  941. be any code *after* sapp_run(), because that may either never be called, or in
  942. case of Emscripten will be called at an unexpected time (at application start).
  943. An application also should not depend on the cleanup-callback being called
  944. when cross-platform compatibility is required.
  945. Since sapp_run() returns immediately on Emscripten you shouldn't activate
  946. the 'EXIT_RUNTIME' linker option (this is disabled by default when compiling
  947. for the browser target), since the C/C++ exit runtime would be called immediately at
  948. application start, causing any global objects to be destroyed and global
  949. variables to be zeroed.
  950. WINDOWS CONSOLE OUTPUT
  951. ======================
  952. On Windows, regular windowed applications don't show any stdout/stderr text
  953. output, which can be a bit of a hassle for printf() debugging or generally
  954. logging text to the console. Also, console output by default uses a local
  955. codepage setting and thus international UTF-8 encoded text is printed
  956. as garbage.
  957. To help with these issues, sokol_app.h can be configured at startup
  958. via the following Windows-specific sapp_desc flags:
  959. sapp_desc.win32.console_utf8 (default: false)
  960. When set to true, the output console codepage will be switched
  961. to UTF-8 (and restored to the original codepage on exit)
  962. sapp_desc.win32.console_attach (default: false)
  963. When set to true, stdout and stderr will be attached to the
  964. console of the parent process (if the parent process actually
  965. has a console). This means that if the application was started
  966. in a command line window, stdout and stderr output will be printed
  967. to the terminal, just like a regular command line program. But if
  968. the application is started via double-click, it will behave like
  969. a regular UI application, and stdout/stderr will not be visible.
  970. sapp_desc.win32.console_create (default: false)
  971. When set to true, a new console window will be created and
  972. stdout/stderr will be redirected to that console window. It
  973. doesn't matter if the application is started from the command
  974. line or via double-click.
  975. NOTE: setting both win32.console_attach and win32.console_create
  976. to true also makes sense and has the effect that output
  977. will appear in the existing terminal when started from the cmdline, and
  978. otherwise (when started via double-click) will open a console window.
  979. MEMORY ALLOCATION OVERRIDE
  980. ==========================
  981. You can override the memory allocation functions at initialization time
  982. like this:
  983. void* my_alloc(size_t size, void* user_data) {
  984. return malloc(size);
  985. }
  986. void my_free(void* ptr, void* user_data) {
  987. free(ptr);
  988. }
  989. sapp_desc sokol_main(int argc, char* argv[]) {
  990. return (sapp_desc){
  991. // ...
  992. .allocator = {
  993. .alloc_fn = my_alloc,
  994. .free_fn = my_free,
  995. .user_data = ...,
  996. }
  997. };
  998. }
  999. If no overrides are provided, malloc and free will be used.
  1000. This only affects memory allocation calls done by sokol_app.h
  1001. itself though, not any allocations in OS libraries.
  1002. ERROR REPORTING AND LOGGING
  1003. ===========================
  1004. To get any logging information at all you need to provide a logging callback in the setup call
  1005. the easiest way is to use sokol_log.h:
  1006. #include "sokol_log.h"
  1007. sapp_desc sokol_main(int argc, char* argv[]) {
  1008. return (sapp_desc) {
  1009. ...
  1010. .logger.func = slog_func,
  1011. };
  1012. }
  1013. To override logging with your own callback, first write a logging function like this:
  1014. void my_log(const char* tag, // e.g. 'sapp'
  1015. uint32_t log_level, // 0=panic, 1=error, 2=warn, 3=info
  1016. uint32_t log_item_id, // SAPP_LOGITEM_*
  1017. const char* message_or_null, // a message string, may be nullptr in release mode
  1018. uint32_t line_nr, // line number in sokol_app.h
  1019. const char* filename_or_null, // source filename, may be nullptr in release mode
  1020. void* user_data)
  1021. {
  1022. ...
  1023. }
  1024. ...and then setup sokol-app like this:
  1025. sapp_desc sokol_main(int argc, char* argv[]) {
  1026. return (sapp_desc) {
  1027. ...
  1028. .logger = {
  1029. .func = my_log,
  1030. .user_data = my_user_data,
  1031. }
  1032. };
  1033. }
  1034. The provided logging function must be reentrant (e.g. be callable from
  1035. different threads).
  1036. If you don't want to provide your own custom logger it is highly recommended to use
  1037. the standard logger in sokol_log.h instead, otherwise you won't see any warnings or
  1038. errors.
  1039. TEMP NOTE DUMP
  1040. ==============
  1041. - sapp_desc needs a bool whether to initialize depth-stencil surface
  1042. - the Android implementation calls cleanup_cb() and destroys the egl context in onDestroy
  1043. at the latest but should do it earlier, in onStop, as an app is "killable" after onStop
  1044. on Android Honeycomb and later (it can't be done at the moment as the app may be started
  1045. again after onStop and the sokol lifecycle does not yet handle context teardown/bringup)
  1046. LICENSE
  1047. =======
  1048. zlib/libpng license
  1049. Copyright (c) 2018 Andre Weissflog
  1050. This software is provided 'as-is', without any express or implied warranty.
  1051. In no event will the authors be held liable for any damages arising from the
  1052. use of this software.
  1053. Permission is granted to anyone to use this software for any purpose,
  1054. including commercial applications, and to alter it and redistribute it
  1055. freely, subject to the following restrictions:
  1056. 1. The origin of this software must not be misrepresented; you must not
  1057. claim that you wrote the original software. If you use this software in a
  1058. product, an acknowledgment in the product documentation would be
  1059. appreciated but is not required.
  1060. 2. Altered source versions must be plainly marked as such, and must not
  1061. be misrepresented as being the original software.
  1062. 3. This notice may not be removed or altered from any source
  1063. distribution.
  1064. */
  1065. import "core:c"
  1066. _ :: c
  1067. SOKOL_DEBUG :: #config(SOKOL_DEBUG, ODIN_DEBUG)
  1068. DEBUG :: #config(SOKOL_APP_DEBUG, SOKOL_DEBUG)
  1069. USE_GL :: #config(SOKOL_USE_GL, false)
  1070. USE_DLL :: #config(SOKOL_DLL, false)
  1071. when ODIN_OS == .Windows {
  1072. when USE_DLL {
  1073. when USE_GL {
  1074. when DEBUG { foreign import sokol_app_clib { "../sokol_dll_windows_x64_gl_debug.lib" } }
  1075. else { foreign import sokol_app_clib { "../sokol_dll_windows_x64_gl_release.lib" } }
  1076. } else {
  1077. when DEBUG { foreign import sokol_app_clib { "../sokol_dll_windows_x64_d3d11_debug.lib" } }
  1078. else { foreign import sokol_app_clib { "../sokol_dll_windows_x64_d3d11_release.lib" } }
  1079. }
  1080. } else {
  1081. when USE_GL {
  1082. when DEBUG { foreign import sokol_app_clib { "sokol_app_windows_x64_gl_debug.lib" } }
  1083. else { foreign import sokol_app_clib { "sokol_app_windows_x64_gl_release.lib" } }
  1084. } else {
  1085. when DEBUG { foreign import sokol_app_clib { "sokol_app_windows_x64_d3d11_debug.lib" } }
  1086. else { foreign import sokol_app_clib { "sokol_app_windows_x64_d3d11_release.lib" } }
  1087. }
  1088. }
  1089. } else when ODIN_OS == .Darwin {
  1090. when USE_DLL {
  1091. when USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_app_clib { "../dylib/sokol_dylib_macos_arm64_gl_debug.dylib" } }
  1092. else when USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_app_clib { "../dylib/sokol_dylib_macos_arm64_gl_release.dylib" } }
  1093. else when USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_app_clib { "../dylib/sokol_dylib_macos_x64_gl_debug.dylib" } }
  1094. else when USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_app_clib { "../dylib/sokol_dylib_macos_x64_gl_release.dylib" } }
  1095. else when !USE_GL && ODIN_ARCH == .arm64 && DEBUG { foreign import sokol_app_clib { "../dylib/sokol_dylib_macos_arm64_metal_debug.dylib" } }
  1096. else when !USE_GL && ODIN_ARCH == .arm64 && !DEBUG { foreign import sokol_app_clib { "../dylib/sokol_dylib_macos_arm64_metal_release.dylib" } }
  1097. else when !USE_GL && ODIN_ARCH == .amd64 && DEBUG { foreign import sokol_app_clib { "../dylib/sokol_dylib_macos_x64_metal_debug.dylib" } }
  1098. else when !USE_GL && ODIN_ARCH == .amd64 && !DEBUG { foreign import sokol_app_clib { "../dylib/sokol_dylib_macos_x64_metal_release.dylib" } }
  1099. } else {
  1100. when USE_GL {
  1101. when ODIN_ARCH == .arm64 {
  1102. when DEBUG { foreign import sokol_app_clib { "sokol_app_macos_arm64_gl_debug.a", "system:Cocoa.framework","system:QuartzCore.framework","system:OpenGL.framework" } }
  1103. else { foreign import sokol_app_clib { "sokol_app_macos_arm64_gl_release.a", "system:Cocoa.framework","system:QuartzCore.framework","system:OpenGL.framework" } }
  1104. } else {
  1105. when DEBUG { foreign import sokol_app_clib { "sokol_app_macos_x64_gl_debug.a", "system:Cocoa.framework","system:QuartzCore.framework","system:OpenGL.framework" } }
  1106. else { foreign import sokol_app_clib { "sokol_app_macos_x64_gl_release.a", "system:Cocoa.framework","system:QuartzCore.framework","system:OpenGL.framework" } }
  1107. }
  1108. } else {
  1109. when ODIN_ARCH == .arm64 {
  1110. when DEBUG { foreign import sokol_app_clib { "sokol_app_macos_arm64_metal_debug.a", "system:Cocoa.framework","system:QuartzCore.framework","system:Metal.framework","system:MetalKit.framework" } }
  1111. else { foreign import sokol_app_clib { "sokol_app_macos_arm64_metal_release.a", "system:Cocoa.framework","system:QuartzCore.framework","system:Metal.framework","system:MetalKit.framework" } }
  1112. } else {
  1113. when DEBUG { foreign import sokol_app_clib { "sokol_app_macos_x64_metal_debug.a", "system:Cocoa.framework","system:QuartzCore.framework","system:Metal.framework","system:MetalKit.framework" } }
  1114. else { foreign import sokol_app_clib { "sokol_app_macos_x64_metal_release.a", "system:Cocoa.framework","system:QuartzCore.framework","system:Metal.framework","system:MetalKit.framework" } }
  1115. }
  1116. }
  1117. }
  1118. } else when ODIN_OS == .Linux {
  1119. when USE_DLL {
  1120. when DEBUG { foreign import sokol_app_clib { "sokol_app_linux_x64_gl_debug.so", "system:X11", "system:Xi", "system:Xcursor", "system:GL", "system:dl", "system:pthread" } }
  1121. else { foreign import sokol_app_clib { "sokol_app_linux_x64_gl_release.so", "system:X11", "system:Xi", "system:Xcursor", "system:GL", "system:dl", "system:pthread" } }
  1122. } else {
  1123. when DEBUG { foreign import sokol_app_clib { "sokol_app_linux_x64_gl_debug.a", "system:X11", "system:Xi", "system:Xcursor", "system:GL", "system:dl", "system:pthread" } }
  1124. else { foreign import sokol_app_clib { "sokol_app_linux_x64_gl_release.a", "system:X11", "system:Xi", "system:Xcursor", "system:GL", "system:dl", "system:pthread" } }
  1125. }
  1126. } else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
  1127. // Feed sokol_app_wasm_gl_debug.a or sokol_app_wasm_gl_release.a into emscripten compiler.
  1128. foreign import sokol_app_clib { "env.o" }
  1129. } else {
  1130. #panic("This OS is currently not supported")
  1131. }
  1132. @(default_calling_convention="c", link_prefix="sapp_")
  1133. foreign sokol_app_clib {
  1134. // returns true after sokol-app has been initialized
  1135. isvalid :: proc() -> bool ---
  1136. // returns the current framebuffer width in pixels
  1137. width :: proc() -> c.int ---
  1138. // same as sapp_width(), but returns float
  1139. widthf :: proc() -> f32 ---
  1140. // returns the current framebuffer height in pixels
  1141. height :: proc() -> c.int ---
  1142. // same as sapp_height(), but returns float
  1143. heightf :: proc() -> f32 ---
  1144. // get default framebuffer color pixel format
  1145. color_format :: proc() -> Pixel_Format ---
  1146. // get default framebuffer depth pixel format
  1147. depth_format :: proc() -> Pixel_Format ---
  1148. // get default framebuffer sample count
  1149. sample_count :: proc() -> c.int ---
  1150. // returns true when high_dpi was requested and actually running in a high-dpi scenario
  1151. high_dpi :: proc() -> bool ---
  1152. // returns the dpi scaling factor (window pixels to framebuffer pixels)
  1153. dpi_scale :: proc() -> f32 ---
  1154. // show or hide the mobile device onscreen keyboard
  1155. show_keyboard :: proc(show: bool) ---
  1156. // return true if the mobile device onscreen keyboard is currently shown
  1157. keyboard_shown :: proc() -> bool ---
  1158. // query fullscreen mode
  1159. is_fullscreen :: proc() -> bool ---
  1160. // toggle fullscreen mode
  1161. toggle_fullscreen :: proc() ---
  1162. // show or hide the mouse cursor
  1163. show_mouse :: proc(show: bool) ---
  1164. // show or hide the mouse cursor
  1165. mouse_shown :: proc() -> bool ---
  1166. // enable/disable mouse-pointer-lock mode
  1167. lock_mouse :: proc(lock: bool) ---
  1168. // return true if in mouse-pointer-lock mode (this may toggle a few frames later)
  1169. mouse_locked :: proc() -> bool ---
  1170. // set mouse cursor type
  1171. set_mouse_cursor :: proc(cursor: Mouse_Cursor) ---
  1172. // get current mouse cursor type
  1173. get_mouse_cursor :: proc() -> Mouse_Cursor ---
  1174. // associate a custom mouse cursor image to a sapp_mouse_cursor enum entry
  1175. bind_mouse_cursor_image :: proc(cursor: Mouse_Cursor, #by_ptr desc: Image_Desc) -> Mouse_Cursor ---
  1176. // restore the sapp_mouse_cursor enum entry to it's default system appearance
  1177. unbind_mouse_cursor_image :: proc(cursor: Mouse_Cursor) ---
  1178. // return the userdata pointer optionally provided in sapp_desc
  1179. userdata :: proc() -> rawptr ---
  1180. // return a copy of the sapp_desc structure
  1181. query_desc :: proc() -> Desc ---
  1182. // initiate a "soft quit" (sends SAPP_EVENTTYPE_QUIT_REQUESTED)
  1183. request_quit :: proc() ---
  1184. // cancel a pending quit (when SAPP_EVENTTYPE_QUIT_REQUESTED has been received)
  1185. cancel_quit :: proc() ---
  1186. // initiate a "hard quit" (quit application without sending SAPP_EVENTTYPE_QUIT_REQUESTED)
  1187. quit :: proc() ---
  1188. // call from inside event callback to consume the current event (don't forward to platform)
  1189. consume_event :: proc() ---
  1190. // get the current frame counter (for comparison with sapp_event.frame_count)
  1191. frame_count :: proc() -> u64 ---
  1192. // get an averaged/smoothed frame duration in seconds
  1193. frame_duration :: proc() -> f64 ---
  1194. // write string into clipboard
  1195. set_clipboard_string :: proc(str: cstring) ---
  1196. // read string from clipboard (usually during SAPP_EVENTTYPE_CLIPBOARD_PASTED)
  1197. get_clipboard_string :: proc() -> cstring ---
  1198. // set the window title (only on desktop platforms)
  1199. set_window_title :: proc(str: cstring) ---
  1200. // set the window icon (only on Windows and Linux)
  1201. set_icon :: proc(#by_ptr icon_desc: Icon_Desc) ---
  1202. // gets the total number of dropped files (after an SAPP_EVENTTYPE_FILES_DROPPED event)
  1203. get_num_dropped_files :: proc() -> c.int ---
  1204. // gets the dropped file paths
  1205. get_dropped_file_path :: proc(#any_int index: c.int) -> cstring ---
  1206. // special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub)
  1207. run :: proc(#by_ptr desc: Desc) ---
  1208. // get runtime environment information
  1209. get_environment :: proc() -> Environment ---
  1210. // get current frame's swapchain information (call once per frame!)
  1211. get_swapchain :: proc() -> Swapchain ---
  1212. // EGL: get EGLDisplay object
  1213. egl_get_display :: proc() -> rawptr ---
  1214. // EGL: get EGLContext object
  1215. egl_get_context :: proc() -> rawptr ---
  1216. // HTML5: enable or disable the hardwired "Leave Site?" dialog box
  1217. html5_ask_leave_site :: proc(ask: bool) ---
  1218. // HTML5: get byte size of a dropped file
  1219. html5_get_dropped_file_size :: proc(#any_int index: c.int) -> u32 ---
  1220. // HTML5: asynchronously load the content of a dropped file
  1221. html5_fetch_dropped_file :: proc(#by_ptr request: Html5_Fetch_Request) ---
  1222. // macOS: get bridged pointer to macOS NSWindow
  1223. macos_get_window :: proc() -> rawptr ---
  1224. // iOS: get bridged pointer to iOS UIWindow
  1225. ios_get_window :: proc() -> rawptr ---
  1226. // D3D11: get pointer to IDXGISwapChain object
  1227. d3d11_get_swap_chain :: proc() -> rawptr ---
  1228. // Win32: get the HWND window handle
  1229. win32_get_hwnd :: proc() -> rawptr ---
  1230. // GL: get major version
  1231. gl_get_major_version :: proc() -> c.int ---
  1232. // GL: get minor version
  1233. gl_get_minor_version :: proc() -> c.int ---
  1234. // GL: return true if the context is GLES
  1235. gl_is_gles :: proc() -> bool ---
  1236. // X11: get Window
  1237. x11_get_window :: proc() -> rawptr ---
  1238. // X11: get Display
  1239. x11_get_display :: proc() -> rawptr ---
  1240. // Android: get native activity handle
  1241. android_get_native_activity :: proc() -> rawptr ---
  1242. }
  1243. // misc constants
  1244. MAX_TOUCHPOINTS :: 8
  1245. MAX_MOUSEBUTTONS :: 3
  1246. MAX_KEYCODES :: 512
  1247. MAX_ICONIMAGES :: 8
  1248. /*
  1249. sapp_event_type
  1250. The type of event that's passed to the event handler callback
  1251. in the sapp_event.type field. These are not just "traditional"
  1252. input events, but also notify the application about state changes
  1253. or other user-invoked actions.
  1254. */
  1255. Event_Type :: enum i32 {
  1256. INVALID,
  1257. KEY_DOWN,
  1258. KEY_UP,
  1259. CHAR,
  1260. MOUSE_DOWN,
  1261. MOUSE_UP,
  1262. MOUSE_SCROLL,
  1263. MOUSE_MOVE,
  1264. MOUSE_ENTER,
  1265. MOUSE_LEAVE,
  1266. TOUCHES_BEGAN,
  1267. TOUCHES_MOVED,
  1268. TOUCHES_ENDED,
  1269. TOUCHES_CANCELLED,
  1270. RESIZED,
  1271. ICONIFIED,
  1272. RESTORED,
  1273. FOCUSED,
  1274. UNFOCUSED,
  1275. SUSPENDED,
  1276. RESUMED,
  1277. QUIT_REQUESTED,
  1278. CLIPBOARD_PASTED,
  1279. FILES_DROPPED,
  1280. }
  1281. /*
  1282. sapp_keycode
  1283. The 'virtual keycode' of a KEY_DOWN or KEY_UP event in the
  1284. struct field sapp_event.key_code.
  1285. Note that the keycode values are identical with GLFW.
  1286. */
  1287. Keycode :: enum i32 {
  1288. INVALID = 0,
  1289. SPACE = 32,
  1290. APOSTROPHE = 39,
  1291. COMMA = 44,
  1292. MINUS = 45,
  1293. PERIOD = 46,
  1294. SLASH = 47,
  1295. _0 = 48,
  1296. _1 = 49,
  1297. _2 = 50,
  1298. _3 = 51,
  1299. _4 = 52,
  1300. _5 = 53,
  1301. _6 = 54,
  1302. _7 = 55,
  1303. _8 = 56,
  1304. _9 = 57,
  1305. SEMICOLON = 59,
  1306. EQUAL = 61,
  1307. A = 65,
  1308. B = 66,
  1309. C = 67,
  1310. D = 68,
  1311. E = 69,
  1312. F = 70,
  1313. G = 71,
  1314. H = 72,
  1315. I = 73,
  1316. J = 74,
  1317. K = 75,
  1318. L = 76,
  1319. M = 77,
  1320. N = 78,
  1321. O = 79,
  1322. P = 80,
  1323. Q = 81,
  1324. R = 82,
  1325. S = 83,
  1326. T = 84,
  1327. U = 85,
  1328. V = 86,
  1329. W = 87,
  1330. X = 88,
  1331. Y = 89,
  1332. Z = 90,
  1333. LEFT_BRACKET = 91,
  1334. BACKSLASH = 92,
  1335. RIGHT_BRACKET = 93,
  1336. GRAVE_ACCENT = 96,
  1337. WORLD_1 = 161,
  1338. WORLD_2 = 162,
  1339. ESCAPE = 256,
  1340. ENTER = 257,
  1341. TAB = 258,
  1342. BACKSPACE = 259,
  1343. INSERT = 260,
  1344. DELETE = 261,
  1345. RIGHT = 262,
  1346. LEFT = 263,
  1347. DOWN = 264,
  1348. UP = 265,
  1349. PAGE_UP = 266,
  1350. PAGE_DOWN = 267,
  1351. HOME = 268,
  1352. END = 269,
  1353. CAPS_LOCK = 280,
  1354. SCROLL_LOCK = 281,
  1355. NUM_LOCK = 282,
  1356. PRINT_SCREEN = 283,
  1357. PAUSE = 284,
  1358. F1 = 290,
  1359. F2 = 291,
  1360. F3 = 292,
  1361. F4 = 293,
  1362. F5 = 294,
  1363. F6 = 295,
  1364. F7 = 296,
  1365. F8 = 297,
  1366. F9 = 298,
  1367. F10 = 299,
  1368. F11 = 300,
  1369. F12 = 301,
  1370. F13 = 302,
  1371. F14 = 303,
  1372. F15 = 304,
  1373. F16 = 305,
  1374. F17 = 306,
  1375. F18 = 307,
  1376. F19 = 308,
  1377. F20 = 309,
  1378. F21 = 310,
  1379. F22 = 311,
  1380. F23 = 312,
  1381. F24 = 313,
  1382. F25 = 314,
  1383. KP_0 = 320,
  1384. KP_1 = 321,
  1385. KP_2 = 322,
  1386. KP_3 = 323,
  1387. KP_4 = 324,
  1388. KP_5 = 325,
  1389. KP_6 = 326,
  1390. KP_7 = 327,
  1391. KP_8 = 328,
  1392. KP_9 = 329,
  1393. KP_DECIMAL = 330,
  1394. KP_DIVIDE = 331,
  1395. KP_MULTIPLY = 332,
  1396. KP_SUBTRACT = 333,
  1397. KP_ADD = 334,
  1398. KP_ENTER = 335,
  1399. KP_EQUAL = 336,
  1400. LEFT_SHIFT = 340,
  1401. LEFT_CONTROL = 341,
  1402. LEFT_ALT = 342,
  1403. LEFT_SUPER = 343,
  1404. RIGHT_SHIFT = 344,
  1405. RIGHT_CONTROL = 345,
  1406. RIGHT_ALT = 346,
  1407. RIGHT_SUPER = 347,
  1408. MENU = 348,
  1409. }
  1410. /*
  1411. Android specific 'tool type' enum for touch events. This lets the
  1412. application check what type of input device was used for
  1413. touch events.
  1414. NOTE: the values must remain in sync with the corresponding
  1415. Android SDK type, so don't change those.
  1416. See https://developer.android.com/reference/android/view/MotionEvent#TOOL_TYPE_UNKNOWN
  1417. */
  1418. Android_Tooltype :: enum i32 {
  1419. UNKNOWN = 0,
  1420. FINGER = 1,
  1421. STYLUS = 2,
  1422. MOUSE = 3,
  1423. }
  1424. /*
  1425. sapp_touchpoint
  1426. Describes a single touchpoint in a multitouch event (TOUCHES_BEGAN,
  1427. TOUCHES_MOVED, TOUCHES_ENDED).
  1428. Touch points are stored in the nested array sapp_event.touches[],
  1429. and the number of touches is stored in sapp_event.num_touches.
  1430. */
  1431. Touchpoint :: struct {
  1432. identifier : c.uintptr_t,
  1433. pos_x : f32,
  1434. pos_y : f32,
  1435. android_tooltype : Android_Tooltype,
  1436. changed : bool,
  1437. }
  1438. /*
  1439. sapp_mousebutton
  1440. The currently pressed mouse button in the events MOUSE_DOWN
  1441. and MOUSE_UP, stored in the struct field sapp_event.mouse_button.
  1442. */
  1443. Mousebutton :: enum i32 {
  1444. LEFT = 0,
  1445. RIGHT = 1,
  1446. MIDDLE = 2,
  1447. INVALID = 256,
  1448. }
  1449. /*
  1450. These are currently pressed modifier keys (and mouse buttons) which are
  1451. passed in the event struct field sapp_event.modifiers.
  1452. */
  1453. MODIFIER_SHIFT :: 1
  1454. MODIFIER_CTRL :: 2
  1455. MODIFIER_ALT :: 4
  1456. MODIFIER_SUPER :: 8
  1457. MODIFIER_LMB :: 256
  1458. MODIFIER_RMB :: 512
  1459. MODIFIER_MMB :: 1024
  1460. /*
  1461. sapp_event
  1462. This is an all-in-one event struct passed to the event handler
  1463. user callback function. Note that it depends on the event
  1464. type what struct fields actually contain useful values, so you
  1465. should first check the event type before reading other struct
  1466. fields.
  1467. */
  1468. Event :: struct {
  1469. frame_count : u64,
  1470. type : Event_Type,
  1471. key_code : Keycode,
  1472. char_code : u32,
  1473. key_repeat : bool,
  1474. modifiers : u32,
  1475. mouse_button : Mousebutton,
  1476. mouse_x : f32,
  1477. mouse_y : f32,
  1478. mouse_dx : f32,
  1479. mouse_dy : f32,
  1480. scroll_x : f32,
  1481. scroll_y : f32,
  1482. num_touches : c.int,
  1483. touches : [8]Touchpoint,
  1484. window_width : c.int,
  1485. window_height : c.int,
  1486. framebuffer_width : c.int,
  1487. framebuffer_height : c.int,
  1488. }
  1489. /*
  1490. sg_range
  1491. A general pointer/size-pair struct and constructor macros for passing binary blobs
  1492. into sokol_app.h.
  1493. */
  1494. Range :: struct {
  1495. ptr : rawptr,
  1496. size : c.size_t,
  1497. }
  1498. /*
  1499. sapp_image_desc
  1500. This is used to describe image data to sokol_app.h (window icons and cursor images).
  1501. The pixel format is RGBA8.
  1502. cursor_hotspot_x and _y are used only for cursors, to define which pixel
  1503. of the image should be aligned with the mouse position.
  1504. */
  1505. Image_Desc :: struct {
  1506. width : c.int,
  1507. height : c.int,
  1508. cursor_hotspot_x : c.int,
  1509. cursor_hotspot_y : c.int,
  1510. pixels : Range,
  1511. }
  1512. /*
  1513. sapp_icon_desc
  1514. An icon description structure for use in sapp_desc.icon and
  1515. sapp_set_icon().
  1516. When setting a custom image, the application can provide a number of
  1517. candidates differing in size, and sokol_app.h will pick the image(s)
  1518. closest to the size expected by the platform's window system.
  1519. To set sokol-app's default icon, set .sokol_default to true.
  1520. Otherwise provide candidate images of different sizes in the
  1521. images[] array.
  1522. If both the sokol_default flag is set to true, any image candidates
  1523. will be ignored and the sokol_app.h default icon will be set.
  1524. */
  1525. Icon_Desc :: struct {
  1526. sokol_default : bool,
  1527. images : [8]Image_Desc,
  1528. }
  1529. /*
  1530. sapp_allocator
  1531. Used in sapp_desc to provide custom memory-alloc and -free functions
  1532. to sokol_app.h. If memory management should be overridden, both the
  1533. alloc_fn and free_fn function must be provided (e.g. it's not valid to
  1534. override one function but not the other).
  1535. */
  1536. Allocator :: struct {
  1537. alloc_fn : proc "c" (a0: c.size_t, a1: rawptr) -> rawptr,
  1538. free_fn : proc "c" (a0: rawptr, a1: rawptr),
  1539. user_data : rawptr,
  1540. }
  1541. Log_Item :: enum i32 {
  1542. OK,
  1543. MALLOC_FAILED,
  1544. MACOS_INVALID_NSOPENGL_PROFILE,
  1545. WIN32_LOAD_OPENGL32_DLL_FAILED,
  1546. WIN32_CREATE_HELPER_WINDOW_FAILED,
  1547. WIN32_HELPER_WINDOW_GETDC_FAILED,
  1548. WIN32_DUMMY_CONTEXT_SET_PIXELFORMAT_FAILED,
  1549. WIN32_CREATE_DUMMY_CONTEXT_FAILED,
  1550. WIN32_DUMMY_CONTEXT_MAKE_CURRENT_FAILED,
  1551. WIN32_GET_PIXELFORMAT_ATTRIB_FAILED,
  1552. WIN32_WGL_FIND_PIXELFORMAT_FAILED,
  1553. WIN32_WGL_DESCRIBE_PIXELFORMAT_FAILED,
  1554. WIN32_WGL_SET_PIXELFORMAT_FAILED,
  1555. WIN32_WGL_ARB_CREATE_CONTEXT_REQUIRED,
  1556. WIN32_WGL_ARB_CREATE_CONTEXT_PROFILE_REQUIRED,
  1557. WIN32_WGL_OPENGL_VERSION_NOT_SUPPORTED,
  1558. WIN32_WGL_OPENGL_PROFILE_NOT_SUPPORTED,
  1559. WIN32_WGL_INCOMPATIBLE_DEVICE_CONTEXT,
  1560. WIN32_WGL_CREATE_CONTEXT_ATTRIBS_FAILED_OTHER,
  1561. WIN32_D3D11_CREATE_DEVICE_AND_SWAPCHAIN_WITH_DEBUG_FAILED,
  1562. WIN32_D3D11_GET_IDXGIFACTORY_FAILED,
  1563. WIN32_D3D11_GET_IDXGIADAPTER_FAILED,
  1564. WIN32_D3D11_QUERY_INTERFACE_IDXGIDEVICE1_FAILED,
  1565. WIN32_REGISTER_RAW_INPUT_DEVICES_FAILED_MOUSE_LOCK,
  1566. WIN32_REGISTER_RAW_INPUT_DEVICES_FAILED_MOUSE_UNLOCK,
  1567. WIN32_GET_RAW_INPUT_DATA_FAILED,
  1568. WIN32_DESTROYICON_FOR_CURSOR_FAILED,
  1569. LINUX_GLX_LOAD_LIBGL_FAILED,
  1570. LINUX_GLX_LOAD_ENTRY_POINTS_FAILED,
  1571. LINUX_GLX_EXTENSION_NOT_FOUND,
  1572. LINUX_GLX_QUERY_VERSION_FAILED,
  1573. LINUX_GLX_VERSION_TOO_LOW,
  1574. LINUX_GLX_NO_GLXFBCONFIGS,
  1575. LINUX_GLX_NO_SUITABLE_GLXFBCONFIG,
  1576. LINUX_GLX_GET_VISUAL_FROM_FBCONFIG_FAILED,
  1577. LINUX_GLX_REQUIRED_EXTENSIONS_MISSING,
  1578. LINUX_GLX_CREATE_CONTEXT_FAILED,
  1579. LINUX_GLX_CREATE_WINDOW_FAILED,
  1580. LINUX_X11_CREATE_WINDOW_FAILED,
  1581. LINUX_EGL_BIND_OPENGL_API_FAILED,
  1582. LINUX_EGL_BIND_OPENGL_ES_API_FAILED,
  1583. LINUX_EGL_GET_DISPLAY_FAILED,
  1584. LINUX_EGL_INITIALIZE_FAILED,
  1585. LINUX_EGL_NO_CONFIGS,
  1586. LINUX_EGL_NO_NATIVE_VISUAL,
  1587. LINUX_EGL_GET_VISUAL_INFO_FAILED,
  1588. LINUX_EGL_CREATE_WINDOW_SURFACE_FAILED,
  1589. LINUX_EGL_CREATE_CONTEXT_FAILED,
  1590. LINUX_EGL_MAKE_CURRENT_FAILED,
  1591. LINUX_X11_OPEN_DISPLAY_FAILED,
  1592. LINUX_X11_QUERY_SYSTEM_DPI_FAILED,
  1593. LINUX_X11_DROPPED_FILE_URI_WRONG_SCHEME,
  1594. LINUX_X11_FAILED_TO_BECOME_OWNER_OF_CLIPBOARD,
  1595. ANDROID_UNSUPPORTED_INPUT_EVENT_INPUT_CB,
  1596. ANDROID_UNSUPPORTED_INPUT_EVENT_MAIN_CB,
  1597. ANDROID_READ_MSG_FAILED,
  1598. ANDROID_WRITE_MSG_FAILED,
  1599. ANDROID_MSG_CREATE,
  1600. ANDROID_MSG_RESUME,
  1601. ANDROID_MSG_PAUSE,
  1602. ANDROID_MSG_FOCUS,
  1603. ANDROID_MSG_NO_FOCUS,
  1604. ANDROID_MSG_SET_NATIVE_WINDOW,
  1605. ANDROID_MSG_SET_INPUT_QUEUE,
  1606. ANDROID_MSG_DESTROY,
  1607. ANDROID_UNKNOWN_MSG,
  1608. ANDROID_LOOP_THREAD_STARTED,
  1609. ANDROID_LOOP_THREAD_DONE,
  1610. ANDROID_NATIVE_ACTIVITY_ONSTART,
  1611. ANDROID_NATIVE_ACTIVITY_ONRESUME,
  1612. ANDROID_NATIVE_ACTIVITY_ONSAVEINSTANCESTATE,
  1613. ANDROID_NATIVE_ACTIVITY_ONWINDOWFOCUSCHANGED,
  1614. ANDROID_NATIVE_ACTIVITY_ONPAUSE,
  1615. ANDROID_NATIVE_ACTIVITY_ONSTOP,
  1616. ANDROID_NATIVE_ACTIVITY_ONNATIVEWINDOWCREATED,
  1617. ANDROID_NATIVE_ACTIVITY_ONNATIVEWINDOWDESTROYED,
  1618. ANDROID_NATIVE_ACTIVITY_ONINPUTQUEUECREATED,
  1619. ANDROID_NATIVE_ACTIVITY_ONINPUTQUEUEDESTROYED,
  1620. ANDROID_NATIVE_ACTIVITY_ONCONFIGURATIONCHANGED,
  1621. ANDROID_NATIVE_ACTIVITY_ONLOWMEMORY,
  1622. ANDROID_NATIVE_ACTIVITY_ONDESTROY,
  1623. ANDROID_NATIVE_ACTIVITY_DONE,
  1624. ANDROID_NATIVE_ACTIVITY_ONCREATE,
  1625. ANDROID_CREATE_THREAD_PIPE_FAILED,
  1626. ANDROID_NATIVE_ACTIVITY_CREATE_SUCCESS,
  1627. WGPU_DEVICE_LOST,
  1628. WGPU_DEVICE_LOG,
  1629. WGPU_DEVICE_UNCAPTURED_ERROR,
  1630. WGPU_SWAPCHAIN_CREATE_SURFACE_FAILED,
  1631. WGPU_SWAPCHAIN_SURFACE_GET_CAPABILITIES_FAILED,
  1632. WGPU_SWAPCHAIN_CREATE_DEPTH_STENCIL_TEXTURE_FAILED,
  1633. WGPU_SWAPCHAIN_CREATE_DEPTH_STENCIL_VIEW_FAILED,
  1634. WGPU_SWAPCHAIN_CREATE_MSAA_TEXTURE_FAILED,
  1635. WGPU_SWAPCHAIN_CREATE_MSAA_VIEW_FAILED,
  1636. WGPU_SWAPCHAIN_GETCURRENTTEXTURE_FAILED,
  1637. WGPU_REQUEST_DEVICE_STATUS_ERROR,
  1638. WGPU_REQUEST_DEVICE_STATUS_UNKNOWN,
  1639. WGPU_REQUEST_ADAPTER_STATUS_UNAVAILABLE,
  1640. WGPU_REQUEST_ADAPTER_STATUS_ERROR,
  1641. WGPU_REQUEST_ADAPTER_STATUS_UNKNOWN,
  1642. WGPU_CREATE_INSTANCE_FAILED,
  1643. VULKAN_ALLOC_DEVICE_MEMORY_NO_SUITABLE_MEMORY_TYPE,
  1644. VULKAN_ALLOCATE_MEMORY_FAILED,
  1645. VULKAN_CREATE_INSTANCE_FAILED,
  1646. VULKAN_ENUMERATE_PHYSICAL_DEVICES_FAILED,
  1647. VULKAN_NO_PHYSICAL_DEVICES_FOUND,
  1648. VULKAN_NO_SUITABLE_PHYSICAL_DEVICE_FOUND,
  1649. VULKAN_CREATE_DEVICE_FAILED_EXTENSION_NOT_PRESENT,
  1650. VULKAN_CREATE_DEVICE_FAILED_FEATURE_NOT_PRESENT,
  1651. VULKAN_CREATE_DEVICE_FAILED_INITIALIZATION_FAILED,
  1652. VULKAN_CREATE_DEVICE_FAILED_OTHER,
  1653. VULKAN_CREATE_SURFACE_FAILED,
  1654. VULKAN_CREATE_SWAPCHAIN_FAILED,
  1655. VULKAN_SWAPCHAIN_CREATE_IMAGE_VIEW_FAILED,
  1656. VULKAN_SWAPCHAIN_CREATE_IMAGE_FAILED,
  1657. VULKAN_SWAPCHAIN_ALLOC_IMAGE_DEVICE_MEMORY_FAILED,
  1658. VULKAN_SWAPCHAIN_BIND_IMAGE_MEMORY_FAILED,
  1659. VULKAN_ACQUIRE_NEXT_IMAGE_FAILED,
  1660. VULKAN_QUEUE_PRESENT_FAILED,
  1661. IMAGE_DATA_SIZE_MISMATCH,
  1662. DROPPED_FILE_PATH_TOO_LONG,
  1663. CLIPBOARD_STRING_TOO_BIG,
  1664. }
  1665. /*
  1666. sapp_pixel_format
  1667. Defines the pixel format for swapchain surfaces.
  1668. NOTE: when using sokol_gfx.h do not assume that the underlying
  1669. values are compatible with sg_pixel_format!
  1670. */
  1671. Pixel_Format :: enum i32 {
  1672. DEFAULT,
  1673. NONE,
  1674. RGBA8,
  1675. SRGB8A8,
  1676. BGRA8,
  1677. SBGRA8,
  1678. DEPTH,
  1679. DEPTH_STENCIL,
  1680. }
  1681. /*
  1682. sapp_environment
  1683. Used to provide runtime environment information to the
  1684. outside world (like default pixel formats and the backend
  1685. 3D API device pointer) via a call to sapp_get_environment().
  1686. NOTE: when using sokol_gfx.h, don't assume that sapp_environment
  1687. is binary compatible with sg_environment! Always use a translation
  1688. function like sglue_environment() to populate sg_environment
  1689. from sapp_environment!
  1690. */
  1691. Environment_Defaults :: struct {
  1692. color_format : Pixel_Format,
  1693. depth_format : Pixel_Format,
  1694. sample_count : c.int,
  1695. }
  1696. Metal_Environment :: struct {
  1697. device : rawptr,
  1698. }
  1699. D3d11_Environment :: struct {
  1700. device : rawptr,
  1701. device_context : rawptr,
  1702. }
  1703. Wgpu_Environment :: struct {
  1704. device : rawptr,
  1705. }
  1706. Vulkan_Environment :: struct {
  1707. physical_device : rawptr,
  1708. device : rawptr,
  1709. queue : rawptr,
  1710. queue_family_index : u32,
  1711. }
  1712. Environment :: struct {
  1713. defaults : Environment_Defaults,
  1714. metal : Metal_Environment,
  1715. d3d11 : D3d11_Environment,
  1716. wgpu : Wgpu_Environment,
  1717. vulkan : Vulkan_Environment,
  1718. }
  1719. /*
  1720. sapp_swapchain
  1721. Provides swapchain information for the current frame to the outside
  1722. world via a call to sapp_get_swapchain().
  1723. NOTE: sapp_get_swapchain() must be called exactly once per frame since
  1724. on some backends it will also acquire the next swapchain image.
  1725. NOTE: when using sokol_gfx.h, don't assume that the sapp_swapchain struct
  1726. has the same memory layout as sg_swapchain! Use the sokol_log.h helper
  1727. function sglue_swapchain() to translate sapp_swapchain into a
  1728. sg_swapchain instead.
  1729. */
  1730. Metal_Swapchain :: struct {
  1731. current_drawable : rawptr,
  1732. depth_stencil_texture : rawptr,
  1733. msaa_color_texture : rawptr,
  1734. }
  1735. D3d11_Swapchain :: struct {
  1736. render_view : rawptr,
  1737. resolve_view : rawptr,
  1738. depth_stencil_view : rawptr,
  1739. }
  1740. Wgpu_Swapchain :: struct {
  1741. render_view : rawptr,
  1742. resolve_view : rawptr,
  1743. depth_stencil_view : rawptr,
  1744. }
  1745. Vulkan_Swapchain :: struct {
  1746. render_image : rawptr,
  1747. render_view : rawptr,
  1748. resolve_image : rawptr,
  1749. resolve_view : rawptr,
  1750. depth_stencil_image : rawptr,
  1751. depth_stencil_view : rawptr,
  1752. render_finished_semaphore : rawptr,
  1753. present_complete_semaphore : rawptr,
  1754. }
  1755. Gl_Swapchain :: struct {
  1756. framebuffer : u32,
  1757. }
  1758. Swapchain :: struct {
  1759. width : c.int,
  1760. height : c.int,
  1761. sample_count : c.int,
  1762. color_format : Pixel_Format,
  1763. depth_format : Pixel_Format,
  1764. metal : Metal_Swapchain,
  1765. d3d11 : D3d11_Swapchain,
  1766. wgpu : Wgpu_Swapchain,
  1767. vulkan : Vulkan_Swapchain,
  1768. gl : Gl_Swapchain,
  1769. }
  1770. /*
  1771. sapp_logger
  1772. Used in sapp_desc to provide a logging function. Please be aware that
  1773. without logging function, sokol-app will be completely silent, e.g. it will
  1774. not report errors or warnings. For maximum error verbosity, compile in
  1775. debug mode (e.g. NDEBUG *not* defined) and install a logger (for instance
  1776. the standard logging function from sokol_log.h).
  1777. */
  1778. Logger :: struct {
  1779. func : proc "c" (a0: cstring, a1: u32, a2: u32, a3: cstring, a4: u32, a5: cstring, a6: rawptr),
  1780. user_data : rawptr,
  1781. }
  1782. /*
  1783. sokol-app initialization options, used as return value of sokol_main()
  1784. or sapp_run() argument.
  1785. */
  1786. Gl_Desc :: struct {
  1787. major_version : c.int,
  1788. minor_version : c.int,
  1789. }
  1790. Win32_Desc :: struct {
  1791. console_utf8 : bool,
  1792. console_create : bool,
  1793. console_attach : bool,
  1794. }
  1795. Html5_Desc :: struct {
  1796. canvas_selector : cstring,
  1797. canvas_resize : bool,
  1798. preserve_drawing_buffer : bool,
  1799. premultiplied_alpha : bool,
  1800. ask_leave_site : bool,
  1801. update_document_title : bool,
  1802. bubble_mouse_events : bool,
  1803. bubble_touch_events : bool,
  1804. bubble_wheel_events : bool,
  1805. bubble_key_events : bool,
  1806. bubble_char_events : bool,
  1807. use_emsc_set_main_loop : bool,
  1808. emsc_set_main_loop_simulate_infinite_loop : bool,
  1809. }
  1810. Ios_Desc :: struct {
  1811. keyboard_resizes_canvas : bool,
  1812. }
  1813. Desc :: struct {
  1814. init_cb : proc "c" (),
  1815. frame_cb : proc "c" (),
  1816. cleanup_cb : proc "c" (),
  1817. event_cb : proc "c" (a0: ^Event),
  1818. user_data : rawptr,
  1819. init_userdata_cb : proc "c" (a0: rawptr),
  1820. frame_userdata_cb : proc "c" (a0: rawptr),
  1821. cleanup_userdata_cb : proc "c" (a0: rawptr),
  1822. event_userdata_cb : proc "c" (a0: ^Event, a1: rawptr),
  1823. width : c.int,
  1824. height : c.int,
  1825. sample_count : c.int,
  1826. swap_interval : c.int,
  1827. high_dpi : bool,
  1828. fullscreen : bool,
  1829. alpha : bool,
  1830. window_title : cstring,
  1831. enable_clipboard : bool,
  1832. clipboard_size : c.int,
  1833. enable_dragndrop : bool,
  1834. max_dropped_files : c.int,
  1835. max_dropped_file_path_length : c.int,
  1836. icon : Icon_Desc,
  1837. allocator : Allocator,
  1838. logger : Logger,
  1839. gl : Gl_Desc,
  1840. win32 : Win32_Desc,
  1841. html5 : Html5_Desc,
  1842. ios : Ios_Desc,
  1843. }
  1844. /*
  1845. HTML5 specific: request and response structs for
  1846. asynchronously loading dropped-file content.
  1847. */
  1848. Html5_Fetch_Error :: enum i32 {
  1849. FETCH_ERROR_NO_ERROR,
  1850. FETCH_ERROR_BUFFER_TOO_SMALL,
  1851. FETCH_ERROR_OTHER,
  1852. }
  1853. Html5_Fetch_Response :: struct {
  1854. succeeded : bool,
  1855. error_code : Html5_Fetch_Error,
  1856. file_index : c.int,
  1857. data : Range,
  1858. buffer : Range,
  1859. user_data : rawptr,
  1860. }
  1861. Html5_Fetch_Request :: struct {
  1862. dropped_file_index : c.int,
  1863. callback : proc "c" (a0: ^Html5_Fetch_Response),
  1864. buffer : Range,
  1865. user_data : rawptr,
  1866. }
  1867. /*
  1868. sapp_mouse_cursor
  1869. Predefined cursor image definitions, set with sapp_set_mouse_cursor(sapp_mouse_cursor cursor)
  1870. */
  1871. Mouse_Cursor :: enum i32 {
  1872. DEFAULT = 0,
  1873. ARROW,
  1874. IBEAM,
  1875. CROSSHAIR,
  1876. POINTING_HAND,
  1877. RESIZE_EW,
  1878. RESIZE_NS,
  1879. RESIZE_NWSE,
  1880. RESIZE_NESW,
  1881. RESIZE_ALL,
  1882. NOT_ALLOWED,
  1883. CUSTOM_0,
  1884. CUSTOM_1,
  1885. CUSTOM_2,
  1886. CUSTOM_3,
  1887. CUSTOM_4,
  1888. CUSTOM_5,
  1889. CUSTOM_6,
  1890. CUSTOM_7,
  1891. CUSTOM_8,
  1892. CUSTOM_9,
  1893. CUSTOM_10,
  1894. CUSTOM_11,
  1895. CUSTOM_12,
  1896. CUSTOM_13,
  1897. CUSTOM_14,
  1898. CUSTOM_15,
  1899. }