Update C sources

This commit is contained in:
Milan Nikolic 2022-10-23 14:21:08 +02:00
parent a460a0fc06
commit 1b0affeed0
No known key found for this signature in database
GPG key ID: 9229D0EAA3AA4E75
96 changed files with 26693 additions and 11843 deletions

170
raylib/external/glad.h vendored
View file

@ -1,9 +1,9 @@
/** /**
* Loader generated by glad 2.0.0-beta on Sun Oct 17 18:39:09 2021 * Loader generated by glad 2.0.0-beta on Sun Sep 18 18:12:12 2022
* *
* Generator: C/C++ * Generator: C/C++
* Specification: gl * Specification: gl
* Extensions: 110 * Extensions: 116
* *
* APIs: * APIs:
* - gl:core=4.3 * - gl:core=4.3
@ -12,16 +12,16 @@
* - ALIAS = False * - ALIAS = False
* - DEBUG = False * - DEBUG = False
* - HEADER_ONLY = True * - HEADER_ONLY = True
* - LOADER = True * - LOADER = False
* - MX = False * - MX = False
* - MX_GLOBAL = False * - MX_GLOBAL = False
* - ON_DEMAND = False * - ON_DEMAND = False
* *
* Commandline: * Commandline:
* --api='gl:core=4.3' --extensions='GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_map_buffer_range,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_pipeline_statistics_query,GL_ARB_query_buffer_object,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_texture_lod,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_spirv_extensions,GL_ARB_tessellation_shader,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_compression,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_rg,GL_ARB_texture_storage,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_OES_compressed_paletted_texture,GL_OES_fixed_point' c --header-only --loader * --api='gl:core=4.3' --extensions='GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_map_buffer_range,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_pipeline_statistics_query,GL_ARB_query_buffer_object,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_texture_lod,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_spirv_extensions,GL_ARB_tessellation_shader,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_compression,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_rg,GL_ARB_texture_storage,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_EXT_draw_instanced,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_mirror_clamp,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_OES_compressed_paletted_texture,GL_OES_fixed_point' c --header-only
* *
* Online: * Online:
* http://glad.sh/#api=gl%3Acore%3D4.3&generator=c&options=HEADER_ONLY%2CLOADER * http://glad.sh/#api=gl%3Acore%3D4.3&generator=c&options=HEADER_ONLY
* *
*/ */
@ -54,7 +54,6 @@
#define GLAD_GL #define GLAD_GL
#define GLAD_OPTION_GL_HEADER_ONLY #define GLAD_OPTION_GL_HEADER_ONLY
#define GLAD_OPTION_GL_LOADER
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -381,11 +380,25 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_COMPRESSED_RGBA 0x84EE #define GL_COMPRESSED_RGBA 0x84EE
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
#define GL_COMPRESSED_RGBA_ARB 0x84EE #define GL_COMPRESSED_RGBA_ARB 0x84EE
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C #define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
#define GL_COMPRESSED_RGB_ARB 0x84ED
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#define GL_COMPRESSED_RGB_ARB 0x84ED
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
@ -395,6 +408,20 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 #define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE #define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
#define GL_COMPRESSED_SRGB 0x8C48 #define GL_COMPRESSED_SRGB 0x8C48
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 #define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
#define GL_COMPRESSED_SRGB8_ETC2 0x9275 #define GL_COMPRESSED_SRGB8_ETC2 0x9275
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 #define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
@ -1067,6 +1094,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 #define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD #define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF #define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
#define GL_MAX_TEXTURE_SIZE 0x0D33 #define GL_MAX_TEXTURE_SIZE 0x0D33
#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 #define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 #define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
@ -1113,7 +1141,10 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_MIPMAP 0x8293 #define GL_MIPMAP 0x8293
#define GL_MIRRORED_REPEAT 0x8370 #define GL_MIRRORED_REPEAT 0x8370
#define GL_MIRRORED_REPEAT_ARB 0x8370 #define GL_MIRRORED_REPEAT_ARB 0x8370
#define GL_MIRROR_CLAMP_EXT 0x8742
#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 #define GL_MIRROR_CLAMP_TO_EDGE 0x8743
#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
#define GL_MULTISAMPLE 0x809D #define GL_MULTISAMPLE 0x809D
#define GL_MULTISAMPLE_ARB 0x809D #define GL_MULTISAMPLE_ARB 0x809D
#define GL_MULTISAMPLE_BIT_ARB 0x20000000 #define GL_MULTISAMPLE_BIT_ARB 0x20000000
@ -1749,6 +1780,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 #define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
#define GL_TEXTURE_MAG_FILTER 0x2800 #define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE #define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
#define GL_TEXTURE_MAX_LEVEL 0x813D #define GL_TEXTURE_MAX_LEVEL 0x813D
#define GL_TEXTURE_MAX_LOD 0x813B #define GL_TEXTURE_MAX_LOD 0x813B
#define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_TEXTURE_MIN_FILTER 0x2801
@ -2159,6 +2191,20 @@ typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t; typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1 #define KHRONOS_SUPPORT_FLOAT 1
/*
* To support platform where unsigned long cannot be used interchangeably with
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
* unsigned long long or similar (this results in different C++ name mangling).
* To avoid changes for existing platforms, we restrict usage of intptr_t to
* platforms where the size of a pointer is larger than the size of long.
*/
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
#define KHRONOS_USE_INTPTR_T
#endif
#endif
#elif defined(__VMS ) || defined(__sgi) #elif defined(__VMS ) || defined(__sgi)
@ -2241,14 +2287,21 @@ typedef unsigned short int khronos_uint16_t;
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use. * to be the only LLP64 architecture in current use.
*/ */
#ifdef _WIN64 #ifdef KHRONOS_USE_INTPTR_T
typedef intptr_t khronos_intptr_t;
typedef uintptr_t khronos_uintptr_t;
#elif defined(_WIN64)
typedef signed long long int khronos_intptr_t; typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t; typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else #else
typedef signed long int khronos_intptr_t; typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t; typedef unsigned long int khronos_uintptr_t;
#endif
#if defined(_WIN64)
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_ssize_t; typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t; typedef unsigned long int khronos_usize_t;
#endif #endif
@ -2294,113 +2347,70 @@ typedef enum {
} khronos_boolean_enum_t; } khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */ #endif /* __khrplatform_h_ */
typedef unsigned int GLenum; typedef unsigned int GLenum;
typedef unsigned char GLboolean; typedef unsigned char GLboolean;
typedef unsigned int GLbitfield; typedef unsigned int GLbitfield;
typedef void GLvoid; typedef void GLvoid;
typedef khronos_int8_t GLbyte; typedef khronos_int8_t GLbyte;
typedef khronos_uint8_t GLubyte; typedef khronos_uint8_t GLubyte;
typedef khronos_int16_t GLshort; typedef khronos_int16_t GLshort;
typedef khronos_uint16_t GLushort; typedef khronos_uint16_t GLushort;
typedef int GLint; typedef int GLint;
typedef unsigned int GLuint; typedef unsigned int GLuint;
typedef khronos_int32_t GLclampx; typedef khronos_int32_t GLclampx;
typedef int GLsizei; typedef int GLsizei;
typedef khronos_float_t GLfloat; typedef khronos_float_t GLfloat;
typedef khronos_float_t GLclampf; typedef khronos_float_t GLclampf;
typedef double GLdouble; typedef double GLdouble;
typedef double GLclampd; typedef double GLclampd;
typedef void *GLeglClientBufferEXT; typedef void *GLeglClientBufferEXT;
typedef void *GLeglImageOES; typedef void *GLeglImageOES;
typedef char GLchar; typedef char GLchar;
typedef char GLcharARB; typedef char GLcharARB;
#ifdef __APPLE__ #ifdef __APPLE__
typedef void *GLhandleARB; typedef void *GLhandleARB;
#else #else
typedef unsigned int GLhandleARB; typedef unsigned int GLhandleARB;
#endif #endif
typedef khronos_uint16_t GLhalf; typedef khronos_uint16_t GLhalf;
typedef khronos_uint16_t GLhalfARB; typedef khronos_uint16_t GLhalfARB;
typedef khronos_int32_t GLfixed; typedef khronos_int32_t GLfixed;
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_intptr_t GLintptr; typedef khronos_intptr_t GLintptr;
#else #else
typedef khronos_intptr_t GLintptr; typedef khronos_intptr_t GLintptr;
#endif #endif
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_intptr_t GLintptrARB; typedef khronos_intptr_t GLintptrARB;
#else #else
typedef khronos_intptr_t GLintptrARB; typedef khronos_intptr_t GLintptrARB;
#endif #endif
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_ssize_t GLsizeiptr; typedef khronos_ssize_t GLsizeiptr;
#else #else
typedef khronos_ssize_t GLsizeiptr; typedef khronos_ssize_t GLsizeiptr;
#endif #endif
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_ssize_t GLsizeiptrARB; typedef khronos_ssize_t GLsizeiptrARB;
#else #else
typedef khronos_ssize_t GLsizeiptrARB; typedef khronos_ssize_t GLsizeiptrARB;
#endif #endif
typedef khronos_int64_t GLint64; typedef khronos_int64_t GLint64;
typedef khronos_int64_t GLint64EXT; typedef khronos_int64_t GLint64EXT;
typedef khronos_uint64_t GLuint64; typedef khronos_uint64_t GLuint64;
typedef khronos_uint64_t GLuint64EXT; typedef khronos_uint64_t GLuint64EXT;
typedef struct __GLsync *GLsync; typedef struct __GLsync *GLsync;
struct _cl_context; struct _cl_context;
struct _cl_event; struct _cl_event;
typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
typedef unsigned short GLhalfNV; typedef unsigned short GLhalfNV;
typedef GLintptr GLvdpauSurfaceNV; typedef GLintptr GLvdpauSurfaceNV;
typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void);
#define GL_VERSION_1_0 1 #define GL_VERSION_1_0 1
GLAD_API_CALL int GLAD_GL_VERSION_1_0; GLAD_API_CALL int GLAD_GL_VERSION_1_0;
#define GL_VERSION_1_1 1 #define GL_VERSION_1_1 1
@ -2593,8 +2603,6 @@ GLAD_API_CALL int GLAD_GL_ARB_texture_border_clamp;
GLAD_API_CALL int GLAD_GL_ARB_texture_buffer_object_rgb32; GLAD_API_CALL int GLAD_GL_ARB_texture_buffer_object_rgb32;
#define GL_ARB_texture_compression 1 #define GL_ARB_texture_compression 1
GLAD_API_CALL int GLAD_GL_ARB_texture_compression; GLAD_API_CALL int GLAD_GL_ARB_texture_compression;
#define GL_EXT_texture_compression_s3tc 1
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc;
#define GL_ARB_texture_cube_map 1 #define GL_ARB_texture_cube_map 1
GLAD_API_CALL int GLAD_GL_ARB_texture_cube_map; GLAD_API_CALL int GLAD_GL_ARB_texture_cube_map;
#define GL_ARB_texture_cube_map_array 1 #define GL_ARB_texture_cube_map_array 1
@ -2641,6 +2649,8 @@ GLAD_API_CALL int GLAD_GL_ARB_vertex_buffer_object;
GLAD_API_CALL int GLAD_GL_ARB_vertex_program; GLAD_API_CALL int GLAD_GL_ARB_vertex_program;
#define GL_ARB_vertex_shader 1 #define GL_ARB_vertex_shader 1
GLAD_API_CALL int GLAD_GL_ARB_vertex_shader; GLAD_API_CALL int GLAD_GL_ARB_vertex_shader;
#define GL_EXT_draw_instanced 1
GLAD_API_CALL int GLAD_GL_EXT_draw_instanced;
#define GL_EXT_fog_coord 1 #define GL_EXT_fog_coord 1
GLAD_API_CALL int GLAD_GL_EXT_fog_coord; GLAD_API_CALL int GLAD_GL_EXT_fog_coord;
#define GL_EXT_framebuffer_blit 1 #define GL_EXT_framebuffer_blit 1
@ -2651,6 +2661,16 @@ GLAD_API_CALL int GLAD_GL_EXT_framebuffer_multisample;
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_object; GLAD_API_CALL int GLAD_GL_EXT_framebuffer_object;
#define GL_EXT_framebuffer_sRGB 1 #define GL_EXT_framebuffer_sRGB 1
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_sRGB; GLAD_API_CALL int GLAD_GL_EXT_framebuffer_sRGB;
#define GL_EXT_texture_compression_s3tc 1
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc;
#define GL_EXT_texture_filter_anisotropic 1
GLAD_API_CALL int GLAD_GL_EXT_texture_filter_anisotropic;
#define GL_EXT_texture_mirror_clamp 1
GLAD_API_CALL int GLAD_GL_EXT_texture_mirror_clamp;
#define GL_KHR_texture_compression_astc_hdr 1
GLAD_API_CALL int GLAD_GL_KHR_texture_compression_astc_hdr;
#define GL_KHR_texture_compression_astc_ldr 1
GLAD_API_CALL int GLAD_GL_KHR_texture_compression_astc_ldr;
#define GL_OES_compressed_paletted_texture 1 #define GL_OES_compressed_paletted_texture 1
GLAD_API_CALL int GLAD_GL_OES_compressed_paletted_texture; GLAD_API_CALL int GLAD_GL_OES_compressed_paletted_texture;
#define GL_OES_fixed_point 1 #define GL_OES_fixed_point 1
@ -2848,6 +2868,7 @@ typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void
typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDARBPROC)(GLenum mode, GLint first, GLsizei count, GLsizei primcount); typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDARBPROC)(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDEXTPROC)(GLenum mode, GLint start, GLsizei count, GLsizei primcount);
typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf); typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf);
typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs); typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs);
typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSARBPROC)(GLsizei n, const GLenum * bufs); typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSARBPROC)(GLsizei n, const GLenum * bufs);
@ -2859,6 +2880,7 @@ typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDARBPROC)(GLenum mode, GLsi
typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance); typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance);
typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex); typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex);
typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount);
typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices);
typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex); typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex);
typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum mode, GLuint id); typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum mode, GLuint id);
@ -4045,6 +4067,8 @@ GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB;
#define glDrawArraysInstancedARB glad_glDrawArraysInstancedARB #define glDrawArraysInstancedARB glad_glDrawArraysInstancedARB
GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance; GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance;
#define glDrawArraysInstancedBaseInstance glad_glDrawArraysInstancedBaseInstance #define glDrawArraysInstancedBaseInstance glad_glDrawArraysInstancedBaseInstance
GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT;
#define glDrawArraysInstancedEXT glad_glDrawArraysInstancedEXT
GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer; GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer;
#define glDrawBuffer glad_glDrawBuffer #define glDrawBuffer glad_glDrawBuffer
GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers;
@ -4067,6 +4091,8 @@ GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstan
#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex #define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex
GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance; GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance;
#define glDrawElementsInstancedBaseVertexBaseInstance glad_glDrawElementsInstancedBaseVertexBaseInstance #define glDrawElementsInstancedBaseVertexBaseInstance glad_glDrawElementsInstancedBaseVertexBaseInstance
GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT;
#define glDrawElementsInstancedEXT glad_glDrawElementsInstancedEXT
GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements;
#define glDrawRangeElements glad_glDrawRangeElements #define glDrawRangeElements glad_glDrawRangeElements
GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex;
@ -5682,12 +5708,6 @@ GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr);
GLAD_API_CALL int gladLoadGL( GLADloadfunc load); GLAD_API_CALL int gladLoadGL( GLADloadfunc load);
#ifdef GLAD_GL
GLAD_API_CALL int gladLoaderLoadGL(void);
GLAD_API_CALL void gladLoaderUnloadGL(void);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
@ -5813,7 +5833,6 @@ int GLAD_GL_ARB_tessellation_shader = 0;
int GLAD_GL_ARB_texture_border_clamp = 0; int GLAD_GL_ARB_texture_border_clamp = 0;
int GLAD_GL_ARB_texture_buffer_object_rgb32 = 0; int GLAD_GL_ARB_texture_buffer_object_rgb32 = 0;
int GLAD_GL_ARB_texture_compression = 0; int GLAD_GL_ARB_texture_compression = 0;
int GLAD_GL_EXT_texture_compression_s3tc = 0;
int GLAD_GL_ARB_texture_cube_map = 0; int GLAD_GL_ARB_texture_cube_map = 0;
int GLAD_GL_ARB_texture_cube_map_array = 0; int GLAD_GL_ARB_texture_cube_map_array = 0;
int GLAD_GL_ARB_texture_env_add = 0; int GLAD_GL_ARB_texture_env_add = 0;
@ -5837,11 +5856,17 @@ int GLAD_GL_ARB_vertex_attrib_binding = 0;
int GLAD_GL_ARB_vertex_buffer_object = 0; int GLAD_GL_ARB_vertex_buffer_object = 0;
int GLAD_GL_ARB_vertex_program = 0; int GLAD_GL_ARB_vertex_program = 0;
int GLAD_GL_ARB_vertex_shader = 0; int GLAD_GL_ARB_vertex_shader = 0;
int GLAD_GL_EXT_draw_instanced = 0;
int GLAD_GL_EXT_fog_coord = 0; int GLAD_GL_EXT_fog_coord = 0;
int GLAD_GL_EXT_framebuffer_blit = 0; int GLAD_GL_EXT_framebuffer_blit = 0;
int GLAD_GL_EXT_framebuffer_multisample = 0; int GLAD_GL_EXT_framebuffer_multisample = 0;
int GLAD_GL_EXT_framebuffer_object = 0; int GLAD_GL_EXT_framebuffer_object = 0;
int GLAD_GL_EXT_framebuffer_sRGB = 0; int GLAD_GL_EXT_framebuffer_sRGB = 0;
int GLAD_GL_EXT_texture_compression_s3tc = 0;
int GLAD_GL_EXT_texture_filter_anisotropic = 0;
int GLAD_GL_EXT_texture_mirror_clamp = 0;
int GLAD_GL_KHR_texture_compression_astc_hdr = 0;
int GLAD_GL_KHR_texture_compression_astc_ldr = 0;
int GLAD_GL_OES_compressed_paletted_texture = 0; int GLAD_GL_OES_compressed_paletted_texture = 0;
int GLAD_GL_OES_fixed_point = 0; int GLAD_GL_OES_fixed_point = 0;
@ -6038,6 +6063,7 @@ PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL;
PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL;
PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB = NULL; PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB = NULL;
PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL; PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL;
PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT = NULL;
PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL;
PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL;
PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB = NULL; PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB = NULL;
@ -6049,6 +6075,7 @@ PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB = NULL;
PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL; PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL;
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL;
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL; PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL;
PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT = NULL;
PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL;
PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL;
PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL; PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL;
@ -8122,6 +8149,11 @@ static void glad_gl_load_GL_ARB_vertex_shader( GLADuserptrloadfunc load, void* u
glad_glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) load(userptr, "glVertexAttrib4usvARB"); glad_glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) load(userptr, "glVertexAttrib4usvARB");
glad_glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) load(userptr, "glVertexAttribPointerARB"); glad_glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) load(userptr, "glVertexAttribPointerARB");
} }
static void glad_gl_load_GL_EXT_draw_instanced( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_EXT_draw_instanced) return;
glad_glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC) load(userptr, "glDrawArraysInstancedEXT");
glad_glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC) load(userptr, "glDrawElementsInstancedEXT");
}
static void glad_gl_load_GL_EXT_fog_coord( GLADuserptrloadfunc load, void* userptr) { static void glad_gl_load_GL_EXT_fog_coord( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_EXT_fog_coord) return; if(!GLAD_GL_EXT_fog_coord) return;
glad_glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC) load(userptr, "glFogCoordPointerEXT"); glad_glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC) load(userptr, "glFogCoordPointerEXT");
@ -8451,8 +8483,7 @@ static int glad_gl_find_extensions_gl( int version) {
GLAD_GL_ARB_texture_border_clamp = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_border_clamp"); GLAD_GL_ARB_texture_border_clamp = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_border_clamp");
GLAD_GL_ARB_texture_buffer_object_rgb32 = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_buffer_object_rgb32"); GLAD_GL_ARB_texture_buffer_object_rgb32 = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_buffer_object_rgb32");
GLAD_GL_ARB_texture_compression = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_compression"); GLAD_GL_ARB_texture_compression = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_compression");
GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_compression_s3tc"); GLAD_GL_ARB_texture_cube_map = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_cube_map");
GLAD_GL_ARB_texture_cube_map = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_cube_map");
GLAD_GL_ARB_texture_cube_map_array = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_cube_map_array"); GLAD_GL_ARB_texture_cube_map_array = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_cube_map_array");
GLAD_GL_ARB_texture_env_add = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_env_add"); GLAD_GL_ARB_texture_env_add = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_env_add");
GLAD_GL_ARB_texture_filter_anisotropic = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_filter_anisotropic"); GLAD_GL_ARB_texture_filter_anisotropic = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_filter_anisotropic");
@ -8475,11 +8506,17 @@ static int glad_gl_find_extensions_gl( int version) {
GLAD_GL_ARB_vertex_buffer_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_vertex_buffer_object"); GLAD_GL_ARB_vertex_buffer_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_vertex_buffer_object");
GLAD_GL_ARB_vertex_program = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_vertex_program"); GLAD_GL_ARB_vertex_program = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_vertex_program");
GLAD_GL_ARB_vertex_shader = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_vertex_shader"); GLAD_GL_ARB_vertex_shader = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_vertex_shader");
GLAD_GL_EXT_draw_instanced = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_draw_instanced");
GLAD_GL_EXT_fog_coord = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_fog_coord"); GLAD_GL_EXT_fog_coord = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_fog_coord");
GLAD_GL_EXT_framebuffer_blit = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_blit"); GLAD_GL_EXT_framebuffer_blit = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_blit");
GLAD_GL_EXT_framebuffer_multisample = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_multisample"); GLAD_GL_EXT_framebuffer_multisample = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_multisample");
GLAD_GL_EXT_framebuffer_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_object"); GLAD_GL_EXT_framebuffer_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_object");
GLAD_GL_EXT_framebuffer_sRGB = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_sRGB"); GLAD_GL_EXT_framebuffer_sRGB = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_sRGB");
GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_compression_s3tc");
GLAD_GL_EXT_texture_filter_anisotropic = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_filter_anisotropic");
GLAD_GL_EXT_texture_mirror_clamp = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_mirror_clamp");
GLAD_GL_KHR_texture_compression_astc_hdr = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_KHR_texture_compression_astc_hdr");
GLAD_GL_KHR_texture_compression_astc_ldr = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_KHR_texture_compression_astc_ldr");
GLAD_GL_OES_compressed_paletted_texture = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_OES_compressed_paletted_texture"); GLAD_GL_OES_compressed_paletted_texture = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_OES_compressed_paletted_texture");
GLAD_GL_OES_fixed_point = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_OES_fixed_point"); GLAD_GL_OES_fixed_point = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_OES_fixed_point");
@ -8615,6 +8652,7 @@ int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) {
glad_gl_load_GL_ARB_vertex_buffer_object(load, userptr); glad_gl_load_GL_ARB_vertex_buffer_object(load, userptr);
glad_gl_load_GL_ARB_vertex_program(load, userptr); glad_gl_load_GL_ARB_vertex_program(load, userptr);
glad_gl_load_GL_ARB_vertex_shader(load, userptr); glad_gl_load_GL_ARB_vertex_shader(load, userptr);
glad_gl_load_GL_EXT_draw_instanced(load, userptr);
glad_gl_load_GL_EXT_fog_coord(load, userptr); glad_gl_load_GL_EXT_fog_coord(load, userptr);
glad_gl_load_GL_EXT_framebuffer_blit(load, userptr); glad_gl_load_GL_EXT_framebuffer_blit(load, userptr);
glad_gl_load_GL_EXT_framebuffer_multisample(load, userptr); glad_gl_load_GL_EXT_framebuffer_multisample(load, userptr);
@ -8632,6 +8670,10 @@ int gladLoadGL( GLADloadfunc load) {
} }
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -1,5 +1,6 @@
Copyright (c) 2002-2006 Marcus Geelnard Copyright (c) 2002-2006 Marcus Geelnard
Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
Copyright (c) 2006-2019 Camilla Löwy
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages

File diff suppressed because it is too large Load diff

1805
raylib/external/glfw/deps/glad/gles2.h vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,282 +0,0 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

View file

@ -1,92 +0,0 @@
/* */
/* File: vk_platform.h */
/* */
/*
** Copyright (c) 2014-2017 The Khronos Group Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#ifndef VK_PLATFORM_H_
#define VK_PLATFORM_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/*
***************************************************************************************************
* Platform-specific directives and type declarations
***************************************************************************************************
*/
/* Platform-specific calling convention macros.
*
* Platforms should define these so that Vulkan clients call Vulkan commands
* with the same calling conventions that the Vulkan implementation expects.
*
* VKAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* VKAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
*/
#if defined(_WIN32)
/* On Windows, Vulkan commands use the stdcall convention */
#define VKAPI_ATTR
#define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
/* On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" */
/* calling convention, i.e. float parameters are passed in registers. This */
/* is true even if the rest of the application passes floats on the stack, */
/* as it does by default when compiling for the armeabi-v7a NDK ABI. */
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define VKAPI_CALL
#define VKAPI_PTR VKAPI_ATTR
#else
/* On other platforms, use the default calling convention */
#define VKAPI_ATTR
#define VKAPI_CALL
#define VKAPI_PTR
#endif
#include <stddef.h>
#if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif /* !defined(VK_NO_STDINT_H) */
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,593 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glad/vulkan.h>
#ifndef GLAD_IMPL_UTIL_C_
#define GLAD_IMPL_UTIL_C_
#ifdef _MSC_VER
#define GLAD_IMPL_UTIL_SSCANF sscanf_s
#else
#define GLAD_IMPL_UTIL_SSCANF sscanf
#endif
#endif /* GLAD_IMPL_UTIL_C_ */
int GLAD_VK_VERSION_1_0 = 0;
int GLAD_VK_VERSION_1_1 = 0;
int GLAD_VK_EXT_debug_report = 0;
int GLAD_VK_KHR_surface = 0;
int GLAD_VK_KHR_swapchain = 0;
PFN_vkAcquireNextImage2KHR glad_vkAcquireNextImage2KHR = NULL;
PFN_vkAcquireNextImageKHR glad_vkAcquireNextImageKHR = NULL;
PFN_vkAllocateCommandBuffers glad_vkAllocateCommandBuffers = NULL;
PFN_vkAllocateDescriptorSets glad_vkAllocateDescriptorSets = NULL;
PFN_vkAllocateMemory glad_vkAllocateMemory = NULL;
PFN_vkBeginCommandBuffer glad_vkBeginCommandBuffer = NULL;
PFN_vkBindBufferMemory glad_vkBindBufferMemory = NULL;
PFN_vkBindBufferMemory2 glad_vkBindBufferMemory2 = NULL;
PFN_vkBindImageMemory glad_vkBindImageMemory = NULL;
PFN_vkBindImageMemory2 glad_vkBindImageMemory2 = NULL;
PFN_vkCmdBeginQuery glad_vkCmdBeginQuery = NULL;
PFN_vkCmdBeginRenderPass glad_vkCmdBeginRenderPass = NULL;
PFN_vkCmdBindDescriptorSets glad_vkCmdBindDescriptorSets = NULL;
PFN_vkCmdBindIndexBuffer glad_vkCmdBindIndexBuffer = NULL;
PFN_vkCmdBindPipeline glad_vkCmdBindPipeline = NULL;
PFN_vkCmdBindVertexBuffers glad_vkCmdBindVertexBuffers = NULL;
PFN_vkCmdBlitImage glad_vkCmdBlitImage = NULL;
PFN_vkCmdClearAttachments glad_vkCmdClearAttachments = NULL;
PFN_vkCmdClearColorImage glad_vkCmdClearColorImage = NULL;
PFN_vkCmdClearDepthStencilImage glad_vkCmdClearDepthStencilImage = NULL;
PFN_vkCmdCopyBuffer glad_vkCmdCopyBuffer = NULL;
PFN_vkCmdCopyBufferToImage glad_vkCmdCopyBufferToImage = NULL;
PFN_vkCmdCopyImage glad_vkCmdCopyImage = NULL;
PFN_vkCmdCopyImageToBuffer glad_vkCmdCopyImageToBuffer = NULL;
PFN_vkCmdCopyQueryPoolResults glad_vkCmdCopyQueryPoolResults = NULL;
PFN_vkCmdDispatch glad_vkCmdDispatch = NULL;
PFN_vkCmdDispatchBase glad_vkCmdDispatchBase = NULL;
PFN_vkCmdDispatchIndirect glad_vkCmdDispatchIndirect = NULL;
PFN_vkCmdDraw glad_vkCmdDraw = NULL;
PFN_vkCmdDrawIndexed glad_vkCmdDrawIndexed = NULL;
PFN_vkCmdDrawIndexedIndirect glad_vkCmdDrawIndexedIndirect = NULL;
PFN_vkCmdDrawIndirect glad_vkCmdDrawIndirect = NULL;
PFN_vkCmdEndQuery glad_vkCmdEndQuery = NULL;
PFN_vkCmdEndRenderPass glad_vkCmdEndRenderPass = NULL;
PFN_vkCmdExecuteCommands glad_vkCmdExecuteCommands = NULL;
PFN_vkCmdFillBuffer glad_vkCmdFillBuffer = NULL;
PFN_vkCmdNextSubpass glad_vkCmdNextSubpass = NULL;
PFN_vkCmdPipelineBarrier glad_vkCmdPipelineBarrier = NULL;
PFN_vkCmdPushConstants glad_vkCmdPushConstants = NULL;
PFN_vkCmdResetEvent glad_vkCmdResetEvent = NULL;
PFN_vkCmdResetQueryPool glad_vkCmdResetQueryPool = NULL;
PFN_vkCmdResolveImage glad_vkCmdResolveImage = NULL;
PFN_vkCmdSetBlendConstants glad_vkCmdSetBlendConstants = NULL;
PFN_vkCmdSetDepthBias glad_vkCmdSetDepthBias = NULL;
PFN_vkCmdSetDepthBounds glad_vkCmdSetDepthBounds = NULL;
PFN_vkCmdSetDeviceMask glad_vkCmdSetDeviceMask = NULL;
PFN_vkCmdSetEvent glad_vkCmdSetEvent = NULL;
PFN_vkCmdSetLineWidth glad_vkCmdSetLineWidth = NULL;
PFN_vkCmdSetScissor glad_vkCmdSetScissor = NULL;
PFN_vkCmdSetStencilCompareMask glad_vkCmdSetStencilCompareMask = NULL;
PFN_vkCmdSetStencilReference glad_vkCmdSetStencilReference = NULL;
PFN_vkCmdSetStencilWriteMask glad_vkCmdSetStencilWriteMask = NULL;
PFN_vkCmdSetViewport glad_vkCmdSetViewport = NULL;
PFN_vkCmdUpdateBuffer glad_vkCmdUpdateBuffer = NULL;
PFN_vkCmdWaitEvents glad_vkCmdWaitEvents = NULL;
PFN_vkCmdWriteTimestamp glad_vkCmdWriteTimestamp = NULL;
PFN_vkCreateBuffer glad_vkCreateBuffer = NULL;
PFN_vkCreateBufferView glad_vkCreateBufferView = NULL;
PFN_vkCreateCommandPool glad_vkCreateCommandPool = NULL;
PFN_vkCreateComputePipelines glad_vkCreateComputePipelines = NULL;
PFN_vkCreateDebugReportCallbackEXT glad_vkCreateDebugReportCallbackEXT = NULL;
PFN_vkCreateDescriptorPool glad_vkCreateDescriptorPool = NULL;
PFN_vkCreateDescriptorSetLayout glad_vkCreateDescriptorSetLayout = NULL;
PFN_vkCreateDescriptorUpdateTemplate glad_vkCreateDescriptorUpdateTemplate = NULL;
PFN_vkCreateDevice glad_vkCreateDevice = NULL;
PFN_vkCreateEvent glad_vkCreateEvent = NULL;
PFN_vkCreateFence glad_vkCreateFence = NULL;
PFN_vkCreateFramebuffer glad_vkCreateFramebuffer = NULL;
PFN_vkCreateGraphicsPipelines glad_vkCreateGraphicsPipelines = NULL;
PFN_vkCreateImage glad_vkCreateImage = NULL;
PFN_vkCreateImageView glad_vkCreateImageView = NULL;
PFN_vkCreateInstance glad_vkCreateInstance = NULL;
PFN_vkCreatePipelineCache glad_vkCreatePipelineCache = NULL;
PFN_vkCreatePipelineLayout glad_vkCreatePipelineLayout = NULL;
PFN_vkCreateQueryPool glad_vkCreateQueryPool = NULL;
PFN_vkCreateRenderPass glad_vkCreateRenderPass = NULL;
PFN_vkCreateSampler glad_vkCreateSampler = NULL;
PFN_vkCreateSamplerYcbcrConversion glad_vkCreateSamplerYcbcrConversion = NULL;
PFN_vkCreateSemaphore glad_vkCreateSemaphore = NULL;
PFN_vkCreateShaderModule glad_vkCreateShaderModule = NULL;
PFN_vkCreateSwapchainKHR glad_vkCreateSwapchainKHR = NULL;
PFN_vkDebugReportMessageEXT glad_vkDebugReportMessageEXT = NULL;
PFN_vkDestroyBuffer glad_vkDestroyBuffer = NULL;
PFN_vkDestroyBufferView glad_vkDestroyBufferView = NULL;
PFN_vkDestroyCommandPool glad_vkDestroyCommandPool = NULL;
PFN_vkDestroyDebugReportCallbackEXT glad_vkDestroyDebugReportCallbackEXT = NULL;
PFN_vkDestroyDescriptorPool glad_vkDestroyDescriptorPool = NULL;
PFN_vkDestroyDescriptorSetLayout glad_vkDestroyDescriptorSetLayout = NULL;
PFN_vkDestroyDescriptorUpdateTemplate glad_vkDestroyDescriptorUpdateTemplate = NULL;
PFN_vkDestroyDevice glad_vkDestroyDevice = NULL;
PFN_vkDestroyEvent glad_vkDestroyEvent = NULL;
PFN_vkDestroyFence glad_vkDestroyFence = NULL;
PFN_vkDestroyFramebuffer glad_vkDestroyFramebuffer = NULL;
PFN_vkDestroyImage glad_vkDestroyImage = NULL;
PFN_vkDestroyImageView glad_vkDestroyImageView = NULL;
PFN_vkDestroyInstance glad_vkDestroyInstance = NULL;
PFN_vkDestroyPipeline glad_vkDestroyPipeline = NULL;
PFN_vkDestroyPipelineCache glad_vkDestroyPipelineCache = NULL;
PFN_vkDestroyPipelineLayout glad_vkDestroyPipelineLayout = NULL;
PFN_vkDestroyQueryPool glad_vkDestroyQueryPool = NULL;
PFN_vkDestroyRenderPass glad_vkDestroyRenderPass = NULL;
PFN_vkDestroySampler glad_vkDestroySampler = NULL;
PFN_vkDestroySamplerYcbcrConversion glad_vkDestroySamplerYcbcrConversion = NULL;
PFN_vkDestroySemaphore glad_vkDestroySemaphore = NULL;
PFN_vkDestroyShaderModule glad_vkDestroyShaderModule = NULL;
PFN_vkDestroySurfaceKHR glad_vkDestroySurfaceKHR = NULL;
PFN_vkDestroySwapchainKHR glad_vkDestroySwapchainKHR = NULL;
PFN_vkDeviceWaitIdle glad_vkDeviceWaitIdle = NULL;
PFN_vkEndCommandBuffer glad_vkEndCommandBuffer = NULL;
PFN_vkEnumerateDeviceExtensionProperties glad_vkEnumerateDeviceExtensionProperties = NULL;
PFN_vkEnumerateDeviceLayerProperties glad_vkEnumerateDeviceLayerProperties = NULL;
PFN_vkEnumerateInstanceExtensionProperties glad_vkEnumerateInstanceExtensionProperties = NULL;
PFN_vkEnumerateInstanceLayerProperties glad_vkEnumerateInstanceLayerProperties = NULL;
PFN_vkEnumerateInstanceVersion glad_vkEnumerateInstanceVersion = NULL;
PFN_vkEnumeratePhysicalDeviceGroups glad_vkEnumeratePhysicalDeviceGroups = NULL;
PFN_vkEnumeratePhysicalDevices glad_vkEnumeratePhysicalDevices = NULL;
PFN_vkFlushMappedMemoryRanges glad_vkFlushMappedMemoryRanges = NULL;
PFN_vkFreeCommandBuffers glad_vkFreeCommandBuffers = NULL;
PFN_vkFreeDescriptorSets glad_vkFreeDescriptorSets = NULL;
PFN_vkFreeMemory glad_vkFreeMemory = NULL;
PFN_vkGetBufferMemoryRequirements glad_vkGetBufferMemoryRequirements = NULL;
PFN_vkGetBufferMemoryRequirements2 glad_vkGetBufferMemoryRequirements2 = NULL;
PFN_vkGetDescriptorSetLayoutSupport glad_vkGetDescriptorSetLayoutSupport = NULL;
PFN_vkGetDeviceGroupPeerMemoryFeatures glad_vkGetDeviceGroupPeerMemoryFeatures = NULL;
PFN_vkGetDeviceGroupPresentCapabilitiesKHR glad_vkGetDeviceGroupPresentCapabilitiesKHR = NULL;
PFN_vkGetDeviceGroupSurfacePresentModesKHR glad_vkGetDeviceGroupSurfacePresentModesKHR = NULL;
PFN_vkGetDeviceMemoryCommitment glad_vkGetDeviceMemoryCommitment = NULL;
PFN_vkGetDeviceProcAddr glad_vkGetDeviceProcAddr = NULL;
PFN_vkGetDeviceQueue glad_vkGetDeviceQueue = NULL;
PFN_vkGetDeviceQueue2 glad_vkGetDeviceQueue2 = NULL;
PFN_vkGetEventStatus glad_vkGetEventStatus = NULL;
PFN_vkGetFenceStatus glad_vkGetFenceStatus = NULL;
PFN_vkGetImageMemoryRequirements glad_vkGetImageMemoryRequirements = NULL;
PFN_vkGetImageMemoryRequirements2 glad_vkGetImageMemoryRequirements2 = NULL;
PFN_vkGetImageSparseMemoryRequirements glad_vkGetImageSparseMemoryRequirements = NULL;
PFN_vkGetImageSparseMemoryRequirements2 glad_vkGetImageSparseMemoryRequirements2 = NULL;
PFN_vkGetImageSubresourceLayout glad_vkGetImageSubresourceLayout = NULL;
PFN_vkGetInstanceProcAddr glad_vkGetInstanceProcAddr = NULL;
PFN_vkGetPhysicalDeviceExternalBufferProperties glad_vkGetPhysicalDeviceExternalBufferProperties = NULL;
PFN_vkGetPhysicalDeviceExternalFenceProperties glad_vkGetPhysicalDeviceExternalFenceProperties = NULL;
PFN_vkGetPhysicalDeviceExternalSemaphoreProperties glad_vkGetPhysicalDeviceExternalSemaphoreProperties = NULL;
PFN_vkGetPhysicalDeviceFeatures glad_vkGetPhysicalDeviceFeatures = NULL;
PFN_vkGetPhysicalDeviceFeatures2 glad_vkGetPhysicalDeviceFeatures2 = NULL;
PFN_vkGetPhysicalDeviceFormatProperties glad_vkGetPhysicalDeviceFormatProperties = NULL;
PFN_vkGetPhysicalDeviceFormatProperties2 glad_vkGetPhysicalDeviceFormatProperties2 = NULL;
PFN_vkGetPhysicalDeviceImageFormatProperties glad_vkGetPhysicalDeviceImageFormatProperties = NULL;
PFN_vkGetPhysicalDeviceImageFormatProperties2 glad_vkGetPhysicalDeviceImageFormatProperties2 = NULL;
PFN_vkGetPhysicalDeviceMemoryProperties glad_vkGetPhysicalDeviceMemoryProperties = NULL;
PFN_vkGetPhysicalDeviceMemoryProperties2 glad_vkGetPhysicalDeviceMemoryProperties2 = NULL;
PFN_vkGetPhysicalDevicePresentRectanglesKHR glad_vkGetPhysicalDevicePresentRectanglesKHR = NULL;
PFN_vkGetPhysicalDeviceProperties glad_vkGetPhysicalDeviceProperties = NULL;
PFN_vkGetPhysicalDeviceProperties2 glad_vkGetPhysicalDeviceProperties2 = NULL;
PFN_vkGetPhysicalDeviceQueueFamilyProperties glad_vkGetPhysicalDeviceQueueFamilyProperties = NULL;
PFN_vkGetPhysicalDeviceQueueFamilyProperties2 glad_vkGetPhysicalDeviceQueueFamilyProperties2 = NULL;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties glad_vkGetPhysicalDeviceSparseImageFormatProperties = NULL;
PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 glad_vkGetPhysicalDeviceSparseImageFormatProperties2 = NULL;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR glad_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = NULL;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR glad_vkGetPhysicalDeviceSurfaceFormatsKHR = NULL;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR glad_vkGetPhysicalDeviceSurfacePresentModesKHR = NULL;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR glad_vkGetPhysicalDeviceSurfaceSupportKHR = NULL;
PFN_vkGetPipelineCacheData glad_vkGetPipelineCacheData = NULL;
PFN_vkGetQueryPoolResults glad_vkGetQueryPoolResults = NULL;
PFN_vkGetRenderAreaGranularity glad_vkGetRenderAreaGranularity = NULL;
PFN_vkGetSwapchainImagesKHR glad_vkGetSwapchainImagesKHR = NULL;
PFN_vkInvalidateMappedMemoryRanges glad_vkInvalidateMappedMemoryRanges = NULL;
PFN_vkMapMemory glad_vkMapMemory = NULL;
PFN_vkMergePipelineCaches glad_vkMergePipelineCaches = NULL;
PFN_vkQueueBindSparse glad_vkQueueBindSparse = NULL;
PFN_vkQueuePresentKHR glad_vkQueuePresentKHR = NULL;
PFN_vkQueueSubmit glad_vkQueueSubmit = NULL;
PFN_vkQueueWaitIdle glad_vkQueueWaitIdle = NULL;
PFN_vkResetCommandBuffer glad_vkResetCommandBuffer = NULL;
PFN_vkResetCommandPool glad_vkResetCommandPool = NULL;
PFN_vkResetDescriptorPool glad_vkResetDescriptorPool = NULL;
PFN_vkResetEvent glad_vkResetEvent = NULL;
PFN_vkResetFences glad_vkResetFences = NULL;
PFN_vkSetEvent glad_vkSetEvent = NULL;
PFN_vkTrimCommandPool glad_vkTrimCommandPool = NULL;
PFN_vkUnmapMemory glad_vkUnmapMemory = NULL;
PFN_vkUpdateDescriptorSetWithTemplate glad_vkUpdateDescriptorSetWithTemplate = NULL;
PFN_vkUpdateDescriptorSets glad_vkUpdateDescriptorSets = NULL;
PFN_vkWaitForFences glad_vkWaitForFences = NULL;
static void glad_vk_load_VK_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_0) return;
vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers) load("vkAllocateCommandBuffers", userptr);
vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets) load("vkAllocateDescriptorSets", userptr);
vkAllocateMemory = (PFN_vkAllocateMemory) load("vkAllocateMemory", userptr);
vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer) load("vkBeginCommandBuffer", userptr);
vkBindBufferMemory = (PFN_vkBindBufferMemory) load("vkBindBufferMemory", userptr);
vkBindImageMemory = (PFN_vkBindImageMemory) load("vkBindImageMemory", userptr);
vkCmdBeginQuery = (PFN_vkCmdBeginQuery) load("vkCmdBeginQuery", userptr);
vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass) load("vkCmdBeginRenderPass", userptr);
vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets) load("vkCmdBindDescriptorSets", userptr);
vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer) load("vkCmdBindIndexBuffer", userptr);
vkCmdBindPipeline = (PFN_vkCmdBindPipeline) load("vkCmdBindPipeline", userptr);
vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers) load("vkCmdBindVertexBuffers", userptr);
vkCmdBlitImage = (PFN_vkCmdBlitImage) load("vkCmdBlitImage", userptr);
vkCmdClearAttachments = (PFN_vkCmdClearAttachments) load("vkCmdClearAttachments", userptr);
vkCmdClearColorImage = (PFN_vkCmdClearColorImage) load("vkCmdClearColorImage", userptr);
vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage) load("vkCmdClearDepthStencilImage", userptr);
vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer) load("vkCmdCopyBuffer", userptr);
vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage) load("vkCmdCopyBufferToImage", userptr);
vkCmdCopyImage = (PFN_vkCmdCopyImage) load("vkCmdCopyImage", userptr);
vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer) load("vkCmdCopyImageToBuffer", userptr);
vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults) load("vkCmdCopyQueryPoolResults", userptr);
vkCmdDispatch = (PFN_vkCmdDispatch) load("vkCmdDispatch", userptr);
vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect) load("vkCmdDispatchIndirect", userptr);
vkCmdDraw = (PFN_vkCmdDraw) load("vkCmdDraw", userptr);
vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed) load("vkCmdDrawIndexed", userptr);
vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect) load("vkCmdDrawIndexedIndirect", userptr);
vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect) load("vkCmdDrawIndirect", userptr);
vkCmdEndQuery = (PFN_vkCmdEndQuery) load("vkCmdEndQuery", userptr);
vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass) load("vkCmdEndRenderPass", userptr);
vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands) load("vkCmdExecuteCommands", userptr);
vkCmdFillBuffer = (PFN_vkCmdFillBuffer) load("vkCmdFillBuffer", userptr);
vkCmdNextSubpass = (PFN_vkCmdNextSubpass) load("vkCmdNextSubpass", userptr);
vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier) load("vkCmdPipelineBarrier", userptr);
vkCmdPushConstants = (PFN_vkCmdPushConstants) load("vkCmdPushConstants", userptr);
vkCmdResetEvent = (PFN_vkCmdResetEvent) load("vkCmdResetEvent", userptr);
vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool) load("vkCmdResetQueryPool", userptr);
vkCmdResolveImage = (PFN_vkCmdResolveImage) load("vkCmdResolveImage", userptr);
vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants) load("vkCmdSetBlendConstants", userptr);
vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias) load("vkCmdSetDepthBias", userptr);
vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds) load("vkCmdSetDepthBounds", userptr);
vkCmdSetEvent = (PFN_vkCmdSetEvent) load("vkCmdSetEvent", userptr);
vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth) load("vkCmdSetLineWidth", userptr);
vkCmdSetScissor = (PFN_vkCmdSetScissor) load("vkCmdSetScissor", userptr);
vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask) load("vkCmdSetStencilCompareMask", userptr);
vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference) load("vkCmdSetStencilReference", userptr);
vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask) load("vkCmdSetStencilWriteMask", userptr);
vkCmdSetViewport = (PFN_vkCmdSetViewport) load("vkCmdSetViewport", userptr);
vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer) load("vkCmdUpdateBuffer", userptr);
vkCmdWaitEvents = (PFN_vkCmdWaitEvents) load("vkCmdWaitEvents", userptr);
vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp) load("vkCmdWriteTimestamp", userptr);
vkCreateBuffer = (PFN_vkCreateBuffer) load("vkCreateBuffer", userptr);
vkCreateBufferView = (PFN_vkCreateBufferView) load("vkCreateBufferView", userptr);
vkCreateCommandPool = (PFN_vkCreateCommandPool) load("vkCreateCommandPool", userptr);
vkCreateComputePipelines = (PFN_vkCreateComputePipelines) load("vkCreateComputePipelines", userptr);
vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool) load("vkCreateDescriptorPool", userptr);
vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout) load("vkCreateDescriptorSetLayout", userptr);
vkCreateDevice = (PFN_vkCreateDevice) load("vkCreateDevice", userptr);
vkCreateEvent = (PFN_vkCreateEvent) load("vkCreateEvent", userptr);
vkCreateFence = (PFN_vkCreateFence) load("vkCreateFence", userptr);
vkCreateFramebuffer = (PFN_vkCreateFramebuffer) load("vkCreateFramebuffer", userptr);
vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines) load("vkCreateGraphicsPipelines", userptr);
vkCreateImage = (PFN_vkCreateImage) load("vkCreateImage", userptr);
vkCreateImageView = (PFN_vkCreateImageView) load("vkCreateImageView", userptr);
vkCreateInstance = (PFN_vkCreateInstance) load("vkCreateInstance", userptr);
vkCreatePipelineCache = (PFN_vkCreatePipelineCache) load("vkCreatePipelineCache", userptr);
vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout) load("vkCreatePipelineLayout", userptr);
vkCreateQueryPool = (PFN_vkCreateQueryPool) load("vkCreateQueryPool", userptr);
vkCreateRenderPass = (PFN_vkCreateRenderPass) load("vkCreateRenderPass", userptr);
vkCreateSampler = (PFN_vkCreateSampler) load("vkCreateSampler", userptr);
vkCreateSemaphore = (PFN_vkCreateSemaphore) load("vkCreateSemaphore", userptr);
vkCreateShaderModule = (PFN_vkCreateShaderModule) load("vkCreateShaderModule", userptr);
vkDestroyBuffer = (PFN_vkDestroyBuffer) load("vkDestroyBuffer", userptr);
vkDestroyBufferView = (PFN_vkDestroyBufferView) load("vkDestroyBufferView", userptr);
vkDestroyCommandPool = (PFN_vkDestroyCommandPool) load("vkDestroyCommandPool", userptr);
vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool) load("vkDestroyDescriptorPool", userptr);
vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout) load("vkDestroyDescriptorSetLayout", userptr);
vkDestroyDevice = (PFN_vkDestroyDevice) load("vkDestroyDevice", userptr);
vkDestroyEvent = (PFN_vkDestroyEvent) load("vkDestroyEvent", userptr);
vkDestroyFence = (PFN_vkDestroyFence) load("vkDestroyFence", userptr);
vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer) load("vkDestroyFramebuffer", userptr);
vkDestroyImage = (PFN_vkDestroyImage) load("vkDestroyImage", userptr);
vkDestroyImageView = (PFN_vkDestroyImageView) load("vkDestroyImageView", userptr);
vkDestroyInstance = (PFN_vkDestroyInstance) load("vkDestroyInstance", userptr);
vkDestroyPipeline = (PFN_vkDestroyPipeline) load("vkDestroyPipeline", userptr);
vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache) load("vkDestroyPipelineCache", userptr);
vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout) load("vkDestroyPipelineLayout", userptr);
vkDestroyQueryPool = (PFN_vkDestroyQueryPool) load("vkDestroyQueryPool", userptr);
vkDestroyRenderPass = (PFN_vkDestroyRenderPass) load("vkDestroyRenderPass", userptr);
vkDestroySampler = (PFN_vkDestroySampler) load("vkDestroySampler", userptr);
vkDestroySemaphore = (PFN_vkDestroySemaphore) load("vkDestroySemaphore", userptr);
vkDestroyShaderModule = (PFN_vkDestroyShaderModule) load("vkDestroyShaderModule", userptr);
vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle) load("vkDeviceWaitIdle", userptr);
vkEndCommandBuffer = (PFN_vkEndCommandBuffer) load("vkEndCommandBuffer", userptr);
vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties) load("vkEnumerateDeviceExtensionProperties", userptr);
vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties) load("vkEnumerateDeviceLayerProperties", userptr);
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) load("vkEnumerateInstanceExtensionProperties", userptr);
vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties) load("vkEnumerateInstanceLayerProperties", userptr);
vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) load("vkEnumeratePhysicalDevices", userptr);
vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges) load("vkFlushMappedMemoryRanges", userptr);
vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers) load("vkFreeCommandBuffers", userptr);
vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets) load("vkFreeDescriptorSets", userptr);
vkFreeMemory = (PFN_vkFreeMemory) load("vkFreeMemory", userptr);
vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements) load("vkGetBufferMemoryRequirements", userptr);
vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment) load("vkGetDeviceMemoryCommitment", userptr);
vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr) load("vkGetDeviceProcAddr", userptr);
vkGetDeviceQueue = (PFN_vkGetDeviceQueue) load("vkGetDeviceQueue", userptr);
vkGetEventStatus = (PFN_vkGetEventStatus) load("vkGetEventStatus", userptr);
vkGetFenceStatus = (PFN_vkGetFenceStatus) load("vkGetFenceStatus", userptr);
vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements) load("vkGetImageMemoryRequirements", userptr);
vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements) load("vkGetImageSparseMemoryRequirements", userptr);
vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout) load("vkGetImageSubresourceLayout", userptr);
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) load("vkGetInstanceProcAddr", userptr);
vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) load("vkGetPhysicalDeviceFeatures", userptr);
vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties) load("vkGetPhysicalDeviceFormatProperties", userptr);
vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties) load("vkGetPhysicalDeviceImageFormatProperties", userptr);
vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties) load("vkGetPhysicalDeviceMemoryProperties", userptr);
vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) load("vkGetPhysicalDeviceProperties", userptr);
vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) load("vkGetPhysicalDeviceQueueFamilyProperties", userptr);
vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties) load("vkGetPhysicalDeviceSparseImageFormatProperties", userptr);
vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData) load("vkGetPipelineCacheData", userptr);
vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults) load("vkGetQueryPoolResults", userptr);
vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity) load("vkGetRenderAreaGranularity", userptr);
vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges) load("vkInvalidateMappedMemoryRanges", userptr);
vkMapMemory = (PFN_vkMapMemory) load("vkMapMemory", userptr);
vkMergePipelineCaches = (PFN_vkMergePipelineCaches) load("vkMergePipelineCaches", userptr);
vkQueueBindSparse = (PFN_vkQueueBindSparse) load("vkQueueBindSparse", userptr);
vkQueueSubmit = (PFN_vkQueueSubmit) load("vkQueueSubmit", userptr);
vkQueueWaitIdle = (PFN_vkQueueWaitIdle) load("vkQueueWaitIdle", userptr);
vkResetCommandBuffer = (PFN_vkResetCommandBuffer) load("vkResetCommandBuffer", userptr);
vkResetCommandPool = (PFN_vkResetCommandPool) load("vkResetCommandPool", userptr);
vkResetDescriptorPool = (PFN_vkResetDescriptorPool) load("vkResetDescriptorPool", userptr);
vkResetEvent = (PFN_vkResetEvent) load("vkResetEvent", userptr);
vkResetFences = (PFN_vkResetFences) load("vkResetFences", userptr);
vkSetEvent = (PFN_vkSetEvent) load("vkSetEvent", userptr);
vkUnmapMemory = (PFN_vkUnmapMemory) load("vkUnmapMemory", userptr);
vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets) load("vkUpdateDescriptorSets", userptr);
vkWaitForFences = (PFN_vkWaitForFences) load("vkWaitForFences", userptr);
}
static void glad_vk_load_VK_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_VERSION_1_1) return;
vkBindBufferMemory2 = (PFN_vkBindBufferMemory2) load("vkBindBufferMemory2", userptr);
vkBindImageMemory2 = (PFN_vkBindImageMemory2) load("vkBindImageMemory2", userptr);
vkCmdDispatchBase = (PFN_vkCmdDispatchBase) load("vkCmdDispatchBase", userptr);
vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask) load("vkCmdSetDeviceMask", userptr);
vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate) load("vkCreateDescriptorUpdateTemplate", userptr);
vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion) load("vkCreateSamplerYcbcrConversion", userptr);
vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate) load("vkDestroyDescriptorUpdateTemplate", userptr);
vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion) load("vkDestroySamplerYcbcrConversion", userptr);
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr);
vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups) load("vkEnumeratePhysicalDeviceGroups", userptr);
vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2) load("vkGetBufferMemoryRequirements2", userptr);
vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport) load("vkGetDescriptorSetLayoutSupport", userptr);
vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures) load("vkGetDeviceGroupPeerMemoryFeatures", userptr);
vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2) load("vkGetDeviceQueue2", userptr);
vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2) load("vkGetImageMemoryRequirements2", userptr);
vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2) load("vkGetImageSparseMemoryRequirements2", userptr);
vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties) load("vkGetPhysicalDeviceExternalBufferProperties", userptr);
vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties) load("vkGetPhysicalDeviceExternalFenceProperties", userptr);
vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties) load("vkGetPhysicalDeviceExternalSemaphoreProperties", userptr);
vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2) load("vkGetPhysicalDeviceFeatures2", userptr);
vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2) load("vkGetPhysicalDeviceFormatProperties2", userptr);
vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2) load("vkGetPhysicalDeviceImageFormatProperties2", userptr);
vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2) load("vkGetPhysicalDeviceMemoryProperties2", userptr);
vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2) load("vkGetPhysicalDeviceProperties2", userptr);
vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2) load("vkGetPhysicalDeviceQueueFamilyProperties2", userptr);
vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2) load("vkGetPhysicalDeviceSparseImageFormatProperties2", userptr);
vkTrimCommandPool = (PFN_vkTrimCommandPool) load("vkTrimCommandPool", userptr);
vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate) load("vkUpdateDescriptorSetWithTemplate", userptr);
}
static void glad_vk_load_VK_EXT_debug_report( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_EXT_debug_report) return;
vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT) load("vkCreateDebugReportCallbackEXT", userptr);
vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT) load("vkDebugReportMessageEXT", userptr);
vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT) load("vkDestroyDebugReportCallbackEXT", userptr);
}
static void glad_vk_load_VK_KHR_surface( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_KHR_surface) return;
vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR) load("vkDestroySurfaceKHR", userptr);
vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR) load("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", userptr);
vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR) load("vkGetPhysicalDeviceSurfaceFormatsKHR", userptr);
vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR) load("vkGetPhysicalDeviceSurfacePresentModesKHR", userptr);
vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) load("vkGetPhysicalDeviceSurfaceSupportKHR", userptr);
}
static void glad_vk_load_VK_KHR_swapchain( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_VK_KHR_swapchain) return;
vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR) load("vkAcquireNextImage2KHR", userptr);
vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR) load("vkAcquireNextImageKHR", userptr);
vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR) load("vkCreateSwapchainKHR", userptr);
vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR) load("vkDestroySwapchainKHR", userptr);
vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR) load("vkGetDeviceGroupPresentCapabilitiesKHR", userptr);
vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR) load("vkGetDeviceGroupSurfacePresentModesKHR", userptr);
vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR) load("vkGetPhysicalDevicePresentRectanglesKHR", userptr);
vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR) load("vkGetSwapchainImagesKHR", userptr);
vkQueuePresentKHR = (PFN_vkQueuePresentKHR) load("vkQueuePresentKHR", userptr);
}
static int glad_vk_get_extensions( VkPhysicalDevice physical_device, uint32_t *out_extension_count, char ***out_extensions) {
uint32_t i;
uint32_t instance_extension_count = 0;
uint32_t device_extension_count = 0;
uint32_t max_extension_count;
uint32_t total_extension_count;
char **extensions;
VkExtensionProperties *ext_properties;
VkResult result;
if (vkEnumerateInstanceExtensionProperties == NULL || (physical_device != NULL && vkEnumerateDeviceExtensionProperties == NULL)) {
return 0;
}
result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, NULL);
if (result != VK_SUCCESS) {
return 0;
}
if (physical_device != NULL) {
result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, NULL);
if (result != VK_SUCCESS) {
return 0;
}
}
total_extension_count = instance_extension_count + device_extension_count;
max_extension_count = instance_extension_count > device_extension_count
? instance_extension_count : device_extension_count;
ext_properties = (VkExtensionProperties*) malloc(max_extension_count * sizeof(VkExtensionProperties));
if (ext_properties == NULL) {
return 0;
}
result = vkEnumerateInstanceExtensionProperties(NULL, &instance_extension_count, ext_properties);
if (result != VK_SUCCESS) {
free((void*) ext_properties);
return 0;
}
extensions = (char**) calloc(total_extension_count, sizeof(char*));
if (extensions == NULL) {
free((void*) ext_properties);
return 0;
}
for (i = 0; i < instance_extension_count; ++i) {
VkExtensionProperties ext = ext_properties[i];
size_t extension_name_length = strlen(ext.extensionName) + 1;
extensions[i] = (char*) malloc(extension_name_length * sizeof(char));
memcpy(extensions[i], ext.extensionName, extension_name_length * sizeof(char));
}
if (physical_device != NULL) {
result = vkEnumerateDeviceExtensionProperties(physical_device, NULL, &device_extension_count, ext_properties);
if (result != VK_SUCCESS) {
for (i = 0; i < instance_extension_count; ++i) {
free((void*) extensions[i]);
}
free(extensions);
return 0;
}
for (i = 0; i < device_extension_count; ++i) {
VkExtensionProperties ext = ext_properties[i];
size_t extension_name_length = strlen(ext.extensionName) + 1;
extensions[instance_extension_count + i] = (char*) malloc(extension_name_length * sizeof(char));
memcpy(extensions[instance_extension_count + i], ext.extensionName, extension_name_length * sizeof(char));
}
}
free((void*) ext_properties);
*out_extension_count = total_extension_count;
*out_extensions = extensions;
return 1;
}
static void glad_vk_free_extensions(uint32_t extension_count, char **extensions) {
uint32_t i;
for(i = 0; i < extension_count ; ++i) {
free((void*) (extensions[i]));
}
free((void*) extensions);
}
static int glad_vk_has_extension(const char *name, uint32_t extension_count, char **extensions) {
uint32_t i;
for (i = 0; i < extension_count; ++i) {
if(strcmp(name, extensions[i]) == 0) {
return 1;
}
}
return 0;
}
static GLADapiproc glad_vk_get_proc_from_userptr(const char* name, void *userptr) {
return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
}
static int glad_vk_find_extensions_vulkan( VkPhysicalDevice physical_device) {
uint32_t extension_count = 0;
char **extensions = NULL;
if (!glad_vk_get_extensions(physical_device, &extension_count, &extensions)) return 0;
GLAD_VK_EXT_debug_report = glad_vk_has_extension("VK_EXT_debug_report", extension_count, extensions);
GLAD_VK_KHR_surface = glad_vk_has_extension("VK_KHR_surface", extension_count, extensions);
GLAD_VK_KHR_swapchain = glad_vk_has_extension("VK_KHR_swapchain", extension_count, extensions);
glad_vk_free_extensions(extension_count, extensions);
return 1;
}
static int glad_vk_find_core_vulkan( VkPhysicalDevice physical_device) {
int major = 1;
int minor = 0;
#ifdef VK_VERSION_1_1
if (vkEnumerateInstanceVersion != NULL) {
uint32_t version;
VkResult result;
result = vkEnumerateInstanceVersion(&version);
if (result == VK_SUCCESS) {
major = (int) VK_VERSION_MAJOR(version);
minor = (int) VK_VERSION_MINOR(version);
}
}
#endif
if (physical_device != NULL && vkGetPhysicalDeviceProperties != NULL) {
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(physical_device, &properties);
major = (int) VK_VERSION_MAJOR(properties.apiVersion);
minor = (int) VK_VERSION_MINOR(properties.apiVersion);
}
GLAD_VK_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1;
GLAD_VK_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1;
return GLAD_MAKE_VERSION(major, minor);
}
int gladLoadVulkanUserPtr( VkPhysicalDevice physical_device, GLADuserptrloadfunc load, void *userptr) {
int version;
#ifdef VK_VERSION_1_1
vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) load("vkEnumerateInstanceVersion", userptr);
#endif
version = glad_vk_find_core_vulkan( physical_device);
if (!version) {
return 0;
}
glad_vk_load_VK_VERSION_1_0(load, userptr);
glad_vk_load_VK_VERSION_1_1(load, userptr);
if (!glad_vk_find_extensions_vulkan( physical_device)) return 0;
glad_vk_load_VK_EXT_debug_report(load, userptr);
glad_vk_load_VK_KHR_surface(load, userptr);
glad_vk_load_VK_KHR_swapchain(load, userptr);
return version;
}
int gladLoadVulkan( VkPhysicalDevice physical_device, GLADloadfunc load) {
return gladLoadVulkanUserPtr( physical_device, glad_vk_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
}

View file

@ -190,6 +190,9 @@ extern "C" {
#else /*__APPLE__*/ #else /*__APPLE__*/
#include <GL/glcorearb.h> #include <GL/glcorearb.h>
#if defined(GLFW_INCLUDE_GLEXT)
#include <GL/glext.h>
#endif
#endif /*__APPLE__*/ #endif /*__APPLE__*/
@ -259,13 +262,12 @@ extern "C" {
/* We are building GLFW as a Win32 DLL */ /* We are building GLFW as a Win32 DLL */
#define GLFWAPI __declspec(dllexport) #define GLFWAPI __declspec(dllexport)
#elif defined(_WIN32) && defined(GLFW_DLL) #elif defined(_WIN32) && defined(GLFW_DLL)
/* We are calling GLFW as a Win32 DLL */ /* We are calling a GLFW Win32 DLL */
#define GLFWAPI __declspec(dllimport) #define GLFWAPI __declspec(dllimport)
#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) #elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL)
/* We are building GLFW as a shared / dynamic library */ /* We are building GLFW as a Unix shared library */
#define GLFWAPI __attribute__((visibility("default"))) #define GLFWAPI __attribute__((visibility("default")))
#else #else
/* We are building or calling GLFW as a static library */
#define GLFWAPI #define GLFWAPI
#endif #endif
@ -372,7 +374,7 @@ extern "C" {
* *
* The naming of the key codes follow these rules: * The naming of the key codes follow these rules:
* - The US keyboard layout is used * - The US keyboard layout is used
* - Names of printable alpha-numeric characters are used (e.g. "A", "R", * - Names of printable alphanumeric characters are used (e.g. "A", "R",
* "3", etc.) * "3", etc.)
* - For non-alphanumeric characters, Unicode:ish names are used (e.g. * - For non-alphanumeric characters, Unicode:ish names are used (e.g.
* "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not
@ -717,7 +719,7 @@ extern "C" {
* GLFW could not find support for the requested API on the system. * GLFW could not find support for the requested API on the system.
* *
* @analysis The installed graphics driver does not support the requested * @analysis The installed graphics driver does not support the requested
* API, or does not support it via the chosen context creation backend. * API, or does not support it via the chosen context creation API.
* Below are a few examples. * Below are a few examples.
* *
* @par * @par
@ -786,7 +788,7 @@ extern "C" {
/*! @brief The specified cursor shape is not available. /*! @brief The specified cursor shape is not available.
* *
* The specified standard cursor shape is not available, either because the * The specified standard cursor shape is not available, either because the
* current system cursor theme does not provide it or because it is not * current platform cursor theme does not provide it or because it is not
* available on the platform. * available on the platform.
* *
* @analysis Platform or system settings limitation. Pick another * @analysis Platform or system settings limitation. Pick another
@ -821,6 +823,28 @@ extern "C" {
* updating any existing out parameters. * updating any existing out parameters.
*/ */
#define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D #define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D
/*! @brief Platform unavailable or no matching platform was found.
*
* If emitted during initialization, no matching platform was found. If @ref
* GLFW_PLATFORM is set to `GLFW_ANY_PLATFORM`, GLFW could not detect any of the
* platforms supported by this library binary, except for the Null platform. If set to
* a specific platform, it is either not supported by this library binary or GLFW was not
* able to detect it.
*
* If emitted by a native access function, GLFW was initialized for a different platform
* than the function is for.
*
* @analysis Failure to detect any platform usually only happens on non-macOS Unix
* systems, either when no window system is running or the program was run from
* a terminal that does not have the necessary environment variables. Fall back to
* a different platform if possible or notify the user that no usable platform was
* detected.
*
* Failure to detect a specific platform may have the same cause as above or be because
* support for that platform was not compiled in. Call @ref glfwPlatformSupported to
* check whether a specific platform is supported by a library binary.
*/
#define GLFW_PLATFORM_UNAVAILABLE 0x0001000E
/*! @} */ /*! @} */
/*! @addtogroup window /*! @addtogroup window
@ -903,6 +927,18 @@ extern "C" {
*/ */
#define GLFW_MOUSE_PASSTHROUGH 0x0002000D #define GLFW_MOUSE_PASSTHROUGH 0x0002000D
/*! @brief Initial position x-coordinate window hint.
*
* Initial position x-coordinate [window hint](@ref GLFW_POSITION_X).
*/
#define GLFW_POSITION_X 0x0002000E
/*! @brief Initial position y-coordinate window hint.
*
* Initial position y-coordinate [window hint](@ref GLFW_POSITION_Y).
*/
#define GLFW_POSITION_Y 0x0002000F
/*! @brief Framebuffer bit depth hint. /*! @brief Framebuffer bit depth hint.
* *
* Framebuffer bit depth [hint](@ref GLFW_RED_BITS). * Framebuffer bit depth [hint](@ref GLFW_RED_BITS).
@ -1003,7 +1039,7 @@ extern "C" {
* and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib). * and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib).
*/ */
#define GLFW_CONTEXT_VERSION_MINOR 0x00022003 #define GLFW_CONTEXT_VERSION_MINOR 0x00022003
/*! @brief Context client API revision number hint and attribute. /*! @brief Context client API revision number attribute.
* *
* Context client API revision number * Context client API revision number
* [attribute](@ref GLFW_CONTEXT_REVISION_attrib). * [attribute](@ref GLFW_CONTEXT_REVISION_attrib).
@ -1081,6 +1117,12 @@ extern "C" {
*/ */
#define GLFW_X11_INSTANCE_NAME 0x00024002 #define GLFW_X11_INSTANCE_NAME 0x00024002
#define GLFW_WIN32_KEYBOARD_MENU 0x00025001 #define GLFW_WIN32_KEYBOARD_MENU 0x00025001
/*! @brief Wayland specific
* [window hint](@ref GLFW_WAYLAND_APP_ID_hint).
*
* Allows specification of the Wayland app_id.
*/
#define GLFW_WAYLAND_APP_ID 0x00026001
/*! @} */ /*! @} */
#define GLFW_NO_API 0 #define GLFW_NO_API 0
@ -1104,6 +1146,7 @@ extern "C" {
#define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_NORMAL 0x00034001
#define GLFW_CURSOR_HIDDEN 0x00034002 #define GLFW_CURSOR_HIDDEN 0x00034002
#define GLFW_CURSOR_DISABLED 0x00034003 #define GLFW_CURSOR_DISABLED 0x00034003
#define GLFW_CURSOR_CAPTURED 0x00034004
#define GLFW_ANY_RELEASE_BEHAVIOR 0 #define GLFW_ANY_RELEASE_BEHAVIOR 0
#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001 #define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
@ -1121,11 +1164,13 @@ extern "C" {
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007 #define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007
#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008 #define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008
#define GLFW_ANY_POSITION 0x80000000
/*! @defgroup shapes Standard cursor shapes /*! @defgroup shapes Standard cursor shapes
* @brief Standard system cursor shapes. * @brief Standard system cursor shapes.
* *
* These are the [standard cursor shapes](@ref cursor_standard) that can be * These are the [standard cursor shapes](@ref cursor_standard) that can be
* requested from the window system. * requested from the platform (window system).
* *
* @ingroup input * @ingroup input
* @{ */ * @{ */
@ -1242,6 +1287,11 @@ extern "C" {
* ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint). * ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint).
*/ */
#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002 #define GLFW_ANGLE_PLATFORM_TYPE 0x00050002
/*! @brief Platform selection init hint.
*
* Platform selection [init hint](@ref GLFW_PLATFORM).
*/
#define GLFW_PLATFORM 0x00050003
/*! @brief macOS specific init hint. /*! @brief macOS specific init hint.
* *
* macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint). * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint).
@ -1259,6 +1309,20 @@ extern "C" {
#define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001 #define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001
/*! @} */ /*! @} */
/*! @addtogroup init
* @{ */
/*! @brief Hint value that enables automatic platform selection.
*
* Hint value for @ref GLFW_PLATFORM that enables automatic platform selection.
*/
#define GLFW_ANY_PLATFORM 0x00060000
#define GLFW_PLATFORM_WIN32 0x00060001
#define GLFW_PLATFORM_COCOA 0x00060002
#define GLFW_PLATFORM_WAYLAND 0x00060003
#define GLFW_PLATFORM_X11 0x00060004
#define GLFW_PLATFORM_NULL 0x00060005
/*! @} */
#define GLFW_DONT_CARE -1 #define GLFW_DONT_CARE -1
@ -1330,6 +1394,131 @@ typedef struct GLFWwindow GLFWwindow;
*/ */
typedef struct GLFWcursor GLFWcursor; typedef struct GLFWcursor GLFWcursor;
/*! @brief The function pointer type for memory allocation callbacks.
*
* This is the function pointer type for memory allocation callbacks. A memory
* allocation callback function has the following signature:
* @code
* void* function_name(size_t size, void* user)
* @endcode
*
* This function must return either a memory block at least `size` bytes long,
* or `NULL` if allocation failed. Note that not all parts of GLFW handle allocation
* failures gracefully yet.
*
* This function may be called during @ref glfwInit but before the library is
* flagged as initialized, as well as during @ref glfwTerminate after the
* library is no longer flagged as initialized.
*
* Any memory allocated by this function will be deallocated during library
* termination or earlier.
*
* The size will always be greater than zero. Allocations of size zero are filtered out
* before reaching the custom allocator.
*
* @param[in] size The minimum size, in bytes, of the memory block.
* @param[in] user The user-defined pointer from the allocator.
* @return The address of the newly allocated memory block, or `NULL` if an
* error occurred.
*
* @pointer_lifetime The returned memory block must be valid at least until it
* is deallocated.
*
* @reentrancy This function should not call any GLFW function.
*
* @thread_safety This function may be called from any thread that calls GLFW functions.
*
* @sa @ref init_allocator
* @sa @ref GLFWallocator
*
* @since Added in version 3.4.
*
* @ingroup init
*/
typedef void* (* GLFWallocatefun)(size_t size, void* user);
/*! @brief The function pointer type for memory reallocation callbacks.
*
* This is the function pointer type for memory reallocation callbacks.
* A memory reallocation callback function has the following signature:
* @code
* void* function_name(void* block, size_t size, void* user)
* @endcode
*
* This function must return a memory block at least `size` bytes long, or
* `NULL` if allocation failed. Note that not all parts of GLFW handle allocation
* failures gracefully yet.
*
* This function may be called during @ref glfwInit but before the library is
* flagged as initialized, as well as during @ref glfwTerminate after the
* library is no longer flagged as initialized.
*
* Any memory allocated by this function will be deallocated during library
* termination or earlier.
*
* The block address will never be `NULL` and the size will always be greater than zero.
* Reallocations of a block to size zero are converted into deallocations. Reallocations
* of `NULL` to a non-zero size are converted into regular allocations.
*
* @param[in] block The address of the memory block to reallocate.
* @param[in] size The new minimum size, in bytes, of the memory block.
* @param[in] user The user-defined pointer from the allocator.
* @return The address of the newly allocated or resized memory block, or
* `NULL` if an error occurred.
*
* @pointer_lifetime The returned memory block must be valid at least until it
* is deallocated.
*
* @reentrancy This function should not call any GLFW function.
*
* @thread_safety This function may be called from any thread that calls GLFW functions.
*
* @sa @ref init_allocator
* @sa @ref GLFWallocator
*
* @since Added in version 3.4.
*
* @ingroup init
*/
typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user);
/*! @brief The function pointer type for memory deallocation callbacks.
*
* This is the function pointer type for memory deallocation callbacks.
* A memory deallocation callback function has the following signature:
* @code
* void function_name(void* block, void* user)
* @endcode
*
* This function may deallocate the specified memory block. This memory block
* will have been allocated with the same allocator.
*
* This function may be called during @ref glfwInit but before the library is
* flagged as initialized, as well as during @ref glfwTerminate after the
* library is no longer flagged as initialized.
*
* The block address will never be `NULL`. Deallocations of `NULL` are filtered out
* before reaching the custom allocator.
*
* @param[in] block The address of the memory block to deallocate.
* @param[in] user The user-defined pointer from the allocator.
*
* @pointer_lifetime The specified memory block will not be accessed by GLFW
* after this function is called.
*
* @reentrancy This function should not call any GLFW function.
*
* @thread_safety This function may be called from any thread that calls GLFW functions.
*
* @sa @ref init_allocator
* @sa @ref GLFWallocator
*
* @since Added in version 3.4.
*
* @ingroup init
*/
typedef void (* GLFWdeallocatefun)(void* block, void* user);
/*! @brief The function pointer type for error callbacks. /*! @brief The function pointer type for error callbacks.
* *
* This is the function pointer type for error callbacks. An error callback * This is the function pointer type for error callbacks. An error callback
@ -1352,7 +1541,7 @@ typedef struct GLFWcursor GLFWcursor;
* *
* @ingroup init * @ingroup init
*/ */
typedef void (* GLFWerrorfun)(int,const char*); typedef void (* GLFWerrorfun)(int error_code, const char* description);
/*! @brief The function pointer type for window position callbacks. /*! @brief The function pointer type for window position callbacks.
* *
@ -1375,7 +1564,7 @@ typedef void (* GLFWerrorfun)(int,const char*);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
/*! @brief The function pointer type for window size callbacks. /*! @brief The function pointer type for window size callbacks.
* *
@ -1397,7 +1586,7 @@ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height);
/*! @brief The function pointer type for window close callbacks. /*! @brief The function pointer type for window close callbacks.
* *
@ -1417,7 +1606,7 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowclosefun)(GLFWwindow*); typedef void (* GLFWwindowclosefun)(GLFWwindow* window);
/*! @brief The function pointer type for window content refresh callbacks. /*! @brief The function pointer type for window content refresh callbacks.
* *
@ -1437,7 +1626,7 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow*);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); typedef void (* GLFWwindowrefreshfun)(GLFWwindow* window);
/*! @brief The function pointer type for window focus callbacks. /*! @brief The function pointer type for window focus callbacks.
* *
@ -1458,7 +1647,7 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); typedef void (* GLFWwindowfocusfun)(GLFWwindow* window, int focused);
/*! @brief The function pointer type for window iconify callbacks. /*! @brief The function pointer type for window iconify callbacks.
* *
@ -1479,7 +1668,7 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); typedef void (* GLFWwindowiconifyfun)(GLFWwindow* window, int iconified);
/*! @brief The function pointer type for window maximize callbacks. /*! @brief The function pointer type for window maximize callbacks.
* *
@ -1500,7 +1689,7 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowmaximizefun)(GLFWwindow*,int); typedef void (* GLFWwindowmaximizefun)(GLFWwindow* window, int maximized);
/*! @brief The function pointer type for framebuffer size callbacks. /*! @brief The function pointer type for framebuffer size callbacks.
* *
@ -1521,7 +1710,7 @@ typedef void (* GLFWwindowmaximizefun)(GLFWwindow*,int);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); typedef void (* GLFWframebuffersizefun)(GLFWwindow* window, int width, int height);
/*! @brief The function pointer type for window content scale callbacks. /*! @brief The function pointer type for window content scale callbacks.
* *
@ -1542,7 +1731,7 @@ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);
* *
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowcontentscalefun)(GLFWwindow*,float,float); typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, float yscale);
/*! @brief The function pointer type for mouse button callbacks. /*! @brief The function pointer type for mouse button callbacks.
* *
@ -1568,7 +1757,7 @@ typedef void (* GLFWwindowcontentscalefun)(GLFWwindow*,float,float);
* *
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); typedef void (* GLFWmousebuttonfun)(GLFWwindow* window, int button, int action, int mods);
/*! @brief The function pointer type for cursor position callbacks. /*! @brief The function pointer type for cursor position callbacks.
* *
@ -1591,7 +1780,7 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
* *
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); typedef void (* GLFWcursorposfun)(GLFWwindow* window, double xpos, double ypos);
/*! @brief The function pointer type for cursor enter/leave callbacks. /*! @brief The function pointer type for cursor enter/leave callbacks.
* *
@ -1612,7 +1801,7 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
* *
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); typedef void (* GLFWcursorenterfun)(GLFWwindow* window, int entered);
/*! @brief The function pointer type for scroll callbacks. /*! @brief The function pointer type for scroll callbacks.
* *
@ -1633,7 +1822,7 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);
* *
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffset);
/*! @brief The function pointer type for keyboard key callbacks. /*! @brief The function pointer type for keyboard key callbacks.
* *
@ -1645,7 +1834,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
* *
* @param[in] window The window that received the event. * @param[in] window The window that received the event.
* @param[in] key The [keyboard key](@ref keys) that was pressed or released. * @param[in] key The [keyboard key](@ref keys) that was pressed or released.
* @param[in] scancode The system-specific scancode of the key. * @param[in] scancode The platform-specific scancode of the key.
* @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. Future * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. Future
* releases may add more actions. * releases may add more actions.
* @param[in] mods Bit field describing which [modifier keys](@ref mods) were * @param[in] mods Bit field describing which [modifier keys](@ref mods) were
@ -1659,7 +1848,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
* *
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int action, int mods);
/*! @brief The function pointer type for Unicode character callbacks. /*! @brief The function pointer type for Unicode character callbacks.
* *
@ -1680,7 +1869,7 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
* *
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); typedef void (* GLFWcharfun)(GLFWwindow* window, unsigned int codepoint);
/*! @brief The function pointer type for Unicode character with modifiers /*! @brief The function pointer type for Unicode character with modifiers
* callbacks. * callbacks.
@ -1707,7 +1896,7 @@ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
* *
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int mods);
/*! @brief The function pointer type for path drop callbacks. /*! @brief The function pointer type for path drop callbacks.
* *
@ -1731,7 +1920,7 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);
* *
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWdropfun)(GLFWwindow*,int,const char*[]); typedef void (* GLFWdropfun)(GLFWwindow* window, int path_count, const char* paths[]);
/*! @brief The function pointer type for monitor configuration callbacks. /*! @brief The function pointer type for monitor configuration callbacks.
* *
@ -1752,7 +1941,7 @@ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char*[]);
* *
* @ingroup monitor * @ingroup monitor
*/ */
typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event);
/*! @brief The function pointer type for joystick configuration callbacks. /*! @brief The function pointer type for joystick configuration callbacks.
* *
@ -1773,7 +1962,7 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
* *
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWjoystickfun)(int,int); typedef void (* GLFWjoystickfun)(int jid, int event);
/*! @brief Video mode type. /*! @brief Video mode type.
* *
@ -1887,6 +2076,23 @@ typedef struct GLFWgamepadstate
float axes[6]; float axes[6];
} GLFWgamepadstate; } GLFWgamepadstate;
/*! @brief
*
* @sa @ref init_allocator
* @sa @ref glfwInitAllocator
*
* @since Added in version 3.4.
*
* @ingroup init
*/
typedef struct GLFWallocator
{
GLFWallocatefun allocate;
GLFWreallocatefun reallocate;
GLFWdeallocatefun deallocate;
void* user;
} GLFWallocator;
/************************************************************************* /*************************************************************************
* GLFW API functions * GLFW API functions
@ -1905,10 +2111,15 @@ typedef struct GLFWgamepadstate
* Additional calls to this function after successful initialization but before * Additional calls to this function after successful initialization but before
* termination will return `GLFW_TRUE` immediately. * termination will return `GLFW_TRUE` immediately.
* *
* The @ref GLFW_PLATFORM init hint controls which platforms are considered during
* initialization. This also depends on which platforms the library was compiled to
* support.
*
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_PLATFORM_ERROR. * @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref
* GLFW_PLATFORM_ERROR.
* *
* @remark @macos This function will change the current directory of the * @remark @macos This function will change the current directory of the
* application to the `Contents/Resources` subdirectory of the application's * application to the `Contents/Resources` subdirectory of the application's
@ -1930,6 +2141,8 @@ typedef struct GLFWgamepadstate
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
* @sa @ref intro_init * @sa @ref intro_init
* @sa @ref glfwInitHint
* @sa @ref glfwInitAllocator
* @sa @ref glfwTerminate * @sa @ref glfwTerminate
* *
* @since Added in version 1.0. * @since Added in version 1.0.
@ -2004,6 +2217,81 @@ GLFWAPI void glfwTerminate(void);
*/ */
GLFWAPI void glfwInitHint(int hint, int value); GLFWAPI void glfwInitHint(int hint, int value);
/*! @brief Sets the init allocator to the desired value.
*
* To use the default allocator, call this function with a `NULL` argument.
*
* If you specify an allocator struct, every member must be a valid function
* pointer. If any member is `NULL`, this function emits @ref
* GLFW_INVALID_VALUE and the init allocator is unchanged.
*
* @param[in] allocator The allocator to use at the next initialization, or
* `NULL` to use the default one.
*
* @errors Possible errors include @ref GLFW_INVALID_VALUE.
*
* @pointer_lifetime The specified allocator is copied before this function
* returns.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref init_allocator
* @sa @ref glfwInit
*
* @since Added in version 3.4.
*
* @ingroup init
*/
GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator);
#if defined(VK_VERSION_1_0)
/*! @brief Sets the desired Vulkan `vkGetInstanceProcAddr` function.
*
* This function sets the `vkGetInstanceProcAddr` function that GLFW will use for all
* Vulkan related entry point queries.
*
* This feature is mostly useful on macOS, if your copy of the Vulkan loader is in
* a location where GLFW cannot find it through dynamic loading, or if you are still
* using the static library version of the loader.
*
* If set to `NULL`, GLFW will try to load the Vulkan loader dynamically by its standard
* name and get this function from there. This is the default behavior.
*
* The standard name of the loader is `vulkan-1.dll` on Windows, `libvulkan.so.1` on
* Linux and other Unix-like systems and `libvulkan.1.dylib` on macOS. If your code is
* also loading it via these names then you probably don't need to use this function.
*
* The function address you set is never reset by GLFW, but it only takes effect during
* initialization. Once GLFW has been initialized, any updates will be ignored until the
* library is terminated and initialized again.
*
* @param[in] loader The address of the function to use, or `NULL`.
*
* @par Loader function signature
* @code
* PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* name)
* @endcode
* For more information about this function, see the
* [Vulkan Registry](https://www.khronos.org/registry/vulkan/).
*
* @errors None.
*
* @remark This function may be called before @ref glfwInit.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref vulkan_loader
* @sa @ref glfwInit
*
* @since Added in version 3.4.
*
* @ingroup init
*/
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader);
#endif /*VK_VERSION_1_0*/
/*! @brief Retrieves the version of the GLFW library. /*! @brief Retrieves the version of the GLFW library.
* *
* This function retrieves the major, minor and revision numbers of the GLFW * This function retrieves the major, minor and revision numbers of the GLFW
@ -2034,15 +2322,18 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
/*! @brief Returns a string describing the compile-time configuration. /*! @brief Returns a string describing the compile-time configuration.
* *
* This function returns the compile-time generated * This function returns the compile-time generated
* [version string](@ref intro_version_string) of the GLFW library binary. It * [version string](@ref intro_version_string) of the GLFW library binary. It describes
* describes the version, platform, compiler and any platform-specific * the version, platforms, compiler and any platform or operating system specific
* compile-time options. It should not be confused with the OpenGL or OpenGL * compile-time options. It should not be confused with the OpenGL or OpenGL ES version
* ES version string, queried with `glGetString`. * string, queried with `glGetString`.
* *
* __Do not use the version string__ to parse the GLFW library version. The * __Do not use the version string__ to parse the GLFW library version. The
* @ref glfwGetVersion function provides the version of the running library * @ref glfwGetVersion function provides the version of the running library
* binary in numerical format. * binary in numerical format.
* *
* __Do not use the version string__ to parse what platforms are supported. The @ref
* glfwPlatformSupported function lets you query platform support.
*
* @return The ASCII encoded GLFW version string. * @return The ASCII encoded GLFW version string.
* *
* @errors None. * @errors None.
@ -2139,6 +2430,51 @@ GLFWAPI int glfwGetError(const char** description);
*/ */
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback); GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback);
/*! @brief Returns the currently selected platform.
*
* This function returns the platform that was selected during initialization. The
* returned value will be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`,
* `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`.
*
* @return The currently selected platform, or zero if an error occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread.
*
* @sa @ref platform
* @sa @ref glfwPlatformSupported
*
* @since Added in version 3.4.
*
* @ingroup init
*/
GLFWAPI int glfwGetPlatform(void);
/*! @brief Returns whether the library includes support for the specified platform.
*
* This function returns whether the library was compiled with support for the specified
* platform. The platform must be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`,
* `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`.
*
* @param[in] platform The platform to query.
* @return `GLFW_TRUE` if the platform is supported, or `GLFW_FALSE` otherwise.
*
* @errors Possible errors include @ref GLFW_INVALID_ENUM.
*
* @remark This function may be called before @ref glfwInit.
*
* @thread_safety This function may be called from any thread.
*
* @sa @ref platform
* @sa @ref glfwGetPlatform
*
* @since Added in version 3.4.
*
* @ingroup init
*/
GLFWAPI int glfwPlatformSupported(int platform);
/*! @brief Returns the currently connected monitors. /*! @brief Returns the currently connected monitors.
* *
* This function returns an array of handles for all currently connected * This function returns an array of handles for all currently connected
@ -2222,7 +2558,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
* This function returns the position, in screen coordinates, of the upper-left * This function returns the position, in screen coordinates, of the upper-left
* corner of the work area of the specified monitor along with the work area * corner of the work area of the specified monitor along with the work area
* size in screen coordinates. The work area is defined as the area of the * size in screen coordinates. The work area is defined as the area of the
* monitor not occluded by the operating system task bar where present. If no * monitor not occluded by the window system task bar where present. If no
* task bar exists then the work area is the monitor resolution in screen * task bar exists then the work area is the monitor resolution in screen
* coordinates. * coordinates.
* *
@ -2253,7 +2589,7 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos,
* This function returns the size, in millimetres, of the display area of the * This function returns the size, in millimetres, of the display area of the
* specified monitor. * specified monitor.
* *
* Some systems do not provide accurate monitor size information, either * Some platforms do not provide accurate monitor size information, either
* because the monitor * because the monitor
* [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data) * [EDID](https://en.wikipedia.org/wiki/Extended_display_identification_data)
* data is incorrect or because the driver does not report it accurately. * data is incorrect or because the driver does not report it accurately.
@ -2269,8 +2605,8 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos,
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
* @remark @win32 calculates the returned physical size from the * @remark @win32 On Windows 8 and earlier the physical size is calculated from
* current resolution and system DPI instead of querying the monitor EDID data. * the current resolution and system DPI instead of querying the monitor EDID data.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
@ -2714,10 +3050,10 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* OpenGL or OpenGL ES context. * OpenGL or OpenGL ES context.
* *
* By default, newly created windows use the placement recommended by the * By default, newly created windows use the placement recommended by the
* window system. To create the window at a specific position, make it * window system. To create the window at a specific position, set the @ref
* initially invisible using the [GLFW_VISIBLE](@ref GLFW_VISIBLE_hint) window * GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints before creation. To
* hint, set its [position](@ref window_pos) and then [show](@ref window_hide) * restore the default behavior, set either or both hints back to
* it. * `GLFW_ANY_POSITION`.
* *
* As long as at least one full screen window is not iconified, the screensaver * As long as at least one full screen window is not iconified, the screensaver
* is prohibited from starting. * is prohibited from starting.
@ -2942,7 +3278,8 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
* count is zero. * count is zero.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref
* GLFW_FEATURE_UNAVAILABLE (see remarks).
* *
* @pointer_lifetime The specified image data is copied before this function * @pointer_lifetime The specified image data is copied before this function
* returns. * returns.
@ -3267,7 +3604,7 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int
* regardless of their DPI and scaling settings. This relies on the system DPI * regardless of their DPI and scaling settings. This relies on the system DPI
* and scaling settings being somewhat correct. * and scaling settings being somewhat correct.
* *
* On systems where each monitors can have its own content scale, the window * On platforms where each monitors can have its own content scale, the window
* content scale will depend on which monitor the system considers the window * content scale will depend on which monitor the system considers the window
* to be on. * to be on.
* *
@ -3355,8 +3692,9 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
* previously restored. If the window is already iconified, this function does * previously restored. If the window is already iconified, this function does
* nothing. * nothing.
* *
* If the specified window is a full screen window, the original monitor * If the specified window is a full screen window, GLFW restores the original
* resolution is restored until the window is restored. * video mode of the monitor. The window's desired video mode is set again
* when the window is restored.
* *
* @param[in] window The window to iconify. * @param[in] window The window to iconify.
* *
@ -3386,8 +3724,8 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* (minimized) or maximized. If the window is already restored, this function * (minimized) or maximized. If the window is already restored, this function
* does nothing. * does nothing.
* *
* If the specified window is a full screen window, the resolution chosen for * If the specified window is an iconified full screen window, its desired
* the window is restored on the selected monitor. * video mode is set again for its monitor when the window is restored.
* *
* @param[in] window The window to restore. * @param[in] window The window to restore.
* *
@ -3448,6 +3786,11 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @wayland Because Wayland wants every frame of the desktop to be
* complete, this function does not immediately make the window visible.
* Instead it will become visible the next time the window framebuffer is
* updated after this call.
*
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
* @sa @ref window_hide * @sa @ref window_hide
@ -3650,6 +3993,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
* errors. However, this function should not fail as long as it is passed * errors. However, this function should not fail as long as it is passed
* valid arguments and the library has been [initialized](@ref intro_init). * valid arguments and the library has been [initialized](@ref intro_init).
* *
* @remark @wayland The Wayland protocol provides no way to check whether a
* window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`.
*
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
* @sa @ref window_attribs * @sa @ref window_attribs
@ -4235,6 +4581,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual
* and unlimited cursor movement. This is useful for implementing for * and unlimited cursor movement. This is useful for implementing for
* example 3D camera controls. * example 3D camera controls.
* - `GLFW_CURSOR_CAPTURED` makes the cursor visible and confines it to the
* content area of the window.
* *
* If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to
* enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are
@ -4409,8 +4757,7 @@ GLFWAPI int glfwGetKeyScancode(int key);
* *
* This function returns the last state reported for the specified key to the * This function returns the last state reported for the specified key to the
* specified window. The returned state is one of `GLFW_PRESS` or * specified window. The returned state is one of `GLFW_PRESS` or
* `GLFW_RELEASE`. The higher-level action `GLFW_REPEAT` is only reported to * `GLFW_RELEASE`. The action `GLFW_REPEAT` is only reported to the key callback.
* the key callback.
* *
* If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns * If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns
* `GLFW_PRESS` the first time you call it for a key that was pressed, even if * `GLFW_PRESS` the first time you call it for a key that was pressed, even if
@ -4571,8 +4918,8 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
* @return The handle of the created cursor, or `NULL` if an * @return The handle of the created cursor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR. * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR.
* *
* @pointer_lifetime The specified image data is copied before this function * @pointer_lifetime The specified image data is copied before this function
* returns. * returns.
@ -5387,6 +5734,8 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string);
* joystick is not present, does not have a mapping or an * joystick is not present, does not have a mapping or an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref GLFW_INVALID_ENUM.
*
* @pointer_lifetime The returned string is allocated and freed by GLFW. You * @pointer_lifetime The returned string is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the specified joystick is * should not free it yourself. It is valid until the specified joystick is
* disconnected, the gamepad mappings are updated or the library is terminated. * disconnected, the gamepad mappings are updated or the library is terminated.
@ -5476,8 +5825,8 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
* @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL`
* if an [error](@ref error_handling) occurred. * if an [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR. * GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
* *
* @pointer_lifetime The returned string is allocated and freed by GLFW. You * @pointer_lifetime The returned string is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the next call to @ref * should not free it yourself. It is valid until the next call to @ref
@ -5506,7 +5855,7 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
* *
* The resolution of the timer is system dependent, but is usually on the order * The resolution of the timer is system dependent, but is usually on the order
* of a few micro- or nanoseconds. It uses the highest-resolution monotonic * of a few micro- or nanoseconds. It uses the highest-resolution monotonic
* time source on each supported platform. * time source on each operating system.
* *
* @return The current time, in seconds, or zero if an * @return The current time, in seconds, or zero if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
@ -5717,7 +6066,7 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* window);
* GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR.
* *
* @remark This function is not called during context creation, leaving the * @remark This function is not called during context creation, leaving the
* swap interval set to whatever is the default on that platform. This is done * swap interval set to whatever is the default for that API. This is done
* because some swap interval extensions used by GLFW do not allow the swap * because some swap interval extensions used by GLFW do not allow the swap
* interval to be reset to zero once it has been set to a non-zero value. * interval to be reset to zero once it has been set to a non-zero value.
* *
@ -5821,13 +6170,11 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
* This function returns whether the Vulkan loader and any minimally functional * This function returns whether the Vulkan loader and any minimally functional
* ICD have been found. * ICD have been found.
* *
* The availability of a Vulkan loader and even an ICD does not by itself * The availability of a Vulkan loader and even an ICD does not by itself guarantee that
* guarantee that surface creation or even instance creation is possible. * surface creation or even instance creation is possible. Call @ref
* For example, on Fermi systems Nvidia will install an ICD that provides no * glfwGetRequiredInstanceExtensions to check whether the extensions necessary for Vulkan
* actual Vulkan support. Call @ref glfwGetRequiredInstanceExtensions to check * surface creation are available and @ref glfwGetPhysicalDevicePresentationSupport to
* whether the extensions necessary for Vulkan surface creation are available * check whether a queue family of a physical device supports image presentation.
* and @ref glfwGetPhysicalDevicePresentationSupport to check whether a queue
* family of a physical device supports image presentation.
* *
* @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE` * @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE`
* otherwise. * otherwise.
@ -5873,9 +6220,6 @@ GLFWAPI int glfwVulkanSupported(void);
* returned array, as it is an error to specify an extension more than once in * returned array, as it is an error to specify an extension more than once in
* the `VkInstanceCreateInfo` struct. * the `VkInstanceCreateInfo` struct.
* *
* @remark @macos GLFW currently supports both the `VK_MVK_macos_surface` and
* the newer `VK_EXT_metal_surface` extensions.
*
* @pointer_lifetime The returned array is allocated and freed by GLFW. You * @pointer_lifetime The returned array is allocated and freed by GLFW. You
* should not free it yourself. It is guaranteed to be valid only until the * should not free it yourself. It is guaranteed to be valid only until the
* library is terminated. * library is terminated.
@ -6014,17 +6358,20 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
* eliminate almost all occurrences of these errors. * eliminate almost all occurrences of these errors.
* *
* @remark @macos This function currently only supports the * @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the
* `VK_MVK_macos_surface` extension from MoltenVK. * `VK_MVK_macos_surface` extension as a fallback. The name of the selected
* extension, if any, is included in the array returned by @ref
* glfwGetRequiredInstanceExtensions.
* *
* @remark @macos This function creates and sets a `CAMetalLayer` instance for * @remark @macos This function creates and sets a `CAMetalLayer` instance for
* the window content view, which is required for MoltenVK to function. * the window content view, which is required for MoltenVK to function.
* *
* @remark @x11 GLFW by default attempts to use the `VK_KHR_xcb_surface` * @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension,
* extension, if available. You can make it prefer the `VK_KHR_xlib_surface` * with the `VK_KHR_xlib_surface` extension as a fallback. You can make
* extension by setting the * `VK_KHR_xlib_surface` the preferred extension by setting the
* [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init * [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init
* hint. * hint. The name of the selected extension, if any, is included in the array
* returned by @ref glfwGetRequiredInstanceExtensions.
* *
* @thread_safety This function may be called from any thread. For * @thread_safety This function may be called from any thread. For
* synchronization details of Vulkan objects, see the Vulkan specification. * synchronization details of Vulkan objects, see the Vulkan specification.
@ -6062,6 +6409,7 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window
*/ */
#ifndef GLAPIENTRY #ifndef GLAPIENTRY
#define GLAPIENTRY APIENTRY #define GLAPIENTRY APIENTRY
#define GLFW_GLAPIENTRY_DEFINED
#endif #endif
/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ /* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */

View file

@ -74,6 +74,16 @@ extern "C" {
* and which platform-specific headers to include. It is then up your (by * and which platform-specific headers to include. It is then up your (by
* definition platform-specific) code to handle which of these should be * definition platform-specific) code to handle which of these should be
* defined. * defined.
*
* If you do not want the platform-specific headers to be included, define
* `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header.
*
* @code
* #define GLFW_EXPOSE_NATIVE_WIN32
* #define GLFW_EXPOSE_NATIVE_WGL
* #define GLFW_NATIVE_INCLUDE_NONE
* #include <GLFW/glfw3native.h>
* @endcode
*/ */
@ -81,46 +91,71 @@ extern "C" {
* System headers and types * System headers and types
*************************************************************************/ *************************************************************************/
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) #if !defined(GLFW_NATIVE_INCLUDE_NONE)
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_KHR_debug callback)
// but windows.h assumes no one will define APIENTRY before it does
#if defined(GLFW_APIENTRY_DEFINED)
#undef APIENTRY
#undef GLFW_APIENTRY_DEFINED
#endif
// @raysan5: Actually, only HWND handler needs to be defined
// Including windows.h could suppose symbols re-definition issues (i.e Rectangle type)
//#include <windows.h>
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
typedef void* id;
#endif
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL) #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */ /* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
#endif * example to allow applications to correctly declare a GL_KHR_debug callback)
#if defined(GLFW_EXPOSE_NATIVE_NSGL) * but windows.h assumes no one will define APIENTRY before it does
/* NSGL is declared by Cocoa.h */ */
#endif #if defined(GLFW_APIENTRY_DEFINED)
#if defined(GLFW_EXPOSE_NATIVE_GLX) #undef APIENTRY
#include <GL/glx.h> #undef GLFW_APIENTRY_DEFINED
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_EGL) #include <windows.h>
#include <EGL/egl.h> #endif
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA) #if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#include <GL/osmesa.h> #if defined(__OBJC__)
#endif #import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
#include <objc/objc.h>
#endif
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, glx.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/glx.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, osmesa.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/osmesa.h>
#endif
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
/************************************************************************* /*************************************************************************
@ -134,6 +169,8 @@ extern "C" {
* of the specified monitor, or `NULL` if an [error](@ref error_handling) * of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred. * occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -149,6 +186,8 @@ GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -163,6 +202,16 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
* @return The `HWND` of the specified window, or `NULL` if an * @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -179,6 +228,17 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
* @return The `HGLRC` of the specified window, or `NULL` if an * @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -195,6 +255,8 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
* @return The `CGDirectDisplayID` of the specified monitor, or * @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -209,6 +271,8 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
* @return The `NSWindow` of the specified window, or `nil` if an * @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -225,6 +289,9 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
* @return The `NSOpenGLContext` of the specified window, or `nil` if an * @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -241,6 +308,8 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
* @return The `Display` used by GLFW, or `NULL` if an * @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -255,6 +324,8 @@ GLFWAPI Display* glfwGetX11Display(void);
* @return The `RRCrtc` of the specified monitor, or `None` if an * @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -269,6 +340,8 @@ GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
* @return The `RROutput` of the specified monitor, or `None` if an * @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -283,6 +356,8 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
* @return The `Window` of the specified window, or `None` if an * @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -349,6 +424,9 @@ GLFWAPI const char* glfwGetX11SelectionString(void);
* @return The `GLXContext` of the specified window, or `NULL` if an * @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -363,6 +441,9 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
* @return The `GLXWindow` of the specified window, or `None` if an * @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -379,6 +460,8 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
* @return The `struct wl_display*` used by GLFW, or `NULL` if an * @return The `struct wl_display*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -393,6 +476,8 @@ GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an * @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -407,6 +492,8 @@ GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
* @return The main `struct wl_surface*` of the specified window, or `NULL` if * @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred. * an [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -423,6 +510,11 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark Because EGL is initialized on demand, this function will return
* `EGL_NO_DISPLAY` until the first context has been created via EGL.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -437,6 +529,9 @@ GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -451,6 +546,9 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -474,6 +572,9 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -495,6 +596,9 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *
@ -509,6 +613,9 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height
* @return The `OSMesaContext` of the specified window, or `NULL` if an * @return The `OSMesaContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NO_WINDOW_CONTEXT and @ref
* GLFW_NOT_INITIALIZED.
*
* @thread_safety This function may be called from any thread. Access is not * @thread_safety This function may be called from any thread. Access is not
* synchronized. * synchronized.
* *

View file

@ -75,7 +75,6 @@ static void changeToResourcesDirectory(void)
// //
static void createMenuBar(void) static void createMenuBar(void)
{ {
size_t i;
NSString* appName = nil; NSString* appName = nil;
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary]; NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
NSString* nameKeys[] = NSString* nameKeys[] =
@ -87,7 +86,7 @@ static void createMenuBar(void)
// Try to figure out what the calling application is called // Try to figure out what the calling application is called
for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++) for (size_t i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
{ {
id name = bundleInfo[nameKeys[i]]; id name = bundleInfo[nameKeys[i]];
if (name && if (name &&
@ -177,8 +176,6 @@ static void createMenuBar(void)
// //
static void createKeyTables(void) static void createKeyTables(void)
{ {
int scancode;
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes)); memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes)); memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
@ -297,7 +294,7 @@ static void createKeyTables(void)
_glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY; _glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY;
_glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT; _glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT;
for (scancode = 0; scancode < 256; scancode++) for (int scancode = 0; scancode < 256; scancode++)
{ {
// Store the reverse translation for faster key name lookup // Store the reverse translation for faster key name lookup
if (_glfw.ns.keycodes[scancode] >= 0) if (_glfw.ns.keycodes[scancode] >= 0)
@ -307,7 +304,7 @@ static void createKeyTables(void)
// Retrieve Unicode data for the current keyboard layout // Retrieve Unicode data for the current keyboard layout
// //
static GLFWbool updateUnicodeDataNS(void) static GLFWbool updateUnicodeData(void)
{ {
if (_glfw.ns.inputSource) if (_glfw.ns.inputSource)
{ {
@ -377,7 +374,7 @@ static GLFWbool initializeTIS(void)
_glfw.ns.tis.kPropertyUnicodeKeyLayoutData = _glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
*kPropertyUnicodeKeyLayoutData; *kPropertyUnicodeKeyLayoutData;
return updateUnicodeDataNS(); return updateUnicodeData();
} }
@interface GLFWHelper : NSObject @interface GLFWHelper : NSObject
@ -387,7 +384,7 @@ static GLFWbool initializeTIS(void)
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object - (void)selectedKeyboardInputSourceChanged:(NSObject* )object
{ {
updateUnicodeDataNS(); updateUnicodeData();
} }
- (void)doNothing:(id)object - (void)doNothing:(id)object
@ -403,9 +400,7 @@ static GLFWbool initializeTIS(void)
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{ {
_GLFWwindow* window; for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
for (window = _glfw.windowListHead; window; window = window->next)
_glfwInputWindowCloseRequest(window); _glfwInputWindowCloseRequest(window);
return NSTerminateCancel; return NSTerminateCancel;
@ -413,15 +408,13 @@ static GLFWbool initializeTIS(void)
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification - (void)applicationDidChangeScreenParameters:(NSNotification *) notification
{ {
_GLFWwindow* window; for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
for (window = _glfw.windowListHead; window; window = window->next)
{ {
if (window->context.client != GLFW_NO_API) if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update]; [window->context.nsgl.object update];
} }
_glfwPollMonitorsNS(); _glfwPollMonitorsCocoa();
} }
- (void)applicationWillFinishLaunching:(NSNotification *)notification - (void)applicationWillFinishLaunching:(NSNotification *)notification
@ -444,16 +437,14 @@ static GLFWbool initializeTIS(void)
- (void)applicationDidFinishLaunching:(NSNotification *)notification - (void)applicationDidFinishLaunching:(NSNotification *)notification
{ {
_glfwPlatformPostEmptyEvent(); _glfwPostEmptyEventCocoa();
[NSApp stop:nil]; [NSApp stop:nil];
} }
- (void)applicationDidHide:(NSNotification *)notification - (void)applicationDidHide:(NSNotification *)notification
{ {
int i; for (int i = 0; i < _glfw.monitorCount; i++)
_glfwRestoreVideoModeCocoa(_glfw.monitors[i]);
for (i = 0; i < _glfw.monitorCount; i++)
_glfwRestoreVideoModeNS(_glfw.monitors[i]);
} }
@end // GLFWApplicationDelegate @end // GLFWApplicationDelegate
@ -463,24 +454,32 @@ static GLFWbool initializeTIS(void)
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void* _glfwLoadLocalVulkanLoaderNS(void) void* _glfwLoadLocalVulkanLoaderCocoa(void)
{ {
CFBundleRef bundle = CFBundleGetMainBundle(); CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle) if (!bundle)
return NULL; return NULL;
CFURLRef url = CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
CFBundleCopyAuxiliaryExecutableURL(bundle, CFSTR("libvulkan.1.dylib")); if (!frameworksUrl)
if (!url)
return NULL; return NULL;
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
if (!loaderUrl)
{
CFRelease(frameworksUrl);
return NULL;
}
char path[PATH_MAX]; char path[PATH_MAX];
void* handle = NULL; void* handle = NULL;
if (CFURLGetFileSystemRepresentation(url, true, (UInt8*) path, sizeof(path) - 1)) if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
handle = _glfw_dlopen(path); handle = _glfwPlatformLoadModule(path);
CFRelease(url); CFRelease(loaderUrl);
CFRelease(frameworksUrl);
return handle; return handle;
} }
@ -489,7 +488,89 @@ void* _glfwLoadLocalVulkanLoaderNS(void)
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void) GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
{
const _GLFWplatform cocoa =
{
GLFW_PLATFORM_COCOA,
_glfwInitCocoa,
_glfwTerminateCocoa,
_glfwGetCursorPosCocoa,
_glfwSetCursorPosCocoa,
_glfwSetCursorModeCocoa,
_glfwSetRawMouseMotionCocoa,
_glfwRawMouseMotionSupportedCocoa,
_glfwCreateCursorCocoa,
_glfwCreateStandardCursorCocoa,
_glfwDestroyCursorCocoa,
_glfwSetCursorCocoa,
_glfwGetScancodeNameCocoa,
_glfwGetKeyScancodeCocoa,
_glfwSetClipboardStringCocoa,
_glfwGetClipboardStringCocoa,
_glfwInitJoysticksCocoa,
_glfwTerminateJoysticksCocoa,
_glfwPollJoystickCocoa,
_glfwGetMappingNameCocoa,
_glfwUpdateGamepadGUIDCocoa,
_glfwFreeMonitorCocoa,
_glfwGetMonitorPosCocoa,
_glfwGetMonitorContentScaleCocoa,
_glfwGetMonitorWorkareaCocoa,
_glfwGetVideoModesCocoa,
_glfwGetVideoModeCocoa,
_glfwGetGammaRampCocoa,
_glfwSetGammaRampCocoa,
_glfwCreateWindowCocoa,
_glfwDestroyWindowCocoa,
_glfwSetWindowTitleCocoa,
_glfwSetWindowIconCocoa,
_glfwGetWindowPosCocoa,
_glfwSetWindowPosCocoa,
_glfwGetWindowSizeCocoa,
_glfwSetWindowSizeCocoa,
_glfwSetWindowSizeLimitsCocoa,
_glfwSetWindowAspectRatioCocoa,
_glfwGetFramebufferSizeCocoa,
_glfwGetWindowFrameSizeCocoa,
_glfwGetWindowContentScaleCocoa,
_glfwIconifyWindowCocoa,
_glfwRestoreWindowCocoa,
_glfwMaximizeWindowCocoa,
_glfwShowWindowCocoa,
_glfwHideWindowCocoa,
_glfwRequestWindowAttentionCocoa,
_glfwFocusWindowCocoa,
_glfwSetWindowMonitorCocoa,
_glfwWindowFocusedCocoa,
_glfwWindowIconifiedCocoa,
_glfwWindowVisibleCocoa,
_glfwWindowMaximizedCocoa,
_glfwWindowHoveredCocoa,
_glfwFramebufferTransparentCocoa,
_glfwGetWindowOpacityCocoa,
_glfwSetWindowResizableCocoa,
_glfwSetWindowDecoratedCocoa,
_glfwSetWindowFloatingCocoa,
_glfwSetWindowOpacityCocoa,
_glfwSetWindowMousePassthroughCocoa,
_glfwPollEventsCocoa,
_glfwWaitEventsCocoa,
_glfwWaitEventsTimeoutCocoa,
_glfwPostEmptyEventCocoa,
_glfwGetEGLPlatformCocoa,
_glfwGetEGLNativeDisplayCocoa,
_glfwGetEGLNativeWindowCocoa,
_glfwGetRequiredInstanceExtensionsCocoa,
_glfwGetPhysicalDevicePresentationSupportCocoa,
_glfwCreateWindowSurfaceCocoa,
};
*platform = cocoa;
return GLFW_TRUE;
}
int _glfwInitCocoa(void)
{ {
@autoreleasepool { @autoreleasepool {
@ -547,9 +628,7 @@ int _glfwPlatformInit(void)
if (!initializeTIS()) if (!initializeTIS())
return GLFW_FALSE; return GLFW_FALSE;
_glfwInitTimerNS(); _glfwPollMonitorsCocoa();
_glfwPollMonitorsNS();
if (![[NSRunningApplication currentApplication] isFinishedLaunching]) if (![[NSRunningApplication currentApplication] isFinishedLaunching])
[NSApp run]; [NSApp run];
@ -563,7 +642,7 @@ int _glfwPlatformInit(void)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformTerminate(void) void _glfwTerminateCocoa(void)
{ {
@autoreleasepool { @autoreleasepool {
@ -602,19 +681,12 @@ void _glfwPlatformTerminate(void)
if (_glfw.ns.keyUpMonitor) if (_glfw.ns.keyUpMonitor)
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor]; [NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
free(_glfw.ns.clipboardString); _glfw_free(_glfw.ns.clipboardString);
_glfwTerminateNSGL(); _glfwTerminateNSGL();
_glfwTerminateEGL();
_glfwTerminateOSMesa();
} // autoreleasepool } // autoreleasepool
} }
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " Cocoa NSGL EGL OSMesa"
#if defined(_GLFW_BUILD_DLL)
" dynamic"
#endif
;
}

View file

@ -26,13 +26,12 @@
#include <IOKit/IOKitLib.h> #include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h> #include <IOKit/IOCFPlugIn.h>
#include <IOKit/hid/IOHIDLib.h>
#include <IOKit/hid/IOHIDKeys.h> #include <IOKit/hid/IOHIDKeys.h>
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns #define GLFW_COCOA_JOYSTICK_STATE _GLFWjoystickNS ns;
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyJoystick; } #define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X" #define GLFW_BUILD_COCOA_MAPPINGS
// Cocoa-specific per-joystick data // Cocoa-specific per-joystick data
// //
@ -44,3 +43,9 @@ typedef struct _GLFWjoystickNS
CFMutableArrayRef hats; CFMutableArrayRef hats;
} _GLFWjoystickNS; } _GLFWjoystickNS;
GLFWbool _glfwInitJoysticksCocoa(void);
void _glfwTerminateJoysticksCocoa(void);
GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameCocoa(void);
void _glfwUpdateGamepadGUIDCocoa(char* guid);

View file

@ -96,25 +96,21 @@ static CFComparisonResult compareElements(const void* fp,
// //
static void closeJoystick(_GLFWjoystick* js) static void closeJoystick(_GLFWjoystick* js)
{ {
int i; _glfwInputJoystick(js, GLFW_DISCONNECTED);
if (!js->present) for (int i = 0; i < CFArrayGetCount(js->ns.axes); i++)
return; _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
CFRelease(js->ns.axes); CFRelease(js->ns.axes);
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++) for (int i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i)); _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
CFRelease(js->ns.buttons); CFRelease(js->ns.buttons);
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) for (int i = 0; i < CFArrayGetCount(js->ns.hats); i++)
free((void*) CFArrayGetValueAtIndex(js->ns.hats, i)); _glfw_free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
CFRelease(js->ns.hats); CFRelease(js->ns.hats);
_glfwFreeJoystick(js); _glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
} }
// Callback for user-initiated joystick addition // Callback for user-initiated joystick addition
@ -127,7 +123,6 @@ static void matchCallback(void* context,
int jid; int jid;
char name[256]; char name[256];
char guid[33]; char guid[33];
CFIndex i;
CFTypeRef property; CFTypeRef property;
uint32_t vendor = 0, product = 0, version = 0; uint32_t vendor = 0, product = 0, version = 0;
_GLFWjoystick* js; _GLFWjoystick* js;
@ -185,7 +180,7 @@ static void matchCallback(void* context,
CFArrayRef elements = CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone); IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
for (i = 0; i < CFArrayGetCount(elements); i++) for (CFIndex i = 0; i < CFArrayGetCount(elements); i++)
{ {
IOHIDElementRef native = (IOHIDElementRef) IOHIDElementRef native = (IOHIDElementRef)
CFArrayGetValueAtIndex(elements, i); CFArrayGetValueAtIndex(elements, i);
@ -251,7 +246,7 @@ static void matchCallback(void* context,
if (target) if (target)
{ {
_GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS)); _GLFWjoyelementNS* element = _glfw_calloc(1, sizeof(_GLFWjoyelementNS));
element->native = native; element->native = native;
element->usage = usage; element->usage = usage;
element->index = (int) CFArrayGetCount(target); element->index = (int) CFArrayGetCount(target);
@ -290,13 +285,11 @@ static void removeCallback(void* context,
void* sender, void* sender,
IOHIDDeviceRef device) IOHIDDeviceRef device)
{ {
int jid; for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (_glfw.joysticks[jid].ns.device == device) if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device)
{ {
closeJoystick(_glfw.joysticks + jid); closeJoystick(&_glfw.joysticks[jid]);
break; break;
} }
} }
@ -307,7 +300,7 @@ static void removeCallback(void* context,
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformInitJoysticks(void) GLFWbool _glfwInitJoysticksCocoa(void)
{ {
CFMutableArrayRef matching; CFMutableArrayRef matching;
const long usages[] = const long usages[] =
@ -384,12 +377,13 @@ GLFWbool _glfwPlatformInitJoysticks(void)
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformTerminateJoysticks(void) void _glfwTerminateJoysticksCocoa(void)
{ {
int jid; for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) if (_glfw.joysticks[jid].connected)
closeJoystick(_glfw.joysticks + jid); closeJoystick(&_glfw.joysticks[jid]);
}
if (_glfw.ns.hidManager) if (_glfw.ns.hidManager)
{ {
@ -399,13 +393,11 @@ void _glfwPlatformTerminateJoysticks(void)
} }
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode)
{ {
if (mode & _GLFW_POLL_AXES) if (mode & _GLFW_POLL_AXES)
{ {
CFIndex i; for (CFIndex i = 0; i < CFArrayGetCount(js->ns.axes); i++)
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
{ {
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*) _GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.axes, i); CFArrayGetValueAtIndex(js->ns.axes, i);
@ -430,9 +422,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
if (mode & _GLFW_POLL_BUTTONS) if (mode & _GLFW_POLL_BUTTONS)
{ {
CFIndex i; for (CFIndex i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
{ {
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*) _GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.buttons, i); CFArrayGetValueAtIndex(js->ns.buttons, i);
@ -441,7 +431,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
_glfwInputJoystickButton(js, (int) i, state); _glfwInputJoystickButton(js, (int) i, state);
} }
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++) for (CFIndex i = 0; i < CFArrayGetCount(js->ns.hats); i++)
{ {
const int states[9] = const int states[9] =
{ {
@ -466,10 +456,15 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
} }
} }
return js->present; return js->connected;
} }
void _glfwPlatformUpdateGamepadGUID(char* guid) const char* _glfwGetMappingNameCocoa(void)
{
return "Mac OS X";
}
void _glfwUpdateGamepadGUIDCocoa(char* guid)
{ {
if ((strncmp(guid + 4, "000000000000", 12) == 0) && if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
(strncmp(guid + 20, "000000000000", 12) == 0)) (strncmp(guid + 20, "000000000000", 12) == 0))

View file

@ -58,7 +58,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
io_service_t service; io_service_t service;
CFDictionaryRef info; CFDictionaryRef info;
if (IOServiceGetMatchingServices(kIOMasterPortDefault, if (IOServiceGetMatchingServices(MACH_PORT_NULL,
IOServiceMatching("IODisplayConnect"), IOServiceMatching("IODisplayConnect"),
&it) != 0) &it) != 0)
{ {
@ -98,11 +98,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
IOObjectRelease(it); IOObjectRelease(it);
if (!service) if (!service)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to find service port for display");
return _glfw_strdup("Display"); return _glfw_strdup("Display");
}
CFDictionaryRef names = CFDictionaryRef names =
CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
@ -120,7 +116,7 @@ static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
const CFIndex size = const CFIndex size =
CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef),
kCFStringEncodingUTF8); kCFStringEncodingUTF8);
char* name = calloc(size + 1, 1); char* name = _glfw_calloc(size + 1, 1);
CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8); CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8);
CFRelease(info); CFRelease(info);
@ -231,7 +227,7 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
io_iterator_t it; io_iterator_t it;
io_service_t service; io_service_t service;
if (IOServiceGetMatchingServices(kIOMasterPortDefault, if (IOServiceGetMatchingServices(MACH_PORT_NULL,
IOServiceMatching("IOFramebuffer"), IOServiceMatching("IOFramebuffer"),
&it) != 0) &it) != 0)
{ {
@ -297,11 +293,11 @@ static double getFallbackRefreshRate(CGDirectDisplayID displayID)
// Poll for changes in the set of connected monitors // Poll for changes in the set of connected monitors
// //
void _glfwPollMonitorsNS(void) void _glfwPollMonitorsCocoa(void)
{ {
uint32_t displayCount; uint32_t displayCount;
CGGetOnlineDisplayList(0, NULL, &displayCount); CGGetOnlineDisplayList(0, NULL, &displayCount);
CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID)); CGDirectDisplayID* displays = _glfw_calloc(displayCount, sizeof(CGDirectDisplayID));
CGGetOnlineDisplayList(displayCount, displays, &displayCount); CGGetOnlineDisplayList(displayCount, displays, &displayCount);
for (int i = 0; i < _glfw.monitorCount; i++) for (int i = 0; i < _glfw.monitorCount; i++)
@ -311,7 +307,7 @@ void _glfwPollMonitorsNS(void)
uint32_t disconnectedCount = _glfw.monitorCount; uint32_t disconnectedCount = _glfw.monitorCount;
if (disconnectedCount) if (disconnectedCount)
{ {
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected, memcpy(disconnected,
_glfw.monitors, _glfw.monitors,
_glfw.monitorCount * sizeof(_GLFWmonitor*)); _glfw.monitorCount * sizeof(_GLFWmonitor*));
@ -363,7 +359,7 @@ void _glfwPollMonitorsNS(void)
monitor->ns.unitNumber = unitNumber; monitor->ns.unitNumber = unitNumber;
monitor->ns.screen = screen; monitor->ns.screen = screen;
free(name); _glfw_free(name);
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]); CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
if (CGDisplayModeGetRefreshRate(mode) == 0.0) if (CGDisplayModeGetRefreshRate(mode) == 0.0)
@ -379,16 +375,16 @@ void _glfwPollMonitorsNS(void)
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
} }
free(disconnected); _glfw_free(disconnected);
free(displays); _glfw_free(displays);
} }
// Change the current video mode // Change the current video mode
// //
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired) void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{ {
GLFWvidmode current; GLFWvidmode current;
_glfwPlatformGetVideoMode(monitor, &current); _glfwGetVideoModeCocoa(monitor, &current);
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired); const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
if (_glfwCompareVideoModes(&current, best) == 0) if (_glfwCompareVideoModes(&current, best) == 0)
@ -428,7 +424,7 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
// Restore the previously saved (original) video mode // Restore the previously saved (original) video mode
// //
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor) void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor)
{ {
if (monitor->ns.previousMode) if (monitor->ns.previousMode)
{ {
@ -447,11 +443,11 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor)
{ {
} }
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos)
{ {
@autoreleasepool { @autoreleasepool {
@ -465,8 +461,8 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
@autoreleasepool { @autoreleasepool {
@ -487,9 +483,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor,
int* xpos, int* ypos, int* xpos, int* ypos,
int* width, int* height) int* width, int* height)
{ {
@autoreleasepool { @autoreleasepool {
@ -504,7 +500,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
if (xpos) if (xpos)
*xpos = frameRect.origin.x; *xpos = frameRect.origin.x;
if (ypos) if (ypos)
*ypos = _glfwTransformYNS(frameRect.origin.y + frameRect.size.height - 1); *ypos = _glfwTransformYCocoa(frameRect.origin.y + frameRect.size.height - 1);
if (width) if (width)
*width = frameRect.size.width; *width = frameRect.size.width;
if (height) if (height)
@ -513,7 +509,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
} // autoreleasepool } // autoreleasepool
} }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count)
{ {
@autoreleasepool { @autoreleasepool {
@ -521,7 +517,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL); CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
const CFIndex found = CFArrayGetCount(modes); const CFIndex found = CFArrayGetCount(modes);
GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode)); GLFWvidmode* result = _glfw_calloc(found, sizeof(GLFWvidmode));
for (CFIndex i = 0; i < found; i++) for (CFIndex i = 0; i < found; i++)
{ {
@ -553,7 +549,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) void _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode *mode)
{ {
@autoreleasepool { @autoreleasepool {
@ -564,12 +560,12 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
} // autoreleasepool } // autoreleasepool
} }
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
@autoreleasepool { @autoreleasepool {
uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID); uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); CGGammaValue* values = _glfw_calloc(size * 3, sizeof(CGGammaValue));
CGGetDisplayTransferByTable(monitor->ns.displayID, CGGetDisplayTransferByTable(monitor->ns.displayID,
size, size,
@ -587,17 +583,17 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535); ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535);
} }
free(values); _glfw_free(values);
return GLFW_TRUE; return GLFW_TRUE;
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{ {
@autoreleasepool { @autoreleasepool {
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue)); CGGammaValue* values = _glfw_calloc(ramp->size * 3, sizeof(CGGammaValue));
for (unsigned int i = 0; i < ramp->size; i++) for (unsigned int i = 0; i < ramp->size; i++)
{ {
@ -612,7 +608,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
values + ramp->size, values + ramp->size,
values + ramp->size * 2); values + ramp->size * 2);
free(values); _glfw_free(values);
} // autoreleasepool } // autoreleasepool
} }

View file

@ -25,13 +25,15 @@
//======================================================================== //========================================================================
#include <stdint.h> #include <stdint.h>
#include <dlfcn.h>
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDLib.h>
// NOTE: All of NSGL was deprecated in the 10.14 SDK // NOTE: All of NSGL was deprecated in the 10.14 SDK
// This disables the pointless warnings for every symbol we use // This disables the pointless warnings for every symbol we use
#ifndef GL_SILENCE_DEPRECATION
#define GL_SILENCE_DEPRECATION #define GL_SILENCE_DEPRECATION
#endif
#if defined(__OBJC__) #if defined(__OBJC__)
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
@ -40,8 +42,15 @@ typedef void* id;
#endif #endif
// NOTE: Many Cocoa enum values have been renamed and we need to build across // NOTE: Many Cocoa enum values have been renamed and we need to build across
// SDK versions where one is unavailable or the other deprecated // SDK versions where one is unavailable or deprecated.
// We use the newer names in code and these macros to handle compatibility // We use the newer names in code and replace them with the older names if
// the base SDK does not provide the newer names.
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 #if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat #define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
#define NSEventMaskAny NSAnyEventMask #define NSEventMaskAny NSAnyEventMask
@ -60,6 +69,15 @@ typedef void* id;
#define NSWindowStyleMaskTitled NSTitledWindowMask #define NSWindowStyleMaskTitled NSTitledWindowMask
#endif #endif
// NOTE: Many Cocoa dynamically linked constants have been renamed and we need
// to build across SDK versions where one is unavailable or deprecated.
// We use the newer names in code and replace them with the older names if
// the deployment target is older than the newer names.
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101300
#define NSPasteboardTypeURL NSURLPboardType
#endif
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef VkFlags VkMetalSurfaceCreateFlagsEXT; typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
@ -82,19 +100,13 @@ typedef struct VkMetalSurfaceCreateInfoEXT
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*);
#include "posix_thread.h" #define GLFW_COCOA_WINDOW_STATE _GLFWwindowNS ns;
#include "cocoa_joystick.h" #define GLFW_COCOA_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns;
#include "nsgl_context.h" #define GLFW_COCOA_MONITOR_STATE _GLFWmonitorNS ns;
#define GLFW_COCOA_CURSOR_STATE _GLFWcursorNS ns;
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) #define GLFW_NSGL_CONTEXT_STATE _GLFWcontextNSGL nsgl;
#define _glfw_dlclose(handle) dlclose(handle) #define GLFW_NSGL_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl;
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerNS ns
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns
// HIToolbox.framework pointer typedefs // HIToolbox.framework pointer typedefs
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData #define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
@ -106,6 +118,22 @@ typedef UInt8 (*PFN_LMGetKbdType)(void);
#define LMGetKbdType _glfw.ns.tis.GetKbdType #define LMGetKbdType _glfw.ns.tis.GetKbdType
// NSGL-specific per-context data
//
typedef struct _GLFWcontextNSGL
{
id pixelFormat;
id object;
} _GLFWcontextNSGL;
// NSGL-specific global data
//
typedef struct _GLFWlibraryNSGL
{
// dlopen handle for OpenGL.framework (for glfwGetProcAddress)
CFBundleRef framework;
} _GLFWlibraryNSGL;
// Cocoa-specific per-window data // Cocoa-specific per-window data
// //
typedef struct _GLFWwindowNS typedef struct _GLFWwindowNS
@ -128,7 +156,6 @@ typedef struct _GLFWwindowNS
// since the last cursor motion event was processed // since the last cursor motion event was processed
// This is kept to counteract Cocoa doing the same internally // This is kept to counteract Cocoa doing the same internally
double cursorWarpDeltaX, cursorWarpDeltaY; double cursorWarpDeltaX, cursorWarpDeltaY;
} _GLFWwindowNS; } _GLFWwindowNS;
// Cocoa-specific global data // Cocoa-specific global data
@ -162,7 +189,6 @@ typedef struct _GLFWlibraryNS
PFN_LMGetKbdType GetKbdType; PFN_LMGetKbdType GetKbdType;
CFStringRef kPropertyUnicodeKeyLayoutData; CFStringRef kPropertyUnicodeKeyLayoutData;
} tis; } tis;
} _GLFWlibraryNS; } _GLFWlibraryNS;
// Cocoa-specific per-monitor data // Cocoa-specific per-monitor data
@ -174,7 +200,6 @@ typedef struct _GLFWmonitorNS
uint32_t unitNumber; uint32_t unitNumber;
id screen; id screen;
double fallbackRefreshRate; double fallbackRefreshRate;
} _GLFWmonitorNS; } _GLFWmonitorNS;
// Cocoa-specific per-cursor data // Cocoa-specific per-cursor data
@ -182,25 +207,96 @@ typedef struct _GLFWmonitorNS
typedef struct _GLFWcursorNS typedef struct _GLFWcursorNS
{ {
id object; id object;
} _GLFWcursorNS; } _GLFWcursorNS;
// Cocoa-specific global timer data
//
typedef struct _GLFWtimerNS
{
uint64_t frequency;
} _GLFWtimerNS; GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform);
int _glfwInitCocoa(void);
void _glfwTerminateCocoa(void);
GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowCocoa(_GLFWwindow* window);
void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconCocoa(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosCocoa(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeCocoa(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsCocoa(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioCocoa(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeCocoa(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeCocoa(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleCocoa(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowCocoa(_GLFWwindow* window);
void _glfwRestoreWindowCocoa(_GLFWwindow* window);
void _glfwMaximizeWindowCocoa(_GLFWwindow* window);
void _glfwShowWindowCocoa(_GLFWwindow* window);
void _glfwHideWindowCocoa(_GLFWwindow* window);
void _glfwRequestWindowAttentionCocoa(_GLFWwindow* window);
void _glfwFocusWindowCocoa(_GLFWwindow* window);
void _glfwSetWindowMonitorCocoa(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredCocoa(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentCocoa(_GLFWwindow* window);
void _glfwSetWindowResizableCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingCocoa(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityCocoa(_GLFWwindow* window);
void _glfwSetWindowOpacityCocoa(_GLFWwindow* window, float opacity);
void _glfwSetWindowMousePassthroughCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwInitTimerNS(void); void _glfwSetRawMouseMotionCocoa(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedCocoa(void);
void _glfwPollMonitorsNS(void); void _glfwPollEventsCocoa(void);
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired); void _glfwWaitEventsCocoa(void);
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor); void _glfwWaitEventsTimeoutCocoa(double timeout);
void _glfwPostEmptyEventCocoa(void);
float _glfwTransformYNS(float y); void _glfwGetCursorPosCocoa(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosCocoa(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameCocoa(int scancode);
int _glfwGetKeyScancodeCocoa(int key);
GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorCocoa(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorCocoa(_GLFWcursor* cursor);
void _glfwSetCursorCocoa(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringCocoa(const char* string);
const char* _glfwGetClipboardStringCocoa(void);
void* _glfwLoadLocalVulkanLoaderNS(void); EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayCocoa(void);
EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportCocoa(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor);
void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count);
void _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPollMonitorsCocoa(void);
void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor);
float _glfwTransformYCocoa(float y);
void* _glfwLoadLocalVulkanLoaderCocoa(void);
GLFWbool _glfwInitNSGL(void);
void _glfwTerminateNSGL(void);
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window);

View file

@ -32,12 +32,10 @@
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Initialise timer void _glfwPlatformInitTimer(void)
//
void _glfwInitTimerNS(void)
{ {
mach_timebase_info_data_t info; mach_timebase_info_data_t info;
mach_timebase_info(&info); mach_timebase_info(&info);
@ -45,11 +43,6 @@ void _glfwInitTimerNS(void)
_glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer; _glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer;
} }
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
uint64_t _glfwPlatformGetTimerValue(void) uint64_t _glfwPlatformGetTimerValue(void)
{ {
return mach_absolute_time(); return mach_absolute_time();

35
raylib/external/glfw/src/cocoa_time.h vendored Normal file
View file

@ -0,0 +1,35 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2021 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLFW_COCOA_LIBRARY_TIMER_STATE _GLFWtimerNS ns;
// Cocoa-specific global timer data
//
typedef struct _GLFWtimerNS
{
uint64_t frequency;
} _GLFWtimerNS;

View file

@ -31,25 +31,9 @@
#include <float.h> #include <float.h>
#include <string.h> #include <string.h>
// Returns the style mask corresponding to the window settings // HACK: This enum value is missing from framework headers on OS X 10.11 despite
// // having been (according to documentation) added in Mac OS X 10.7
static NSUInteger getStyleMask(_GLFWwindow* window) #define NSWindowCollectionBehaviorFullScreenNone (1 << 9)
{
NSUInteger styleMask = NSWindowStyleMaskMiniaturizable;
if (window->monitor || !window->decorated)
styleMask |= NSWindowStyleMaskBorderless;
else
{
styleMask |= NSWindowStyleMaskTitled |
NSWindowStyleMaskClosable;
if (window->resizable)
styleMask |= NSWindowStyleMaskResizable;
}
return styleMask;
}
// Returns whether the cursor is in the content area of the specified window // Returns whether the cursor is in the content area of the specified window
// //
@ -105,19 +89,20 @@ static void updateCursorMode(_GLFWwindow* window)
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
_glfw.ns.disabledCursorWindow = window; _glfw.ns.disabledCursorWindow = window;
_glfwPlatformGetCursorPos(window, _glfwGetCursorPosCocoa(window,
&_glfw.ns.restoreCursorPosX, &_glfw.ns.restoreCursorPosX,
&_glfw.ns.restoreCursorPosY); &_glfw.ns.restoreCursorPosY);
_glfwCenterCursorInContentArea(window); _glfwCenterCursorInContentArea(window);
CGAssociateMouseAndMouseCursorPosition(false); CGAssociateMouseAndMouseCursorPosition(false);
} }
else if (_glfw.ns.disabledCursorWindow == window) else if (_glfw.ns.disabledCursorWindow == window)
{ {
_glfw.ns.disabledCursorWindow = NULL; _glfw.ns.disabledCursorWindow = NULL;
CGAssociateMouseAndMouseCursorPosition(true); _glfwSetCursorPosCocoa(window,
_glfwPlatformSetCursorPos(window, _glfw.ns.restoreCursorPosX,
_glfw.ns.restoreCursorPosX, _glfw.ns.restoreCursorPosY);
_glfw.ns.restoreCursorPosY); // NOTE: The matching CGAssociateMouseAndMouseCursorPosition call is
// made in _glfwSetCursorPosCocoa as part of a workaround
} }
if (cursorInContentArea(window)) if (cursorInContentArea(window))
@ -128,10 +113,10 @@ static void updateCursorMode(_GLFWwindow* window)
// //
static void acquireMonitor(_GLFWwindow* window) static void acquireMonitor(_GLFWwindow* window)
{ {
_glfwSetVideoModeNS(window->monitor, &window->videoMode); _glfwSetVideoModeCocoa(window->monitor, &window->videoMode);
const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID); const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID);
const NSRect frame = NSMakeRect(bounds.origin.x, const NSRect frame = NSMakeRect(bounds.origin.x,
_glfwTransformYNS(bounds.origin.y + bounds.size.height - 1), _glfwTransformYCocoa(bounds.origin.y + bounds.size.height - 1),
bounds.size.width, bounds.size.width,
bounds.size.height); bounds.size.height);
@ -148,7 +133,7 @@ static void releaseMonitor(_GLFWwindow* window)
return; return;
_glfwInputMonitorWindow(window->monitor, NULL); _glfwInputMonitorWindow(window->monitor, NULL);
_glfwRestoreVideoModeNS(window->monitor); _glfwRestoreVideoModeCocoa(window->monitor);
} }
// Translates macOS key modifiers into GLFW ones // Translates macOS key modifiers into GLFW ones
@ -243,7 +228,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidResize:(NSNotification *)notification - (void)windowDidResize:(NSNotification *)notification
{ {
if (window->context.client != GLFW_NO_API) if (window->context.source == GLFW_NATIVE_CONTEXT_API)
[window->context.nsgl.object update]; [window->context.nsgl.object update];
if (_glfw.ns.disabledCursorWindow == window) if (_glfw.ns.disabledCursorWindow == window)
@ -278,14 +263,14 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidMove:(NSNotification *)notification - (void)windowDidMove:(NSNotification *)notification
{ {
if (window->context.client != GLFW_NO_API) if (window->context.source == GLFW_NATIVE_CONTEXT_API)
[window->context.nsgl.object update]; [window->context.nsgl.object update];
if (_glfw.ns.disabledCursorWindow == window) if (_glfw.ns.disabledCursorWindow == window)
_glfwCenterCursorInContentArea(window); _glfwCenterCursorInContentArea(window);
int x, y; int x, y;
_glfwPlatformGetWindowPos(window, &x, &y); _glfwGetWindowPosCocoa(window, &x, &y);
_glfwInputWindowPos(window, x, y); _glfwInputWindowPos(window, x, y);
} }
@ -317,7 +302,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidResignKey:(NSNotification *)notification - (void)windowDidResignKey:(NSNotification *)notification
{ {
if (window->monitor && window->autoIconify) if (window->monitor && window->autoIconify)
_glfwPlatformIconifyWindow(window); _glfwIconifyWindowCocoa(window);
_glfwInputWindowFocus(window, GLFW_FALSE); _glfwInputWindowFocus(window, GLFW_FALSE);
} }
@ -360,9 +345,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
markedText = [[NSMutableAttributedString alloc] init]; markedText = [[NSMutableAttributedString alloc] init];
[self updateTrackingAreas]; [self updateTrackingAreas];
// NOTE: kUTTypeURL corresponds to NSPasteboardTypeURL but is available [self registerForDraggedTypes:@[NSPasteboardTypeURL]];
// on 10.7 without having been deprecated yet
[self registerForDraggedTypes:@[(__bridge NSString*) kUTTypeURL]];
} }
return self; return self;
@ -397,7 +380,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)updateLayer - (void)updateLayer
{ {
if (window->context.client != GLFW_NO_API) if (window->context.source == GLFW_NATIVE_CONTEXT_API)
[window->context.nsgl.object update]; [window->context.nsgl.object update];
_glfwInputWindowDamage(window); _glfwInputWindowDamage(window);
@ -520,6 +503,18 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
{ {
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect]; const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
const float xscale = fbRect.size.width / contentRect.size.width;
const float yscale = fbRect.size.height / contentRect.size.height;
if (xscale != window->ns.xscale || yscale != window->ns.yscale)
{
if (window->ns.retina && window->ns.layer)
[window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]];
window->ns.xscale = xscale;
window->ns.yscale = yscale;
_glfwInputWindowContentScale(window, xscale, yscale);
}
if (fbRect.size.width != window->ns.fbWidth || if (fbRect.size.width != window->ns.fbWidth ||
fbRect.size.height != window->ns.fbHeight) fbRect.size.height != window->ns.fbHeight)
@ -528,19 +523,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
window->ns.fbHeight = fbRect.size.height; window->ns.fbHeight = fbRect.size.height;
_glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);
} }
const float xscale = fbRect.size.width / contentRect.size.width;
const float yscale = fbRect.size.height / contentRect.size.height;
if (xscale != window->ns.xscale || yscale != window->ns.yscale)
{
window->ns.xscale = xscale;
window->ns.yscale = yscale;
_glfwInputWindowContentScale(window, xscale, yscale);
if (window->ns.retina && window->ns.layer)
[window->ns.layer setContentsScale:[window->ns.object backingScaleFactor]];
}
} }
- (void)drawRect:(NSRect)rect - (void)drawRect:(NSRect)rect
@ -647,7 +629,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
const NSUInteger count = [urls count]; const NSUInteger count = [urls count];
if (count) if (count)
{ {
char** paths = calloc(count, sizeof(char*)); char** paths = _glfw_calloc(count, sizeof(char*));
for (NSUInteger i = 0; i < count; i++) for (NSUInteger i = 0; i < count; i++)
paths[i] = _glfw_strdup([urls[i] fileSystemRepresentation]); paths[i] = _glfw_strdup([urls[i] fileSystemRepresentation]);
@ -655,8 +637,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
_glfwInputDrop(window, (int) count, (const char**) paths); _glfwInputDrop(window, (int) count, (const char**) paths);
for (NSUInteger i = 0; i < count; i++) for (NSUInteger i = 0; i < count; i++)
free(paths[i]); _glfw_free(paths[i]);
free(paths); _glfw_free(paths);
} }
return YES; return YES;
@ -803,17 +785,41 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
GLFWvidmode mode; GLFWvidmode mode;
int xpos, ypos; int xpos, ypos;
_glfwPlatformGetVideoMode(window->monitor, &mode); _glfwGetVideoModeCocoa(window->monitor, &mode);
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); _glfwGetMonitorPosCocoa(window->monitor, &xpos, &ypos);
contentRect = NSMakeRect(xpos, ypos, mode.width, mode.height); contentRect = NSMakeRect(xpos, ypos, mode.width, mode.height);
} }
else else
contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height); {
if (wndconfig->xpos == GLFW_ANY_POSITION ||
wndconfig->ypos == GLFW_ANY_POSITION)
{
contentRect = NSMakeRect(0, 0, wndconfig->width, wndconfig->height);
}
else
{
const int xpos = wndconfig->xpos;
const int ypos = _glfwTransformYCocoa(wndconfig->ypos + wndconfig->height - 1);
contentRect = NSMakeRect(xpos, ypos, wndconfig->width, wndconfig->height);
}
}
NSUInteger styleMask = NSWindowStyleMaskMiniaturizable;
if (window->monitor || !window->decorated)
styleMask |= NSWindowStyleMaskBorderless;
else
{
styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
if (window->resizable)
styleMask |= NSWindowStyleMaskResizable;
}
window->ns.object = [[GLFWWindow alloc] window->ns.object = [[GLFWWindow alloc]
initWithContentRect:contentRect initWithContentRect:contentRect
styleMask:getStyleMask(window) styleMask:styleMask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:NO]; defer:NO];
@ -827,10 +833,14 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
[window->ns.object setLevel:NSMainMenuWindowLevel + 1]; [window->ns.object setLevel:NSMainMenuWindowLevel + 1];
else else
{ {
[(NSWindow*) window->ns.object center]; if (wndconfig->xpos == GLFW_ANY_POSITION ||
_glfw.ns.cascadePoint = wndconfig->ypos == GLFW_ANY_POSITION)
NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint: {
NSPointFromCGPoint(_glfw.ns.cascadePoint)]); [(NSWindow*) window->ns.object center];
_glfw.ns.cascadePoint =
NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint:
NSPointFromCGPoint(_glfw.ns.cascadePoint)]);
}
if (wndconfig->resizable) if (wndconfig->resizable)
{ {
@ -839,6 +849,12 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
NSWindowCollectionBehaviorManaged; NSWindowCollectionBehaviorManaged;
[window->ns.object setCollectionBehavior:behavior]; [window->ns.object setCollectionBehavior:behavior];
} }
else
{
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenNone;
[window->ns.object setCollectionBehavior:behavior];
}
if (wndconfig->floating) if (wndconfig->floating)
[window->ns.object setLevel:NSFloatingWindowLevel]; [window->ns.object setLevel:NSFloatingWindowLevel];
@ -872,8 +888,8 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
[window->ns.object setTabbingMode:NSWindowTabbingModeDisallowed]; [window->ns.object setTabbingMode:NSWindowTabbingModeDisallowed];
#endif #endif
_glfwPlatformGetWindowSize(window, &window->ns.width, &window->ns.height); _glfwGetWindowSizeCocoa(window, &window->ns.width, &window->ns.height);
_glfwPlatformGetFramebufferSize(window, &window->ns.fbWidth, &window->ns.fbHeight); _glfwGetFramebufferSizeCocoa(window, &window->ns.fbWidth, &window->ns.fbHeight);
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -885,7 +901,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
// Transforms a y-coordinate between the CG display and NS screen spaces // Transforms a y-coordinate between the CG display and NS screen spaces
// //
float _glfwTransformYNS(float y) float _glfwTransformYCocoa(float y)
{ {
return CGDisplayBounds(CGMainDisplayID()).size.height - y - 1; return CGDisplayBounds(CGMainDisplayID()).size.height - y - 1;
} }
@ -895,10 +911,10 @@ float _glfwTransformYNS(float y)
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformCreateWindow(_GLFWwindow* window, GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig, const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
@autoreleasepool { @autoreleasepool {
@ -933,13 +949,31 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE;
} }
if (wndconfig->mousePassthrough)
_glfwSetWindowMousePassthroughCocoa(window, GLFW_TRUE);
if (window->monitor) if (window->monitor)
{ {
_glfwPlatformShowWindow(window); _glfwShowWindowCocoa(window);
_glfwPlatformFocusWindow(window); _glfwFocusWindowCocoa(window);
acquireMonitor(window); acquireMonitor(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig->visible)
{
_glfwShowWindowCocoa(window);
if (wndconfig->focused)
_glfwFocusWindowCocoa(window);
}
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -947,7 +981,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformDestroyWindow(_GLFWwindow* window) void _glfwDestroyWindowCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
@ -973,12 +1007,12 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->ns.object = nil; window->ns.object = nil;
// HACK: Allow Cocoa to catch up before returning // HACK: Allow Cocoa to catch up before returning
_glfwPlatformPollEvents(); _glfwPollEventsCocoa();
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title)
{ {
@autoreleasepool { @autoreleasepool {
NSString* string = @(title); NSString* string = @(title);
@ -989,14 +1023,14 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, void _glfwSetWindowIconCocoa(_GLFWwindow* window,
int count, const GLFWimage* images) int count, const GLFWimage* images)
{ {
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
"Cocoa: Regular windows do not have icons on macOS"); "Cocoa: Regular windows do not have icons on macOS");
} }
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos)
{ {
@autoreleasepool { @autoreleasepool {
@ -1006,24 +1040,24 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
if (xpos) if (xpos)
*xpos = contentRect.origin.x; *xpos = contentRect.origin.x;
if (ypos) if (ypos)
*ypos = _glfwTransformYNS(contentRect.origin.y + contentRect.size.height - 1); *ypos = _glfwTransformYCocoa(contentRect.origin.y + contentRect.size.height - 1);
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) void _glfwSetWindowPosCocoa(_GLFWwindow* window, int x, int y)
{ {
@autoreleasepool { @autoreleasepool {
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSRect dummyRect = NSMakeRect(x, _glfwTransformYNS(y + contentRect.size.height - 1), 0, 0); const NSRect dummyRect = NSMakeRect(x, _glfwTransformYCocoa(y + contentRect.size.height - 1), 0, 0);
const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect]; const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect];
[window->ns.object setFrameOrigin:frameRect.origin]; [window->ns.object setFrameOrigin:frameRect.origin];
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height)
{ {
@autoreleasepool { @autoreleasepool {
@ -1037,7 +1071,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) void _glfwSetWindowSizeCocoa(_GLFWwindow* window, int width, int height)
{ {
@autoreleasepool { @autoreleasepool {
@ -1059,9 +1093,9 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, void _glfwSetWindowSizeLimitsCocoa(_GLFWwindow* window,
int minwidth, int minheight, int minwidth, int minheight,
int maxwidth, int maxheight) int maxwidth, int maxheight)
{ {
@autoreleasepool { @autoreleasepool {
@ -1078,7 +1112,7 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) void _glfwSetWindowAspectRatioCocoa(_GLFWwindow* window, int numer, int denom)
{ {
@autoreleasepool { @autoreleasepool {
if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE) if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE)
@ -1088,7 +1122,7 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) void _glfwGetFramebufferSizeCocoa(_GLFWwindow* window, int* width, int* height)
{ {
@autoreleasepool { @autoreleasepool {
@ -1103,9 +1137,9 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* heigh
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, void _glfwGetWindowFrameSizeCocoa(_GLFWwindow* window,
int* left, int* top, int* left, int* top,
int* right, int* bottom) int* right, int* bottom)
{ {
@autoreleasepool { @autoreleasepool {
@ -1126,8 +1160,8 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, void _glfwGetWindowContentScaleCocoa(_GLFWwindow* window,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
@autoreleasepool { @autoreleasepool {
@ -1142,14 +1176,14 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformIconifyWindow(_GLFWwindow* window) void _glfwIconifyWindowCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
[window->ns.object miniaturize:nil]; [window->ns.object miniaturize:nil];
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformRestoreWindow(_GLFWwindow* window) void _glfwRestoreWindowCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
if ([window->ns.object isMiniaturized]) if ([window->ns.object isMiniaturized])
@ -1159,7 +1193,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformMaximizeWindow(_GLFWwindow* window) void _glfwMaximizeWindowCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
if (![window->ns.object isZoomed]) if (![window->ns.object isZoomed])
@ -1167,28 +1201,28 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwShowWindowCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
[window->ns.object orderFront:nil]; [window->ns.object orderFront:nil];
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformHideWindow(_GLFWwindow* window) void _glfwHideWindowCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
[window->ns.object orderOut:nil]; [window->ns.object orderOut:nil];
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) void _glfwRequestWindowAttentionCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
[NSApp requestUserAttention:NSInformationalRequest]; [NSApp requestUserAttention:NSInformationalRequest];
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformFocusWindow(_GLFWwindow* window) void _glfwFocusWindowCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
// Make us the active application // Make us the active application
@ -1200,11 +1234,11 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
_GLFWmonitor* monitor, _GLFWmonitor* monitor,
int xpos, int ypos, int xpos, int ypos,
int width, int height, int width, int height,
int refreshRate) int refreshRate)
{ {
@autoreleasepool { @autoreleasepool {
@ -1218,10 +1252,11 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
else else
{ {
const NSRect contentRect = const NSRect contentRect =
NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1), width, height); NSMakeRect(xpos, _glfwTransformYCocoa(ypos + height - 1), width, height);
const NSUInteger styleMask = [window->ns.object styleMask];
const NSRect frameRect = const NSRect frameRect =
[window->ns.object frameRectForContentRect:contentRect [window->ns.object frameRectForContentRect:contentRect
styleMask:getStyleMask(window)]; styleMask:styleMask];
[window->ns.object setFrame:frameRect display:YES]; [window->ns.object setFrame:frameRect display:YES];
} }
@ -1236,9 +1271,29 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
// HACK: Allow the state cached in Cocoa to catch up to reality // HACK: Allow the state cached in Cocoa to catch up to reality
// TODO: Solve this in a less terrible way // TODO: Solve this in a less terrible way
_glfwPlatformPollEvents(); _glfwPollEventsCocoa();
NSUInteger styleMask = [window->ns.object styleMask];
if (window->monitor)
{
styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
styleMask |= NSWindowStyleMaskBorderless;
}
else
{
if (window->decorated)
{
styleMask &= ~NSWindowStyleMaskBorderless;
styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
}
if (window->resizable)
styleMask |= NSWindowStyleMaskResizable;
else
styleMask &= ~NSWindowStyleMaskResizable;
}
const NSUInteger styleMask = getStyleMask(window);
[window->ns.object setStyleMask:styleMask]; [window->ns.object setStyleMask:styleMask];
// HACK: Changing the style mask can cause the first responder to be cleared // HACK: Changing the style mask can cause the first responder to be cleared
[window->ns.object makeFirstResponder:window->ns.view]; [window->ns.object makeFirstResponder:window->ns.view];
@ -1252,7 +1307,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
} }
else else
{ {
NSRect contentRect = NSMakeRect(xpos, _glfwTransformYNS(ypos + height - 1), NSRect contentRect = NSMakeRect(xpos, _glfwTransformYCocoa(ypos + height - 1),
width, height); width, height);
NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect
styleMask:styleMask]; styleMask:styleMask];
@ -1284,6 +1339,20 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
else else
[window->ns.object setLevel:NSNormalWindowLevel]; [window->ns.object setLevel:NSNormalWindowLevel];
if (window->resizable)
{
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenPrimary |
NSWindowCollectionBehaviorManaged;
[window->ns.object setCollectionBehavior:behavior];
}
else
{
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenNone;
[window->ns.object setCollectionBehavior:behavior];
}
[window->ns.object setHasShadow:YES]; [window->ns.object setHasShadow:YES];
// HACK: Clearing NSWindowStyleMaskTitled resets and disables the window // HACK: Clearing NSWindowStyleMaskTitled resets and disables the window
// title property but the miniwindow title property is unaffected // title property but the miniwindow title property is unaffected
@ -1293,35 +1362,40 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
} // autoreleasepool } // autoreleasepool
} }
int _glfwPlatformWindowFocused(_GLFWwindow* window) GLFWbool _glfwWindowFocusedCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
return [window->ns.object isKeyWindow]; return [window->ns.object isKeyWindow];
} // autoreleasepool } // autoreleasepool
} }
int _glfwPlatformWindowIconified(_GLFWwindow* window) GLFWbool _glfwWindowIconifiedCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
return [window->ns.object isMiniaturized]; return [window->ns.object isMiniaturized];
} // autoreleasepool } // autoreleasepool
} }
int _glfwPlatformWindowVisible(_GLFWwindow* window) GLFWbool _glfwWindowVisibleCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
return [window->ns.object isVisible]; return [window->ns.object isVisible];
} // autoreleasepool } // autoreleasepool
} }
int _glfwPlatformWindowMaximized(_GLFWwindow* window) GLFWbool _glfwWindowMaximizedCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
return [window->ns.object isZoomed];
if (window->resizable)
return [window->ns.object isZoomed];
else
return GLFW_FALSE;
} // autoreleasepool } // autoreleasepool
} }
int _glfwPlatformWindowHovered(_GLFWwindow* window) GLFWbool _glfwWindowHoveredCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
@ -1339,29 +1413,60 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window)
} // autoreleasepool } // autoreleasepool
} }
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) GLFWbool _glfwFramebufferTransparentCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
return ![window->ns.object isOpaque] && ![window->ns.view isOpaque]; return ![window->ns.object isOpaque] && ![window->ns.view isOpaque];
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowResizableCocoa(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool { @autoreleasepool {
[window->ns.object setStyleMask:getStyleMask(window)];
const NSUInteger styleMask = [window->ns.object styleMask];
if (enabled)
{
[window->ns.object setStyleMask:(styleMask | NSWindowStyleMaskResizable)];
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenPrimary |
NSWindowCollectionBehaviorManaged;
[window->ns.object setCollectionBehavior:behavior];
}
else
{
[window->ns.object setStyleMask:(styleMask & ~NSWindowStyleMaskResizable)];
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenNone;
[window->ns.object setCollectionBehavior:behavior];
}
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool { @autoreleasepool {
[window->ns.object setStyleMask:getStyleMask(window)];
NSUInteger styleMask = [window->ns.object styleMask];
if (enabled)
{
styleMask |= (NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
styleMask &= ~NSWindowStyleMaskBorderless;
}
else
{
styleMask |= NSWindowStyleMaskBorderless;
styleMask &= ~(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable);
}
[window->ns.object setStyleMask:styleMask];
[window->ns.object makeFirstResponder:window->ns.view]; [window->ns.object makeFirstResponder:window->ns.view];
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowFloatingCocoa(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool { @autoreleasepool {
if (enabled) if (enabled)
@ -1371,39 +1476,39 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowMousePassthroughCocoa(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool { @autoreleasepool {
[window->ns.object setIgnoresMouseEvents:enabled]; [window->ns.object setIgnoresMouseEvents:enabled];
} }
} }
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) float _glfwGetWindowOpacityCocoa(_GLFWwindow* window)
{ {
@autoreleasepool { @autoreleasepool {
return (float) [window->ns.object alphaValue]; return (float) [window->ns.object alphaValue];
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) void _glfwSetWindowOpacityCocoa(_GLFWwindow* window, float opacity)
{ {
@autoreleasepool { @autoreleasepool {
[window->ns.object setAlphaValue:opacity]; [window->ns.object setAlphaValue:opacity];
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) void _glfwSetRawMouseMotionCocoa(_GLFWwindow *window, GLFWbool enabled)
{ {
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
"Cocoa: Raw mouse motion not yet implemented"); "Cocoa: Raw mouse motion not yet implemented");
} }
GLFWbool _glfwPlatformRawMouseMotionSupported(void) GLFWbool _glfwRawMouseMotionSupportedCocoa(void)
{ {
return GLFW_FALSE; return GLFW_FALSE;
} }
void _glfwPlatformPollEvents(void) void _glfwPollEventsCocoa(void)
{ {
@autoreleasepool { @autoreleasepool {
@ -1422,7 +1527,7 @@ void _glfwPlatformPollEvents(void)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformWaitEvents(void) void _glfwWaitEventsCocoa(void)
{ {
@autoreleasepool { @autoreleasepool {
@ -1435,12 +1540,12 @@ void _glfwPlatformWaitEvents(void)
dequeue:YES]; dequeue:YES];
[NSApp sendEvent:event]; [NSApp sendEvent:event];
_glfwPlatformPollEvents(); _glfwPollEventsCocoa();
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformWaitEventsTimeout(double timeout) void _glfwWaitEventsTimeoutCocoa(double timeout)
{ {
@autoreleasepool { @autoreleasepool {
@ -1452,12 +1557,12 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
if (event) if (event)
[NSApp sendEvent:event]; [NSApp sendEvent:event];
_glfwPlatformPollEvents(); _glfwPollEventsCocoa();
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformPostEmptyEvent(void) void _glfwPostEmptyEventCocoa(void)
{ {
@autoreleasepool { @autoreleasepool {
@ -1475,7 +1580,7 @@ void _glfwPlatformPostEmptyEvent(void)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) void _glfwGetCursorPosCocoa(_GLFWwindow* window, double* xpos, double* ypos)
{ {
@autoreleasepool { @autoreleasepool {
@ -1491,7 +1596,7 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwSetCursorPosCocoa(_GLFWwindow* window, double x, double y)
{ {
@autoreleasepool { @autoreleasepool {
@ -1516,28 +1621,41 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
const NSPoint globalPoint = globalRect.origin; const NSPoint globalPoint = globalRect.origin;
CGWarpMouseCursorPosition(CGPointMake(globalPoint.x, CGWarpMouseCursorPosition(CGPointMake(globalPoint.x,
_glfwTransformYNS(globalPoint.y))); _glfwTransformYCocoa(globalPoint.y)));
} }
// HACK: Calling this right after setting the cursor position prevents macOS
// from freezing the cursor for a fraction of a second afterwards
if (window->cursorMode != GLFW_CURSOR_DISABLED)
CGAssociateMouseAndMouseCursorPosition(true);
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode)
{ {
@autoreleasepool { @autoreleasepool {
if (_glfwPlatformWindowFocused(window))
if (mode == GLFW_CURSOR_CAPTURED)
{
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
"Cocoa: Captured cursor mode not yet implemented");
}
if (_glfwWindowFocusedCocoa(window))
updateCursorMode(window); updateCursorMode(window);
} // autoreleasepool } // autoreleasepool
} }
const char* _glfwPlatformGetScancodeName(int scancode) const char* _glfwGetScancodeNameCocoa(int scancode)
{ {
@autoreleasepool { @autoreleasepool {
if (scancode < 0 || scancode > 0xff || if (scancode < 0 || scancode > 0xff ||
_glfw.ns.keycodes[scancode] == GLFW_KEY_UNKNOWN) _glfw.ns.keycodes[scancode] == GLFW_KEY_UNKNOWN)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode"); _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
return NULL; return NULL;
} }
@ -1579,14 +1697,14 @@ const char* _glfwPlatformGetScancodeName(int scancode)
} // autoreleasepool } // autoreleasepool
} }
int _glfwPlatformGetKeyScancode(int key) int _glfwGetKeyScancodeCocoa(int key)
{ {
return _glfw.ns.scancodes[key]; return _glfw.ns.scancodes[key];
} }
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor,
const GLFWimage* image, const GLFWimage* image,
int xhot, int yhot) int xhot, int yhot)
{ {
@autoreleasepool { @autoreleasepool {
@ -1628,7 +1746,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
} // autoreleasepool } // autoreleasepool
} }
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) GLFWbool _glfwCreateStandardCursorCocoa(_GLFWcursor* cursor, int shape)
{ {
@autoreleasepool { @autoreleasepool {
@ -1702,7 +1820,7 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) void _glfwDestroyCursorCocoa(_GLFWcursor* cursor)
{ {
@autoreleasepool { @autoreleasepool {
if (cursor->ns.object) if (cursor->ns.object)
@ -1710,7 +1828,7 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwSetCursorCocoa(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
@autoreleasepool { @autoreleasepool {
if (cursorInContentArea(window)) if (cursorInContentArea(window))
@ -1718,7 +1836,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
} // autoreleasepool } // autoreleasepool
} }
void _glfwPlatformSetClipboardString(const char* string) void _glfwSetClipboardStringCocoa(const char* string)
{ {
@autoreleasepool { @autoreleasepool {
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
@ -1727,7 +1845,7 @@ void _glfwPlatformSetClipboardString(const char* string)
} // autoreleasepool } // autoreleasepool
} }
const char* _glfwPlatformGetClipboardString(void) const char* _glfwGetClipboardStringCocoa(void)
{ {
@autoreleasepool { @autoreleasepool {
@ -1748,7 +1866,7 @@ const char* _glfwPlatformGetClipboardString(void)
return NULL; return NULL;
} }
free(_glfw.ns.clipboardString); _glfw_free(_glfw.ns.clipboardString);
_glfw.ns.clipboardString = _glfw_strdup([object UTF8String]); _glfw.ns.clipboardString = _glfw_strdup([object UTF8String]);
return _glfw.ns.clipboardString; return _glfw.ns.clipboardString;
@ -1756,7 +1874,7 @@ const char* _glfwPlatformGetClipboardString(void)
} // autoreleasepool } // autoreleasepool
} }
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs) EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs)
{ {
if (_glfw.egl.ANGLE_platform_angle) if (_glfw.egl.ANGLE_platform_angle)
{ {
@ -1776,7 +1894,7 @@ EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
if (type) if (type)
{ {
*attribs = calloc(3, sizeof(EGLint)); *attribs = _glfw_calloc(3, sizeof(EGLint));
(*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE; (*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE;
(*attribs)[1] = type; (*attribs)[1] = type;
(*attribs)[2] = EGL_NONE; (*attribs)[2] = EGL_NONE;
@ -1787,17 +1905,17 @@ EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs)
return 0; return 0;
} }
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void) EGLNativeDisplayType _glfwGetEGLNativeDisplayCocoa(void)
{ {
return EGL_DEFAULT_DISPLAY; return EGL_DEFAULT_DISPLAY;
} }
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window) EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window)
{ {
return window->ns.layer; return window->ns.layer;
} }
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions)
{ {
if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface) if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface)
{ {
@ -1811,17 +1929,17 @@ void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
} }
} }
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, GLFWbool _glfwGetPhysicalDevicePresentationSupportCocoa(VkInstance instance,
VkPhysicalDevice device, VkPhysicalDevice device,
uint32_t queuefamily) uint32_t queuefamily)
{ {
return GLFW_TRUE; return GLFW_TRUE;
} }
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
_GLFWwindow* window, _GLFWwindow* window,
const VkAllocationCallbacks* allocator, const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface) VkSurfaceKHR* surface)
{ {
@autoreleasepool { @autoreleasepool {
@ -1918,6 +2036,14 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil); _GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
"Cocoa: Platform not initialized");
return NULL;
}
return window->ns.object; return window->ns.object;
} }

View file

@ -48,16 +48,6 @@
// //
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig) GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
{ {
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
}
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API && if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
ctxconfig->source != GLFW_EGL_CONTEXT_API && ctxconfig->source != GLFW_EGL_CONTEXT_API &&
ctxconfig->source != GLFW_OSMESA_CONTEXT_API) ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
@ -78,6 +68,23 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
return GLFW_FALSE; return GLFW_FALSE;
} }
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (ctxconfig->source != ctxconfig->share->context.source)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Context creation APIs do not match between contexts");
return GLFW_FALSE;
}
}
if (ctxconfig->client == GLFW_OPENGL_API) if (ctxconfig->client == GLFW_OPENGL_API)
{ {
if ((ctxconfig->major < 1 || ctxconfig->minor < 0) || if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
@ -609,10 +616,12 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot); _GLFWwindow* previous;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
if (window && window->context.client == GLFW_NO_API) if (window && window->context.client == GLFW_NO_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, _glfwInputError(GLFW_NO_WINDOW_CONTEXT,

View file

@ -103,10 +103,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
return GLFW_FALSE; return GLFW_FALSE;
} }
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig)); nativeConfigs = _glfw_calloc(nativeCount, sizeof(EGLConfig));
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount); eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0; usableCount = 0;
for (i = 0; i < nativeCount; i++) for (i = 0; i < nativeCount; i++)
@ -123,6 +123,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
continue; continue;
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
if (_glfw.platform.platformID == GLFW_PLATFORM_X11)
{ {
XVisualInfo vi = {0}; XVisualInfo vi = {0};
@ -172,6 +173,21 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE); u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE); u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
#if defined(_GLFW_WAYLAND)
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
{
// NOTE: The wl_surface opaque region is no guarantee that its buffer
// is presented as opaque, if it also has an alpha channel
// HACK: If EGL_EXT_present_opaque is unavailable, ignore any config
// with an alpha channel to ensure the buffer is opaque
if (!_glfw.egl.EXT_present_opaque)
{
if (!desired->transparent && u->alphaBits > 0)
continue;
}
}
#endif // _GLFW_WAYLAND
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES); u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
u->doublebuffer = desired->doublebuffer; u->doublebuffer = desired->doublebuffer;
@ -183,8 +199,8 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
if (closest) if (closest)
*result = (EGLConfig) closest->handle; *result = (EGLConfig) closest->handle;
free(nativeConfigs); _glfw_free(nativeConfigs);
free(usableConfigs); _glfw_free(usableConfigs);
return closest != NULL; return closest != NULL;
} }
@ -230,6 +246,15 @@ static void swapBuffersEGL(_GLFWwindow* window)
return; return;
} }
#if defined(_GLFW_WAYLAND)
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
{
// NOTE: Swapping buffers on a hidden window on Wayland makes it visible
if (!window->wl.visible)
return;
}
#endif
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface); eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
} }
@ -256,8 +281,8 @@ static GLFWglproc getProcAddressEGL(const char* procname)
if (window->context.egl.client) if (window->context.egl.client)
{ {
GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client, GLFWglproc proc = (GLFWglproc)
procname); _glfwPlatformGetModuleSymbol(window->context.egl.client, procname);
if (proc) if (proc)
return proc; return proc;
} }
@ -267,15 +292,14 @@ static GLFWglproc getProcAddressEGL(const char* procname)
static void destroyContextEGL(_GLFWwindow* window) static void destroyContextEGL(_GLFWwindow* window)
{ {
#if defined(_GLFW_X11)
// NOTE: Do not unload libGL.so.1 while the X11 display is still open, // NOTE: Do not unload libGL.so.1 while the X11 display is still open,
// as it will make XCloseDisplay segfault // as it will make XCloseDisplay segfault
if (window->context.client != GLFW_OPENGL_API) if (_glfw.platform.platformID != GLFW_PLATFORM_X11 ||
#endif // _GLFW_X11 window->context.client != GLFW_OPENGL_API)
{ {
if (window->context.egl.client) if (window->context.egl.client)
{ {
_glfw_dlclose(window->context.egl.client); _glfwPlatformFreeModule(window->context.egl.client);
window->context.egl.client = NULL; window->context.egl.client = NULL;
} }
} }
@ -316,6 +340,8 @@ GLFWbool _glfwInitEGL(void)
"libEGL.dylib", "libEGL.dylib",
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
"libEGL-1.so", "libEGL-1.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libEGL.so",
#else #else
"libEGL.so.1", "libEGL.so.1",
#endif #endif
@ -327,7 +353,7 @@ GLFWbool _glfwInitEGL(void)
for (i = 0; sonames[i]; i++) for (i = 0; sonames[i]; i++)
{ {
_glfw.egl.handle = _glfw_dlopen(sonames[i]); _glfw.egl.handle = _glfwPlatformLoadModule(sonames[i]);
if (_glfw.egl.handle) if (_glfw.egl.handle)
break; break;
} }
@ -341,37 +367,37 @@ GLFWbool _glfwInitEGL(void)
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0); _glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
_glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib) _glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigAttrib");
_glfw.egl.GetConfigs = (PFN_eglGetConfigs) _glfw.egl.GetConfigs = (PFN_eglGetConfigs)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigs");
_glfw.egl.GetDisplay = (PFN_eglGetDisplay) _glfw.egl.GetDisplay = (PFN_eglGetDisplay)
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetDisplay");
_glfw.egl.GetError = (PFN_eglGetError) _glfw.egl.GetError = (PFN_eglGetError)
_glfw_dlsym(_glfw.egl.handle, "eglGetError"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetError");
_glfw.egl.Initialize = (PFN_eglInitialize) _glfw.egl.Initialize = (PFN_eglInitialize)
_glfw_dlsym(_glfw.egl.handle, "eglInitialize"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglInitialize");
_glfw.egl.Terminate = (PFN_eglTerminate) _glfw.egl.Terminate = (PFN_eglTerminate)
_glfw_dlsym(_glfw.egl.handle, "eglTerminate"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglTerminate");
_glfw.egl.BindAPI = (PFN_eglBindAPI) _glfw.egl.BindAPI = (PFN_eglBindAPI)
_glfw_dlsym(_glfw.egl.handle, "eglBindAPI"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglBindAPI");
_glfw.egl.CreateContext = (PFN_eglCreateContext) _glfw.egl.CreateContext = (PFN_eglCreateContext)
_glfw_dlsym(_glfw.egl.handle, "eglCreateContext"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateContext");
_glfw.egl.DestroySurface = (PFN_eglDestroySurface) _glfw.egl.DestroySurface = (PFN_eglDestroySurface)
_glfw_dlsym(_glfw.egl.handle, "eglDestroySurface"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroySurface");
_glfw.egl.DestroyContext = (PFN_eglDestroyContext) _glfw.egl.DestroyContext = (PFN_eglDestroyContext)
_glfw_dlsym(_glfw.egl.handle, "eglDestroyContext"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext");
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface) _glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
_glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface");
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent) _glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
_glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent");
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers) _glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
_glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapBuffers");
_glfw.egl.SwapInterval = (PFN_eglSwapInterval) _glfw.egl.SwapInterval = (PFN_eglSwapInterval)
_glfw_dlsym(_glfw.egl.handle, "eglSwapInterval"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapInterval");
_glfw.egl.QueryString = (PFN_eglQueryString) _glfw.egl.QueryString = (PFN_eglQueryString)
_glfw_dlsym(_glfw.egl.handle, "eglQueryString"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglQueryString");
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress) _glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress"); _glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetProcAddress");
if (!_glfw.egl.GetConfigAttrib || if (!_glfw.egl.GetConfigAttrib ||
!_glfw.egl.GetConfigs || !_glfw.egl.GetConfigs ||
@ -429,18 +455,18 @@ GLFWbool _glfwInitEGL(void)
eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
} }
_glfw.egl.platform = _glfwPlatformGetEGLPlatform(&attribs); _glfw.egl.platform = _glfw.platform.getEGLPlatform(&attribs);
if (_glfw.egl.platform) if (_glfw.egl.platform)
{ {
_glfw.egl.display = _glfw.egl.display =
eglGetPlatformDisplayEXT(_glfw.egl.platform, eglGetPlatformDisplayEXT(_glfw.egl.platform,
_glfwPlatformGetEGLNativeDisplay(), _glfw.platform.getEGLNativeDisplay(),
attribs); attribs);
} }
else else
_glfw.egl.display = eglGetDisplay(_glfwPlatformGetEGLNativeDisplay()); _glfw.egl.display = eglGetDisplay(_glfw.platform.getEGLNativeDisplay());
free(attribs); _glfw_free(attribs);
if (_glfw.egl.display == EGL_NO_DISPLAY) if (_glfw.egl.display == EGL_NO_DISPLAY)
{ {
@ -472,6 +498,8 @@ GLFWbool _glfwInitEGL(void)
extensionSupportedEGL("EGL_KHR_get_all_proc_addresses"); extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
_glfw.egl.KHR_context_flush_control = _glfw.egl.KHR_context_flush_control =
extensionSupportedEGL("EGL_KHR_context_flush_control"); extensionSupportedEGL("EGL_KHR_context_flush_control");
_glfw.egl.EXT_present_opaque =
extensionSupportedEGL("EGL_EXT_present_opaque");
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -488,12 +516,12 @@ void _glfwTerminateEGL(void)
if (_glfw.egl.handle) if (_glfw.egl.handle)
{ {
_glfw_dlclose(_glfw.egl.handle); _glfwPlatformFreeModule(_glfw.egl.handle);
_glfw.egl.handle = NULL; _glfw.egl.handle = NULL;
} }
} }
#define setAttrib(a, v) \ #define SET_ATTRIB(a, v) \
{ \ { \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \ attribs[index++] = a; \
@ -571,13 +599,13 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{ {
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{ {
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_NO_RESET_NOTIFICATION_KHR); EGL_NO_RESET_NOTIFICATION_KHR);
} }
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{ {
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_LOSE_CONTEXT_ON_RESET_KHR); EGL_LOSE_CONTEXT_ON_RESET_KHR);
} }
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
@ -586,42 +614,42 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (ctxconfig->noerror) if (ctxconfig->noerror)
{ {
if (_glfw.egl.KHR_create_context_no_error) if (_glfw.egl.KHR_create_context_no_error)
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE); SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
} }
if (ctxconfig->major != 1 || ctxconfig->minor != 0) if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{ {
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major); SET_ATTRIB(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor); SET_ATTRIB(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
} }
if (mask) if (mask)
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask); SET_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
if (flags) if (flags)
setAttrib(EGL_CONTEXT_FLAGS_KHR, flags); SET_ATTRIB(EGL_CONTEXT_FLAGS_KHR, flags);
} }
else else
{ {
if (ctxconfig->client == GLFW_OPENGL_ES_API) if (ctxconfig->client == GLFW_OPENGL_ES_API)
setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major); SET_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
} }
if (_glfw.egl.KHR_context_flush_control) if (_glfw.egl.KHR_context_flush_control)
{ {
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{ {
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR); EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
} }
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{ {
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR, SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR); EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
} }
} }
setAttrib(EGL_NONE, EGL_NONE); SET_ATTRIB(EGL_NONE, EGL_NONE);
window->context.egl.handle = eglCreateContext(_glfw.egl.display, window->context.egl.handle = eglCreateContext(_glfw.egl.display,
config, share, attribs); config, share, attribs);
@ -640,15 +668,18 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (fbconfig->sRGB) if (fbconfig->sRGB)
{ {
if (_glfw.egl.KHR_gl_colorspace) if (_glfw.egl.KHR_gl_colorspace)
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR); SET_ATTRIB(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
} }
if (!fbconfig->doublebuffer) if (!fbconfig->doublebuffer)
setAttrib(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER); SET_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
setAttrib(EGL_NONE, EGL_NONE); if (_glfw.egl.EXT_present_opaque)
SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
native = _glfwPlatformGetEGLNativeWindow(window); SET_ATTRIB(EGL_NONE, EGL_NONE);
native = _glfw.platform.getEGLNativeWindow(window);
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT // HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
// despite reporting EGL_EXT_platform_base // despite reporting EGL_EXT_platform_base
if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE) if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
@ -686,6 +717,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
"libGLES_CM.dll", "libGLES_CM.dll",
#elif defined(_GLFW_COCOA) #elif defined(_GLFW_COCOA)
"libGLESv1_CM.dylib", "libGLESv1_CM.dylib",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGLESv1_CM.so",
#else #else
"libGLESv1_CM.so.1", "libGLESv1_CM.so.1",
"libGLES_CM.so.1", "libGLES_CM.so.1",
@ -703,6 +736,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
"libGLESv2.dylib", "libGLESv2.dylib",
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
"libGLESv2-2.so", "libGLESv2-2.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGLESv2.so",
#else #else
"libGLESv2.so.2", "libGLESv2.so.2",
#endif #endif
@ -714,7 +749,10 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
_GLFW_OPENGL_LIBRARY, _GLFW_OPENGL_LIBRARY,
#elif defined(_GLFW_WIN32) #elif defined(_GLFW_WIN32)
#elif defined(_GLFW_COCOA) #elif defined(_GLFW_COCOA)
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so",
#else #else
"libOpenGL.so.0",
"libGL.so.1", "libGL.so.1",
#endif #endif
NULL NULL
@ -737,7 +775,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0)) if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))
continue; continue;
window->context.egl.client = _glfw_dlopen(sonames[i]); window->context.egl.client = _glfwPlatformLoadModule(sonames[i]);
if (window->context.egl.client) if (window->context.egl.client)
break; break;
} }
@ -760,7 +798,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
return GLFW_TRUE; return GLFW_TRUE;
} }
#undef setAttrib #undef SET_ATTRIB
// Returns the Visual and depth of the chosen EGLConfig // Returns the Visual and depth of the chosen EGLConfig
// //
@ -821,7 +859,7 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT); _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
if (window->context.client == GLFW_NO_API) if (window->context.source != GLFW_EGL_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_CONTEXT; return EGL_NO_CONTEXT;
@ -835,7 +873,7 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE); _GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
if (window->context.client == GLFW_NO_API) if (window->context.source != GLFW_EGL_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_SURFACE; return EGL_NO_SURFACE;

View file

@ -1,229 +0,0 @@
//========================================================================
// GLFW 3.4 EGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#if defined(_GLFW_WIN32)
#define EGLAPIENTRY __stdcall
#else
#define EGLAPIENTRY
#endif
#define EGL_SUCCESS 0x3000
#define EGL_NOT_INITIALIZED 0x3001
#define EGL_BAD_ACCESS 0x3002
#define EGL_BAD_ALLOC 0x3003
#define EGL_BAD_ATTRIBUTE 0x3004
#define EGL_BAD_CONFIG 0x3005
#define EGL_BAD_CONTEXT 0x3006
#define EGL_BAD_CURRENT_SURFACE 0x3007
#define EGL_BAD_DISPLAY 0x3008
#define EGL_BAD_MATCH 0x3009
#define EGL_BAD_NATIVE_PIXMAP 0x300a
#define EGL_BAD_NATIVE_WINDOW 0x300b
#define EGL_BAD_PARAMETER 0x300c
#define EGL_BAD_SURFACE 0x300d
#define EGL_CONTEXT_LOST 0x300e
#define EGL_COLOR_BUFFER_TYPE 0x303f
#define EGL_RGB_BUFFER 0x308e
#define EGL_SURFACE_TYPE 0x3033
#define EGL_WINDOW_BIT 0x0004
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_OPENGL_ES_BIT 0x0001
#define EGL_OPENGL_ES2_BIT 0x0004
#define EGL_OPENGL_BIT 0x0008
#define EGL_ALPHA_SIZE 0x3021
#define EGL_BLUE_SIZE 0x3022
#define EGL_GREEN_SIZE 0x3023
#define EGL_RED_SIZE 0x3024
#define EGL_DEPTH_SIZE 0x3025
#define EGL_STENCIL_SIZE 0x3026
#define EGL_SAMPLES 0x3031
#define EGL_OPENGL_ES_API 0x30a0
#define EGL_OPENGL_API 0x30a2
#define EGL_NONE 0x3038
#define EGL_RENDER_BUFFER 0x3086
#define EGL_SINGLE_BUFFER 0x3085
#define EGL_EXTENSIONS 0x3055
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_NATIVE_VISUAL_ID 0x302e
#define EGL_NO_SURFACE ((EGLSurface) 0)
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
#define EGL_NO_CONTEXT ((EGLContext) 0)
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31bd
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31be
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31bf
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd
#define EGL_CONTEXT_FLAGS_KHR 0x30fc
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
#define EGL_GL_COLORSPACE_KHR 0x309d
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
#define EGL_PLATFORM_X11_EXT 0x31d5
#define EGL_PLATFORM_WAYLAND_EXT 0x31d8
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320d
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320e
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f
typedef int EGLint;
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void* EGLConfig;
typedef void* EGLContext;
typedef void* EGLDisplay;
typedef void* EGLSurface;
typedef void* EGLNativeDisplayType;
typedef void* EGLNativeWindowType;
// EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);
typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglTerminate)(EGLDisplay);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglBindAPI)(EGLenum);
typedef EGLContext (EGLAPIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
typedef EGLSurface (EGLAPIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define eglGetConfigs _glfw.egl.GetConfigs
#define eglGetDisplay _glfw.egl.GetDisplay
#define eglGetError _glfw.egl.GetError
#define eglInitialize _glfw.egl.Initialize
#define eglTerminate _glfw.egl.Terminate
#define eglBindAPI _glfw.egl.BindAPI
#define eglCreateContext _glfw.egl.CreateContext
#define eglDestroySurface _glfw.egl.DestroySurface
#define eglDestroyContext _glfw.egl.DestroyContext
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
#define eglMakeCurrent _glfw.egl.MakeCurrent
#define eglSwapBuffers _glfw.egl.SwapBuffers
#define eglSwapInterval _glfw.egl.SwapInterval
#define eglQueryString _glfw.egl.QueryString
#define eglGetProcAddress _glfw.egl.GetProcAddress
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*);
#define eglGetPlatformDisplayEXT _glfw.egl.GetPlatformDisplayEXT
#define eglCreatePlatformWindowSurfaceEXT _glfw.egl.CreatePlatformWindowSurfaceEXT
// EGL-specific per-context data
//
typedef struct _GLFWcontextEGL
{
EGLConfig config;
EGLContext handle;
EGLSurface surface;
void* client;
} _GLFWcontextEGL;
// EGL-specific global data
//
typedef struct _GLFWlibraryEGL
{
EGLenum platform;
EGLDisplay display;
EGLint major, minor;
GLFWbool prefix;
GLFWbool KHR_create_context;
GLFWbool KHR_create_context_no_error;
GLFWbool KHR_gl_colorspace;
GLFWbool KHR_get_all_proc_addresses;
GLFWbool KHR_context_flush_control;
GLFWbool EXT_client_extensions;
GLFWbool EXT_platform_base;
GLFWbool EXT_platform_x11;
GLFWbool EXT_platform_wayland;
GLFWbool ANGLE_platform_angle;
GLFWbool ANGLE_platform_angle_opengl;
GLFWbool ANGLE_platform_angle_d3d;
GLFWbool ANGLE_platform_angle_vulkan;
GLFWbool ANGLE_platform_angle_metal;
void* handle;
PFN_eglGetConfigAttrib GetConfigAttrib;
PFN_eglGetConfigs GetConfigs;
PFN_eglGetDisplay GetDisplay;
PFN_eglGetError GetError;
PFN_eglInitialize Initialize;
PFN_eglTerminate Terminate;
PFN_eglBindAPI BindAPI;
PFN_eglCreateContext CreateContext;
PFN_eglDestroySurface DestroySurface;
PFN_eglDestroyContext DestroyContext;
PFN_eglCreateWindowSurface CreateWindowSurface;
PFN_eglMakeCurrent MakeCurrent;
PFN_eglSwapBuffers SwapBuffers;
PFN_eglSwapInterval SwapInterval;
PFN_eglQueryString QueryString;
PFN_eglGetProcAddress GetProcAddress;
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC CreatePlatformWindowSurfaceEXT;
} _GLFWlibraryEGL;
GLFWbool _glfwInitEGL(void);
void _glfwTerminateEGL(void);
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);
#endif /*_GLFW_X11*/

View file

@ -55,7 +55,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
GLXFBConfig* nativeConfigs; GLXFBConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
int i, nativeCount, usableCount; int nativeCount, usableCount;
const char* vendor; const char* vendor;
GLFWbool trustWindowBit = GLFW_TRUE; GLFWbool trustWindowBit = GLFW_TRUE;
@ -73,10 +73,10 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
return GLFW_FALSE; return GLFW_FALSE;
} }
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0; usableCount = 0;
for (i = 0; i < nativeCount; i++) for (int i = 0; i < nativeCount; i++)
{ {
const GLXFBConfig n = nativeConfigs[i]; const GLXFBConfig n = nativeConfigs[i];
_GLFWfbconfig* u = usableConfigs + usableCount; _GLFWfbconfig* u = usableConfigs + usableCount;
@ -138,7 +138,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
*result = (GLXFBConfig) closest->handle; *result = (GLXFBConfig) closest->handle;
XFree(nativeConfigs); XFree(nativeConfigs);
free(usableConfigs); _glfw_free(usableConfigs);
return closest != NULL; return closest != NULL;
} }
@ -226,7 +226,10 @@ static GLFWglproc getProcAddressGLX(const char* procname)
else if (_glfw.glx.GetProcAddressARB) else if (_glfw.glx.GetProcAddressARB)
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname); return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
else else
return _glfw_dlsym(_glfw.glx.handle, procname); {
// NOTE: glvnd provides GLX 1.4, so this can only happen with libGL
return _glfwPlatformGetModuleSymbol(_glfw.glx.handle, procname);
}
} }
static void destroyContextGLX(_GLFWwindow* window) static void destroyContextGLX(_GLFWwindow* window)
@ -253,14 +256,16 @@ static void destroyContextGLX(_GLFWwindow* window)
// //
GLFWbool _glfwInitGLX(void) GLFWbool _glfwInitGLX(void)
{ {
int i;
const char* sonames[] = const char* sonames[] =
{ {
#if defined(_GLFW_GLX_LIBRARY) #if defined(_GLFW_GLX_LIBRARY)
_GLFW_GLX_LIBRARY, _GLFW_GLX_LIBRARY,
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
"libGL-1.so", "libGL-1.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so",
#else #else
"libGLX.so.0",
"libGL.so.1", "libGL.so.1",
"libGL.so", "libGL.so",
#endif #endif
@ -270,9 +275,9 @@ GLFWbool _glfwInitGLX(void)
if (_glfw.glx.handle) if (_glfw.glx.handle)
return GLFW_TRUE; return GLFW_TRUE;
for (i = 0; sonames[i]; i++) for (int i = 0; sonames[i]; i++)
{ {
_glfw.glx.handle = _glfw_dlopen(sonames[i]); _glfw.glx.handle = _glfwPlatformLoadModule(sonames[i]);
if (_glfw.glx.handle) if (_glfw.glx.handle)
break; break;
} }
@ -283,36 +288,32 @@ GLFWbool _glfwInitGLX(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfw.glx.GetFBConfigs = _glfw.glx.GetFBConfigs = (PFNGLXGETFBCONFIGSPROC)
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigs");
_glfw.glx.GetFBConfigAttrib = _glfw.glx.GetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigAttrib");
_glfw.glx.GetClientString = _glfw.glx.GetClientString = (PFNGLXGETCLIENTSTRINGPROC)
_glfw_dlsym(_glfw.glx.handle, "glXGetClientString"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetClientString");
_glfw.glx.QueryExtension = _glfw.glx.QueryExtension = (PFNGLXQUERYEXTENSIONPROC)
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtension"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtension");
_glfw.glx.QueryVersion = _glfw.glx.QueryVersion = (PFNGLXQUERYVERSIONPROC)
_glfw_dlsym(_glfw.glx.handle, "glXQueryVersion"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryVersion");
_glfw.glx.DestroyContext = _glfw.glx.DestroyContext = (PFNGLXDESTROYCONTEXTPROC)
_glfw_dlsym(_glfw.glx.handle, "glXDestroyContext"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyContext");
_glfw.glx.MakeCurrent = _glfw.glx.MakeCurrent = (PFNGLXMAKECURRENTPROC)
_glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXMakeCurrent");
_glfw.glx.SwapBuffers = _glfw.glx.SwapBuffers = (PFNGLXSWAPBUFFERSPROC)
_glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXSwapBuffers");
_glfw.glx.QueryExtensionsString = _glfw.glx.QueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC)
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtensionsString");
_glfw.glx.CreateNewContext = _glfw.glx.CreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)
_glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateNewContext");
_glfw.glx.CreateWindow = _glfw.glx.CreateWindow = (PFNGLXCREATEWINDOWPROC)
_glfw_dlsym(_glfw.glx.handle, "glXCreateWindow"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateWindow");
_glfw.glx.DestroyWindow = _glfw.glx.DestroyWindow = (PFNGLXDESTROYWINDOWPROC)
_glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyWindow");
_glfw.glx.GetProcAddress = _glfw.glx.GetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress"); _glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetVisualFromFBConfig");
_glfw.glx.GetProcAddressARB =
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
_glfw.glx.GetVisualFromFBConfig =
_glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
if (!_glfw.glx.GetFBConfigs || if (!_glfw.glx.GetFBConfigs ||
!_glfw.glx.GetFBConfigAttrib || !_glfw.glx.GetFBConfigAttrib ||
@ -326,8 +327,6 @@ GLFWbool _glfwInitGLX(void)
!_glfw.glx.CreateNewContext || !_glfw.glx.CreateNewContext ||
!_glfw.glx.CreateWindow || !_glfw.glx.CreateWindow ||
!_glfw.glx.DestroyWindow || !_glfw.glx.DestroyWindow ||
!_glfw.glx.GetProcAddress ||
!_glfw.glx.GetProcAddressARB ||
!_glfw.glx.GetVisualFromFBConfig) !_glfw.glx.GetVisualFromFBConfig)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -335,6 +334,12 @@ GLFWbool _glfwInitGLX(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
// NOTE: Unlike GLX 1.3 entry points these are not required to be present
_glfw.glx.GetProcAddress = (PFNGLXGETPROCADDRESSPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddress");
_glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddressARB");
if (!glXQueryExtension(_glfw.x11.display, if (!glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase, &_glfw.glx.errorBase,
&_glfw.glx.eventBase)) &_glfw.glx.eventBase))
@ -425,16 +430,16 @@ GLFWbool _glfwInitGLX(void)
void _glfwTerminateGLX(void) void _glfwTerminateGLX(void)
{ {
// NOTE: This function must not call any X11 functions, as it is called // NOTE: This function must not call any X11 functions, as it is called
// after XCloseDisplay (see _glfwPlatformTerminate for details) // after XCloseDisplay (see _glfwTerminateX11 for details)
if (_glfw.glx.handle) if (_glfw.glx.handle)
{ {
_glfw_dlclose(_glfw.glx.handle); _glfwPlatformFreeModule(_glfw.glx.handle);
_glfw.glx.handle = NULL; _glfw.glx.handle = NULL;
} }
} }
#define setAttrib(a, v) \ #define SET_ATTRIB(a, v) \
{ \ { \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \ attribs[index++] = a; \
@ -522,13 +527,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{ {
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{ {
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_NO_RESET_NOTIFICATION_ARB); GLX_NO_RESET_NOTIFICATION_ARB);
} }
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{ {
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_LOSE_CONTEXT_ON_RESET_ARB); GLX_LOSE_CONTEXT_ON_RESET_ARB);
} }
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
@ -541,13 +546,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{ {
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{ {
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
} }
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{ {
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
} }
} }
} }
@ -555,7 +560,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
if (ctxconfig->noerror) if (ctxconfig->noerror)
{ {
if (_glfw.glx.ARB_create_context_no_error) if (_glfw.glx.ARB_create_context_no_error)
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); SET_ATTRIB(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
} }
// NOTE: Only request an explicitly versioned context when necessary, as // NOTE: Only request an explicitly versioned context when necessary, as
@ -563,17 +568,17 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
// highest version supported by the driver // highest version supported by the driver
if (ctxconfig->major != 1 || ctxconfig->minor != 0) if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{ {
setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); SET_ATTRIB(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); SET_ATTRIB(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
} }
if (mask) if (mask)
setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); SET_ATTRIB(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
if (flags) if (flags)
setAttrib(GLX_CONTEXT_FLAGS_ARB, flags); SET_ATTRIB(GLX_CONTEXT_FLAGS_ARB, flags);
setAttrib(None, None); SET_ATTRIB(None, None);
window->context.glx.handle = window->context.glx.handle =
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display, _glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
@ -630,7 +635,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
return GLFW_TRUE; return GLFW_TRUE;
} }
#undef setAttrib #undef SET_ATTRIB
// Returns the Visual and depth of the chosen GLXFBConfig // Returns the Visual and depth of the chosen GLXFBConfig
// //
@ -674,7 +679,13 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (window->context.client == GLFW_NO_API) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
return NULL;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL; return NULL;
@ -688,7 +699,13 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None); _GLFW_REQUIRE_INIT_OR_RETURN(None);
if (window->context.client == GLFW_NO_API) if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
return None;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return None; return None;

View file

@ -1,181 +0,0 @@
//========================================================================
// GLFW 3.4 GLX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLX_VENDOR 1
#define GLX_RGBA_BIT 0x00000001
#define GLX_WINDOW_BIT 0x00000001
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_RGBA_TYPE 0x8014
#define GLX_DOUBLEBUFFER 5
#define GLX_STEREO 6
#define GLX_AUX_BUFFERS 7
#define GLX_RED_SIZE 8
#define GLX_GREEN_SIZE 9
#define GLX_BLUE_SIZE 10
#define GLX_ALPHA_SIZE 11
#define GLX_DEPTH_SIZE 12
#define GLX_STENCIL_SIZE 13
#define GLX_ACCUM_RED_SIZE 14
#define GLX_ACCUM_GREEN_SIZE 15
#define GLX_ACCUM_BLUE_SIZE 16
#define GLX_ACCUM_ALPHA_SIZE 17
#define GLX_SAMPLES 0x186a1
#define GLX_VISUAL_ID 0x800b
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GLX_CONTEXT_FLAGS_ARB 0x2094
#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
typedef XID GLXWindow;
typedef XID GLXDrawable;
typedef struct __GLXFBConfig* GLXFBConfig;
typedef struct __GLXcontext* GLXContext;
typedef void (*__GLXextproc)(void);
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);
typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext);
typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext);
typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);
typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool);
typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName);
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig);
typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*);
typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow);
typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);
// libGL.so function pointer typedefs
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
#define glXGetClientString _glfw.glx.GetClientString
#define glXQueryExtension _glfw.glx.QueryExtension
#define glXQueryVersion _glfw.glx.QueryVersion
#define glXDestroyContext _glfw.glx.DestroyContext
#define glXMakeCurrent _glfw.glx.MakeCurrent
#define glXSwapBuffers _glfw.glx.SwapBuffers
#define glXQueryExtensionsString _glfw.glx.QueryExtensionsString
#define glXCreateNewContext _glfw.glx.CreateNewContext
#define glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig
#define glXCreateWindow _glfw.glx.CreateWindow
#define glXDestroyWindow _glfw.glx.DestroyWindow
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx
// GLX-specific per-context data
//
typedef struct _GLFWcontextGLX
{
GLXContext handle;
GLXWindow window;
} _GLFWcontextGLX;
// GLX-specific global data
//
typedef struct _GLFWlibraryGLX
{
int major, minor;
int eventBase;
int errorBase;
// dlopen handle for libGL.so.1
void* handle;
// GLX 1.3 functions
PFNGLXGETFBCONFIGSPROC GetFBConfigs;
PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
PFNGLXGETCLIENTSTRINGPROC GetClientString;
PFNGLXQUERYEXTENSIONPROC QueryExtension;
PFNGLXQUERYVERSIONPROC QueryVersion;
PFNGLXDESTROYCONTEXTPROC DestroyContext;
PFNGLXMAKECURRENTPROC MakeCurrent;
PFNGLXSWAPBUFFERSPROC SwapBuffers;
PFNGLXQUERYEXTENSIONSSTRINGPROC QueryExtensionsString;
PFNGLXCREATENEWCONTEXTPROC CreateNewContext;
PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig;
PFNGLXCREATEWINDOWPROC CreateWindow;
PFNGLXDESTROYWINDOWPROC DestroyWindow;
// GLX 1.4 and extension functions
PFNGLXGETPROCADDRESSPROC GetProcAddress;
PFNGLXGETPROCADDRESSPROC GetProcAddressARB;
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool SGI_swap_control;
GLFWbool EXT_swap_control;
GLFWbool MESA_swap_control;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
} _GLFWlibraryGLX;
GLFWbool _glfwInitGLX(void);
void _glfwTerminateGLX(void);
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextGLX(_GLFWwindow* window);
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);

View file

@ -28,7 +28,6 @@
//======================================================================== //========================================================================
#include "internal.h" #include "internal.h"
#include "mappings.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -37,23 +36,25 @@
#include <assert.h> #include <assert.h>
// The global variables below comprise all mutable global data in GLFW // NOTE: The global variables below comprise all mutable global data in GLFW
// // Any other mutable global variable is a bug
// Any other global variable is a bug
// Global state shared between compilation units of GLFW // This contains all mutable state shared between compilation units of GLFW
// //
_GLFWlibrary _glfw = { GLFW_FALSE }; _GLFWlibrary _glfw = { GLFW_FALSE };
// These are outside of _glfw so they can be used before initialization and // These are outside of _glfw so they can be used before initialization and
// after termination // after termination without special handling when _glfw is cleared to zero
// //
static _GLFWerror _glfwMainThreadError; static _GLFWerror _glfwMainThreadError;
static GLFWerrorfun _glfwErrorCallback; static GLFWerrorfun _glfwErrorCallback;
static GLFWallocator _glfwInitAllocator;
static _GLFWinitconfig _glfwInitHints = static _GLFWinitconfig _glfwInitHints =
{ {
GLFW_TRUE, // hat buttons GLFW_TRUE, // hat buttons
GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend
GLFW_ANY_PLATFORM, // preferred platform
NULL, // vkGetInstanceProcAddr function
{ {
GLFW_TRUE, // macOS menu bar GLFW_TRUE, // macOS menu bar
GLFW_TRUE // macOS bundle chdir GLFW_TRUE // macOS bundle chdir
@ -63,6 +64,27 @@ static _GLFWinitconfig _glfwInitHints =
}, },
}; };
// The allocation function used when no custom allocator is set
//
static void* defaultAllocate(size_t size, void* user)
{
return malloc(size);
}
// The deallocation function used when no custom allocator is set
//
static void defaultDeallocate(void* block, void* user)
{
free(block);
}
// The reallocation function used when no custom allocator is set
//
static void* defaultReallocate(void* block, size_t size, void* user)
{
return realloc(block, size);
}
// Terminate the library // Terminate the library
// //
static void terminate(void) static void terminate(void)
@ -81,21 +103,21 @@ static void terminate(void)
{ {
_GLFWmonitor* monitor = _glfw.monitors[i]; _GLFWmonitor* monitor = _glfw.monitors[i];
if (monitor->originalRamp.size) if (monitor->originalRamp.size)
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp); _glfw.platform.setGammaRamp(monitor, &monitor->originalRamp);
_glfwFreeMonitor(monitor); _glfwFreeMonitor(monitor);
} }
free(_glfw.monitors); _glfw_free(_glfw.monitors);
_glfw.monitors = NULL; _glfw.monitors = NULL;
_glfw.monitorCount = 0; _glfw.monitorCount = 0;
free(_glfw.mappings); _glfw_free(_glfw.mappings);
_glfw.mappings = NULL; _glfw.mappings = NULL;
_glfw.mappingCount = 0; _glfw.mappingCount = 0;
_glfwTerminateVulkan(); _glfwTerminateVulkan();
_glfwPlatformTerminateJoysticks(); _glfw.platform.terminateJoysticks();
_glfwPlatformTerminate(); _glfw.platform.terminate();
_glfw.initialized = GLFW_FALSE; _glfw.initialized = GLFW_FALSE;
@ -103,7 +125,7 @@ static void terminate(void)
{ {
_GLFWerror* error = _glfw.errorListHead; _GLFWerror* error = _glfw.errorListHead;
_glfw.errorListHead = error->next; _glfw.errorListHead = error->next;
free(error); _glfw_free(error);
} }
_glfwPlatformDestroyTls(&_glfw.contextSlot); _glfwPlatformDestroyTls(&_glfw.contextSlot);
@ -118,14 +140,108 @@ static void terminate(void)
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Encode a Unicode code point to a UTF-8 stream
// Based on cutef8 by Jeff Bezanson (Public Domain)
//
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint)
{
size_t count = 0;
if (codepoint < 0x80)
s[count++] = (char) codepoint;
else if (codepoint < 0x800)
{
s[count++] = (codepoint >> 6) | 0xc0;
s[count++] = (codepoint & 0x3f) | 0x80;
}
else if (codepoint < 0x10000)
{
s[count++] = (codepoint >> 12) | 0xe0;
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
s[count++] = (codepoint & 0x3f) | 0x80;
}
else if (codepoint < 0x110000)
{
s[count++] = (codepoint >> 18) | 0xf0;
s[count++] = ((codepoint >> 12) & 0x3f) | 0x80;
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
s[count++] = (codepoint & 0x3f) | 0x80;
}
return count;
}
// Splits and translates a text/uri-list into separate file paths
// NOTE: This function destroys the provided string
//
char** _glfwParseUriList(char* text, int* count)
{
const char* prefix = "file://";
char** paths = NULL;
char* line;
*count = 0;
while ((line = strtok(text, "\r\n")))
{
char* path;
text = NULL;
if (line[0] == '#')
continue;
if (strncmp(line, prefix, strlen(prefix)) == 0)
{
line += strlen(prefix);
// TODO: Validate hostname
while (*line != '/')
line++;
}
(*count)++;
path = _glfw_calloc(strlen(line) + 1, 1);
paths = _glfw_realloc(paths, *count * sizeof(char*));
paths[*count - 1] = path;
while (*line)
{
if (line[0] == '%' && line[1] && line[2])
{
const char digits[3] = { line[1], line[2], '\0' };
*path = (char) strtol(digits, NULL, 16);
line += 2;
}
else
*path = *line;
path++;
line++;
}
}
return paths;
}
char* _glfw_strdup(const char* source) char* _glfw_strdup(const char* source)
{ {
const size_t length = strlen(source); const size_t length = strlen(source);
char* result = calloc(length + 1, 1); char* result = _glfw_calloc(length + 1, 1);
strcpy(result, source); strcpy(result, source);
return result; return result;
} }
int _glfw_min(int a, int b)
{
return a < b ? a : b;
}
int _glfw_max(int a, int b)
{
return a > b ? a : b;
}
float _glfw_fminf(float a, float b) float _glfw_fminf(float a, float b)
{ {
if (a != a) if (a != a)
@ -150,6 +266,59 @@ float _glfw_fmaxf(float a, float b)
return b; return b;
} }
void* _glfw_calloc(size_t count, size_t size)
{
if (count && size)
{
void* block;
if (count > SIZE_MAX / size)
{
_glfwInputError(GLFW_INVALID_VALUE, "Allocation size overflow");
return NULL;
}
block = _glfw.allocator.allocate(count * size, _glfw.allocator.user);
if (block)
return memset(block, 0, count * size);
else
{
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
return NULL;
}
}
else
return NULL;
}
void* _glfw_realloc(void* block, size_t size)
{
if (block && size)
{
void* resized = _glfw.allocator.reallocate(block, size, _glfw.allocator.user);
if (resized)
return resized;
else
{
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
return NULL;
}
}
else if (block)
{
_glfw_free(block);
return NULL;
}
else
return _glfw_calloc(1, size);
}
void _glfw_free(void* block)
{
if (block)
_glfw.allocator.deallocate(block, _glfw.allocator.user);
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW event API ////// ////// GLFW event API //////
@ -200,6 +369,8 @@ void _glfwInputError(int code, const char* format, ...)
strcpy(description, "The requested feature cannot be implemented for this platform"); strcpy(description, "The requested feature cannot be implemented for this platform");
else if (code == GLFW_FEATURE_UNIMPLEMENTED) else if (code == GLFW_FEATURE_UNIMPLEMENTED)
strcpy(description, "The requested feature has not yet been implemented for this platform"); strcpy(description, "The requested feature has not yet been implemented for this platform");
else if (code == GLFW_PLATFORM_UNAVAILABLE)
strcpy(description, "The requested platform is unavailable");
else else
strcpy(description, "ERROR: UNKNOWN GLFW ERROR"); strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
} }
@ -209,7 +380,7 @@ void _glfwInputError(int code, const char* format, ...)
error = _glfwPlatformGetTls(&_glfw.errorSlot); error = _glfwPlatformGetTls(&_glfw.errorSlot);
if (!error) if (!error)
{ {
error = calloc(1, sizeof(_GLFWerror)); error = _glfw_calloc(1, sizeof(_GLFWerror));
_glfwPlatformSetTls(&_glfw.errorSlot, error); _glfwPlatformSetTls(&_glfw.errorSlot, error);
_glfwPlatformLockMutex(&_glfw.errorLock); _glfwPlatformLockMutex(&_glfw.errorLock);
error->next = _glfw.errorListHead; error->next = _glfw.errorListHead;
@ -240,7 +411,18 @@ GLFWAPI int glfwInit(void)
memset(&_glfw, 0, sizeof(_glfw)); memset(&_glfw, 0, sizeof(_glfw));
_glfw.hints.init = _glfwInitHints; _glfw.hints.init = _glfwInitHints;
if (!_glfwPlatformInit()) _glfw.allocator = _glfwInitAllocator;
if (!_glfw.allocator.allocate)
{
_glfw.allocator.allocate = defaultAllocate;
_glfw.allocator.reallocate = defaultReallocate;
_glfw.allocator.deallocate = defaultDeallocate;
}
if (!_glfwSelectPlatform(_glfw.hints.init.platformID, &_glfw.platform))
return GLFW_FALSE;
if (!_glfw.platform.init())
{ {
terminate(); terminate();
return GLFW_FALSE; return GLFW_FALSE;
@ -256,24 +438,14 @@ GLFWAPI int glfwInit(void)
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError); _glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
_glfw.initialized = GLFW_TRUE; _glfwInitGamepadMappings();
_glfwPlatformInitTimer();
_glfw.timer.offset = _glfwPlatformGetTimerValue(); _glfw.timer.offset = _glfwPlatformGetTimerValue();
_glfw.initialized = GLFW_TRUE;
glfwDefaultWindowHints(); glfwDefaultWindowHints();
{
int i;
for (i = 0; _glfwDefaultMappings[i]; i++)
{
if (!glfwUpdateGamepadMappings(_glfwDefaultMappings[i]))
{
terminate();
return GLFW_FALSE;
}
}
}
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -295,6 +467,9 @@ GLFWAPI void glfwInitHint(int hint, int value)
case GLFW_ANGLE_PLATFORM_TYPE: case GLFW_ANGLE_PLATFORM_TYPE:
_glfwInitHints.angleType = value; _glfwInitHints.angleType = value;
return; return;
case GLFW_PLATFORM:
_glfwInitHints.platformID = value;
return;
case GLFW_COCOA_CHDIR_RESOURCES: case GLFW_COCOA_CHDIR_RESOURCES:
_glfwInitHints.ns.chdir = value; _glfwInitHints.ns.chdir = value;
return; return;
@ -310,6 +485,24 @@ GLFWAPI void glfwInitHint(int hint, int value)
"Invalid init hint 0x%08X", hint); "Invalid init hint 0x%08X", hint);
} }
GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator)
{
if (allocator)
{
if (allocator->allocate && allocator->reallocate && allocator->deallocate)
_glfwInitAllocator = *allocator;
else
_glfwInputError(GLFW_INVALID_VALUE, "Missing function in allocator");
}
else
memset(&_glfwInitAllocator, 0, sizeof(GLFWallocator));
}
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
{
_glfwInitHints.vulkanLoader = loader;
}
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev) GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
{ {
if (major != NULL) if (major != NULL)
@ -320,11 +513,6 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
*rev = GLFW_VERSION_REVISION; *rev = GLFW_VERSION_REVISION;
} }
GLFWAPI const char* glfwGetVersionString(void)
{
return _glfwPlatformGetVersionString();
}
GLFWAPI int glfwGetError(const char** description) GLFWAPI int glfwGetError(const char** description)
{ {
_GLFWerror* error; _GLFWerror* error;
@ -351,7 +539,7 @@ GLFWAPI int glfwGetError(const char** description)
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun) GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
{ {
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun); _GLFW_SWAP(GLFWerrorfun, _glfwErrorCallback, cbfun);
return cbfun; return cbfun;
} }

View file

@ -28,6 +28,7 @@
//======================================================================== //========================================================================
#include "internal.h" #include "internal.h"
#include "mappings.h"
#include <assert.h> #include <assert.h>
#include <float.h> #include <float.h>
@ -43,15 +44,22 @@
#define _GLFW_JOYSTICK_BUTTON 2 #define _GLFW_JOYSTICK_BUTTON 2
#define _GLFW_JOYSTICK_HATBIT 3 #define _GLFW_JOYSTICK_HATBIT 3
#define GLFW_MOD_MASK (GLFW_MOD_SHIFT | \
GLFW_MOD_CONTROL | \
GLFW_MOD_ALT | \
GLFW_MOD_SUPER | \
GLFW_MOD_CAPS_LOCK | \
GLFW_MOD_NUM_LOCK)
// Initializes the platform joystick API if it has not been already // Initializes the platform joystick API if it has not been already
// //
static GLFWbool initJoysticks(void) static GLFWbool initJoysticks(void)
{ {
if (!_glfw.joysticksInitialized) if (!_glfw.joysticksInitialized)
{ {
if (!_glfwPlatformInitJoysticks()) if (!_glfw.platform.initJoysticks())
{ {
_glfwPlatformTerminateJoysticks(); _glfw.platform.terminateJoysticks();
return GLFW_FALSE; return GLFW_FALSE;
} }
} }
@ -101,25 +109,13 @@ static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++) for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
{ {
if (!isValidElementForJoystick(mapping->buttons + i, js)) if (!isValidElementForJoystick(mapping->buttons + i, js))
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid button in gamepad mapping %s (%s)",
mapping->guid,
mapping->name);
return NULL; return NULL;
}
} }
for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++) for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++)
{ {
if (!isValidElementForJoystick(mapping->axes + i, js)) if (!isValidElementForJoystick(mapping->axes + i, js))
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid axis in gamepad mapping %s (%s)",
mapping->guid,
mapping->name);
return NULL; return NULL;
}
} }
} }
@ -245,8 +241,9 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
} }
else else
{ {
length = strlen(_GLFW_PLATFORM_MAPPING_NAME); const char* name = _glfw.platform.getMappingName();
if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0) length = strlen(name);
if (strncmp(c, name, length) != 0)
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -263,7 +260,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
mapping->guid[i] += 'a' - 'A'; mapping->guid[i] += 'a' - 'A';
} }
_glfwPlatformUpdateGamepadGUID(mapping->guid); _glfw.platform.updateGamepadGUID(mapping->guid);
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -276,6 +273,12 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
// //
void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods) void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods)
{ {
assert(window != NULL);
assert(key >= 0 || key == GLFW_KEY_UNKNOWN);
assert(key <= GLFW_KEY_LAST);
assert(action == GLFW_PRESS || action == GLFW_RELEASE);
assert(mods == (mods & GLFW_MOD_MASK));
if (key >= 0 && key <= GLFW_KEY_LAST) if (key >= 0 && key <= GLFW_KEY_LAST)
{ {
GLFWbool repeated = GLFW_FALSE; GLFWbool repeated = GLFW_FALSE;
@ -305,8 +308,12 @@ void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int m
// Notifies shared code of a Unicode codepoint input event // Notifies shared code of a Unicode codepoint input event
// The 'plain' parameter determines whether to emit a regular character event // The 'plain' parameter determines whether to emit a regular character event
// //
void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain) void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool plain)
{ {
assert(window != NULL);
assert(mods == (mods & GLFW_MOD_MASK));
assert(plain == GLFW_TRUE || plain == GLFW_FALSE);
if (codepoint < 32 || (codepoint > 126 && codepoint < 160)) if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
return; return;
@ -327,6 +334,12 @@ void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWb
// //
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset) void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
{ {
assert(window != NULL);
assert(xoffset > -FLT_MAX);
assert(xoffset < FLT_MAX);
assert(yoffset > -FLT_MAX);
assert(yoffset < FLT_MAX);
if (window->callbacks.scroll) if (window->callbacks.scroll)
window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset); window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset);
} }
@ -335,6 +348,12 @@ void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
// //
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
{ {
assert(window != NULL);
assert(button >= 0);
assert(button <= GLFW_MOUSE_BUTTON_LAST);
assert(action == GLFW_PRESS || action == GLFW_RELEASE);
assert(mods == (mods & GLFW_MOD_MASK));
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
return; return;
@ -355,6 +374,12 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
// //
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos) void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
{ {
assert(window != NULL);
assert(xpos > -FLT_MAX);
assert(xpos < FLT_MAX);
assert(ypos > -FLT_MAX);
assert(ypos < FLT_MAX);
if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos) if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
return; return;
@ -369,6 +394,9 @@ void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
// //
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered) void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
{ {
assert(window != NULL);
assert(entered == GLFW_TRUE || entered == GLFW_FALSE);
if (window->callbacks.cursorEnter) if (window->callbacks.cursorEnter)
window->callbacks.cursorEnter((GLFWwindow*) window, entered); window->callbacks.cursorEnter((GLFWwindow*) window, entered);
} }
@ -377,6 +405,10 @@ void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
// //
void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths) void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
{ {
assert(window != NULL);
assert(count > 0);
assert(paths != NULL);
if (window->callbacks.drop) if (window->callbacks.drop)
window->callbacks.drop((GLFWwindow*) window, count, paths); window->callbacks.drop((GLFWwindow*) window, count, paths);
} }
@ -385,16 +417,26 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
// //
void _glfwInputJoystick(_GLFWjoystick* js, int event) void _glfwInputJoystick(_GLFWjoystick* js, int event)
{ {
const int jid = (int) (js - _glfw.joysticks); assert(js != NULL);
assert(event == GLFW_CONNECTED || event == GLFW_DISCONNECTED);
if (event == GLFW_CONNECTED)
js->connected = GLFW_TRUE;
else if (event == GLFW_DISCONNECTED)
js->connected = GLFW_FALSE;
if (_glfw.callbacks.joystick) if (_glfw.callbacks.joystick)
_glfw.callbacks.joystick(jid, event); _glfw.callbacks.joystick((int) (js - _glfw.joysticks), event);
} }
// Notifies shared code of the new value of a joystick axis // Notifies shared code of the new value of a joystick axis
// //
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value) void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
{ {
assert(js != NULL);
assert(axis >= 0);
assert(axis < js->axisCount);
js->axes[axis] = value; js->axes[axis] = value;
} }
@ -402,6 +444,11 @@ void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
// //
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value) void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value)
{ {
assert(js != NULL);
assert(button >= 0);
assert(button < js->buttonCount);
assert(value == GLFW_PRESS || value == GLFW_RELEASE);
js->buttons[button] = value; js->buttons[button] = value;
} }
@ -409,7 +456,18 @@ void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value)
// //
void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value) void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
{ {
const int base = js->buttonCount + hat * 4; int base;
assert(js != NULL);
assert(hat >= 0);
assert(hat < js->hatCount);
// Valid hat values only use the least significant nibble and have at most two bits
// set, which can be considered adjacent plus an arbitrary rotation within the nibble
assert((value & 0xf0) == 0);
assert((value & ((value << 2) | (value >> 2))) == 0);
base = js->buttonCount + hat * 4;
js->buttons[base + 0] = (value & 0x01) ? GLFW_PRESS : GLFW_RELEASE; js->buttons[base + 0] = (value & 0x01) ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[base + 1] = (value & 0x02) ? GLFW_PRESS : GLFW_RELEASE; js->buttons[base + 1] = (value & 0x02) ? GLFW_PRESS : GLFW_RELEASE;
@ -424,6 +482,21 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Adds the built-in set of gamepad mappings
//
void _glfwInitGamepadMappings(void)
{
size_t i;
const size_t count = sizeof(_glfwDefaultMappings) / sizeof(char*);
_glfw.mappings = _glfw_calloc(count, sizeof(_GLFWmapping));
for (i = 0; i < count; i++)
{
if (parseMapping(&_glfw.mappings[_glfw.mappingCount], _glfwDefaultMappings[i]))
_glfw.mappingCount++;
}
}
// Returns an available joystick object with arrays and name allocated // Returns an available joystick object with arrays and name allocated
// //
_GLFWjoystick* _glfwAllocJoystick(const char* name, _GLFWjoystick* _glfwAllocJoystick(const char* name,
@ -437,7 +510,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (!_glfw.joysticks[jid].present) if (!_glfw.joysticks[jid].allocated)
break; break;
} }
@ -445,10 +518,10 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
return NULL; return NULL;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
js->present = GLFW_TRUE; js->allocated = GLFW_TRUE;
js->axes = calloc(axisCount, sizeof(float)); js->axes = _glfw_calloc(axisCount, sizeof(float));
js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1); js->buttons = _glfw_calloc(buttonCount + (size_t) hatCount * 4, 1);
js->hats = calloc(hatCount, 1); js->hats = _glfw_calloc(hatCount, 1);
js->axisCount = axisCount; js->axisCount = axisCount;
js->buttonCount = buttonCount; js->buttonCount = buttonCount;
js->hatCount = hatCount; js->hatCount = hatCount;
@ -464,9 +537,9 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
// //
void _glfwFreeJoystick(_GLFWjoystick* js) void _glfwFreeJoystick(_GLFWjoystick* js)
{ {
free(js->axes); _glfw_free(js->axes);
free(js->buttons); _glfw_free(js->buttons);
free(js->hats); _glfw_free(js->hats);
memset(js, 0, sizeof(_GLFWjoystick)); memset(js, 0, sizeof(_GLFWjoystick));
} }
@ -476,8 +549,8 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window)
{ {
int width, height; int width, height;
_glfwPlatformGetWindowSize(window, &width, &height); _glfw.platform.getWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); _glfw.platform.setCursorPos(window, width / 2.0, height / 2.0);
} }
@ -517,96 +590,109 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (mode == GLFW_CURSOR) switch (mode)
{ {
if (value != GLFW_CURSOR_NORMAL && case GLFW_CURSOR:
value != GLFW_CURSOR_HIDDEN &&
value != GLFW_CURSOR_DISABLED)
{ {
_glfwInputError(GLFW_INVALID_ENUM, if (value != GLFW_CURSOR_NORMAL &&
"Invalid cursor mode 0x%08X", value != GLFW_CURSOR_HIDDEN &&
value); value != GLFW_CURSOR_DISABLED &&
return; value != GLFW_CURSOR_CAPTURED)
}
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
_glfwPlatformSetCursorMode(window, value);
}
else if (mode == GLFW_STICKY_KEYS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyKeys == value)
return;
if (!value)
{
int i;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
{ {
if (window->keys[i] == _GLFW_STICK) _glfwInputError(GLFW_INVALID_ENUM,
window->keys[i] = GLFW_RELEASE; "Invalid cursor mode 0x%08X",
value);
return;
} }
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfw.platform.getCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
_glfw.platform.setCursorMode(window, value);
return;
} }
window->stickyKeys = value; case GLFW_STICKY_KEYS:
}
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyMouseButtons == value)
return;
if (!value)
{ {
int i; value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyKeys == value)
return;
// Release all sticky mouse buttons if (!value)
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{ {
if (window->mouseButtons[i] == _GLFW_STICK) int i;
window->mouseButtons[i] = GLFW_RELEASE;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
}
} }
window->stickyKeys = value;
return;
} }
window->stickyMouseButtons = value; case GLFW_STICKY_MOUSE_BUTTONS:
}
else if (mode == GLFW_LOCK_KEY_MODS)
{
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
}
else if (mode == GLFW_RAW_MOUSE_MOTION)
{
if (!_glfwPlatformRawMouseMotionSupported())
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, value = value ? GLFW_TRUE : GLFW_FALSE;
"Raw mouse motion is not supported on this system"); if (window->stickyMouseButtons == value)
return;
if (!value)
{
int i;
// Release all sticky mouse buttons
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{
if (window->mouseButtons[i] == _GLFW_STICK)
window->mouseButtons[i] = GLFW_RELEASE;
}
}
window->stickyMouseButtons = value;
return; return;
} }
value = value ? GLFW_TRUE : GLFW_FALSE; case GLFW_LOCK_KEY_MODS:
if (window->rawMouseMotion == value) {
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
}
window->rawMouseMotion = value; case GLFW_RAW_MOUSE_MOTION:
_glfwPlatformSetRawMouseMotion(window, value); {
if (!_glfw.platform.rawMouseMotionSupported())
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Raw mouse motion is not supported on this system");
return;
}
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->rawMouseMotion == value)
return;
window->rawMouseMotion = value;
_glfw.platform.setRawMouseMotion(window, value);
return;
}
} }
else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
} }
GLFWAPI int glfwRawMouseMotionSupported(void) GLFWAPI int glfwRawMouseMotionSupported(void)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
return _glfwPlatformRawMouseMotionSupported(); return _glfw.platform.rawMouseMotionSupported();
} }
GLFWAPI const char* glfwGetKeyName(int key, int scancode) GLFWAPI const char* glfwGetKeyName(int key, int scancode)
@ -622,10 +708,10 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode)
return NULL; return NULL;
} }
scancode = _glfwPlatformGetKeyScancode(key); scancode = _glfw.platform.getKeyScancode(key);
} }
return _glfwPlatformGetScancodeName(scancode); return _glfw.platform.getScancodeName(scancode);
} }
GLFWAPI int glfwGetKeyScancode(int key) GLFWAPI int glfwGetKeyScancode(int key)
@ -638,7 +724,7 @@ GLFWAPI int glfwGetKeyScancode(int key)
return GLFW_RELEASE; return GLFW_RELEASE;
} }
return _glfwPlatformGetKeyScancode(key); return _glfw.platform.getKeyScancode(key);
} }
GLFWAPI int glfwGetKey(GLFWwindow* handle, int key) GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
@ -707,7 +793,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
*ypos = window->virtualCursorPosY; *ypos = window->virtualCursorPosY;
} }
else else
_glfwPlatformGetCursorPos(window, xpos, ypos); _glfw.platform.getCursorPos(window, xpos, ypos);
} }
GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos) GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
@ -726,7 +812,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
return; return;
} }
if (!_glfwPlatformWindowFocused(window)) if (!_glfw.platform.windowFocused(window))
return; return;
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
@ -738,7 +824,7 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
else else
{ {
// Update system cursor position // Update system cursor position
_glfwPlatformSetCursorPos(window, xpos, ypos); _glfw.platform.setCursorPos(window, xpos, ypos);
} }
} }
@ -747,14 +833,21 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
_GLFWcursor* cursor; _GLFWcursor* cursor;
assert(image != NULL); assert(image != NULL);
assert(image->pixels != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
cursor = calloc(1, sizeof(_GLFWcursor)); if (image->width <= 0 || image->height <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid image dimensions for cursor");
return NULL;
}
cursor = _glfw_calloc(1, sizeof(_GLFWcursor));
cursor->next = _glfw.cursorListHead; cursor->next = _glfw.cursorListHead;
_glfw.cursorListHead = cursor; _glfw.cursorListHead = cursor;
if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot)) if (!_glfw.platform.createCursor(cursor, image, xhot, yhot))
{ {
glfwDestroyCursor((GLFWcursor*) cursor); glfwDestroyCursor((GLFWcursor*) cursor);
return NULL; return NULL;
@ -784,11 +877,11 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
return NULL; return NULL;
} }
cursor = calloc(1, sizeof(_GLFWcursor)); cursor = _glfw_calloc(1, sizeof(_GLFWcursor));
cursor->next = _glfw.cursorListHead; cursor->next = _glfw.cursorListHead;
_glfw.cursorListHead = cursor; _glfw.cursorListHead = cursor;
if (!_glfwPlatformCreateStandardCursor(cursor, shape)) if (!_glfw.platform.createStandardCursor(cursor, shape))
{ {
glfwDestroyCursor((GLFWcursor*) cursor); glfwDestroyCursor((GLFWcursor*) cursor);
return NULL; return NULL;
@ -817,7 +910,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
} }
} }
_glfwPlatformDestroyCursor(cursor); _glfw.platform.destroyCursor(cursor);
// Unlink cursor from global linked list // Unlink cursor from global linked list
{ {
@ -829,7 +922,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
*prev = cursor->next; *prev = cursor->next;
} }
free(cursor); _glfw_free(cursor);
} }
GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle) GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
@ -842,7 +935,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
window->cursor = cursor; window->cursor = cursor;
_glfwPlatformSetCursor(window, cursor); _glfw.platform.setCursor(window, cursor);
} }
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
@ -851,7 +944,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.key, cbfun); _GLFW_SWAP(GLFWkeyfun, window->callbacks.key, cbfun);
return cbfun; return cbfun;
} }
@ -861,7 +954,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.character, cbfun); _GLFW_SWAP(GLFWcharfun, window->callbacks.character, cbfun);
return cbfun; return cbfun;
} }
@ -871,7 +964,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmods
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun); _GLFW_SWAP(GLFWcharmodsfun, window->callbacks.charmods, cbfun);
return cbfun; return cbfun;
} }
@ -882,7 +975,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun); _GLFW_SWAP(GLFWmousebuttonfun, window->callbacks.mouseButton, cbfun);
return cbfun; return cbfun;
} }
@ -893,7 +986,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun); _GLFW_SWAP(GLFWcursorposfun, window->callbacks.cursorPos, cbfun);
return cbfun; return cbfun;
} }
@ -904,7 +997,7 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun); _GLFW_SWAP(GLFWcursorenterfun, window->callbacks.cursorEnter, cbfun);
return cbfun; return cbfun;
} }
@ -915,7 +1008,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun); _GLFW_SWAP(GLFWscrollfun, window->callbacks.scroll, cbfun);
return cbfun; return cbfun;
} }
@ -925,7 +1018,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); _GLFW_SWAP(GLFWdropfun, window->callbacks.drop, cbfun);
return cbfun; return cbfun;
} }
@ -948,10 +1041,10 @@ GLFWAPI int glfwJoystickPresent(int jid)
return GLFW_FALSE; return GLFW_FALSE;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return GLFW_FALSE; return GLFW_FALSE;
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); return _glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE);
} }
GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count) GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
@ -976,10 +1069,10 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
return NULL; return NULL;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES)) if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_AXES))
return NULL; return NULL;
*count = js->axisCount; *count = js->axisCount;
@ -1008,10 +1101,10 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
return NULL; return NULL;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_BUTTONS))
return NULL; return NULL;
if (_glfw.hints.init.hatButtons) if (_glfw.hints.init.hatButtons)
@ -1044,10 +1137,10 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count)
return NULL; return NULL;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_BUTTONS))
return NULL; return NULL;
*count = js->hatCount; *count = js->hatCount;
@ -1073,10 +1166,10 @@ GLFWAPI const char* glfwGetJoystickName(int jid)
return NULL; return NULL;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE))
return NULL; return NULL;
return js->name; return js->name;
@ -1101,10 +1194,10 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid)
return NULL; return NULL;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE))
return NULL; return NULL;
return js->guid; return js->guid;
@ -1120,7 +1213,7 @@ GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->allocated)
return; return;
js->userPointer = pointer; js->userPointer = pointer;
@ -1136,7 +1229,7 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->allocated)
return NULL; return NULL;
return js->userPointer; return js->userPointer;
@ -1149,7 +1242,7 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
if (!initJoysticks()) if (!initJoysticks())
return NULL; return NULL;
_GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun); _GLFW_SWAP(GLFWjoystickfun, _glfw.callbacks.joystick, cbfun);
return cbfun; return cbfun;
} }
@ -1187,8 +1280,8 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
{ {
_glfw.mappingCount++; _glfw.mappingCount++;
_glfw.mappings = _glfw.mappings =
realloc(_glfw.mappings, _glfw_realloc(_glfw.mappings,
sizeof(_GLFWmapping) * _glfw.mappingCount); sizeof(_GLFWmapping) * _glfw.mappingCount);
_glfw.mappings[_glfw.mappingCount - 1] = mapping; _glfw.mappings[_glfw.mappingCount - 1] = mapping;
} }
} }
@ -1206,7 +1299,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
_GLFWjoystick* js = _glfw.joysticks + jid; _GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
js->mapping = findValidMapping(js); js->mapping = findValidMapping(js);
} }
@ -1232,10 +1325,10 @@ GLFWAPI int glfwJoystickIsGamepad(int jid)
return GLFW_FALSE; return GLFW_FALSE;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE))
return GLFW_FALSE; return GLFW_FALSE;
return js->mapping != NULL; return js->mapping != NULL;
@ -1260,10 +1353,10 @@ GLFWAPI const char* glfwGetGamepadName(int jid)
return NULL; return NULL;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return NULL; return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE))
return NULL; return NULL;
if (!js->mapping) if (!js->mapping)
@ -1295,10 +1388,10 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
return GLFW_FALSE; return GLFW_FALSE;
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (!js->present) if (!js->connected)
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL)) if (!_glfw.platform.pollJoystick(js, _GLFW_POLL_ALL))
return GLFW_FALSE; return GLFW_FALSE;
if (!js->mapping) if (!js->mapping)
@ -1363,13 +1456,13 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
assert(string != NULL); assert(string != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformSetClipboardString(string); _glfw.platform.setClipboardString(string);
} }
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle) GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetClipboardString(); return _glfw.platform.getClipboardString();
} }
GLFWAPI double glfwGetTime(void) GLFWAPI double glfwGetTime(void)
@ -1404,3 +1497,4 @@ GLFWAPI uint64_t glfwGetTimerFrequency(void)
_GLFW_REQUIRE_INIT_OR_RETURN(0); _GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfwPlatformGetTimerFrequency(); return _glfwPlatformGetTimerFrequency();
} }

View file

@ -59,6 +59,7 @@
#define _GLFW_MESSAGE_SIZE 1024 #define _GLFW_MESSAGE_SIZE 1024
typedef int GLFWbool; typedef int GLFWbool;
typedef void (*GLFWproc)(void);
typedef struct _GLFWerror _GLFWerror; typedef struct _GLFWerror _GLFWerror;
typedef struct _GLFWinitconfig _GLFWinitconfig; typedef struct _GLFWinitconfig _GLFWinitconfig;
@ -67,6 +68,7 @@ typedef struct _GLFWctxconfig _GLFWctxconfig;
typedef struct _GLFWfbconfig _GLFWfbconfig; typedef struct _GLFWfbconfig _GLFWfbconfig;
typedef struct _GLFWcontext _GLFWcontext; typedef struct _GLFWcontext _GLFWcontext;
typedef struct _GLFWwindow _GLFWwindow; typedef struct _GLFWwindow _GLFWwindow;
typedef struct _GLFWplatform _GLFWplatform;
typedef struct _GLFWlibrary _GLFWlibrary; typedef struct _GLFWlibrary _GLFWlibrary;
typedef struct _GLFWmonitor _GLFWmonitor; typedef struct _GLFWmonitor _GLFWmonitor;
typedef struct _GLFWcursor _GLFWcursor; typedef struct _GLFWcursor _GLFWcursor;
@ -76,13 +78,6 @@ typedef struct _GLFWjoystick _GLFWjoystick;
typedef struct _GLFWtls _GLFWtls; typedef struct _GLFWtls _GLFWtls;
typedef struct _GLFWmutex _GLFWmutex; typedef struct _GLFWmutex _GLFWmutex;
typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*);
typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*);
typedef void (* _GLFWswapintervalfun)(int);
typedef int (* _GLFWextensionsupportedfun)(const char*);
typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*);
typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
#define GL_VERSION 0x1f02 #define GL_VERSION 0x1f02
#define GL_NONE 0 #define GL_NONE 0
#define GL_COLOR_BUFFER_BIT 0x00004000 #define GL_COLOR_BUFFER_BIT 0x00004000
@ -113,6 +108,165 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGPROC)(GLenum);
typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*); typedef void (APIENTRY * PFNGLGETINTEGERVPROC)(GLenum,GLint*);
typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint); typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
#if defined(_GLFW_WIN32)
#define EGLAPIENTRY __stdcall
#else
#define EGLAPIENTRY
#endif
#define EGL_SUCCESS 0x3000
#define EGL_NOT_INITIALIZED 0x3001
#define EGL_BAD_ACCESS 0x3002
#define EGL_BAD_ALLOC 0x3003
#define EGL_BAD_ATTRIBUTE 0x3004
#define EGL_BAD_CONFIG 0x3005
#define EGL_BAD_CONTEXT 0x3006
#define EGL_BAD_CURRENT_SURFACE 0x3007
#define EGL_BAD_DISPLAY 0x3008
#define EGL_BAD_MATCH 0x3009
#define EGL_BAD_NATIVE_PIXMAP 0x300a
#define EGL_BAD_NATIVE_WINDOW 0x300b
#define EGL_BAD_PARAMETER 0x300c
#define EGL_BAD_SURFACE 0x300d
#define EGL_CONTEXT_LOST 0x300e
#define EGL_COLOR_BUFFER_TYPE 0x303f
#define EGL_RGB_BUFFER 0x308e
#define EGL_SURFACE_TYPE 0x3033
#define EGL_WINDOW_BIT 0x0004
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_OPENGL_ES_BIT 0x0001
#define EGL_OPENGL_ES2_BIT 0x0004
#define EGL_OPENGL_BIT 0x0008
#define EGL_ALPHA_SIZE 0x3021
#define EGL_BLUE_SIZE 0x3022
#define EGL_GREEN_SIZE 0x3023
#define EGL_RED_SIZE 0x3024
#define EGL_DEPTH_SIZE 0x3025
#define EGL_STENCIL_SIZE 0x3026
#define EGL_SAMPLES 0x3031
#define EGL_OPENGL_ES_API 0x30a0
#define EGL_OPENGL_API 0x30a2
#define EGL_NONE 0x3038
#define EGL_RENDER_BUFFER 0x3086
#define EGL_SINGLE_BUFFER 0x3085
#define EGL_EXTENSIONS 0x3055
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_NATIVE_VISUAL_ID 0x302e
#define EGL_NO_SURFACE ((EGLSurface) 0)
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
#define EGL_NO_CONTEXT ((EGLContext) 0)
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31bd
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31be
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31bf
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd
#define EGL_CONTEXT_FLAGS_KHR 0x30fc
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
#define EGL_GL_COLORSPACE_KHR 0x309d
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
#define EGL_PLATFORM_X11_EXT 0x31d5
#define EGL_PLATFORM_WAYLAND_EXT 0x31d8
#define EGL_PRESENT_OPAQUE_EXT 0x31df
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320d
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320e
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f
typedef int EGLint;
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void* EGLConfig;
typedef void* EGLContext;
typedef void* EGLDisplay;
typedef void* EGLSurface;
typedef void* EGLNativeDisplayType;
typedef void* EGLNativeWindowType;
// EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigs)(EGLDisplay,EGLConfig*,EGLint,EGLint*);
typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetDisplay)(EGLNativeDisplayType);
typedef EGLint (EGLAPIENTRY * PFN_eglGetError)(void);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglInitialize)(EGLDisplay,EGLint*,EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglTerminate)(EGLDisplay);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglBindAPI)(EGLenum);
typedef EGLContext (EGLAPIENTRY * PFN_eglCreateContext)(EGLDisplay,EGLConfig,EGLContext,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroySurface)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglDestroyContext)(EGLDisplay,EGLContext);
typedef EGLSurface (EGLAPIENTRY * PFN_eglCreateWindowSurface)(EGLDisplay,EGLConfig,EGLNativeWindowType,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglMakeCurrent)(EGLDisplay,EGLSurface,EGLSurface,EGLContext);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint);
typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint);
typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*);
#define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define eglGetConfigs _glfw.egl.GetConfigs
#define eglGetDisplay _glfw.egl.GetDisplay
#define eglGetError _glfw.egl.GetError
#define eglInitialize _glfw.egl.Initialize
#define eglTerminate _glfw.egl.Terminate
#define eglBindAPI _glfw.egl.BindAPI
#define eglCreateContext _glfw.egl.CreateContext
#define eglDestroySurface _glfw.egl.DestroySurface
#define eglDestroyContext _glfw.egl.DestroyContext
#define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
#define eglMakeCurrent _glfw.egl.MakeCurrent
#define eglSwapBuffers _glfw.egl.SwapBuffers
#define eglSwapInterval _glfw.egl.SwapInterval
#define eglQueryString _glfw.egl.QueryString
#define eglGetProcAddress _glfw.egl.GetProcAddress
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*);
#define eglGetPlatformDisplayEXT _glfw.egl.GetPlatformDisplayEXT
#define eglCreatePlatformWindowSurfaceEXT _glfw.egl.CreatePlatformWindowSurfaceEXT
#define OSMESA_RGBA 0x1908
#define OSMESA_FORMAT 0x22
#define OSMESA_DEPTH_BITS 0x30
#define OSMESA_STENCIL_BITS 0x31
#define OSMESA_ACCUM_BITS 0x32
#define OSMESA_PROFILE 0x33
#define OSMESA_CORE_PROFILE 0x34
#define OSMESA_COMPAT_PROFILE 0x35
#define OSMESA_CONTEXT_MAJOR_VERSION 0x36
#define OSMESA_CONTEXT_MINOR_VERSION 0x37
typedef void* OSMesaContext;
typedef void (*OSMESAproc)(void);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextExt)(GLenum,GLint,GLint,GLint,OSMesaContext);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextAttribs)(const int*,OSMesaContext);
typedef void (GLAPIENTRY * PFN_OSMesaDestroyContext)(OSMesaContext);
typedef int (GLAPIENTRY * PFN_OSMesaMakeCurrent)(OSMesaContext,void*,int,int,int);
typedef int (GLAPIENTRY * PFN_OSMesaGetColorBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef int (GLAPIENTRY * PFN_OSMesaGetDepthBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*);
#define OSMesaCreateContextExt _glfw.osmesa.CreateContextExt
#define OSMesaCreateContextAttribs _glfw.osmesa.CreateContextAttribs
#define OSMesaDestroyContext _glfw.osmesa.DestroyContext
#define OSMesaMakeCurrent _glfw.osmesa.MakeCurrent
#define OSMesaGetColorBuffer _glfw.osmesa.GetColorBuffer
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
#define VK_NULL_HANDLE 0 #define VK_NULL_HANDLE 0
typedef void* VkInstance; typedef void* VkInstance;
@ -170,32 +324,11 @@ typedef struct VkExtensionProperties
typedef void (APIENTRY * PFN_vkVoidFunction)(void); typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#if defined(_GLFW_VULKAN_STATIC) typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*); typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*); #define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
#else
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
#endif
#if defined(_GLFW_COCOA) #include "platform.h"
#include "cocoa_platform.h"
#elif defined(_GLFW_WIN32)
#include "win32_platform.h"
#elif defined(_GLFW_X11)
#include "x11_platform.h"
#elif defined(_GLFW_WAYLAND)
#include "wl_platform.h"
#elif defined(_GLFW_OSMESA)
#include "null_platform.h"
#else
#error "No supported window creation API selected"
#endif
#include "egl_context.h"
#include "osmesa_context.h"
// Constructs a version number string from the public header macros // Constructs a version number string from the public header macros
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r #define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
@ -219,12 +352,12 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
} }
// Swaps the provided pointers // Swaps the provided pointers
#define _GLFW_SWAP_POINTERS(x, y) \ #define _GLFW_SWAP(type, x, y) \
{ \ { \
void* t; \ type t; \
t = x; \ t = x; \
x = y; \ x = y; \
y = t; \ y = t; \
} }
// Per-thread error structure // Per-thread error structure
@ -244,6 +377,8 @@ struct _GLFWinitconfig
{ {
GLFWbool hatButtons; GLFWbool hatButtons;
int angleType; int angleType;
int platformID;
PFN_vkGetInstanceProcAddr vulkanLoader;
struct { struct {
GLFWbool menubar; GLFWbool menubar;
GLFWbool chdir; GLFWbool chdir;
@ -261,6 +396,8 @@ struct _GLFWinitconfig
// //
struct _GLFWwndconfig struct _GLFWwndconfig
{ {
int xpos;
int ypos;
int width; int width;
int height; int height;
const char* title; const char* title;
@ -286,6 +423,9 @@ struct _GLFWwndconfig
struct { struct {
GLFWbool keymenu; GLFWbool keymenu;
} win32; } win32;
struct {
char appId[256];
} wl;
}; };
// Context configuration // Context configuration
@ -357,19 +497,29 @@ struct _GLFWcontext
PFNGLGETINTEGERVPROC GetIntegerv; PFNGLGETINTEGERVPROC GetIntegerv;
PFNGLGETSTRINGPROC GetString; PFNGLGETSTRINGPROC GetString;
_GLFWmakecontextcurrentfun makeCurrent; void (*makeCurrent)(_GLFWwindow*);
_GLFWswapbuffersfun swapBuffers; void (*swapBuffers)(_GLFWwindow*);
_GLFWswapintervalfun swapInterval; void (*swapInterval)(int);
_GLFWextensionsupportedfun extensionSupported; int (*extensionSupported)(const char*);
_GLFWgetprocaddressfun getProcAddress; GLFWglproc (*getProcAddress)(const char*);
_GLFWdestroycontextfun destroy; void (*destroy)(_GLFWwindow*);
// This is defined in the context API's context.h struct {
_GLFW_PLATFORM_CONTEXT_STATE; EGLConfig config;
// This is defined in egl_context.h EGLContext handle;
_GLFWcontextEGL egl; EGLSurface surface;
// This is defined in osmesa_context.h void* client;
_GLFWcontextOSMesa osmesa; } egl;
struct {
OSMesaContext handle;
int width;
int height;
void* buffer;
} osmesa;
// This is defined in platform.h
GLFW_PLATFORM_CONTEXT_STATE
}; };
// Window and context structure // Window and context structure
@ -428,8 +578,8 @@ struct _GLFWwindow
GLFWdropfun drop; GLFWdropfun drop;
} callbacks; } callbacks;
// This is defined in the window API's platform.h // This is defined in platform.h
_GLFW_PLATFORM_WINDOW_STATE; GLFW_PLATFORM_WINDOW_STATE
}; };
// Monitor structure // Monitor structure
@ -452,8 +602,8 @@ struct _GLFWmonitor
GLFWgammaramp originalRamp; GLFWgammaramp originalRamp;
GLFWgammaramp currentRamp; GLFWgammaramp currentRamp;
// This is defined in the window API's platform.h // This is defined in platform.h
_GLFW_PLATFORM_MONITOR_STATE; GLFW_PLATFORM_MONITOR_STATE
}; };
// Cursor structure // Cursor structure
@ -461,9 +611,8 @@ struct _GLFWmonitor
struct _GLFWcursor struct _GLFWcursor
{ {
_GLFWcursor* next; _GLFWcursor* next;
// This is defined in platform.h
// This is defined in the window API's platform.h GLFW_PLATFORM_CURSOR_STATE
_GLFW_PLATFORM_CURSOR_STATE;
}; };
// Gamepad mapping element structure // Gamepad mapping element structure
@ -490,7 +639,8 @@ struct _GLFWmapping
// //
struct _GLFWjoystick struct _GLFWjoystick
{ {
GLFWbool present; GLFWbool allocated;
GLFWbool connected;
float* axes; float* axes;
int axisCount; int axisCount;
unsigned char* buttons; unsigned char* buttons;
@ -502,24 +652,108 @@ struct _GLFWjoystick
char guid[33]; char guid[33];
_GLFWmapping* mapping; _GLFWmapping* mapping;
// This is defined in the joystick API's joystick.h // This is defined in platform.h
_GLFW_PLATFORM_JOYSTICK_STATE; GLFW_PLATFORM_JOYSTICK_STATE
}; };
// Thread local storage structure // Thread local storage structure
// //
struct _GLFWtls struct _GLFWtls
{ {
// This is defined in the platform's thread.h // This is defined in platform.h
_GLFW_PLATFORM_TLS_STATE; GLFW_PLATFORM_TLS_STATE
}; };
// Mutex structure // Mutex structure
// //
struct _GLFWmutex struct _GLFWmutex
{ {
// This is defined in the platform's thread.h // This is defined in platform.h
_GLFW_PLATFORM_MUTEX_STATE; GLFW_PLATFORM_MUTEX_STATE
};
// Platform API structure
//
struct _GLFWplatform
{
int platformID;
// init
GLFWbool (*init)(void);
void (*terminate)(void);
// input
void (*getCursorPos)(_GLFWwindow*,double*,double*);
void (*setCursorPos)(_GLFWwindow*,double,double);
void (*setCursorMode)(_GLFWwindow*,int);
void (*setRawMouseMotion)(_GLFWwindow*,GLFWbool);
GLFWbool (*rawMouseMotionSupported)(void);
GLFWbool (*createCursor)(_GLFWcursor*,const GLFWimage*,int,int);
GLFWbool (*createStandardCursor)(_GLFWcursor*,int);
void (*destroyCursor)(_GLFWcursor*);
void (*setCursor)(_GLFWwindow*,_GLFWcursor*);
const char* (*getScancodeName)(int);
int (*getKeyScancode)(int);
void (*setClipboardString)(const char*);
const char* (*getClipboardString)(void);
GLFWbool (*initJoysticks)(void);
void (*terminateJoysticks)(void);
GLFWbool (*pollJoystick)(_GLFWjoystick*,int);
const char* (*getMappingName)(void);
void (*updateGamepadGUID)(char*);
// monitor
void (*freeMonitor)(_GLFWmonitor*);
void (*getMonitorPos)(_GLFWmonitor*,int*,int*);
void (*getMonitorContentScale)(_GLFWmonitor*,float*,float*);
void (*getMonitorWorkarea)(_GLFWmonitor*,int*,int*,int*,int*);
GLFWvidmode* (*getVideoModes)(_GLFWmonitor*,int*);
void (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*);
GLFWbool (*getGammaRamp)(_GLFWmonitor*,GLFWgammaramp*);
void (*setGammaRamp)(_GLFWmonitor*,const GLFWgammaramp*);
// window
GLFWbool (*createWindow)(_GLFWwindow*,const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*);
void (*destroyWindow)(_GLFWwindow*);
void (*setWindowTitle)(_GLFWwindow*,const char*);
void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*);
void (*getWindowPos)(_GLFWwindow*,int*,int*);
void (*setWindowPos)(_GLFWwindow*,int,int);
void (*getWindowSize)(_GLFWwindow*,int*,int*);
void (*setWindowSize)(_GLFWwindow*,int,int);
void (*setWindowSizeLimits)(_GLFWwindow*,int,int,int,int);
void (*setWindowAspectRatio)(_GLFWwindow*,int,int);
void (*getFramebufferSize)(_GLFWwindow*,int*,int*);
void (*getWindowFrameSize)(_GLFWwindow*,int*,int*,int*,int*);
void (*getWindowContentScale)(_GLFWwindow*,float*,float*);
void (*iconifyWindow)(_GLFWwindow*);
void (*restoreWindow)(_GLFWwindow*);
void (*maximizeWindow)(_GLFWwindow*);
void (*showWindow)(_GLFWwindow*);
void (*hideWindow)(_GLFWwindow*);
void (*requestWindowAttention)(_GLFWwindow*);
void (*focusWindow)(_GLFWwindow*);
void (*setWindowMonitor)(_GLFWwindow*,_GLFWmonitor*,int,int,int,int,int);
GLFWbool (*windowFocused)(_GLFWwindow*);
GLFWbool (*windowIconified)(_GLFWwindow*);
GLFWbool (*windowVisible)(_GLFWwindow*);
GLFWbool (*windowMaximized)(_GLFWwindow*);
GLFWbool (*windowHovered)(_GLFWwindow*);
GLFWbool (*framebufferTransparent)(_GLFWwindow*);
float (*getWindowOpacity)(_GLFWwindow*);
void (*setWindowResizable)(_GLFWwindow*,GLFWbool);
void (*setWindowDecorated)(_GLFWwindow*,GLFWbool);
void (*setWindowFloating)(_GLFWwindow*,GLFWbool);
void (*setWindowOpacity)(_GLFWwindow*,float);
void (*setWindowMousePassthrough)(_GLFWwindow*,GLFWbool);
void (*pollEvents)(void);
void (*waitEvents)(void);
void (*waitEventsTimeout)(double);
void (*postEmptyEvent)(void);
// EGL
EGLenum (*getEGLPlatform)(EGLint**);
EGLNativeDisplayType (*getEGLNativeDisplay)(void);
EGLNativeWindowType (*getEGLNativeWindow)(_GLFWwindow*);
// vulkan
void (*getRequiredInstanceExtensions)(char**);
GLFWbool (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t);
VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*);
}; };
// Library global data // Library global data
@ -527,6 +761,9 @@ struct _GLFWmutex
struct _GLFWlibrary struct _GLFWlibrary
{ {
GLFWbool initialized; GLFWbool initialized;
GLFWallocator allocator;
_GLFWplatform platform;
struct { struct {
_GLFWinitconfig init; _GLFWinitconfig init;
@ -554,30 +791,80 @@ struct _GLFWlibrary
struct { struct {
uint64_t offset; uint64_t offset;
// This is defined in the platform's time.h // This is defined in platform.h
_GLFW_PLATFORM_LIBRARY_TIMER_STATE; GLFW_PLATFORM_LIBRARY_TIMER_STATE
} timer; } timer;
struct {
EGLenum platform;
EGLDisplay display;
EGLint major, minor;
GLFWbool prefix;
GLFWbool KHR_create_context;
GLFWbool KHR_create_context_no_error;
GLFWbool KHR_gl_colorspace;
GLFWbool KHR_get_all_proc_addresses;
GLFWbool KHR_context_flush_control;
GLFWbool EXT_client_extensions;
GLFWbool EXT_platform_base;
GLFWbool EXT_platform_x11;
GLFWbool EXT_platform_wayland;
GLFWbool EXT_present_opaque;
GLFWbool ANGLE_platform_angle;
GLFWbool ANGLE_platform_angle_opengl;
GLFWbool ANGLE_platform_angle_d3d;
GLFWbool ANGLE_platform_angle_vulkan;
GLFWbool ANGLE_platform_angle_metal;
void* handle;
PFN_eglGetConfigAttrib GetConfigAttrib;
PFN_eglGetConfigs GetConfigs;
PFN_eglGetDisplay GetDisplay;
PFN_eglGetError GetError;
PFN_eglInitialize Initialize;
PFN_eglTerminate Terminate;
PFN_eglBindAPI BindAPI;
PFN_eglCreateContext CreateContext;
PFN_eglDestroySurface DestroySurface;
PFN_eglDestroyContext DestroyContext;
PFN_eglCreateWindowSurface CreateWindowSurface;
PFN_eglMakeCurrent MakeCurrent;
PFN_eglSwapBuffers SwapBuffers;
PFN_eglSwapInterval SwapInterval;
PFN_eglQueryString QueryString;
PFN_eglGetProcAddress GetProcAddress;
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC CreatePlatformWindowSurfaceEXT;
} egl;
struct {
void* handle;
PFN_OSMesaCreateContextExt CreateContextExt;
PFN_OSMesaCreateContextAttribs CreateContextAttribs;
PFN_OSMesaDestroyContext DestroyContext;
PFN_OSMesaMakeCurrent MakeCurrent;
PFN_OSMesaGetColorBuffer GetColorBuffer;
PFN_OSMesaGetDepthBuffer GetDepthBuffer;
PFN_OSMesaGetProcAddress GetProcAddress;
} osmesa;
struct { struct {
GLFWbool available; GLFWbool available;
void* handle; void* handle;
char* extensions[2]; char* extensions[2];
#if !defined(_GLFW_VULKAN_STATIC)
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr; PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
#endif
GLFWbool KHR_surface; GLFWbool KHR_surface;
#if defined(_GLFW_WIN32)
GLFWbool KHR_win32_surface; GLFWbool KHR_win32_surface;
#elif defined(_GLFW_COCOA)
GLFWbool MVK_macos_surface; GLFWbool MVK_macos_surface;
GLFWbool EXT_metal_surface; GLFWbool EXT_metal_surface;
#elif defined(_GLFW_X11)
GLFWbool KHR_xlib_surface; GLFWbool KHR_xlib_surface;
GLFWbool KHR_xcb_surface; GLFWbool KHR_xcb_surface;
#elif defined(_GLFW_WAYLAND)
GLFWbool KHR_wayland_surface; GLFWbool KHR_wayland_surface;
#endif
} vk; } vk;
struct { struct {
@ -585,16 +872,10 @@ struct _GLFWlibrary
GLFWjoystickfun joystick; GLFWjoystickfun joystick;
} callbacks; } callbacks;
// This is defined in the window API's platform.h // These are defined in platform.h
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE; GLFW_PLATFORM_LIBRARY_WINDOW_STATE
// This is defined in the context API's context.h GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE; GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
// This is defined in the platform's joystick.h
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
// This is defined in egl_context.h
_GLFWlibraryEGL egl;
// This is defined in osmesa_context.h
_GLFWlibraryOSMesa osmesa;
}; };
// Global state shared between compilation units of GLFW // Global state shared between compilation units of GLFW
@ -606,108 +887,10 @@ extern _GLFWlibrary _glfw;
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void); void _glfwPlatformInitTimer(void);
void _glfwPlatformTerminate(void);
const char* _glfwPlatformGetVersionString(void);
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwPlatformRawMouseMotionSupported(void);
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image, int xhot, int yhot);
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
const char* _glfwPlatformGetScancodeName(int scancode);
int _glfwPlatformGetKeyScancode(int key);
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor);
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale);
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPlatformSetClipboardString(const char* string);
const char* _glfwPlatformGetClipboardString(void);
GLFWbool _glfwPlatformInitJoysticks(void);
void _glfwPlatformTerminateJoysticks(void);
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
void _glfwPlatformUpdateGamepadGUID(char* guid);
uint64_t _glfwPlatformGetTimerValue(void); uint64_t _glfwPlatformGetTimerValue(void);
uint64_t _glfwPlatformGetTimerFrequency(void); uint64_t _glfwPlatformGetTimerFrequency(void);
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwPlatformDestroyWindow(_GLFWwindow* window);
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
int count, const GLFWimage* images);
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight);
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom);
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
float* xscale, float* yscale);
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
void _glfwPlatformShowWindow(_GLFWwindow* window);
void _glfwPlatformHideWindow(_GLFWwindow* window);
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
void _glfwPlatformFocusWindow(_GLFWwindow* window);
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor,
int xpos, int ypos, int width, int height,
int refreshRate);
int _glfwPlatformWindowFocused(_GLFWwindow* window);
int _glfwPlatformWindowIconified(_GLFWwindow* window);
int _glfwPlatformWindowVisible(_GLFWwindow* window);
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
int _glfwPlatformWindowHovered(_GLFWwindow* window);
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
void _glfwPlatformPollEvents(void);
void _glfwPlatformWaitEvents(void);
void _glfwPlatformWaitEventsTimeout(double timeout);
void _glfwPlatformPostEmptyEvent(void);
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs);
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void);
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window);
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily);
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface);
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls); GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
void _glfwPlatformDestroyTls(_GLFWtls* tls); void _glfwPlatformDestroyTls(_GLFWtls* tls);
void* _glfwPlatformGetTls(_GLFWtls* tls); void* _glfwPlatformGetTls(_GLFWtls* tls);
@ -718,6 +901,10 @@ void _glfwPlatformDestroyMutex(_GLFWmutex* mutex);
void _glfwPlatformLockMutex(_GLFWmutex* mutex); void _glfwPlatformLockMutex(_GLFWmutex* mutex);
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex); void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
void* _glfwPlatformLoadModule(const char* path);
void _glfwPlatformFreeModule(void* module);
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name);
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW event API ////// ////// GLFW event API //////
@ -738,7 +925,7 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
void _glfwInputKey(_GLFWwindow* window, void _glfwInputKey(_GLFWwindow* window,
int key, int scancode, int action, int mods); int key, int scancode, int action, int mods);
void _glfwInputChar(_GLFWwindow* window, void _glfwInputChar(_GLFWwindow* window,
unsigned int codepoint, int mods, GLFWbool plain); uint32_t codepoint, int mods, GLFWbool plain);
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset); void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods); void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos); void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
@ -764,6 +951,8 @@ void _glfwInputError(int code, const char* format, ...);
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWbool _glfwSelectPlatform(int platformID, _GLFWplatform* platform);
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions); GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
const _GLFWfbconfig* alternatives, const _GLFWfbconfig* alternatives,
@ -781,6 +970,7 @@ void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size);
void _glfwFreeGammaArrays(GLFWgammaramp* ramp); void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
void _glfwInitGamepadMappings(void);
_GLFWjoystick* _glfwAllocJoystick(const char* name, _GLFWjoystick* _glfwAllocJoystick(const char* name,
const char* guid, const char* guid,
int axisCount, int axisCount,
@ -789,11 +979,38 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
void _glfwFreeJoystick(_GLFWjoystick* js); void _glfwFreeJoystick(_GLFWjoystick* js);
void _glfwCenterCursorInContentArea(_GLFWwindow* window); void _glfwCenterCursorInContentArea(_GLFWwindow* window);
GLFWbool _glfwInitEGL(void);
void _glfwTerminateEGL(void);
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);
#endif /*_GLFW_X11*/
GLFWbool _glfwInitOSMesa(void);
void _glfwTerminateOSMesa(void);
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
GLFWbool _glfwInitVulkan(int mode); GLFWbool _glfwInitVulkan(int mode);
void _glfwTerminateVulkan(void); void _glfwTerminateVulkan(void);
const char* _glfwGetVulkanResultString(VkResult result); const char* _glfwGetVulkanResultString(VkResult result);
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint);
char** _glfwParseUriList(char* text, int* count);
char* _glfw_strdup(const char* source); char* _glfw_strdup(const char* source);
int _glfw_min(int a, int b);
int _glfw_max(int a, int b);
float _glfw_fminf(float a, float b); float _glfw_fminf(float a, float b);
float _glfw_fmaxf(float a, float b); float _glfw_fmaxf(float a, float b);
void* _glfw_calloc(size_t count, size_t size);
void* _glfw_realloc(void* pointer, size_t size);
void _glfw_free(void* pointer);

View file

@ -128,7 +128,7 @@ static GLFWbool openJoystickDevice(const char* path)
{ {
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (!_glfw.joysticks[jid].present) if (!_glfw.joysticks[jid].connected)
continue; continue;
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0) if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
return GLFW_FALSE; return GLFW_FALSE;
@ -157,7 +157,7 @@ static GLFWbool openJoystickDevice(const char* path)
} }
// Ensure this device supports the events expected of a joystick // Ensure this device supports the events expected of a joystick
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits)) if (!isBitSet(EV_ABS, evBits))
{ {
close(linjs.fd); close(linjs.fd);
return GLFW_FALSE; return GLFW_FALSE;
@ -245,9 +245,9 @@ static GLFWbool openJoystickDevice(const char* path)
// //
static void closeJoystick(_GLFWjoystick* js) static void closeJoystick(_GLFWjoystick* js)
{ {
_glfwInputJoystick(js, GLFW_DISCONNECTED);
close(js->linjs.fd); close(js->linjs.fd);
_glfwFreeJoystick(js); _glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
} }
// Lexically compare joysticks by name; used by qsort // Lexically compare joysticks by name; used by qsort
@ -307,7 +307,7 @@ void _glfwDetectJoystickConnectionLinux(void)
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformInitJoysticks(void) GLFWbool _glfwInitJoysticksLinux(void)
{ {
const char* dirname = "/dev/input"; const char* dirname = "/dev/input";
@ -361,14 +361,12 @@ GLFWbool _glfwPlatformInitJoysticks(void)
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformTerminateJoysticks(void) void _glfwTerminateJoysticksLinux(void)
{ {
int jid; for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
_GLFWjoystick* js = _glfw.joysticks + jid; _GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
closeJoystick(js); closeJoystick(js);
} }
@ -382,7 +380,7 @@ void _glfwPlatformTerminateJoysticks(void)
} }
} }
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode)
{ {
// Read all queued events (non-blocking) // Read all queued events (non-blocking)
for (;;) for (;;)
@ -419,10 +417,15 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
handleAbsEvent(js, e.code, e.value); handleAbsEvent(js, e.code, e.value);
} }
return js->present; return js->connected;
} }
void _glfwPlatformUpdateGamepadGUID(char* guid) const char* _glfwGetMappingNameLinux(void)
{
return "Linux";
}
void _glfwUpdateGamepadGUIDLinux(char* guid)
{ {
} }

View file

@ -28,10 +28,10 @@
#include <linux/limits.h> #include <linux/limits.h>
#include <regex.h> #include <regex.h>
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs #define GLFW_LINUX_JOYSTICK_STATE _GLFWjoystickLinux linjs;
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs #define GLFW_LINUX_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs;
#define _GLFW_PLATFORM_MAPPING_NAME "Linux" #define GLFW_BUILD_LINUX_MAPPINGS
// Linux-specific joystick data // Linux-specific joystick data
// //
@ -57,3 +57,9 @@ typedef struct _GLFWlibraryLinux
void _glfwDetectJoystickConnectionLinux(void); void _glfwDetectJoystickConnectionLinux(void);
GLFWbool _glfwInitJoysticksLinux(void);
void _glfwTerminateJoysticksLinux(void);
GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameLinux(void);
void _glfwUpdateGamepadGUIDLinux(char* guid);

File diff suppressed because it is too large Load diff

View file

@ -74,13 +74,13 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
if (monitor->modes) if (monitor->modes)
return GLFW_TRUE; return GLFW_TRUE;
modes = _glfwPlatformGetVideoModes(monitor, &modeCount); modes = _glfw.platform.getVideoModes(monitor, &modeCount);
if (!modes) if (!modes)
return GLFW_FALSE; return GLFW_FALSE;
qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes); qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
free(monitor->modes); _glfw_free(monitor->modes);
monitor->modes = modes; monitor->modes = modes;
monitor->modeCount = modeCount; monitor->modeCount = modeCount;
@ -96,11 +96,16 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
// //
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement) void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
{ {
assert(monitor != NULL);
assert(action == GLFW_CONNECTED || action == GLFW_DISCONNECTED);
assert(placement == _GLFW_INSERT_FIRST || placement == _GLFW_INSERT_LAST);
if (action == GLFW_CONNECTED) if (action == GLFW_CONNECTED)
{ {
_glfw.monitorCount++; _glfw.monitorCount++;
_glfw.monitors = _glfw.monitors =
realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount); _glfw_realloc(_glfw.monitors,
sizeof(_GLFWmonitor*) * _glfw.monitorCount);
if (placement == _GLFW_INSERT_FIRST) if (placement == _GLFW_INSERT_FIRST)
{ {
@ -122,10 +127,10 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
if (window->monitor == monitor) if (window->monitor == monitor)
{ {
int width, height, xoff, yoff; int width, height, xoff, yoff;
_glfwPlatformGetWindowSize(window, &width, &height); _glfw.platform.getWindowSize(window, &width, &height);
_glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0); _glfw.platform.setWindowMonitor(window, NULL, 0, 0, width, height, 0);
_glfwPlatformGetWindowFrameSize(window, &xoff, &yoff, NULL, NULL); _glfw.platform.getWindowFrameSize(window, &xoff, &yoff, NULL, NULL);
_glfwPlatformSetWindowPos(window, xoff, yoff); _glfw.platform.setWindowPos(window, xoff, yoff);
} }
} }
@ -154,6 +159,7 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
// //
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window) void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
{ {
assert(monitor != NULL);
monitor->window = window; monitor->window = window;
} }
@ -166,7 +172,7 @@ void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
// //
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM) _GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM)
{ {
_GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor)); _GLFWmonitor* monitor = _glfw_calloc(1, sizeof(_GLFWmonitor));
monitor->widthMM = widthMM; monitor->widthMM = widthMM;
monitor->heightMM = heightMM; monitor->heightMM = heightMM;
@ -182,22 +188,22 @@ void _glfwFreeMonitor(_GLFWmonitor* monitor)
if (monitor == NULL) if (monitor == NULL)
return; return;
_glfwPlatformFreeMonitor(monitor); _glfw.platform.freeMonitor(monitor);
_glfwFreeGammaArrays(&monitor->originalRamp); _glfwFreeGammaArrays(&monitor->originalRamp);
_glfwFreeGammaArrays(&monitor->currentRamp); _glfwFreeGammaArrays(&monitor->currentRamp);
free(monitor->modes); _glfw_free(monitor->modes);
free(monitor); _glfw_free(monitor);
} }
// Allocates red, green and blue value arrays of the specified size // Allocates red, green and blue value arrays of the specified size
// //
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
{ {
ramp->red = calloc(size, sizeof(unsigned short)); ramp->red = _glfw_calloc(size, sizeof(unsigned short));
ramp->green = calloc(size, sizeof(unsigned short)); ramp->green = _glfw_calloc(size, sizeof(unsigned short));
ramp->blue = calloc(size, sizeof(unsigned short)); ramp->blue = _glfw_calloc(size, sizeof(unsigned short));
ramp->size = size; ramp->size = size;
} }
@ -205,9 +211,9 @@ void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
// //
void _glfwFreeGammaArrays(GLFWgammaramp* ramp) void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
{ {
free(ramp->red); _glfw_free(ramp->red);
free(ramp->green); _glfw_free(ramp->green);
free(ramp->blue); _glfw_free(ramp->blue);
memset(ramp, 0, sizeof(GLFWgammaramp)); memset(ramp, 0, sizeof(GLFWgammaramp));
} }
@ -331,7 +337,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetMonitorPos(monitor, xpos, ypos); _glfw.platform.getMonitorPos(monitor, xpos, ypos);
} }
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
@ -352,7 +358,7 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height); _glfw.platform.getMonitorWorkarea(monitor, xpos, ypos, width, height);
} }
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
@ -385,7 +391,7 @@ GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle,
*yscale = 0.f; *yscale = 0.f;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetMonitorContentScale(monitor, xscale, yscale); _glfw.platform.getMonitorContentScale(monitor, xscale, yscale);
} }
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
@ -418,7 +424,7 @@ GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle)
GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(_glfw.callbacks.monitor, cbfun); _GLFW_SWAP(GLFWmonitorfun, _glfw.callbacks.monitor, cbfun);
return cbfun; return cbfun;
} }
@ -446,7 +452,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwPlatformGetVideoMode(monitor, &monitor->currentMode); _glfw.platform.getVideoMode(monitor, &monitor->currentMode);
return &monitor->currentMode; return &monitor->currentMode;
} }
@ -472,7 +478,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
if (!original) if (!original)
return; return;
values = calloc(original->size, sizeof(unsigned short)); values = _glfw_calloc(original->size, sizeof(unsigned short));
for (i = 0; i < original->size; i++) for (i = 0; i < original->size; i++)
{ {
@ -494,7 +500,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
ramp.size = original->size; ramp.size = original->size;
glfwSetGammaRamp(handle, &ramp); glfwSetGammaRamp(handle, &ramp);
free(values); _glfw_free(values);
} }
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
@ -505,7 +511,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwFreeGammaArrays(&monitor->currentRamp); _glfwFreeGammaArrays(&monitor->currentRamp);
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp)) if (!_glfw.platform.getGammaRamp(monitor, &monitor->currentRamp))
return NULL; return NULL;
return &monitor->currentRamp; return &monitor->currentRamp;
@ -521,6 +527,8 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
assert(ramp->green != NULL); assert(ramp->green != NULL);
assert(ramp->blue != NULL); assert(ramp->blue != NULL);
_GLFW_REQUIRE_INIT();
if (ramp->size <= 0) if (ramp->size <= 0)
{ {
_glfwInputError(GLFW_INVALID_VALUE, _glfwInputError(GLFW_INVALID_VALUE,
@ -529,14 +537,12 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
return; return;
} }
_GLFW_REQUIRE_INIT();
if (!monitor->originalRamp.size) if (!monitor->originalRamp.size)
{ {
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp)) if (!_glfw.platform.getGammaRamp(monitor, &monitor->originalRamp))
return; return;
} }
_glfwPlatformSetGammaRamp(monitor, ramp); _glfw.platform.setGammaRamp(monitor, ramp);
} }

View file

@ -1,66 +0,0 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// NOTE: Many Cocoa enum values have been renamed and we need to build across
// SDK versions where one is unavailable or the other deprecated
// We use the newer names in code and these macros to handle compatibility
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
#endif
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
#include <stdatomic.h>
// NSGL-specific per-context data
//
typedef struct _GLFWcontextNSGL
{
id pixelFormat;
id object;
} _GLFWcontextNSGL;
// NSGL-specific global data
//
typedef struct _GLFWlibraryNSGL
{
// dlopen handle for OpenGL.framework (for glfwGetProcAddress)
CFBundleRef framework;
} _GLFWlibraryNSGL;
GLFWbool _glfwInitNSGL(void);
void _glfwTerminateNSGL(void);
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window);

View file

@ -188,45 +188,45 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but // No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
// are not a hard constraint, so ignore and continue // are not a hard constraint, so ignore and continue
#define addAttrib(a) \ #define ADD_ATTRIB(a) \
{ \ { \
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \ attribs[index++] = a; \
} }
#define setAttrib(a, v) { addAttrib(a); addAttrib(v); } #define SET_ATTRIB(a, v) { ADD_ATTRIB(a); ADD_ATTRIB(v); }
NSOpenGLPixelFormatAttribute attribs[40]; NSOpenGLPixelFormatAttribute attribs[40];
int index = 0; int index = 0;
addAttrib(NSOpenGLPFAAccelerated); ADD_ATTRIB(NSOpenGLPFAAccelerated);
addAttrib(NSOpenGLPFAClosestPolicy); ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
if (ctxconfig->nsgl.offline) if (ctxconfig->nsgl.offline)
{ {
addAttrib(NSOpenGLPFAAllowOfflineRenderers); ADD_ATTRIB(NSOpenGLPFAAllowOfflineRenderers);
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in // NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
// Info.plist for unbundled applications // Info.plist for unbundled applications
// HACK: This assumes that NSOpenGLPixelFormat will remain // HACK: This assumes that NSOpenGLPixelFormat will remain
// a straightforward wrapper of its CGL counterpart // a straightforward wrapper of its CGL counterpart
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching); ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching);
} }
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
if (ctxconfig->major >= 4) if (ctxconfig->major >= 4)
{ {
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core); SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
} }
else else
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
if (ctxconfig->major >= 3) if (ctxconfig->major >= 3)
{ {
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
} }
if (ctxconfig->major <= 2) if (ctxconfig->major <= 2)
{ {
if (fbconfig->auxBuffers != GLFW_DONT_CARE) if (fbconfig->auxBuffers != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); SET_ATTRIB(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->accumRedBits != GLFW_DONT_CARE && if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
fbconfig->accumGreenBits != GLFW_DONT_CARE && fbconfig->accumGreenBits != GLFW_DONT_CARE &&
@ -238,7 +238,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
fbconfig->accumBlueBits + fbconfig->accumBlueBits +
fbconfig->accumAlphaBits; fbconfig->accumAlphaBits;
setAttrib(NSOpenGLPFAAccumSize, accumBits); SET_ATTRIB(NSOpenGLPFAAccumSize, accumBits);
} }
} }
@ -256,17 +256,17 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
else if (colorBits < 15) else if (colorBits < 15)
colorBits = 15; colorBits = 15;
setAttrib(NSOpenGLPFAColorSize, colorBits); SET_ATTRIB(NSOpenGLPFAColorSize, colorBits);
} }
if (fbconfig->alphaBits != GLFW_DONT_CARE) if (fbconfig->alphaBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); SET_ATTRIB(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
if (fbconfig->depthBits != GLFW_DONT_CARE) if (fbconfig->depthBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits); SET_ATTRIB(NSOpenGLPFADepthSize, fbconfig->depthBits);
if (fbconfig->stencilBits != GLFW_DONT_CARE) if (fbconfig->stencilBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits); SET_ATTRIB(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
if (fbconfig->stereo) if (fbconfig->stereo)
{ {
@ -275,33 +275,33 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
"NSGL: Stereo rendering is deprecated"); "NSGL: Stereo rendering is deprecated");
return GLFW_FALSE; return GLFW_FALSE;
#else #else
addAttrib(NSOpenGLPFAStereo); ADD_ATTRIB(NSOpenGLPFAStereo);
#endif #endif
} }
if (fbconfig->doublebuffer) if (fbconfig->doublebuffer)
addAttrib(NSOpenGLPFADoubleBuffer); ADD_ATTRIB(NSOpenGLPFADoubleBuffer);
if (fbconfig->samples != GLFW_DONT_CARE) if (fbconfig->samples != GLFW_DONT_CARE)
{ {
if (fbconfig->samples == 0) if (fbconfig->samples == 0)
{ {
setAttrib(NSOpenGLPFASampleBuffers, 0); SET_ATTRIB(NSOpenGLPFASampleBuffers, 0);
} }
else else
{ {
setAttrib(NSOpenGLPFASampleBuffers, 1); SET_ATTRIB(NSOpenGLPFASampleBuffers, 1);
setAttrib(NSOpenGLPFASamples, fbconfig->samples); SET_ATTRIB(NSOpenGLPFASamples, fbconfig->samples);
} }
} }
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// framebuffer, so there's no need (and no way) to request it // framebuffer, so there's no need (and no way) to request it
addAttrib(0); ADD_ATTRIB(0);
#undef addAttrib #undef ADD_ATTRIB
#undef setAttrib #undef SET_ATTRIB
window->context.nsgl.pixelFormat = window->context.nsgl.pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
@ -358,7 +358,14 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil); _GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (window->context.client == GLFW_NO_API) if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
"NSGL: Platform not initialized");
return nil;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return nil; return nil;

View file

@ -36,22 +36,98 @@
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void) GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
{ {
_glfwInitTimerPOSIX(); const _GLFWplatform null =
_glfwPollMonitorsNull(); {
GLFW_PLATFORM_NULL,
_glfwInitNull,
_glfwTerminateNull,
_glfwGetCursorPosNull,
_glfwSetCursorPosNull,
_glfwSetCursorModeNull,
_glfwSetRawMouseMotionNull,
_glfwRawMouseMotionSupportedNull,
_glfwCreateCursorNull,
_glfwCreateStandardCursorNull,
_glfwDestroyCursorNull,
_glfwSetCursorNull,
_glfwGetScancodeNameNull,
_glfwGetKeyScancodeNull,
_glfwSetClipboardStringNull,
_glfwGetClipboardStringNull,
_glfwInitJoysticksNull,
_glfwTerminateJoysticksNull,
_glfwPollJoystickNull,
_glfwGetMappingNameNull,
_glfwUpdateGamepadGUIDNull,
_glfwFreeMonitorNull,
_glfwGetMonitorPosNull,
_glfwGetMonitorContentScaleNull,
_glfwGetMonitorWorkareaNull,
_glfwGetVideoModesNull,
_glfwGetVideoModeNull,
_glfwGetGammaRampNull,
_glfwSetGammaRampNull,
_glfwCreateWindowNull,
_glfwDestroyWindowNull,
_glfwSetWindowTitleNull,
_glfwSetWindowIconNull,
_glfwGetWindowPosNull,
_glfwSetWindowPosNull,
_glfwGetWindowSizeNull,
_glfwSetWindowSizeNull,
_glfwSetWindowSizeLimitsNull,
_glfwSetWindowAspectRatioNull,
_glfwGetFramebufferSizeNull,
_glfwGetWindowFrameSizeNull,
_glfwGetWindowContentScaleNull,
_glfwIconifyWindowNull,
_glfwRestoreWindowNull,
_glfwMaximizeWindowNull,
_glfwShowWindowNull,
_glfwHideWindowNull,
_glfwRequestWindowAttentionNull,
_glfwFocusWindowNull,
_glfwSetWindowMonitorNull,
_glfwWindowFocusedNull,
_glfwWindowIconifiedNull,
_glfwWindowVisibleNull,
_glfwWindowMaximizedNull,
_glfwWindowHoveredNull,
_glfwFramebufferTransparentNull,
_glfwGetWindowOpacityNull,
_glfwSetWindowResizableNull,
_glfwSetWindowDecoratedNull,
_glfwSetWindowFloatingNull,
_glfwSetWindowOpacityNull,
_glfwSetWindowMousePassthroughNull,
_glfwPollEventsNull,
_glfwWaitEventsNull,
_glfwWaitEventsTimeoutNull,
_glfwPostEmptyEventNull,
_glfwGetEGLPlatformNull,
_glfwGetEGLNativeDisplayNull,
_glfwGetEGLNativeWindowNull,
_glfwGetRequiredInstanceExtensionsNull,
_glfwGetPhysicalDevicePresentationSupportNull,
_glfwCreateWindowSurfaceNull,
};
*platform = null;
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformTerminate(void) int _glfwInitNull(void)
{
_glfwPollMonitorsNull();
return GLFW_TRUE;
}
void _glfwTerminateNull(void)
{ {
free(_glfw.null.clipboardString); free(_glfw.null.clipboardString);
_glfwTerminateOSMesa(); _glfwTerminateOSMesa();
} _glfwTerminateEGL();
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " null OSMesa";
} }

View file

@ -33,21 +33,26 @@
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformInitJoysticks(void) GLFWbool _glfwInitJoysticksNull(void)
{ {
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformTerminateJoysticks(void) void _glfwTerminateJoysticksNull(void)
{ {
} }
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode)
{ {
return GLFW_FALSE; return GLFW_FALSE;
} }
void _glfwPlatformUpdateGamepadGUID(char* guid) const char* _glfwGetMappingNameNull(void)
{
return "";
}
void _glfwUpdateGamepadGUIDNull(char* guid)
{ {
} }

View file

@ -24,8 +24,9 @@
// //
//======================================================================== //========================================================================
#define _GLFW_PLATFORM_JOYSTICK_STATE struct { int dummyJoystick; } GLFWbool _glfwInitJoysticksNull(void);
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; } void _glfwTerminateJoysticksNull(void);
GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode);
#define _GLFW_PLATFORM_MAPPING_NAME "" const char* _glfwGetMappingNameNull(void);
void _glfwUpdateGamepadGUIDNull(char* guid);

View file

@ -65,12 +65,12 @@ void _glfwPollMonitorsNull(void)
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) void _glfwFreeMonitorNull(_GLFWmonitor* monitor)
{ {
_glfwFreeGammaArrays(&monitor->null.ramp); _glfwFreeGammaArrays(&monitor->null.ramp);
} }
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) void _glfwGetMonitorPosNull(_GLFWmonitor* monitor, int* xpos, int* ypos)
{ {
if (xpos) if (xpos)
*xpos = 0; *xpos = 0;
@ -78,8 +78,8 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
*ypos = 0; *ypos = 0;
} }
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
if (xscale) if (xscale)
*xscale = 1.f; *xscale = 1.f;
@ -87,9 +87,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = 1.f; *yscale = 1.f;
} }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor,
int* xpos, int* ypos, int* xpos, int* ypos,
int* width, int* height) int* width, int* height)
{ {
const GLFWvidmode mode = getVideoMode(); const GLFWvidmode mode = getVideoMode();
@ -103,26 +103,28 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
*height = mode.height - 10; *height = mode.height - 10;
} }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found)
{ {
GLFWvidmode* mode = calloc(1, sizeof(GLFWvidmode)); GLFWvidmode* mode = _glfw_calloc(1, sizeof(GLFWvidmode));
*mode = getVideoMode(); *mode = getVideoMode();
*found = 1; *found = 1;
return mode; return mode;
} }
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) void _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode)
{ {
*mode = getVideoMode(); *mode = getVideoMode();
} }
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
if (!monitor->null.ramp.size) if (!monitor->null.ramp.size)
{ {
unsigned int i;
_glfwAllocGammaArrays(&monitor->null.ramp, 256); _glfwAllocGammaArrays(&monitor->null.ramp, 256);
for (unsigned int i = 0; i < monitor->null.ramp.size; i++) for (i = 0; i < monitor->null.ramp.size; i++)
{ {
const float gamma = 2.2f; const float gamma = 2.2f;
float value; float value;
@ -143,7 +145,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{ {
if (monitor->null.ramp.size != ramp->size) if (monitor->null.ramp.size != ramp->size)
{ {

View file

@ -25,29 +25,14 @@
// //
//======================================================================== //========================================================================
#include <dlfcn.h> #define GLFW_NULL_WINDOW_STATE _GLFWwindowNull null;
#define GLFW_NULL_LIBRARY_WINDOW_STATE _GLFWlibraryNull null;
#define GLFW_NULL_MONITOR_STATE _GLFWmonitorNull null;
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null #define GLFW_NULL_CONTEXT_STATE
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNull null #define GLFW_NULL_CURSOR_STATE
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNull null #define GLFW_NULL_LIBRARY_CONTEXT_STATE
#define _GLFW_PLATFORM_CONTEXT_STATE struct { int dummyContext; }
#define _GLFW_PLATFORM_CURSOR_STATE struct { int dummyCursor; }
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; }
#include "posix_time.h"
#include "posix_thread.h"
#include "null_joystick.h"
#if defined(_GLFW_WIN32)
#define _glfw_dlopen(name) LoadLibraryA(name)
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
#else
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#endif
// Null-specific per-window data // Null-specific per-window data
// //
@ -87,3 +72,78 @@ typedef struct _GLFWlibraryNull
void _glfwPollMonitorsNull(void); void _glfwPollMonitorsNull(void);
GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform);
int _glfwInitNull(void);
void _glfwTerminateNull(void);
void _glfwFreeMonitorNull(_GLFWmonitor* monitor);
void _glfwGetMonitorPosNull(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found);
void _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowNull(_GLFWwindow* window);
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwSetWindowMonitorNull(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeNull(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsNull(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioNull(_GLFWwindow* window, int n, int d);
void _glfwGetFramebufferSizeNull(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeNull(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleNull(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowNull(_GLFWwindow* window);
void _glfwRestoreWindowNull(_GLFWwindow* window);
void _glfwMaximizeWindowNull(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedNull(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredNull(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentNull(_GLFWwindow* window);
void _glfwSetWindowResizableNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityNull(_GLFWwindow* window);
void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity);
void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedNull(void);
void _glfwShowWindowNull(_GLFWwindow* window);
void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
void _glfwHideWindowNull(_GLFWwindow* window);
void _glfwFocusWindowNull(_GLFWwindow* window);
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window);
void _glfwPollEventsNull(void);
void _glfwWaitEventsNull(void);
void _glfwWaitEventsTimeoutNull(double timeout);
void _glfwPostEmptyEventNull(void);
void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y);
void _glfwSetCursorModeNull(_GLFWwindow* window, int mode);
GLFWbool _glfwCreateCursorNull(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorNull(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorNull(_GLFWcursor* cursor);
void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringNull(const char* string);
const char* _glfwGetClipboardStringNull(void);
const char* _glfwGetScancodeNameNull(int scancode);
int _glfwGetKeyScancodeNull(int key);
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void);
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsNull(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwPollMonitorsNull(void);

View file

@ -39,24 +39,24 @@ static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
*height = (int) (*width / ratio); *height = (int) (*width / ratio);
} }
if (window->minwidth != GLFW_DONT_CARE && *width < window->minwidth) if (window->minwidth != GLFW_DONT_CARE)
*width = window->minwidth; *width = _glfw_max(*width, window->minwidth);
else if (window->maxwidth != GLFW_DONT_CARE && *width > window->maxwidth) else if (window->maxwidth != GLFW_DONT_CARE)
*width = window->maxwidth; *width = _glfw_min(*width, window->maxwidth);
if (window->minheight != GLFW_DONT_CARE && *height < window->minheight) if (window->minheight != GLFW_DONT_CARE)
*height = window->minheight; *height = _glfw_min(*height, window->minheight);
else if (window->maxheight != GLFW_DONT_CARE && *height > window->maxheight) else if (window->maxheight != GLFW_DONT_CARE)
*height = window->maxheight; *height = _glfw_max(*height, window->maxheight);
} }
static void fitToMonitor(_GLFWwindow* window) static void fitToMonitor(_GLFWwindow* window)
{ {
GLFWvidmode mode; GLFWvidmode mode;
_glfwPlatformGetVideoMode(window->monitor, &mode); _glfwGetVideoModeNull(window->monitor, &mode);
_glfwPlatformGetMonitorPos(window->monitor, _glfwGetMonitorPosNull(window->monitor,
&window->null.xpos, &window->null.xpos,
&window->null.ypos); &window->null.ypos);
window->null.width = mode.width; window->null.width = mode.width;
window->null.height = mode.height; window->null.height = mode.height;
} }
@ -82,8 +82,17 @@ static int createNativeWindow(_GLFWwindow* window,
fitToMonitor(window); fitToMonitor(window);
else else
{ {
window->null.xpos = 17; if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION)
window->null.ypos = 17; {
window->null.xpos = 17;
window->null.ypos = 17;
}
else
{
window->null.xpos = wndconfig->xpos;
window->null.ypos = wndconfig->ypos;
}
window->null.width = wndconfig->width; window->null.width = wndconfig->width;
window->null.height = wndconfig->height; window->null.height = wndconfig->height;
} }
@ -103,10 +112,10 @@ static int createNativeWindow(_GLFWwindow* window,
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int _glfwPlatformCreateWindow(_GLFWwindow* window, GLFWbool _glfwCreateWindowNull(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig, const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
if (!createNativeWindow(window, wndconfig, fbconfig)) if (!createNativeWindow(window, wndconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
@ -121,24 +130,44 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
else else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available"); if (!_glfwInitEGL())
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
} }
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE;
} }
if (wndconfig->mousePassthrough)
_glfwSetWindowMousePassthroughNull(window, GLFW_TRUE);
if (window->monitor) if (window->monitor)
{ {
_glfwPlatformShowWindow(window); _glfwShowWindowNull(window);
_glfwPlatformFocusWindow(window); _glfwFocusWindowNull(window);
acquireMonitor(window); acquireMonitor(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig->visible)
{
_glfwShowWindowNull(window);
if (wndconfig->focused)
_glfwFocusWindowNull(window);
}
} }
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformDestroyWindow(_GLFWwindow* window) void _glfwDestroyWindowNull(_GLFWwindow* window)
{ {
if (window->monitor) if (window->monitor)
releaseMonitor(window); releaseMonitor(window);
@ -150,27 +179,26 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->context.destroy(window); window->context.destroy(window);
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title)
{ {
} }
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images)
const GLFWimage* images)
{ {
} }
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, void _glfwSetWindowMonitorNull(_GLFWwindow* window,
_GLFWmonitor* monitor, _GLFWmonitor* monitor,
int xpos, int ypos, int xpos, int ypos,
int width, int height, int width, int height,
int refreshRate) int refreshRate)
{ {
if (window->monitor == monitor) if (window->monitor == monitor)
{ {
if (!monitor) if (!monitor)
{ {
_glfwPlatformSetWindowPos(window, xpos, ypos); _glfwSetWindowPosNull(window, xpos, ypos);
_glfwPlatformSetWindowSize(window, width, height); _glfwSetWindowSizeNull(window, width, height);
} }
return; return;
@ -189,12 +217,12 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
} }
else else
{ {
_glfwPlatformSetWindowPos(window, xpos, ypos); _glfwSetWindowPosNull(window, xpos, ypos);
_glfwPlatformSetWindowSize(window, width, height); _glfwSetWindowSizeNull(window, width, height);
} }
} }
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos)
{ {
if (xpos) if (xpos)
*xpos = window->null.xpos; *xpos = window->null.xpos;
@ -202,7 +230,7 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
*ypos = window->null.ypos; *ypos = window->null.ypos;
} }
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos)
{ {
if (window->monitor) if (window->monitor)
return; return;
@ -215,7 +243,7 @@ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
} }
} }
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) void _glfwGetWindowSizeNull(_GLFWwindow* window, int* width, int* height)
{ {
if (width) if (width)
*width = window->null.width; *width = window->null.width;
@ -223,7 +251,7 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
*height = window->null.height; *height = window->null.height;
} }
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height)
{ {
if (window->monitor) if (window->monitor)
return; return;
@ -237,25 +265,25 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
} }
} }
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, void _glfwSetWindowSizeLimitsNull(_GLFWwindow* window,
int minwidth, int minheight, int minwidth, int minheight,
int maxwidth, int maxheight) int maxwidth, int maxheight)
{ {
int width = window->null.width; int width = window->null.width;
int height = window->null.height; int height = window->null.height;
applySizeLimits(window, &width, &height); applySizeLimits(window, &width, &height);
_glfwPlatformSetWindowSize(window, width, height); _glfwSetWindowSizeNull(window, width, height);
} }
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d) void _glfwSetWindowAspectRatioNull(_GLFWwindow* window, int n, int d)
{ {
int width = window->null.width; int width = window->null.width;
int height = window->null.height; int height = window->null.height;
applySizeLimits(window, &width, &height); applySizeLimits(window, &width, &height);
_glfwPlatformSetWindowSize(window, width, height); _glfwSetWindowSizeNull(window, width, height);
} }
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) void _glfwGetFramebufferSizeNull(_GLFWwindow* window, int* width, int* height)
{ {
if (width) if (width)
*width = window->null.width; *width = window->null.width;
@ -263,9 +291,9 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* heigh
*height = window->null.height; *height = window->null.height;
} }
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, void _glfwGetWindowFrameSizeNull(_GLFWwindow* window,
int* left, int* top, int* left, int* top,
int* right, int* bottom) int* right, int* bottom)
{ {
if (window->null.decorated && !window->monitor) if (window->null.decorated && !window->monitor)
{ {
@ -291,8 +319,7 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
} }
} }
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, void _glfwGetWindowContentScaleNull(_GLFWwindow* window, float* xscale, float* yscale)
float* xscale, float* yscale)
{ {
if (xscale) if (xscale)
*xscale = 1.f; *xscale = 1.f;
@ -300,7 +327,7 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
*yscale = 1.f; *yscale = 1.f;
} }
void _glfwPlatformIconifyWindow(_GLFWwindow* window) void _glfwIconifyWindowNull(_GLFWwindow* window)
{ {
if (_glfw.null.focusedWindow == window) if (_glfw.null.focusedWindow == window)
{ {
@ -318,7 +345,7 @@ void _glfwPlatformIconifyWindow(_GLFWwindow* window)
} }
} }
void _glfwPlatformRestoreWindow(_GLFWwindow* window) void _glfwRestoreWindowNull(_GLFWwindow* window)
{ {
if (window->null.iconified) if (window->null.iconified)
{ {
@ -335,7 +362,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
} }
} }
void _glfwPlatformMaximizeWindow(_GLFWwindow* window) void _glfwMaximizeWindowNull(_GLFWwindow* window)
{ {
if (!window->null.maximized) if (!window->null.maximized)
{ {
@ -344,12 +371,12 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
} }
} }
int _glfwPlatformWindowMaximized(_GLFWwindow* window) GLFWbool _glfwWindowMaximizedNull(_GLFWwindow* window)
{ {
return window->null.maximized; return window->null.maximized;
} }
int _glfwPlatformWindowHovered(_GLFWwindow* window) GLFWbool _glfwWindowHoveredNull(_GLFWwindow* window)
{ {
return _glfw.null.xcursor >= window->null.xpos && return _glfw.null.xcursor >= window->null.xpos &&
_glfw.null.ycursor >= window->null.ypos && _glfw.null.ycursor >= window->null.ypos &&
@ -357,59 +384,59 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window)
_glfw.null.ycursor <= window->null.ypos + window->null.height - 1; _glfw.null.ycursor <= window->null.ypos + window->null.height - 1;
} }
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) GLFWbool _glfwFramebufferTransparentNull(_GLFWwindow* window)
{ {
return window->null.transparent; return window->null.transparent;
} }
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowResizableNull(_GLFWwindow* window, GLFWbool enabled)
{ {
window->null.resizable = enabled; window->null.resizable = enabled;
} }
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled)
{ {
window->null.decorated = enabled; window->null.decorated = enabled;
} }
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled)
{ {
window->null.floating = enabled; window->null.floating = enabled;
} }
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled) void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled)
{ {
} }
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) float _glfwGetWindowOpacityNull(_GLFWwindow* window)
{ {
return window->null.opacity; return window->null.opacity;
} }
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity)
{ {
window->null.opacity = opacity; window->null.opacity = opacity;
} }
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled)
{ {
} }
GLFWbool _glfwPlatformRawMouseMotionSupported(void) GLFWbool _glfwRawMouseMotionSupportedNull(void)
{ {
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwShowWindowNull(_GLFWwindow* window)
{ {
window->null.visible = GLFW_TRUE; window->null.visible = GLFW_TRUE;
} }
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) void _glfwRequestWindowAttentionNull(_GLFWwindow* window)
{ {
} }
void _glfwPlatformHideWindow(_GLFWwindow* window) void _glfwHideWindowNull(_GLFWwindow* window)
{ {
if (_glfw.null.focusedWindow == window) if (_glfw.null.focusedWindow == window)
{ {
@ -420,59 +447,61 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
window->null.visible = GLFW_FALSE; window->null.visible = GLFW_FALSE;
} }
void _glfwPlatformFocusWindow(_GLFWwindow* window) void _glfwFocusWindowNull(_GLFWwindow* window)
{ {
_GLFWwindow* previous;
if (_glfw.null.focusedWindow == window) if (_glfw.null.focusedWindow == window)
return; return;
if (!window->null.visible) if (!window->null.visible)
return; return;
_GLFWwindow* previous = _glfw.null.focusedWindow; previous = _glfw.null.focusedWindow;
_glfw.null.focusedWindow = window; _glfw.null.focusedWindow = window;
if (previous) if (previous)
{ {
_glfwInputWindowFocus(previous, GLFW_FALSE); _glfwInputWindowFocus(previous, GLFW_FALSE);
if (previous->monitor && previous->autoIconify) if (previous->monitor && previous->autoIconify)
_glfwPlatformIconifyWindow(previous); _glfwIconifyWindowNull(previous);
} }
_glfwInputWindowFocus(window, GLFW_TRUE); _glfwInputWindowFocus(window, GLFW_TRUE);
} }
int _glfwPlatformWindowFocused(_GLFWwindow* window) GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window)
{ {
return _glfw.null.focusedWindow == window; return _glfw.null.focusedWindow == window;
} }
int _glfwPlatformWindowIconified(_GLFWwindow* window) GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window)
{ {
return window->null.iconified; return window->null.iconified;
} }
int _glfwPlatformWindowVisible(_GLFWwindow* window) GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window)
{ {
return window->null.visible; return window->null.visible;
} }
void _glfwPlatformPollEvents(void) void _glfwPollEventsNull(void)
{ {
} }
void _glfwPlatformWaitEvents(void) void _glfwWaitEventsNull(void)
{ {
} }
void _glfwPlatformWaitEventsTimeout(double timeout) void _glfwWaitEventsTimeoutNull(double timeout)
{ {
} }
void _glfwPlatformPostEmptyEvent(void) void _glfwPostEmptyEventNull(void)
{ {
} }
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos)
{ {
if (xpos) if (xpos)
*xpos = _glfw.null.xcursor - window->null.xpos; *xpos = _glfw.null.xcursor - window->null.xpos;
@ -480,50 +509,71 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
*ypos = _glfw.null.ycursor - window->null.ypos; *ypos = _glfw.null.ycursor - window->null.ypos;
} }
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y)
{ {
_glfw.null.xcursor = window->null.xpos + (int) x; _glfw.null.xcursor = window->null.xpos + (int) x;
_glfw.null.ycursor = window->null.ypos + (int) y; _glfw.null.ycursor = window->null.ypos + (int) y;
} }
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwSetCursorModeNull(_GLFWwindow* window, int mode)
{ {
} }
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, GLFWbool _glfwCreateCursorNull(_GLFWcursor* cursor,
const GLFWimage* image, const GLFWimage* image,
int xhot, int yhot) int xhot, int yhot)
{ {
return GLFW_TRUE; return GLFW_TRUE;
} }
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) GLFWbool _glfwCreateStandardCursorNull(_GLFWcursor* cursor, int shape)
{ {
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) void _glfwDestroyCursorNull(_GLFWcursor* cursor)
{ {
} }
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
} }
void _glfwPlatformSetClipboardString(const char* string) void _glfwSetClipboardStringNull(const char* string)
{ {
char* copy = _glfw_strdup(string); char* copy = _glfw_strdup(string);
free(_glfw.null.clipboardString); _glfw_free(_glfw.null.clipboardString);
_glfw.null.clipboardString = copy; _glfw.null.clipboardString = copy;
} }
const char* _glfwPlatformGetClipboardString(void) const char* _glfwGetClipboardStringNull(void)
{ {
return _glfw.null.clipboardString; return _glfw.null.clipboardString;
} }
const char* _glfwPlatformGetScancodeName(int scancode) EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
{ {
return 0;
}
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void)
{
return 0;
}
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
{
return 0;
}
const char* _glfwGetScancodeNameNull(int scancode)
{
if (scancode < GLFW_KEY_SPACE || scancode > GLFW_KEY_LAST)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
return NULL;
}
switch (scancode) switch (scancode)
{ {
case GLFW_KEY_APOSTROPHE: case GLFW_KEY_APOSTROPHE:
@ -643,26 +693,26 @@ const char* _glfwPlatformGetScancodeName(int scancode)
return NULL; return NULL;
} }
int _glfwPlatformGetKeyScancode(int key) int _glfwGetKeyScancodeNull(int key)
{ {
return key; return key;
} }
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
{ {
} }
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance,
VkPhysicalDevice device, VkPhysicalDevice device,
uint32_t queuefamily) uint32_t queuefamily)
{ {
return GLFW_FALSE; return GLFW_FALSE;
} }
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, VkResult _glfwCreateWindowSurfaceNull(VkInstance instance,
_GLFWwindow* window, _GLFWwindow* window,
const VkAllocationCallbacks* allocator, const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface) VkSurfaceKHR* surface)
{ {
// This seems like the most appropriate error to return here // This seems like the most appropriate error to return here
return VK_ERROR_EXTENSION_NOT_PRESENT; return VK_ERROR_EXTENSION_NOT_PRESENT;

View file

@ -39,17 +39,17 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
if (window) if (window)
{ {
int width, height; int width, height;
_glfwPlatformGetFramebufferSize(window, &width, &height); _glfw.platform.getFramebufferSize(window, &width, &height);
// Check to see if we need to allocate a new buffer // Check to see if we need to allocate a new buffer
if ((window->context.osmesa.buffer == NULL) || if ((window->context.osmesa.buffer == NULL) ||
(width != window->context.osmesa.width) || (width != window->context.osmesa.width) ||
(height != window->context.osmesa.height)) (height != window->context.osmesa.height))
{ {
free(window->context.osmesa.buffer); _glfw_free(window->context.osmesa.buffer);
// Allocate the new buffer (width * height * 8-bit RGBA) // Allocate the new buffer (width * height * 8-bit RGBA)
window->context.osmesa.buffer = calloc(4, (size_t) width * height); window->context.osmesa.buffer = _glfw_calloc(4, (size_t) width * height);
window->context.osmesa.width = width; window->context.osmesa.width = width;
window->context.osmesa.height = height; window->context.osmesa.height = height;
} }
@ -83,7 +83,7 @@ static void destroyContextOSMesa(_GLFWwindow* window)
if (window->context.osmesa.buffer) if (window->context.osmesa.buffer)
{ {
free(window->context.osmesa.buffer); _glfw_free(window->context.osmesa.buffer);
window->context.osmesa.width = 0; window->context.osmesa.width = 0;
window->context.osmesa.height = 0; window->context.osmesa.height = 0;
} }
@ -124,6 +124,8 @@ GLFWbool _glfwInitOSMesa(void)
"libOSMesa.8.dylib", "libOSMesa.8.dylib",
#elif defined(__CYGWIN__) #elif defined(__CYGWIN__)
"libOSMesa-8.so", "libOSMesa-8.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libOSMesa.so",
#else #else
"libOSMesa.so.8", "libOSMesa.so.8",
"libOSMesa.so.6", "libOSMesa.so.6",
@ -136,7 +138,7 @@ GLFWbool _glfwInitOSMesa(void)
for (i = 0; sonames[i]; i++) for (i = 0; sonames[i]; i++)
{ {
_glfw.osmesa.handle = _glfw_dlopen(sonames[i]); _glfw.osmesa.handle = _glfwPlatformLoadModule(sonames[i]);
if (_glfw.osmesa.handle) if (_glfw.osmesa.handle)
break; break;
} }
@ -148,19 +150,19 @@ GLFWbool _glfwInitOSMesa(void)
} }
_glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt) _glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextExt");
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs) _glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext) _glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaDestroyContext");
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent) _glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaMakeCurrent");
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer) _glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer) _glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress) _glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress"); _glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetProcAddress");
if (!_glfw.osmesa.CreateContextExt || if (!_glfw.osmesa.CreateContextExt ||
!_glfw.osmesa.DestroyContext || !_glfw.osmesa.DestroyContext ||
@ -183,12 +185,12 @@ void _glfwTerminateOSMesa(void)
{ {
if (_glfw.osmesa.handle) if (_glfw.osmesa.handle)
{ {
_glfw_dlclose(_glfw.osmesa.handle); _glfwPlatformFreeModule(_glfw.osmesa.handle);
_glfw.osmesa.handle = NULL; _glfw.osmesa.handle = NULL;
} }
} }
#define setAttrib(a, v) \ #define SET_ATTRIB(a, v) \
{ \ { \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \ attribs[index++] = a; \
@ -219,24 +221,24 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
{ {
int index = 0, attribs[40]; int index = 0, attribs[40];
setAttrib(OSMESA_FORMAT, OSMESA_RGBA); SET_ATTRIB(OSMESA_FORMAT, OSMESA_RGBA);
setAttrib(OSMESA_DEPTH_BITS, fbconfig->depthBits); SET_ATTRIB(OSMESA_DEPTH_BITS, fbconfig->depthBits);
setAttrib(OSMESA_STENCIL_BITS, fbconfig->stencilBits); SET_ATTRIB(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
setAttrib(OSMESA_ACCUM_BITS, accumBits); SET_ATTRIB(OSMESA_ACCUM_BITS, accumBits);
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
{ {
setAttrib(OSMESA_PROFILE, OSMESA_CORE_PROFILE); SET_ATTRIB(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
} }
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
{ {
setAttrib(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE); SET_ATTRIB(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
} }
if (ctxconfig->major != 1 || ctxconfig->minor != 0) if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{ {
setAttrib(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major); SET_ATTRIB(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
setAttrib(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor); SET_ATTRIB(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
} }
if (ctxconfig->forward) if (ctxconfig->forward)
@ -246,7 +248,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
return GLFW_FALSE; return GLFW_FALSE;
} }
setAttrib(0, 0); SET_ATTRIB(0, 0);
window->context.osmesa.handle = window->context.osmesa.handle =
OSMesaCreateContextAttribs(attribs, share); OSMesaCreateContextAttribs(attribs, share);
@ -285,7 +287,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
return GLFW_TRUE; return GLFW_TRUE;
} }
#undef setAttrib #undef SET_ATTRIB
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -302,6 +304,12 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (!OSMesaGetColorBuffer(window->context.osmesa.handle, if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight, &mesaWidth, &mesaHeight,
&mesaFormat, &mesaBuffer)) &mesaFormat, &mesaBuffer))
@ -335,6 +343,12 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (!OSMesaGetDepthBuffer(window->context.osmesa.handle, if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight, &mesaWidth, &mesaHeight,
&mesaBytes, &mesaBuffer)) &mesaBytes, &mesaBuffer))
@ -361,7 +375,7 @@ GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (window->context.client == GLFW_NO_API) if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL; return NULL;

View file

@ -1,90 +0,0 @@
//========================================================================
// GLFW 3.4 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define OSMESA_RGBA 0x1908
#define OSMESA_FORMAT 0x22
#define OSMESA_DEPTH_BITS 0x30
#define OSMESA_STENCIL_BITS 0x31
#define OSMESA_ACCUM_BITS 0x32
#define OSMESA_PROFILE 0x33
#define OSMESA_CORE_PROFILE 0x34
#define OSMESA_COMPAT_PROFILE 0x35
#define OSMESA_CONTEXT_MAJOR_VERSION 0x36
#define OSMESA_CONTEXT_MINOR_VERSION 0x37
typedef void* OSMesaContext;
typedef void (*OSMESAproc)(void);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextExt)(GLenum,GLint,GLint,GLint,OSMesaContext);
typedef OSMesaContext (GLAPIENTRY * PFN_OSMesaCreateContextAttribs)(const int*,OSMesaContext);
typedef void (GLAPIENTRY * PFN_OSMesaDestroyContext)(OSMesaContext);
typedef int (GLAPIENTRY * PFN_OSMesaMakeCurrent)(OSMesaContext,void*,int,int,int);
typedef int (GLAPIENTRY * PFN_OSMesaGetColorBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef int (GLAPIENTRY * PFN_OSMesaGetDepthBuffer)(OSMesaContext,int*,int*,int*,void**);
typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*);
#define OSMesaCreateContextExt _glfw.osmesa.CreateContextExt
#define OSMesaCreateContextAttribs _glfw.osmesa.CreateContextAttribs
#define OSMesaDestroyContext _glfw.osmesa.DestroyContext
#define OSMesaMakeCurrent _glfw.osmesa.MakeCurrent
#define OSMesaGetColorBuffer _glfw.osmesa.GetColorBuffer
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
// OSMesa-specific per-context data
//
typedef struct _GLFWcontextOSMesa
{
OSMesaContext handle;
int width;
int height;
void* buffer;
} _GLFWcontextOSMesa;
// OSMesa-specific global data
//
typedef struct _GLFWlibraryOSMesa
{
void* handle;
PFN_OSMesaCreateContextExt CreateContextExt;
PFN_OSMesaCreateContextAttribs CreateContextAttribs;
PFN_OSMesaDestroyContext DestroyContext;
PFN_OSMesaMakeCurrent MakeCurrent;
PFN_OSMesaGetColorBuffer GetColorBuffer;
PFN_OSMesaGetDepthBuffer GetDepthBuffer;
PFN_OSMesaGetProcAddress GetProcAddress;
} _GLFWlibraryOSMesa;
GLFWbool _glfwInitOSMesa(void);
void _glfwTerminateOSMesa(void);
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);

189
raylib/external/glfw/src/platform.c vendored Normal file
View file

@ -0,0 +1,189 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
static const struct
{
int ID;
GLFWbool (*connect)(int,_GLFWplatform*);
} supportedPlatforms[] =
{
#if defined(_GLFW_WIN32)
{ GLFW_PLATFORM_WIN32, _glfwConnectWin32 },
#endif
#if defined(_GLFW_COCOA)
{ GLFW_PLATFORM_COCOA, _glfwConnectCocoa },
#endif
#if defined(_GLFW_X11)
{ GLFW_PLATFORM_X11, _glfwConnectX11 },
#endif
#if defined(_GLFW_WAYLAND)
{ GLFW_PLATFORM_WAYLAND, _glfwConnectWayland },
#endif
};
GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
{
const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]);
size_t i;
if (desiredID != GLFW_ANY_PLATFORM &&
desiredID != GLFW_PLATFORM_WIN32 &&
desiredID != GLFW_PLATFORM_COCOA &&
desiredID != GLFW_PLATFORM_WAYLAND &&
desiredID != GLFW_PLATFORM_X11 &&
desiredID != GLFW_PLATFORM_NULL)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", desiredID);
return GLFW_FALSE;
}
// Only allow the Null platform if specifically requested
if (desiredID == GLFW_PLATFORM_NULL)
return GLFW_FALSE; //_glfwConnectNull(desiredID, platform); // @raysan5
else if (count == 0)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform");
return GLFW_FALSE;
}
if (desiredID == GLFW_ANY_PLATFORM)
{
// If there is exactly one platform available for auto-selection, let it emit the
// error on failure as the platform-specific error description may be more helpful
if (count == 1)
return supportedPlatforms[0].connect(supportedPlatforms[0].ID, platform);
for (i = 0; i < count; i++)
{
if (supportedPlatforms[i].connect(desiredID, platform))
return GLFW_TRUE;
}
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Failed to detect any supported platform");
}
else
{
for (i = 0; i < count; i++)
{
if (supportedPlatforms[i].ID == desiredID)
return supportedPlatforms[i].connect(desiredID, platform);
}
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "The requested platform is not supported");
}
return GLFW_FALSE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI int glfwGetPlatform(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfw.platform.platformID;
}
GLFWAPI int glfwPlatformSupported(int platformID)
{
const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]);
size_t i;
if (platformID != GLFW_PLATFORM_WIN32 &&
platformID != GLFW_PLATFORM_COCOA &&
platformID != GLFW_PLATFORM_WAYLAND &&
platformID != GLFW_PLATFORM_X11 &&
platformID != GLFW_PLATFORM_NULL)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", platformID);
return GLFW_FALSE;
}
if (platformID == GLFW_PLATFORM_NULL)
return GLFW_TRUE;
for (i = 0; i < count; i++)
{
if (platformID == supportedPlatforms[i].ID)
return GLFW_TRUE;
}
return GLFW_FALSE;
}
GLFWAPI const char* glfwGetVersionString(void)
{
return _GLFW_VERSION_NUMBER
#if defined(_GLFW_WIN32)
" Win32 WGL"
#endif
#if defined(_GLFW_COCOA)
" Cocoa NSGL"
#endif
#if defined(_GLFW_WAYLAND)
" Wayland"
#endif
#if defined(_GLFW_X11)
" X11 GLX"
#endif
" Null"
" EGL"
" OSMesa"
#if defined(__MINGW64_VERSION_MAJOR)
" MinGW-w64"
#elif defined(__MINGW32__)
" MinGW"
#elif defined(_MSC_VER)
" VisualC"
#endif
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
" hybrid-GPU"
#endif
#if defined(_POSIX_MONOTONIC_CLOCK)
" monotonic"
#endif
#if defined(_GLFW_BUILD_DLL)
#if defined(_WIN32)
" DLL"
#elif defined(__APPLE__)
" dynamic"
#else
" shared"
#endif
#endif
;
}

163
raylib/external/glfw/src/platform.h vendored Normal file
View file

@ -0,0 +1,163 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "null_platform.h"
#if defined(_GLFW_WIN32)
#include "win32_platform.h"
#else
#define GLFW_WIN32_WINDOW_STATE
#define GLFW_WIN32_MONITOR_STATE
#define GLFW_WIN32_CURSOR_STATE
#define GLFW_WIN32_LIBRARY_WINDOW_STATE
#define GLFW_WGL_CONTEXT_STATE
#define GLFW_WGL_LIBRARY_CONTEXT_STATE
#endif
#if defined(_GLFW_COCOA)
#include "cocoa_platform.h"
#else
#define GLFW_COCOA_WINDOW_STATE
#define GLFW_COCOA_MONITOR_STATE
#define GLFW_COCOA_CURSOR_STATE
#define GLFW_COCOA_LIBRARY_WINDOW_STATE
#define GLFW_NSGL_CONTEXT_STATE
#define GLFW_NSGL_LIBRARY_CONTEXT_STATE
#endif
#if defined(_GLFW_WAYLAND)
#include "wl_platform.h"
#else
#define GLFW_WAYLAND_WINDOW_STATE
#define GLFW_WAYLAND_MONITOR_STATE
#define GLFW_WAYLAND_CURSOR_STATE
#define GLFW_WAYLAND_LIBRARY_WINDOW_STATE
#endif
#if defined(_GLFW_X11)
#include "x11_platform.h"
#else
#define GLFW_X11_WINDOW_STATE
#define GLFW_X11_MONITOR_STATE
#define GLFW_X11_CURSOR_STATE
#define GLFW_X11_LIBRARY_WINDOW_STATE
#define GLFW_GLX_CONTEXT_STATE
#define GLFW_GLX_LIBRARY_CONTEXT_STATE
#endif
#include "null_joystick.h"
#if defined(_GLFW_WIN32)
#include "win32_joystick.h"
#else
#define GLFW_WIN32_JOYSTICK_STATE
#define GLFW_WIN32_LIBRARY_JOYSTICK_STATE
#endif
#if defined(_GLFW_COCOA)
#include "cocoa_joystick.h"
#else
#define GLFW_COCOA_JOYSTICK_STATE
#define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
#endif
#if (defined(_GLFW_X11) || defined(_GLFW_WAYLAND)) && defined(__linux__)
#include "linux_joystick.h"
#else
#define GLFW_LINUX_JOYSTICK_STATE
#define GLFW_LINUX_LIBRARY_JOYSTICK_STATE
#endif
#define GLFW_PLATFORM_WINDOW_STATE \
GLFW_WIN32_WINDOW_STATE \
GLFW_COCOA_WINDOW_STATE \
GLFW_WAYLAND_WINDOW_STATE \
GLFW_X11_WINDOW_STATE \
GLFW_NULL_WINDOW_STATE \
#define GLFW_PLATFORM_MONITOR_STATE \
GLFW_WIN32_MONITOR_STATE \
GLFW_COCOA_MONITOR_STATE \
GLFW_WAYLAND_MONITOR_STATE \
GLFW_X11_MONITOR_STATE \
GLFW_NULL_MONITOR_STATE \
#define GLFW_PLATFORM_CURSOR_STATE \
GLFW_WIN32_CURSOR_STATE \
GLFW_COCOA_CURSOR_STATE \
GLFW_WAYLAND_CURSOR_STATE \
GLFW_X11_CURSOR_STATE \
GLFW_NULL_CURSOR_STATE \
#define GLFW_PLATFORM_JOYSTICK_STATE \
GLFW_WIN32_JOYSTICK_STATE \
GLFW_COCOA_JOYSTICK_STATE \
GLFW_LINUX_JOYSTICK_STATE
#define GLFW_PLATFORM_LIBRARY_WINDOW_STATE \
GLFW_WIN32_LIBRARY_WINDOW_STATE \
GLFW_COCOA_LIBRARY_WINDOW_STATE \
GLFW_WAYLAND_LIBRARY_WINDOW_STATE \
GLFW_X11_LIBRARY_WINDOW_STATE \
GLFW_NULL_LIBRARY_WINDOW_STATE \
#define GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
GLFW_WIN32_LIBRARY_JOYSTICK_STATE \
GLFW_COCOA_LIBRARY_JOYSTICK_STATE \
GLFW_LINUX_LIBRARY_JOYSTICK_STATE
#define GLFW_PLATFORM_CONTEXT_STATE \
GLFW_WGL_CONTEXT_STATE \
GLFW_NSGL_CONTEXT_STATE \
GLFW_GLX_CONTEXT_STATE
#define GLFW_PLATFORM_LIBRARY_CONTEXT_STATE \
GLFW_WGL_LIBRARY_CONTEXT_STATE \
GLFW_NSGL_LIBRARY_CONTEXT_STATE \
GLFW_GLX_LIBRARY_CONTEXT_STATE
#if defined(_WIN32)
#include "win32_thread.h"
#define GLFW_PLATFORM_TLS_STATE GLFW_WIN32_TLS_STATE
#define GLFW_PLATFORM_MUTEX_STATE GLFW_WIN32_MUTEX_STATE
#else
#include "posix_thread.h"
#define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_STATE
#define GLFW_PLATFORM_MUTEX_STATE GLFW_POSIX_MUTEX_STATE
#endif
#if defined(_WIN32)
#include "win32_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_WIN32_LIBRARY_TIMER_STATE
#elif defined(__APPLE__)
#include "cocoa_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_COCOA_LIBRARY_TIMER_STATE
#else
#include "posix_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE
#endif

51
raylib/external/glfw/src/posix_module.c vendored Normal file
View file

@ -0,0 +1,51 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2021 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include "internal.h"
#include <dlfcn.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwPlatformLoadModule(const char* path)
{
return dlopen(path, RTLD_LAZY | RTLD_LOCAL);
}
void _glfwPlatformFreeModule(void* module)
{
dlclose(module);
}
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
{
return dlsym(module, name);
}

81
raylib/external/glfw/src/posix_poll.c vendored Normal file
View file

@ -0,0 +1,81 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#define _GNU_SOURCE
#include "internal.h"
#include <signal.h>
#include <time.h>
#include <errno.h>
GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout)
{
for (;;)
{
if (timeout)
{
const uint64_t base = _glfwPlatformGetTimerValue();
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
const time_t seconds = (time_t) *timeout;
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
const struct timespec ts = { seconds, nanoseconds };
const int result = ppoll(fds, count, &ts, NULL);
#elif defined(__NetBSD__)
const time_t seconds = (time_t) *timeout;
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
const struct timespec ts = { seconds, nanoseconds };
const int result = pollts(fds, count, &ts, NULL);
#else
const int milliseconds = (int) (*timeout * 1e3);
const int result = poll(fds, count, milliseconds);
#endif
const int error = errno; // clock_gettime may overwrite our error
*timeout -= (_glfwPlatformGetTimerValue() - base) /
(double) _glfwPlatformGetTimerFrequency();
if (result > 0)
return GLFW_TRUE;
else if (result == -1 && error != EINTR && error != EAGAIN)
return GLFW_FALSE;
else if (*timeout <= 0.0)
return GLFW_FALSE;
}
else
{
const int result = poll(fds, count, -1);
if (result > 0)
return GLFW_TRUE;
else if (result == -1 && errno != EINTR && errno != EAGAIN)
return GLFW_FALSE;
}
}
}

32
raylib/external/glfw/src/posix_poll.h vendored Normal file
View file

@ -0,0 +1,32 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#include <poll.h>
GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout);

View file

@ -27,8 +27,8 @@
#include <pthread.h> #include <pthread.h>
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix #define GLFW_POSIX_TLS_STATE _GLFWtlsPOSIX posix;
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexPOSIX posix #define GLFW_POSIX_MUTEX_STATE _GLFWmutexPOSIX posix;
// POSIX-specific thread local storage data // POSIX-specific thread local storage data
@ -37,7 +37,6 @@ typedef struct _GLFWtlsPOSIX
{ {
GLFWbool allocated; GLFWbool allocated;
pthread_key_t key; pthread_key_t key;
} _GLFWtlsPOSIX; } _GLFWtlsPOSIX;
// POSIX-specific mutex data // POSIX-specific mutex data
@ -46,6 +45,5 @@ typedef struct _GLFWmutexPOSIX
{ {
GLFWbool allocated; GLFWbool allocated;
pthread_mutex_t handle; pthread_mutex_t handle;
} _GLFWmutexPOSIX; } _GLFWmutexPOSIX;

View file

@ -27,60 +27,33 @@
// It is fine to use C99 in this file because it will not be built with VS // It is fine to use C99 in this file because it will not be built with VS
//======================================================================== //========================================================================
//#define _POSIX_C_SOURCE 199309L
#include "internal.h" #include "internal.h"
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <time.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialise timer
//
void _glfwInitTimerPOSIX(void)
{
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
{
_glfw.timer.posix.monotonic = GLFW_TRUE;
_glfw.timer.posix.frequency = 1000000000;
}
else
#endif
{
_glfw.timer.posix.monotonic = GLFW_FALSE;
_glfw.timer.posix.frequency = 1000000;
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformInitTimer(void)
{
_glfw.timer.posix.clock = CLOCK_REALTIME;
_glfw.timer.posix.frequency = 1000000000;
#if defined(_POSIX_MONOTONIC_CLOCK)
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
_glfw.timer.posix.clock = CLOCK_MONOTONIC;
#endif
}
uint64_t _glfwPlatformGetTimerValue(void) uint64_t _glfwPlatformGetTimerValue(void)
{ {
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) struct timespec ts;
if (_glfw.timer.posix.monotonic) clock_gettime(_glfw.timer.posix.clock, &ts);
{ return (uint64_t) ts.tv_sec * _glfw.timer.posix.frequency + (uint64_t) ts.tv_nsec;
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t) ts.tv_sec * (uint64_t) 1000000000 + (uint64_t) ts.tv_nsec;
}
else
#endif
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (uint64_t) tv.tv_sec * (uint64_t) 1000000 + (uint64_t) tv.tv_usec;
}
} }
uint64_t _glfwPlatformGetTimerFrequency(void) uint64_t _glfwPlatformGetTimerFrequency(void)

View file

@ -25,20 +25,17 @@
// //
//======================================================================== //========================================================================
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix #define GLFW_POSIX_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix;
#include <stdint.h> #include <stdint.h>
#include <time.h>
// POSIX-specific global timer data // POSIX-specific global timer data
// //
typedef struct _GLFWtimerPOSIX typedef struct _GLFWtimerPOSIX
{ {
GLFWbool monotonic; clockid_t clock;
uint64_t frequency; uint64_t frequency;
} _GLFWtimerPOSIX; } _GLFWtimerPOSIX;
void _glfwInitTimerPOSIX(void);

View file

@ -45,45 +45,52 @@ GLFWbool _glfwInitVulkan(int mode)
{ {
VkResult err; VkResult err;
VkExtensionProperties* ep; VkExtensionProperties* ep;
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
uint32_t i, count; uint32_t i, count;
if (_glfw.vk.available) if (_glfw.vk.available)
return GLFW_TRUE; return GLFW_TRUE;
#if !defined(_GLFW_VULKAN_STATIC) if (_glfw.hints.init.vulkanLoader)
_glfw.vk.GetInstanceProcAddr = _glfw.hints.init.vulkanLoader;
else
{
#if defined(_GLFW_VULKAN_LIBRARY) #if defined(_GLFW_VULKAN_LIBRARY)
_glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY); _glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
#elif defined(_GLFW_WIN32) #elif defined(_GLFW_WIN32)
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll"); _glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
#elif defined(_GLFW_COCOA) #elif defined(_GLFW_COCOA)
_glfw.vk.handle = _glfw_dlopen("libvulkan.1.dylib"); _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib");
if (!_glfw.vk.handle) if (!_glfw.vk.handle)
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderNS(); _glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa();
#elif defined(__OpenBSD__) || defined(__NetBSD__)
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
#else #else
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1"); _glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1");
#endif #endif
if (!_glfw.vk.handle) if (!_glfw.vk.handle)
{ {
if (mode == _GLFW_REQUIRE_LOADER) if (mode == _GLFW_REQUIRE_LOADER)
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
return GLFW_FALSE; return GLFW_FALSE;
}
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
_glfwPlatformGetModuleSymbol(_glfw.vk.handle, "vkGetInstanceProcAddr");
if (!_glfw.vk.GetInstanceProcAddr)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Loader does not export vkGetInstanceProcAddr");
_glfwTerminateVulkan();
return GLFW_FALSE;
}
} }
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
if (!_glfw.vk.GetInstanceProcAddr)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Loader does not export vkGetInstanceProcAddr");
_glfwTerminateVulkan();
return GLFW_FALSE;
}
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties"); vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
if (!_glfw.vk.EnumerateInstanceExtensionProperties) if (!vkEnumerateInstanceExtensionProperties)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties"); "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
@ -91,7 +98,6 @@ GLFWbool _glfwInitVulkan(int mode)
_glfwTerminateVulkan(); _glfwTerminateVulkan();
return GLFW_FALSE; return GLFW_FALSE;
} }
#endif // _GLFW_VULKAN_STATIC
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
if (err) if (err)
@ -108,7 +114,7 @@ GLFWbool _glfwInitVulkan(int mode)
return GLFW_FALSE; return GLFW_FALSE;
} }
ep = calloc(count, sizeof(VkExtensionProperties)); ep = _glfw_calloc(count, sizeof(VkExtensionProperties));
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep); err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
if (err) if (err)
@ -117,7 +123,7 @@ GLFWbool _glfwInitVulkan(int mode)
"Vulkan: Failed to query instance extensions: %s", "Vulkan: Failed to query instance extensions: %s",
_glfwGetVulkanResultString(err)); _glfwGetVulkanResultString(err));
free(ep); _glfw_free(ep);
_glfwTerminateVulkan(); _glfwTerminateVulkan();
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -126,40 +132,33 @@ GLFWbool _glfwInitVulkan(int mode)
{ {
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0) if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
_glfw.vk.KHR_surface = GLFW_TRUE; _glfw.vk.KHR_surface = GLFW_TRUE;
#if defined(_GLFW_WIN32)
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
_glfw.vk.KHR_win32_surface = GLFW_TRUE; _glfw.vk.KHR_win32_surface = GLFW_TRUE;
#elif defined(_GLFW_COCOA)
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
_glfw.vk.MVK_macos_surface = GLFW_TRUE; _glfw.vk.MVK_macos_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
_glfw.vk.EXT_metal_surface = GLFW_TRUE; _glfw.vk.EXT_metal_surface = GLFW_TRUE;
#elif defined(_GLFW_X11)
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
_glfw.vk.KHR_xlib_surface = GLFW_TRUE; _glfw.vk.KHR_xlib_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
_glfw.vk.KHR_xcb_surface = GLFW_TRUE; _glfw.vk.KHR_xcb_surface = GLFW_TRUE;
#elif defined(_GLFW_WAYLAND)
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0) else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
_glfw.vk.KHR_wayland_surface = GLFW_TRUE; _glfw.vk.KHR_wayland_surface = GLFW_TRUE;
#endif
} }
free(ep); _glfw_free(ep);
_glfw.vk.available = GLFW_TRUE; _glfw.vk.available = GLFW_TRUE;
_glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions); _glfw.platform.getRequiredInstanceExtensions(_glfw.vk.extensions);
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwTerminateVulkan(void) void _glfwTerminateVulkan(void)
{ {
#if !defined(_GLFW_VULKAN_STATIC)
if (_glfw.vk.handle) if (_glfw.vk.handle)
_glfw_dlclose(_glfw.vk.handle); _glfwPlatformFreeModule(_glfw.vk.handle);
#endif
} }
const char* _glfwGetVulkanResultString(VkResult result) const char* _glfwGetVulkanResultString(VkResult result)
@ -257,17 +256,16 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER)) if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return NULL; return NULL;
// NOTE: Vulkan 1.0 and 1.1 vkGetInstanceProcAddr cannot return itself
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
return (GLFWvkproc) vkGetInstanceProcAddr;
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname); proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
#if defined(_GLFW_VULKAN_STATIC)
if (!proc) if (!proc)
{ {
if (strcmp(procname, "vkGetInstanceProcAddr") == 0) if (_glfw.vk.handle)
return (GLFWvkproc) vkGetInstanceProcAddr; proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname);
} }
#else
if (!proc)
proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);
#endif
return proc; return proc;
} }
@ -291,9 +289,9 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
return GLFW_FALSE; return GLFW_FALSE;
} }
return _glfwPlatformGetPhysicalDevicePresentationSupport(instance, return _glfw.platform.getPhysicalDevicePresentationSupport(instance,
device, device,
queuefamily); queuefamily);
} }
GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
@ -327,6 +325,6 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR; return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
} }
return _glfwPlatformCreateWindowSurface(instance, window, allocator, surface); return _glfw.platform.createWindowSurface(instance, window, allocator, surface);
} }

View file

@ -0,0 +1,521 @@
/* Generated by wayland-scanner 1.21.0 */
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2010-2011 Intel Corporation
* Copyright © 2012-2013 Collabora, Ltd.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_buffer_interface;
extern const struct wl_interface wl_callback_interface;
extern const struct wl_interface wl_data_device_interface;
extern const struct wl_interface wl_data_offer_interface;
extern const struct wl_interface wl_data_source_interface;
extern const struct wl_interface wl_keyboard_interface;
extern const struct wl_interface wl_output_interface;
extern const struct wl_interface wl_pointer_interface;
extern const struct wl_interface wl_region_interface;
extern const struct wl_interface wl_registry_interface;
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_shell_surface_interface;
extern const struct wl_interface wl_shm_pool_interface;
extern const struct wl_interface wl_subsurface_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface wl_touch_interface;
static const struct wl_interface *wayland_types[] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&wl_callback_interface,
&wl_registry_interface,
&wl_surface_interface,
&wl_region_interface,
&wl_buffer_interface,
NULL,
NULL,
NULL,
NULL,
NULL,
&wl_shm_pool_interface,
NULL,
NULL,
&wl_data_source_interface,
&wl_surface_interface,
&wl_surface_interface,
NULL,
&wl_data_source_interface,
NULL,
&wl_data_offer_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
&wl_data_offer_interface,
&wl_data_offer_interface,
&wl_data_source_interface,
&wl_data_device_interface,
&wl_seat_interface,
&wl_shell_surface_interface,
&wl_surface_interface,
&wl_seat_interface,
NULL,
&wl_seat_interface,
NULL,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
NULL,
NULL,
&wl_output_interface,
&wl_seat_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
&wl_output_interface,
&wl_buffer_interface,
NULL,
NULL,
&wl_callback_interface,
&wl_region_interface,
&wl_region_interface,
&wl_output_interface,
&wl_output_interface,
&wl_pointer_interface,
&wl_keyboard_interface,
&wl_touch_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
&wl_surface_interface,
NULL,
&wl_surface_interface,
NULL,
NULL,
&wl_surface_interface,
NULL,
NULL,
&wl_surface_interface,
NULL,
NULL,
NULL,
&wl_subsurface_interface,
&wl_surface_interface,
&wl_surface_interface,
&wl_surface_interface,
&wl_surface_interface,
};
static const struct wl_message wl_display_requests[] = {
{ "sync", "n", wayland_types + 8 },
{ "get_registry", "n", wayland_types + 9 },
};
static const struct wl_message wl_display_events[] = {
{ "error", "ous", wayland_types + 0 },
{ "delete_id", "u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_display_interface = {
"wl_display", 1,
2, wl_display_requests,
2, wl_display_events,
};
static const struct wl_message wl_registry_requests[] = {
{ "bind", "usun", wayland_types + 0 },
};
static const struct wl_message wl_registry_events[] = {
{ "global", "usu", wayland_types + 0 },
{ "global_remove", "u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_registry_interface = {
"wl_registry", 1,
1, wl_registry_requests,
2, wl_registry_events,
};
static const struct wl_message wl_callback_events[] = {
{ "done", "u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_callback_interface = {
"wl_callback", 1,
0, NULL,
1, wl_callback_events,
};
static const struct wl_message wl_compositor_requests[] = {
{ "create_surface", "n", wayland_types + 10 },
{ "create_region", "n", wayland_types + 11 },
};
WL_PRIVATE const struct wl_interface wl_compositor_interface = {
"wl_compositor", 5,
2, wl_compositor_requests,
0, NULL,
};
static const struct wl_message wl_shm_pool_requests[] = {
{ "create_buffer", "niiiiu", wayland_types + 12 },
{ "destroy", "", wayland_types + 0 },
{ "resize", "i", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_shm_pool_interface = {
"wl_shm_pool", 1,
3, wl_shm_pool_requests,
0, NULL,
};
static const struct wl_message wl_shm_requests[] = {
{ "create_pool", "nhi", wayland_types + 18 },
};
static const struct wl_message wl_shm_events[] = {
{ "format", "u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_shm_interface = {
"wl_shm", 1,
1, wl_shm_requests,
1, wl_shm_events,
};
static const struct wl_message wl_buffer_requests[] = {
{ "destroy", "", wayland_types + 0 },
};
static const struct wl_message wl_buffer_events[] = {
{ "release", "", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_buffer_interface = {
"wl_buffer", 1,
1, wl_buffer_requests,
1, wl_buffer_events,
};
static const struct wl_message wl_data_offer_requests[] = {
{ "accept", "u?s", wayland_types + 0 },
{ "receive", "sh", wayland_types + 0 },
{ "destroy", "", wayland_types + 0 },
{ "finish", "3", wayland_types + 0 },
{ "set_actions", "3uu", wayland_types + 0 },
};
static const struct wl_message wl_data_offer_events[] = {
{ "offer", "s", wayland_types + 0 },
{ "source_actions", "3u", wayland_types + 0 },
{ "action", "3u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_data_offer_interface = {
"wl_data_offer", 3,
5, wl_data_offer_requests,
3, wl_data_offer_events,
};
static const struct wl_message wl_data_source_requests[] = {
{ "offer", "s", wayland_types + 0 },
{ "destroy", "", wayland_types + 0 },
{ "set_actions", "3u", wayland_types + 0 },
};
static const struct wl_message wl_data_source_events[] = {
{ "target", "?s", wayland_types + 0 },
{ "send", "sh", wayland_types + 0 },
{ "cancelled", "", wayland_types + 0 },
{ "dnd_drop_performed", "3", wayland_types + 0 },
{ "dnd_finished", "3", wayland_types + 0 },
{ "action", "3u", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_data_source_interface = {
"wl_data_source", 3,
3, wl_data_source_requests,
6, wl_data_source_events,
};
static const struct wl_message wl_data_device_requests[] = {
{ "start_drag", "?oo?ou", wayland_types + 21 },
{ "set_selection", "?ou", wayland_types + 25 },
{ "release", "2", wayland_types + 0 },
};
static const struct wl_message wl_data_device_events[] = {
{ "data_offer", "n", wayland_types + 27 },
{ "enter", "uoff?o", wayland_types + 28 },
{ "leave", "", wayland_types + 0 },
{ "motion", "uff", wayland_types + 0 },
{ "drop", "", wayland_types + 0 },
{ "selection", "?o", wayland_types + 33 },
};
WL_PRIVATE const struct wl_interface wl_data_device_interface = {
"wl_data_device", 3,
3, wl_data_device_requests,
6, wl_data_device_events,
};
static const struct wl_message wl_data_device_manager_requests[] = {
{ "create_data_source", "n", wayland_types + 34 },
{ "get_data_device", "no", wayland_types + 35 },
};
WL_PRIVATE const struct wl_interface wl_data_device_manager_interface = {
"wl_data_device_manager", 3,
2, wl_data_device_manager_requests,
0, NULL,
};
static const struct wl_message wl_shell_requests[] = {
{ "get_shell_surface", "no", wayland_types + 37 },
};
WL_PRIVATE const struct wl_interface wl_shell_interface = {
"wl_shell", 1,
1, wl_shell_requests,
0, NULL,
};
static const struct wl_message wl_shell_surface_requests[] = {
{ "pong", "u", wayland_types + 0 },
{ "move", "ou", wayland_types + 39 },
{ "resize", "ouu", wayland_types + 41 },
{ "set_toplevel", "", wayland_types + 0 },
{ "set_transient", "oiiu", wayland_types + 44 },
{ "set_fullscreen", "uu?o", wayland_types + 48 },
{ "set_popup", "ouoiiu", wayland_types + 51 },
{ "set_maximized", "?o", wayland_types + 57 },
{ "set_title", "s", wayland_types + 0 },
{ "set_class", "s", wayland_types + 0 },
};
static const struct wl_message wl_shell_surface_events[] = {
{ "ping", "u", wayland_types + 0 },
{ "configure", "uii", wayland_types + 0 },
{ "popup_done", "", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_shell_surface_interface = {
"wl_shell_surface", 1,
10, wl_shell_surface_requests,
3, wl_shell_surface_events,
};
static const struct wl_message wl_surface_requests[] = {
{ "destroy", "", wayland_types + 0 },
{ "attach", "?oii", wayland_types + 58 },
{ "damage", "iiii", wayland_types + 0 },
{ "frame", "n", wayland_types + 61 },
{ "set_opaque_region", "?o", wayland_types + 62 },
{ "set_input_region", "?o", wayland_types + 63 },
{ "commit", "", wayland_types + 0 },
{ "set_buffer_transform", "2i", wayland_types + 0 },
{ "set_buffer_scale", "3i", wayland_types + 0 },
{ "damage_buffer", "4iiii", wayland_types + 0 },
{ "offset", "5ii", wayland_types + 0 },
};
static const struct wl_message wl_surface_events[] = {
{ "enter", "o", wayland_types + 64 },
{ "leave", "o", wayland_types + 65 },
};
WL_PRIVATE const struct wl_interface wl_surface_interface = {
"wl_surface", 5,
11, wl_surface_requests,
2, wl_surface_events,
};
static const struct wl_message wl_seat_requests[] = {
{ "get_pointer", "n", wayland_types + 66 },
{ "get_keyboard", "n", wayland_types + 67 },
{ "get_touch", "n", wayland_types + 68 },
{ "release", "5", wayland_types + 0 },
};
static const struct wl_message wl_seat_events[] = {
{ "capabilities", "u", wayland_types + 0 },
{ "name", "2s", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_seat_interface = {
"wl_seat", 8,
4, wl_seat_requests,
2, wl_seat_events,
};
static const struct wl_message wl_pointer_requests[] = {
{ "set_cursor", "u?oii", wayland_types + 69 },
{ "release", "3", wayland_types + 0 },
};
static const struct wl_message wl_pointer_events[] = {
{ "enter", "uoff", wayland_types + 73 },
{ "leave", "uo", wayland_types + 77 },
{ "motion", "uff", wayland_types + 0 },
{ "button", "uuuu", wayland_types + 0 },
{ "axis", "uuf", wayland_types + 0 },
{ "frame", "5", wayland_types + 0 },
{ "axis_source", "5u", wayland_types + 0 },
{ "axis_stop", "5uu", wayland_types + 0 },
{ "axis_discrete", "5ui", wayland_types + 0 },
{ "axis_value120", "8ui", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_pointer_interface = {
"wl_pointer", 8,
2, wl_pointer_requests,
10, wl_pointer_events,
};
static const struct wl_message wl_keyboard_requests[] = {
{ "release", "3", wayland_types + 0 },
};
static const struct wl_message wl_keyboard_events[] = {
{ "keymap", "uhu", wayland_types + 0 },
{ "enter", "uoa", wayland_types + 79 },
{ "leave", "uo", wayland_types + 82 },
{ "key", "uuuu", wayland_types + 0 },
{ "modifiers", "uuuuu", wayland_types + 0 },
{ "repeat_info", "4ii", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_keyboard_interface = {
"wl_keyboard", 8,
1, wl_keyboard_requests,
6, wl_keyboard_events,
};
static const struct wl_message wl_touch_requests[] = {
{ "release", "3", wayland_types + 0 },
};
static const struct wl_message wl_touch_events[] = {
{ "down", "uuoiff", wayland_types + 84 },
{ "up", "uui", wayland_types + 0 },
{ "motion", "uiff", wayland_types + 0 },
{ "frame", "", wayland_types + 0 },
{ "cancel", "", wayland_types + 0 },
{ "shape", "6iff", wayland_types + 0 },
{ "orientation", "6if", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_touch_interface = {
"wl_touch", 8,
1, wl_touch_requests,
7, wl_touch_events,
};
static const struct wl_message wl_output_requests[] = {
{ "release", "3", wayland_types + 0 },
};
static const struct wl_message wl_output_events[] = {
{ "geometry", "iiiiissi", wayland_types + 0 },
{ "mode", "uiii", wayland_types + 0 },
{ "done", "2", wayland_types + 0 },
{ "scale", "2i", wayland_types + 0 },
{ "name", "4s", wayland_types + 0 },
{ "description", "4s", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_output_interface = {
"wl_output", 4,
1, wl_output_requests,
6, wl_output_events,
};
static const struct wl_message wl_region_requests[] = {
{ "destroy", "", wayland_types + 0 },
{ "add", "iiii", wayland_types + 0 },
{ "subtract", "iiii", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_region_interface = {
"wl_region", 1,
3, wl_region_requests,
0, NULL,
};
static const struct wl_message wl_subcompositor_requests[] = {
{ "destroy", "", wayland_types + 0 },
{ "get_subsurface", "noo", wayland_types + 90 },
};
WL_PRIVATE const struct wl_interface wl_subcompositor_interface = {
"wl_subcompositor", 1,
2, wl_subcompositor_requests,
0, NULL,
};
static const struct wl_message wl_subsurface_requests[] = {
{ "destroy", "", wayland_types + 0 },
{ "set_position", "ii", wayland_types + 0 },
{ "place_above", "o", wayland_types + 93 },
{ "place_below", "o", wayland_types + 94 },
{ "set_sync", "", wayland_types + 0 },
{ "set_desync", "", wayland_types + 0 },
};
WL_PRIVATE const struct wl_interface wl_subsurface_interface = {
"wl_subsurface", 1,
6, wl_subsurface_requests,
0, NULL,
};

File diff suppressed because it is too large Load diff

View file

@ -27,30 +27,40 @@
#include <stdint.h> #include <stdint.h>
#include "wayland-util.h" #include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_surface_interface; extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface zwp_idle_inhibitor_v1_interface; extern const struct wl_interface zwp_idle_inhibitor_v1_interface;
static const struct wl_interface *idle_inhibit_unstable_v1_wl_ii_types[] = { static const struct wl_interface *idle_inhibit_unstable_v1_types[] = {
&zwp_idle_inhibitor_v1_interface, &zwp_idle_inhibitor_v1_interface,
&wl_surface_interface, &wl_surface_interface,
}; };
static const struct wl_message zwp_idle_inhibit_manager_v1_requests[] = { static const struct wl_message zwp_idle_inhibit_manager_v1_requests[] = {
{ "destroy", "", idle_inhibit_unstable_v1_wl_ii_types + 0 }, { "destroy", "", idle_inhibit_unstable_v1_types + 0 },
{ "create_inhibitor", "no", idle_inhibit_unstable_v1_wl_ii_types + 0 }, { "create_inhibitor", "no", idle_inhibit_unstable_v1_types + 0 },
}; };
WL_EXPORT const struct wl_interface zwp_idle_inhibit_manager_v1_interface = { WL_PRIVATE const struct wl_interface zwp_idle_inhibit_manager_v1_interface = {
"zwp_idle_inhibit_manager_v1", 1, "zwp_idle_inhibit_manager_v1", 1,
2, zwp_idle_inhibit_manager_v1_requests, 2, zwp_idle_inhibit_manager_v1_requests,
0, NULL, 0, NULL,
}; };
static const struct wl_message zwp_idle_inhibitor_v1_requests[] = { static const struct wl_message zwp_idle_inhibitor_v1_requests[] = {
{ "destroy", "", idle_inhibit_unstable_v1_wl_ii_types + 0 }, { "destroy", "", idle_inhibit_unstable_v1_types + 0 },
}; };
WL_EXPORT const struct wl_interface zwp_idle_inhibitor_v1_interface = { WL_PRIVATE const struct wl_interface zwp_idle_inhibitor_v1_interface = {
"zwp_idle_inhibitor_v1", 1, "zwp_idle_inhibitor_v1", 1,
1, zwp_idle_inhibitor_v1_requests, 1, zwp_idle_inhibitor_v1_requests,
0, NULL, 0, NULL,

View file

@ -28,13 +28,23 @@
#include <stdint.h> #include <stdint.h>
#include "wayland-util.h" #include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_pointer_interface; extern const struct wl_interface wl_pointer_interface;
extern const struct wl_interface wl_region_interface; extern const struct wl_interface wl_region_interface;
extern const struct wl_interface wl_surface_interface; extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface zwp_confined_pointer_v1_interface; extern const struct wl_interface zwp_confined_pointer_v1_interface;
extern const struct wl_interface zwp_locked_pointer_v1_interface; extern const struct wl_interface zwp_locked_pointer_v1_interface;
static const struct wl_interface *pointer_constraints_unstable_v1_wl_pc_types[] = { static const struct wl_interface *pointer_constraints_unstable_v1_types[] = {
NULL, NULL,
NULL, NULL,
&zwp_locked_pointer_v1_interface, &zwp_locked_pointer_v1_interface,
@ -52,45 +62,45 @@ static const struct wl_interface *pointer_constraints_unstable_v1_wl_pc_types[]
}; };
static const struct wl_message zwp_pointer_constraints_v1_requests[] = { static const struct wl_message zwp_pointer_constraints_v1_requests[] = {
{ "destroy", "", pointer_constraints_unstable_v1_wl_pc_types + 0 }, { "destroy", "", pointer_constraints_unstable_v1_types + 0 },
{ "lock_pointer", "noo?ou", pointer_constraints_unstable_v1_wl_pc_types + 2 }, { "lock_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 2 },
{ "confine_pointer", "noo?ou", pointer_constraints_unstable_v1_wl_pc_types + 7 }, { "confine_pointer", "noo?ou", pointer_constraints_unstable_v1_types + 7 },
}; };
WL_EXPORT const struct wl_interface zwp_pointer_constraints_v1_interface = { WL_PRIVATE const struct wl_interface zwp_pointer_constraints_v1_interface = {
"zwp_pointer_constraints_v1", 1, "zwp_pointer_constraints_v1", 1,
3, zwp_pointer_constraints_v1_requests, 3, zwp_pointer_constraints_v1_requests,
0, NULL, 0, NULL,
}; };
static const struct wl_message zwp_locked_pointer_v1_requests[] = { static const struct wl_message zwp_locked_pointer_v1_requests[] = {
{ "destroy", "", pointer_constraints_unstable_v1_wl_pc_types + 0 }, { "destroy", "", pointer_constraints_unstable_v1_types + 0 },
{ "set_cursor_position_hint", "ff", pointer_constraints_unstable_v1_wl_pc_types + 0 }, { "set_cursor_position_hint", "ff", pointer_constraints_unstable_v1_types + 0 },
{ "set_region", "?o", pointer_constraints_unstable_v1_wl_pc_types + 12 }, { "set_region", "?o", pointer_constraints_unstable_v1_types + 12 },
}; };
static const struct wl_message zwp_locked_pointer_v1_events[] = { static const struct wl_message zwp_locked_pointer_v1_events[] = {
{ "locked", "", pointer_constraints_unstable_v1_wl_pc_types + 0 }, { "locked", "", pointer_constraints_unstable_v1_types + 0 },
{ "unlocked", "", pointer_constraints_unstable_v1_wl_pc_types + 0 }, { "unlocked", "", pointer_constraints_unstable_v1_types + 0 },
}; };
WL_EXPORT const struct wl_interface zwp_locked_pointer_v1_interface = { WL_PRIVATE const struct wl_interface zwp_locked_pointer_v1_interface = {
"zwp_locked_pointer_v1", 1, "zwp_locked_pointer_v1", 1,
3, zwp_locked_pointer_v1_requests, 3, zwp_locked_pointer_v1_requests,
2, zwp_locked_pointer_v1_events, 2, zwp_locked_pointer_v1_events,
}; };
static const struct wl_message zwp_confined_pointer_v1_requests[] = { static const struct wl_message zwp_confined_pointer_v1_requests[] = {
{ "destroy", "", pointer_constraints_unstable_v1_wl_pc_types + 0 }, { "destroy", "", pointer_constraints_unstable_v1_types + 0 },
{ "set_region", "?o", pointer_constraints_unstable_v1_wl_pc_types + 13 }, { "set_region", "?o", pointer_constraints_unstable_v1_types + 13 },
}; };
static const struct wl_message zwp_confined_pointer_v1_events[] = { static const struct wl_message zwp_confined_pointer_v1_events[] = {
{ "confined", "", pointer_constraints_unstable_v1_wl_pc_types + 0 }, { "confined", "", pointer_constraints_unstable_v1_types + 0 },
{ "unconfined", "", pointer_constraints_unstable_v1_wl_pc_types + 0 }, { "unconfined", "", pointer_constraints_unstable_v1_types + 0 },
}; };
WL_EXPORT const struct wl_interface zwp_confined_pointer_v1_interface = { WL_PRIVATE const struct wl_interface zwp_confined_pointer_v1_interface = {
"zwp_confined_pointer_v1", 1, "zwp_confined_pointer_v1", 1,
2, zwp_confined_pointer_v1_requests, 2, zwp_confined_pointer_v1_requests,
2, zwp_confined_pointer_v1_events, 2, zwp_confined_pointer_v1_events,

View file

@ -28,10 +28,20 @@
#include <stdint.h> #include <stdint.h>
#include "wayland-util.h" #include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_pointer_interface; extern const struct wl_interface wl_pointer_interface;
extern const struct wl_interface zwp_relative_pointer_v1_interface; extern const struct wl_interface zwp_relative_pointer_v1_interface;
static const struct wl_interface *relative_pointer_unstable_v1_wl_rp_types[] = { static const struct wl_interface *relative_pointer_unstable_v1_types[] = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
@ -43,25 +53,25 @@ static const struct wl_interface *relative_pointer_unstable_v1_wl_rp_types[] = {
}; };
static const struct wl_message zwp_relative_pointer_manager_v1_requests[] = { static const struct wl_message zwp_relative_pointer_manager_v1_requests[] = {
{ "destroy", "", relative_pointer_unstable_v1_wl_rp_types + 0 }, { "destroy", "", relative_pointer_unstable_v1_types + 0 },
{ "get_relative_pointer", "no", relative_pointer_unstable_v1_wl_rp_types + 6 }, { "get_relative_pointer", "no", relative_pointer_unstable_v1_types + 6 },
}; };
WL_EXPORT const struct wl_interface zwp_relative_pointer_manager_v1_interface = { WL_PRIVATE const struct wl_interface zwp_relative_pointer_manager_v1_interface = {
"zwp_relative_pointer_manager_v1", 1, "zwp_relative_pointer_manager_v1", 1,
2, zwp_relative_pointer_manager_v1_requests, 2, zwp_relative_pointer_manager_v1_requests,
0, NULL, 0, NULL,
}; };
static const struct wl_message zwp_relative_pointer_v1_requests[] = { static const struct wl_message zwp_relative_pointer_v1_requests[] = {
{ "destroy", "", relative_pointer_unstable_v1_wl_rp_types + 0 }, { "destroy", "", relative_pointer_unstable_v1_types + 0 },
}; };
static const struct wl_message zwp_relative_pointer_v1_events[] = { static const struct wl_message zwp_relative_pointer_v1_events[] = {
{ "relative_motion", "uuffff", relative_pointer_unstable_v1_wl_rp_types + 0 }, { "relative_motion", "uuffff", relative_pointer_unstable_v1_types + 0 },
}; };
WL_EXPORT const struct wl_interface zwp_relative_pointer_v1_interface = { WL_PRIVATE const struct wl_interface zwp_relative_pointer_v1_interface = {
"zwp_relative_pointer_v1", 1, "zwp_relative_pointer_v1", 1,
1, zwp_relative_pointer_v1_requests, 1, zwp_relative_pointer_v1_requests,
1, zwp_relative_pointer_v1_events, 1, zwp_relative_pointer_v1_events,

View file

@ -27,10 +27,20 @@
#include <stdint.h> #include <stdint.h>
#include "wayland-util.h" #include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_surface_interface; extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface wp_viewport_interface; extern const struct wl_interface wp_viewport_interface;
static const struct wl_interface *viewporter_wl_v_types[] = { static const struct wl_interface *viewporter_types[] = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
@ -40,23 +50,23 @@ static const struct wl_interface *viewporter_wl_v_types[] = {
}; };
static const struct wl_message wp_viewporter_requests[] = { static const struct wl_message wp_viewporter_requests[] = {
{ "destroy", "", viewporter_wl_v_types + 0 }, { "destroy", "", viewporter_types + 0 },
{ "get_viewport", "no", viewporter_wl_v_types + 4 }, { "get_viewport", "no", viewporter_types + 4 },
}; };
WL_EXPORT const struct wl_interface wp_viewporter_interface = { WL_PRIVATE const struct wl_interface wp_viewporter_interface = {
"wp_viewporter", 1, "wp_viewporter", 1,
2, wp_viewporter_requests, 2, wp_viewporter_requests,
0, NULL, 0, NULL,
}; };
static const struct wl_message wp_viewport_requests[] = { static const struct wl_message wp_viewport_requests[] = {
{ "destroy", "", viewporter_wl_v_types + 0 }, { "destroy", "", viewporter_types + 0 },
{ "set_source", "ffff", viewporter_wl_v_types + 0 }, { "set_source", "ffff", viewporter_types + 0 },
{ "set_destination", "ii", viewporter_wl_v_types + 0 }, { "set_destination", "ii", viewporter_types + 0 },
}; };
WL_EXPORT const struct wl_interface wp_viewport_interface = { WL_PRIVATE const struct wl_interface wp_viewport_interface = {
"wp_viewport", 1, "wp_viewport", 1,
3, wp_viewport_requests, 3, wp_viewport_requests,
0, NULL, 0, NULL,

View file

@ -27,6 +27,16 @@
#include <stdint.h> #include <stdint.h>
#include "wayland-util.h" #include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface xdg_toplevel_interface; extern const struct wl_interface xdg_toplevel_interface;
extern const struct wl_interface zxdg_toplevel_decoration_v1_interface; extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
@ -41,7 +51,7 @@ static const struct wl_message zxdg_decoration_manager_v1_requests[] = {
{ "get_toplevel_decoration", "no", xdg_decoration_unstable_v1_types + 1 }, { "get_toplevel_decoration", "no", xdg_decoration_unstable_v1_types + 1 },
}; };
WL_EXPORT const struct wl_interface zxdg_decoration_manager_v1_interface = { WL_PRIVATE const struct wl_interface zxdg_decoration_manager_v1_interface = {
"zxdg_decoration_manager_v1", 1, "zxdg_decoration_manager_v1", 1,
2, zxdg_decoration_manager_v1_requests, 2, zxdg_decoration_manager_v1_requests,
0, NULL, 0, NULL,
@ -57,7 +67,7 @@ static const struct wl_message zxdg_toplevel_decoration_v1_events[] = {
{ "configure", "u", xdg_decoration_unstable_v1_types + 0 }, { "configure", "u", xdg_decoration_unstable_v1_types + 0 },
}; };
WL_EXPORT const struct wl_interface zxdg_toplevel_decoration_v1_interface = { WL_PRIVATE const struct wl_interface zxdg_toplevel_decoration_v1_interface = {
"zxdg_toplevel_decoration_v1", 1, "zxdg_toplevel_decoration_v1", 1,
3, zxdg_toplevel_decoration_v1_requests, 3, zxdg_toplevel_decoration_v1_requests,
1, zxdg_toplevel_decoration_v1_events, 1, zxdg_toplevel_decoration_v1_events,

View file

@ -32,6 +32,16 @@
#include <stdint.h> #include <stdint.h>
#include "wayland-util.h" #include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_output_interface; extern const struct wl_interface wl_output_interface;
extern const struct wl_interface wl_seat_interface; extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_surface_interface; extern const struct wl_interface wl_surface_interface;
@ -40,7 +50,7 @@ extern const struct wl_interface xdg_positioner_interface;
extern const struct wl_interface xdg_surface_interface; extern const struct wl_interface xdg_surface_interface;
extern const struct wl_interface xdg_toplevel_interface; extern const struct wl_interface xdg_toplevel_interface;
static const struct wl_interface *xdg_shell_wl_xs_types[] = { static const struct wl_interface *xdg_shell_types[] = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
@ -70,102 +80,102 @@ static const struct wl_interface *xdg_shell_wl_xs_types[] = {
}; };
static const struct wl_message xdg_wm_base_requests[] = { static const struct wl_message xdg_wm_base_requests[] = {
{ "destroy", "", xdg_shell_wl_xs_types + 0 }, { "destroy", "", xdg_shell_types + 0 },
{ "create_positioner", "n", xdg_shell_wl_xs_types + 4 }, { "create_positioner", "n", xdg_shell_types + 4 },
{ "get_xdg_surface", "no", xdg_shell_wl_xs_types + 5 }, { "get_xdg_surface", "no", xdg_shell_types + 5 },
{ "pong", "u", xdg_shell_wl_xs_types + 0 }, { "pong", "u", xdg_shell_types + 0 },
}; };
static const struct wl_message xdg_wm_base_events[] = { static const struct wl_message xdg_wm_base_events[] = {
{ "ping", "u", xdg_shell_wl_xs_types + 0 }, { "ping", "u", xdg_shell_types + 0 },
}; };
WL_EXPORT const struct wl_interface xdg_wm_base_interface = { WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
"xdg_wm_base", 5, "xdg_wm_base", 5,
4, xdg_wm_base_requests, 4, xdg_wm_base_requests,
1, xdg_wm_base_events, 1, xdg_wm_base_events,
}; };
static const struct wl_message xdg_positioner_requests[] = { static const struct wl_message xdg_positioner_requests[] = {
{ "destroy", "", xdg_shell_wl_xs_types + 0 }, { "destroy", "", xdg_shell_types + 0 },
{ "set_size", "ii", xdg_shell_wl_xs_types + 0 }, { "set_size", "ii", xdg_shell_types + 0 },
{ "set_anchor_rect", "iiii", xdg_shell_wl_xs_types + 0 }, { "set_anchor_rect", "iiii", xdg_shell_types + 0 },
{ "set_anchor", "u", xdg_shell_wl_xs_types + 0 }, { "set_anchor", "u", xdg_shell_types + 0 },
{ "set_gravity", "u", xdg_shell_wl_xs_types + 0 }, { "set_gravity", "u", xdg_shell_types + 0 },
{ "set_constraint_adjustment", "u", xdg_shell_wl_xs_types + 0 }, { "set_constraint_adjustment", "u", xdg_shell_types + 0 },
{ "set_offset", "ii", xdg_shell_wl_xs_types + 0 }, { "set_offset", "ii", xdg_shell_types + 0 },
{ "set_reactive", "3", xdg_shell_wl_xs_types + 0 }, { "set_reactive", "3", xdg_shell_types + 0 },
{ "set_parent_size", "3ii", xdg_shell_wl_xs_types + 0 }, { "set_parent_size", "3ii", xdg_shell_types + 0 },
{ "set_parent_configure", "3u", xdg_shell_wl_xs_types + 0 }, { "set_parent_configure", "3u", xdg_shell_types + 0 },
}; };
WL_EXPORT const struct wl_interface xdg_positioner_interface = { WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
"xdg_positioner", 5, "xdg_positioner", 5,
10, xdg_positioner_requests, 10, xdg_positioner_requests,
0, NULL, 0, NULL,
}; };
static const struct wl_message xdg_surface_requests[] = { static const struct wl_message xdg_surface_requests[] = {
{ "destroy", "", xdg_shell_wl_xs_types + 0 }, { "destroy", "", xdg_shell_types + 0 },
{ "get_toplevel", "n", xdg_shell_wl_xs_types + 7 }, { "get_toplevel", "n", xdg_shell_types + 7 },
{ "get_popup", "n?oo", xdg_shell_wl_xs_types + 8 }, { "get_popup", "n?oo", xdg_shell_types + 8 },
{ "set_window_geometry", "iiii", xdg_shell_wl_xs_types + 0 }, { "set_window_geometry", "iiii", xdg_shell_types + 0 },
{ "ack_configure", "u", xdg_shell_wl_xs_types + 0 }, { "ack_configure", "u", xdg_shell_types + 0 },
}; };
static const struct wl_message xdg_surface_events[] = { static const struct wl_message xdg_surface_events[] = {
{ "configure", "u", xdg_shell_wl_xs_types + 0 }, { "configure", "u", xdg_shell_types + 0 },
}; };
WL_EXPORT const struct wl_interface xdg_surface_interface = { WL_PRIVATE const struct wl_interface xdg_surface_interface = {
"xdg_surface", 5, "xdg_surface", 5,
5, xdg_surface_requests, 5, xdg_surface_requests,
1, xdg_surface_events, 1, xdg_surface_events,
}; };
static const struct wl_message xdg_toplevel_requests[] = { static const struct wl_message xdg_toplevel_requests[] = {
{ "destroy", "", xdg_shell_wl_xs_types + 0 }, { "destroy", "", xdg_shell_types + 0 },
{ "set_parent", "?o", xdg_shell_wl_xs_types + 11 }, { "set_parent", "?o", xdg_shell_types + 11 },
{ "set_title", "s", xdg_shell_wl_xs_types + 0 }, { "set_title", "s", xdg_shell_types + 0 },
{ "set_app_id", "s", xdg_shell_wl_xs_types + 0 }, { "set_app_id", "s", xdg_shell_types + 0 },
{ "show_window_menu", "ouii", xdg_shell_wl_xs_types + 12 }, { "show_window_menu", "ouii", xdg_shell_types + 12 },
{ "move", "ou", xdg_shell_wl_xs_types + 16 }, { "move", "ou", xdg_shell_types + 16 },
{ "resize", "ouu", xdg_shell_wl_xs_types + 18 }, { "resize", "ouu", xdg_shell_types + 18 },
{ "set_max_size", "ii", xdg_shell_wl_xs_types + 0 }, { "set_max_size", "ii", xdg_shell_types + 0 },
{ "set_min_size", "ii", xdg_shell_wl_xs_types + 0 }, { "set_min_size", "ii", xdg_shell_types + 0 },
{ "set_maximized", "", xdg_shell_wl_xs_types + 0 }, { "set_maximized", "", xdg_shell_types + 0 },
{ "unset_maximized", "", xdg_shell_wl_xs_types + 0 }, { "unset_maximized", "", xdg_shell_types + 0 },
{ "set_fullscreen", "?o", xdg_shell_wl_xs_types + 21 }, { "set_fullscreen", "?o", xdg_shell_types + 21 },
{ "unset_fullscreen", "", xdg_shell_wl_xs_types + 0 }, { "unset_fullscreen", "", xdg_shell_types + 0 },
{ "set_minimized", "", xdg_shell_wl_xs_types + 0 }, { "set_minimized", "", xdg_shell_types + 0 },
}; };
static const struct wl_message xdg_toplevel_events[] = { static const struct wl_message xdg_toplevel_events[] = {
{ "configure", "iia", xdg_shell_wl_xs_types + 0 }, { "configure", "iia", xdg_shell_types + 0 },
{ "close", "", xdg_shell_wl_xs_types + 0 }, { "close", "", xdg_shell_types + 0 },
{ "configure_bounds", "4ii", xdg_shell_wl_xs_types + 0 }, { "configure_bounds", "4ii", xdg_shell_types + 0 },
{ "wm_capabilities", "5a", xdg_shell_wl_xs_types + 0 }, { "wm_capabilities", "5a", xdg_shell_types + 0 },
}; };
WL_EXPORT const struct wl_interface xdg_toplevel_interface = { WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
"xdg_toplevel", 5, "xdg_toplevel", 5,
14, xdg_toplevel_requests, 14, xdg_toplevel_requests,
4, xdg_toplevel_events, 4, xdg_toplevel_events,
}; };
static const struct wl_message xdg_popup_requests[] = { static const struct wl_message xdg_popup_requests[] = {
{ "destroy", "", xdg_shell_wl_xs_types + 0 }, { "destroy", "", xdg_shell_types + 0 },
{ "grab", "ou", xdg_shell_wl_xs_types + 22 }, { "grab", "ou", xdg_shell_types + 22 },
{ "reposition", "3ou", xdg_shell_wl_xs_types + 24 }, { "reposition", "3ou", xdg_shell_types + 24 },
}; };
static const struct wl_message xdg_popup_events[] = { static const struct wl_message xdg_popup_events[] = {
{ "configure", "iiii", xdg_shell_wl_xs_types + 0 }, { "configure", "iiii", xdg_shell_types + 0 },
{ "popup_done", "", xdg_shell_wl_xs_types + 0 }, { "popup_done", "", xdg_shell_types + 0 },
{ "repositioned", "3u", xdg_shell_wl_xs_types + 0 }, { "repositioned", "3u", xdg_shell_types + 0 },
}; };
WL_EXPORT const struct wl_interface xdg_popup_interface = { WL_PRIVATE const struct wl_interface xdg_popup_interface = {
"xdg_popup", 5, "xdg_popup", 5,
3, xdg_popup_requests, 3, xdg_popup_requests,
3, xdg_popup_events, 3, xdg_popup_events,

View file

@ -950,6 +950,7 @@ enum xdg_surface_error {
XDG_SURFACE_ERROR_NOT_CONSTRUCTED = 1, XDG_SURFACE_ERROR_NOT_CONSTRUCTED = 1,
XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED = 2, XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED = 2,
XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER = 3, XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER = 3,
XDG_SURFACE_ERROR_INVALID_SERIAL = 4,
}; };
#endif /* XDG_SURFACE_ERROR_ENUM */ #endif /* XDG_SURFACE_ERROR_ENUM */
@ -1168,6 +1169,17 @@ xdg_surface_set_window_geometry(struct xdg_surface *xdg_surface, int32_t x, int3
* A client may send multiple ack_configure requests before committing, but * A client may send multiple ack_configure requests before committing, but
* only the last request sent before a commit indicates which configure * only the last request sent before a commit indicates which configure
* event the client really is responding to. * event the client really is responding to.
*
* Sending an ack_configure request consumes the serial number sent with
* the request, as well as serial numbers sent by all configure events
* sent on this xdg_surface prior to the configure event referenced by
* the committed serial.
*
* It is an error to issue multiple ack_configure requests referencing a
* serial from the same configure event, or to issue an ack_configure
* request referencing a serial from a configure event issued before the
* event identified by the last ack_configure request for the same
* xdg_surface. Doing so will raise an invalid_serial error.
*/ */
static inline void static inline void
xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial) xdg_surface_ack_configure(struct xdg_surface *xdg_surface, uint32_t serial)
@ -1183,6 +1195,10 @@ enum xdg_toplevel_error {
* provided value is not a valid variant of the resize_edge enum * provided value is not a valid variant of the resize_edge enum
*/ */
XDG_TOPLEVEL_ERROR_INVALID_RESIZE_EDGE = 0, XDG_TOPLEVEL_ERROR_INVALID_RESIZE_EDGE = 0,
/**
* invalid parent toplevel
*/
XDG_TOPLEVEL_ERROR_INVALID_PARENT = 1,
}; };
#endif /* XDG_TOPLEVEL_ERROR_ENUM */ #endif /* XDG_TOPLEVEL_ERROR_ENUM */
@ -1595,6 +1611,10 @@ xdg_toplevel_destroy(struct xdg_toplevel *xdg_toplevel)
* the now-unmapped surface. If the now-unmapped surface has no parent, * the now-unmapped surface. If the now-unmapped surface has no parent,
* its children's parent is unset. If the now-unmapped surface becomes * its children's parent is unset. If the now-unmapped surface becomes
* mapped again, its parent-child relationship is not restored. * mapped again, its parent-child relationship is not restored.
*
* The parent toplevel must not be one of the child toplevel's
* descendants, and the parent must be different from the child toplevel,
* otherwise the invalid_parent protocol error is raised.
*/ */
static inline void static inline void
xdg_toplevel_set_parent(struct xdg_toplevel *xdg_toplevel, struct xdg_toplevel *parent) xdg_toplevel_set_parent(struct xdg_toplevel *xdg_toplevel, struct xdg_toplevel *parent)

View file

@ -30,15 +30,14 @@
#include "internal.h" #include "internal.h"
#include <stdlib.h> #include <stdlib.h>
#include <malloc.h>
#include <assert.h> #include <assert.h>
// Return the value corresponding to the specified attribute // Return the value corresponding to the specified attribute
// //
static int findPixelFormatAttribValue(const int* attribs, static int findPixelFormatAttribValueWGL(const int* attribs,
int attribCount, int attribCount,
const int* values, const int* values,
int attrib) int attrib)
{ {
int i; int i;
@ -53,19 +52,19 @@ static int findPixelFormatAttribValue(const int* attribs,
return 0; return 0;
} }
#define addAttrib(a) \ #define ADD_ATTRIB(a) \
{ \ { \
assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \ assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
attribs[attribCount++] = a; \ attribs[attribCount++] = a; \
} }
#define findAttribValue(a) \ #define FIND_ATTRIB_VALUE(a) \
findPixelFormatAttribValue(attribs, attribCount, values, a) findPixelFormatAttribValueWGL(attribs, attribCount, values, a)
// Return a list of available and usable framebuffer configs // Return a list of available and usable framebuffer configs
// //
static int choosePixelFormat(_GLFWwindow* window, static int choosePixelFormatWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
@ -73,64 +72,52 @@ static int choosePixelFormat(_GLFWwindow* window,
int attribs[40]; int attribs[40];
int values[sizeof(attribs) / sizeof(attribs[0])]; int values[sizeof(attribs) / sizeof(attribs[0])];
nativeCount = DescribePixelFormat(window->context.wgl.dc,
1,
sizeof(PIXELFORMATDESCRIPTOR),
NULL);
if (_glfw.wgl.ARB_pixel_format) if (_glfw.wgl.ARB_pixel_format)
{ {
const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB; ADD_ATTRIB(WGL_SUPPORT_OPENGL_ARB);
ADD_ATTRIB(WGL_DRAW_TO_WINDOW_ARB);
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc, ADD_ATTRIB(WGL_PIXEL_TYPE_ARB);
1, 0, 1, &attrib, &nativeCount)) ADD_ATTRIB(WGL_ACCELERATION_ARB);
{ ADD_ATTRIB(WGL_RED_BITS_ARB);
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, ADD_ATTRIB(WGL_RED_SHIFT_ARB);
"WGL: Failed to retrieve pixel format attribute"); ADD_ATTRIB(WGL_GREEN_BITS_ARB);
return 0; ADD_ATTRIB(WGL_GREEN_SHIFT_ARB);
} ADD_ATTRIB(WGL_BLUE_BITS_ARB);
ADD_ATTRIB(WGL_BLUE_SHIFT_ARB);
addAttrib(WGL_SUPPORT_OPENGL_ARB); ADD_ATTRIB(WGL_ALPHA_BITS_ARB);
addAttrib(WGL_DRAW_TO_WINDOW_ARB); ADD_ATTRIB(WGL_ALPHA_SHIFT_ARB);
addAttrib(WGL_PIXEL_TYPE_ARB); ADD_ATTRIB(WGL_DEPTH_BITS_ARB);
addAttrib(WGL_ACCELERATION_ARB); ADD_ATTRIB(WGL_STENCIL_BITS_ARB);
addAttrib(WGL_RED_BITS_ARB); ADD_ATTRIB(WGL_ACCUM_BITS_ARB);
addAttrib(WGL_RED_SHIFT_ARB); ADD_ATTRIB(WGL_ACCUM_RED_BITS_ARB);
addAttrib(WGL_GREEN_BITS_ARB); ADD_ATTRIB(WGL_ACCUM_GREEN_BITS_ARB);
addAttrib(WGL_GREEN_SHIFT_ARB); ADD_ATTRIB(WGL_ACCUM_BLUE_BITS_ARB);
addAttrib(WGL_BLUE_BITS_ARB); ADD_ATTRIB(WGL_ACCUM_ALPHA_BITS_ARB);
addAttrib(WGL_BLUE_SHIFT_ARB); ADD_ATTRIB(WGL_AUX_BUFFERS_ARB);
addAttrib(WGL_ALPHA_BITS_ARB); ADD_ATTRIB(WGL_STEREO_ARB);
addAttrib(WGL_ALPHA_SHIFT_ARB); ADD_ATTRIB(WGL_DOUBLE_BUFFER_ARB);
addAttrib(WGL_DEPTH_BITS_ARB);
addAttrib(WGL_STENCIL_BITS_ARB);
addAttrib(WGL_ACCUM_BITS_ARB);
addAttrib(WGL_ACCUM_RED_BITS_ARB);
addAttrib(WGL_ACCUM_GREEN_BITS_ARB);
addAttrib(WGL_ACCUM_BLUE_BITS_ARB);
addAttrib(WGL_ACCUM_ALPHA_BITS_ARB);
addAttrib(WGL_AUX_BUFFERS_ARB);
addAttrib(WGL_STEREO_ARB);
addAttrib(WGL_DOUBLE_BUFFER_ARB);
if (_glfw.wgl.ARB_multisample) if (_glfw.wgl.ARB_multisample)
addAttrib(WGL_SAMPLES_ARB); ADD_ATTRIB(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API) if (ctxconfig->client == GLFW_OPENGL_API)
{ {
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
addAttrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); ADD_ATTRIB(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
} }
else else
{ {
if (_glfw.wgl.EXT_colorspace) if (_glfw.wgl.EXT_colorspace)
addAttrib(WGL_COLORSPACE_EXT); ADD_ATTRIB(WGL_COLORSPACE_EXT);
} }
} }
else
{
nativeCount = DescribePixelFormat(window->context.wgl.dc,
1,
sizeof(PIXELFORMATDESCRIPTOR),
NULL);
}
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
for (i = 0; i < nativeCount; i++) for (i = 0; i < nativeCount; i++)
{ {
@ -149,52 +136,52 @@ static int choosePixelFormat(_GLFWwindow* window,
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attributes"); "WGL: Failed to retrieve pixel format attributes");
free(usableConfigs); _glfw_free(usableConfigs);
return 0; return 0;
} }
if (!findAttribValue(WGL_SUPPORT_OPENGL_ARB) || if (!FIND_ATTRIB_VALUE(WGL_SUPPORT_OPENGL_ARB) ||
!findAttribValue(WGL_DRAW_TO_WINDOW_ARB)) !FIND_ATTRIB_VALUE(WGL_DRAW_TO_WINDOW_ARB))
{ {
continue; continue;
} }
if (findAttribValue(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
continue; continue;
if (findAttribValue(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
continue; continue;
if (findAttribValue(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer) if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer)
continue; continue;
u->redBits = findAttribValue(WGL_RED_BITS_ARB); u->redBits = FIND_ATTRIB_VALUE(WGL_RED_BITS_ARB);
u->greenBits = findAttribValue(WGL_GREEN_BITS_ARB); u->greenBits = FIND_ATTRIB_VALUE(WGL_GREEN_BITS_ARB);
u->blueBits = findAttribValue(WGL_BLUE_BITS_ARB); u->blueBits = FIND_ATTRIB_VALUE(WGL_BLUE_BITS_ARB);
u->alphaBits = findAttribValue(WGL_ALPHA_BITS_ARB); u->alphaBits = FIND_ATTRIB_VALUE(WGL_ALPHA_BITS_ARB);
u->depthBits = findAttribValue(WGL_DEPTH_BITS_ARB); u->depthBits = FIND_ATTRIB_VALUE(WGL_DEPTH_BITS_ARB);
u->stencilBits = findAttribValue(WGL_STENCIL_BITS_ARB); u->stencilBits = FIND_ATTRIB_VALUE(WGL_STENCIL_BITS_ARB);
u->accumRedBits = findAttribValue(WGL_ACCUM_RED_BITS_ARB); u->accumRedBits = FIND_ATTRIB_VALUE(WGL_ACCUM_RED_BITS_ARB);
u->accumGreenBits = findAttribValue(WGL_ACCUM_GREEN_BITS_ARB); u->accumGreenBits = FIND_ATTRIB_VALUE(WGL_ACCUM_GREEN_BITS_ARB);
u->accumBlueBits = findAttribValue(WGL_ACCUM_BLUE_BITS_ARB); u->accumBlueBits = FIND_ATTRIB_VALUE(WGL_ACCUM_BLUE_BITS_ARB);
u->accumAlphaBits = findAttribValue(WGL_ACCUM_ALPHA_BITS_ARB); u->accumAlphaBits = FIND_ATTRIB_VALUE(WGL_ACCUM_ALPHA_BITS_ARB);
u->auxBuffers = findAttribValue(WGL_AUX_BUFFERS_ARB); u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB);
if (findAttribValue(WGL_STEREO_ARB)) if (FIND_ATTRIB_VALUE(WGL_STEREO_ARB))
u->stereo = GLFW_TRUE; u->stereo = GLFW_TRUE;
if (_glfw.wgl.ARB_multisample) if (_glfw.wgl.ARB_multisample)
u->samples = findAttribValue(WGL_SAMPLES_ARB); u->samples = FIND_ATTRIB_VALUE(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API) if (ctxconfig->client == GLFW_OPENGL_API)
{ {
if (_glfw.wgl.ARB_framebuffer_sRGB || if (_glfw.wgl.ARB_framebuffer_sRGB ||
_glfw.wgl.EXT_framebuffer_sRGB) _glfw.wgl.EXT_framebuffer_sRGB)
{ {
if (findAttribValue(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) if (FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
u->sRGB = GLFW_TRUE; u->sRGB = GLFW_TRUE;
} }
} }
@ -202,7 +189,7 @@ static int choosePixelFormat(_GLFWwindow* window,
{ {
if (_glfw.wgl.EXT_colorspace) if (_glfw.wgl.EXT_colorspace)
{ {
if (findAttribValue(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT) if (FIND_ATTRIB_VALUE(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
u->sRGB = GLFW_TRUE; u->sRGB = GLFW_TRUE;
} }
} }
@ -221,7 +208,7 @@ static int choosePixelFormat(_GLFWwindow* window,
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to describe pixel format"); "WGL: Failed to describe pixel format");
free(usableConfigs); _glfw_free(usableConfigs);
return 0; return 0;
} }
@ -271,7 +258,7 @@ static int choosePixelFormat(_GLFWwindow* window,
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"WGL: The driver does not appear to support OpenGL"); "WGL: The driver does not appear to support OpenGL");
free(usableConfigs); _glfw_free(usableConfigs);
return 0; return 0;
} }
@ -281,18 +268,18 @@ static int choosePixelFormat(_GLFWwindow* window,
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"WGL: Failed to find a suitable pixel format"); "WGL: Failed to find a suitable pixel format");
free(usableConfigs); _glfw_free(usableConfigs);
return 0; return 0;
} }
pixelFormat = (int) closest->handle; pixelFormat = (int) closest->handle;
free(usableConfigs); _glfw_free(usableConfigs);
return pixelFormat; return pixelFormat;
} }
#undef addAttrib #undef ADD_ATTRIB
#undef findAttribValue #undef FIND_ATTRIB_VALUE
static void makeContextCurrentWGL(_GLFWwindow* window) static void makeContextCurrentWGL(_GLFWwindow* window)
{ {
@ -323,14 +310,12 @@ static void swapBuffersWGL(_GLFWwindow* window)
{ {
if (!window->monitor) if (!window->monitor)
{ {
if (IsWindowsVistaOrGreater()) // HACK: Use DwmFlush when desktop composition is enabled on Windows Vista and 7
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
{ {
// DWM Composition is always enabled on Win8+ BOOL enabled = FALSE;
BOOL enabled = IsWindows8OrGreater();
// HACK: Use DwmFlush when desktop composition is enabled if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
if (enabled ||
(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled))
{ {
int count = abs(window->context.wgl.interval); int count = abs(window->context.wgl.interval);
while (count--) while (count--)
@ -350,15 +335,13 @@ static void swapIntervalWGL(int interval)
if (!window->monitor) if (!window->monitor)
{ {
if (IsWindowsVistaOrGreater()) // HACK: Disable WGL swap interval when desktop composition is enabled on Windows
// Vista and 7 to avoid interfering with DWM vsync
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
{ {
// DWM Composition is always enabled on Win8+ BOOL enabled = FALSE;
BOOL enabled = IsWindows8OrGreater();
// HACK: Disable WGL swap interval when desktop composition is enabled to if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
// avoid interfering with DWM vsync
if (enabled ||
(SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled))
interval = 0; interval = 0;
} }
} }
@ -388,7 +371,7 @@ static GLFWglproc getProcAddressWGL(const char* procname)
if (proc) if (proc)
return proc; return proc;
return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname); return (GLFWglproc) _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, procname);
} }
static void destroyContextWGL(_GLFWwindow* window) static void destroyContextWGL(_GLFWwindow* window)
@ -400,11 +383,6 @@ static void destroyContextWGL(_GLFWwindow* window)
} }
} }
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize WGL // Initialize WGL
// //
GLFWbool _glfwInitWGL(void) GLFWbool _glfwInitWGL(void)
@ -416,7 +394,7 @@ GLFWbool _glfwInitWGL(void)
if (_glfw.wgl.instance) if (_glfw.wgl.instance)
return GLFW_TRUE; return GLFW_TRUE;
_glfw.wgl.instance = LoadLibraryA("opengl32.dll"); _glfw.wgl.instance = _glfwPlatformLoadModule("opengl32.dll");
if (!_glfw.wgl.instance) if (!_glfw.wgl.instance)
{ {
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
@ -425,19 +403,19 @@ GLFWbool _glfwInitWGL(void)
} }
_glfw.wgl.CreateContext = (PFN_wglCreateContext) _glfw.wgl.CreateContext = (PFN_wglCreateContext)
GetProcAddress(_glfw.wgl.instance, "wglCreateContext"); _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglCreateContext");
_glfw.wgl.DeleteContext = (PFN_wglDeleteContext) _glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
GetProcAddress(_glfw.wgl.instance, "wglDeleteContext"); _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglDeleteContext");
_glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress) _glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress"); _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetProcAddress");
_glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC) _glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC"); _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentDC");
_glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext) _glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentContext"); _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentContext");
_glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent) _glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent"); _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglMakeCurrent");
_glfw.wgl.ShareLists = (PFN_wglShareLists) _glfw.wgl.ShareLists = (PFN_wglShareLists)
GetProcAddress(_glfw.wgl.instance, "wglShareLists"); _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglShareLists");
// NOTE: A dummy context has to be created for opengl32.dll to load the // NOTE: A dummy context has to be created for opengl32.dll to load the
// OpenGL ICD, from which we can then query WGL extensions // OpenGL ICD, from which we can then query WGL extensions
@ -530,10 +508,10 @@ GLFWbool _glfwInitWGL(void)
void _glfwTerminateWGL(void) void _glfwTerminateWGL(void)
{ {
if (_glfw.wgl.instance) if (_glfw.wgl.instance)
FreeLibrary(_glfw.wgl.instance); _glfwPlatformFreeModule(_glfw.wgl.instance);
} }
#define setAttrib(a, v) \ #define SET_ATTRIB(a, v) \
{ \ { \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \ attribs[index++] = a; \
@ -562,7 +540,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
return GLFW_FALSE; return GLFW_FALSE;
} }
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig); pixelFormat = choosePixelFormatWGL(window, ctxconfig, fbconfig);
if (!pixelFormat) if (!pixelFormat)
return GLFW_FALSE; return GLFW_FALSE;
@ -641,13 +619,13 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{ {
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{ {
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_NO_RESET_NOTIFICATION_ARB); WGL_NO_RESET_NOTIFICATION_ARB);
} }
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{ {
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_LOSE_CONTEXT_ON_RESET_ARB); WGL_LOSE_CONTEXT_ON_RESET_ARB);
} }
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
@ -660,13 +638,13 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{ {
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{ {
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
} }
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{ {
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
} }
} }
} }
@ -674,7 +652,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
if (ctxconfig->noerror) if (ctxconfig->noerror)
{ {
if (_glfw.wgl.ARB_create_context_no_error) if (_glfw.wgl.ARB_create_context_no_error)
setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
} }
// NOTE: Only request an explicitly versioned context when necessary, as // NOTE: Only request an explicitly versioned context when necessary, as
@ -682,17 +660,17 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
// highest version supported by the driver // highest version supported by the driver
if (ctxconfig->major != 1 || ctxconfig->minor != 0) if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{ {
setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
} }
if (flags) if (flags)
setAttrib(WGL_CONTEXT_FLAGS_ARB, flags); SET_ATTRIB(WGL_CONTEXT_FLAGS_ARB, flags);
if (mask) if (mask)
setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask); SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
setAttrib(0, 0); SET_ATTRIB(0, 0);
window->context.wgl.handle = window->context.wgl.handle =
wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs); wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs);
@ -775,19 +753,21 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
return GLFW_TRUE; return GLFW_TRUE;
} }
#undef setAttrib #undef SET_ATTRIB
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (window->context.client == GLFW_NO_API) if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
"WGL: Platform not initialized");
return NULL;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL; return NULL;

View file

@ -1,160 +0,0 @@
//========================================================================
// GLFW 3.4 WGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_TYPE_RGBA_ARB 0x202b
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201a
#define WGL_ALPHA_BITS_ARB 0x201b
#define WGL_ALPHA_SHIFT_ARB 0x201c
#define WGL_ACCUM_BITS_ARB 0x201d
#define WGL_ACCUM_RED_BITS_ARB 0x201e
#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_STEREO_ARB 0x2012
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_SAMPLES_ARB 0x2042
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
#define WGL_COLORSPACE_EXT 0x309d
#define WGL_COLORSPACE_SRGB_EXT 0x3089
#define ERROR_INVALID_VERSION_ARB 0x2095
#define ERROR_INVALID_PROFILE_ARB 0x2096
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
// WGL extension pointer typedefs
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);
#define wglSwapIntervalEXT _glfw.wgl.SwapIntervalEXT
#define wglGetPixelFormatAttribivARB _glfw.wgl.GetPixelFormatAttribivARB
#define wglGetExtensionsStringEXT _glfw.wgl.GetExtensionsStringEXT
#define wglGetExtensionsStringARB _glfw.wgl.GetExtensionsStringARB
#define wglCreateContextAttribsARB _glfw.wgl.CreateContextAttribsARB
// opengl32.dll function pointer typedefs
typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
#define wglCreateContext _glfw.wgl.CreateContext
#define wglDeleteContext _glfw.wgl.DeleteContext
#define wglGetProcAddress _glfw.wgl.GetProcAddress
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
#define wglGetCurrentContext _glfw.wgl.GetCurrentContext
#define wglMakeCurrent _glfw.wgl.MakeCurrent
#define wglShareLists _glfw.wgl.ShareLists
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl
// WGL-specific per-context data
//
typedef struct _GLFWcontextWGL
{
HDC dc;
HGLRC handle;
int interval;
} _GLFWcontextWGL;
// WGL-specific global data
//
typedef struct _GLFWlibraryWGL
{
HINSTANCE instance;
PFN_wglCreateContext CreateContext;
PFN_wglDeleteContext DeleteContext;
PFN_wglGetProcAddress GetProcAddress;
PFN_wglGetCurrentDC GetCurrentDC;
PFN_wglGetCurrentContext GetCurrentContext;
PFN_wglMakeCurrent MakeCurrent;
PFN_wglShareLists ShareLists;
PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool EXT_swap_control;
GLFWbool EXT_colorspace;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_pixel_format;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
} _GLFWlibraryWGL;
GLFWbool _glfwInitWGL(void);
void _glfwTerminateWGL(void);
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);

View file

@ -30,7 +30,6 @@
#include "internal.h" #include "internal.h"
#include <stdlib.h> #include <stdlib.h>
#include <malloc.h>
static const GUID _glfw_GUID_DEVINTERFACE_HID = static const GUID _glfw_GUID_DEVINTERFACE_HID =
{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}}; {0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
@ -40,7 +39,7 @@ static const GUID _glfw_GUID_DEVINTERFACE_HID =
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG) #if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
#if defined(_GLFW_BUILD_DLL) #if defined(_GLFW_BUILD_DLL)
#warning "These symbols must be exported by the executable and have no effect in a DLL" #pragma message("These symbols must be exported by the executable and have no effect in a DLL")
#endif #endif
// Executables (but not DLLs) exporting this symbol with this value will be // Executables (but not DLLs) exporting this symbol with this value will be
@ -72,18 +71,17 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
// //
static GLFWbool loadLibraries(void) static GLFWbool loadLibraries(void)
{ {
_glfw.win32.winmm.instance = LoadLibraryA("winmm.dll"); if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
if (!_glfw.win32.winmm.instance) GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(const WCHAR*) &_glfw,
(HMODULE*) &_glfw.win32.instance))
{ {
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to load winmm.dll"); "Win32: Failed to retrieve own module handle");
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfw.win32.winmm.GetTime = (PFN_timeGetTime) _glfw.win32.user32.instance = _glfwPlatformLoadModule("user32.dll");
GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
if (!_glfw.win32.user32.instance) if (!_glfw.win32.user32.instance)
{ {
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
@ -92,23 +90,25 @@ static GLFWbool loadLibraries(void)
} }
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware) _glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware"); _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDPIAware");
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx) _glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx"); _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling) _glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling"); _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext) _glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext"); _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext");
_glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow) _glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow"); _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetDpiForWindow");
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi) _glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi"); _glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
_glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetSystemMetricsForDpi");
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll"); _glfw.win32.dinput8.instance = _glfwPlatformLoadModule("dinput8.dll");
if (_glfw.win32.dinput8.instance) if (_glfw.win32.dinput8.instance)
{ {
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create) _glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create"); _glfwPlatformGetModuleSymbol(_glfw.win32.dinput8.instance, "DirectInput8Create");
} }
{ {
@ -125,46 +125,46 @@ static GLFWbool loadLibraries(void)
for (i = 0; names[i]; i++) for (i = 0; names[i]; i++)
{ {
_glfw.win32.xinput.instance = LoadLibraryA(names[i]); _glfw.win32.xinput.instance = _glfwPlatformLoadModule(names[i]);
if (_glfw.win32.xinput.instance) if (_glfw.win32.xinput.instance)
{ {
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities) _glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities"); _glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetCapabilities");
_glfw.win32.xinput.GetState = (PFN_XInputGetState) _glfw.win32.xinput.GetState = (PFN_XInputGetState)
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState"); _glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetState");
break; break;
} }
} }
} }
_glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll"); _glfw.win32.dwmapi.instance = _glfwPlatformLoadModule("dwmapi.dll");
if (_glfw.win32.dwmapi.instance) if (_glfw.win32.dwmapi.instance)
{ {
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled) _glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush) _glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush"); _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmFlush");
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow) _glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow"); _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor) _glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor"); _glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
} }
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll"); _glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll");
if (_glfw.win32.shcore.instance) if (_glfw.win32.shcore.instance)
{ {
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness) _glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness"); _glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
_glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor) _glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor"); _glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "GetDpiForMonitor");
} }
_glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll"); _glfw.win32.ntdll.instance = _glfwPlatformLoadModule("ntdll.dll");
if (_glfw.win32.ntdll.instance) if (_glfw.win32.ntdll.instance)
{ {
_glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo) _glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo"); _glfwPlatformGetModuleSymbol(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -175,25 +175,22 @@ static GLFWbool loadLibraries(void)
static void freeLibraries(void) static void freeLibraries(void)
{ {
if (_glfw.win32.xinput.instance) if (_glfw.win32.xinput.instance)
FreeLibrary(_glfw.win32.xinput.instance); _glfwPlatformFreeModule(_glfw.win32.xinput.instance);
if (_glfw.win32.dinput8.instance) if (_glfw.win32.dinput8.instance)
FreeLibrary(_glfw.win32.dinput8.instance); _glfwPlatformFreeModule(_glfw.win32.dinput8.instance);
if (_glfw.win32.winmm.instance)
FreeLibrary(_glfw.win32.winmm.instance);
if (_glfw.win32.user32.instance) if (_glfw.win32.user32.instance)
FreeLibrary(_glfw.win32.user32.instance); _glfwPlatformFreeModule(_glfw.win32.user32.instance);
if (_glfw.win32.dwmapi.instance) if (_glfw.win32.dwmapi.instance)
FreeLibrary(_glfw.win32.dwmapi.instance); _glfwPlatformFreeModule(_glfw.win32.dwmapi.instance);
if (_glfw.win32.shcore.instance) if (_glfw.win32.shcore.instance)
FreeLibrary(_glfw.win32.shcore.instance); _glfwPlatformFreeModule(_glfw.win32.shcore.instance);
if (_glfw.win32.ntdll.instance) if (_glfw.win32.ntdll.instance)
FreeLibrary(_glfw.win32.ntdll.instance); _glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
} }
// Create key code translation tables // Create key code translation tables
@ -266,7 +263,6 @@ static void createKeyTables(void)
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN; _glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP; _glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE; _glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
_glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE;
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE; _glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB; _glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK; _glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
@ -335,20 +331,69 @@ static void createKeyTables(void)
} }
} }
// Window procedure for the hidden helper window
//
static LRESULT CALLBACK helperWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DISPLAYCHANGE:
_glfwPollMonitorsWin32();
break;
case WM_DEVICECHANGE:
{
if (!_glfw.joysticksInitialized)
break;
if (wParam == DBT_DEVICEARRIVAL)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickConnectionWin32();
}
else if (wParam == DBT_DEVICEREMOVECOMPLETE)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickDisconnectionWin32();
}
break;
}
}
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
// Creates a dummy window for behind-the-scenes work // Creates a dummy window for behind-the-scenes work
// //
static GLFWbool createHelperWindow(void) static GLFWbool createHelperWindow(void)
{ {
MSG msg; MSG msg;
WNDCLASSEXW wc = { sizeof(wc) };
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) helperWindowProc;
wc.hInstance = _glfw.win32.instance;
wc.lpszClassName = L"GLFW3 Helper";
_glfw.win32.helperWindowClass = RegisterClassExW(&wc);
if (!_glfw.win32.helperWindowClass)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WIn32: Failed to register helper window class");
return GLFW_FALSE;
}
_glfw.win32.helperWindowHandle = _glfw.win32.helperWindowHandle =
CreateWindowExW(WS_EX_OVERLAPPEDWINDOW, CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
_GLFW_WNDCLASSNAME, MAKEINTATOM(_glfw.win32.helperWindowClass),
L"GLFW message window", L"GLFW message window",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, 1, 1, 0, 0, 1, 1,
NULL, NULL, NULL, NULL,
GetModuleHandleW(NULL), _glfw.win32.instance,
NULL); NULL);
if (!_glfw.win32.helperWindowHandle) if (!_glfw.win32.helperWindowHandle)
@ -405,13 +450,13 @@ WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
return NULL; return NULL;
} }
target = calloc(count, sizeof(WCHAR)); target = _glfw_calloc(count, sizeof(WCHAR));
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count)) if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
{ {
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8"); "Win32: Failed to convert string from UTF-8");
free(target); _glfw_free(target);
return NULL; return NULL;
} }
@ -433,13 +478,13 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
return NULL; return NULL;
} }
target = calloc(size, 1); target = _glfw_calloc(size, 1);
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL)) if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
{ {
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8"); "Win32: Failed to convert string to UTF-8");
free(target); _glfw_free(target);
return NULL; return NULL;
} }
@ -498,7 +543,7 @@ void _glfwUpdateKeyNamesWin32(void)
vk = vks[key - GLFW_KEY_KP_0]; vk = vks[key - GLFW_KEY_KP_0];
} }
else else
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK); vk = MapVirtualKeyW(scancode, MAPVK_VSC_TO_VK);
length = ToUnicode(vk, scancode, state, length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR), chars, sizeof(chars) / sizeof(WCHAR),
@ -506,6 +551,8 @@ void _glfwUpdateKeyNamesWin32(void)
if (length == -1) if (length == -1)
{ {
// This is a dead key, so we need a second simulated key press
// to make it output its own character (usually a diacritic)
length = ToUnicode(vk, scancode, state, length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR), chars, sizeof(chars) / sizeof(WCHAR),
0); 0);
@ -521,7 +568,8 @@ void _glfwUpdateKeyNamesWin32(void)
} }
} }
// Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h // Replacement for IsWindowsVersionOrGreater, as we cannot rely on the
// application having a correct embedded manifest
// //
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp) BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
{ {
@ -551,86 +599,129 @@ BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build)
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0; return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
} }
GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void)
{ {
// To make SetForegroundWindow work as we want, we need to fiddle const _GLFWplatform win32 =
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early {
// as possible in the hope of still being the foreground process) GLFW_PLATFORM_WIN32,
SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, _glfwInitWin32,
&_glfw.win32.foregroundLockTimeout, 0); _glfwTerminateWin32,
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0), _glfwGetCursorPosWin32,
SPIF_SENDCHANGE); _glfwSetCursorPosWin32,
_glfwSetCursorModeWin32,
_glfwSetRawMouseMotionWin32,
_glfwRawMouseMotionSupportedWin32,
_glfwCreateCursorWin32,
_glfwCreateStandardCursorWin32,
_glfwDestroyCursorWin32,
_glfwSetCursorWin32,
_glfwGetScancodeNameWin32,
_glfwGetKeyScancodeWin32,
_glfwSetClipboardStringWin32,
_glfwGetClipboardStringWin32,
_glfwInitJoysticksWin32,
_glfwTerminateJoysticksWin32,
_glfwPollJoystickWin32,
_glfwGetMappingNameWin32,
_glfwUpdateGamepadGUIDWin32,
_glfwFreeMonitorWin32,
_glfwGetMonitorPosWin32,
_glfwGetMonitorContentScaleWin32,
_glfwGetMonitorWorkareaWin32,
_glfwGetVideoModesWin32,
_glfwGetVideoModeWin32,
_glfwGetGammaRampWin32,
_glfwSetGammaRampWin32,
_glfwCreateWindowWin32,
_glfwDestroyWindowWin32,
_glfwSetWindowTitleWin32,
_glfwSetWindowIconWin32,
_glfwGetWindowPosWin32,
_glfwSetWindowPosWin32,
_glfwGetWindowSizeWin32,
_glfwSetWindowSizeWin32,
_glfwSetWindowSizeLimitsWin32,
_glfwSetWindowAspectRatioWin32,
_glfwGetFramebufferSizeWin32,
_glfwGetWindowFrameSizeWin32,
_glfwGetWindowContentScaleWin32,
_glfwIconifyWindowWin32,
_glfwRestoreWindowWin32,
_glfwMaximizeWindowWin32,
_glfwShowWindowWin32,
_glfwHideWindowWin32,
_glfwRequestWindowAttentionWin32,
_glfwFocusWindowWin32,
_glfwSetWindowMonitorWin32,
_glfwWindowFocusedWin32,
_glfwWindowIconifiedWin32,
_glfwWindowVisibleWin32,
_glfwWindowMaximizedWin32,
_glfwWindowHoveredWin32,
_glfwFramebufferTransparentWin32,
_glfwGetWindowOpacityWin32,
_glfwSetWindowResizableWin32,
_glfwSetWindowDecoratedWin32,
_glfwSetWindowFloatingWin32,
_glfwSetWindowOpacityWin32,
_glfwSetWindowMousePassthroughWin32,
_glfwPollEventsWin32,
_glfwWaitEventsWin32,
_glfwWaitEventsTimeoutWin32,
_glfwPostEmptyEventWin32,
_glfwGetEGLPlatformWin32,
_glfwGetEGLNativeDisplayWin32,
_glfwGetEGLNativeWindowWin32,
_glfwGetRequiredInstanceExtensionsWin32,
_glfwGetPhysicalDevicePresentationSupportWin32,
_glfwCreateWindowSurfaceWin32,
};
*platform = win32;
return GLFW_TRUE;
}
int _glfwInitWin32(void)
{
if (!loadLibraries()) if (!loadLibraries())
return GLFW_FALSE; return GLFW_FALSE;
createKeyTables(); createKeyTables();
_glfwUpdateKeyNamesWin32(); _glfwUpdateKeyNamesWin32();
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32()) if (_glfwIsWindows10Version1703OrGreaterWin32())
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
else if (IsWindows8Point1OrGreater()) else if (IsWindows8Point1OrGreater())
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
else if (IsWindowsVistaOrGreater()) else if (IsWindowsVistaOrGreater())
SetProcessDPIAware(); SetProcessDPIAware();
if (!_glfwRegisterWindowClassWin32())
return GLFW_FALSE;
if (!createHelperWindow()) if (!createHelperWindow())
return GLFW_FALSE; return GLFW_FALSE;
_glfwInitTimerWin32();
_glfwPollMonitorsWin32(); _glfwPollMonitorsWin32();
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformTerminate(void) void _glfwTerminateWin32(void)
{ {
if (_glfw.win32.deviceNotificationHandle) if (_glfw.win32.deviceNotificationHandle)
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle); UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
if (_glfw.win32.helperWindowHandle) if (_glfw.win32.helperWindowHandle)
DestroyWindow(_glfw.win32.helperWindowHandle); DestroyWindow(_glfw.win32.helperWindowHandle);
if (_glfw.win32.helperWindowClass)
UnregisterClassW(MAKEINTATOM(_glfw.win32.helperWindowClass), _glfw.win32.instance);
if (_glfw.win32.mainWindowClass)
UnregisterClassW(MAKEINTATOM(_glfw.win32.mainWindowClass), _glfw.win32.instance);
_glfwUnregisterWindowClassWin32(); _glfw_free(_glfw.win32.clipboardString);
_glfw_free(_glfw.win32.rawInput);
// Restore previous foreground lock timeout system setting
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
UIntToPtr(_glfw.win32.foregroundLockTimeout),
SPIF_SENDCHANGE);
free(_glfw.win32.clipboardString);
free(_glfw.win32.rawInput);
_glfwTerminateWGL(); _glfwTerminateWGL();
_glfwTerminateEGL(); _glfwTerminateEGL();
_glfwTerminateOSMesa();
freeLibraries(); freeLibraries();
} }
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " Win32 WGL EGL OSMesa"
#if defined(__MINGW64_VERSION_MAJOR)
" MinGW-w64"
#elif defined(__MINGW32__)
" MinGW"
#elif defined(_MSC_VER)
" VisualC"
#endif
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
" hybrid-GPU"
#endif
#if defined(_GLFW_BUILD_DLL)
" DLL"
#endif
;
}

View file

@ -199,11 +199,11 @@ static GLFWbool supportsXInput(const GUID* guid)
if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0) if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
return GLFW_FALSE; return GLFW_FALSE;
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST)); ridl = _glfw_calloc(count, sizeof(RAWINPUTDEVICELIST));
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1) if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
{ {
free(ridl); _glfw_free(ridl);
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -248,7 +248,7 @@ static GLFWbool supportsXInput(const GUID* guid)
} }
} }
free(ridl); _glfw_free(ridl);
return result; return result;
} }
@ -256,16 +256,16 @@ static GLFWbool supportsXInput(const GUID* guid)
// //
static void closeJoystick(_GLFWjoystick* js) static void closeJoystick(_GLFWjoystick* js)
{ {
_glfwInputJoystick(js, GLFW_DISCONNECTED);
if (js->win32.device) if (js->win32.device)
{ {
IDirectInputDevice8_Unacquire(js->win32.device); IDirectInputDevice8_Unacquire(js->win32.device);
IDirectInputDevice8_Release(js->win32.device); IDirectInputDevice8_Release(js->win32.device);
} }
free(js->win32.objects); _glfw_free(js->win32.objects);
_glfwFreeJoystick(js); _glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
} }
// DirectInput device object enumeration callback // DirectInput device object enumeration callback
@ -357,7 +357,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
js = _glfw.joysticks + jid; js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
{ {
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0) if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
@ -416,8 +416,8 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.device = device; data.device = device;
data.objects = calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs, data.objects = _glfw_calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs,
sizeof(_GLFWjoyobjectWin32)); sizeof(_GLFWjoyobjectWin32));
if (FAILED(IDirectInputDevice8_EnumObjects(device, if (FAILED(IDirectInputDevice8_EnumObjects(device,
deviceObjectCallback, deviceObjectCallback,
@ -428,7 +428,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
"Win32: Failed to enumerate device objects"); "Win32: Failed to enumerate device objects");
IDirectInputDevice8_Release(device); IDirectInputDevice8_Release(device);
free(data.objects); _glfw_free(data.objects);
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
@ -445,7 +445,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
"Win32: Failed to convert joystick name to UTF-8"); "Win32: Failed to convert joystick name to UTF-8");
IDirectInputDevice8_Release(device); IDirectInputDevice8_Release(device);
free(data.objects); _glfw_free(data.objects);
return DIENUM_STOP; return DIENUM_STOP;
} }
@ -473,7 +473,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
if (!js) if (!js)
{ {
IDirectInputDevice8_Release(device); IDirectInputDevice8_Release(device);
free(data.objects); _glfw_free(data.objects);
return DIENUM_STOP; return DIENUM_STOP;
} }
@ -508,7 +508,7 @@ void _glfwDetectJoystickConnectionWin32(void)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
if (_glfw.joysticks[jid].present && if (_glfw.joysticks[jid].connected &&
_glfw.joysticks[jid].win32.device == NULL && _glfw.joysticks[jid].win32.device == NULL &&
_glfw.joysticks[jid].win32.index == index) _glfw.joysticks[jid].win32.index == index)
{ {
@ -560,8 +560,8 @@ void _glfwDetectJoystickDisconnectionWin32(void)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{ {
_GLFWjoystick* js = _glfw.joysticks + jid; _GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present) if (js->connected)
_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); _glfwPollJoystickWin32(js, _GLFW_POLL_PRESENCE);
} }
} }
@ -570,11 +570,11 @@ void _glfwDetectJoystickDisconnectionWin32(void)
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformInitJoysticks(void) GLFWbool _glfwInitJoysticksWin32(void)
{ {
if (_glfw.win32.dinput8.instance) if (_glfw.win32.dinput8.instance)
{ {
if (FAILED(DirectInput8Create(GetModuleHandle(NULL), if (FAILED(DirectInput8Create(_glfw.win32.instance,
DIRECTINPUT_VERSION, DIRECTINPUT_VERSION,
&IID_IDirectInput8W, &IID_IDirectInput8W,
(void**) &_glfw.win32.dinput8.api, (void**) &_glfw.win32.dinput8.api,
@ -590,7 +590,7 @@ GLFWbool _glfwPlatformInitJoysticks(void)
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformTerminateJoysticks(void) void _glfwTerminateJoysticksWin32(void)
{ {
int jid; int jid;
@ -601,13 +601,13 @@ void _glfwPlatformTerminateJoysticks(void)
IDirectInput8_Release(_glfw.win32.dinput8.api); IDirectInput8_Release(_glfw.win32.dinput8.api);
} }
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) GLFWbool _glfwPollJoystickWin32(_GLFWjoystick* js, int mode)
{ {
if (js->win32.device) if (js->win32.device)
{ {
int i, ai = 0, bi = 0, pi = 0; int i, ai = 0, bi = 0, pi = 0;
HRESULT result; HRESULT result;
DIJOYSTATE state; DIJOYSTATE state = {0};
IDirectInputDevice8_Poll(js->win32.device); IDirectInputDevice8_Poll(js->win32.device);
result = IDirectInputDevice8_GetDeviceState(js->win32.device, result = IDirectInputDevice8_GetDeviceState(js->win32.device,
@ -740,7 +740,12 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformUpdateGamepadGUID(char* guid) const char* _glfwGetMappingNameWin32(void)
{
return "Windows";
}
void _glfwUpdateGamepadGUIDWin32(char* guid)
{ {
if (strcmp(guid + 20, "504944564944") == 0) if (strcmp(guid + 20, "504944564944") == 0)
{ {

View file

@ -24,10 +24,10 @@
// //
//======================================================================== //========================================================================
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32 #define GLFW_WIN32_JOYSTICK_STATE _GLFWjoystickWin32 win32;
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; } #define GLFW_WIN32_LIBRARY_JOYSTICK_STATE
#define _GLFW_PLATFORM_MAPPING_NAME "Windows" #define GLFW_BUILD_WIN32_MAPPINGS
// Joystick element (axis, button or slider) // Joystick element (axis, button or slider)
// //

49
raylib/external/glfw/src/win32_module.c vendored Normal file
View file

@ -0,0 +1,49 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2021 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// Please use C89 style variable declarations in this file because VS 2010
//========================================================================
#include "internal.h"
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwPlatformLoadModule(const char* path)
{
return LoadLibraryA(path);
}
void _glfwPlatformFreeModule(void* module)
{
FreeLibrary((HMODULE) module);
}
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
{
return (GLFWproc) GetProcAddress((HMODULE) module, name);
}

View file

@ -32,7 +32,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <malloc.h>
#include <wchar.h> #include <wchar.h>
@ -96,7 +95,7 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
DeleteDC(dc); DeleteDC(dc);
monitor = _glfwAllocMonitor(name, widthMM, heightMM); monitor = _glfwAllocMonitor(name, widthMM, heightMM);
free(name); _glfw_free(name);
if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED) if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
monitor->win32.modesPruned = GLFW_TRUE; monitor->win32.modesPruned = GLFW_TRUE;
@ -145,7 +144,7 @@ void _glfwPollMonitorsWin32(void)
disconnectedCount = _glfw.monitorCount; disconnectedCount = _glfw.monitorCount;
if (disconnectedCount) if (disconnectedCount)
{ {
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected, memcpy(disconnected,
_glfw.monitors, _glfw.monitors,
_glfw.monitorCount * sizeof(_GLFWmonitor*)); _glfw.monitorCount * sizeof(_GLFWmonitor*));
@ -197,7 +196,7 @@ void _glfwPollMonitorsWin32(void)
monitor = createMonitor(&adapter, &display); monitor = createMonitor(&adapter, &display);
if (!monitor) if (!monitor)
{ {
free(disconnected); _glfw_free(disconnected);
return; return;
} }
@ -227,7 +226,7 @@ void _glfwPollMonitorsWin32(void)
monitor = createMonitor(&adapter, NULL); monitor = createMonitor(&adapter, NULL);
if (!monitor) if (!monitor)
{ {
free(disconnected); _glfw_free(disconnected);
return; return;
} }
@ -241,7 +240,7 @@ void _glfwPollMonitorsWin32(void)
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
} }
free(disconnected); _glfw_free(disconnected);
} }
// Change the current video mode // Change the current video mode
@ -254,7 +253,7 @@ void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
LONG result; LONG result;
best = _glfwChooseVideoMode(monitor, desired); best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current); _glfwGetVideoModeWin32(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0) if (_glfwCompareVideoModes(&current, best) == 0)
return; return;
@ -314,12 +313,23 @@ void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
} }
} }
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale) void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* yscale)
{ {
UINT xdpi, ydpi; UINT xdpi, ydpi;
if (xscale)
*xscale = 0.f;
if (yscale)
*yscale = 0.f;
if (IsWindows8Point1OrGreater()) if (IsWindows8Point1OrGreater())
GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); {
if (GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi) != S_OK)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query monitor DPI");
return;
}
}
else else
{ {
const HDC dc = GetDC(NULL); const HDC dc = GetDC(NULL);
@ -339,11 +349,11 @@ void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* ysc
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) void _glfwFreeMonitorWin32(_GLFWmonitor* monitor)
{ {
} }
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) void _glfwGetMonitorPosWin32(_GLFWmonitor* monitor, int* xpos, int* ypos)
{ {
DEVMODEW dm; DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm)); ZeroMemory(&dm, sizeof(dm));
@ -360,18 +370,18 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
*ypos = dm.dmPosition.y; *ypos = dm.dmPosition.y;
} }
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, void _glfwGetMonitorContentScaleWin32(_GLFWmonitor* monitor,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
_glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale); _glfwGetHMONITORContentScaleWin32(monitor->win32.handle, xscale, yscale);
} }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, void _glfwGetMonitorWorkareaWin32(_GLFWmonitor* monitor,
int* xpos, int* ypos, int* xpos, int* ypos,
int* width, int* height) int* width, int* height)
{ {
MONITORINFO mi = { sizeof(mi) }; MONITORINFO mi = { sizeof(mi) };
GetMonitorInfo(monitor->win32.handle, &mi); GetMonitorInfoW(monitor->win32.handle, &mi);
if (xpos) if (xpos)
*xpos = mi.rcWork.left; *xpos = mi.rcWork.left;
@ -383,7 +393,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
*height = mi.rcWork.bottom - mi.rcWork.top; *height = mi.rcWork.bottom - mi.rcWork.top;
} }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) GLFWvidmode* _glfwGetVideoModesWin32(_GLFWmonitor* monitor, int* count)
{ {
int modeIndex = 0, size = 0; int modeIndex = 0, size = 0;
GLFWvidmode* result = NULL; GLFWvidmode* result = NULL;
@ -442,7 +452,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
if (*count == size) if (*count == size)
{ {
size += 128; size += 128;
result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode)); result = (GLFWvidmode*) _glfw_realloc(result, size * sizeof(GLFWvidmode));
} }
(*count)++; (*count)++;
@ -452,15 +462,15 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
if (!*count) if (!*count)
{ {
// HACK: Report the current mode if no valid modes were found // HACK: Report the current mode if no valid modes were found
result = calloc(1, sizeof(GLFWvidmode)); result = _glfw_calloc(1, sizeof(GLFWvidmode));
_glfwPlatformGetVideoMode(monitor, result); _glfwGetVideoModeWin32(monitor, result);
*count = 1; *count = 1;
} }
return result; return result;
} }
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) void _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode)
{ {
DEVMODEW dm; DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm)); ZeroMemory(&dm, sizeof(dm));
@ -477,7 +487,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
&mode->blueBits); &mode->blueBits);
} }
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
HDC dc; HDC dc;
WORD values[3][256]; WORD values[3][256];
@ -495,7 +505,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{ {
HDC dc; HDC dc;
WORD values[3][256]; WORD values[3][256];

View file

@ -162,7 +162,9 @@ typedef enum
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4) #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4)
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/ #endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header // Replacement for versionhelpers.h macros, as we cannot rely on the
// application having a correct embedded manifest
//
#define IsWindowsVistaOrGreater() \ #define IsWindowsVistaOrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \ _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
LOBYTE(_WIN32_WINNT_VISTA), 0) LOBYTE(_WIN32_WINNT_VISTA), 0)
@ -176,9 +178,11 @@ typedef enum
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \ _glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
LOBYTE(_WIN32_WINNT_WINBLUE), 0) LOBYTE(_WIN32_WINNT_WINBLUE), 0)
#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \ // Windows 10 Anniversary Update
#define _glfwIsWindows10Version1607OrGreaterWin32() \
_glfwIsWindows10BuildOrGreaterWin32(14393) _glfwIsWindows10BuildOrGreaterWin32(14393)
#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \ // Windows 10 Creators Update
#define _glfwIsWindows10Version1703OrGreaterWin32() \
_glfwIsWindows10BuildOrGreaterWin32(15063) _glfwIsWindows10BuildOrGreaterWin32(15063)
// HACK: Define macros that some xinput.h variants don't // HACK: Define macros that some xinput.h variants don't
@ -215,9 +219,56 @@ typedef enum
#define DIDFT_OPTIONAL 0x80000000 #define DIDFT_OPTIONAL 0x80000000
#endif #endif
// winmm.dll function pointer typedefs #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
typedef DWORD (WINAPI * PFN_timeGetTime)(void); #define WGL_SUPPORT_OPENGL_ARB 0x2010
#define timeGetTime _glfw.win32.winmm.GetTime #define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_TYPE_RGBA_ARB 0x202b
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201a
#define WGL_ALPHA_BITS_ARB 0x201b
#define WGL_ALPHA_SHIFT_ARB 0x201c
#define WGL_ACCUM_BITS_ARB 0x201d
#define WGL_ACCUM_RED_BITS_ARB 0x201e
#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_STEREO_ARB 0x2012
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_SAMPLES_ARB 0x2042
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
#define WGL_COLORSPACE_EXT 0x309d
#define WGL_COLORSPACE_SRGB_EXT 0x3089
#define ERROR_INVALID_VERSION_ARB 0x2095
#define ERROR_INVALID_PROFILE_ARB 0x2096
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
// xinput.dll function pointer typedefs // xinput.dll function pointer typedefs
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*); typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
@ -236,12 +287,14 @@ typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE); typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND); typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT); typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT);
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_ #define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_ #define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_ #define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_ #define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_ #define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_ #define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
#define GetSystemMetricsForDpi _glfw.win32.user32.GetSystemMetricsForDpi_
// dwmapi.dll function pointer typedefs // dwmapi.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*); typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
@ -263,6 +316,34 @@ typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG); typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
#define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_ #define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
// WGL extension pointer typedefs
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);
#define wglSwapIntervalEXT _glfw.wgl.SwapIntervalEXT
#define wglGetPixelFormatAttribivARB _glfw.wgl.GetPixelFormatAttribivARB
#define wglGetExtensionsStringEXT _glfw.wgl.GetExtensionsStringEXT
#define wglGetExtensionsStringARB _glfw.wgl.GetExtensionsStringARB
#define wglCreateContextAttribsARB _glfw.wgl.CreateContextAttribsARB
// opengl32.dll function pointer typedefs
typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
#define wglCreateContext _glfw.wgl.CreateContext
#define wglDeleteContext _glfw.wgl.DeleteContext
#define wglGetProcAddress _glfw.wgl.GetProcAddress
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
#define wglGetCurrentContext _glfw.wgl.GetCurrentContext
#define wglMakeCurrent _glfw.wgl.MakeCurrent
#define wglShareLists _glfw.wgl.ShareLists
typedef VkFlags VkWin32SurfaceCreateFlagsKHR; typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
typedef struct VkWin32SurfaceCreateInfoKHR typedef struct VkWin32SurfaceCreateInfoKHR
@ -277,25 +358,55 @@ typedef struct VkWin32SurfaceCreateInfoKHR
typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t); typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
#include "win32_joystick.h" #define GLFW_WIN32_WINDOW_STATE _GLFWwindowWin32 win32;
#include "wgl_context.h" #define GLFW_WIN32_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32;
#define GLFW_WIN32_MONITOR_STATE _GLFWmonitorWin32 win32;
#define GLFW_WIN32_CURSOR_STATE _GLFWcursorWin32 win32;
#if !defined(_GLFW_WNDCLASSNAME) #define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl;
#define _GLFW_WNDCLASSNAME L"GLFW30" #define GLFW_WGL_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl;
#endif
#define _glfw_dlopen(name) LoadLibraryA(name)
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32 // WGL-specific per-context data
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32 //
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32 typedef struct _GLFWcontextWGL
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32 {
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32 HDC dc;
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32 HGLRC handle;
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexWin32 win32 int interval;
} _GLFWcontextWGL;
// WGL-specific global data
//
typedef struct _GLFWlibraryWGL
{
HINSTANCE instance;
PFN_wglCreateContext CreateContext;
PFN_wglDeleteContext DeleteContext;
PFN_wglGetProcAddress GetProcAddress;
PFN_wglGetCurrentDC GetCurrentDC;
PFN_wglGetCurrentContext GetCurrentContext;
PFN_wglMakeCurrent MakeCurrent;
PFN_wglShareLists ShareLists;
PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool EXT_swap_control;
GLFWbool EXT_colorspace;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_pixel_format;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
} _GLFWlibraryWGL;
// Win32-specific per-window data // Win32-specific per-window data
// //
@ -319,18 +430,19 @@ typedef struct _GLFWwindowWin32
// The last received cursor position, regardless of source // The last received cursor position, regardless of source
int lastCursorPosX, lastCursorPosY; int lastCursorPosX, lastCursorPosY;
// The last recevied high surrogate when decoding pairs of UTF-16 messages // The last received high surrogate when decoding pairs of UTF-16 messages
WCHAR highSurrogate; WCHAR highSurrogate;
} _GLFWwindowWin32; } _GLFWwindowWin32;
// Win32-specific global data // Win32-specific global data
// //
typedef struct _GLFWlibraryWin32 typedef struct _GLFWlibraryWin32
{ {
HINSTANCE instance;
HWND helperWindowHandle; HWND helperWindowHandle;
ATOM helperWindowClass;
ATOM mainWindowClass;
HDEVNOTIFY deviceNotificationHandle; HDEVNOTIFY deviceNotificationHandle;
DWORD foregroundLockTimeout;
int acquiredMonitorCount; int acquiredMonitorCount;
char* clipboardString; char* clipboardString;
short int keycodes[512]; short int keycodes[512];
@ -340,15 +452,12 @@ typedef struct _GLFWlibraryWin32
double restoreCursorPosX, restoreCursorPosY; double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active // The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow; _GLFWwindow* disabledCursorWindow;
// The window the cursor is captured in
_GLFWwindow* capturedCursorWindow;
RAWINPUT* rawInput; RAWINPUT* rawInput;
int rawInputSize; int rawInputSize;
UINT mouseTrailSize; UINT mouseTrailSize;
struct {
HINSTANCE instance;
PFN_timeGetTime GetTime;
} winmm;
struct { struct {
HINSTANCE instance; HINSTANCE instance;
PFN_DirectInput8Create Create; PFN_DirectInput8Create Create;
@ -369,6 +478,7 @@ typedef struct _GLFWlibraryWin32
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_; PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
PFN_GetDpiForWindow GetDpiForWindow_; PFN_GetDpiForWindow GetDpiForWindow_;
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_; PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
PFN_GetSystemMetricsForDpi GetSystemMetricsForDpi_;
} user32; } user32;
struct { struct {
@ -389,7 +499,6 @@ typedef struct _GLFWlibraryWin32
HINSTANCE instance; HINSTANCE instance;
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_; PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
} ntdll; } ntdll;
} _GLFWlibraryWin32; } _GLFWlibraryWin32;
// Win32-specific per-monitor data // Win32-specific per-monitor data
@ -404,7 +513,6 @@ typedef struct _GLFWmonitorWin32
char publicDisplayName[32]; char publicDisplayName[32];
GLFWbool modesPruned; GLFWbool modesPruned;
GLFWbool modeChanged; GLFWbool modeChanged;
} _GLFWmonitorWin32; } _GLFWmonitorWin32;
// Win32-specific per-cursor data // Win32-specific per-cursor data
@ -412,39 +520,12 @@ typedef struct _GLFWmonitorWin32
typedef struct _GLFWcursorWin32 typedef struct _GLFWcursorWin32
{ {
HCURSOR handle; HCURSOR handle;
} _GLFWcursorWin32; } _GLFWcursorWin32;
// Win32-specific global timer data
//
typedef struct _GLFWtimerWin32
{
GLFWbool hasPC;
uint64_t frequency;
} _GLFWtimerWin32; GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform);
int _glfwInitWin32(void);
// Win32-specific thread local storage data void _glfwTerminateWin32(void);
//
typedef struct _GLFWtlsWin32
{
GLFWbool allocated;
DWORD index;
} _GLFWtlsWin32;
// Win32-specific mutex data
//
typedef struct _GLFWmutexWin32
{
GLFWbool allocated;
CRITICAL_SECTION section;
} _GLFWmutexWin32;
GLFWbool _glfwRegisterWindowClassWin32(void);
void _glfwUnregisterWindowClassWin32(void);
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source); WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source); char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
@ -453,10 +534,91 @@ BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
void _glfwInputErrorWin32(int error, const char* description); void _glfwInputErrorWin32(int error, const char* description);
void _glfwUpdateKeyNamesWin32(void); void _glfwUpdateKeyNamesWin32(void);
void _glfwInitTimerWin32(void);
void _glfwPollMonitorsWin32(void); void _glfwPollMonitorsWin32(void);
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired); void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor); void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale); void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);
GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowWin32(_GLFWwindow* window);
void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosWin32(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeWin32(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsWin32(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioWin32(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeWin32(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeWin32(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleWin32(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowWin32(_GLFWwindow* window);
void _glfwRestoreWindowWin32(_GLFWwindow* window);
void _glfwMaximizeWindowWin32(_GLFWwindow* window);
void _glfwShowWindowWin32(_GLFWwindow* window);
void _glfwHideWindowWin32(_GLFWwindow* window);
void _glfwRequestWindowAttentionWin32(_GLFWwindow* window);
void _glfwFocusWindowWin32(_GLFWwindow* window);
void _glfwSetWindowMonitorWin32(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedWin32(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedWin32(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleWin32(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedWin32(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredWin32(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentWin32(_GLFWwindow* window);
void _glfwSetWindowResizableWin32(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedWin32(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingWin32(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowMousePassthroughWin32(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityWin32(_GLFWwindow* window);
void _glfwSetWindowOpacityWin32(_GLFWwindow* window, float opacity);
void _glfwSetRawMouseMotionWin32(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedWin32(void);
void _glfwPollEventsWin32(void);
void _glfwWaitEventsWin32(void);
void _glfwWaitEventsTimeoutWin32(double timeout);
void _glfwPostEmptyEventWin32(void);
void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosWin32(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameWin32(int scancode);
int _glfwGetKeyScancodeWin32(int key);
GLFWbool _glfwCreateCursorWin32(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorWin32(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorWin32(_GLFWcursor* cursor);
void _glfwSetCursorWin32(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringWin32(const char* string);
const char* _glfwGetClipboardStringWin32(void);
EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayWin32(void);
EGLNativeWindowType _glfwGetEGLNativeWindowWin32(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsWin32(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportWin32(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorWin32(_GLFWmonitor* monitor);
void _glfwGetMonitorPosWin32(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleWin32(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaWin32(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesWin32(_GLFWmonitor* monitor, int* count);
void _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
GLFWbool _glfwInitJoysticksWin32(void);
void _glfwTerminateJoysticksWin32(void);
GLFWbool _glfwPollJoystickWin32(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameWin32(void);
void _glfwUpdateGamepadGUIDWin32(char* guid);
GLFWbool _glfwInitWGL(void);
void _glfwTerminateWGL(void);
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);

View file

@ -43,8 +43,7 @@ GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
tls->win32.index = TlsAlloc(); tls->win32.index = TlsAlloc();
if (tls->win32.index == TLS_OUT_OF_INDEXES) if (tls->win32.index == TLS_OUT_OF_INDEXES)
{ {
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to allocate TLS index");
"Win32: Failed to allocate TLS index");
return GLFW_FALSE; return GLFW_FALSE;
} }

48
raylib/external/glfw/src/win32_thread.h vendored Normal file
View file

@ -0,0 +1,48 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <windows.h>
#define GLFW_WIN32_TLS_STATE _GLFWtlsWin32 win32;
#define GLFW_WIN32_MUTEX_STATE _GLFWmutexWin32 win32;
// Win32-specific thread local storage data
//
typedef struct _GLFWtlsWin32
{
GLFWbool allocated;
DWORD index;
} _GLFWtlsWin32;
// Win32-specific mutex data
//
typedef struct _GLFWmutexWin32
{
GLFWbool allocated;
CRITICAL_SECTION section;
} _GLFWmutexWin32;

View file

@ -30,43 +30,20 @@
#include "internal.h" #include "internal.h"
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialise timer
//
void _glfwInitTimerWin32(void)
{
uint64_t frequency;
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))
{
_glfw.timer.win32.hasPC = GLFW_TRUE;
_glfw.timer.win32.frequency = frequency;
}
else
{
_glfw.timer.win32.hasPC = GLFW_FALSE;
_glfw.timer.win32.frequency = 1000;
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformInitTimer(void)
{
QueryPerformanceFrequency((LARGE_INTEGER*) &_glfw.timer.win32.frequency);
}
uint64_t _glfwPlatformGetTimerValue(void) uint64_t _glfwPlatformGetTimerValue(void)
{ {
if (_glfw.timer.win32.hasPC) uint64_t value;
{ QueryPerformanceCounter((LARGE_INTEGER*) &value);
uint64_t value; return value;
QueryPerformanceCounter((LARGE_INTEGER*) &value);
return value;
}
else
return (uint64_t) timeGetTime();
} }
uint64_t _glfwPlatformGetTimerFrequency(void) uint64_t _glfwPlatformGetTimerFrequency(void)

38
raylib/external/glfw/src/win32_time.h vendored Normal file
View file

@ -0,0 +1,38 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <windows.h>
#define GLFW_WIN32_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32;
// Win32-specific global timer data
//
typedef struct _GLFWtimerWin32
{
uint64_t frequency;
} _GLFWtimerWin32;

File diff suppressed because it is too large Load diff

View file

@ -44,6 +44,9 @@
// //
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused) void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
{ {
assert(window != NULL);
assert(focused == GLFW_TRUE || focused == GLFW_FALSE);
if (window->callbacks.focus) if (window->callbacks.focus)
window->callbacks.focus((GLFWwindow*) window, focused); window->callbacks.focus((GLFWwindow*) window, focused);
@ -55,7 +58,7 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
{ {
if (window->keys[key] == GLFW_PRESS) if (window->keys[key] == GLFW_PRESS)
{ {
const int scancode = _glfwPlatformGetKeyScancode(key); const int scancode = _glfw.platform.getKeyScancode(key);
_glfwInputKey(window, key, scancode, GLFW_RELEASE, 0); _glfwInputKey(window, key, scancode, GLFW_RELEASE, 0);
} }
} }
@ -73,6 +76,8 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
// //
void _glfwInputWindowPos(_GLFWwindow* window, int x, int y) void _glfwInputWindowPos(_GLFWwindow* window, int x, int y)
{ {
assert(window != NULL);
if (window->callbacks.pos) if (window->callbacks.pos)
window->callbacks.pos((GLFWwindow*) window, x, y); window->callbacks.pos((GLFWwindow*) window, x, y);
} }
@ -82,6 +87,10 @@ void _glfwInputWindowPos(_GLFWwindow* window, int x, int y)
// //
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height) void _glfwInputWindowSize(_GLFWwindow* window, int width, int height)
{ {
assert(window != NULL);
assert(width >= 0);
assert(height >= 0);
if (window->callbacks.size) if (window->callbacks.size)
window->callbacks.size((GLFWwindow*) window, width, height); window->callbacks.size((GLFWwindow*) window, width, height);
} }
@ -90,6 +99,9 @@ void _glfwInputWindowSize(_GLFWwindow* window, int width, int height)
// //
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified) void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
{ {
assert(window != NULL);
assert(iconified == GLFW_TRUE || iconified == GLFW_FALSE);
if (window->callbacks.iconify) if (window->callbacks.iconify)
window->callbacks.iconify((GLFWwindow*) window, iconified); window->callbacks.iconify((GLFWwindow*) window, iconified);
} }
@ -98,6 +110,9 @@ void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
// //
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized) void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized)
{ {
assert(window != NULL);
assert(maximized == GLFW_TRUE || maximized == GLFW_FALSE);
if (window->callbacks.maximize) if (window->callbacks.maximize)
window->callbacks.maximize((GLFWwindow*) window, maximized); window->callbacks.maximize((GLFWwindow*) window, maximized);
} }
@ -107,6 +122,10 @@ void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized)
// //
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height) void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height)
{ {
assert(window != NULL);
assert(width >= 0);
assert(height >= 0);
if (window->callbacks.fbsize) if (window->callbacks.fbsize)
window->callbacks.fbsize((GLFWwindow*) window, width, height); window->callbacks.fbsize((GLFWwindow*) window, width, height);
} }
@ -116,6 +135,12 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height)
// //
void _glfwInputWindowContentScale(_GLFWwindow* window, float xscale, float yscale) void _glfwInputWindowContentScale(_GLFWwindow* window, float xscale, float yscale)
{ {
assert(window != NULL);
assert(xscale > 0.f);
assert(xscale < FLT_MAX);
assert(yscale > 0.f);
assert(yscale < FLT_MAX);
if (window->callbacks.scale) if (window->callbacks.scale)
window->callbacks.scale((GLFWwindow*) window, xscale, yscale); window->callbacks.scale((GLFWwindow*) window, xscale, yscale);
} }
@ -124,6 +149,8 @@ void _glfwInputWindowContentScale(_GLFWwindow* window, float xscale, float yscal
// //
void _glfwInputWindowDamage(_GLFWwindow* window) void _glfwInputWindowDamage(_GLFWwindow* window)
{ {
assert(window != NULL);
if (window->callbacks.refresh) if (window->callbacks.refresh)
window->callbacks.refresh((GLFWwindow*) window); window->callbacks.refresh((GLFWwindow*) window);
} }
@ -132,6 +159,8 @@ void _glfwInputWindowDamage(_GLFWwindow* window)
// //
void _glfwInputWindowCloseRequest(_GLFWwindow* window) void _glfwInputWindowCloseRequest(_GLFWwindow* window)
{ {
assert(window != NULL);
window->shouldClose = GLFW_TRUE; window->shouldClose = GLFW_TRUE;
if (window->callbacks.close) if (window->callbacks.close)
@ -142,6 +171,7 @@ void _glfwInputWindowCloseRequest(_GLFWwindow* window)
// //
void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor) void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor)
{ {
assert(window != NULL);
window->monitor = monitor; window->monitor = monitor;
} }
@ -186,7 +216,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
if (!_glfwIsValidContextConfig(&ctxconfig)) if (!_glfwIsValidContextConfig(&ctxconfig))
return NULL; return NULL;
window = calloc(1, sizeof(_GLFWwindow)); window = _glfw_calloc(1, sizeof(_GLFWwindow));
window->next = _glfw.windowListHead; window->next = _glfw.windowListHead;
_glfw.windowListHead = window; _glfw.windowListHead = window;
@ -215,40 +245,12 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
window->numer = GLFW_DONT_CARE; window->numer = GLFW_DONT_CARE;
window->denom = GLFW_DONT_CARE; window->denom = GLFW_DONT_CARE;
// Open the actual window and create its context if (!_glfw.platform.createWindow(window, &wndconfig, &ctxconfig, &fbconfig))
if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig))
{ {
glfwDestroyWindow((GLFWwindow*) window); glfwDestroyWindow((GLFWwindow*) window);
return NULL; return NULL;
} }
if (ctxconfig.client != GLFW_NO_API)
{
if (!_glfwRefreshContextAttribs(window, &ctxconfig))
{
glfwDestroyWindow((GLFWwindow*) window);
return NULL;
}
}
if (wndconfig.mousePassthrough)
_glfwPlatformSetWindowMousePassthrough(window, GLFW_TRUE);
if (window->monitor)
{
if (wndconfig.centerCursor)
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig.visible)
{
_glfwPlatformShowWindow(window);
if (wndconfig.focused)
_glfwPlatformFocusWindow(window);
}
}
return (GLFWwindow*) window; return (GLFWwindow*) window;
} }
@ -272,6 +274,8 @@ void glfwDefaultWindowHints(void)
_glfw.hints.window.autoIconify = GLFW_TRUE; _glfw.hints.window.autoIconify = GLFW_TRUE;
_glfw.hints.window.centerCursor = GLFW_TRUE; _glfw.hints.window.centerCursor = GLFW_TRUE;
_glfw.hints.window.focusOnShow = GLFW_TRUE; _glfw.hints.window.focusOnShow = GLFW_TRUE;
_glfw.hints.window.xpos = GLFW_ANY_POSITION;
_glfw.hints.window.ypos = GLFW_ANY_POSITION;
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
// double buffered // double buffered
@ -366,6 +370,12 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_VISIBLE: case GLFW_VISIBLE:
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
case GLFW_POSITION_X:
_glfw.hints.window.xpos = value;
return;
case GLFW_POSITION_Y:
_glfw.hints.window.ypos = value;
return;
case GLFW_COCOA_RETINA_FRAMEBUFFER: case GLFW_COCOA_RETINA_FRAMEBUFFER:
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE; _glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
return; return;
@ -445,6 +455,10 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value)
strncpy(_glfw.hints.window.x11.instanceName, value, strncpy(_glfw.hints.window.x11.instanceName, value,
sizeof(_glfw.hints.window.x11.instanceName) - 1); sizeof(_glfw.hints.window.x11.instanceName) - 1);
return; return;
case GLFW_WAYLAND_APP_ID:
strncpy(_glfw.hints.window.wl.appId, value,
sizeof(_glfw.hints.window.wl.appId) - 1);
return;
} }
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint string 0x%08X", hint); _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint string 0x%08X", hint);
@ -468,7 +482,7 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
if (window == _glfwPlatformGetTls(&_glfw.contextSlot)) if (window == _glfwPlatformGetTls(&_glfw.contextSlot))
glfwMakeContextCurrent(NULL); glfwMakeContextCurrent(NULL);
_glfwPlatformDestroyWindow(window); _glfw.platform.destroyWindow(window);
// Unlink window from global linked list // Unlink window from global linked list
{ {
@ -480,7 +494,7 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
*prev = window->next; *prev = window->next;
} }
free(window); _glfw_free(window);
} }
GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle)
@ -508,19 +522,40 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
assert(title != NULL); assert(title != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformSetWindowTitle(window, title); _glfw.platform.setWindowTitle(window, title);
} }
GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle, GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle,
int count, const GLFWimage* images) int count, const GLFWimage* images)
{ {
int i;
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
assert(count >= 0); assert(count >= 0);
assert(count == 0 || images != NULL); assert(count == 0 || images != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformSetWindowIcon(window, count, images);
if (count < 0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid image count for window icon");
return;
}
for (i = 0; i < count; i++)
{
assert(images[i].pixels != NULL);
if (images[i].width <= 0 || images[i].height <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid image dimensions for window icon");
return;
}
}
_glfw.platform.setWindowIcon(window, count, images);
} }
GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
@ -534,7 +569,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos)
*ypos = 0; *ypos = 0;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetWindowPos(window, xpos, ypos); _glfw.platform.getWindowPos(window, xpos, ypos);
} }
GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
@ -547,7 +582,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos)
if (window->monitor) if (window->monitor)
return; return;
_glfwPlatformSetWindowPos(window, xpos, ypos); _glfw.platform.setWindowPos(window, xpos, ypos);
} }
GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
@ -561,7 +596,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height)
*height = 0; *height = 0;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetWindowSize(window, width, height); _glfw.platform.getWindowSize(window, width, height);
} }
GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
@ -576,7 +611,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
window->videoMode.width = width; window->videoMode.width = width;
window->videoMode.height = height; window->videoMode.height = height;
_glfwPlatformSetWindowSize(window, width, height); _glfw.platform.setWindowSize(window, width, height);
} }
GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
@ -619,9 +654,9 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
if (window->monitor || !window->resizable) if (window->monitor || !window->resizable)
return; return;
_glfwPlatformSetWindowSizeLimits(window, _glfw.platform.setWindowSizeLimits(window,
minwidth, minheight, minwidth, minheight,
maxwidth, maxheight); maxwidth, maxheight);
} }
GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
@ -650,7 +685,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
if (window->monitor || !window->resizable) if (window->monitor || !window->resizable)
return; return;
_glfwPlatformSetWindowAspectRatio(window, numer, denom); _glfw.platform.setWindowAspectRatio(window, numer, denom);
} }
GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height)
@ -664,7 +699,7 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height)
*height = 0; *height = 0;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetFramebufferSize(window, width, height); _glfw.platform.getFramebufferSize(window, width, height);
} }
GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
@ -684,7 +719,7 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle,
*bottom = 0; *bottom = 0;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetWindowFrameSize(window, left, top, right, bottom); _glfw.platform.getWindowFrameSize(window, left, top, right, bottom);
} }
GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle, GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle,
@ -699,7 +734,7 @@ GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle,
*yscale = 0.f; *yscale = 0.f;
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformGetWindowContentScale(window, xscale, yscale); _glfw.platform.getWindowContentScale(window, xscale, yscale);
} }
GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle) GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle)
@ -708,7 +743,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle)
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(1.f); _GLFW_REQUIRE_INIT_OR_RETURN(1.f);
return _glfwPlatformGetWindowOpacity(window); return _glfw.platform.getWindowOpacity(window);
} }
GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity) GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity)
@ -727,7 +762,7 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity)
return; return;
} }
_glfwPlatformSetWindowOpacity(window, opacity); _glfw.platform.setWindowOpacity(window, opacity);
} }
GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
@ -736,7 +771,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* handle)
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformIconifyWindow(window); _glfw.platform.iconifyWindow(window);
} }
GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
@ -745,7 +780,7 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformRestoreWindow(window); _glfw.platform.restoreWindow(window);
} }
GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
@ -758,7 +793,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
if (window->monitor) if (window->monitor)
return; return;
_glfwPlatformMaximizeWindow(window); _glfw.platform.maximizeWindow(window);
} }
GLFWAPI void glfwShowWindow(GLFWwindow* handle) GLFWAPI void glfwShowWindow(GLFWwindow* handle)
@ -771,10 +806,10 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
if (window->monitor) if (window->monitor)
return; return;
_glfwPlatformShowWindow(window); _glfw.platform.showWindow(window);
if (window->focusOnShow) if (window->focusOnShow)
_glfwPlatformFocusWindow(window); _glfw.platform.focusWindow(window);
} }
GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle) GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
@ -784,7 +819,7 @@ GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformRequestWindowAttention(window); _glfw.platform.requestWindowAttention(window);
} }
GLFWAPI void glfwHideWindow(GLFWwindow* handle) GLFWAPI void glfwHideWindow(GLFWwindow* handle)
@ -797,7 +832,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* handle)
if (window->monitor) if (window->monitor)
return; return;
_glfwPlatformHideWindow(window); _glfw.platform.hideWindow(window);
} }
GLFWAPI void glfwFocusWindow(GLFWwindow* handle) GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
@ -807,7 +842,7 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* handle)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformFocusWindow(window); _glfw.platform.focusWindow(window);
} }
GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
@ -820,21 +855,21 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
switch (attrib) switch (attrib)
{ {
case GLFW_FOCUSED: case GLFW_FOCUSED:
return _glfwPlatformWindowFocused(window); return _glfw.platform.windowFocused(window);
case GLFW_ICONIFIED: case GLFW_ICONIFIED:
return _glfwPlatformWindowIconified(window); return _glfw.platform.windowIconified(window);
case GLFW_VISIBLE: case GLFW_VISIBLE:
return _glfwPlatformWindowVisible(window); return _glfw.platform.windowVisible(window);
case GLFW_MAXIMIZED: case GLFW_MAXIMIZED:
return _glfwPlatformWindowMaximized(window); return _glfw.platform.windowMaximized(window);
case GLFW_HOVERED: case GLFW_HOVERED:
return _glfwPlatformWindowHovered(window); return _glfw.platform.windowHovered(window);
case GLFW_FOCUS_ON_SHOW: case GLFW_FOCUS_ON_SHOW:
return window->focusOnShow; return window->focusOnShow;
case GLFW_MOUSE_PASSTHROUGH: case GLFW_MOUSE_PASSTHROUGH:
return window->mousePassthrough; return window->mousePassthrough;
case GLFW_TRANSPARENT_FRAMEBUFFER: case GLFW_TRANSPARENT_FRAMEBUFFER:
return _glfwPlatformFramebufferTransparent(window); return _glfw.platform.framebufferTransparent(window);
case GLFW_RESIZABLE: case GLFW_RESIZABLE:
return window->resizable; return window->resizable;
case GLFW_DECORATED: case GLFW_DECORATED:
@ -882,35 +917,41 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
value = value ? GLFW_TRUE : GLFW_FALSE; value = value ? GLFW_TRUE : GLFW_FALSE;
if (attrib == GLFW_AUTO_ICONIFY) switch (attrib)
window->autoIconify = value;
else if (attrib == GLFW_RESIZABLE)
{ {
window->resizable = value; case GLFW_AUTO_ICONIFY:
if (!window->monitor) window->autoIconify = value;
_glfwPlatformSetWindowResizable(window, value); return;
case GLFW_RESIZABLE:
window->resizable = value;
if (!window->monitor)
_glfw.platform.setWindowResizable(window, value);
return;
case GLFW_DECORATED:
window->decorated = value;
if (!window->monitor)
_glfw.platform.setWindowDecorated(window, value);
return;
case GLFW_FLOATING:
window->floating = value;
if (!window->monitor)
_glfw.platform.setWindowFloating(window, value);
return;
case GLFW_FOCUS_ON_SHOW:
window->focusOnShow = value;
return;
case GLFW_MOUSE_PASSTHROUGH:
window->mousePassthrough = value;
_glfw.platform.setWindowMousePassthrough(window, value);
return;
} }
else if (attrib == GLFW_DECORATED)
{ _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
window->decorated = value;
if (!window->monitor)
_glfwPlatformSetWindowDecorated(window, value);
}
else if (attrib == GLFW_FLOATING)
{
window->floating = value;
if (!window->monitor)
_glfwPlatformSetWindowFloating(window, value);
}
else if (attrib == GLFW_FOCUS_ON_SHOW)
window->focusOnShow = value;
else if (attrib == GLFW_MOUSE_PASSTHROUGH)
{
window->mousePassthrough = value;
_glfwPlatformSetWindowMousePassthrough(window, value);
}
else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
} }
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
@ -956,9 +997,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
window->videoMode.height = height; window->videoMode.height = height;
window->videoMode.refreshRate = refreshRate; window->videoMode.refreshRate = refreshRate;
_glfwPlatformSetWindowMonitor(window, monitor, _glfw.platform.setWindowMonitor(window, monitor,
xpos, ypos, width, height, xpos, ypos, width, height,
refreshRate); refreshRate);
} }
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
@ -986,7 +1027,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun); _GLFW_SWAP(GLFWwindowposfun, window->callbacks.pos, cbfun);
return cbfun; return cbfun;
} }
@ -997,7 +1038,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.size, cbfun); _GLFW_SWAP(GLFWwindowsizefun, window->callbacks.size, cbfun);
return cbfun; return cbfun;
} }
@ -1008,7 +1049,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.close, cbfun); _GLFW_SWAP(GLFWwindowclosefun, window->callbacks.close, cbfun);
return cbfun; return cbfun;
} }
@ -1019,7 +1060,7 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun); _GLFW_SWAP(GLFWwindowrefreshfun, window->callbacks.refresh, cbfun);
return cbfun; return cbfun;
} }
@ -1030,7 +1071,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun); _GLFW_SWAP(GLFWwindowfocusfun, window->callbacks.focus, cbfun);
return cbfun; return cbfun;
} }
@ -1041,7 +1082,7 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun); _GLFW_SWAP(GLFWwindowiconifyfun, window->callbacks.iconify, cbfun);
return cbfun; return cbfun;
} }
@ -1052,7 +1093,7 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle,
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.maximize, cbfun); _GLFW_SWAP(GLFWwindowmaximizefun, window->callbacks.maximize, cbfun);
return cbfun; return cbfun;
} }
@ -1063,7 +1104,7 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun); _GLFW_SWAP(GLFWframebuffersizefun, window->callbacks.fbsize, cbfun);
return cbfun; return cbfun;
} }
@ -1074,20 +1115,20 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
assert(window != NULL); assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP_POINTERS(window->callbacks.scale, cbfun); _GLFW_SWAP(GLFWwindowcontentscalefun, window->callbacks.scale, cbfun);
return cbfun; return cbfun;
} }
GLFWAPI void glfwPollEvents(void) GLFWAPI void glfwPollEvents(void)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformPollEvents(); _glfw.platform.pollEvents();
} }
GLFWAPI void glfwWaitEvents(void) GLFWAPI void glfwWaitEvents(void)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformWaitEvents(); _glfw.platform.waitEvents();
} }
GLFWAPI void glfwWaitEventsTimeout(double timeout) GLFWAPI void glfwWaitEventsTimeout(double timeout)
@ -1103,12 +1144,12 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout)
return; return;
} }
_glfwPlatformWaitEventsTimeout(timeout); _glfw.platform.waitEventsTimeout(timeout);
} }
GLFWAPI void glfwPostEmptyEvent(void) GLFWAPI void glfwPostEmptyEvent(void)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformPostEmptyEvent(); _glfw.platform.postEmptyEvent();
} }

File diff suppressed because it is too large Load diff

View file

@ -34,8 +34,10 @@
#include <errno.h> #include <errno.h>
#include <math.h> #include <math.h>
#include "wayland-client-protocol.h"
static void outputHandleGeometry(void* data,
static void outputHandleGeometry(void* userData,
struct wl_output* output, struct wl_output* output,
int32_t x, int32_t x,
int32_t y, int32_t y,
@ -46,24 +48,25 @@ static void outputHandleGeometry(void* data,
const char* model, const char* model,
int32_t transform) int32_t transform)
{ {
struct _GLFWmonitor *monitor = data; struct _GLFWmonitor* monitor = userData;
monitor->wl.x = x; monitor->wl.x = x;
monitor->wl.y = y; monitor->wl.y = y;
monitor->widthMM = physicalWidth; monitor->widthMM = physicalWidth;
monitor->heightMM = physicalHeight; monitor->heightMM = physicalHeight;
snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model); if (strlen(monitor->name) == 0)
snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model);
} }
static void outputHandleMode(void* data, static void outputHandleMode(void* userData,
struct wl_output* output, struct wl_output* output,
uint32_t flags, uint32_t flags,
int32_t width, int32_t width,
int32_t height, int32_t height,
int32_t refresh) int32_t refresh)
{ {
struct _GLFWmonitor *monitor = data; struct _GLFWmonitor* monitor = userData;
GLFWvidmode mode; GLFWvidmode mode;
mode.width = width; mode.width = width;
@ -75,16 +78,16 @@ static void outputHandleMode(void* data,
monitor->modeCount++; monitor->modeCount++;
monitor->modes = monitor->modes =
realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode)); _glfw_realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
monitor->modes[monitor->modeCount - 1] = mode; monitor->modes[monitor->modeCount - 1] = mode;
if (flags & WL_OUTPUT_MODE_CURRENT) if (flags & WL_OUTPUT_MODE_CURRENT)
monitor->wl.currentMode = monitor->modeCount - 1; monitor->wl.currentMode = monitor->modeCount - 1;
} }
static void outputHandleDone(void* data, struct wl_output* output) static void outputHandleDone(void* userData, struct wl_output* output)
{ {
struct _GLFWmonitor *monitor = data; struct _GLFWmonitor* monitor = userData;
if (monitor->widthMM <= 0 || monitor->heightMM <= 0) if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
{ {
@ -94,23 +97,63 @@ static void outputHandleDone(void* data, struct wl_output* output)
monitor->heightMM = (int) (mode->height * 25.4f / 96.f); monitor->heightMM = (int) (mode->height * 25.4f / 96.f);
} }
for (int i = 0; i < _glfw.monitorCount; i++)
{
if (_glfw.monitors[i] == monitor)
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST); _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
} }
static void outputHandleScale(void* data, static void outputHandleScale(void* userData,
struct wl_output* output, struct wl_output* output,
int32_t factor) int32_t factor)
{ {
struct _GLFWmonitor *monitor = data; struct _GLFWmonitor* monitor = userData;
monitor->wl.scale = factor; monitor->wl.scale = factor;
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
{
for (int i = 0; i < window->wl.monitorsCount; i++)
{
if (window->wl.monitors[i] == monitor)
{
_glfwUpdateContentScaleWayland(window);
break;
}
}
}
} }
static const struct wl_output_listener outputListener = { #ifdef WL_OUTPUT_NAME_SINCE_VERSION
void outputHandleName(void* userData, struct wl_output* wl_output, const char* name)
{
struct _GLFWmonitor* monitor = userData;
strncpy(monitor->name, name, sizeof(monitor->name) - 1);
}
void outputHandleDescription(void* userData,
struct wl_output* wl_output,
const char* description)
{
}
#endif // WL_OUTPUT_NAME_SINCE_VERSION
static const struct wl_output_listener outputListener =
{
outputHandleGeometry, outputHandleGeometry,
outputHandleMode, outputHandleMode,
outputHandleDone, outputHandleDone,
outputHandleScale, outputHandleScale,
#ifdef WL_OUTPUT_NAME_SINCE_VERSION
outputHandleName,
outputHandleDescription,
#endif
}; };
@ -120,9 +163,6 @@ static const struct wl_output_listener outputListener = {
void _glfwAddOutputWayland(uint32_t name, uint32_t version) void _glfwAddOutputWayland(uint32_t name, uint32_t version)
{ {
_GLFWmonitor *monitor;
struct wl_output *output;
if (version < 2) if (version < 2)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -130,19 +170,21 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
return; return;
} }
// The actual name of this output will be set in the geometry handler. #ifdef WL_OUTPUT_NAME_SINCE_VERSION
monitor = _glfwAllocMonitor("", 0, 0); version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION);
#else
version = 2;
#endif
output = wl_registry_bind(_glfw.wl.registry, struct wl_output* output = wl_registry_bind(_glfw.wl.registry,
name, name,
&wl_output_interface, &wl_output_interface,
2); version);
if (!output) if (!output)
{
_glfwFreeMonitor(monitor);
return; return;
}
// The actual name of this output will be set in the geometry handler
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
monitor->wl.scale = 1; monitor->wl.scale = 1;
monitor->wl.output = output; monitor->wl.output = output;
monitor->wl.name = name; monitor->wl.name = name;
@ -155,13 +197,13 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) void _glfwFreeMonitorWayland(_GLFWmonitor* monitor)
{ {
if (monitor->wl.output) if (monitor->wl.output)
wl_output_destroy(monitor->wl.output); wl_output_destroy(monitor->wl.output);
} }
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) void _glfwGetMonitorPosWayland(_GLFWmonitor* monitor, int* xpos, int* ypos)
{ {
if (xpos) if (xpos)
*xpos = monitor->wl.x; *xpos = monitor->wl.x;
@ -169,8 +211,8 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
*ypos = monitor->wl.y; *ypos = monitor->wl.y;
} }
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
if (xscale) if (xscale)
*xscale = (float) monitor->wl.scale; *xscale = (float) monitor->wl.scale;
@ -178,9 +220,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = (float) monitor->wl.scale; *yscale = (float) monitor->wl.scale;
} }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor,
int* xpos, int* ypos, int* xpos, int* ypos,
int* width, int* height) int* width, int* height)
{ {
if (xpos) if (xpos)
*xpos = monitor->wl.x; *xpos = monitor->wl.x;
@ -192,26 +234,25 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
*height = monitor->modes[monitor->wl.currentMode].height; *height = monitor->modes[monitor->wl.currentMode].height;
} }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* found)
{ {
*found = monitor->modeCount; *found = monitor->modeCount;
return monitor->modes; return monitor->modes;
} }
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) void _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode)
{ {
*mode = monitor->modes[monitor->wl.currentMode]; *mode = monitor->modes[monitor->wl.currentMode];
} }
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
"Wayland: Gamma ramp access is not available"); "Wayland: Gamma ramp access is not available");
return GLFW_FALSE; return GLFW_FALSE;
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
const GLFWgammaramp* ramp)
{ {
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
"Wayland: Gamma ramp access is not available"); "Wayland: Gamma ramp access is not available");

View file

@ -24,12 +24,9 @@
// //
//======================================================================== //========================================================================
#include <wayland-client.h> #include <wayland-client-core.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#ifdef HAVE_XKBCOMMON_COMPOSE_H
#include <xkbcommon/xkbcommon-compose.h> #include <xkbcommon/xkbcommon-compose.h>
#endif
#include <dlfcn.h>
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
@ -45,33 +42,91 @@ typedef struct VkWaylandSurfaceCreateInfoKHR
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*); typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
#include "posix_thread.h"
#include "posix_time.h"
#ifdef __linux__
#include "linux_joystick.h"
#else
#include "null_joystick.h"
#endif
#include "xkb_unicode.h" #include "xkb_unicode.h"
#include "posix_poll.h"
#include "wayland-xdg-shell-client-protocol.h" typedef int (* PFN_wl_display_flush)(struct wl_display* display);
#include "wayland-xdg-decoration-client-protocol.h" typedef void (* PFN_wl_display_cancel_read)(struct wl_display* display);
#include "wayland-viewporter-client-protocol.h" typedef int (* PFN_wl_display_dispatch_pending)(struct wl_display* display);
#include "wayland-relative-pointer-unstable-v1-client-protocol.h" typedef int (* PFN_wl_display_read_events)(struct wl_display* display);
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h" typedef struct wl_display* (* PFN_wl_display_connect)(const char*);
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h" typedef void (* PFN_wl_display_disconnect)(struct wl_display*);
typedef int (* PFN_wl_display_roundtrip)(struct wl_display*);
typedef int (* PFN_wl_display_get_fd)(struct wl_display*);
typedef int (* PFN_wl_display_prepare_read)(struct wl_display*);
typedef void (* PFN_wl_proxy_marshal)(struct wl_proxy*,uint32_t,...);
typedef int (* PFN_wl_proxy_add_listener)(struct wl_proxy*,void(**)(void),void*);
typedef void (* PFN_wl_proxy_destroy)(struct wl_proxy*);
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor)(struct wl_proxy*,uint32_t,const struct wl_interface*,...);
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,...);
typedef void* (* PFN_wl_proxy_get_user_data)(struct wl_proxy*);
typedef void (* PFN_wl_proxy_set_user_data)(struct wl_proxy*,void*);
typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*);
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...);
#define wl_display_flush _glfw.wl.client.display_flush
#define wl_display_cancel_read _glfw.wl.client.display_cancel_read
#define wl_display_dispatch_pending _glfw.wl.client.display_dispatch_pending
#define wl_display_read_events _glfw.wl.client.display_read_events
#define wl_display_disconnect _glfw.wl.client.display_disconnect
#define wl_display_roundtrip _glfw.wl.client.display_roundtrip
#define wl_display_get_fd _glfw.wl.client.display_get_fd
#define wl_display_prepare_read _glfw.wl.client.display_prepare_read
#define wl_proxy_marshal _glfw.wl.client.proxy_marshal
#define wl_proxy_add_listener _glfw.wl.client.proxy_add_listener
#define wl_proxy_destroy _glfw.wl.client.proxy_destroy
#define wl_proxy_marshal_constructor _glfw.wl.client.proxy_marshal_constructor
#define wl_proxy_marshal_constructor_versioned _glfw.wl.client.proxy_marshal_constructor_versioned
#define wl_proxy_get_user_data _glfw.wl.client.proxy_get_user_data
#define wl_proxy_set_user_data _glfw.wl.client.proxy_set_user_data
#define wl_proxy_get_version _glfw.wl.client.proxy_get_version
#define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) struct wl_shm;
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl #define wl_display_interface _glfw_wl_display_interface
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl #define wl_subcompositor_interface _glfw_wl_subcompositor_interface
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wl #define wl_compositor_interface _glfw_wl_compositor_interface
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWayland wl #define wl_shm_interface _glfw_wl_shm_interface
#define wl_data_device_manager_interface _glfw_wl_data_device_manager_interface
#define wl_shell_interface _glfw_wl_shell_interface
#define wl_buffer_interface _glfw_wl_buffer_interface
#define wl_callback_interface _glfw_wl_callback_interface
#define wl_data_device_interface _glfw_wl_data_device_interface
#define wl_data_offer_interface _glfw_wl_data_offer_interface
#define wl_data_source_interface _glfw_wl_data_source_interface
#define wl_keyboard_interface _glfw_wl_keyboard_interface
#define wl_output_interface _glfw_wl_output_interface
#define wl_pointer_interface _glfw_wl_pointer_interface
#define wl_region_interface _glfw_wl_region_interface
#define wl_registry_interface _glfw_wl_registry_interface
#define wl_seat_interface _glfw_wl_seat_interface
#define wl_shell_surface_interface _glfw_wl_shell_surface_interface
#define wl_shm_pool_interface _glfw_wl_shm_pool_interface
#define wl_subsurface_interface _glfw_wl_subsurface_interface
#define wl_surface_interface _glfw_wl_surface_interface
#define wl_touch_interface _glfw_wl_touch_interface
#define zwp_idle_inhibitor_v1_interface _glfw_zwp_idle_inhibitor_v1_interface
#define zwp_idle_inhibit_manager_v1_interface _glfw_zwp_idle_inhibit_manager_v1_interface
#define zwp_confined_pointer_v1_interface _glfw_zwp_confined_pointer_v1_interface
#define zwp_locked_pointer_v1_interface _glfw_zwp_locked_pointer_v1_interface
#define zwp_pointer_constraints_v1_interface _glfw_zwp_pointer_constraints_v1_interface
#define zwp_relative_pointer_v1_interface _glfw_zwp_relative_pointer_v1_interface
#define zwp_relative_pointer_manager_v1_interface _glfw_zwp_relative_pointer_manager_v1_interface
#define wp_viewport_interface _glfw_wp_viewport_interface
#define wp_viewporter_interface _glfw_wp_viewporter_interface
#define xdg_toplevel_interface _glfw_xdg_toplevel_interface
#define zxdg_toplevel_decoration_v1_interface _glfw_zxdg_toplevel_decoration_v1_interface
#define zxdg_decoration_manager_v1_interface _glfw_zxdg_decoration_manager_v1_interface
#define xdg_popup_interface _glfw_xdg_popup_interface
#define xdg_positioner_interface _glfw_xdg_positioner_interface
#define xdg_surface_interface _glfw_xdg_surface_interface
#define xdg_toplevel_interface _glfw_xdg_toplevel_interface
#define xdg_wm_base_interface _glfw_xdg_wm_base_interface
#define _GLFW_PLATFORM_CONTEXT_STATE struct { int dummyContext; } #define GLFW_WAYLAND_WINDOW_STATE _GLFWwindowWayland wl;
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; } #define GLFW_WAYLAND_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl;
#define GLFW_WAYLAND_MONITOR_STATE _GLFWmonitorWayland wl;
#define GLFW_WAYLAND_CURSOR_STATE _GLFWcursorWayland wl;
struct wl_cursor_image { struct wl_cursor_image {
uint32_t width; uint32_t width;
@ -107,24 +162,27 @@ typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context
typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*); typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*); typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t); typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t);
typedef int (* PFN_xkb_keymap_key_get_syms_by_level)(struct xkb_keymap*,xkb_keycode_t,xkb_layout_index_t,xkb_level_index_t,const xkb_keysym_t**);
typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*); typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
typedef void (* PFN_xkb_state_unref)(struct xkb_state*); typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**); typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t); typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
typedef xkb_mod_mask_t (* PFN_xkb_state_serialize_mods)(struct xkb_state*, enum xkb_state_component); typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t);
typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,enum xkb_state_component);
#define xkb_context_new _glfw.wl.xkb.context_new #define xkb_context_new _glfw.wl.xkb.context_new
#define xkb_context_unref _glfw.wl.xkb.context_unref #define xkb_context_unref _glfw.wl.xkb.context_unref
#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string #define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
#define xkb_keymap_unref _glfw.wl.xkb.keymap_unref #define xkb_keymap_unref _glfw.wl.xkb.keymap_unref
#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index #define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index
#define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats #define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats
#define xkb_keymap_key_get_syms_by_level _glfw.wl.xkb.keymap_key_get_syms_by_level
#define xkb_state_new _glfw.wl.xkb.state_new #define xkb_state_new _glfw.wl.xkb.state_new
#define xkb_state_unref _glfw.wl.xkb.state_unref #define xkb_state_unref _glfw.wl.xkb.state_unref
#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms #define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms
#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask #define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
#define xkb_state_serialize_mods _glfw.wl.xkb.state_serialize_mods #define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout
#define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active
#ifdef HAVE_XKBCOMMON_COMPOSE_H
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags); typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*); typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags); typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags);
@ -139,12 +197,6 @@ typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_st
#define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed #define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed
#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status #define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status
#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym #define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym
#endif
#define _GLFW_DECORATION_WIDTH 4
#define _GLFW_DECORATION_TOP 24
#define _GLFW_DECORATION_VERTICAL (_GLFW_DECORATION_TOP + _GLFW_DECORATION_WIDTH)
#define _GLFW_DECORATION_HORIZONTAL (2 * _GLFW_DECORATION_WIDTH)
typedef enum _GLFWdecorationSideWayland typedef enum _GLFWdecorationSideWayland
{ {
@ -153,7 +205,6 @@ typedef enum _GLFWdecorationSideWayland
leftDecoration, leftDecoration,
rightDecoration, rightDecoration,
bottomDecoration, bottomDecoration,
} _GLFWdecorationSideWayland; } _GLFWdecorationSideWayland;
typedef struct _GLFWdecorationWayland typedef struct _GLFWdecorationWayland
@ -161,9 +212,15 @@ typedef struct _GLFWdecorationWayland
struct wl_surface* surface; struct wl_surface* surface;
struct wl_subsurface* subsurface; struct wl_subsurface* subsurface;
struct wp_viewport* viewport; struct wp_viewport* viewport;
} _GLFWdecorationWayland; } _GLFWdecorationWayland;
typedef struct _GLFWofferWayland
{
struct wl_data_offer* offer;
GLFWbool text_plain_utf8;
GLFWbool text_uri_list;
} _GLFWofferWayland;
// Wayland-specific per-window data // Wayland-specific per-window data
// //
typedef struct _GLFWwindowWayland typedef struct _GLFWwindowWayland
@ -171,22 +228,37 @@ typedef struct _GLFWwindowWayland
int width, height; int width, height;
GLFWbool visible; GLFWbool visible;
GLFWbool maximized; GLFWbool maximized;
GLFWbool activated;
GLFWbool fullscreen;
GLFWbool hovered; GLFWbool hovered;
GLFWbool transparent; GLFWbool transparent;
struct wl_surface* surface; struct wl_surface* surface;
struct wl_egl_window* native;
struct wl_callback* callback; struct wl_callback* callback;
struct {
struct wl_egl_window* window;
} egl;
struct {
int width, height;
GLFWbool maximized;
GLFWbool iconified;
GLFWbool activated;
GLFWbool fullscreen;
} pending;
struct { struct {
struct xdg_surface* surface; struct xdg_surface* surface;
struct xdg_toplevel* toplevel; struct xdg_toplevel* toplevel;
struct zxdg_toplevel_decoration_v1* decoration; struct zxdg_toplevel_decoration_v1* decoration;
uint32_t decorationMode;
} xdg; } xdg;
_GLFWcursor* currentCursor; _GLFWcursor* currentCursor;
double cursorPosX, cursorPosY; double cursorPosX, cursorPosY;
char* title; char* title;
char* appId;
// We need to track the monitors the window spans on to calculate the // We need to track the monitors the window spans on to calculate the
// optimal scaling factor. // optimal scaling factor.
@ -195,22 +267,17 @@ typedef struct _GLFWwindowWayland
int monitorsCount; int monitorsCount;
int monitorsSize; int monitorsSize;
struct { struct zwp_relative_pointer_v1* relativePointer;
struct zwp_relative_pointer_v1* relativePointer; struct zwp_locked_pointer_v1* lockedPointer;
struct zwp_locked_pointer_v1* lockedPointer; struct zwp_confined_pointer_v1* confinedPointer;
} pointerLock;
struct zwp_idle_inhibitor_v1* idleInhibitor; struct zwp_idle_inhibitor_v1* idleInhibitor;
GLFWbool wasFullscreen;
struct { struct {
GLFWbool serverSide;
struct wl_buffer* buffer; struct wl_buffer* buffer;
_GLFWdecorationWayland top, left, right, bottom; _GLFWdecorationWayland top, left, right, bottom;
int focus; _GLFWdecorationSideWayland focus;
} decorations; } decorations;
} _GLFWwindowWayland; } _GLFWwindowWayland;
// Wayland-specific global data // Wayland-specific global data
@ -227,8 +294,6 @@ typedef struct _GLFWlibraryWayland
struct wl_keyboard* keyboard; struct wl_keyboard* keyboard;
struct wl_data_device_manager* dataDeviceManager; struct wl_data_device_manager* dataDeviceManager;
struct wl_data_device* dataDevice; struct wl_data_device* dataDevice;
struct wl_data_offer* dataOffer;
struct wl_data_source* dataSource;
struct xdg_wm_base* wmBase; struct xdg_wm_base* wmBase;
struct zxdg_decoration_manager_v1* decorationManager; struct zxdg_decoration_manager_v1* decorationManager;
struct wp_viewporter* viewporter; struct wp_viewporter* viewporter;
@ -236,6 +301,16 @@ typedef struct _GLFWlibraryWayland
struct zwp_pointer_constraints_v1* pointerConstraints; struct zwp_pointer_constraints_v1* pointerConstraints;
struct zwp_idle_inhibit_manager_v1* idleInhibitManager; struct zwp_idle_inhibit_manager_v1* idleInhibitManager;
_GLFWofferWayland* offers;
unsigned int offerCount;
struct wl_data_offer* selectionOffer;
struct wl_data_source* selectionSource;
struct wl_data_offer* dragOffer;
_GLFWwindow* dragFocus;
uint32_t dragSerial;
int compositorVersion; int compositorVersion;
int seatVersion; int seatVersion;
@ -245,18 +320,17 @@ typedef struct _GLFWlibraryWayland
const char* cursorPreviousName; const char* cursorPreviousName;
int cursorTimerfd; int cursorTimerfd;
uint32_t serial; uint32_t serial;
uint32_t pointerEnterSerial;
int keyRepeatTimerfd;
int32_t keyRepeatRate;
int32_t keyRepeatDelay;
int keyRepeatScancode;
int32_t keyboardRepeatRate;
int32_t keyboardRepeatDelay;
int keyboardLastKey;
int keyboardLastScancode;
char* clipboardString; char* clipboardString;
size_t clipboardSize;
char* clipboardSendString;
size_t clipboardSendSize;
int timerfd;
short int keycodes[256]; short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1]; short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
struct { struct {
void* handle; void* handle;
@ -264,16 +338,14 @@ typedef struct _GLFWlibraryWayland
struct xkb_keymap* keymap; struct xkb_keymap* keymap;
struct xkb_state* state; struct xkb_state* state;
#ifdef HAVE_XKBCOMMON_COMPOSE_H
struct xkb_compose_state* composeState; struct xkb_compose_state* composeState;
#endif
xkb_mod_mask_t controlMask; xkb_mod_index_t controlIndex;
xkb_mod_mask_t altMask; xkb_mod_index_t altIndex;
xkb_mod_mask_t shiftMask; xkb_mod_index_t shiftIndex;
xkb_mod_mask_t superMask; xkb_mod_index_t superIndex;
xkb_mod_mask_t capsLockMask; xkb_mod_index_t capsLockIndex;
xkb_mod_mask_t numLockMask; xkb_mod_index_t numLockIndex;
unsigned int modifiers; unsigned int modifiers;
PFN_xkb_context_new context_new; PFN_xkb_context_new context_new;
@ -282,13 +354,14 @@ typedef struct _GLFWlibraryWayland
PFN_xkb_keymap_unref keymap_unref; PFN_xkb_keymap_unref keymap_unref;
PFN_xkb_keymap_mod_get_index keymap_mod_get_index; PFN_xkb_keymap_mod_get_index keymap_mod_get_index;
PFN_xkb_keymap_key_repeats keymap_key_repeats; PFN_xkb_keymap_key_repeats keymap_key_repeats;
PFN_xkb_keymap_key_get_syms_by_level keymap_key_get_syms_by_level;
PFN_xkb_state_new state_new; PFN_xkb_state_new state_new;
PFN_xkb_state_unref state_unref; PFN_xkb_state_unref state_unref;
PFN_xkb_state_key_get_syms state_key_get_syms; PFN_xkb_state_key_get_syms state_key_get_syms;
PFN_xkb_state_update_mask state_update_mask; PFN_xkb_state_update_mask state_update_mask;
PFN_xkb_state_serialize_mods state_serialize_mods; PFN_xkb_state_key_get_layout state_key_get_layout;
PFN_xkb_state_mod_index_is_active state_mod_index_is_active;
#ifdef HAVE_XKBCOMMON_COMPOSE_H
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale; PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
PFN_xkb_compose_table_unref compose_table_unref; PFN_xkb_compose_table_unref compose_table_unref;
PFN_xkb_compose_state_new compose_state_new; PFN_xkb_compose_state_new compose_state_new;
@ -296,12 +369,32 @@ typedef struct _GLFWlibraryWayland
PFN_xkb_compose_state_feed compose_state_feed; PFN_xkb_compose_state_feed compose_state_feed;
PFN_xkb_compose_state_get_status compose_state_get_status; PFN_xkb_compose_state_get_status compose_state_get_status;
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym; PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
#endif
} xkb; } xkb;
_GLFWwindow* pointerFocus; _GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus; _GLFWwindow* keyboardFocus;
struct {
void* handle;
PFN_wl_display_flush display_flush;
PFN_wl_display_cancel_read display_cancel_read;
PFN_wl_display_dispatch_pending display_dispatch_pending;
PFN_wl_display_read_events display_read_events;
PFN_wl_display_disconnect display_disconnect;
PFN_wl_display_roundtrip display_roundtrip;
PFN_wl_display_get_fd display_get_fd;
PFN_wl_display_prepare_read display_prepare_read;
PFN_wl_proxy_marshal proxy_marshal;
PFN_wl_proxy_add_listener proxy_add_listener;
PFN_wl_proxy_destroy proxy_destroy;
PFN_wl_proxy_marshal_constructor proxy_marshal_constructor;
PFN_wl_proxy_marshal_constructor_versioned proxy_marshal_constructor_versioned;
PFN_wl_proxy_get_user_data proxy_get_user_data;
PFN_wl_proxy_set_user_data proxy_set_user_data;
PFN_wl_proxy_get_version proxy_get_version;
PFN_wl_proxy_marshal_flags proxy_marshal_flags;
} client;
struct { struct {
void* handle; void* handle;
@ -318,7 +411,6 @@ typedef struct _GLFWlibraryWayland
PFN_wl_egl_window_destroy window_destroy; PFN_wl_egl_window_destroy window_destroy;
PFN_wl_egl_window_resize window_resize; PFN_wl_egl_window_resize window_resize;
} egl; } egl;
} _GLFWlibraryWayland; } _GLFWlibraryWayland;
// Wayland-specific per-monitor data // Wayland-specific per-monitor data
@ -332,7 +424,6 @@ typedef struct _GLFWmonitorWayland
int x; int x;
int y; int y;
int scale; int scale;
} _GLFWmonitorWayland; } _GLFWmonitorWayland;
// Wayland-specific per-cursor data // Wayland-specific per-cursor data
@ -347,6 +438,84 @@ typedef struct _GLFWcursorWayland
int currentImage; int currentImage;
} _GLFWcursorWayland; } _GLFWcursorWayland;
GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform);
int _glfwInitWayland(void);
void _glfwTerminateWayland(void);
GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowWayland(_GLFWwindow* window);
void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconWayland(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeWayland(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeWayland(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleWayland(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowWayland(_GLFWwindow* window);
void _glfwRestoreWindowWayland(_GLFWwindow* window);
void _glfwMaximizeWindowWayland(_GLFWwindow* window);
void _glfwShowWindowWayland(_GLFWwindow* window);
void _glfwHideWindowWayland(_GLFWwindow* window);
void _glfwRequestWindowAttentionWayland(_GLFWwindow* window);
void _glfwFocusWindowWayland(_GLFWwindow* window);
void _glfwSetWindowMonitorWayland(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedWayland(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedWayland(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleWayland(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedWayland(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window);
void _glfwSetWindowResizableWayland(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingWayland(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityWayland(_GLFWwindow* window);
void _glfwSetWindowOpacityWayland(_GLFWwindow* window, float opacity);
void _glfwSetWindowMousePassthroughWayland(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetRawMouseMotionWayland(_GLFWwindow* window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedWayland(void);
void _glfwPollEventsWayland(void);
void _glfwWaitEventsWayland(void);
void _glfwWaitEventsTimeoutWayland(double timeout);
void _glfwPostEmptyEventWayland(void);
void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosWayland(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameWayland(int scancode);
int _glfwGetKeyScancodeWayland(int key);
GLFWbool _glfwCreateCursorWayland(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorWayland(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorWayland(_GLFWcursor* cursor);
void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringWayland(const char* string);
const char* _glfwGetClipboardStringWayland(void);
EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayWayland(void);
EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsWayland(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportWayland(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorWayland(_GLFWmonitor* monitor);
void _glfwGetMonitorPosWayland(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* count);
void _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwAddOutputWayland(uint32_t name, uint32_t version); void _glfwAddOutputWayland(uint32_t name, uint32_t version);
void _glfwUpdateContentScaleWayland(_GLFWwindow* window);
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -116,7 +116,7 @@ void _glfwPollMonitorsX11(void)
disconnectedCount = _glfw.monitorCount; disconnectedCount = _glfw.monitorCount;
if (disconnectedCount) if (disconnectedCount)
{ {
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected, memcpy(disconnected,
_glfw.monitors, _glfw.monitors,
_glfw.monitorCount * sizeof(_GLFWmonitor*)); _glfw.monitorCount * sizeof(_GLFWmonitor*));
@ -209,7 +209,7 @@ void _glfwPollMonitorsX11(void)
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
} }
free(disconnected); _glfw_free(disconnected);
} }
else else
{ {
@ -232,7 +232,7 @@ void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
RRMode native = None; RRMode native = None;
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired); const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current); _glfwGetVideoModeX11(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0) if (_glfwCompareVideoModes(&current, best) == 0)
return; return;
@ -310,11 +310,11 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) void _glfwFreeMonitorX11(_GLFWmonitor* monitor)
{ {
} }
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) void _glfwGetMonitorPosX11(_GLFWmonitor* monitor, int* xpos, int* ypos)
{ {
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{ {
@ -336,8 +336,8 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
} }
} }
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, void _glfwGetMonitorContentScaleX11(_GLFWmonitor* monitor,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
if (xscale) if (xscale)
*xscale = _glfw.x11.contentScaleX; *xscale = _glfw.x11.contentScaleX;
@ -345,7 +345,9 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*yscale = _glfw.x11.contentScaleY; *yscale = _glfw.x11.contentScaleY;
} }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height) void _glfwGetMonitorWorkareaX11(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{ {
int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0; int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0;
@ -437,7 +439,7 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos
*height = areaHeight; *height = areaHeight;
} }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) GLFWvidmode* _glfwGetVideoModesX11(_GLFWmonitor* monitor, int* count)
{ {
GLFWvidmode* result; GLFWvidmode* result;
@ -450,7 +452,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
result = calloc(oi->nmode, sizeof(GLFWvidmode)); result = _glfw_calloc(oi->nmode, sizeof(GLFWvidmode));
for (int i = 0; i < oi->nmode; i++) for (int i = 0; i < oi->nmode; i++)
{ {
@ -482,14 +484,14 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
else else
{ {
*count = 1; *count = 1;
result = calloc(1, sizeof(GLFWvidmode)); result = _glfw_calloc(1, sizeof(GLFWvidmode));
_glfwPlatformGetVideoMode(monitor, result); _glfwGetVideoModeX11(monitor, result);
} }
return result; return result;
} }
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) void _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode)
{ {
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{ {
@ -519,7 +521,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
} }
} }
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwGetGammaRampX11(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{ {
@ -557,7 +559,7 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
} }
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{ {
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken) if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{ {

View file

@ -28,7 +28,6 @@
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <stdint.h> #include <stdint.h>
#include <dlfcn.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/keysym.h> #include <X11/keysym.h>
@ -51,6 +50,53 @@
// The Shape extension provides custom window shapes // The Shape extension provides custom window shapes
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#define GLX_VENDOR 1
#define GLX_RGBA_BIT 0x00000001
#define GLX_WINDOW_BIT 0x00000001
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_RGBA_TYPE 0x8014
#define GLX_DOUBLEBUFFER 5
#define GLX_STEREO 6
#define GLX_AUX_BUFFERS 7
#define GLX_RED_SIZE 8
#define GLX_GREEN_SIZE 9
#define GLX_BLUE_SIZE 10
#define GLX_ALPHA_SIZE 11
#define GLX_DEPTH_SIZE 12
#define GLX_STENCIL_SIZE 13
#define GLX_ACCUM_RED_SIZE 14
#define GLX_ACCUM_GREEN_SIZE 15
#define GLX_ACCUM_BLUE_SIZE 16
#define GLX_ACCUM_ALPHA_SIZE 17
#define GLX_SAMPLES 0x186a1
#define GLX_VISUAL_ID 0x800b
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GLX_CONTEXT_FLAGS_ARB 0x2094
#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
typedef XID GLXWindow;
typedef XID GLXDrawable;
typedef struct __GLXFBConfig* GLXFBConfig;
typedef struct __GLXcontext* GLXContext;
typedef void (*__GLXextproc)(void);
typedef XClassHint* (* PFN_XAllocClassHint)(void); typedef XClassHint* (* PFN_XAllocClassHint)(void);
typedef XSizeHints* (* PFN_XAllocSizeHints)(void); typedef XSizeHints* (* PFN_XAllocSizeHints)(void);
typedef XWMHints* (* PFN_XAllocWMHints)(void); typedef XWMHints* (* PFN_XAllocWMHints)(void);
@ -197,7 +243,6 @@ typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char
#define XGetWindowProperty _glfw.x11.xlib.GetWindowProperty #define XGetWindowProperty _glfw.x11.xlib.GetWindowProperty
#define XGrabPointer _glfw.x11.xlib.GrabPointer #define XGrabPointer _glfw.x11.xlib.GrabPointer
#define XIconifyWindow _glfw.x11.xlib.IconifyWindow #define XIconifyWindow _glfw.x11.xlib.IconifyWindow
#define XInitThreads _glfw.x11.xlib.InitThreads
#define XInternAtom _glfw.x11.xlib.InternAtom #define XInternAtom _glfw.x11.xlib.InternAtom
#define XLookupString _glfw.x11.xlib.LookupString #define XLookupString _glfw.x11.xlib.LookupString
#define XMapRaised _glfw.x11.xlib.MapRaised #define XMapRaised _glfw.x11.xlib.MapRaised
@ -205,7 +250,6 @@ typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char
#define XMoveResizeWindow _glfw.x11.xlib.MoveResizeWindow #define XMoveResizeWindow _glfw.x11.xlib.MoveResizeWindow
#define XMoveWindow _glfw.x11.xlib.MoveWindow #define XMoveWindow _glfw.x11.xlib.MoveWindow
#define XNextEvent _glfw.x11.xlib.NextEvent #define XNextEvent _glfw.x11.xlib.NextEvent
#define XOpenDisplay _glfw.x11.xlib.OpenDisplay
#define XOpenIM _glfw.x11.xlib.OpenIM #define XOpenIM _glfw.x11.xlib.OpenIM
#define XPeekEvent _glfw.x11.xlib.PeekEvent #define XPeekEvent _glfw.x11.xlib.PeekEvent
#define XPending _glfw.x11.xlib.Pending #define XPending _glfw.x11.xlib.Pending
@ -250,7 +294,6 @@ typedef void (* PFN_Xutf8SetWMProperties)(Display*,Window,const char*,const char
#define XrmDestroyDatabase _glfw.x11.xrm.DestroyDatabase #define XrmDestroyDatabase _glfw.x11.xrm.DestroyDatabase
#define XrmGetResource _glfw.x11.xrm.GetResource #define XrmGetResource _glfw.x11.xrm.GetResource
#define XrmGetStringDatabase _glfw.x11.xrm.GetStringDatabase #define XrmGetStringDatabase _glfw.x11.xrm.GetStringDatabase
#define XrmInitialize _glfw.x11.xrm.Initialize
#define XrmUniqueQuark _glfw.x11.xrm.UniqueQuark #define XrmUniqueQuark _glfw.x11.xrm.UniqueQuark
#define XUnregisterIMInstantiateCallback _glfw.x11.xlib.UnregisterIMInstantiateCallback #define XUnregisterIMInstantiateCallback _glfw.x11.xlib.UnregisterIMInstantiateCallback
#define Xutf8LookupString _glfw.x11.xlib.utf8LookupString #define Xutf8LookupString _glfw.x11.xlib.utf8LookupString
@ -348,6 +391,41 @@ typedef void (* PFN_XShapeCombineMask)(Display*,Window,int,int,int,Pixmap,int);
#define XShapeCombineRegion _glfw.x11.xshape.ShapeCombineRegion #define XShapeCombineRegion _glfw.x11.xshape.ShapeCombineRegion
#define XShapeCombineMask _glfw.x11.xshape.ShapeCombineMask #define XShapeCombineMask _glfw.x11.xshape.ShapeCombineMask
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);
typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext);
typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext);
typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
typedef GLXFBConfig* (*PFNGLXGETFBCONFIGSPROC)(Display*,int,int*);
typedef GLXContext (*PFNGLXCREATENEWCONTEXTPROC)(Display*,GLXFBConfig,int,GLXContext,Bool);
typedef __GLXextproc (* PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName);
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig);
typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*);
typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow);
typedef int (*PFNGLXSWAPINTERVALMESAPROC)(int);
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int);
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLXContext,Bool,const int*);
// libGL.so function pointer typedefs
#define glXGetFBConfigs _glfw.glx.GetFBConfigs
#define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
#define glXGetClientString _glfw.glx.GetClientString
#define glXQueryExtension _glfw.glx.QueryExtension
#define glXQueryVersion _glfw.glx.QueryVersion
#define glXDestroyContext _glfw.glx.DestroyContext
#define glXMakeCurrent _glfw.glx.MakeCurrent
#define glXSwapBuffers _glfw.glx.SwapBuffers
#define glXQueryExtensionsString _glfw.glx.QueryExtensionsString
#define glXCreateNewContext _glfw.glx.CreateNewContext
#define glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig
#define glXCreateWindow _glfw.glx.CreateWindow
#define glXDestroyWindow _glfw.glx.DestroyWindow
typedef VkFlags VkXlibSurfaceCreateFlagsKHR; typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
typedef VkFlags VkXcbSurfaceCreateFlagsKHR; typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
@ -374,26 +452,72 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(V
typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); typedef VkResult (APIENTRY *PFN_vkCreateXcbSurfaceKHR)(VkInstance,const VkXcbSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t); typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice,uint32_t,xcb_connection_t*,xcb_visualid_t);
#include "posix_thread.h"
#include "posix_time.h"
#include "xkb_unicode.h" #include "xkb_unicode.h"
#include "glx_context.h" #include "posix_poll.h"
#if defined(__linux__)
#include "linux_joystick.h"
#else
#include "null_joystick.h"
#endif
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) #define GLFW_X11_WINDOW_STATE _GLFWwindowX11 x11;
#define _glfw_dlclose(handle) dlclose(handle) #define GLFW_X11_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11;
#define _glfw_dlsym(handle, name) dlsym(handle, name) #define GLFW_X11_MONITOR_STATE _GLFWmonitorX11 x11;
#define GLFW_X11_CURSOR_STATE _GLFWcursorX11 x11;
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11 #define GLFW_GLX_CONTEXT_STATE _GLFWcontextGLX glx;
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 #define GLFW_GLX_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx;
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11
// GLX-specific per-context data
//
typedef struct _GLFWcontextGLX
{
GLXContext handle;
GLXWindow window;
} _GLFWcontextGLX;
// GLX-specific global data
//
typedef struct _GLFWlibraryGLX
{
int major, minor;
int eventBase;
int errorBase;
void* handle;
// GLX 1.3 functions
PFNGLXGETFBCONFIGSPROC GetFBConfigs;
PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
PFNGLXGETCLIENTSTRINGPROC GetClientString;
PFNGLXQUERYEXTENSIONPROC QueryExtension;
PFNGLXQUERYVERSIONPROC QueryVersion;
PFNGLXDESTROYCONTEXTPROC DestroyContext;
PFNGLXMAKECURRENTPROC MakeCurrent;
PFNGLXSWAPBUFFERSPROC SwapBuffers;
PFNGLXQUERYEXTENSIONSSTRINGPROC QueryExtensionsString;
PFNGLXCREATENEWCONTEXTPROC CreateNewContext;
PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig;
PFNGLXCREATEWINDOWPROC CreateWindow;
PFNGLXDESTROYWINDOWPROC DestroyWindow;
// GLX 1.4 and extension functions
PFNGLXGETPROCADDRESSPROC GetProcAddress;
PFNGLXGETPROCADDRESSPROC GetProcAddressARB;
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool SGI_swap_control;
GLFWbool EXT_swap_control;
GLFWbool MESA_swap_control;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
} _GLFWlibraryGLX;
// X11-specific per-window data // X11-specific per-window data
// //
typedef struct _GLFWwindowX11 typedef struct _GLFWwindowX11
@ -422,7 +546,6 @@ typedef struct _GLFWwindowX11
// The time of the last KeyPress event per keycode, for discarding // The time of the last KeyPress event per keycode, for discarding
// duplicate key events generated for some keys by ibus // duplicate key events generated for some keys by ibus
Time keyPressTimes[256]; Time keyPressTimes[256];
} _GLFWwindowX11; } _GLFWwindowX11;
// X11-specific global data // X11-specific global data
@ -443,6 +566,8 @@ typedef struct _GLFWlibraryX11
XContext context; XContext context;
// XIM input method // XIM input method
XIM im; XIM im;
// The previous X error handler, to be restored later
XErrorHandler errorHandler;
// Most recent error code received by X error handler // Most recent error code received by X error handler
int errorCode; int errorCode;
// Primary selection string (while the primary selection is owned) // Primary selection string (while the primary selection is owned)
@ -459,6 +584,7 @@ typedef struct _GLFWlibraryX11
double restoreCursorPosX, restoreCursorPosY; double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active // The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow; _GLFWwindow* disabledCursorWindow;
int emptyEventPipe[2];
// Window manager atoms // Window manager atoms
Atom NET_SUPPORTED; Atom NET_SUPPORTED;
@ -563,7 +689,6 @@ typedef struct _GLFWlibraryX11
PFN_XGetWindowProperty GetWindowProperty; PFN_XGetWindowProperty GetWindowProperty;
PFN_XGrabPointer GrabPointer; PFN_XGrabPointer GrabPointer;
PFN_XIconifyWindow IconifyWindow; PFN_XIconifyWindow IconifyWindow;
PFN_XInitThreads InitThreads;
PFN_XInternAtom InternAtom; PFN_XInternAtom InternAtom;
PFN_XLookupString LookupString; PFN_XLookupString LookupString;
PFN_XMapRaised MapRaised; PFN_XMapRaised MapRaised;
@ -571,7 +696,6 @@ typedef struct _GLFWlibraryX11
PFN_XMoveResizeWindow MoveResizeWindow; PFN_XMoveResizeWindow MoveResizeWindow;
PFN_XMoveWindow MoveWindow; PFN_XMoveWindow MoveWindow;
PFN_XNextEvent NextEvent; PFN_XNextEvent NextEvent;
PFN_XOpenDisplay OpenDisplay;
PFN_XOpenIM OpenIM; PFN_XOpenIM OpenIM;
PFN_XPeekEvent PeekEvent; PFN_XPeekEvent PeekEvent;
PFN_XPending Pending; PFN_XPending Pending;
@ -613,7 +737,6 @@ typedef struct _GLFWlibraryX11
PFN_XrmDestroyDatabase DestroyDatabase; PFN_XrmDestroyDatabase DestroyDatabase;
PFN_XrmGetResource GetResource; PFN_XrmGetResource GetResource;
PFN_XrmGetStringDatabase GetStringDatabase; PFN_XrmGetStringDatabase GetStringDatabase;
PFN_XrmInitialize Initialize;
PFN_XrmUniqueQuark UniqueQuark; PFN_XrmUniqueQuark UniqueQuark;
} xrm; } xrm;
@ -751,7 +874,6 @@ typedef struct _GLFWlibraryX11
PFN_XShapeQueryVersion QueryVersion; PFN_XShapeQueryVersion QueryVersion;
PFN_XShapeCombineMask ShapeCombineMask; PFN_XShapeCombineMask ShapeCombineMask;
} xshape; } xshape;
} _GLFWlibraryX11; } _GLFWlibraryX11;
// X11-specific per-monitor data // X11-specific per-monitor data
@ -765,7 +887,6 @@ typedef struct _GLFWmonitorX11
// Index of corresponding Xinerama screen, // Index of corresponding Xinerama screen,
// for EWMH full screen window placement // for EWMH full screen window placement
int index; int index;
} _GLFWmonitorX11; } _GLFWmonitorX11;
// X11-specific per-cursor data // X11-specific per-cursor data
@ -773,15 +894,89 @@ typedef struct _GLFWmonitorX11
typedef struct _GLFWcursorX11 typedef struct _GLFWcursorX11
{ {
Cursor handle; Cursor handle;
} _GLFWcursorX11; } _GLFWcursorX11;
GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform);
int _glfwInitX11(void);
void _glfwTerminateX11(void);
GLFWbool _glfwCreateWindowX11(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowX11(_GLFWwindow* window);
void _glfwSetWindowTitleX11(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconX11(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosX11(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosX11(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeX11(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsX11(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioX11(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeX11(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeX11(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleX11(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowX11(_GLFWwindow* window);
void _glfwRestoreWindowX11(_GLFWwindow* window);
void _glfwMaximizeWindowX11(_GLFWwindow* window);
void _glfwShowWindowX11(_GLFWwindow* window);
void _glfwHideWindowX11(_GLFWwindow* window);
void _glfwRequestWindowAttentionX11(_GLFWwindow* window);
void _glfwFocusWindowX11(_GLFWwindow* window);
void _glfwSetWindowMonitorX11(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedX11(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedX11(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleX11(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedX11(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredX11(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentX11(_GLFWwindow* window);
void _glfwSetWindowResizableX11(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedX11(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingX11(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityX11(_GLFWwindow* window);
void _glfwSetWindowOpacityX11(_GLFWwindow* window, float opacity);
void _glfwSetWindowMousePassthroughX11(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetRawMouseMotionX11(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedX11(void);
void _glfwPollEventsX11(void);
void _glfwWaitEventsX11(void);
void _glfwWaitEventsTimeoutX11(double timeout);
void _glfwPostEmptyEventX11(void);
void _glfwGetCursorPosX11(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosX11(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeX11(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameX11(int scancode);
int _glfwGetKeyScancodeX11(int key);
GLFWbool _glfwCreateCursorX11(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorX11(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorX11(_GLFWcursor* cursor);
void _glfwSetCursorX11(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringX11(const char* string);
const char* _glfwGetClipboardStringX11(void);
EGLenum _glfwGetEGLPlatformX11(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayX11(void);
EGLNativeWindowType _glfwGetEGLNativeWindowX11(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsX11(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportX11(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceX11(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorX11(_GLFWmonitor* monitor);
void _glfwGetMonitorPosX11(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleX11(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaX11(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesX11(_GLFWmonitor* monitor, int* count);
void _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampX11(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPollMonitorsX11(void); void _glfwPollMonitorsX11(void);
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired); void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor); void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot); Cursor _glfwCreateNativeCursorX11(const GLFWimage* image, int xhot, int yhot);
unsigned long _glfwGetWindowPropertyX11(Window window, unsigned long _glfwGetWindowPropertyX11(Window window,
Atom property, Atom property,
@ -796,3 +991,14 @@ void _glfwInputErrorX11(int error, const char* message);
void _glfwPushSelectionToManagerX11(void); void _glfwPushSelectionToManagerX11(void);
void _glfwCreateInputContextX11(_GLFWwindow* window); void _glfwCreateInputContextX11(_GLFWwindow* window);
GLFWbool _glfwInitGLX(void);
void _glfwTerminateGLX(void);
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextGLX(_GLFWwindow* window);
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);

File diff suppressed because it is too large Load diff

View file

@ -907,7 +907,7 @@ static const struct codepair {
// Convert XKB KeySym to Unicode // Convert XKB KeySym to Unicode
// //
long _glfwKeySym2Unicode(unsigned int keysym) uint32_t _glfwKeySym2Unicode(unsigned int keysym)
{ {
int min = 0; int min = 0;
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
@ -937,6 +937,6 @@ long _glfwKeySym2Unicode(unsigned int keysym)
} }
// No matching Unicode value found // No matching Unicode value found
return -1; return GLFW_INVALID_CODEPOINT;
} }

View file

@ -24,5 +24,7 @@
// //
//======================================================================== //========================================================================
long _glfwKeySym2Unicode(unsigned int keysym); #define GLFW_INVALID_CODEPOINT 0xffffffffu
uint32_t _glfwKeySym2Unicode(unsigned int keysym);

818
raylib/external/rl_gputex.h vendored Normal file
View file

@ -0,0 +1,818 @@
/**********************************************************************************************
*
* rl_gputex - GPU compressed textures loading and saving
*
* DESCRIPTION:
*
* Load GPU compressed image data from image files provided as memory data arrays,
* data is loaded compressed, ready to be loaded into GPU.
*
* Note that some file formats (DDS, PVR, KTX) also support uncompressed data storage.
* In those cases data is loaded uncompressed and format is returned.
*
* TODO:
* - Implement raylib function: rlGetGlTextureFormats(), required by rl_save_ktx_to_memory()
* - Review rl_load_ktx_from_memory() to support KTX v2.2 specs
*
* CONFIGURATION:
*
* #define RL_GPUTEX_SUPPORT_DDS
* #define RL_GPUTEX_SUPPORT_PKM
* #define RL_GPUTEX_SUPPORT_KTX
* #define RL_GPUTEX_SUPPORT_PVR
* #define RL_GPUTEX_SUPPORT_ASTC
* Define desired file formats to be supported
*
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2013-2022 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef RL_GPUTEX_H
#define RL_GPUTEX_H
#ifndef RLAPI
#define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
#endif
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
#if defined(__cplusplus)
extern "C" { // Prevents name mangling of functions
#endif
// Load image data from memory data files
RLAPI void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
RLAPI void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
RLAPI void *rl_load_ktx_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
RLAPI void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
RLAPI void *rl_load_astc_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
RLAPI int rl_save_ktx_to_memory(const char *fileName, void *data, int width, int height, int format, int mipmaps); // Save image data as KTX file
#if defined(__cplusplus)
}
#endif
#endif // RL_GPUTEX_H
/***********************************************************************************
*
* RL_GPUTEX IMPLEMENTATION
*
************************************************************************************/
#if defined(RL_GPUTEX_IMPLEMENTATION)
// Simple log system to avoid RPNG_LOG() calls if required
// NOTE: Avoiding those calls, also avoids const strings memory usage
#define RL_GPUTEX_SHOW_LOG_INFO
#if defined(RL_GPUTEX_SHOW_LOG_INFO) && !defined(LOG)
#define LOG(...) printf(__VA_ARGS__)
#else
#define LOG(...)
#endif
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
// Get pixel data size in bytes for certain pixel format
static int get_pixel_data_size(int width, int height, int format);
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
#if defined(RL_GPUTEX_SUPPORT_DDS)
// Loading DDS from memory image data (compressed or uncompressed)
void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
void *image_data = NULL; // Image data pointer
int image_pixel_size = 0; // Image pixel size
unsigned char *file_data_ptr = (unsigned char *)file_data;
// Required extension:
// GL_EXT_texture_compression_s3tc
// Supported tokens (defined by extensions)
// GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
// GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
// GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
// GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
// DDS Pixel Format
typedef struct {
unsigned int size;
unsigned int flags;
unsigned int fourcc;
unsigned int rgb_bit_count;
unsigned int r_bit_mask;
unsigned int g_bit_mask;
unsigned int b_bit_mask;
unsigned int a_bit_mask;
} dds_pixel_format;
// DDS Header (124 bytes)
typedef struct {
unsigned int size;
unsigned int flags;
unsigned int height;
unsigned int width;
unsigned int pitch_or_linear_size;
unsigned int depth;
unsigned int mipmap_count;
unsigned int reserved1[11];
dds_pixel_format ddspf;
unsigned int caps;
unsigned int caps2;
unsigned int caps3;
unsigned int caps4;
unsigned int reserved2;
} dds_header;
if (file_data_ptr != NULL)
{
// Verify the type of file
unsigned char *dds_header_id = file_data_ptr;
file_data_ptr += 4;
if ((dds_header_id[0] != 'D') || (dds_header_id[1] != 'D') || (dds_header_id[2] != 'S') || (dds_header_id[3] != ' '))
{
LOG("WARNING: IMAGE: DDS file data not valid");
}
else
{
dds_header *header = (dds_header *)file_data_ptr;
file_data_ptr += sizeof(dds_header); // Skip header
*width = header->width;
*height = header->height;
image_pixel_size = header->width*header->height;
if (header->mipmap_count == 0) *mips = 1; // Parameter not used
else *mips = header->mipmap_count;
if (header->ddspf.rgb_bit_count == 16) // 16bit mode, no compressed
{
if (header->ddspf.flags == 0x40) // No alpha channel
{
int data_size = image_pixel_size*sizeof(unsigned short);
image_data = RL_MALLOC(data_size);
memcpy(image_data, file_data_ptr, data_size);
*format = PIXELFORMAT_UNCOMPRESSED_R5G6B5;
}
else if (header->ddspf.flags == 0x41) // With alpha channel
{
if (header->ddspf.a_bit_mask == 0x8000) // 1bit alpha
{
int data_size = image_pixel_size*sizeof(unsigned short);
image_data = RL_MALLOC(data_size);
memcpy(image_data, file_data_ptr, data_size);
unsigned char alpha = 0;
// NOTE: Data comes as A1R5G5B5, it must be reordered to R5G5B5A1
for (int i = 0; i < image_pixel_size; i++)
{
alpha = ((unsigned short *)image_data)[i] >> 15;
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 1;
((unsigned short *)image_data)[i] += alpha;
}
*format = PIXELFORMAT_UNCOMPRESSED_R5G5B5A1;
}
else if (header->ddspf.a_bit_mask == 0xf000) // 4bit alpha
{
int data_size = image_pixel_size*sizeof(unsigned short);
image_data = RL_MALLOC(data_size);
memcpy(image_data, file_data_ptr, data_size);
unsigned char alpha = 0;
// NOTE: Data comes as A4R4G4B4, it must be reordered R4G4B4A4
for (int i = 0; i < image_pixel_size; i++)
{
alpha = ((unsigned short *)image_data)[i] >> 12;
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 4;
((unsigned short *)image_data)[i] += alpha;
}
*format = PIXELFORMAT_UNCOMPRESSED_R4G4B4A4;
}
}
}
else if (header->ddspf.flags == 0x40 && header->ddspf.rgb_bit_count == 24) // DDS_RGB, no compressed
{
int data_size = image_pixel_size*3*sizeof(unsigned char);
image_data = RL_MALLOC(data_size);
memcpy(image_data, file_data_ptr, data_size);
*format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
}
else if (header->ddspf.flags == 0x41 && header->ddspf.rgb_bit_count == 32) // DDS_RGBA, no compressed
{
int data_size = image_pixel_size*4*sizeof(unsigned char);
image_data = RL_MALLOC(data_size);
memcpy(image_data, file_data_ptr, data_size);
unsigned char blue = 0;
// NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment)
// DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA
// So, we must realign B8G8R8A8 to R8G8B8A8
for (int i = 0; i < image_pixel_size*4; i += 4)
{
blue = ((unsigned char *)image_data)[i];
((unsigned char *)image_data)[i] = ((unsigned char *)image_data)[i + 2];
((unsigned char *)image_data)[i + 2] = blue;
}
*format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
}
else if (((header->ddspf.flags == 0x04) || (header->ddspf.flags == 0x05)) && (header->ddspf.fourcc > 0)) // Compressed
{
int data_size = 0;
// Calculate data size, including all mipmaps
if (header->mipmap_count > 1) data_size = header->pitch_or_linear_size*2;
else data_size = header->pitch_or_linear_size;
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
memcpy(image_data, file_data_ptr, data_size);
switch (header->ddspf.fourcc)
{
case FOURCC_DXT1:
{
if (header->ddspf.flags == 0x04) *format = PIXELFORMAT_COMPRESSED_DXT1_RGB;
else *format = PIXELFORMAT_COMPRESSED_DXT1_RGBA;
} break;
case FOURCC_DXT3: *format = PIXELFORMAT_COMPRESSED_DXT3_RGBA; break;
case FOURCC_DXT5: *format = PIXELFORMAT_COMPRESSED_DXT5_RGBA; break;
default: break;
}
}
}
}
return image_data;
}
#endif
#if defined(RL_GPUTEX_SUPPORT_PKM)
// Loading PKM image data (ETC1/ETC2 compression)
// NOTE: KTX is the standard Khronos Group compression format (ETC1/ETC2, mipmaps)
// PKM is a much simpler file format used mainly to contain a single ETC1/ETC2 compressed image (no mipmaps)
void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
void *image_data = NULL; // Image data pointer
unsigned char *file_data_ptr = (unsigned char *)file_data;
// Required extensions:
// GL_OES_compressed_ETC1_RGB8_texture (ETC1) (OpenGL ES 2.0)
// GL_ARB_ES3_compatibility (ETC2/EAC) (OpenGL ES 3.0)
// Supported tokens (defined by extensions)
// GL_ETC1_RGB8_OES 0x8D64
// GL_COMPRESSED_RGB8_ETC2 0x9274
// GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
// PKM file (ETC1) Header (16 bytes)
typedef struct {
char id[4]; // "PKM "
char version[2]; // "10" or "20"
unsigned short format; // Data format (big-endian) (Check list below)
unsigned short width; // Texture width (big-endian) (orig_width rounded to multiple of 4)
unsigned short height; // Texture height (big-endian) (orig_height rounded to multiple of 4)
unsigned short orig_width; // Original width (big-endian)
unsigned short orig_height; // Original height (big-endian)
} pkm_header;
// Formats list
// version 10: format: 0=ETC1_RGB, [1=ETC1_RGBA, 2=ETC1_RGB_MIP, 3=ETC1_RGBA_MIP] (not used)
// version 20: format: 0=ETC1_RGB, 1=ETC2_RGB, 2=ETC2_RGBA_OLD, 3=ETC2_RGBA, 4=ETC2_RGBA1, 5=ETC2_R, 6=ETC2_RG, 7=ETC2_SIGNED_R, 8=ETC2_SIGNED_R
// NOTE: The extended width and height are the widths rounded up to a multiple of 4.
// NOTE: ETC is always 4bit per pixel (64 bit for each 4x4 block of pixels)
if (file_data_ptr != NULL)
{
pkm_header *header = (pkm_header *)file_data_ptr;
if ((header->id[0] != 'P') || (header->id[1] != 'K') || (header->id[2] != 'M') || (header->id[3] != ' '))
{
LOG("WARNING: IMAGE: PKM file data not valid");
}
else
{
file_data_ptr += sizeof(pkm_header); // Skip header
// NOTE: format, width and height come as big-endian, data must be swapped to little-endian
header->format = ((header->format & 0x00FF) << 8) | ((header->format & 0xFF00) >> 8);
header->width = ((header->width & 0x00FF) << 8) | ((header->width & 0xFF00) >> 8);
header->height = ((header->height & 0x00FF) << 8) | ((header->height & 0xFF00) >> 8);
*width = header->width;
*height = header->height;
*mips = 1;
int bpp = 4;
if (header->format == 3) bpp = 8;
int data_size = (*width)*(*height)*bpp/8; // Total data size in bytes
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
memcpy(image_data, file_data_ptr, data_size);
if (header->format == 0) *format = PIXELFORMAT_COMPRESSED_ETC1_RGB;
else if (header->format == 1) *format = PIXELFORMAT_COMPRESSED_ETC2_RGB;
else if (header->format == 3) *format = PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA;
}
}
return image_data;
}
#endif
#if defined(RL_GPUTEX_SUPPORT_KTX)
// Load KTX compressed image data (ETC1/ETC2 compression)
// TODO: Review KTX loading, many things changed!
void *rl_load_ktx_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
void *image_data = NULL; // Image data pointer
unsigned char *file_data_ptr = (unsigned char *)file_data;
// Required extensions:
// GL_OES_compressed_ETC1_RGB8_texture (ETC1)
// GL_ARB_ES3_compatibility (ETC2/EAC)
// Supported tokens (defined by extensions)
// GL_ETC1_RGB8_OES 0x8D64
// GL_COMPRESSED_RGB8_ETC2 0x9274
// GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
// KTX file Header (64 bytes)
// v1.1 - https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
// v2.0 - http://github.khronos.org/KTX-Specification/
// KTX 1.1 Header
// TODO: Support KTX 2.2 specs!
typedef struct {
char id[12]; // Identifier: "«KTX 11»\r\n\x1A\n"
unsigned int endianness; // Little endian: 0x01 0x02 0x03 0x04
unsigned int gl_type; // For compressed textures, glType must equal 0
unsigned int gl_type_size; // For compressed texture data, usually 1
unsigned int gl_format; // For compressed textures is 0
unsigned int gl_internal_format; // Compressed internal format
unsigned int gl_base_internal_format; // Same as glFormat (RGB, RGBA, ALPHA...)
unsigned int width; // Texture image width in pixels
unsigned int height; // Texture image height in pixels
unsigned int depth; // For 2D textures is 0
unsigned int elements; // Number of array elements, usually 0
unsigned int faces; // Cubemap faces, for no-cubemap = 1
unsigned int mipmap_levels; // Non-mipmapped textures = 1
unsigned int key_value_data_size; // Used to encode any arbitrary data...
} ktx_header;
// NOTE: Before start of every mipmap data block, we have: unsigned int data_size
if (file_data_ptr != NULL)
{
ktx_header *header = (ktx_header *)file_data_ptr;
if ((header->id[1] != 'K') || (header->id[2] != 'T') || (header->id[3] != 'X') ||
(header->id[4] != ' ') || (header->id[5] != '1') || (header->id[6] != '1'))
{
LOG("WARNING: IMAGE: KTX file data not valid");
}
else
{
file_data_ptr += sizeof(ktx_header); // Move file data pointer
*width = header->width;
*height = header->height;
*mips = header->mipmap_levels;
file_data_ptr += header->key_value_data_size; // Skip value data size
int data_size = ((int *)file_data_ptr)[0];
file_data_ptr += sizeof(int);
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
memcpy(image_data, file_data_ptr, data_size);
if (header->gl_internal_format == 0x8D64) *format = PIXELFORMAT_COMPRESSED_ETC1_RGB;
else if (header->gl_internal_format == 0x9274) *format = PIXELFORMAT_COMPRESSED_ETC2_RGB;
else if (header->gl_internal_format == 0x9278) *format = PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA;
// TODO: Support uncompressed data formats? Right now it returns format = 0!
}
}
return image_data;
}
// Save image data as KTX file
// NOTE: By default KTX 1.1 spec is used, 2.0 is still on draft (01Oct2018)
// TODO: Review KTX saving, many things changed!
int rl_save_ktx(const char *file_name, void *data, int width, int height, int format, int mipmaps)
{
// KTX file Header (64 bytes)
// v1.1 - https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
// v2.0 - http://github.khronos.org/KTX-Specification/ - Final specs by 2021-04-18
typedef struct {
char id[12]; // Identifier: "«KTX 11»\r\n\x1A\n" // KTX 2.0: "«KTX 22»\r\n\x1A\n"
unsigned int endianness; // Little endian: 0x01 0x02 0x03 0x04
unsigned int gl_type; // For compressed textures, glType must equal 0
unsigned int gl_type_size; // For compressed texture data, usually 1
unsigned int gl_format; // For compressed textures is 0
unsigned int gl_internal_format; // Compressed internal format
unsigned int gl_base_internal_format; // Same as glFormat (RGB, RGBA, ALPHA...) // KTX 2.0: UInt32 vkFormat
unsigned int width; // Texture image width in pixels
unsigned int height; // Texture image height in pixels
unsigned int depth; // For 2D textures is 0
unsigned int elements; // Number of array elements, usually 0
unsigned int faces; // Cubemap faces, for no-cubemap = 1
unsigned int mipmap_levels; // Non-mipmapped textures = 1
unsigned int key_value_data_size; // Used to encode any arbitrary data... // KTX 2.0: UInt32 levelOrder - ordering of the mipmap levels, usually 0
// KTX 2.0: UInt32 supercompressionScheme - 0 (None), 1 (Crunch CRN), 2 (Zlib DEFLATE)...
// KTX 2.0 defines additional header elements...
} ktx_header;
// Calculate file data_size required
int data_size = sizeof(ktx_header);
for (int i = 0, width = width, height = height; i < mipmaps; i++)
{
data_size += get_pixel_data_size(width, height, format);
width /= 2; height /= 2;
}
unsigned char *file_data = RL_CALLOC(data_size, 1);
unsigned char *file_data_ptr = file_data;
ktx_header header = { 0 };
// KTX identifier (v1.1)
//unsigned char id[12] = { '«', 'K', 'T', 'X', ' ', '1', '1', '»', '\r', '\n', '\x1A', '\n' };
//unsigned char id[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
const char ktx_identifier[12] = { 0xAB, 'K', 'T', 'X', ' ', '1', '1', 0xBB, '\r', '\n', 0x1A, '\n' };
// Get the image header
memcpy(header.id, ktx_identifier, 12); // KTX 1.1 signature
header.endianness = 0;
header.gl_type = 0; // Obtained from format
header.gl_type_size = 1;
header.gl_format = 0; // Obtained from format
header.gl_internal_format = 0; // Obtained from format
header.gl_base_internal_format = 0;
header.width = width;
header.height = height;
header.depth = 0;
header.elements = 0;
header.faces = 1;
header.mipmap_levels = mipmaps; // If it was 0, it means mipmaps should be generated on loading (not for compressed formats)
header.key_value_data_size = 0; // No extra data after the header
rlGetGlTextureFormats(format, &header.gl_internal_format, &header.gl_format, &header.gl_type); // rlgl module function
header.gl_base_internal_format = header.gl_format; // KTX 1.1 only
// NOTE: We can save into a .ktx all PixelFormats supported by raylib, including compressed formats like DXT, ETC or ASTC
if (header.gl_format == -1) LOG("WARNING: IMAGE: GL format not supported for KTX export (%i)", header.gl_format);
else
{
memcpy(file_data_ptr, &header, sizeof(ktx_header));
file_data_ptr += sizeof(ktx_header);
int temp_width = width;
int temp_height = height;
int data_offset = 0;
// Save all mipmaps data
for (int i = 0; i < mipmaps; i++)
{
unsigned int data_size = get_pixel_data_size(temp_width, temp_height, format);
memcpy(file_data_ptr, &data_size, sizeof(unsigned int));
memcpy(file_data_ptr + 4, (unsigned char *)data + data_offset, data_size);
temp_width /= 2;
temp_height /= 2;
data_offset += data_size;
file_data_ptr += (4 + data_size);
}
}
// Save file data to file
int success = false;
FILE *file = fopen(file_name, "wb");
if (file != NULL)
{
unsigned int count = (unsigned int)fwrite(file_data, sizeof(unsigned char), data_size, file);
if (count == 0) LOG("WARNING: FILEIO: [%s] Failed to write file", file_name);
else if (count != data_size) LOG("WARNING: FILEIO: [%s] File partially written", file_name);
else LOG("INFO: FILEIO: [%s] File saved successfully", file_name);
int result = fclose(file);
if (result == 0) success = true;
}
else LOG("WARNING: FILEIO: [%s] Failed to open file", file_name);
RL_FREE(file_data); // Free file data buffer
// If all data has been written correctly to file, success = 1
return success;
}
#endif
#if defined(RL_GPUTEX_SUPPORT_PVR)
// Loading PVR image data (uncompressed or PVRT compression)
// NOTE: PVR v2 not supported, use PVR v3 instead
void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
void *image_data = NULL; // Image data pointer
unsigned char *file_data_ptr = (unsigned char *)file_data;
// Required extension:
// GL_IMG_texture_compression_pvrtc
// Supported tokens (defined by extensions)
// GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
// GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
#if 0 // Not used...
// PVR file v2 Header (52 bytes)
typedef struct {
unsigned int headerLength;
unsigned int height;
unsigned int width;
unsigned int numMipmaps;
unsigned int flags;
unsigned int dataLength;
unsigned int bpp;
unsigned int bitmaskRed;
unsigned int bitmaskGreen;
unsigned int bitmaskBlue;
unsigned int bitmaskAlpha;
unsigned int pvrTag;
unsigned int numSurfs;
} PVRHeaderV2;
#endif
// PVR file v3 Header (52 bytes)
// NOTE: After it could be metadata (15 bytes?)
typedef struct {
char id[4];
unsigned int flags;
unsigned char channels[4]; // pixelFormat high part
unsigned char channel_depth[4]; // pixelFormat low part
unsigned int color_space;
unsigned int channel_type;
unsigned int height;
unsigned int width;
unsigned int depth;
unsigned int num_surfaces;
unsigned int num_faces;
unsigned int num_mipmaps;
unsigned int metadata_size;
} pvr_header;
#if 0 // Not used...
// Metadata (usually 15 bytes)
typedef struct {
unsigned int devFOURCC;
unsigned int key;
unsigned int data_size; // Not used?
unsigned char *data; // Not used?
} PVRMetadata;
#endif
if (file_data_ptr != NULL)
{
// Check PVR image version
unsigned char pvr_version = file_data_ptr[0];
// Load different PVR data formats
if (pvr_version == 0x50)
{
pvr_header *header = (pvr_header *)file_data_ptr;
if ((header->id[0] != 'P') || (header->id[1] != 'V') || (header->id[2] != 'R') || (header->id[3] != 3))
{
LOG("WARNING: IMAGE: PVR file data not valid");
}
else
{
file_data_ptr += sizeof(pvr_header); // Skip header
*width = header->width;
*height = header->height;
*mips = header->num_mipmaps;
// Check data format
if (((header->channels[0] == 'l') && (header->channels[1] == 0)) && (header->channel_depth[0] == 8)) *format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
else if (((header->channels[0] == 'l') && (header->channels[1] == 'a')) && ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8))) *format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA;
else if ((header->channels[0] == 'r') && (header->channels[1] == 'g') && (header->channels[2] == 'b'))
{
if (header->channels[3] == 'a')
{
if ((header->channel_depth[0] == 5) && (header->channel_depth[1] == 5) && (header->channel_depth[2] == 5) && (header->channel_depth[3] == 1)) *format = PIXELFORMAT_UNCOMPRESSED_R5G5B5A1;
else if ((header->channel_depth[0] == 4) && (header->channel_depth[1] == 4) && (header->channel_depth[2] == 4) && (header->channel_depth[3] == 4)) *format = PIXELFORMAT_UNCOMPRESSED_R4G4B4A4;
else if ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8) && (header->channel_depth[2] == 8) && (header->channel_depth[3] == 8)) *format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
}
else if (header->channels[3] == 0)
{
if ((header->channel_depth[0] == 5) && (header->channel_depth[1] == 6) && (header->channel_depth[2] == 5)) *format = PIXELFORMAT_UNCOMPRESSED_R5G6B5;
else if ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8) && (header->channel_depth[2] == 8)) *format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
}
}
else if (header->channels[0] == 2) *format = PIXELFORMAT_COMPRESSED_PVRT_RGB;
else if (header->channels[0] == 3) *format = PIXELFORMAT_COMPRESSED_PVRT_RGBA;
file_data_ptr += header->metadata_size; // Skip meta data header
// Calculate data size (depends on format)
int bpp = 0;
switch (*format)
{
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
case PIXELFORMAT_COMPRESSED_PVRT_RGB:
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
default: break;
}
int data_size = (*width)*(*height)*bpp/8; // Total data size in bytes
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
memcpy(image_data, file_data_ptr, data_size);
}
}
else if (pvr_version == 52) LOG("INFO: IMAGE: PVRv2 format not supported, update your files to PVRv3");
}
return image_data;
}
#endif
#if defined(RL_GPUTEX_SUPPORT_ASTC)
// Load ASTC compressed image data (ASTC compression)
void *rl_load_astc_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
void *image_data = NULL; // Image data pointer
unsigned char *file_data_ptr = (unsigned char *)file_data;
// Required extensions:
// GL_KHR_texture_compression_astc_hdr
// GL_KHR_texture_compression_astc_ldr
// Supported tokens (defined by extensions)
// GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93b0
// GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7
// ASTC file Header (16 bytes)
typedef struct {
unsigned char id[4]; // Signature: 0x13 0xAB 0xA1 0x5C
unsigned char blockX; // Block X dimensions
unsigned char blockY; // Block Y dimensions
unsigned char blockZ; // Block Z dimensions (1 for 2D images)
unsigned char width[3]; // void *width in pixels (24bit value)
unsigned char height[3]; // void *height in pixels (24bit value)
unsigned char length[3]; // void *Z-size (1 for 2D images)
} astc_header;
if (file_data_ptr != NULL)
{
astc_header *header = (astc_header *)file_data_ptr;
if ((header->id[3] != 0x5c) || (header->id[2] != 0xa1) || (header->id[1] != 0xab) || (header->id[0] != 0x13))
{
LOG("WARNING: IMAGE: ASTC file data not valid");
}
else
{
file_data_ptr += sizeof(astc_header); // Skip header
// NOTE: Assuming Little Endian (could it be wrong?)
*width = 0x00000000 | ((int)header->width[2] << 16) | ((int)header->width[1] << 8) | ((int)header->width[0]);
*height = 0x00000000 | ((int)header->height[2] << 16) | ((int)header->height[1] << 8) | ((int)header->height[0]);
*mips = 1; // NOTE: ASTC format only contains one mipmap level
// NOTE: Each block is always stored in 128bit so we can calculate the bpp
int bpp = 128/(header->blockX*header->blockY);
// NOTE: Currently we only support 2 blocks configurations: 4x4 and 8x8
if ((bpp == 8) || (bpp == 2))
{
int data_size = (*width)*(*height)*bpp/8; // Data size in bytes
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
memcpy(image_data, file_data_ptr, data_size);
if (bpp == 8) *format = PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA;
else if (bpp == 2) *format = PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA;
}
else LOG("WARNING: IMAGE: ASTC block size configuration not supported");
}
}
return image_data;
}
#endif
//----------------------------------------------------------------------------------
// Module Internal Functions Definition
//----------------------------------------------------------------------------------
// Get pixel data size in bytes for certain pixel format
static int get_pixel_data_size(int width, int height, int format)
{
int data_size = 0; // Size in bytes
int bpp = 0; // Bits per pixel
switch (format)
{
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
case PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break;
case PIXELFORMAT_COMPRESSED_DXT1_RGB:
case PIXELFORMAT_COMPRESSED_DXT1_RGBA:
case PIXELFORMAT_COMPRESSED_ETC1_RGB:
case PIXELFORMAT_COMPRESSED_ETC2_RGB:
case PIXELFORMAT_COMPRESSED_PVRT_RGB:
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
case PIXELFORMAT_COMPRESSED_DXT3_RGBA:
case PIXELFORMAT_COMPRESSED_DXT5_RGBA:
case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA:
case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break;
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
default: break;
}
data_size = width*height*bpp/8; // Total data size in bytes
// Most compressed formats works on 4x4 blocks,
// if texture is smaller, minimum dataSize is 8 or 16
if ((width < 4) && (height < 4))
{
if ((format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < PIXELFORMAT_COMPRESSED_DXT3_RGBA)) data_size = 8;
else if ((format >= PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) data_size = 16;
}
return data_size;
}
#endif // RL_GPUTEX_IMPLEMENTATION

428
raylib/external/stb_perlin.h vendored Normal file
View file

@ -0,0 +1,428 @@
// stb_perlin.h - v0.5 - perlin noise
// public domain single-file C implementation by Sean Barrett
//
// LICENSE
//
// See end of file.
//
//
// to create the implementation,
// #define STB_PERLIN_IMPLEMENTATION
// in *one* C/CPP file that includes this file.
//
//
// Documentation:
//
// float stb_perlin_noise3( float x,
// float y,
// float z,
// int x_wrap=0,
// int y_wrap=0,
// int z_wrap=0)
//
// This function computes a random value at the coordinate (x,y,z).
// Adjacent random values are continuous but the noise fluctuates
// its randomness with period 1, i.e. takes on wholly unrelated values
// at integer points. Specifically, this implements Ken Perlin's
// revised noise function from 2002.
//
// The "wrap" parameters can be used to create wraparound noise that
// wraps at powers of two. The numbers MUST be powers of two. Specify
// 0 to mean "don't care". (The noise always wraps every 256 due
// details of the implementation, even if you ask for larger or no
// wrapping.)
//
// float stb_perlin_noise3_seed( float x,
// float y,
// float z,
// int x_wrap=0,
// int y_wrap=0,
// int z_wrap=0,
// int seed)
//
// As above, but 'seed' selects from multiple different variations of the
// noise function. The current implementation only uses the bottom 8 bits
// of 'seed', but possibly in the future more bits will be used.
//
//
// Fractal Noise:
//
// Three common fractal noise functions are included, which produce
// a wide variety of nice effects depending on the parameters
// provided. Note that each function will call stb_perlin_noise3
// 'octaves' times, so this parameter will affect runtime.
//
// float stb_perlin_ridge_noise3(float x, float y, float z,
// float lacunarity, float gain, float offset, int octaves)
//
// float stb_perlin_fbm_noise3(float x, float y, float z,
// float lacunarity, float gain, int octaves)
//
// float stb_perlin_turbulence_noise3(float x, float y, float z,
// float lacunarity, float gain, int octaves)
//
// Typical values to start playing with:
// octaves = 6 -- number of "octaves" of noise3() to sum
// lacunarity = ~ 2.0 -- spacing between successive octaves (use exactly 2.0 for wrapping output)
// gain = 0.5 -- relative weighting applied to each successive octave
// offset = 1.0? -- used to invert the ridges, may need to be larger, not sure
//
//
// Contributors:
// Jack Mott - additional noise functions
// Jordan Peck - seeded noise
//
#ifdef __cplusplus
extern "C" {
#endif
extern float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap);
extern float stb_perlin_noise3_seed(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, int seed);
extern float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves);
extern float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
extern float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
extern float stb_perlin_noise3_wrap_nonpow2(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed);
#ifdef __cplusplus
}
#endif
#ifdef STB_PERLIN_IMPLEMENTATION
#include <math.h> // fabs()
// not same permutation table as Perlin's reference to avoid copyright issues;
// Perlin's table can be found at http://mrl.nyu.edu/~perlin/noise/
static unsigned char stb__perlin_randtab[512] =
{
23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
// and a second copy so we don't need an extra mask or static initializer
23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
};
// perlin's gradient has 12 cases so some get used 1/16th of the time
// and some 2/16ths. We reduce bias by changing those fractions
// to 5/64ths and 6/64ths
// this array is designed to match the previous implementation
// of gradient hash: indices[stb__perlin_randtab[i]&63]
static unsigned char stb__perlin_randtab_grad_idx[512] =
{
7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
// and a second copy so we don't need an extra mask or static initializer
7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
};
static float stb__perlin_lerp(float a, float b, float t)
{
return a + (b-a) * t;
}
static int stb__perlin_fastfloor(float a)
{
int ai = (int) a;
return (a < ai) ? ai-1 : ai;
}
// different grad function from Perlin's, but easy to modify to match reference
static float stb__perlin_grad(int grad_idx, float x, float y, float z)
{
static float basis[12][4] =
{
{ 1, 1, 0 },
{ -1, 1, 0 },
{ 1,-1, 0 },
{ -1,-1, 0 },
{ 1, 0, 1 },
{ -1, 0, 1 },
{ 1, 0,-1 },
{ -1, 0,-1 },
{ 0, 1, 1 },
{ 0,-1, 1 },
{ 0, 1,-1 },
{ 0,-1,-1 },
};
float *grad = basis[grad_idx];
return grad[0]*x + grad[1]*y + grad[2]*z;
}
float stb_perlin_noise3_internal(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed)
{
float u,v,w;
float n000,n001,n010,n011,n100,n101,n110,n111;
float n00,n01,n10,n11;
float n0,n1;
unsigned int x_mask = (x_wrap-1) & 255;
unsigned int y_mask = (y_wrap-1) & 255;
unsigned int z_mask = (z_wrap-1) & 255;
int px = stb__perlin_fastfloor(x);
int py = stb__perlin_fastfloor(y);
int pz = stb__perlin_fastfloor(z);
int x0 = px & x_mask, x1 = (px+1) & x_mask;
int y0 = py & y_mask, y1 = (py+1) & y_mask;
int z0 = pz & z_mask, z1 = (pz+1) & z_mask;
int r0,r1, r00,r01,r10,r11;
#define stb__perlin_ease(a) (((a*6-15)*a + 10) * a * a * a)
x -= px; u = stb__perlin_ease(x);
y -= py; v = stb__perlin_ease(y);
z -= pz; w = stb__perlin_ease(z);
r0 = stb__perlin_randtab[x0+seed];
r1 = stb__perlin_randtab[x1+seed];
r00 = stb__perlin_randtab[r0+y0];
r01 = stb__perlin_randtab[r0+y1];
r10 = stb__perlin_randtab[r1+y0];
r11 = stb__perlin_randtab[r1+y1];
n000 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z0], x , y , z );
n001 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z1], x , y , z-1 );
n010 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z0], x , y-1, z );
n011 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z1], x , y-1, z-1 );
n100 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z0], x-1, y , z );
n101 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z1], x-1, y , z-1 );
n110 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z0], x-1, y-1, z );
n111 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z1], x-1, y-1, z-1 );
n00 = stb__perlin_lerp(n000,n001,w);
n01 = stb__perlin_lerp(n010,n011,w);
n10 = stb__perlin_lerp(n100,n101,w);
n11 = stb__perlin_lerp(n110,n111,w);
n0 = stb__perlin_lerp(n00,n01,v);
n1 = stb__perlin_lerp(n10,n11,v);
return stb__perlin_lerp(n0,n1,u);
}
float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap)
{
return stb_perlin_noise3_internal(x,y,z,x_wrap,y_wrap,z_wrap,0);
}
float stb_perlin_noise3_seed(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, int seed)
{
return stb_perlin_noise3_internal(x,y,z,x_wrap,y_wrap,z_wrap, (unsigned char) seed);
}
float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves)
{
int i;
float frequency = 1.0f;
float prev = 1.0f;
float amplitude = 0.5f;
float sum = 0.0f;
for (i = 0; i < octaves; i++) {
float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i);
r = offset - (float) fabs(r);
r = r*r;
sum += r*amplitude*prev;
prev = r;
frequency *= lacunarity;
amplitude *= gain;
}
return sum;
}
float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
{
int i;
float frequency = 1.0f;
float amplitude = 1.0f;
float sum = 0.0f;
for (i = 0; i < octaves; i++) {
sum += stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
frequency *= lacunarity;
amplitude *= gain;
}
return sum;
}
float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
{
int i;
float frequency = 1.0f;
float amplitude = 1.0f;
float sum = 0.0f;
for (i = 0; i < octaves; i++) {
float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
sum += (float) fabs(r);
frequency *= lacunarity;
amplitude *= gain;
}
return sum;
}
float stb_perlin_noise3_wrap_nonpow2(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed)
{
float u,v,w;
float n000,n001,n010,n011,n100,n101,n110,n111;
float n00,n01,n10,n11;
float n0,n1;
int px = stb__perlin_fastfloor(x);
int py = stb__perlin_fastfloor(y);
int pz = stb__perlin_fastfloor(z);
int x_wrap2 = (x_wrap ? x_wrap : 256);
int y_wrap2 = (y_wrap ? y_wrap : 256);
int z_wrap2 = (z_wrap ? z_wrap : 256);
int x0 = px % x_wrap2, x1;
int y0 = py % y_wrap2, y1;
int z0 = pz % z_wrap2, z1;
int r0,r1, r00,r01,r10,r11;
if (x0 < 0) x0 += x_wrap2;
if (y0 < 0) y0 += y_wrap2;
if (z0 < 0) z0 += z_wrap2;
x1 = (x0+1) % x_wrap2;
y1 = (y0+1) % y_wrap2;
z1 = (z0+1) % z_wrap2;
#define stb__perlin_ease(a) (((a*6-15)*a + 10) * a * a * a)
x -= px; u = stb__perlin_ease(x);
y -= py; v = stb__perlin_ease(y);
z -= pz; w = stb__perlin_ease(z);
r0 = stb__perlin_randtab[x0];
r0 = stb__perlin_randtab[r0+seed];
r1 = stb__perlin_randtab[x1];
r1 = stb__perlin_randtab[r1+seed];
r00 = stb__perlin_randtab[r0+y0];
r01 = stb__perlin_randtab[r0+y1];
r10 = stb__perlin_randtab[r1+y0];
r11 = stb__perlin_randtab[r1+y1];
n000 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z0], x , y , z );
n001 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z1], x , y , z-1 );
n010 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z0], x , y-1, z );
n011 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z1], x , y-1, z-1 );
n100 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z0], x-1, y , z );
n101 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z1], x-1, y , z-1 );
n110 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z0], x-1, y-1, z );
n111 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z1], x-1, y-1, z-1 );
n00 = stb__perlin_lerp(n000,n001,w);
n01 = stb__perlin_lerp(n010,n011,w);
n10 = stb__perlin_lerp(n100,n101,w);
n11 = stb__perlin_lerp(n110,n111,w);
n0 = stb__perlin_lerp(n00,n01,v);
n1 = stb__perlin_lerp(n10,n11,v);
return stb__perlin_lerp(n0,n1,u);
}
#endif // STB_PERLIN_IMPLEMENTATION
/*
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/

View file

@ -67,7 +67,7 @@ revision history:
#define VOX_SUCCESS (0) #define VOX_SUCCESS (0)
#define VOX_ERROR_FILE_NOT_FOUND (-1) #define VOX_ERROR_FILE_NOT_FOUND (-1)
#define VOX_ERROR_INVALID_FORMAT (-2) #define VOX_ERROR_INVALID_FORMAT (-2)
#define VOX_ERROR_FILE_VERSION_TOO_OLD (-3) #define VOX_ERROR_FILE_VERSION_NOT_MATCH (-3)
// VoxColor, 4 components, R8G8B8A8 (32bit) // VoxColor, 4 components, R8G8B8A8 (32bit)
typedef struct { typedef struct {
@ -538,31 +538,26 @@ int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArr
// @raysan5: Reviewed (unsigned long) -> (unsigned int), possible issue with Ubuntu 18.04 64bit // @raysan5: Reviewed (unsigned long) -> (unsigned int), possible issue with Ubuntu 18.04 64bit
// @raysan5: reviewed signature loading // @raysan5: reviewed signature loading
unsigned char signature[4] = { 0 };
unsigned char* fileData = pvoxData; unsigned char* fileData = pvoxData;
unsigned char* fileDataPtr = fileData; unsigned char* fileDataPtr = fileData;
unsigned char* endfileDataPtr = fileData + voxDataSize; unsigned char* endfileDataPtr = fileData + voxDataSize;
signature[0] = fileDataPtr[0]; if (strncmp((char*)fileDataPtr, "VOX ", 4) != 0)
signature[1] = fileDataPtr[1];
signature[2] = fileDataPtr[2];
signature[3] = fileDataPtr[3];
fileDataPtr += 4;
if ((signature[0] != 'V') && (signature[0] != 'O') && (signature[0] != 'X') && (signature[0] != ' '))
{ {
return VOX_ERROR_INVALID_FORMAT; //"Not an MagicaVoxel File format" return VOX_ERROR_INVALID_FORMAT; //"Not an MagicaVoxel File format"
} }
fileDataPtr += 4;
// @raysan5: reviewed version loading // @raysan5: reviewed version loading
unsigned int version = 0; unsigned int version = 0;
version = ((unsigned int*)fileDataPtr)[0]; version = ((unsigned int*)fileDataPtr)[0];
fileDataPtr += 4; fileDataPtr += 4;
if (version < 150) if (version != 150)
{ {
return VOX_ERROR_FILE_VERSION_TOO_OLD; //"MagicaVoxel version too old" return VOX_ERROR_FILE_VERSION_NOT_MATCH; //"MagicaVoxel version doesn't match"
} }

View file

@ -512,7 +512,9 @@ void CloseAudioDevice(void)
AUDIO.System.isReady = false; AUDIO.System.isReady = false;
RL_FREE(AUDIO.System.pcmBuffer); RL_FREE(AUDIO.System.pcmBuffer);
AUDIO.System.pcmBuffer = NULL;
AUDIO.System.pcmBufferSize = 0;
TRACELOG(LOG_INFO, "AUDIO: Device closed successfully"); TRACELOG(LOG_INFO, "AUDIO: Device closed successfully");
} }
else TRACELOG(LOG_WARNING, "AUDIO: Device could not be closed, not currently initialized"); else TRACELOG(LOG_WARNING, "AUDIO: Device could not be closed, not currently initialized");

View file

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raylib v4.2 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) * raylib v4.5-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
* *
* FEATURES: * FEATURES:
* - NO external dependencies, all required libraries included with raylib * - NO external dependencies, all required libraries included with raylib
@ -81,7 +81,7 @@
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback #include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
#define RAYLIB_VERSION "4.2" #define RAYLIB_VERSION "4.5-dev"
// Function specifiers in case library is build/used as a shared library (Windows) // Function specifiers in case library is build/used as a shared library (Windows)
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
@ -305,7 +305,7 @@ typedef struct Camera3D {
Vector3 position; // Camera position Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis) Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic float fovy; // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic
int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
} Camera3D; } Camera3D;
@ -364,7 +364,7 @@ typedef struct Material {
float params[4]; // Material generic parameters (if required) float params[4]; // Material generic parameters (if required)
} Material; } Material;
// Transform, vectex transformation data // Transform, vertex transformation data
typedef struct Transform { typedef struct Transform {
Vector3 translation; // Translation Vector3 translation; // Translation
Quaternion rotation; // Rotation Quaternion rotation; // Rotation
@ -663,7 +663,7 @@ typedef enum {
MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel) MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel)
MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device) MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device)
MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device) MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device)
MOUSE_BUTTON_FORWARD = 5, // Mouse button fordward (advanced mouse device) MOUSE_BUTTON_FORWARD = 5, // Mouse button forward (advanced mouse device)
MOUSE_BUTTON_BACK = 6, // Mouse button back (advanced mouse device) MOUSE_BUTTON_BACK = 6, // Mouse button back (advanced mouse device)
} MouseButton; } MouseButton;
@ -857,7 +857,8 @@ typedef enum {
BLEND_ADD_COLORS, // Blend textures adding colors (alternative) BLEND_ADD_COLORS, // Blend textures adding colors (alternative)
BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative)
BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha
BLEND_CUSTOM // Blend textures using custom src/dst factors (use rlSetBlendMode()) BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendMode())
BLEND_CUSTOM_SEPARATE // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendModeSeparate())
} BlendMode; } BlendMode;
// Gesture // Gesture
@ -967,7 +968,7 @@ RLAPI void DisableEventWaiting(void); // Disable wai
// Custom frame control functions // Custom frame control functions
// NOTE: Those functions are intended for advance users that want full control over the frame processing // NOTE: Those functions are intended for advance users that want full control over the frame processing
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents() // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents()
// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL // To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL
RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing)
RLAPI void PollInputEvents(void); // Register all input events RLAPI void PollInputEvents(void); // Register all input events
@ -1039,8 +1040,8 @@ RLAPI void SetConfigFlags(unsigned int flags); // Setup init
RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)
RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level
RLAPI void *MemAlloc(int size); // Internal memory allocator RLAPI void *MemAlloc(unsigned int size); // Internal memory allocator
RLAPI void *MemRealloc(void *ptr, int size); // Internal memory reallocator RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal memory reallocator
RLAPI void MemFree(void *ptr); // Internal memory free RLAPI void MemFree(void *ptr); // Internal memory free
RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available)
@ -1213,6 +1214,7 @@ RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec);
RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
RLAPI bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices
RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
@ -1240,7 +1242,9 @@ RLAPI Image GenImageGradientH(int width, int height, Color left, Color right);
RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient
RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked
RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise
RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise
RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells
RLAPI Image GenImageText(int width, int height, const char *text); // Generate image: grayscale image from text data
// Image manipulation functions // Image manipulation functions
RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
@ -1283,8 +1287,10 @@ RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color);
RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version) RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version)
RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image
RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version) RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version)
RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle within an image RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image
RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw circle within an image (Vector version) RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version)
RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image
RLAPI void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color); // Draw circle outline within an image (Vector version)
RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version) RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
@ -1366,12 +1372,15 @@ RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint);
RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found
// Text codepoints management functions (unicode characters) // Text codepoints management functions (unicode characters)
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
RLAPI int GetCodepoint(const char *text, int *bytesProcessed); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
RLAPI const char *CodepointToUTF8(int codepoint, int *byteSize); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
RLAPI char *TextCodepointsToUTF8(const int *codepoints, int length); // Encode text as codepoints array into UTF-8 text string (WARNING: memory must be freed!) RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
// Text strings management functions (no UTF-8 strings, only byte chars) // Text strings management functions (no UTF-8 strings, only byte chars)
// NOTE: Some strings allocate memory internally for returned strings, just be careful! // NOTE: Some strings allocate memory internally for returned strings, just be careful!
@ -1414,6 +1423,8 @@ RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, f
RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos
RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos
RLAPI void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos
RLAPI void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos
RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line
RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))

View file

@ -241,7 +241,7 @@
//#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition //#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition
#include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow() #include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow()
#endif #endif
// TODO: HACK: Added flag if not provided by GLFW when using external library // TODO: HACK: Added flag if not provided by GLFW when using external library
// Latest GLFW release (GLFW 3.3.8) does not implement this flag, it was added for 3.4.0-dev // Latest GLFW release (GLFW 3.3.8) does not implement this flag, it was added for 3.4.0-dev
#if !defined(GLFW_MOUSE_PASSTHROUGH) #if !defined(GLFW_MOUSE_PASSTHROUGH)
@ -505,7 +505,7 @@ typedef struct CoreData {
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
const char *raylibVersion = RAYLIB_VERSION; // raylib version symbol, it could be required for some bindings RLAPI const char *raylib_version = RAYLIB_VERSION; // raylib version exported symbol, required for some bindings
static CoreData CORE = { 0 }; // Global CORE state context static CoreData CORE = { 0 }; // Global CORE state context
@ -1697,49 +1697,58 @@ int GetMonitorCount(void)
// Get number of monitors // Get number of monitors
int GetCurrentMonitor(void) int GetCurrentMonitor(void)
{ {
int index = 0;
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
int monitorCount; int monitorCount;
GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
GLFWmonitor* monitor = NULL; GLFWmonitor *monitor = NULL;
if (monitorCount == 1) // easy out if (monitorCount > 1)
return 0;
if (IsWindowFullscreen())
{ {
monitor = glfwGetWindowMonitor(CORE.Window.handle); if (IsWindowFullscreen())
for (int i = 0; i < monitorCount; i++)
{ {
if (monitors[i] == monitor) // Get the handle of the monitor that the specified window is in full screen on
return i; monitor = glfwGetWindowMonitor(CORE.Window.handle);
for (int i = 0; i < monitorCount; i++)
{
if (monitors[i] == monitor)
{
index = i;
break;
}
}
} }
return 0; else
}
else
{
int x = 0;
int y = 0;
glfwGetWindowPos(CORE.Window.handle, &x, &y);
for (int i = 0; i < monitorCount; i++)
{ {
int mx = 0; int x = 0;
int my = 0; int y = 0;
int width = 0; glfwGetWindowPos(CORE.Window.handle, &x, &y);
int height = 0;
monitor = monitors[i]; for (int i = 0; i < monitorCount; i++)
glfwGetMonitorWorkarea(monitor, &mx, &my, &width, &height); {
if (x >= mx && x <= (mx + width) && y >= my && y <= (my + height)) int mx = 0;
return i; int my = 0;
int width = 0;
int height = 0;
monitor = monitors[i];
glfwGetMonitorWorkarea(monitor, &mx, &my, &width, &height);
if (x >= mx && x <= (mx + width) && y >= my && y <= (my + height))
{
index = i;
break;
}
}
} }
} }
return 0;
#else
return 0;
#endif #endif
return index;
} }
// Get selected monitor position // Get selected monitor position
@ -1747,7 +1756,7 @@ Vector2 GetMonitorPosition(int monitor)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
int monitorCount; int monitorCount;
GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
if ((monitor >= 0) && (monitor < monitorCount)) if ((monitor >= 0) && (monitor < monitorCount))
{ {
@ -1817,7 +1826,7 @@ int GetMonitorPhysicalWidth(int monitor)
return 0; return 0;
} }
// Get primary monitor physical height in millimetres // Get selected monitor physical height in millimetres
int GetMonitorPhysicalHeight(int monitor) int GetMonitorPhysicalHeight(int monitor)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
@ -1835,6 +1844,7 @@ int GetMonitorPhysicalHeight(int monitor)
return 0; return 0;
} }
// Get selected monitor refresh rate
int GetMonitorRefreshRate(int monitor) int GetMonitorRefreshRate(int monitor)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
@ -1868,7 +1878,7 @@ Vector2 GetWindowPosition(void)
return (Vector2){ (float)x, (float)y }; return (Vector2){ (float)x, (float)y };
} }
// Get window scale DPI factor // Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void) Vector2 GetWindowScaleDPI(void)
{ {
Vector2 scale = { 1.0f, 1.0f }; Vector2 scale = { 1.0f, 1.0f };
@ -1902,7 +1912,7 @@ Vector2 GetWindowScaleDPI(void)
return scale; return scale;
} }
// Get the human-readable, UTF-8 encoded name of the primary monitor // Get the human-readable, UTF-8 encoded name of the selected monitor
const char *GetMonitorName(int monitor) const char *GetMonitorName(int monitor)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
@ -1936,7 +1946,7 @@ void EnableEventWaiting(void)
} }
// Disable waiting for events on EndDrawing(), automatic events polling // Disable waiting for events on EndDrawing(), automatic events polling
RLAPI void DisableEventWaiting(void) void DisableEventWaiting(void)
{ {
CORE.Window.eventWaiting = false; CORE.Window.eventWaiting = false;
} }
@ -1954,8 +1964,6 @@ const char *GetClipboardText(void)
return NULL; return NULL;
} }
// Show mouse cursor // Show mouse cursor
void ShowCursor(void) void ShowCursor(void)
{ {
@ -2341,7 +2349,7 @@ VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device)
{ {
VrStereoConfig config = { 0 }; VrStereoConfig config = { 0 };
if ((rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20)) if ((rlGetVersion() == RL_OPENGL_33) || (rlGetVersion() == RL_OPENGL_ES_20))
{ {
// Compute aspect ratio // Compute aspect ratio
float aspect = ((float)device.hResolution*0.5f)/(float)device.vResolution; float aspect = ((float)device.hResolution*0.5f)/(float)device.vResolution;
@ -2437,7 +2445,7 @@ Shader LoadShader(const char *vsFileName, const char *fsFileName)
} }
// Load shader from code strings and bind default locations // Load shader from code strings and bind default locations
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode) Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
{ {
Shader shader = { 0 }; Shader shader = { 0 };
shader.locs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int)); shader.locs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int));
@ -3784,7 +3792,7 @@ float GetMouseWheelMove(void)
Vector2 GetMouseWheelMoveV(void) Vector2 GetMouseWheelMoveV(void)
{ {
Vector2 result = { 0 }; Vector2 result = { 0 };
result = CORE.Input.Mouse.currentWheelMove; result = CORE.Input.Mouse.currentWheelMove;
return result; return result;
@ -3837,22 +3845,7 @@ Vector2 GetTouchPosition(int index)
// https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages // https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages
if (index == 0) position = GetMousePosition(); if (index == 0) position = GetMousePosition();
#endif #endif
#if defined(PLATFORM_ANDROID) #if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
if (index < MAX_TOUCH_POINTS) position = CORE.Input.Touch.position[index];
else TRACELOG(LOG_WARNING, "INPUT: Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS);
if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
{
position.x = position.x*((float)CORE.Window.screen.width/(float)(CORE.Window.display.width - CORE.Window.renderOffset.x)) - CORE.Window.renderOffset.x/2;
position.y = position.y*((float)CORE.Window.screen.height/(float)(CORE.Window.display.height - CORE.Window.renderOffset.y)) - CORE.Window.renderOffset.y/2;
}
else
{
position.x = position.x*((float)CORE.Window.render.width/(float)CORE.Window.display.width) - CORE.Window.renderOffset.x/2;
position.y = position.y*((float)CORE.Window.render.height/(float)CORE.Window.display.height) - CORE.Window.renderOffset.y/2;
}
#endif
#if defined(PLATFORM_WEB) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
if (index < MAX_TOUCH_POINTS) position = CORE.Input.Touch.position[index]; if (index < MAX_TOUCH_POINTS) position = CORE.Input.Touch.position[index];
else TRACELOG(LOG_WARNING, "INPUT: Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS); else TRACELOG(LOG_WARNING, "INPUT: Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS);
#endif #endif
@ -3916,30 +3909,6 @@ static bool InitGraphicsDevice(int width, int height)
return false; return false;
} }
// NOTE: Getting video modes is not implemented in emscripten GLFW3 version
#if defined(PLATFORM_DESKTOP)
// Find monitor resolution
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor)
{
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return false;
}
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
#endif // PLATFORM_DESKTOP
#if defined(PLATFORM_WEB)
CORE.Window.display.width = CORE.Window.screen.width;
CORE.Window.display.height = CORE.Window.screen.height;
#endif // PLATFORM_WEB
glfwDefaultWindowHints(); // Set default windows hints glfwDefaultWindowHints(); // Set default windows hints
//glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
//glfwWindowHint(GLFW_GREEN_BITS, 8); // Framebuffer green color component bits //glfwWindowHint(GLFW_GREEN_BITS, 8); // Framebuffer green color component bits
@ -4003,17 +3972,17 @@ static bool InitGraphicsDevice(int width, int height)
glfwWindowHint(GLFW_SAMPLES, 4); // Tries to enable multisampling x4 (MSAA), default is 0 glfwWindowHint(GLFW_SAMPLES, 4); // Tries to enable multisampling x4 (MSAA), default is 0
} }
// NOTE: When asking for an OpenGL context version, most drivers provide highest supported version // NOTE: When asking for an OpenGL context version, most drivers provide the highest supported version
// with forward compatibility to older OpenGL versions. // with backward compatibility to older OpenGL versions.
// For example, if using OpenGL 1.1, driver can provide a 4.3 context forward compatible. // For example, if using OpenGL 1.1, driver can provide a 4.3 backwards compatible context.
// Check selection OpenGL version // Check selection OpenGL version
if (rlGetVersion() == OPENGL_21) if (rlGetVersion() == RL_OPENGL_21)
{ {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); // Choose OpenGL major version (just hint) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); // Choose OpenGL major version (just hint)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); // Choose OpenGL minor version (just hint) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); // Choose OpenGL minor version (just hint)
} }
else if (rlGetVersion() == OPENGL_33) else if (rlGetVersion() == RL_OPENGL_33)
{ {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
@ -4026,7 +3995,7 @@ static bool InitGraphicsDevice(int width, int height)
#endif #endif
//glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context //glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Request OpenGL DEBUG context
} }
else if (rlGetVersion() == OPENGL_43) else if (rlGetVersion() == RL_OPENGL_43)
{ {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // Choose OpenGL major version (just hint) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // Choose OpenGL major version (just hint)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
@ -4036,7 +4005,7 @@ static bool InitGraphicsDevice(int width, int height)
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Enable OpenGL Debug Context glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); // Enable OpenGL Debug Context
#endif #endif
} }
else if (rlGetVersion() == OPENGL_ES_20) // Request OpenGL ES 2.0 context else if (rlGetVersion() == RL_OPENGL_ES_20) // Request OpenGL ES 2.0 context
{ {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
@ -4056,6 +4025,31 @@ static bool InitGraphicsDevice(int width, int height)
if (MAX_GAMEPADS > 0) glfwSetJoystickCallback(NULL); if (MAX_GAMEPADS > 0) glfwSetJoystickCallback(NULL);
#endif #endif
#if defined(PLATFORM_DESKTOP)
// Find monitor resolution
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor)
{
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return false;
}
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
#endif // PLATFORM_DESKTOP
#if defined(PLATFORM_WEB)
// NOTE: Getting video modes is not implemented in emscripten GLFW3 version
CORE.Window.display.width = CORE.Window.screen.width;
CORE.Window.display.height = CORE.Window.screen.height;
#endif // PLATFORM_WEB
if (CORE.Window.fullscreen) if (CORE.Window.fullscreen)
{ {
// remember center for switchinging from fullscreen to window // remember center for switchinging from fullscreen to window
@ -4115,16 +4109,6 @@ static bool InitGraphicsDevice(int width, int height)
if (CORE.Window.handle) if (CORE.Window.handle)
{ {
#if defined(PLATFORM_DESKTOP)
// Center window on screen
int windowPosX = CORE.Window.display.width/2 - CORE.Window.screen.width/2;
int windowPosY = CORE.Window.display.height/2 - CORE.Window.screen.height/2;
if (windowPosX < 0) windowPosX = 0;
if (windowPosY < 0) windowPosY = 0;
glfwSetWindowPos(CORE.Window.handle, windowPosX, windowPosY);
#endif
CORE.Window.render.width = CORE.Window.screen.width; CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height; CORE.Window.render.height = CORE.Window.screen.height;
} }
@ -4145,6 +4129,7 @@ static bool InitGraphicsDevice(int width, int height)
glfwSetWindowIconifyCallback(CORE.Window.handle, WindowIconifyCallback); glfwSetWindowIconifyCallback(CORE.Window.handle, WindowIconifyCallback);
glfwSetWindowFocusCallback(CORE.Window.handle, WindowFocusCallback); glfwSetWindowFocusCallback(CORE.Window.handle, WindowFocusCallback);
glfwSetDropCallback(CORE.Window.handle, WindowDropCallback); glfwSetDropCallback(CORE.Window.handle, WindowDropCallback);
// Set input callback events // Set input callback events
glfwSetKeyCallback(CORE.Window.handle, KeyCallback); glfwSetKeyCallback(CORE.Window.handle, KeyCallback);
glfwSetCharCallback(CORE.Window.handle, CharCallback); glfwSetCharCallback(CORE.Window.handle, CharCallback);
@ -4156,6 +4141,8 @@ static bool InitGraphicsDevice(int width, int height)
glfwMakeContextCurrent(CORE.Window.handle); glfwMakeContextCurrent(CORE.Window.handle);
#if !defined(PLATFORM_WEB) #if !defined(PLATFORM_WEB)
glfwSetInputMode(CORE.Window.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM)
glfwSwapInterval(0); // No V-Sync by default glfwSwapInterval(0); // No V-Sync by default
#endif #endif
@ -4275,6 +4262,7 @@ static bool InitGraphicsDevice(int width, int height)
drmModeFreeConnector(con); drmModeFreeConnector(con);
} }
} }
if (!CORE.Window.connector) if (!CORE.Window.connector)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found"); TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
@ -4320,18 +4308,20 @@ static bool InitGraphicsDevice(int width, int height)
const bool allowInterlaced = CORE.Window.flags & FLAG_INTERLACED_HINT; const bool allowInterlaced = CORE.Window.flags & FLAG_INTERLACED_HINT;
const int fps = (CORE.Time.target > 0) ? (1.0/CORE.Time.target) : 60; const int fps = (CORE.Time.target > 0) ? (1.0/CORE.Time.target) : 60;
// try to find an exact matching mode
// Try to find an exact matching mode
CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced); CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
// if nothing found, try to find a nearly matching mode
if (CORE.Window.modeIndex < 0) // If nothing found, try to find a nearly matching mode
CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced); if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
// if nothing found, try to find an exactly matching mode including interlaced
if (CORE.Window.modeIndex < 0) // If nothing found, try to find an exactly matching mode including interlaced
CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true); if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
// if nothing found, try to find a nearly matching mode including interlaced
if (CORE.Window.modeIndex < 0) // If nothing found, try to find a nearly matching mode including interlaced
CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true); if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
// if nothing found, there is no suitable mode
// If nothing found, there is no suitable mode
if (CORE.Window.modeIndex < 0) if (CORE.Window.modeIndex < 0)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode"); TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
@ -5163,7 +5153,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
// Scan all files and directories recursively from a base path // Scan all files and directories recursively from a base path
static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *files, const char *filter) static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *files, const char *filter)
{ {
static char path[MAX_FILEPATH_LENGTH] = { 0 }; char path[MAX_FILEPATH_LENGTH] = { 0 };
memset(path, 0, MAX_FILEPATH_LENGTH); memset(path, 0, MAX_FILEPATH_LENGTH);
struct dirent *dp = NULL; struct dirent *dp = NULL;
@ -5278,12 +5268,18 @@ static void WindowFocusCallback(GLFWwindow *window, int focused)
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{ {
if (key < 0) return; // Security check, macOS fn key generates -1 if (key < 0) return; // Security check, macOS fn key generates -1
// WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1
// to work properly with our implementation (IsKeyDown/IsKeyUp checks) // to work properly with our implementation (IsKeyDown/IsKeyUp checks)
if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
else CORE.Input.Keyboard.currentKeyState[key] = 1; else CORE.Input.Keyboard.currentKeyState[key] = 1;
#if !defined(PLATFORM_WEB)
// WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys
if (((key == KEY_CAPS_LOCK) && ((mods & GLFW_MOD_CAPS_LOCK) > 0)) ||
((key == KEY_NUM_LOCK) && ((mods & GLFW_MOD_NUM_LOCK) > 0))) CORE.Input.Keyboard.currentKeyState[key] = 1;
#endif
// Check if there is space available in the key queue // Check if there is space available in the key queue
if ((CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) && (action == GLFW_PRESS)) if ((CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) && (action == GLFW_PRESS))
{ {
@ -5501,7 +5497,14 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// Reset screen scaling to full display size // Reset screen scaling to full display size
EGLint displayFormat = 0; EGLint displayFormat = 0;
eglGetConfigAttrib(CORE.Window.device, CORE.Window.config, EGL_NATIVE_VISUAL_ID, &displayFormat); eglGetConfigAttrib(CORE.Window.device, CORE.Window.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
ANativeWindow_setBuffersGeometry(app->window, CORE.Window.render.width, CORE.Window.render.height, displayFormat);
// Adding renderOffset here feels rather hackish, but the viewport scaling is wrong after the
// context rebinding if the screen is scaled unless offsets are added. There's probably a more
// appropriate way to fix this
ANativeWindow_setBuffersGeometry(app->window,
CORE.Window.render.width + CORE.Window.renderOffset.x,
CORE.Window.render.height + CORE.Window.renderOffset.y,
displayFormat);
// Recreate display surface and re-attach OpenGL context // Recreate display surface and re-attach OpenGL context
CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, app->window, NULL); CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, app->window, NULL);
@ -5590,6 +5593,32 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
} }
} }
static GamepadButton AndroidTranslateGamepadButton(int button)
{
switch (button)
{
case AKEYCODE_BUTTON_A: return GAMEPAD_BUTTON_RIGHT_FACE_DOWN;
case AKEYCODE_BUTTON_B: return GAMEPAD_BUTTON_RIGHT_FACE_RIGHT;
case AKEYCODE_BUTTON_X: return GAMEPAD_BUTTON_RIGHT_FACE_LEFT;
case AKEYCODE_BUTTON_Y: return GAMEPAD_BUTTON_RIGHT_FACE_UP;
case AKEYCODE_BUTTON_L1: return GAMEPAD_BUTTON_LEFT_TRIGGER_1;
case AKEYCODE_BUTTON_R1: return GAMEPAD_BUTTON_RIGHT_TRIGGER_1;
case AKEYCODE_BUTTON_L2: return GAMEPAD_BUTTON_LEFT_TRIGGER_2;
case AKEYCODE_BUTTON_R2: return GAMEPAD_BUTTON_RIGHT_TRIGGER_2;
case AKEYCODE_BUTTON_THUMBL: return GAMEPAD_BUTTON_LEFT_THUMB;
case AKEYCODE_BUTTON_THUMBR: return GAMEPAD_BUTTON_RIGHT_THUMB;
case AKEYCODE_BUTTON_START: return GAMEPAD_BUTTON_MIDDLE_RIGHT;
case AKEYCODE_BUTTON_SELECT: return GAMEPAD_BUTTON_MIDDLE_LEFT;
case AKEYCODE_BUTTON_MODE: return GAMEPAD_BUTTON_MIDDLE;
// On some (most?) gamepads dpad events are reported as axis motion instead
case AKEYCODE_DPAD_DOWN: return GAMEPAD_BUTTON_LEFT_FACE_DOWN;
case AKEYCODE_DPAD_RIGHT: return GAMEPAD_BUTTON_LEFT_FACE_RIGHT;
case AKEYCODE_DPAD_LEFT: return GAMEPAD_BUTTON_LEFT_FACE_LEFT;
case AKEYCODE_DPAD_UP: return GAMEPAD_BUTTON_LEFT_FACE_UP;
default: return GAMEPAD_BUTTON_UNKNOWN;
}
}
// ANDROID: Get input events // ANDROID: Get input events
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
{ {
@ -5605,26 +5634,59 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) || if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) ||
((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD)) ((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD))
{ {
// Get first touch position // For now we'll assume a single gamepad which we "detect" on its input event
CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0); CORE.Input.Gamepad.ready[0] = true;
CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0);
// Get second touch position CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_X] = AMotionEvent_getAxisValue(
CORE.Input.Touch.position[1].x = AMotionEvent_getX(event, 1); event, AMOTION_EVENT_AXIS_X, 0);
CORE.Input.Touch.position[1].y = AMotionEvent_getY(event, 1); CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_Y] = AMotionEvent_getAxisValue(
event, AMOTION_EVENT_AXIS_Y, 0);
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_X] = AMotionEvent_getAxisValue(
event, AMOTION_EVENT_AXIS_Z, 0);
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_Y] = AMotionEvent_getAxisValue(
event, AMOTION_EVENT_AXIS_RZ, 0);
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_TRIGGER] = AMotionEvent_getAxisValue(
event, AMOTION_EVENT_AXIS_BRAKE, 0) * 2.0f - 1.0f;
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_TRIGGER] = AMotionEvent_getAxisValue(
event, AMOTION_EVENT_AXIS_GAS, 0) * 2.0f - 1.0f;
int32_t keycode = AKeyEvent_getKeyCode(event); // dpad is reported as an axis on android
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) float dpadX = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_X, 0);
float dpadY = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_Y, 0);
if (dpadX == 1.0f)
{ {
CORE.Input.Keyboard.currentKeyState[keycode] = 1; // Key down CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_RIGHT] = 1;
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_LEFT] = 0;
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; }
CORE.Input.Keyboard.keyPressedQueueCount++; else if (dpadX == -1.0f)
{
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_RIGHT] = 0;
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_LEFT] = 1;
}
else
{
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_RIGHT] = 0;
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_LEFT] = 0;
} }
else CORE.Input.Keyboard.currentKeyState[keycode] = 0; // Key up
// Stop processing gamepad buttons if (dpadY == 1.0f)
return 1; {
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_DOWN] = 1;
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_UP] = 0;
}
else if (dpadY == -1.0f)
{
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_DOWN] = 0;
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_UP] = 1;
}
else
{
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_DOWN] = 0;
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_UP] = 0;
}
return 1; // Handled gamepad axis motion
} }
} }
else if (type == AINPUT_EVENT_TYPE_KEY) else if (type == AINPUT_EVENT_TYPE_KEY)
@ -5632,6 +5694,25 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
int32_t keycode = AKeyEvent_getKeyCode(event); int32_t keycode = AKeyEvent_getKeyCode(event);
//int32_t AKeyEvent_getMetaState(event); //int32_t AKeyEvent_getMetaState(event);
// Handle gamepad button presses and releases
if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) ||
((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD))
{
// For now we'll assume a single gamepad which we "detect" on its input event
CORE.Input.Gamepad.ready[0] = true;
GamepadButton button = AndroidTranslateGamepadButton(keycode);
if (button == GAMEPAD_BUTTON_UNKNOWN)
return 1;
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
{
CORE.Input.Gamepad.currentButtonState[0][button] = 1;
}
else CORE.Input.Gamepad.currentButtonState[0][button] = 0; // Key up
return 1; // Handled gamepad button
}
// Save current button and its state // Save current button and its state
// NOTE: Android key action is 0 for down and 1 for up // NOTE: Android key action is 0 for down and 1 for up
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
@ -5677,17 +5758,16 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
// Register touch points position // Register touch points position
CORE.Input.Touch.position[i] = (Vector2){ AMotionEvent_getX(event, i), AMotionEvent_getY(event, i) }; CORE.Input.Touch.position[i] = (Vector2){ AMotionEvent_getX(event, i), AMotionEvent_getY(event, i) };
// Normalize CORE.Input.Touch.position[x] for screenWidth and screenHeight // Normalize CORE.Input.Touch.position[i] for CORE.Window.screen.width and CORE.Window.screen.height
CORE.Input.Touch.position[i].x /= (float)GetScreenWidth(); float widthRatio = (float)(CORE.Window.screen.width + CORE.Window.renderOffset.x) / (float)CORE.Window.display.width;
CORE.Input.Touch.position[i].y /= (float)GetScreenHeight(); float heightRatio = (float)(CORE.Window.screen.height + CORE.Window.renderOffset.y) / (float)CORE.Window.display.height;
CORE.Input.Touch.position[i].x = CORE.Input.Touch.position[i].x * widthRatio - (float)CORE.Window.renderOffset.x / 2;
CORE.Input.Touch.position[i].y = CORE.Input.Touch.position[i].y * heightRatio - (float)CORE.Window.renderOffset.y / 2;
} }
int32_t action = AMotionEvent_getAction(event); int32_t action = AMotionEvent_getAction(event);
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK; unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
if (flags == AMOTION_EVENT_ACTION_DOWN || flags == AMOTION_EVENT_ACTION_MOVE) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 1;
else if (flags == AMOTION_EVENT_ACTION_UP) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0;
#if defined(SUPPORT_GESTURES_SYSTEM) // PLATFORM_ANDROID #if defined(SUPPORT_GESTURES_SYSTEM) // PLATFORM_ANDROID
GestureEvent gestureEvent = { 0 }; GestureEvent gestureEvent = { 0 };
@ -5709,6 +5789,25 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
ProcessGestureEvent(gestureEvent); ProcessGestureEvent(gestureEvent);
#endif #endif
int32_t pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
if (flags == AMOTION_EVENT_ACTION_POINTER_UP || flags == AMOTION_EVENT_ACTION_UP)
{
// One of the touchpoints is released, remove it from touch point arrays
for (int i = pointerIndex; (i < CORE.Input.Touch.pointCount-1) && (i < MAX_TOUCH_POINTS); i++)
{
CORE.Input.Touch.pointId[i] = CORE.Input.Touch.pointId[i+1];
CORE.Input.Touch.position[i] = CORE.Input.Touch.position[i+1];
}
CORE.Input.Touch.pointCount--;
}
// When all touchpoints are tapped and released really quickly, this event is generated
if (flags == AMOTION_EVENT_ACTION_CANCEL) CORE.Input.Touch.pointCount = 0;
if (CORE.Input.Touch.pointCount > 0) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 1;
else CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0;
return 0; return 0;
} }
#endif #endif

View file

@ -151,6 +151,7 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
#if defined(GESTURES_IMPLEMENTATION) #if defined(GESTURES_IMPLEMENTATION)
#if defined(GESTURES_STANDALONE)
#if defined(_WIN32) #if defined(_WIN32)
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { // Prevents name mangling of functions extern "C" { // Prevents name mangling of functions
@ -175,6 +176,7 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
#include <mach/clock.h> // Required for: clock_get_time() #include <mach/clock.h> // Required for: clock_get_time()
#include <mach/mach.h> // Required for: mach_timespec_t #include <mach/mach.h> // Required for: mach_timespec_t
#endif #endif
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
@ -526,6 +528,9 @@ static double rgGetCurrentTime(void)
{ {
double time = 0; double time = 0;
#if !defined(GESTURES_STANDALONE)
time = GetTime();
#else
#if defined(_WIN32) #if defined(_WIN32)
unsigned long long int clockFrequency, currentTime; unsigned long long int clockFrequency, currentTime;
@ -558,6 +563,7 @@ static double rgGetCurrentTime(void)
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
time = ((double)nowTime/1000000.0); // Time in miliseconds time = ((double)nowTime/1000000.0); // Time in miliseconds
#endif
#endif #endif
return time; return time;

View file

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* rlgl v4.0 - A multi-OpenGL abstraction layer with an immediate-mode style API * rlgl v4.2 - A multi-OpenGL abstraction layer with an immediate-mode style API
* *
* An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0) * An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0)
* that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...) * that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...)
@ -107,7 +107,7 @@
#ifndef RLGL_H #ifndef RLGL_H
#define RLGL_H #define RLGL_H
#define RLGL_VERSION "4.0" #define RLGL_VERSION "4.2"
// Function specifiers in case library is build/used as a shared library (Windows) // Function specifiers in case library is build/used as a shared library (Windows)
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
@ -243,6 +243,7 @@
#define RL_TEXTURE_FILTER_LINEAR_MIP_NEAREST 0x2701 // GL_LINEAR_MIPMAP_NEAREST #define RL_TEXTURE_FILTER_LINEAR_MIP_NEAREST 0x2701 // GL_LINEAR_MIPMAP_NEAREST
#define RL_TEXTURE_FILTER_MIP_LINEAR 0x2703 // GL_LINEAR_MIPMAP_LINEAR #define RL_TEXTURE_FILTER_MIP_LINEAR 0x2703 // GL_LINEAR_MIPMAP_LINEAR
#define RL_TEXTURE_FILTER_ANISOTROPIC 0x3000 // Anisotropic filter (custom identifier) #define RL_TEXTURE_FILTER_ANISOTROPIC 0x3000 // Anisotropic filter (custom identifier)
#define RL_TEXTURE_MIPMAP_BIAS_RATIO 0x4000 // Texture mipmap bias, percentage ratio (custom identifier)
#define RL_TEXTURE_WRAP_REPEAT 0x2901 // GL_REPEAT #define RL_TEXTURE_WRAP_REPEAT 0x2901 // GL_REPEAT
#define RL_TEXTURE_WRAP_CLAMP 0x812F // GL_CLAMP_TO_EDGE #define RL_TEXTURE_WRAP_CLAMP 0x812F // GL_CLAMP_TO_EDGE
@ -282,37 +283,23 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
typedef enum { #if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
OPENGL_11 = 1, #include <stdbool.h>
OPENGL_21, #elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
OPENGL_33, // Boolean type
OPENGL_43, typedef enum bool { false = 0, true = !false } bool;
OPENGL_ES_20 #endif
} rlGlVersion;
typedef enum { #if !defined(RL_MATRIX_TYPE)
RL_ATTACHMENT_COLOR_CHANNEL0 = 0, // Matrix, 4x4 components, column major, OpenGL style, right handed
RL_ATTACHMENT_COLOR_CHANNEL1, typedef struct Matrix {
RL_ATTACHMENT_COLOR_CHANNEL2, float m0, m4, m8, m12; // Matrix first row (4 components)
RL_ATTACHMENT_COLOR_CHANNEL3, float m1, m5, m9, m13; // Matrix second row (4 components)
RL_ATTACHMENT_COLOR_CHANNEL4, float m2, m6, m10, m14; // Matrix third row (4 components)
RL_ATTACHMENT_COLOR_CHANNEL5, float m3, m7, m11, m15; // Matrix fourth row (4 components)
RL_ATTACHMENT_COLOR_CHANNEL6, } Matrix;
RL_ATTACHMENT_COLOR_CHANNEL7, #define RL_MATRIX_TYPE
RL_ATTACHMENT_DEPTH = 100, #endif
RL_ATTACHMENT_STENCIL = 200,
} rlFramebufferAttachType;
typedef enum {
RL_ATTACHMENT_CUBEMAP_POSITIVE_X = 0,
RL_ATTACHMENT_CUBEMAP_NEGATIVE_X,
RL_ATTACHMENT_CUBEMAP_POSITIVE_Y,
RL_ATTACHMENT_CUBEMAP_NEGATIVE_Y,
RL_ATTACHMENT_CUBEMAP_POSITIVE_Z,
RL_ATTACHMENT_CUBEMAP_NEGATIVE_Z,
RL_ATTACHMENT_TEXTURE2D = 100,
RL_ATTACHMENT_RENDERBUFFER = 200,
} rlFramebufferAttachTextureType;
// Dynamic vertex buffers (position + texcoords + colors + indices arrays) // Dynamic vertex buffers (position + texcoords + colors + indices arrays)
typedef struct rlVertexBuffer { typedef struct rlVertexBuffer {
@ -343,8 +330,8 @@ typedef struct rlDrawCall {
//unsigned int shaderId; // Shader id to be used on the draw -> Using RLGL.currentShaderId //unsigned int shaderId; // Shader id to be used on the draw -> Using RLGL.currentShaderId
unsigned int textureId; // Texture id to be used on the draw -> Use to create new draw call if changes unsigned int textureId; // Texture id to be used on the draw -> Use to create new draw call if changes
//Matrix projection; // Projection matrix for this draw -> Using RLGL.projection by default //Matrix projection; // Projection matrix for this draw -> Using RLGL.projection by default
//Matrix modelview; // Modelview matrix for this draw -> Using RLGL.modelview by default //Matrix modelview; // Modelview matrix for this draw -> Using RLGL.modelview by default
} rlDrawCall; } rlDrawCall;
// rlRenderBatch type // rlRenderBatch type
@ -358,38 +345,30 @@ typedef struct rlRenderBatch {
float currentDepth; // Current depth value for next draw float currentDepth; // Current depth value for next draw
} rlRenderBatch; } rlRenderBatch;
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) // OpenGL version
#include <stdbool.h> typedef enum {
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE) RL_OPENGL_11 = 1, // OpenGL 1.1
// Boolean type RL_OPENGL_21, // OpenGL 2.1 (GLSL 120)
typedef enum bool { false = 0, true = !false } bool; RL_OPENGL_33, // OpenGL 3.3 (GLSL 330)
#endif RL_OPENGL_43, // OpenGL 4.3 (using GLSL 330)
RL_OPENGL_ES_20 // OpenGL ES 2.0 (GLSL 100)
#if !defined(RL_MATRIX_TYPE) } rlGlVersion;
// Matrix, 4x4 components, column major, OpenGL style, right handed
typedef struct Matrix {
float m0, m4, m8, m12; // Matrix first row (4 components)
float m1, m5, m9, m13; // Matrix second row (4 components)
float m2, m6, m10, m14; // Matrix third row (4 components)
float m3, m7, m11, m15; // Matrix fourth row (4 components)
} Matrix;
#define RL_MATRIX_TYPE
#endif
// Trace log level // Trace log level
// NOTE: Organized by priority level // NOTE: Organized by priority level
typedef enum { typedef enum {
RL_LOG_ALL = 0, // Display all logs RL_LOG_ALL = 0, // Display all logs
RL_LOG_TRACE, // Trace logging, intended for internal use only RL_LOG_TRACE, // Trace logging, intended for internal use only
RL_LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds RL_LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds
RL_LOG_INFO, // Info logging, used for program execution info RL_LOG_INFO, // Info logging, used for program execution info
RL_LOG_WARNING, // Warning logging, used on recoverable failures RL_LOG_WARNING, // Warning logging, used on recoverable failures
RL_LOG_ERROR, // Error logging, used on unrecoverable failures RL_LOG_ERROR, // Error logging, used on unrecoverable failures
RL_LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) RL_LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE)
RL_LOG_NONE // Disable logging RL_LOG_NONE // Disable logging
} rlTraceLogLevel; } rlTraceLogLevel;
// Texture formats (support depends on OpenGL version) // Texture pixel formats
// NOTE: Support depends on OpenGL version
typedef enum { typedef enum {
RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels)
@ -418,79 +397,107 @@ typedef enum {
// NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 1: Filtering considers mipmaps if available in the texture
// NOTE 2: Filter is accordingly set for minification and magnification // NOTE 2: Filter is accordingly set for minification and magnification
typedef enum { typedef enum {
RL_TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation RL_TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation
RL_TEXTURE_FILTER_BILINEAR, // Linear filtering RL_TEXTURE_FILTER_BILINEAR, // Linear filtering
RL_TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) RL_TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps)
RL_TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x RL_TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x
RL_TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x RL_TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x
RL_TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x RL_TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x
} rlTextureFilter; } rlTextureFilter;
// Color blending modes (pre-defined) // Color blending modes (pre-defined)
typedef enum { typedef enum {
RL_BLEND_ALPHA = 0, // Blend textures considering alpha (default) RL_BLEND_ALPHA = 0, // Blend textures considering alpha (default)
RL_BLEND_ADDITIVE, // Blend textures adding colors RL_BLEND_ADDITIVE, // Blend textures adding colors
RL_BLEND_MULTIPLIED, // Blend textures multiplying colors RL_BLEND_MULTIPLIED, // Blend textures multiplying colors
RL_BLEND_ADD_COLORS, // Blend textures adding colors (alternative) RL_BLEND_ADD_COLORS, // Blend textures adding colors (alternative)
RL_BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) RL_BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative)
RL_BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha RL_BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha
RL_BLEND_CUSTOM // Blend textures using custom src/dst factors (use rlSetBlendFactors()) RL_BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors())
RL_BLEND_CUSTOM_SEPARATE // Blend textures using custom src/dst factors (use rlSetBlendFactorsSeparate())
} rlBlendMode; } rlBlendMode;
// Shader location point type // Shader location point type
typedef enum { typedef enum {
RL_SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position RL_SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position
RL_SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 RL_SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01
RL_SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 RL_SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02
RL_SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal RL_SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal
RL_SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent RL_SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent
RL_SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color RL_SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color
RL_SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection RL_SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection
RL_SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) RL_SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform)
RL_SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection RL_SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection
RL_SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform) RL_SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform)
RL_SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal RL_SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal
RL_SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view RL_SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view
RL_SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color RL_SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color
RL_SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color RL_SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color
RL_SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color RL_SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color
RL_SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: RL_SHADER_LOC_MAP_DIFFUSE) RL_SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: RL_SHADER_LOC_MAP_DIFFUSE)
RL_SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: RL_SHADER_LOC_MAP_SPECULAR) RL_SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: RL_SHADER_LOC_MAP_SPECULAR)
RL_SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal RL_SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal
RL_SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness RL_SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness
RL_SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion RL_SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion
RL_SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission RL_SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission
RL_SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height RL_SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height
RL_SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap RL_SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap
RL_SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance RL_SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance
RL_SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter RL_SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter
RL_SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf RL_SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf
} rlShaderLocationIndex; } rlShaderLocationIndex;
#define RL_SHADER_LOC_MAP_DIFFUSE RL_SHADER_LOC_MAP_ALBEDO #define RL_SHADER_LOC_MAP_DIFFUSE RL_SHADER_LOC_MAP_ALBEDO
#define RL_SHADER_LOC_MAP_SPECULAR RL_SHADER_LOC_MAP_METALNESS #define RL_SHADER_LOC_MAP_SPECULAR RL_SHADER_LOC_MAP_METALNESS
// Shader uniform data type // Shader uniform data type
typedef enum { typedef enum {
RL_SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float RL_SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float
RL_SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float) RL_SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float)
RL_SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float) RL_SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float)
RL_SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float) RL_SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float)
RL_SHADER_UNIFORM_INT, // Shader uniform type: int RL_SHADER_UNIFORM_INT, // Shader uniform type: int
RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int) RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int)
RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int) RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int)
RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int) RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int)
RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d
} rlShaderUniformDataType; } rlShaderUniformDataType;
// Shader attribute data types // Shader attribute data types
typedef enum { typedef enum {
RL_SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float RL_SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float
RL_SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float) RL_SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float)
RL_SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float) RL_SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float)
RL_SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float) RL_SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float)
} rlShaderAttributeDataType; } rlShaderAttributeDataType;
// Framebuffer attachment type
// NOTE: By default up to 8 color channels defined but it can be more
typedef enum {
RL_ATTACHMENT_COLOR_CHANNEL0 = 0, // Framebuffer attachmment type: color 0
RL_ATTACHMENT_COLOR_CHANNEL1, // Framebuffer attachmment type: color 1
RL_ATTACHMENT_COLOR_CHANNEL2, // Framebuffer attachmment type: color 2
RL_ATTACHMENT_COLOR_CHANNEL3, // Framebuffer attachmment type: color 3
RL_ATTACHMENT_COLOR_CHANNEL4, // Framebuffer attachmment type: color 4
RL_ATTACHMENT_COLOR_CHANNEL5, // Framebuffer attachmment type: color 5
RL_ATTACHMENT_COLOR_CHANNEL6, // Framebuffer attachmment type: color 6
RL_ATTACHMENT_COLOR_CHANNEL7, // Framebuffer attachmment type: color 7
RL_ATTACHMENT_DEPTH = 100, // Framebuffer attachmment type: depth
RL_ATTACHMENT_STENCIL = 200, // Framebuffer attachmment type: stencil
} rlFramebufferAttachType;
// Framebuffer texture attachment type
typedef enum {
RL_ATTACHMENT_CUBEMAP_POSITIVE_X = 0, // Framebuffer texture attachment type: cubemap, +X side
RL_ATTACHMENT_CUBEMAP_NEGATIVE_X, // Framebuffer texture attachment type: cubemap, -X side
RL_ATTACHMENT_CUBEMAP_POSITIVE_Y, // Framebuffer texture attachment type: cubemap, +Y side
RL_ATTACHMENT_CUBEMAP_NEGATIVE_Y, // Framebuffer texture attachment type: cubemap, -Y side
RL_ATTACHMENT_CUBEMAP_POSITIVE_Z, // Framebuffer texture attachment type: cubemap, +Z side
RL_ATTACHMENT_CUBEMAP_NEGATIVE_Z, // Framebuffer texture attachment type: cubemap, -Z side
RL_ATTACHMENT_TEXTURE2D = 100, // Framebuffer texture attachment type: texture2d
RL_ATTACHMENT_RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer
} rlFramebufferAttachTextureType;
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration - Matrix operations // Functions Declaration - Matrix operations
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -589,23 +596,24 @@ RLAPI void rlClearScreenBuffers(void); // Clear used screen buf
RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes
RLAPI void rlSetBlendMode(int mode); // Set blending mode RLAPI void rlSetBlendMode(int mode); // Set blending mode
RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors) RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors)
RLAPI void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha); // Set blending mode factors and equations separately (using OpenGL factors)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration - rlgl functionality // Functions Declaration - rlgl functionality
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// rlgl initialization functions // rlgl initialization functions
RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states) RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states)
RLAPI void rlglClose(void); // De-inititialize rlgl (buffers, shaders, textures) RLAPI void rlglClose(void); // De-inititialize rlgl (buffers, shaders, textures)
RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required) RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required)
RLAPI int rlGetVersion(void); // Get current OpenGL version RLAPI int rlGetVersion(void); // Get current OpenGL version
RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width
RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width
RLAPI void rlSetFramebufferHeight(int height); // Set current framebuffer height RLAPI void rlSetFramebufferHeight(int height); // Set current framebuffer height
RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height
RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id
RLAPI unsigned int rlGetShaderIdDefault(void); // Get default shader id RLAPI unsigned int rlGetShaderIdDefault(void); // Get default shader id
RLAPI int *rlGetShaderLocsDefault(void); // Get default shader locations RLAPI int *rlGetShaderLocsDefault(void); // Get default shader locations
// Render batch management // Render batch management
// NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode // NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode
@ -616,7 +624,8 @@ RLAPI void rlDrawRenderBatch(rlRenderBatch *batch); // D
RLAPI void rlSetRenderBatchActive(rlRenderBatch *batch); // Set the active render batch for rlgl (NULL for default internal) RLAPI void rlSetRenderBatchActive(rlRenderBatch *batch); // Set the active render batch for rlgl (NULL for default internal)
RLAPI void rlDrawRenderBatchActive(void); // Update and draw internal render batch RLAPI void rlDrawRenderBatchActive(void); // Update and draw internal render batch
RLAPI bool rlCheckRenderBatchLimit(int vCount); // Check internal buffer overflow for a given number of vertex RLAPI bool rlCheckRenderBatchLimit(int vCount); // Check internal buffer overflow for a given number of vertex
RLAPI void rlSetTexture(unsigned int id); // Set current texture for render batch and check buffers limits
RLAPI void rlSetTexture(unsigned int id); // Set current texture for render batch and check buffers limits
//------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------
@ -671,15 +680,15 @@ RLAPI unsigned int rlLoadComputeShaderProgram(unsigned int shaderId);
RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pilepine) RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pilepine)
// Shader buffer storage object management (ssbo) // Shader buffer storage object management (ssbo)
RLAPI unsigned int rlLoadShaderBuffer(unsigned long long size, const void *data, int usageHint); // Load shader storage buffer object (SSBO) RLAPI unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHint); // Load shader storage buffer object (SSBO)
RLAPI void rlUnloadShaderBuffer(unsigned int ssboId); // Unload shader storage buffer object (SSBO) RLAPI void rlUnloadShaderBuffer(unsigned int ssboId); // Unload shader storage buffer object (SSBO)
RLAPI void rlUpdateShaderBufferElements(unsigned int id, const void *data, unsigned long long dataSize, unsigned long long offset); // Update SSBO buffer data RLAPI void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSize, unsigned int offset); // Update SSBO buffer data
RLAPI unsigned long long rlGetShaderBufferSize(unsigned int id); // Get SSBO buffer size RLAPI void rlBindShaderBuffer(unsigned int id, unsigned int index); // Bind SSBO buffer
RLAPI void rlReadShaderBufferElements(unsigned int id, void *dest, unsigned long long count, unsigned long long offset); // Bind SSBO buffer RLAPI void rlReadShaderBuffer(unsigned int id, void *dest, unsigned int count, unsigned int offset); // Read SSBO buffer data (GPU->CPU)
RLAPI void rlBindShaderBuffer(unsigned int id, unsigned int index); // Copy SSBO buffer data RLAPI void rlCopyShaderBuffer(unsigned int destId, unsigned int srcId, unsigned int destOffset, unsigned int srcOffset, unsigned int count); // Copy SSBO data between buffers
RLAPI unsigned int rlGetShaderBufferSize(unsigned int id); // Get SSBO buffer size
// Buffer management // Buffer management
RLAPI void rlCopyBuffersElements(unsigned int destId, unsigned int srcId, unsigned long long destOffset, unsigned long long srcOffset, unsigned long long count); // Copy SSBO buffer data
RLAPI void rlBindImageTexture(unsigned int id, unsigned int index, unsigned int format, int readonly); // Bind image texture RLAPI void rlBindImageTexture(unsigned int id, unsigned int index, unsigned int format, int readonly); // Bind image texture
// Matrix state management // Matrix state management
@ -734,16 +743,11 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#endif #endif
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
#if defined(__APPLE__) #define GLAD_MALLOC RL_MALLOC
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX #define GLAD_FREE RL_FREE
#include <OpenGL/gl3ext.h> // OpenGL 3 extensions library for OSX
#else
#define GLAD_MALLOC RL_MALLOC
#define GLAD_FREE RL_FREE
#define GLAD_GL_IMPLEMENTATION #define GLAD_GL_IMPLEMENTATION
#include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers #include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers
#endif
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
@ -924,10 +928,18 @@ typedef struct rlglData {
Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices
Matrix viewOffsetStereo[2]; // VR stereo rendering eyes view offset matrices Matrix viewOffsetStereo[2]; // VR stereo rendering eyes view offset matrices
// Blending variables
int currentBlendMode; // Blending mode active int currentBlendMode; // Blending mode active
int glBlendSrcFactor; // Blending source factor int glBlendSrcFactor; // Blending source factor
int glBlendDstFactor; // Blending destination factor int glBlendDstFactor; // Blending destination factor
int glBlendEquation; // Blending equation int glBlendEquation; // Blending equation
int glBlendSrcFactorRGB; // Blending source RGB factor
int glBlendDestFactorRGB; // Blending destination RGB factor
int glBlendSrcFactorAlpha; // Blending source alpha factor
int glBlendDestFactorAlpha; // Blending destination alpha factor
int glBlendEquationRGB; // Blending equation for RGB
int glBlendEquationAlpha; // Blending equation for alpha
bool glCustomBlendModeModified; // Custom blending factor and equation modification status
int framebufferWidth; // Current framebuffer width int framebufferWidth; // Current framebuffer width
int framebufferHeight; // Current framebuffer height int framebufferHeight; // Current framebuffer height
@ -988,14 +1000,12 @@ static void rlUnloadShaderDefault(void); // Unload default shader
static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name
#endif // RLGL_SHOW_GL_DETAILS_INFO #endif // RLGL_SHOW_GL_DETAILS_INFO
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
#if defined(GRAPHICS_API_OPENGL_11)
static int rlGenTextureMipmapsData(unsigned char *data, int baseWidth, int baseHeight); // Generate mipmaps data on CPU side
static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight); // Generate next mipmap level on CPU side
#endif
static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture) static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture)
// Auxiliar matrix math functions // Auxiliar matrix math functions
static Matrix rlMatrixIdentity(void); // Get identity matrix static Matrix rlMatrixIdentity(void); // Get identity matrix
static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition - Matrix operations // Module Functions Definition - Matrix operations
@ -1306,17 +1316,6 @@ void rlEnd(void)
// as well as depth buffer bit-depth (16bit or 24bit or 32bit) // as well as depth buffer bit-depth (16bit or 24bit or 32bit)
// Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits)
RLGL.currentBatch->currentDepth += (1.0f/20000.0f); RLGL.currentBatch->currentDepth += (1.0f/20000.0f);
// Verify internal buffers limits
// NOTE: This check is combined with usage of rlCheckRenderBatchLimit()
if (RLGL.State.vertexCounter >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4))
{
// WARNING: If we are between rlPushMatrix() and rlPopMatrix() and we need to force a rlDrawRenderBatch(),
// we need to call rlPopMatrix() before to recover *RLGL.State.currentMatrix (RLGL.State.modelview) for the next forced draw call!
// If we have multiple matrix pushed, it will require "RLGL.State.stackCounter" pops before launching the draw
for (int i = RLGL.State.stackCounter; i >= 0; i--) rlPopMatrix();
rlDrawRenderBatch(RLGL.currentBatch);
}
} }
// Define one vertex (position) // Define one vertex (position)
@ -1335,32 +1334,51 @@ void rlVertex3f(float x, float y, float z)
tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14; tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14;
} }
// Verify that current vertex buffer elements limit has not been reached // WARNING: We can't break primitives when launching a new batch.
if (RLGL.State.vertexCounter < (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4)) // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices.
// We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4
if (RLGL.State.vertexCounter > (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4))
{ {
// Add vertices if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) &&
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter] = tx; (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%2 == 0))
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 1] = ty; {
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 2] = tz; // Reached the maximum number of vertices for RL_LINES drawing
// Launch a draw call but keep current state for next vertices comming
// Add current texcoord // NOTE: We add +1 vertex to the check for security
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter] = RLGL.State.texcoordx; rlCheckRenderBatchLimit(2 + 1);
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter + 1] = RLGL.State.texcoordy; }
else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) &&
// TODO: Add current normal (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%3 == 0))
// By default rlVertexBuffer type does not store normals {
rlCheckRenderBatchLimit(3 + 1);
// Add current color }
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter] = RLGL.State.colorr; else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_QUADS) &&
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 1] = RLGL.State.colorg; (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4 == 0))
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 2] = RLGL.State.colorb; {
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 3] = RLGL.State.colora; rlCheckRenderBatchLimit(4 + 1);
}
RLGL.State.vertexCounter++;
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount++;
} }
else TRACELOG(RL_LOG_ERROR, "RLGL: Batch elements overflow");
// Add vertices
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter] = tx;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 1] = ty;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 2] = tz;
// Add current texcoord
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter] = RLGL.State.texcoordx;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter + 1] = RLGL.State.texcoordy;
// TODO: Add current normal
// By default rlVertexBuffer type does not store normals
// Add current color
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter] = RLGL.State.colorr;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 1] = RLGL.State.colorg;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 2] = RLGL.State.colorb;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 3] = RLGL.State.colora;
RLGL.State.vertexCounter++;
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount++;
} }
// Define one vertex (position) // Define one vertex (position)
@ -1551,6 +1569,9 @@ void rlTextureParameters(unsigned int id, int param, int value)
else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported"); else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported");
#endif #endif
} break; } break;
#if defined(GRAPHICS_API_OPENGL_33)
case RL_TEXTURE_MIPMAP_BIAS_RATIO: glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, value/100.0f);
#endif
default: break; default: break;
} }
@ -1777,7 +1798,7 @@ void rlCheckErrors()
void rlSetBlendMode(int mode) void rlSetBlendMode(int mode)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (RLGL.State.currentBlendMode != mode) if (RLGL.State.currentBlendMode != mode || ((mode == RL_BLEND_CUSTOM || mode == RL_BLEND_CUSTOM_SEPARATE) && RLGL.State.glCustomBlendModeModified))
{ {
rlDrawRenderBatch(RLGL.currentBatch); rlDrawRenderBatch(RLGL.currentBatch);
@ -1793,11 +1814,20 @@ void rlSetBlendMode(int mode)
{ {
// NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors() // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors()
glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation);
} break;
case RL_BLEND_CUSTOM_SEPARATE:
{
// NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactorsSeparate()
glBlendFuncSeparate(RLGL.State.glBlendSrcFactorRGB, RLGL.State.glBlendDestFactorRGB, RLGL.State.glBlendSrcFactorAlpha, RLGL.State.glBlendDestFactorAlpha);
glBlendEquationSeparate(RLGL.State.glBlendEquationRGB, RLGL.State.glBlendEquationAlpha);
} break; } break;
default: break; default: break;
} }
RLGL.State.currentBlendMode = mode; RLGL.State.currentBlendMode = mode;
RLGL.State.glCustomBlendModeModified = false;
} }
#endif #endif
} }
@ -1806,9 +1836,39 @@ void rlSetBlendMode(int mode)
void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation) void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
RLGL.State.glBlendSrcFactor = glSrcFactor; if ((RLGL.State.glBlendSrcFactor != glSrcFactor) ||
RLGL.State.glBlendDstFactor = glDstFactor; (RLGL.State.glBlendDstFactor != glDstFactor) ||
RLGL.State.glBlendEquation = glEquation; (RLGL.State.glBlendEquation != glEquation))
{
RLGL.State.glBlendSrcFactor = glSrcFactor;
RLGL.State.glBlendDstFactor = glDstFactor;
RLGL.State.glBlendEquation = glEquation;
RLGL.State.glCustomBlendModeModified = true;
}
#endif
}
// Set blending mode factor and equation separately for RGB and alpha
void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if ((RLGL.State.glBlendSrcFactorRGB != glSrcRGB) ||
(RLGL.State.glBlendDestFactorRGB != glDstRGB) ||
(RLGL.State.glBlendSrcFactorAlpha != glSrcAlpha) ||
(RLGL.State.glBlendDestFactorAlpha != glDstAlpha) ||
(RLGL.State.glBlendEquationRGB != glEqRGB) ||
(RLGL.State.glBlendEquationAlpha != glEqAlpha))
{
RLGL.State.glBlendSrcFactorRGB = glSrcRGB;
RLGL.State.glBlendDestFactorRGB = glDstRGB;
RLGL.State.glBlendSrcFactorAlpha = glSrcAlpha;
RLGL.State.glBlendDestFactorAlpha = glDstAlpha;
RLGL.State.glBlendEquationRGB = glEqRGB;
RLGL.State.glBlendEquationAlpha = glEqAlpha;
RLGL.State.glCustomBlendModeModified = true;
}
#endif #endif
} }
@ -1983,10 +2043,8 @@ void rlLoadExtensions(void *loader)
{ {
#if defined(GRAPHICS_API_OPENGL_33) // Also defined for GRAPHICS_API_OPENGL_21 #if defined(GRAPHICS_API_OPENGL_33) // Also defined for GRAPHICS_API_OPENGL_21
// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions) // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
#if !defined(__APPLE__) if (gladLoadGL((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
if (gladLoadGL((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL extensions"); else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
#endif
// Get number of supported extensions // Get number of supported extensions
GLint numExt = 0; GLint numExt = 0;
@ -2000,6 +2058,18 @@ void rlLoadExtensions(void *loader)
for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", glGetStringi(GL_EXTENSIONS, i)); for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", glGetStringi(GL_EXTENSIONS, i));
#endif #endif
#if defined(GRAPHICS_API_OPENGL_21)
// Register supported extensions flags
// Optional OpenGL 2.1 extensions
RLGL.ExtSupported.vao = GLAD_GL_ARB_vertex_array_object;
RLGL.ExtSupported.instancing = (GLAD_GL_EXT_draw_instanced && GLAD_GL_ARB_instanced_arrays);
RLGL.ExtSupported.texNPOT = GLAD_GL_ARB_texture_non_power_of_two;
RLGL.ExtSupported.texFloat32 = GLAD_GL_ARB_texture_float;
RLGL.ExtSupported.texDepth = GLAD_GL_ARB_depth_texture;
RLGL.ExtSupported.maxDepthBits = 32;
RLGL.ExtSupported.texAnisoFilter = GLAD_GL_EXT_texture_filter_anisotropic;
RLGL.ExtSupported.texMirrorClamp = GLAD_GL_EXT_texture_mirror_clamp;
#else
// Register supported extensions flags // Register supported extensions flags
// OpenGL 3.3 extensions supported by default (core) // OpenGL 3.3 extensions supported by default (core)
RLGL.ExtSupported.vao = true; RLGL.ExtSupported.vao = true;
@ -2010,15 +2080,17 @@ void rlLoadExtensions(void *loader)
RLGL.ExtSupported.maxDepthBits = 32; RLGL.ExtSupported.maxDepthBits = 32;
RLGL.ExtSupported.texAnisoFilter = true; RLGL.ExtSupported.texAnisoFilter = true;
RLGL.ExtSupported.texMirrorClamp = true; RLGL.ExtSupported.texMirrorClamp = true;
#endif
// Optional OpenGL 3.3 extensions
RLGL.ExtSupported.texCompASTC = GLAD_GL_KHR_texture_compression_astc_hdr && GLAD_GL_KHR_texture_compression_astc_ldr;
RLGL.ExtSupported.texCompDXT = GLAD_GL_EXT_texture_compression_s3tc; // Texture compression: DXT
RLGL.ExtSupported.texCompETC2 = GLAD_GL_ARB_ES3_compatibility; // Texture compression: ETC2/EAC
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
if (GLAD_GL_ARB_compute_shader) RLGL.ExtSupported.computeShader = true; RLGL.ExtSupported.computeShader = GLAD_GL_ARB_compute_shader;
if (GLAD_GL_ARB_shader_storage_buffer_object) RLGL.ExtSupported.ssbo = true; RLGL.ExtSupported.ssbo = GLAD_GL_ARB_shader_storage_buffer_object;
#endif
#if !defined(__APPLE__)
// NOTE: With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
if (GLAD_GL_EXT_texture_compression_s3tc) RLGL.ExtSupported.texCompDXT = true; // Texture compression: DXT
if (GLAD_GL_ARB_ES3_compatibility) RLGL.ExtSupported.texCompETC2 = true; // Texture compression: ETC2/EAC
#endif #endif
#endif // GRAPHICS_API_OPENGL_33 #endif // GRAPHICS_API_OPENGL_33
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
@ -2184,12 +2256,10 @@ void rlLoadExtensions(void *loader)
#else // RLGL_SHOW_GL_DETAILS_INFO #else // RLGL_SHOW_GL_DETAILS_INFO
// Show some basic info about GL supported features // Show some basic info about GL supported features
#if defined(GRAPHICS_API_OPENGL_ES2)
if (RLGL.ExtSupported.vao) TRACELOG(RL_LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully"); if (RLGL.ExtSupported.vao) TRACELOG(RL_LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully");
else TRACELOG(RL_LOG_WARNING, "GL: VAO extension not found, VAO not supported"); else TRACELOG(RL_LOG_WARNING, "GL: VAO extension not found, VAO not supported");
if (RLGL.ExtSupported.texNPOT) TRACELOG(RL_LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported"); if (RLGL.ExtSupported.texNPOT) TRACELOG(RL_LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported");
else TRACELOG(RL_LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)"); else TRACELOG(RL_LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)");
#endif
if (RLGL.ExtSupported.texCompDXT) TRACELOG(RL_LOG_INFO, "GL: DXT compressed textures supported"); if (RLGL.ExtSupported.texCompDXT) TRACELOG(RL_LOG_INFO, "GL: DXT compressed textures supported");
if (RLGL.ExtSupported.texCompETC1) TRACELOG(RL_LOG_INFO, "GL: ETC1 compressed textures supported"); if (RLGL.ExtSupported.texCompETC1) TRACELOG(RL_LOG_INFO, "GL: ETC1 compressed textures supported");
if (RLGL.ExtSupported.texCompETC2) TRACELOG(RL_LOG_INFO, "GL: ETC2/EAC compressed textures supported"); if (RLGL.ExtSupported.texCompETC2) TRACELOG(RL_LOG_INFO, "GL: ETC2/EAC compressed textures supported");
@ -2207,22 +2277,18 @@ int rlGetVersion(void)
{ {
int glVersion = 0; int glVersion = 0;
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
glVersion = OPENGL_11; glVersion = RL_OPENGL_11;
#endif #endif
#if defined(GRAPHICS_API_OPENGL_21) #if defined(GRAPHICS_API_OPENGL_21)
#if defined(__APPLE__) glVersion = RL_OPENGL_21;
glVersion = OPENGL_33; // NOTE: Force OpenGL 3.3 on OSX
#else
glVersion = OPENGL_21;
#endif
#elif defined(GRAPHICS_API_OPENGL_33) #elif defined(GRAPHICS_API_OPENGL_33)
glVersion = OPENGL_33; glVersion = RL_OPENGL_33;
#endif #endif
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
glVersion = OPENGL_43; glVersion = RL_OPENGL_43;
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
glVersion = OPENGL_ES_20; glVersion = RL_OPENGL_ES_20;
#endif #endif
return glVersion; return glVersion;
} }
@ -2692,10 +2758,12 @@ bool rlCheckRenderBatchLimit(int vCount)
if ((RLGL.State.vertexCounter + vCount) >= if ((RLGL.State.vertexCounter + vCount) >=
(RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4)) (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4))
{ {
overflow = true;
// Store current primitive drawing mode and texture id
int currentMode = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode; int currentMode = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode;
int currentTexture = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId; int currentTexture = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId;
overflow = true;
rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside
// Restore state of last batch so we can continue adding vertices // Restore state of last batch so we can continue adding vertices
@ -3063,6 +3131,7 @@ void rlUnloadTexture(unsigned int id)
} }
// Generate mipmap data for selected texture // Generate mipmap data for selected texture
// NOTE: Only supports GPU mipmap generation
void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps) void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps)
{ {
glBindTexture(GL_TEXTURE_2D, id); glBindTexture(GL_TEXTURE_2D, id);
@ -3073,45 +3142,6 @@ void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int
if (((width > 0) && ((width & (width - 1)) == 0)) && if (((width > 0) && ((width & (width - 1)) == 0)) &&
((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true; ((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true;
#if defined(GRAPHICS_API_OPENGL_11)
if (texIsPOT)
{
// WARNING: Manual mipmap generation only works for RGBA 32bit textures!
if (format == RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
{
// Retrieve texture data from VRAM
void *texData = rlReadTexturePixels(id, width, height, format);
// NOTE: Texture data size is reallocated to fit mipmaps data
// NOTE: CPU mipmap generation only supports RGBA 32bit data
int mipmapCount = rlGenTextureMipmapsData(texData, width, height);
int size = width*height*4;
int offset = size;
int mipWidth = width/2;
int mipHeight = height/2;
// Load the mipmaps
for (int level = 1; level < mipmapCount; level++)
{
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, mipWidth, mipHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)texData + offset);
size = mipWidth*mipHeight*4;
offset += size;
mipWidth /= 2;
mipHeight /= 2;
}
*mipmaps = mipmapCount + 1;
RL_FREE(texData); // Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data
TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Mipmaps generated manually on CPU side, total: %i", id, *mipmaps);
}
else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps for provided texture format", id);
}
#endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if ((texIsPOT) || (RLGL.ExtSupported.texNPOT)) if ((texIsPOT) || (RLGL.ExtSupported.texNPOT))
{ {
@ -3934,7 +3964,7 @@ void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned
} }
// Load shader storage buffer object (SSBO) // Load shader storage buffer object (SSBO)
unsigned int rlLoadShaderBuffer(unsigned long long size, const void *data, int usageHint) unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHint)
{ {
unsigned int ssbo = 0; unsigned int ssbo = 0;
@ -3958,7 +3988,7 @@ void rlUnloadShaderBuffer(unsigned int ssboId)
} }
// Update SSBO buffer data // Update SSBO buffer data
void rlUpdateShaderBufferElements(unsigned int id, const void *data, unsigned long long dataSize, unsigned long long offset) void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSize, unsigned int offset)
{ {
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); glBindBuffer(GL_SHADER_STORAGE_BUFFER, id);
@ -3967,7 +3997,7 @@ void rlUpdateShaderBufferElements(unsigned int id, const void *data, unsigned lo
} }
// Get SSBO buffer size // Get SSBO buffer size
unsigned long long rlGetShaderBufferSize(unsigned int id) unsigned int rlGetShaderBufferSize(unsigned int id)
{ {
long long size = 0; long long size = 0;
@ -3976,11 +4006,11 @@ unsigned long long rlGetShaderBufferSize(unsigned int id)
glGetInteger64v(GL_SHADER_STORAGE_BUFFER_SIZE, &size); glGetInteger64v(GL_SHADER_STORAGE_BUFFER_SIZE, &size);
#endif #endif
return (size > 0)? size : 0; return (size > 0)? (unsigned int)size : 0;
} }
// Read SSBO buffer data // Read SSBO buffer data (GPU->CPU)
void rlReadShaderBufferElements(unsigned int id, void *dest, unsigned long long count, unsigned long long offset) void rlReadShaderBuffer(unsigned int id, void *dest, unsigned int count, unsigned int offset)
{ {
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); glBindBuffer(GL_SHADER_STORAGE_BUFFER, id);
@ -3997,7 +4027,7 @@ void rlBindShaderBuffer(unsigned int id, unsigned int index)
} }
// Copy SSBO buffer data // Copy SSBO buffer data
void rlCopyBuffersElements(unsigned int destId, unsigned int srcId, unsigned long long destOffset, unsigned long long srcOffset, unsigned long long count) void rlCopyShaderBuffer(unsigned int destId, unsigned int srcId, unsigned int destOffset, unsigned int srcOffset, unsigned int count)
{ {
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
glBindBuffer(GL_COPY_READ_BUFFER, srcId); glBindBuffer(GL_COPY_READ_BUFFER, srcId);
@ -4501,132 +4531,6 @@ static char *rlGetCompressedFormatName(int format)
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
#if defined(GRAPHICS_API_OPENGL_11)
// Mipmaps data is generated after image data
// NOTE: Only works with RGBA (4 bytes) data!
static int rlGenTextureMipmapsData(unsigned char *data, int baseWidth, int baseHeight)
{
int mipmapCount = 1; // Required mipmap levels count (including base level)
int width = baseWidth;
int height = baseHeight;
int size = baseWidth*baseHeight*4; // Size in bytes (will include mipmaps...), RGBA only
// Count mipmap levels required
while ((width != 1) && (height != 1))
{
width /= 2;
height /= 2;
TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height);
mipmapCount++;
size += (width*height*4); // Add mipmap size (in bytes)
}
TRACELOGD("TEXTURE: Total mipmaps required: %i", mipmapCount);
TRACELOGD("TEXTURE: Total size of data required: %i", size);
unsigned char *temp = RL_REALLOC(data, size);
if (temp != NULL) data = temp;
else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to re-allocate required mipmaps memory");
width = baseWidth;
height = baseHeight;
size = (width*height*4); // RGBA: 4 bytes
// Generate mipmaps
// NOTE: Every mipmap data is stored after data (RGBA - 4 bytes)
unsigned char *image = (unsigned char *)RL_MALLOC(width*height*4);
unsigned char *mipmap = NULL;
int offset = 0;
for (int i = 0; i < size; i += 4)
{
image[i] = data[i];
image[i + 1] = data[i + 1];
image[i + 2] = data[i + 2];
image[i + 3] = data[i + 3];
}
TRACELOGD("TEXTURE: Mipmap base size (%ix%i)", width, height);
for (int mip = 1; mip < mipmapCount; mip++)
{
mipmap = rlGenNextMipmapData(image, width, height);
offset += (width*height*4); // Size of last mipmap
width /= 2;
height /= 2;
size = (width*height*4); // Mipmap size to store after offset
// Add mipmap to data
for (int i = 0; i < size; i += 4)
{
data[offset + i] = mipmap[i];
data[offset + i + 1] = mipmap[i + 1];
data[offset + i + 2] = mipmap[i + 2];
data[offset + i + 3] = mipmap[i + 3];
}
RL_FREE(image);
image = mipmap;
mipmap = NULL;
}
RL_FREE(mipmap); // free mipmap data
return mipmapCount;
}
// Manual mipmap generation (basic scaling algorithm)
static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight)
{
int x2 = 0;
int y2 = 0;
unsigned char prow[4] = { 0 };
unsigned char pcol[4] = { 0 };
int width = srcWidth/2;
int height = srcHeight/2;
unsigned char *mipmap = (unsigned char *)RL_MALLOC(width*height*4);
// Scaling algorithm works perfectly (box-filter)
for (int y = 0; y < height; y++)
{
y2 = 2*y;
for (int x = 0; x < width; x++)
{
x2 = 2*x;
prow[0] = (srcData[(y2*srcWidth + x2)*4 + 0] + srcData[(y2*srcWidth + x2 + 1)*4 + 0])/2;
prow[1] = (srcData[(y2*srcWidth + x2)*4 + 1] + srcData[(y2*srcWidth + x2 + 1)*4 + 1])/2;
prow[2] = (srcData[(y2*srcWidth + x2)*4 + 2] + srcData[(y2*srcWidth + x2 + 1)*4 + 2])/2;
prow[3] = (srcData[(y2*srcWidth + x2)*4 + 3] + srcData[(y2*srcWidth + x2 + 1)*4 + 3])/2;
pcol[0] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 0] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 0])/2;
pcol[1] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 1] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 1])/2;
pcol[2] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 2] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 2])/2;
pcol[3] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 3] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 3])/2;
mipmap[(y*width + x)*4 + 0] = (prow[0] + pcol[0])/2;
mipmap[(y*width + x)*4 + 1] = (prow[1] + pcol[1])/2;
mipmap[(y*width + x)*4 + 2] = (prow[2] + pcol[2])/2;
mipmap[(y*width + x)*4 + 3] = (prow[3] + pcol[3])/2;
}
}
TRACELOGD("TEXTURE: Mipmap generated successfully (%ix%i)", width, height);
return mipmap;
}
#endif // GRAPHICS_API_OPENGL_11
// Get pixel data size in bytes (image or texture) // Get pixel data size in bytes (image or texture)
// NOTE: Size depends on pixel format // NOTE: Size depends on pixel format
static int rlGetPixelDataSize(int width, int height, int format) static int rlGetPixelDataSize(int width, int height, int format)

View file

@ -163,11 +163,6 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, unsigned int
// Draw a line in 3D world space // Draw a line in 3D world space
void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color) void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color)
{ {
// WARNING: Be careful with internal buffer vertex alignment
// when using RL_LINES or RL_TRIANGLES, data is aligned to fit
// lines-triangles-quads in the same indexed buffers!!!
rlCheckRenderBatchLimit(8);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex3f(startPos.x, startPos.y, startPos.z); rlVertex3f(startPos.x, startPos.y, startPos.z);
@ -178,8 +173,6 @@ void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color)
// Draw a point in 3D space, actually a small line // Draw a point in 3D space, actually a small line
void DrawPoint3D(Vector3 position, Color color) void DrawPoint3D(Vector3 position, Color color)
{ {
rlCheckRenderBatchLimit(8);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
rlBegin(RL_LINES); rlBegin(RL_LINES);
@ -193,8 +186,6 @@ void DrawPoint3D(Vector3 position, Color color)
// Draw a circle in 3D world space // Draw a circle in 3D world space
void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color) void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color)
{ {
rlCheckRenderBatchLimit(2*36);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(center.x, center.y, center.z); rlTranslatef(center.x, center.y, center.z);
rlRotatef(rotationAngle, rotationAxis.x, rotationAxis.y, rotationAxis.z); rlRotatef(rotationAngle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
@ -214,8 +205,6 @@ void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rota
// Draw a color-filled triangle (vertex in counter-clockwise order!) // Draw a color-filled triangle (vertex in counter-clockwise order!)
void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color) void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color)
{ {
rlCheckRenderBatchLimit(8);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex3f(v1.x, v1.y, v1.z); rlVertex3f(v1.x, v1.y, v1.z);
@ -227,30 +216,27 @@ void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color)
// Draw a triangle strip defined by points // Draw a triangle strip defined by points
void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color) void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color)
{ {
if (pointCount >= 3) if (pointCount < 3) return;
{
rlCheckRenderBatchLimit(3*(pointCount - 2));
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
for (int i = 2; i < pointCount; i++) for (int i = 2; i < pointCount; i++)
{
if ((i%2) == 0)
{ {
if ((i%2) == 0) rlVertex3f(points[i].x, points[i].y, points[i].z);
{ rlVertex3f(points[i - 2].x, points[i - 2].y, points[i - 2].z);
rlVertex3f(points[i].x, points[i].y, points[i].z); rlVertex3f(points[i - 1].x, points[i - 1].y, points[i - 1].z);
rlVertex3f(points[i - 2].x, points[i - 2].y, points[i - 2].z);
rlVertex3f(points[i - 1].x, points[i - 1].y, points[i - 1].z);
}
else
{
rlVertex3f(points[i].x, points[i].y, points[i].z);
rlVertex3f(points[i - 1].x, points[i - 1].y, points[i - 1].z);
rlVertex3f(points[i - 2].x, points[i - 2].y, points[i - 2].z);
}
} }
rlEnd(); else
} {
rlVertex3f(points[i].x, points[i].y, points[i].z);
rlVertex3f(points[i - 1].x, points[i - 1].y, points[i - 1].z);
rlVertex3f(points[i - 2].x, points[i - 2].y, points[i - 2].z);
}
}
rlEnd();
} }
// Draw cube // Draw cube
@ -261,8 +247,6 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c
float y = 0.0f; float y = 0.0f;
float z = 0.0f; float z = 0.0f;
rlCheckRenderBatchLimit(36);
rlPushMatrix(); rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> rotate -> translate) // NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
@ -342,65 +326,67 @@ void DrawCubeWires(Vector3 position, float width, float height, float length, Co
float y = 0.0f; float y = 0.0f;
float z = 0.0f; float z = 0.0f;
rlCheckRenderBatchLimit(36);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
// Front face ----------------------------------------------------- // Front face
//------------------------------------------------------------------
// Bottom line // Bottom line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom left rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom left
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom right rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom right
// Left line // Left line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom right rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom right
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top right rlVertex3f(x + width/2, y + height/2, z + length/2); // Top right
// Top line // Top line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top right rlVertex3f(x + width/2, y + height/2, z + length/2); // Top right
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top left rlVertex3f(x - width/2, y + height/2, z + length/2); // Top left
// Right line // Right line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top left rlVertex3f(x - width/2, y + height/2, z + length/2); // Top left
rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom left rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom left
// Back face ------------------------------------------------------ // Back face
//------------------------------------------------------------------
// Bottom line // Bottom line
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom left rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom left
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom right rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom right
// Left line // Left line
rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom right rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom right
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top right rlVertex3f(x + width/2, y + height/2, z - length/2); // Top right
// Top line // Top line
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top right rlVertex3f(x + width/2, y + height/2, z - length/2); // Top right
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top left rlVertex3f(x - width/2, y + height/2, z - length/2); // Top left
// Right line // Right line
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top left rlVertex3f(x - width/2, y + height/2, z - length/2); // Top left
rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom left rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom left
// Top face ------------------------------------------------------- // Top face
//------------------------------------------------------------------
// Left line // Left line
rlVertex3f(x-width/2, y+height/2, z+length/2); // Top left front rlVertex3f(x - width/2, y + height/2, z + length/2); // Top left front
rlVertex3f(x-width/2, y+height/2, z-length/2); // Top left back rlVertex3f(x - width/2, y + height/2, z - length/2); // Top left back
// Right line // Right line
rlVertex3f(x+width/2, y+height/2, z+length/2); // Top right front rlVertex3f(x + width/2, y + height/2, z + length/2); // Top right front
rlVertex3f(x+width/2, y+height/2, z-length/2); // Top right back rlVertex3f(x + width/2, y + height/2, z - length/2); // Top right back
// Bottom face --------------------------------------------------- // Bottom face
//------------------------------------------------------------------
// Left line // Left line
rlVertex3f(x-width/2, y-height/2, z+length/2); // Top left front rlVertex3f(x - width/2, y - height/2, z + length/2); // Top left front
rlVertex3f(x-width/2, y-height/2, z-length/2); // Top left back rlVertex3f(x - width/2, y - height/2, z - length/2); // Top left back
// Right line // Right line
rlVertex3f(x+width/2, y-height/2, z+length/2); // Top right front rlVertex3f(x + width/2, y - height/2, z + length/2); // Top right front
rlVertex3f(x+width/2, y-height/2, z-length/2); // Top right back rlVertex3f(x + width/2, y - height/2, z - length/2); // Top right back
rlEnd(); rlEnd();
rlPopMatrix(); rlPopMatrix();
} }
@ -419,8 +405,6 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei
float y = position.y; float y = position.y;
float z = position.z; float z = position.z;
rlCheckRenderBatchLimit(36);
rlSetTexture(texture.id); rlSetTexture(texture.id);
//rlPushMatrix(); //rlPushMatrix();
@ -432,37 +416,37 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face // Front Face
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad
// Back Face // Back Face
rlNormal3f(0.0f, 0.0f, - 1.0f); // Normal Pointing Away From Viewer rlNormal3f(0.0f, 0.0f, - 1.0f); // Normal Pointing Away From Viewer
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad
// Top Face // Top Face
rlNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up rlNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Bottom Left Of The Texture and Quad rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Bottom Right Of The Texture and Quad rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
// Bottom Face // Bottom Face
rlNormal3f(0.0f, - 1.0f, 0.0f); // Normal Pointing Down rlNormal3f(0.0f, - 1.0f, 0.0f); // Normal Pointing Down
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Top Right Of The Texture and Quad rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Top Left Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
// Right face // Right face
rlNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right rlNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
// Left Face // Left Face
rlNormal3f( - 1.0f, 0.0f, 0.0f); // Normal Pointing Left rlNormal3f( - 1.0f, 0.0f, 0.0f); // Normal Pointing Left
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad
@ -482,8 +466,6 @@ void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, f
float texWidth = (float)texture.width; float texWidth = (float)texture.width;
float texHeight = (float)texture.height; float texHeight = (float)texture.height;
rlCheckRenderBatchLimit(36);
rlSetTexture(texture.id); rlSetTexture(texture.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -569,9 +551,6 @@ void DrawSphere(Vector3 centerPos, float radius, Color color)
// Draw sphere with extended parameters // Draw sphere with extended parameters
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color) void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color)
{ {
int numVertex = (rings + 2)*slices*6;
rlCheckRenderBatchLimit(numVertex);
rlPushMatrix(); rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> translate) // NOTE: Transformation is applied in inverse order (scale -> translate)
rlTranslatef(centerPos.x, centerPos.y, centerPos.z); rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
@ -612,9 +591,6 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
// Draw sphere wires // Draw sphere wires
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color) void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color)
{ {
int numVertex = (rings + 2)*slices*6;
rlCheckRenderBatchLimit(numVertex);
rlPushMatrix(); rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> translate) // NOTE: Transformation is applied in inverse order (scale -> translate)
rlTranslatef(centerPos.x, centerPos.y, centerPos.z); rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
@ -659,9 +635,6 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
{ {
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
int numVertex = sides*6;
rlCheckRenderBatchLimit(numVertex);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
@ -718,9 +691,6 @@ void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float e
{ {
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
int numVertex = sides*6;
rlCheckRenderBatchLimit(numVertex);
Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z }; Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z };
if ((direction.x == 0) && (direction.y == 0) && (direction.z == 0)) return; if ((direction.x == 0) && (direction.y == 0) && (direction.z == 0)) return;
@ -777,9 +747,6 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
{ {
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
int numVertex = sides*8;
rlCheckRenderBatchLimit(numVertex);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
@ -811,9 +778,6 @@ void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, fl
{ {
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
int numVertex = sides*6;
rlCheckRenderBatchLimit(numVertex);
Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z }; Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z };
if ((direction.x == 0) && (direction.y == 0) && (direction.z == 0))return; if ((direction.x == 0) && (direction.y == 0) && (direction.z == 0))return;
@ -853,12 +817,287 @@ void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, fl
rlEnd(); rlEnd();
} }
// Draw a capsule with the center of its sphere caps at startPos and endPos
void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color)
{
if (slices < 3) slices = 3;
Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z };
// draw a sphere if start and end points are the same
bool sphereCase = (direction.x == 0) && (direction.y == 0) && (direction.z == 0);
if (sphereCase) direction = (Vector3){0.0f, 1.0f, 0.0f};
// Construct a basis of the base and the caps:
Vector3 b0 = Vector3Normalize(direction);
Vector3 b1 = Vector3Normalize(Vector3Perpendicular(direction));
Vector3 b2 = Vector3Normalize(Vector3CrossProduct(b1, direction));
Vector3 capCenter = endPos;
float baseSliceAngle = (2.0f*PI)/slices;
float baseRingAngle = PI * 0.5 / rings;
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
// render both caps
for (int c = 0; c < 2; c++)
{
for (int i = 0; i < rings; i++)
{
for (int j = 0; j < slices; j++)
{
// we build up the rings from capCenter in the direction of the 'direction' vector we computed earlier
// as we iterate through the rings they must be placed higher above the center, the height we need is sin(angle(i))
// as we iterate through the rings they must get smaller by the cos(angle(i))
// compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 ));
float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 ));
Vector3 w1 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin1*b1.x + ringCos1*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin1*b1.y + ringCos1*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin1*b1.z + ringCos1*b2.z) * radius
};
float ringSin2 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 ));
float ringCos2 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 ));
Vector3 w2 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin2*b1.x + ringCos2*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin2*b1.y + ringCos2*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin2*b1.z + ringCos2*b2.z) * radius
};
float ringSin3 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 ));
float ringCos3 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 ));
Vector3 w3 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin3*b1.x + ringCos3*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin3*b1.y + ringCos3*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin3*b1.z + ringCos3*b2.z) * radius
};
float ringSin4 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 ));
float ringCos4 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 ));
Vector3 w4 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin4*b1.x + ringCos4*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin4*b1.y + ringCos4*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin4*b1.z + ringCos4*b2.z) * radius
};
// make sure cap triangle normals are facing outwards
if(c == 0)
{
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w4.x, w4.y, w4.z);
rlVertex3f(w3.x, w3.y, w3.z);
}
else
{
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w4.x, w4.y, w4.z);
}
}
}
capCenter = startPos;
b0 = Vector3Scale(b0, -1.0f);
}
// render middle
if (!sphereCase)
{
for (int j = 0; j < slices; j++)
{
// compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*radius;
float ringCos1 = cosf(baseSliceAngle*(j + 0))*radius;
Vector3 w1 = {
startPos.x + ringSin1*b1.x + ringCos1*b2.x,
startPos.y + ringSin1*b1.y + ringCos1*b2.y,
startPos.z + ringSin1*b1.z + ringCos1*b2.z
};
float ringSin2 = sinf(baseSliceAngle*(j + 1))*radius;
float ringCos2 = cosf(baseSliceAngle*(j + 1))*radius;
Vector3 w2 = {
startPos.x + ringSin2*b1.x + ringCos2*b2.x,
startPos.y + ringSin2*b1.y + ringCos2*b2.y,
startPos.z + ringSin2*b1.z + ringCos2*b2.z
};
float ringSin3 = sinf(baseSliceAngle*(j + 0))*radius;
float ringCos3 = cosf(baseSliceAngle*(j + 0))*radius;
Vector3 w3 = {
endPos.x + ringSin3*b1.x + ringCos3*b2.x,
endPos.y + ringSin3*b1.y + ringCos3*b2.y,
endPos.z + ringSin3*b1.z + ringCos3*b2.z
};
float ringSin4 = sinf(baseSliceAngle*(j + 1))*radius;
float ringCos4 = cosf(baseSliceAngle*(j + 1))*radius;
Vector3 w4 = {
endPos.x + ringSin4*b1.x + ringCos4*b2.x,
endPos.y + ringSin4*b1.y + ringCos4*b2.y,
endPos.z + ringSin4*b1.z + ringCos4*b2.z
};
// w2 x.-----------x startPos
rlVertex3f(w1.x, w1.y, w1.z); // | |\'. T0 /
rlVertex3f(w2.x, w2.y, w2.z); // T1 | \ '. /
rlVertex3f(w3.x, w3.y, w3.z); // | |T \ '. /
// | 2 \ T 'x w1
rlVertex3f(w2.x, w2.y, w2.z); // | w4 x.---\-1-|---x endPos
rlVertex3f(w4.x, w4.y, w4.z); // T2 '. \ |T3/
rlVertex3f(w3.x, w3.y, w3.z); // | '. \ | /
// '.\|/
// 'x w3
}
}
rlEnd();
}
// Draw capsule wires with the center of its sphere caps at startPos and endPos
void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color)
{
if (slices < 3) slices = 3;
Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z };
// draw a sphere if start and end points are the same
bool sphereCase = (direction.x == 0) && (direction.y == 0) && (direction.z == 0);
if (sphereCase) direction = (Vector3){0.0f, 1.0f, 0.0f};
// Construct a basis of the base and the caps:
Vector3 b0 = Vector3Normalize(direction);
Vector3 b1 = Vector3Normalize(Vector3Perpendicular(direction));
Vector3 b2 = Vector3Normalize(Vector3CrossProduct(b1, direction));
Vector3 capCenter = endPos;
float baseSliceAngle = (2.0f*PI)/slices;
float baseRingAngle = PI * 0.5 / rings;
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
// render both caps
for (int c = 0; c < 2; c++)
{
for (int i = 0; i < rings; i++)
{
for (int j = 0; j < slices; j++)
{
// we build up the rings from capCenter in the direction of the 'direction' vector we computed earlier
// as we iterate through the rings they must be placed higher above the center, the height we need is sin(angle(i))
// as we iterate through the rings they must get smaller by the cos(angle(i))
// compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 ));
float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 ));
Vector3 w1 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin1*b1.x + ringCos1*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin1*b1.y + ringCos1*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin1*b1.z + ringCos1*b2.z) * radius
};
float ringSin2 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 ));
float ringCos2 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 ));
Vector3 w2 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin2*b1.x + ringCos2*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin2*b1.y + ringCos2*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin2*b1.z + ringCos2*b2.z) * radius
};
float ringSin3 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 ));
float ringCos3 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 ));
Vector3 w3 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin3*b1.x + ringCos3*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin3*b1.y + ringCos3*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin3*b1.z + ringCos3*b2.z) * radius
};
float ringSin4 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 ));
float ringCos4 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 ));
Vector3 w4 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin4*b1.x + ringCos4*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin4*b1.y + ringCos4*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin4*b1.z + ringCos4*b2.z) * radius
};
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w4.x, w4.y, w4.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w4.x, w4.y, w4.z);
}
}
capCenter = startPos;
b0 = Vector3Scale(b0, -1.0f);
}
// render middle
if (!sphereCase)
{
for (int j = 0; j < slices; j++)
{
// compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*radius;
float ringCos1 = cosf(baseSliceAngle*(j + 0))*radius;
Vector3 w1 = {
startPos.x + ringSin1*b1.x + ringCos1*b2.x,
startPos.y + ringSin1*b1.y + ringCos1*b2.y,
startPos.z + ringSin1*b1.z + ringCos1*b2.z
};
float ringSin2 = sinf(baseSliceAngle*(j + 1))*radius;
float ringCos2 = cosf(baseSliceAngle*(j + 1))*radius;
Vector3 w2 = {
startPos.x + ringSin2*b1.x + ringCos2*b2.x,
startPos.y + ringSin2*b1.y + ringCos2*b2.y,
startPos.z + ringSin2*b1.z + ringCos2*b2.z
};
float ringSin3 = sinf(baseSliceAngle*(j + 0))*radius;
float ringCos3 = cosf(baseSliceAngle*(j + 0))*radius;
Vector3 w3 = {
endPos.x + ringSin3*b1.x + ringCos3*b2.x,
endPos.y + ringSin3*b1.y + ringCos3*b2.y,
endPos.z + ringSin3*b1.z + ringCos3*b2.z
};
float ringSin4 = sinf(baseSliceAngle*(j + 1))*radius;
float ringCos4 = cosf(baseSliceAngle*(j + 1))*radius;
Vector3 w4 = {
endPos.x + ringSin4*b1.x + ringCos4*b2.x,
endPos.y + ringSin4*b1.y + ringCos4*b2.y,
endPos.z + ringSin4*b1.z + ringCos4*b2.z
};
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w4.x, w4.y, w4.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w3.x, w3.y, w3.z);
}
}
rlEnd();
}
// Draw a plane // Draw a plane
void DrawPlane(Vector3 centerPos, Vector2 size, Color color) void DrawPlane(Vector3 centerPos, Vector2 size, Color color)
{ {
rlCheckRenderBatchLimit(4);
// NOTE: Plane is always created on XZ ground // NOTE: Plane is always created on XZ ground
rlPushMatrix(); rlPushMatrix();
rlTranslatef(centerPos.x, centerPos.y, centerPos.z); rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
@ -895,8 +1134,6 @@ void DrawGrid(int slices, float spacing)
{ {
int halfSlices = slices/2; int halfSlices = slices/2;
rlCheckRenderBatchLimit((slices + 2)*4);
rlBegin(RL_LINES); rlBegin(RL_LINES);
for (int i = -halfSlices; i <= halfSlices; i++) for (int i = -halfSlices; i <= halfSlices; i++)
{ {
@ -2671,7 +2908,7 @@ Mesh GenMeshKnot(float radius, float size, int radSeg, int sides)
// NOTE: Vertex data is uploaded to GPU // NOTE: Vertex data is uploaded to GPU
Mesh GenMeshHeightmap(Image heightmap, Vector3 size) Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
{ {
#define GRAY_VALUE(c) ((c.r+c.g+c.b)/3.0f) #define GRAY_VALUE(c) ((float)(c.r + c.g + c.b)/3.0f)
Mesh mesh = { 0 }; Mesh mesh = { 0 };
@ -2681,7 +2918,7 @@ Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
Color *pixels = LoadImageColors(heightmap); Color *pixels = LoadImageColors(heightmap);
// NOTE: One vertex per pixel // NOTE: One vertex per pixel
mesh.triangleCount = (mapX-1)*(mapZ-1)*2; // One quad every four pixels mesh.triangleCount = (mapX - 1)*(mapZ - 1)*2; // One quad every four pixels
mesh.vertexCount = mesh.triangleCount*3; mesh.vertexCount = mesh.triangleCount*3;
@ -2694,7 +2931,7 @@ Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
int tcCounter = 0; // Used to count texcoords float by float int tcCounter = 0; // Used to count texcoords float by float
int nCounter = 0; // Used to count normals float by float int nCounter = 0; // Used to count normals float by float
Vector3 scaleFactor = { size.x/mapX, size.y/255.0f, size.z/mapZ }; Vector3 scaleFactor = { size.x/(mapX - 1), size.y/255.0f, size.z/(mapZ - 1) };
Vector3 vA = { 0 }; Vector3 vA = { 0 };
Vector3 vB = { 0 }; Vector3 vB = { 0 };
@ -2721,7 +2958,7 @@ Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
mesh.vertices[vCounter + 7] = GRAY_VALUE(pixels[(x + 1) + z*mapX])*scaleFactor.y; mesh.vertices[vCounter + 7] = GRAY_VALUE(pixels[(x + 1) + z*mapX])*scaleFactor.y;
mesh.vertices[vCounter + 8] = (float)z*scaleFactor.z; mesh.vertices[vCounter + 8] = (float)z*scaleFactor.z;
// another triangle - 3 vertex // Another triangle - 3 vertex
mesh.vertices[vCounter + 9] = mesh.vertices[vCounter + 6]; mesh.vertices[vCounter + 9] = mesh.vertices[vCounter + 6];
mesh.vertices[vCounter + 10] = mesh.vertices[vCounter + 7]; mesh.vertices[vCounter + 10] = mesh.vertices[vCounter + 7];
mesh.vertices[vCounter + 11] = mesh.vertices[vCounter + 8]; mesh.vertices[vCounter + 11] = mesh.vertices[vCounter + 8];
@ -3421,8 +3658,6 @@ void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector
bottomRight = Vector3Add(bottomRight, position); bottomRight = Vector3Add(bottomRight, position);
bottomLeft = Vector3Add(bottomLeft, position); bottomLeft = Vector3Add(bottomLeft, position);
rlCheckRenderBatchLimit(8);
rlSetTexture(texture.id); rlSetTexture(texture.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -4302,6 +4537,7 @@ static Model LoadIQM(const char *fileName)
RL_FREE(blendi); RL_FREE(blendi);
RL_FREE(blendw); RL_FREE(blendw);
RL_FREE(ijoint); RL_FREE(ijoint);
RL_FREE(color);
return model; return model;
} }
@ -5263,18 +5499,28 @@ static Model LoadM3D(const char *fileName)
} }
// Add skin (vertex / bone weight pairs) // Add skin (vertex / bone weight pairs)
if (m3d->numbone && m3d->numskin) { if (m3d->numbone && m3d->numskin)
for (n = 0; n < 3; n++) { {
for (n = 0; n < 3; n++)
{
int skinid = m3d->vertex[m3d->face[i].vertex[n]].skinid; int skinid = m3d->vertex[m3d->face[i].vertex[n]].skinid;
// check if there's a skin for this mesh, should be, just failsafe
// Check if there is a skin for this mesh, should be, just failsafe
if (skinid != M3D_UNDEF && skinid < m3d->numskin) if (skinid != M3D_UNDEF && skinid < m3d->numskin)
{ {
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
{ {
model.meshes[k].boneIds[l * 12 + n * 4 + j] = m3d->skin[skinid].boneid[j]; model.meshes[k].boneIds[l*12 + n*4 + j] = m3d->skin[skinid].boneid[j];
model.meshes[k].boneWeights[l * 12 + n * 4 + j] = m3d->skin[skinid].weight[j]; model.meshes[k].boneWeights[l*12 + n*4 + j] = m3d->skin[skinid].weight[j];
} }
} }
else
{
// raylib does not handle boneless meshes with skeletal animations, so
// we put all vertices without a bone into a special "no bone" bone
model.meshes[k].boneIds[l * 12 + n * 4] = m3d->numbone;
model.meshes[k].boneWeights[l * 12 + n * 4] = 1.0f;
}
} }
} }
} }
@ -5351,18 +5597,19 @@ static Model LoadM3D(const char *fileName)
} }
// Load bones // Load bones
if(m3d->numbone) if (m3d->numbone)
{ {
model.boneCount = m3d->numbone; model.boneCount = m3d->numbone + 1;
model.bones = RL_MALLOC(m3d->numbone*sizeof(BoneInfo)); model.bones = RL_CALLOC(model.boneCount, sizeof(BoneInfo));
model.bindPose = RL_MALLOC(m3d->numbone*sizeof(Transform)); model.bindPose = RL_CALLOC(model.boneCount, sizeof(Transform));
for (i = 0; i < m3d->numbone; i++) for (i = 0; i < m3d->numbone; i++)
{ {
model.bones[i].parent = m3d->bone[i].parent; model.bones[i].parent = m3d->bone[i].parent;
strncpy(model.bones[i].name, m3d->bone[i].name, sizeof(model.bones[i].name)); strncpy(model.bones[i].name, m3d->bone[i].name, sizeof(model.bones[i].name));
model.bindPose[i].translation.x = m3d->vertex[m3d->bone[i].pos].x; model.bindPose[i].translation.x = m3d->vertex[m3d->bone[i].pos].x*m3d->scale;
model.bindPose[i].translation.y = m3d->vertex[m3d->bone[i].pos].y; model.bindPose[i].translation.y = m3d->vertex[m3d->bone[i].pos].y*m3d->scale;
model.bindPose[i].translation.z = m3d->vertex[m3d->bone[i].pos].z; model.bindPose[i].translation.z = m3d->vertex[m3d->bone[i].pos].z*m3d->scale;
model.bindPose[i].rotation.x = m3d->vertex[m3d->bone[i].ori].x; model.bindPose[i].rotation.x = m3d->vertex[m3d->bone[i].ori].x;
model.bindPose[i].rotation.y = m3d->vertex[m3d->bone[i].ori].y; model.bindPose[i].rotation.y = m3d->vertex[m3d->bone[i].ori].y;
model.bindPose[i].rotation.z = m3d->vertex[m3d->bone[i].ori].z; model.bindPose[i].rotation.z = m3d->vertex[m3d->bone[i].ori].z;
@ -5370,7 +5617,28 @@ static Model LoadM3D(const char *fileName)
// TODO: if the orientation quaternion not normalized, then that's encoding scaling // TODO: if the orientation quaternion not normalized, then that's encoding scaling
model.bindPose[i].rotation = QuaternionNormalize(model.bindPose[i].rotation); model.bindPose[i].rotation = QuaternionNormalize(model.bindPose[i].rotation);
model.bindPose[i].scale.x = model.bindPose[i].scale.y = model.bindPose[i].scale.z = 1.0f; model.bindPose[i].scale.x = model.bindPose[i].scale.y = model.bindPose[i].scale.z = 1.0f;
// Child bones are stored in parent bone relative space, convert that into model space
if (model.bones[i].parent >= 0)
{
model.bindPose[i].rotation = QuaternionMultiply(model.bindPose[model.bones[i].parent].rotation, model.bindPose[i].rotation);
model.bindPose[i].translation = Vector3RotateByQuaternion(model.bindPose[i].translation, model.bindPose[model.bones[i].parent].rotation);
model.bindPose[i].translation = Vector3Add(model.bindPose[i].translation, model.bindPose[model.bones[i].parent].translation);
model.bindPose[i].scale = Vector3Multiply(model.bindPose[i].scale, model.bindPose[model.bones[i].parent].scale);
}
} }
// Add a special "no bone" bone
model.bones[i].parent = -1;
strcpy(model.bones[i].name, "NO BONE");
model.bindPose[i].translation.x = 0.0f;
model.bindPose[i].translation.y = 0.0f;
model.bindPose[i].translation.z = 0.0f;
model.bindPose[i].rotation.x = 0.0f;
model.bindPose[i].rotation.y = 0.0f;
model.bindPose[i].rotation.z = 0.0f;
model.bindPose[i].rotation.w = 1.0f;
model.bindPose[i].scale.x = model.bindPose[i].scale.y = model.bindPose[i].scale.z = 1.0f;
} }
// Load bone-pose default mesh into animation vertices. These will be updated when UpdateModelAnimation gets // Load bone-pose default mesh into animation vertices. These will be updated when UpdateModelAnimation gets
@ -5430,8 +5698,8 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, unsigned int
for (unsigned int a = 0; a < m3d->numaction; a++) for (unsigned int a = 0; a < m3d->numaction; a++)
{ {
animations[a].frameCount = m3d->action[a].durationmsec / M3D_ANIMDELAY; animations[a].frameCount = m3d->action[a].durationmsec / M3D_ANIMDELAY;
animations[a].boneCount = m3d->numbone; animations[a].boneCount = m3d->numbone + 1;
animations[a].bones = RL_MALLOC(m3d->numbone*sizeof(BoneInfo)); animations[a].bones = RL_MALLOC((m3d->numbone + 1)*sizeof(BoneInfo));
animations[a].framePoses = RL_MALLOC(animations[a].frameCount*sizeof(Transform *)); animations[a].framePoses = RL_MALLOC(animations[a].frameCount*sizeof(Transform *));
// strncpy(animations[a].name, m3d->action[a].name, sizeof(animations[a].name)); // strncpy(animations[a].name, m3d->action[a].name, sizeof(animations[a].name));
TRACELOG(LOG_INFO, "MODEL: [%s] animation #%i: %i msec, %i frames", fileName, a, m3d->action[a].durationmsec, animations[a].frameCount); TRACELOG(LOG_INFO, "MODEL: [%s] animation #%i: %i msec, %i frames", fileName, a, m3d->action[a].durationmsec, animations[a].frameCount);
@ -5442,27 +5710,50 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, unsigned int
strncpy(animations[a].bones[i].name, m3d->bone[i].name, sizeof(animations[a].bones[i].name)); strncpy(animations[a].bones[i].name, m3d->bone[i].name, sizeof(animations[a].bones[i].name));
} }
// A special, never transformed "no bone" bone, used for boneless vertices
animations[a].bones[i].parent = -1;
strcpy(animations[a].bones[i].name, "NO BONE");
// M3D stores frames at arbitrary intervals with sparse skeletons. We need full skeletons at // M3D stores frames at arbitrary intervals with sparse skeletons. We need full skeletons at
// regular intervals, so let the M3D SDK do the heavy lifting and calculate interpolated bones // regular intervals, so let the M3D SDK do the heavy lifting and calculate interpolated bones
for (i = 0; i < animations[a].frameCount; i++) for (i = 0; i < animations[a].frameCount; i++)
{ {
animations[a].framePoses[i] = RL_MALLOC(m3d->numbone*sizeof(Transform)); animations[a].framePoses[i] = RL_MALLOC((m3d->numbone + 1)*sizeof(Transform));
m3db_t *pose = m3d_pose(m3d, a, i * M3D_ANIMDELAY); m3db_t *pose = m3d_pose(m3d, a, i * M3D_ANIMDELAY);
if (pose != NULL) if (pose != NULL)
{ {
for (j = 0; j < m3d->numbone; j++) for (j = 0; j < m3d->numbone; j++)
{ {
animations[a].framePoses[i][j].translation.x = m3d->vertex[pose[j].pos].x; animations[a].framePoses[i][j].translation.x = m3d->vertex[pose[j].pos].x*m3d->scale;
animations[a].framePoses[i][j].translation.y = m3d->vertex[pose[j].pos].y; animations[a].framePoses[i][j].translation.y = m3d->vertex[pose[j].pos].y*m3d->scale;
animations[a].framePoses[i][j].translation.z = m3d->vertex[pose[j].pos].z; animations[a].framePoses[i][j].translation.z = m3d->vertex[pose[j].pos].z*m3d->scale;
animations[a].framePoses[i][j].rotation.x = m3d->vertex[pose[j].ori].x; animations[a].framePoses[i][j].rotation.x = m3d->vertex[pose[j].ori].x;
animations[a].framePoses[i][j].rotation.y = m3d->vertex[pose[j].ori].y; animations[a].framePoses[i][j].rotation.y = m3d->vertex[pose[j].ori].y;
animations[a].framePoses[i][j].rotation.z = m3d->vertex[pose[j].ori].z; animations[a].framePoses[i][j].rotation.z = m3d->vertex[pose[j].ori].z;
animations[a].framePoses[i][j].rotation.w = m3d->vertex[pose[j].ori].w; animations[a].framePoses[i][j].rotation.w = m3d->vertex[pose[j].ori].w;
animations[a].framePoses[i][j].rotation = QuaternionNormalize(animations[a].framePoses[i][j].rotation); animations[a].framePoses[i][j].rotation = QuaternionNormalize(animations[a].framePoses[i][j].rotation);
animations[a].framePoses[i][j].scale.x = animations[a].framePoses[i][j].scale.y = animations[a].framePoses[i][j].scale.z = 1.0f; animations[a].framePoses[i][j].scale.x = animations[a].framePoses[i][j].scale.y = animations[a].framePoses[i][j].scale.z = 1.0f;
// Child bones are stored in parent bone relative space, convert that into model space
if (animations[a].bones[j].parent >= 0)
{
animations[a].framePoses[i][j].rotation = QuaternionMultiply(animations[a].framePoses[i][animations[a].bones[j].parent].rotation, animations[a].framePoses[i][j].rotation);
animations[a].framePoses[i][j].translation = Vector3RotateByQuaternion(animations[a].framePoses[i][j].translation, animations[a].framePoses[i][animations[a].bones[j].parent].rotation);
animations[a].framePoses[i][j].translation = Vector3Add(animations[a].framePoses[i][j].translation, animations[a].framePoses[i][animations[a].bones[j].parent].translation);
animations[a].framePoses[i][j].scale = Vector3Multiply(animations[a].framePoses[i][j].scale, animations[a].framePoses[i][animations[a].bones[j].parent].scale);
}
} }
// Default transform for the "no bone" bone
animations[a].framePoses[i][j].translation.x = 0.0f;
animations[a].framePoses[i][j].translation.y = 0.0f;
animations[a].framePoses[i][j].translation.z = 0.0f;
animations[a].framePoses[i][j].rotation.x = 0.0f;
animations[a].framePoses[i][j].rotation.y = 0.0f;
animations[a].framePoses[i][j].rotation.z = 0.0f;
animations[a].framePoses[i][j].rotation.w = 1.0f;
animations[a].framePoses[i][j].scale.x = animations[a].framePoses[i][j].scale.y = animations[a].framePoses[i][j].scale.z = 1.0f;
RL_FREE(pose); RL_FREE(pose);
} }
} }

View file

@ -104,21 +104,50 @@ void SetShapesTexture(Texture2D texture, Rectangle source)
// Draw a pixel // Draw a pixel
void DrawPixel(int posX, int posY, Color color) void DrawPixel(int posX, int posY, Color color)
{ {
rlBegin(RL_LINES); DrawPixelV((Vector2){ posX, posY }, color);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(posX, posY);
rlVertex2i(posX + 1, posY + 1);
rlEnd();
} }
// Draw a pixel (Vector version) // Draw a pixel (Vector version)
void DrawPixelV(Vector2 position, Color color) void DrawPixelV(Vector2 position, Color color)
{ {
rlBegin(RL_LINES); #if defined(SUPPORT_QUADS_DRAW_MODE)
rlSetTexture(texShapes.id);
rlBegin(RL_QUADS);
rlNormal3f(0.0f, 0.0f, 1.0f);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(position.x, position.y); rlVertex2f(position.x, position.y);
rlVertex2f(position.x + 1.0f, position.y + 1.0f);
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(position.x, position.y + 1);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(position.x + 1, position.y + 1);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(position.x + 1, position.y);
rlEnd(); rlEnd();
rlSetTexture(0);
#else
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(position.x, position.y);
rlVertex2f(position.x, position.y + 1);
rlVertex2f(position.x + 1, position.y);
rlVertex2f(position.x + 1, position.y);
rlVertex2f(position.x, position.y + 1);
rlVertex2f(position.x + 1, position.y + 1);
rlEnd();
#endif
} }
// Draw a line // Draw a line
@ -126,8 +155,8 @@ void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color colo
{ {
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(startPosX, startPosY); rlVertex2f(startPosX, startPosY);
rlVertex2i(endPosX, endPosY); rlVertex2f(endPosX, endPosY);
rlEnd(); rlEnd();
} }
@ -175,6 +204,8 @@ void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color)
current.y = EaseCubicInOut((float)i, startPos.y, endPos.y - startPos.y, (float)BEZIER_LINE_DIVISIONS); current.y = EaseCubicInOut((float)i, startPos.y, endPos.y - startPos.y, (float)BEZIER_LINE_DIVISIONS);
current.x = previous.x + (endPos.x - startPos.x)/ (float)BEZIER_LINE_DIVISIONS; current.x = previous.x + (endPos.x - startPos.x)/ (float)BEZIER_LINE_DIVISIONS;
// TODO: Avoid drawing the line by pieces, it generates gaps for big thicks,
// Custom "triangle-strip" implementation should be used, check DrawTriangleStrip() for reference
DrawLineEx(previous, current, thick, color); DrawLineEx(previous, current, thick, color);
previous = current; previous = current;
@ -201,6 +232,8 @@ void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, fl
current.y = a*startPos.y + b*controlPos.y + c*endPos.y; current.y = a*startPos.y + b*controlPos.y + c*endPos.y;
current.x = a*startPos.x + b*controlPos.x + c*endPos.x; current.x = a*startPos.x + b*controlPos.x + c*endPos.x;
// TODO: Avoid drawing the line by pieces, it generates gaps for big thicks,
// Custom "triangle-strip" implementation should be used, check DrawTriangleStrip() for reference
DrawLineEx(previous, current, thick, color); DrawLineEx(previous, current, thick, color);
previous = current; previous = current;
@ -227,6 +260,8 @@ void DrawLineBezierCubic(Vector2 startPos, Vector2 endPos, Vector2 startControlP
current.y = a*startPos.y + b*startControlPos.y + c*endControlPos.y + d*endPos.y; current.y = a*startPos.y + b*startControlPos.y + c*endControlPos.y + d*endPos.y;
current.x = a*startPos.x + b*startControlPos.x + c*endControlPos.x + d*endPos.x; current.x = a*startPos.x + b*startControlPos.x + c*endControlPos.x + d*endPos.x;
// TODO: Avoid drawing the line by pieces, it generates gaps for big thicks,
// Custom "triangle-strip" implementation should be used, check DrawTriangleStrip() for reference
DrawLineEx(previous, current, thick, color); DrawLineEx(previous, current, thick, color);
previous = current; previous = current;
@ -238,8 +273,6 @@ void DrawLineStrip(Vector2 *points, int pointCount, Color color)
{ {
if (pointCount >= 2) if (pointCount >= 2)
{ {
rlCheckRenderBatchLimit(pointCount);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -287,8 +320,6 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
float angle = startAngle; float angle = startAngle;
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4*segments/2);
rlSetTexture(texShapes.id); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -333,8 +364,6 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
rlSetTexture(0); rlSetTexture(0);
#else #else
rlCheckRenderBatchLimit(3*segments);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i = 0; i < segments; i++) for (int i = 0; i < segments; i++)
{ {
@ -377,13 +406,7 @@ void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float
float stepLength = (endAngle - startAngle)/(float)segments; float stepLength = (endAngle - startAngle)/(float)segments;
float angle = startAngle; float angle = startAngle;
// Hide the cap lines when the circle is full
bool showCapLines = true; bool showCapLines = true;
int limit = 2*(segments + 2);
if ((int)(endAngle - startAngle)%360 == 0) { limit = 2*segments; showCapLines = false; }
rlCheckRenderBatchLimit(limit);
rlBegin(RL_LINES); rlBegin(RL_LINES);
if (showCapLines) if (showCapLines)
@ -416,8 +439,6 @@ void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float
// NOTE: Gradient goes from center (color1) to border (color2) // NOTE: Gradient goes from center (color1) to border (color2)
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2) void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
{ {
rlCheckRenderBatchLimit(3*36);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i = 0; i < 360; i += 10) for (int i = 0; i < 360; i += 10)
{ {
@ -441,8 +462,6 @@ void DrawCircleV(Vector2 center, float radius, Color color)
// Draw circle outline // Draw circle outline
void DrawCircleLines(int centerX, int centerY, float radius, Color color) void DrawCircleLines(int centerX, int centerY, float radius, Color color)
{ {
rlCheckRenderBatchLimit(2*36);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -458,8 +477,6 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
// Draw ellipse // Draw ellipse
void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color) void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color)
{ {
rlCheckRenderBatchLimit(3*36);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i = 0; i < 360; i += 10) for (int i = 0; i < 360; i += 10)
{ {
@ -474,8 +491,6 @@ void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color c
// Draw ellipse outline // Draw ellipse outline
void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color) void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color)
{ {
rlCheckRenderBatchLimit(2*36);
rlBegin(RL_LINES); rlBegin(RL_LINES);
for (int i = 0; i < 360; i += 10) for (int i = 0; i < 360; i += 10)
{ {
@ -532,8 +547,6 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA
float angle = startAngle; float angle = startAngle;
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4*segments);
rlSetTexture(texShapes.id); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -559,8 +572,6 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA
rlSetTexture(0); rlSetTexture(0);
#else #else
rlCheckRenderBatchLimit(6*segments);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i = 0; i < segments; i++) for (int i = 0; i < segments; i++)
{ {
@ -623,12 +634,7 @@ void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float s
float stepLength = (endAngle - startAngle)/(float)segments; float stepLength = (endAngle - startAngle)/(float)segments;
float angle = startAngle; float angle = startAngle;
bool showCapLines = true; bool showCapLines = true;
int limit = 4*(segments + 1);
if ((int)(endAngle - startAngle)%360 == 0) { limit = 4*segments; showCapLines = false; }
rlCheckRenderBatchLimit(limit);
rlBegin(RL_LINES); rlBegin(RL_LINES);
if (showCapLines) if (showCapLines)
@ -720,8 +726,6 @@ void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color
} }
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4);
rlSetTexture(texShapes.id); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -745,8 +749,6 @@ void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color
rlSetTexture(0); rlSetTexture(0);
#else #else
rlCheckRenderBatchLimit(6);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -781,8 +783,6 @@ void DrawRectangleGradientH(int posX, int posY, int width, int height, Color col
// NOTE: Colors refer to corners, starting at top-lef corner and counter-clockwise // NOTE: Colors refer to corners, starting at top-lef corner and counter-clockwise
void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4) void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4)
{ {
rlCheckRenderBatchLimit(4);
rlSetTexture(texShapes.id); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -821,17 +821,17 @@ void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
#else #else
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(posX + 1, posY + 1); rlVertex2f(posX + 1, posY + 1);
rlVertex2i(posX + width, posY + 1); rlVertex2f(posX + width, posY + 1);
rlVertex2i(posX + width, posY + 1); rlVertex2f(posX + width, posY + 1);
rlVertex2i(posX + width, posY + height); rlVertex2f(posX + width, posY + height);
rlVertex2i(posX + width, posY + height); rlVertex2f(posX + width, posY + height);
rlVertex2i(posX + 1, posY + height); rlVertex2f(posX + 1, posY + height);
rlVertex2i(posX + 1, posY + height); rlVertex2f(posX + 1, posY + height);
rlVertex2i(posX + 1, posY + 1); rlVertex2f(posX + 1, posY + 1);
rlEnd(); rlEnd();
#endif #endif
} }
@ -923,8 +923,6 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
const float angles[4] = { 180.0f, 90.0f, 0.0f, 270.0f }; const float angles[4] = { 180.0f, 90.0f, 0.0f, 270.0f };
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(16*segments/2 + 5*4);
rlSetTexture(texShapes.id); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -1022,8 +1020,6 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
rlEnd(); rlEnd();
rlSetTexture(0); rlSetTexture(0);
#else #else
rlCheckRenderBatchLimit(12*segments + 5*6); // 4 corners with 3 vertices per segment + 5 rectangles with 6 vertices each
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
// Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner // Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner
@ -1155,8 +1151,6 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo
if (lineThick > 1) if (lineThick > 1)
{ {
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4*4*segments + 4*4); // 4 corners with 4 vertices for each segment + 4 rectangles with 4 vertices each
rlSetTexture(texShapes.id); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -1229,8 +1223,6 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo
rlEnd(); rlEnd();
rlSetTexture(0); rlSetTexture(0);
#else #else
rlCheckRenderBatchLimit(4*6*segments + 4*6); // 4 corners with 6(2*3) vertices for each segment + 4 rectangles with 6 vertices each
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
// Draw all of the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner // Draw all of the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner
@ -1296,8 +1288,6 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo
else else
{ {
// Use LINES to draw the outline // Use LINES to draw the outline
rlCheckRenderBatchLimit(8*segments + 4*2); // 4 corners with 2 vertices for each segment + 4 rectangles with 2 vertices each
rlBegin(RL_LINES); rlBegin(RL_LINES);
// Draw all of the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner // Draw all of the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner
@ -1332,8 +1322,6 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, flo
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color) void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{ {
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4);
rlSetTexture(texShapes.id); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -1354,8 +1342,6 @@ void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
rlSetTexture(0); rlSetTexture(0);
#else #else
rlCheckRenderBatchLimit(3);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(v1.x, v1.y); rlVertex2f(v1.x, v1.y);
@ -1369,8 +1355,6 @@ void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
// NOTE: Vertex must be provided in counter-clockwise order // NOTE: Vertex must be provided in counter-clockwise order
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color) void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{ {
rlCheckRenderBatchLimit(6);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(v1.x, v1.y); rlVertex2f(v1.x, v1.y);
@ -1391,8 +1375,6 @@ void DrawTriangleFan(Vector2 *points, int pointCount, Color color)
{ {
if (pointCount >= 3) if (pointCount >= 3)
{ {
rlCheckRenderBatchLimit((pointCount - 2)*4);
rlSetTexture(texShapes.id); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -1422,8 +1404,6 @@ void DrawTriangleStrip(Vector2 *points, int pointCount, Color color)
{ {
if (pointCount >= 3) if (pointCount >= 3)
{ {
rlCheckRenderBatchLimit(3*(pointCount - 2));
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -1450,143 +1430,114 @@ void DrawTriangleStrip(Vector2 *points, int pointCount, Color color)
void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color) void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color)
{ {
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
float centralAngle = 0.0f; float centralAngle = rotation;
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4*sides); // Each side is a quad rlSetTexture(texShapes.id);
rlBegin(RL_QUADS);
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(center.x, center.y);
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
centralAngle += 360.0f/(float)sides;
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
}
rlEnd();
rlSetTexture(0);
#else #else
rlCheckRenderBatchLimit(3*sides); rlBegin(RL_TRIANGLES);
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x, center.y);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
centralAngle += 360.0f/(float)sides;
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
}
rlEnd();
#endif #endif
rlPushMatrix();
rlTranslatef(center.x, center.y, 0.0f);
rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
#if defined(SUPPORT_QUADS_DRAW_MODE)
rlSetTexture(texShapes.id);
rlBegin(RL_QUADS);
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(0, 0);
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
centralAngle += 360.0f/(float)sides;
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
}
rlEnd();
rlSetTexture(0);
#else
rlBegin(RL_TRIANGLES);
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(0, 0);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
centralAngle += 360.0f/(float)sides;
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
}
rlEnd();
#endif
rlPopMatrix();
} }
// Draw a polygon outline of n sides // Draw a polygon outline of n sides
void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color) void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color)
{ {
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
float centralAngle = 0.0f; float centralAngle = rotation;
rlCheckRenderBatchLimit(2*sides); rlBegin(RL_LINES);
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlPushMatrix(); rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
rlTranslatef(center.x, center.y, 0.0f); centralAngle += 360.0f/(float)sides;
rlRotatef(rotation, 0.0f, 0.0f, 1.0f); rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
}
rlBegin(RL_LINES); rlEnd();
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
centralAngle += 360.0f/(float)sides;
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
}
rlEnd();
rlPopMatrix();
} }
void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color) void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color)
{ {
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
float centralAngle = 0.0f; float centralAngle = rotation;
float exteriorAngle = 360.0f/(float)sides; float exteriorAngle = 360.0f/(float)sides;
float innerRadius = radius - (lineThick*cosf(DEG2RAD*exteriorAngle/2.0f)); float innerRadius = radius - (lineThick*cosf(DEG2RAD*exteriorAngle/2.0f));
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4*sides); rlSetTexture(texShapes.id);
rlBegin(RL_QUADS);
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*innerRadius, center.y + cosf(DEG2RAD*centralAngle)*innerRadius);
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
centralAngle += exteriorAngle;
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*innerRadius, center.y + cosf(DEG2RAD*centralAngle)*innerRadius);
}
rlEnd();
rlSetTexture(0);
#else #else
rlCheckRenderBatchLimit(6*sides); rlBegin(RL_TRIANGLES);
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
float nextAngle = centralAngle + exteriorAngle;
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*radius, center.y + cosf(DEG2RAD*centralAngle)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*innerRadius, center.y + cosf(DEG2RAD*centralAngle)*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*nextAngle)*radius, center.y + cosf(DEG2RAD*nextAngle)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*centralAngle)*innerRadius, center.y + cosf(DEG2RAD*centralAngle)*innerRadius);
rlVertex2f(center.x + sinf(DEG2RAD*nextAngle)*radius, center.y + cosf(DEG2RAD*nextAngle)*radius);
rlVertex2f(center.x + sinf(DEG2RAD*nextAngle)*innerRadius, center.y + cosf(DEG2RAD*nextAngle)*innerRadius);
centralAngle = nextAngle;
}
rlEnd();
#endif #endif
rlPushMatrix();
rlTranslatef(center.x, center.y, 0.0f);
rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
#if defined(SUPPORT_QUADS_DRAW_MODE)
rlSetTexture(texShapes.id);
rlBegin(RL_QUADS);
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*innerRadius, cosf(DEG2RAD*centralAngle)*innerRadius);
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
centralAngle += exteriorAngle;
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*innerRadius, cosf(DEG2RAD*centralAngle)*innerRadius);
}
rlEnd();
rlSetTexture(0);
#else
rlBegin(RL_TRIANGLES);
for (int i = 0; i < sides; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
float nextAngle = centralAngle + exteriorAngle;
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
rlVertex2f(sinf(DEG2RAD*centralAngle)*innerRadius, cosf(DEG2RAD*centralAngle)*innerRadius);
rlVertex2f(sinf(DEG2RAD*nextAngle)*radius, cosf(DEG2RAD*nextAngle)*radius);
rlVertex2f(sinf(DEG2RAD*centralAngle)*innerRadius, cosf(DEG2RAD*centralAngle)*innerRadius);
rlVertex2f(sinf(DEG2RAD*nextAngle)*radius, cosf(DEG2RAD*nextAngle)*radius);
rlVertex2f(sinf(DEG2RAD*nextAngle)*innerRadius, cosf(DEG2RAD*nextAngle)*innerRadius);
centralAngle = nextAngle;
}
rlEnd();
#endif
rlPopMatrix();
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1631,6 +1582,27 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2
return collision; return collision;
} }
// Check if point is within a polygon described by array of vertices
// NOTE: Based on http://jeffreythompson.org/collision-detection/poly-point.php
bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount)
{
bool collision = false;
if (pointCount > 2)
{
for (int i = 0; i < pointCount - 1; i++)
{
Vector2 vc = points[i];
Vector2 vn = points[i + 1];
if ((((vc.y >= point.y) && (vn.y < point.y)) || ((vc.y < point.y) && (vn.y >= point.y))) &&
(point.x < ((vn.x - vc.x)*(point.y - vc.y)/(vn.y - vc.y) + vc.x))) collision = !collision;
}
}
return collision;
}
// Check collision between two rectangles // Check collision between two rectangles
bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2) bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2)
{ {

View file

@ -58,7 +58,7 @@
#if defined(SUPPORT_MODULE_RTEXT) #if defined(SUPPORT_MODULE_RTEXT)
#include "utils.h" // Required for: LoadFileText() #include "utils.h" // Required for: LoadFile*()
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -> Only DrawTextPro() #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -> Only DrawTextPro()
#include <stdlib.h> // Required for: malloc(), free() #include <stdlib.h> // Required for: malloc(), free()
@ -359,7 +359,7 @@ Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCou
// Loading font from memory data // Loading font from memory data
font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, fontChars, glyphCount); font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, fontChars, glyphCount);
RL_FREE(fileData); UnloadFileData(fileData);
} }
else font = GetFontDefault(); else font = GetFontDefault();
@ -1043,7 +1043,7 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
{ {
// Get next codepoint from byte string and glyph index in font // Get next codepoint from byte string and glyph index in font
int codepointByteCount = 0; int codepointByteCount = 0;
int codepoint = GetCodepoint(&text[i], &codepointByteCount); int codepoint = GetCodepointNext(&text[i], &codepointByteCount);
int index = GetGlyphIndex(font, codepoint); int index = GetGlyphIndex(font, codepoint);
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
@ -1185,7 +1185,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
byteCounter++; byteCounter++;
int next = 0; int next = 0;
letter = GetCodepoint(&text[i], &next); letter = GetCodepointNext(&text[i], &next);
index = GetGlyphIndex(font, letter); index = GetGlyphIndex(font, letter);
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f) // NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
@ -1627,7 +1627,7 @@ const char *TextToPascal(const char *text)
// Encode text codepoint into UTF-8 text // Encode text codepoint into UTF-8 text
// REQUIRES: memcpy() // REQUIRES: memcpy()
// WARNING: Allocated memory must be manually freed // WARNING: Allocated memory must be manually freed
char *TextCodepointsToUTF8(const int *codepoints, int length) char *LoadUTF8(const int *codepoints, int length)
{ {
// We allocate enough memory fo fit all possible codepoints // We allocate enough memory fo fit all possible codepoints
// NOTE: 5 bytes for every codepoint should be enough // NOTE: 5 bytes for every codepoint should be enough
@ -1650,9 +1650,68 @@ char *TextCodepointsToUTF8(const int *codepoints, int length)
return text; return text;
} }
// Unload UTF-8 text encoded from codepoints array
void UnloadUTF8(char *text)
{
RL_FREE(text);
}
// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
int *LoadCodepoints(const char *text, int *count)
{
int textLength = TextLength(text);
int codepointSize = 0;
int codepointCount = 0;
// Allocate a big enough buffer to store as many codepoints as text bytes
int *codepoints = RL_CALLOC(textLength, sizeof(int));
for (int i = 0; i < textLength; codepointCount++)
{
codepoints[codepointCount] = GetCodepointNext(text + i, &codepointSize);
i += codepointSize;
}
// Re-allocate buffer to the actual number of codepoints loaded
void *temp = RL_REALLOC(codepoints, codepointCount*sizeof(int));
if (temp != NULL) codepoints = temp;
*count = codepointCount;
return codepoints;
}
// Unload codepoints data from memory
void UnloadCodepoints(int *codepoints)
{
RL_FREE(codepoints);
}
// Get total number of characters(codepoints) in a UTF-8 encoded text, until '\0' is found
// NOTE: If an invalid UTF-8 sequence is encountered a '?'(0x3f) codepoint is counted instead
int GetCodepointCount(const char *text)
{
unsigned int length = 0;
char *ptr = (char *)&text[0];
while (*ptr != '\0')
{
int next = 0;
int letter = GetCodepointNext(ptr, &next);
if (letter == 0x3f) ptr += 1;
else ptr += next;
length++;
}
return length;
}
// Encode codepoint into utf8 text (char array length returned as parameter) // Encode codepoint into utf8 text (char array length returned as parameter)
// NOTE: It uses a static array to store UTF-8 bytes // NOTE: It uses a static array to store UTF-8 bytes
RLAPI const char *CodepointToUTF8(int codepoint, int *byteSize) const char *CodepointToUTF8(int codepoint, int *utf8Size)
{ {
static char utf8[6] = { 0 }; static char utf8[6] = { 0 };
int size = 0; // Byte size of codepoint int size = 0; // Byte size of codepoint
@ -1684,63 +1743,10 @@ RLAPI const char *CodepointToUTF8(int codepoint, int *byteSize)
size = 4; size = 4;
} }
*byteSize = size; *utf8Size = size;
return utf8; return utf8;
} }
// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
int *LoadCodepoints(const char *text, int *count)
{
int textLength = TextLength(text);
int bytesProcessed = 0;
int codepointCount = 0;
// Allocate a big enough buffer to store as many codepoints as text bytes
int *codepoints = RL_CALLOC(textLength, sizeof(int));
for (int i = 0; i < textLength; codepointCount++)
{
codepoints[codepointCount] = GetCodepoint(text + i, &bytesProcessed);
i += bytesProcessed;
}
// Re-allocate buffer to the actual number of codepoints loaded
void *temp = RL_REALLOC(codepoints, codepointCount*sizeof(int));
if (temp != NULL) codepoints = temp;
*count = codepointCount;
return codepoints;
}
// Unload codepoints data from memory
void UnloadCodepoints(int *codepoints)
{
RL_FREE(codepoints);
}
// Get total number of characters(codepoints) in a UTF-8 encoded text, until '\0' is found
// NOTE: If an invalid UTF-8 sequence is encountered a '?'(0x3f) codepoint is counted instead
int GetCodepointCount(const char *text)
{
unsigned int length = 0;
char *ptr = (char *)&text[0];
while (*ptr != '\0')
{
int next = 0;
int letter = GetCodepoint(ptr, &next);
if (letter == 0x3f) ptr += 1;
else ptr += next;
length++;
}
return length;
}
#endif // SUPPORT_TEXT_MANIPULATION #endif // SUPPORT_TEXT_MANIPULATION
// Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found // Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found
@ -1748,7 +1754,7 @@ int GetCodepointCount(const char *text)
// Total number of bytes processed are returned as a parameter // Total number of bytes processed are returned as a parameter
// NOTE: The standard says U+FFFD should be returned in case of errors // NOTE: The standard says U+FFFD should be returned in case of errors
// but that character is not supported by the default font in raylib // but that character is not supported by the default font in raylib
int GetCodepoint(const char *text, int *bytesProcessed) int GetCodepoint(const char *text, int *codepointSize)
{ {
/* /*
UTF-8 specs from https://www.ietf.org/rfc/rfc3629.txt UTF-8 specs from https://www.ietf.org/rfc/rfc3629.txt
@ -1763,14 +1769,14 @@ int GetCodepoint(const char *text, int *bytesProcessed)
*/ */
// NOTE: on decode errors we return as soon as possible // NOTE: on decode errors we return as soon as possible
int code = 0x3f; // Codepoint (defaults to '?') int codepoint = 0x3f; // Codepoint (defaults to '?')
int octet = (unsigned char)(text[0]); // The first UTF8 octet int octet = (unsigned char)(text[0]); // The first UTF8 octet
*bytesProcessed = 1; *codepointSize = 1;
if (octet <= 0x7f) if (octet <= 0x7f)
{ {
// Only one octet (ASCII range x00-7F) // Only one octet (ASCII range x00-7F)
code = text[0]; codepoint = text[0];
} }
else if ((octet & 0xe0) == 0xc0) else if ((octet & 0xe0) == 0xc0)
{ {
@ -1779,12 +1785,12 @@ int GetCodepoint(const char *text, int *bytesProcessed)
// [0]xC2-DF [1]UTF8-tail(x80-BF) // [0]xC2-DF [1]UTF8-tail(x80-BF)
unsigned char octet1 = text[1]; unsigned char octet1 = text[1];
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *codepointSize = 2; return codepoint; } // Unexpected sequence
if ((octet >= 0xc2) && (octet <= 0xdf)) if ((octet >= 0xc2) && (octet <= 0xdf))
{ {
code = ((octet & 0x1f) << 6) | (octet1 & 0x3f); codepoint = ((octet & 0x1f) << 6) | (octet1 & 0x3f);
*bytesProcessed = 2; *codepointSize = 2;
} }
} }
else if ((octet & 0xf0) == 0xe0) else if ((octet & 0xf0) == 0xe0)
@ -1793,11 +1799,11 @@ int GetCodepoint(const char *text, int *bytesProcessed)
unsigned char octet1 = text[1]; unsigned char octet1 = text[1];
unsigned char octet2 = '\0'; unsigned char octet2 = '\0';
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *codepointSize = 2; return codepoint; } // Unexpected sequence
octet2 = text[2]; octet2 = text[2];
if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *codepointSize = 3; return codepoint; } // Unexpected sequence
// [0]xE0 [1]xA0-BF [2]UTF8-tail(x80-BF) // [0]xE0 [1]xA0-BF [2]UTF8-tail(x80-BF)
// [0]xE1-EC [1]UTF8-tail [2]UTF8-tail(x80-BF) // [0]xE1-EC [1]UTF8-tail [2]UTF8-tail(x80-BF)
@ -1805,50 +1811,105 @@ int GetCodepoint(const char *text, int *bytesProcessed)
// [0]xEE-EF [1]UTF8-tail [2]UTF8-tail(x80-BF) // [0]xEE-EF [1]UTF8-tail [2]UTF8-tail(x80-BF)
if (((octet == 0xe0) && !((octet1 >= 0xa0) && (octet1 <= 0xbf))) || if (((octet == 0xe0) && !((octet1 >= 0xa0) && (octet1 <= 0xbf))) ||
((octet == 0xed) && !((octet1 >= 0x80) && (octet1 <= 0x9f)))) { *bytesProcessed = 2; return code; } ((octet == 0xed) && !((octet1 >= 0x80) && (octet1 <= 0x9f)))) { *codepointSize = 2; return codepoint; }
if ((octet >= 0xe0) && (octet <= 0xef)) if ((octet >= 0xe0) && (octet <= 0xef))
{ {
code = ((octet & 0xf) << 12) | ((octet1 & 0x3f) << 6) | (octet2 & 0x3f); codepoint = ((octet & 0xf) << 12) | ((octet1 & 0x3f) << 6) | (octet2 & 0x3f);
*bytesProcessed = 3; *codepointSize = 3;
} }
} }
else if ((octet & 0xf8) == 0xf0) else if ((octet & 0xf8) == 0xf0)
{ {
// Four octets // Four octets
if (octet > 0xf4) return code; if (octet > 0xf4) return codepoint;
unsigned char octet1 = text[1]; unsigned char octet1 = text[1];
unsigned char octet2 = '\0'; unsigned char octet2 = '\0';
unsigned char octet3 = '\0'; unsigned char octet3 = '\0';
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *codepointSize = 2; return codepoint; } // Unexpected sequence
octet2 = text[2]; octet2 = text[2];
if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *codepointSize = 3; return codepoint; } // Unexpected sequence
octet3 = text[3]; octet3 = text[3];
if ((octet3 == '\0') || ((octet3 >> 6) != 2)) { *bytesProcessed = 4; return code; } // Unexpected sequence if ((octet3 == '\0') || ((octet3 >> 6) != 2)) { *codepointSize = 4; return codepoint; } // Unexpected sequence
// [0]xF0 [1]x90-BF [2]UTF8-tail [3]UTF8-tail // [0]xF0 [1]x90-BF [2]UTF8-tail [3]UTF8-tail
// [0]xF1-F3 [1]UTF8-tail [2]UTF8-tail [3]UTF8-tail // [0]xF1-F3 [1]UTF8-tail [2]UTF8-tail [3]UTF8-tail
// [0]xF4 [1]x80-8F [2]UTF8-tail [3]UTF8-tail // [0]xF4 [1]x80-8F [2]UTF8-tail [3]UTF8-tail
if (((octet == 0xf0) && !((octet1 >= 0x90) && (octet1 <= 0xbf))) || if (((octet == 0xf0) && !((octet1 >= 0x90) && (octet1 <= 0xbf))) ||
((octet == 0xf4) && !((octet1 >= 0x80) && (octet1 <= 0x8f)))) { *bytesProcessed = 2; return code; } // Unexpected sequence ((octet == 0xf4) && !((octet1 >= 0x80) && (octet1 <= 0x8f)))) { *codepointSize = 2; return codepoint; } // Unexpected sequence
if (octet >= 0xf0) if (octet >= 0xf0)
{ {
code = ((octet & 0x7) << 18) | ((octet1 & 0x3f) << 12) | ((octet2 & 0x3f) << 6) | (octet3 & 0x3f); codepoint = ((octet & 0x7) << 18) | ((octet1 & 0x3f) << 12) | ((octet2 & 0x3f) << 6) | (octet3 & 0x3f);
*bytesProcessed = 4; *codepointSize = 4;
} }
} }
if (code > 0x10ffff) code = 0x3f; // Codepoints after U+10ffff are invalid if (codepoint > 0x10ffff) codepoint = 0x3f; // Codepoints after U+10ffff are invalid
return code; return codepoint;
}
// Get next codepoint in a byte sequence and bytes processed
int GetCodepointNext(const char *text, int *codepointSize)
{
const char *ptr = text;
int codepoint = 0x3f; // Codepoint (defaults to '?')
*codepointSize = 0;
// Get current codepoint and bytes processed
if (0xf0 == (0xf8 & ptr[0]))
{
// 4 byte UTF-8 codepoint
codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]);
*codepointSize = 4;
}
else if (0xe0 == (0xf0 & ptr[0]))
{
// 3 byte UTF-8 codepoint */
codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]);
*codepointSize = 3;
}
else if (0xc0 == (0xe0 & ptr[0]))
{
// 2 byte UTF-8 codepoint
codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]);
*codepointSize = 2;
}
else
{
// 1 byte UTF-8 codepoint
codepoint = ptr[0];
*codepointSize = 1;
}
return codepoint;
}
// Get previous codepoint in a byte sequence and bytes processed
int GetCodepointPrevious(const char *text, int *codepointSize)
{
const char *ptr = text;
int codepoint = 0x3f; // Codepoint (defaults to '?')
int cpSize = 0;
*codepointSize = 0;
// Move to previous codepoint
do ptr--;
while (((0x80 & ptr[0]) != 0) && ((0xc0 & ptr[0]) == 0x80));
codepoint = GetCodepointNext(ptr, &cpSize);
if (codepoint != 0) *codepointSize = cpSize;
return codepoint;
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

File diff suppressed because it is too large Load diff

View file

@ -160,14 +160,14 @@ void TraceLog(int logType, const char *text, ...)
// Internal memory allocator // Internal memory allocator
// NOTE: Initializes to zero by default // NOTE: Initializes to zero by default
void *MemAlloc(int size) void *MemAlloc(unsigned int size)
{ {
void *ptr = RL_CALLOC(size, 1); void *ptr = RL_CALLOC(size, 1);
return ptr; return ptr;
} }
// Internal memory reallocator // Internal memory reallocator
void *MemRealloc(void *ptr, int size) void *MemRealloc(void *ptr, unsigned int size)
{ {
void *ret = RL_REALLOC(ptr, size); void *ret = RL_REALLOC(ptr, size);
return ret; return ret;