API Details¶
Functions by group¶
Versioning¶
1 | evdi_get_lib_version(struct evdi_lib_version device); |
Function returns library version. It uses semantic versioning to mark compatibility changes. Version consists of 3 components formatted as MAJOR.MINOR.PATCH
MAJOR
number is changed for incompatibile API changesMINOR
number is changed for backwards-compatible changesPATCH
number is changed for backwards-compatibile bug fixes
Module parameters¶
User can modify driver behaviour by its parameters that can be set at module load time or changed during runtime.
initial_device_count
Number of evdi devices added at module load time (default: 0)
EVDI nodes¶
Finding an available EVDI node to use¶
1 | evdi_device_status evdi_check_device(int device); |
Use this function to check if a particular /dev/dri/cardX
is EVDI or not.
Arguments: device
is a number of card to check, e.g. passing 1
will mean /dev/dri/card1
.
Return value:
AVAILABLE
if the device node is EVDI and is available to use.UNRECOGNIZED
when a node has not been created by EVDI kernel module.NOT_PRESENT
in other cases, e.g. when the device does not exist or cannot be opened to check.
Adding new EVDI node (pre v1.9.0)¶
1 | int evdi_add_device() |
Use this to tell the kernel module to create a new cardX
node for your application to use.
Return value:
1
when successful, 0
otherwise.
Opening device nodes (pre v1.9.0)¶
1 | evdi_handle evdi_open(int device); |
This function attempts to open a DRM device node with given number as EVDI. Function performs compatibility check with underlying drm device. If version of the library and module does not match then the device will not be opened.
Arguments: device
is a number of card to open, e.g. 1
means /dev/dri/card1
.
Return value: On success, a handle to the opened device to be used in following API calls. EVDI_INVALID_HANDLE
otherwise.
Request evdi nodes (since v1.9.0)¶
1 | evdi_handle evdi_open_attached_to(char *sysfs_parent_device); |
This function attempts to add (if necessary) and open a DRM device node attached to given parent device. Linking with another sysfs device is sometimes useful if it is required to reflect such relationship in sysfs.
The function performs a compatibility check with an underlying drm device. If version of the library and module does not match, the device will not be opened.
Arguments: sysfs_parent_device
is a string with the following format: usb:[busNum]-[portNum1].[portNum2].[portNum3]...
, which describes the
device that evdi is linked to. Or NULL
when evdi device node is not linked with any other device.
Return value: On success, a handle to the opened device to be used in following API calls. EVDI_INVALID_HANDLE
otherwise.
Closing devices¶
1 | void evdi_close(evdi_handle handle); |
Closes an opened EVDI handle.
Arguments: handle
to an opened device that is to be closed.
Connection¶
Opening connections¶
1 2 3 4 | void evdi_connect(evdi_handle handle, const unsigned char* edid, const unsigned edid_length, const uint32_t sku_area_limit); |
Creates a connection between the EVDI and Linux DRM subsystem, resulting in kernel mode driver processing a hot plug event.
Arguments:
handle
to an opened deviceedid
should be a pointer to a memory block with contents of an EDID of a monitor that will be exposed to kerneledid_length
is the length of the EDID block (typically 512 bytes, or more if extension blocks are present)sku_area_limit
is maximum pixel area (width x height) connected device can display
Disconnecting¶
1 | void evdi_disconnect(evdi_handle handle) |
Breaks the connection between the device handle and DRM subsystem - resulting in an unplug event being processed.
Arguments: handle
to an opened device.
Buffers¶
Managing memory for frame buffers is left to the client applications.
The evdi_buffer
structure is used to let the library know details about the frame buffer your application is working with.
For more details, see struct evdi_buffer description.
Registering¶
1 | void evdi_register_buffer(evdi_handle handle, evdi_buffer buffer); |
This function allows to register a buffer
of type evdi_buffer
with an opened EVDI device handle
.
Warning
Registering a buffer does not allocate memory for the frame.
Unregistering¶
1 | void evdi_unregister_buffer(evdi_handle handle, int bufferId); |
This function unregisters a buffer with a given bufferId
from an opened EVDI device handle
.
Warning
Unregistering a buffer does not deallocate memory for the frame.
Screen updates¶
Requesting an update¶
1 | bool evdi_request_update(evdi_handle handle, int bufferId); |
Requests an update for a buffer with a given bufferId
. The buffer must be already registered with the library.
Arguments:
handle
to an opened device.bufferId
is an identifier for a buffer that should be updated.
Return value:
The function can return true
if the data for the buffer is ready to be grabbed immediately after the call.
If false
is returned, then an update is not yet ready to grab and the application should wait until it gets
notified by the kernel module - see Events and handlers.
Grabbing pixels¶
1 | void evdi_grab_pixels(evdi_handle handle, evdi_rect *rects, int *num_rects); |
Grabs pixels following the most recent update request (see Requesting an update).
This should be called either after a call to evdi_request_update
(if it returns true
which means pixels can be grabbed immediately),
or while handling the update_ready
notification.
Arguments:
handle
to an opened device.rects
is a pointer to the firstevdi_rect
that the library fills, based on what the kernel tells.
Note
It is expected that this pointer is a beginning of an array of evdi_rect
s, and current implementation assumes
the array does not contain more than 16 slots for rects.
num_rects
is a pointer to an integer that will be modified to tell how many dirty rectangles are valid in the list, and the client should only care about as many. In particular, a failed grab will be indicated by0
valid rectangles to take into account (this can happen when there was a mode change between the request and the grab).
DDC/CI response¶
1 2 | void evdi_ddcci_response(evdi_handle handle, const unsigned char *buffer, const uint32_t buffer_length, const bool result); |
Pass back DDC/CI data following the most recent DDC/CI request to the EVDI kernel driver (see DDC/CI data notification).
Arguments:
handle
to an opened device.buffer
a pointer to the response buffer. This will be copied into kernel space.buffer_length
the length of the response buffer.result
the boolean result. The caller should setresult
to true if the most recent DDC/CI request was successful and false if it was unsuccessful. If false,buffer
andbuffer_length
are ignored.
Note
The buffer_length
will be truncated to 64 bytes (DDCCI_BUFFER_SIZE
).
Events and handlers¶
DPMS mode change¶
1 | void (*dpms_handler)(int dpms_mode, void* user_data); |
This notification is sent when a DPMS mode changes. The possible modes are as defined by the standard, and values are bit-compatible with DRM interface:
/* DPMS flags */ #define DRM_MODE_DPMS_ON 0 #define DRM_MODE_DPMS_STANDBY 1 #define DRM_MODE_DPMS_SUSPEND 2 #define DRM_MODE_DPMS_OFF 3
Mode change notification¶
1 | void (*mode_changed_handler)(evdi_mode mode, void* user_data); |
This notification is sent when a display mode changes. Details of the new mode are sent in the mode
argument.
See evdi_mode for description of the structure.
Update ready notification¶
1 | void (*update_ready_handler)(int buffer_to_be_updated, void* user_data); |
This notification is sent when an update for a buffer, that had been earlier requested is ready to be consumed.
The buffer number to be updated is buffer_to_be_updated
.
Cursor change notification¶
1 | void (*cursor_set_handler)(struct evdi_cursor_set cursor_set, void* user_data); |
This notification is sent for an update of cursor buffer or shape. It is also raised when cursor is enabled or disabled. Such situation happens when cursor is moved on and off the screen respectively.
Cursor move notification¶
1 | void (*cursor_move_handler)(struct evdi_cursor_move cursor_move, void* user_data); |
This notification is sent for a cursor position change. It is raised only when cursor is positioned on virtual screen.
CRTC state change¶
1 | void (*crtc_state_handler)(int state, void* user_data); |
Sent when DRM's CRTC changes state. The state
is a value that's forwarded from the kernel.
DDC/CI data notification¶
1 | void (*ddcci_data_handler)(struct evdi_ddcci_data ddcci_data, void *user_data); |
This notification is sent when an i2c request has been made to the DDC/CI address (0x37).
The module will wait for a maximum of DDCCI_TIMEOUT_MS (50ms - The default DDC request timeout) for a response to this request to be passed back via evdi_ddcci_response
.
Logging¶
Client can register their own callback to be used for logging instead of default printf
.
1 | void evdi_set_logging(struct evdi_logging evdi_logging); |
For more on argument see struct evdi_logging.
Types¶
evdi_handle¶
This is a handle to an opened device node that you get from an evdi_open
call,
and use in all following API calls to indicate which EVDI device you communicate with.
evdi_selectable¶
A typedef denoting a file descriptor you can watch to know when there are events being signalled from the kernel module.
Each opened EVDI device handle has its own descriptor to watch.
When the descriptor becomes ready to read from, the application should call evdi_handle_events
to dispatch notifications to its handlers.
evdi_device_status¶
An enumerated type used while finding the DRM device node that is EVDI. Possible values are AVAILABLE
, UNRECOGNIZED
and NOT_PRESENT
.
evdi_rect¶
A simple structure used by the library to represent a rectangular area of a screen. Top left coordinates of the rectangle are x1
and y1
,
bottom right are x2
and y2
.
evdi_mode¶
A structure used to describe a video mode that's set for a display. Contains details of resolution set (width
, height
), refresh rate (refresh_rate
),
and details of a pixel format used to encode color value (bits_per_pixel
and pixel_format
- which are forwarded from kernel's DRM).
evdi_buffer¶
A structure holding details about a buffer.
1 2 3 4 5 6 7 8 9 10 | typedef struct { int id; void* buffer; int width; int height; int stride; evdi_rect* rects; int rect_count; } evdi_buffer; |
Buffers have IDs, which can be arbitrarily chosen integer numbers - but typically a simple sequence of numbers starting
from 0
is used in client applications. The pointer to the beginning of an already allocated memory block should be assigned
to the buffer
member of the structure. This memory will be filled by the kernel module when handling requests to grab pixels.
width
, height
and stride
are properties of the buffer - the first two indicate what the size of the frame is,
and stride
is a width stride - tells what is the increment in bytes between data for lines in memory.
Stride can be equal to width of a single line multiplied by the number of bytes necessary for encoding color value for one pixel (e.g. 4 for RGB32) if the data for lines are contigous in the memory, but you can use larger value to indicate extra space/padding between them, e.g. oftentimes an additional requirement for the value of stride is it being divisbile by 8; note that those values might be specific to particular hardware/graphic drivers. Please consult documentation of your GPU for details.
Last two structure members, rects
and rect_counts
are updated during grabbing pixels to inform about the number and coordinates of areas that are changed from the last update.
evdi_event_context¶
1 2 3 4 5 6 7 8 9 10 | typedef struct { void (*dpms_handler)(int dpms_mode, void* user_data); void (*mode_changed_handler)(evdi_mode mode, void* user_data); void (*update_ready_handler)(int buffer_to_be_updated, void* user_data); void (*crtc_state_handler)(int state, void* user_data); void (*cursor_set_handler)(struct evdi_cursor_set cursor_set, void *user_data); void (*cursor_move_handler)(struct evdi_cursor_move cursor_move, void *user_data); void (*ddcci_data_handler)(struct evdi_ddcci_data ddcci_data, void *user_data); void* user_data; } evdi_event_context; |
The evdi_device_context
structure is used for holding pointers to handlers for all notifications that the application may receive from
the kernel module. The user_data
member is a value that the library will use while dispatching the call back.
See Events and handlers for more information.
evdi_lib_version¶
1 2 3 4 5 | struct evdi_lib_version { int version_major; int version_minor; int version_patchlevel; }; |
The evdi_lib_version
structure contains libevdi version.
Version can be used to check compatibility between library and a client application.
evdi_cursor_set¶
1 2 3 4 5 6 7 8 9 10 11 | struct evdi_cursor_set { int32_t hot_x; int32_t hot_y; uint32_t width; uint32_t height; uint8_t enabled; uint32_t buffer_length; uint32_t *buffer; uint32_t pixel_format; uint32_t stride; }; |
The evdi_cursor_set
structure contains cursor state information. hot_x
and hot_y
define hotspot information.
enabled
parameter is true when cursor bitmap is available and cursor is visible on virtual display.
Parameters width
and height
define size of the cursor bitmap stored in a buffer
memory area of size buffer_length
.
Warning
Event handler or library user has to free buffer memory when it is not using it.
Remaining stride
and pixel_format
describe data organization in the buffer. stride
is a size of a single line in a buffer.
Usually it is width of the cursor multiplied by bytes per pixel value plus additional extra padding. It ensures proper alignment of subsequent pixel rows.
Pixel encoding is described by FourCC code in pixel_format
field.
evdi_cursor_move¶
1 2 3 4 | struct evdi_cursor_move { int32_t x; int32_t y; }; |
The evdi_cursor_move
structure contains current cursor position.
It is defined as top left corner of the cursor bitmap.
evdi_ddcci_data¶
1 2 3 4 5 6 | struct evdi_ddcci_data { uint16_t address; uint16_t flags; uint32_t buffer_length; uint8_t *buffer; }; |
The evdi_ddcci_data
structure contains:
address
i2c address, will always be 0x37.flags
read/write flags. Read = 1, Write = 0.buffer_length
the length of the buffer.buffer
pointer to the ddc/ci buffer. For both read and write this will be truncated to 64 bytes (DDCCI_BUFFER_SIZE
).
Warning
Although the DDC spec advices the maximum buffer length is 32 bytes, we have identified monitors which support bigger buffers.
evdi_logging¶
1 2 3 4 | struct evdi_logging { void (*function)(void *user_data, const char *fmt, ...); void *user_data; }; |
Structure contains two fields:
function
which is a pointer to the actual callback. Thefmt
and...
are the same as in case ofprintf
.user_data
a pointer provided by the client when registering callback
Note
By setting function
to NULL libevdi will switch to default behaviour of using printf
.