/* ======================================================================================================================== GENERATED CODE This code was generated with wayland/codegen from the 'wayland.xml' protocol file. Do not edit this code! ======================================================================================================================== wayland.xml 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. ======================================================================================================================== */ #+build linux #+vet explicit-allocators package wayland import "base:intrinsics" import "core:fmt" import "core:log" import "core:io" // ===================================================================================================================== // DISPLAY // The core global object. This is a special singleton object. It is used for internal Wayland protocol features. Display_ID :: distinct Object_ID DISPLAY_INTERFACE_NAME :: "wl_display" DISPLAY_INTERFACE_VERSION :: 1 // --------------------------------------------------------- // REQUESTS Display_Request :: enum Opcode { Sync = 0, // asynchronous roundtrip Get_Registry = 1, // get global registry object } /* The sync request asks the server to emit the 'done' event on the returned wl_callback object. Since requests are handled in-order and events are delivered in-order, this can be used as a barrier to ensure all previous requests and the resulting events have been handled. The object returned by this request will be destroyed by the compositor after the callback is fired and as such the client must not attempt to use it after that point. The callback_data passed in the callback is undefined and should be ignored. Returns: Callback object for the sync request. */ @(require_results) display_sync :: proc(session: ^Session) -> (callback_id: Callback_ID, error: Error) { callback_id = Callback_ID(_allocate_object(session, .Callback)) _msg_write(session, DISPLAY, Display_Request.Sync, Object_ID(callback_id)) or_return return } /* This request creates a registry object that allows the client to list and bind the global objects available from the compositor. It should be noted that the server side resources consumed in response to a get_registry request can only be released when the client disconnects, not when the client side proxy is destroyed. Therefore, clients should invoke get_registry as infrequently as possible to avoid wasting memory. Returns: Global registry object. */ @(require_results) display_get_registry :: proc(session: ^Session) -> (registry_id: Registry_ID, error: Error) { registry_id = Registry_ID(_allocate_object(session, .Registry)) _msg_write(session, DISPLAY, Display_Request.Get_Registry, Object_ID(registry_id)) or_return return } // --------------------------------------------------------- // EVENTS Display_Event :: enum Opcode { Error = 0, // Fatal error event. Delete_ID = 1, // Acknowledge object ID deletion. } // Fatal error event. // // The error event is sent out when a fatal (non-recoverable) error has occurred. The object_id argument is the object // where the error occurred, most often in response to a request to that object. The code identifies the error and is // defined by the object interface. As such, each interface defines its own set of error codes. The message is a brief // description of the error, for (debugging) convenience. Display_Error :: struct { session: ^Session, // Object where the error occurred. object: Object_ID, // Error code. code: u32, // Error description. message: string, } on_display_error :: proc(session: ^Session, handler: $Handler_Type/proc(e: Display_Error, userdata: $Userdata_Type), userdata: Userdata_Type) where size_of(userdata) <= size_of(rawptr) { dispatch :: proc(session: ^Session, stream: io.Stream, object_id: Object_ID, opcode: Opcode, handler_info: Handler_Info) -> Error { assert(session.objects[object_id].kind == .Display) event: Display_Error event.session = session _unmarshal_to(&event.object, stream, session.frame_allocator) or_return _unmarshal_to(&event.code, stream, session.frame_allocator) or_return _unmarshal_to(&event.message, stream, session.frame_allocator) or_return _message_log(session, .Event, object_id, Display_Event(opcode), event.object, event.code, event.message) (transmute(Handler_Type) handler_info.handler)(event, transmute(Userdata_Type) handler_info.userdata) return nil } handler_info := Handler_Info{ dispatcher = dispatch, handler = transmute(rawptr) handler, userdata = transmute(rawptr) userdata, } _on_event_internal(session, Object_ID(DISPLAY), Opcode(Display_Event.Error), handler_info) } // Acknowledge object ID deletion. // // This event is used internally by the object ID management logic. When a client deletes an object that it had created, // the server will send this event to acknowledge that it has seen the delete request. When the client receives this // event, it will know that it can safely reuse the object ID. Display_Delete_ID :: struct { session: ^Session, // Deleted object ID. object: Object_ID, } on_display_delete_id :: proc(session: ^Session, handler: $H/proc(e: Display_Delete_ID, userdata: $U), userdata: U) where size_of(userdata) <= size_of(rawptr) { dispatch :: proc(session: ^Session, stream: io.Stream, object_id: Object_ID, opcode: Opcode, handler_info: Handler_Info) -> Error { assert(session.objects[object_id].kind == .Display) e: Display_Delete_ID e.session = session _unmarshal_to(&e.object, stream, session.frame_allocator) or_return _message_log(session, .Event, object_id, Display_Event(opcode), e.object) (transmute(H) handler_info.handler)(e, transmute(U) handler_info.userdata) // TODO: We need to actually delete the ID here. return nil } handler_info := Handler_Info{ dispatcher = dispatch, handler = transmute(rawptr) handler, userdata = transmute(rawptr) userdata, } _on_event_internal(session, Object_ID(DISPLAY), Opcode(Display_Event.Delete_ID), handler_info) } // ENUMS // Global error values. // // These errors are global and can be emitted in response to any server request. Display_Error_Enum :: enum u32 { // Server couldn't find object. Invalid_Object = 0, // Method doesn't exist on the specified interface or malformed request. Invalid_Method = 1, // Server is out of memory. No_Memory = 2, // Implementation error in compositor. Implementation = 3, } // ===================================================================================================================== // REGISTRY // Global registry object. // // The singleton global registry object. The server has a number of global objects that are available to all clients. // These objects typically represent an actual object in the server (for example, an input device) or they are singleton // objects that provide extension functionality. // // When a client creates a registry object, the registry object will emit a global event for each global currently in // the registry. Globals come and go as a result of device or monitor hotplugs, reconfiguration or other events, and the // registry will send out global and global_remove events to keep the client up to date with the changes. To mark the // end of the initial burst of events, the client can use the wl_display.sync request immediately after calling // wl_display.get_registry. // // A client can bind to a global object by using the bind request. This creates a client-side handle that lets the // object emit events to the client and lets the client invoke requests on the object. Registry_ID :: distinct Object_ID REGISTRY_INTERFACE_NAME :: "wl_registry" REGISTRY_INTERFACE_VERSION :: 1 // --------------------------------------------------------- // REQUESTS Registry_Request :: enum Opcode { // Bind an object to the display. Bind = 0, } // Binds a new, client-created object to the server using the specified name as the identifier. registry_bind :: proc(session: ^Session, registry_id: Registry_ID, name: u32, interface: string, version: u32, object_id: ^$ID_Type/Object_ID) -> Error { object_id^ = ID_Type(_allocate_object(session, _object_id_type_to_kind(ID_Type))) _msg_write(session, registry_id, Registry_Request.Bind, name, interface, version, Object_ID(object_id^)) or_return return nil } // --------------------------------------------------------- // EVENTS Registry_Event :: enum Opcode { // Announce global object. Global = 0, // Announce removal of global object. Global_Remove, } // Notify the client of global objects. // // The event notifies the client that a global object with the given name is now available, and it implements the given // version of the given interface. Registry_Global :: struct { session: ^Session, registry: Registry_ID, // Numeric name of the global object. name: u32, // Interface implemented by the object. interface: string, // Interface version. version: u32, } on_registry_global :: proc(session: ^Session, registry: Registry_ID, handler: $H/proc(e: Registry_Global, userdata: $U), userdata: U) where size_of(userdata) <= size_of(rawptr) { dispatch :: proc(session: ^Session, stream: io.Stream, object_id: Object_ID, opcode: Opcode, handler_info: Handler_Info) -> Error { assert(session.objects[object_id].kind == .Registry) e: Registry_Global e.session = session e.registry = Registry_ID(object_id) _unmarshal_to(&e.name, stream, session.frame_allocator) or_return _unmarshal_to(&e.interface, stream, session.frame_allocator) or_return _unmarshal_to(&e.version, stream, session.frame_allocator) or_return _message_log(session, .Event, object_id, Registry_Event(opcode), e.name, e.interface, e.version) (transmute(H) handler_info.handler)(e, transmute(U) handler_info.userdata) return nil } handler_info := Handler_Info{ dispatcher = dispatch, handler = transmute(rawptr) handler, userdata = transmute(rawptr) userdata, } _on_event_internal(session, Object_ID(registry), Opcode(Registry_Event.Global), handler_info) } // Notify the client of removed global objects. // // This event notifies the client that the global identified by name is no longer available. If the client bound to // the global using the bind request, the client should now destroy that object. // // The object remains valid and requests to the object will be ignored until the client destroys it, to avoid races // between the global going away and a client sending a request to it. Registry_Global_Remove :: struct { session: ^Session, registry: Registry_ID, // Numeric name of the global object. name: u32, } on_registry_global_remove :: proc(session: ^Session, registry: Registry_ID, handler: $H/proc(e: Registry_Global_Remove, userdata: $U), userdata: U) { dispatch :: proc(session: ^Session, stream: io.Stream, object_id: Object_ID, opcode: Opcode, handler_info: Handler_Info) -> Error { assert(session.objects[object_id].kind == .Registry) e: Registry_Global_Remove e.session = session e.registry = Registry_ID(object_id) _unmarshal_to(&e.name, stream, session.frame_allocator) or_return _message_log(session, .Event, object_id, opcode, e.name) (transmute(H) handler_info.handler)(e, transmute(U) handler_info.userdata) return nil } handler_info := Handler_Info{ dispatcher = dispatch, handler = transmute(rawptr) handler, userdata = transmute(rawptr) userdata, } _on_event_internal(session, Object_ID(registry), Opcode(Registry_Event.Global_Remove), handler_info) } // ===================================================================================================================== // CALLBACK // Clients can handle the 'done' event to get notified when the related request is done. // // Note, because wl_callback objects are created from multiple independent factory interfaces, the wl_callback interface // is frozen at version 1. Callback_ID :: distinct Object_ID CALLBACK_INTERFACE_NAME :: "wl_callback" CALLBACK_INTERFACE_VERSION :: 1 // TODO gen: frozen // EVENTS Callback_Event :: enum Opcode { Done = 0, // done event } // Notify the client when the related request is done. Callback_Done :: struct { session: ^Session, callback: Callback_ID, // request-specific data for the callback callback_data: u32, } on_callback_done :: proc(session: ^Session, callback: Callback_ID, handler: $H/proc(e: Callback_Done, userdata: $U), userdata: U) { dispatch :: proc(session: ^Session, stream: io.Stream, object_id: Object_ID, opcode: Opcode, handler_info: Handler_Info) -> Error { assert(session.objects[object_id].kind == .Callback) e: Callback_Done e.session = session e.callback = Callback_ID(object_id) _unmarshal_to(&e.callback_data, stream, session.frame_allocator) or_return _message_log(session, .Event, object_id, Callback_Event(opcode), e.callback_data) (transmute(H) handler_info.handler)(e, transmute(U) handler_info.userdata) return nil } handler_info := Handler_Info{ dispatcher = dispatch, handler = transmute(rawptr) handler, userdata = transmute(rawptr) userdata, } _on_event_internal(session, Object_ID(callback), Opcode(Callback_Event.Done), handler_info) } // ===================================================================================================================== // CALLBACK Compositor_ID :: distinct Object_ID COMPOSITOR_INTERFACE_NAME :: "wl_compositor" COMPOSITOR_VERSION :: 7