# -*- python -*-
# Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
cimport cython
from libc.stdlib cimport malloc, free
cdef extern void blueshift_drm_close()
cdef extern int blueshift_drm_card_count()
cdef extern int blueshift_drm_open_card(int card_index)
cdef extern void blueshift_drm_update_card(int connection)
cdef extern void blueshift_drm_close_card(int connection)
cdef extern int blueshift_drm_crtc_count(int connection)
cdef extern int blueshift_drm_connector_count(int connection)
cdef extern int blueshift_drm_gamma_size(int connection, int crtc_index)
cdef extern int blueshift_drm_get_gamma_ramps(int connection, int crtc_index, int gamma_size,
unsigned short int* red,
unsigned short int* green,
unsigned short int* blue)
cdef extern int blueshift_drm_set_gamma_ramps(int connection, int crtc_index, int gamma_size,
unsigned short int* red,
unsigned short int* green,
unsigned short int* blue)
cdef extern void blueshift_drm_open_connector(int connection, int connector_index)
cdef extern void blueshift_drm_close_connector(int connection, int connector_index)
cdef extern int blueshift_drm_get_width(int connection, int connector_index)
cdef extern int blueshift_drm_get_height(int connection, int connector_index)
cdef extern int blueshift_drm_is_connected(int connection, int connector_index)
cdef extern int blueshift_drm_get_crtc(int connection, int connector_index)
cdef extern int blueshift_drm_get_connector_type_index(int connection, int connector_index)
cdef extern const char* blueshift_drm_get_connector_type_name(int connection, int connector_index)
cdef extern long int blueshift_drm_get_edid(int connection, int connector_index, char* edid,
long int size, int hexadecimal)
cdef unsigned short int* r_shared
cdef unsigned short int* g_shared
cdef unsigned short int* b_shared
r_shared = NULL
g_shared = NULL
b_shared = NULL
def drm_close():
'''
Free all resources, but you need to close all connections first
'''
global r_shared, g_shared, b_shared
if r_shared is not NULL:
free(r_shared)
r_shared = NULL
if g_shared is not NULL:
free(g_shared)
g_shared = NULL
if b_shared is not NULL:
free(b_shared)
b_shared = NULL
blueshift_drm_close()
def drm_card_count():
'''
Get the number of cards present on the system
@return :int The number of cards present on the system
'''
return blueshift_drm_card_count()
def drm_open_card(int card_index):
'''
Open connection to a graphics card
@param card_index The index of the graphics card
@return :int -1 on failure, otherwise an identifier for the connection to the card
'''
return blueshift_drm_open_card(card_index)
def drm_update_card(int connection):
'''
Update the resource, required after `blueshift_drm_open_card`
@param connection The identifier for the connection to the card
'''
blueshift_drm_update_card(connection)
def drm_close_card(int connection):
'''
Close connection to the graphics card
@param connection The identifier for the connection to the card
'''
blueshift_drm_close_card(connection)
def drm_crtc_count(int connection):
'''
Return the number of CRTC:s on the opened card
@param connection The identifier for the connection to the card
@return :int The number of CRTC:s on the opened card
'''
return blueshift_drm_crtc_count(connection)
def drm_connector_count(int connection):
'''
Return the number of connectors on the opened card
@param connection The identifier for the connection to the card
@return :int The number of connectors on the opened card
'''
return blueshift_drm_connector_count(connection)
def drm_gamma_size(int connection, int crtc_index):
'''
Return the size of the gamma ramps on a CRTC
@param connection The identifier for the connection to the card
@param crtc_index The index of the CRTC
@return :int The size of the gamma ramps on a CRTC
'''
return blueshift_drm_gamma_size(connection, crtc_index)
def drm_get_gamma_ramps(int connection, int crtc_index, int gamma_size, threadsafe = False):
'''
Get the gamma ramps of the of a monitor
@param connection The identifier for the connection to the card
@param crtc_index The index of the CRTC to read from
@param gamma_size The size a gamma ramp
@param threadsafe:bool Whether to decrease memory efficiency and performace so
multiple threads can use DRM concurrently
@return :(r:list, g:list, b:list)? The current red, green and blue colour curves
'''
global r_shared, g_shared, b_shared
cdef unsigned short int* r
cdef unsigned short int* g
cdef unsigned short int* b
if not threadsafe:
if r_shared is NULL:
r_shared = malloc(gamma_size * 2)
if g_shared is NULL:
g_shared = malloc(gamma_size * 2)
if b_shared is NULL:
b_shared = malloc(gamma_size * 2)
r = malloc(gamma_size * 2) if threadsafe else r_shared
g = malloc(gamma_size * 2) if threadsafe else g_shared
b = malloc(gamma_size * 2) if threadsafe else b_shared
if (r is NULL) or (g is NULL) or (b is NULL):
raise MemoryError()
rc = blueshift_drm_get_gamma_ramps(connection, crtc_index, gamma_size, r, g, b)
if rc == 0:
rc_r, rc_g, rc_b = [], [], []
for i in range(gamma_size):
rc_r.append(r[i])
rc_g.append(g[i])
rc_b.append(b[i])
if threadsafe:
free(r)
free(g)
free(b)
return (rc_r, rc_g, rc_b)
else:
if threadsafe:
free(r)
free(g)
free(b)
return None
def drm_set_gamma_ramps(int connection, crtc_indices, int gamma_size, r_curve, g_curve, b_curve, threadsafe = False):
'''
Set the gamma ramps of the of a monitor
@param connection The identifier for the connection to the card
@param crtc_index:list The index of the CRTC to read from
@param gamma_size The size a gamma ramp
@param r_curve:list The red gamma ramp
@param g_curve:list The green gamma ramp
@param b_curve:list The blue gamma ramp
@param threadsafe:bool Whether to decrease memory efficiency and performace so
multiple threads can use DRM concurrently
@return :int Zero on success
'''
global r_shared, g_shared, b_shared
cdef unsigned short int* r
cdef unsigned short int* g
cdef unsigned short int* b
if not threadsafe:
if r_shared is NULL:
r_shared = malloc(gamma_size * 2)
if g_shared is NULL:
g_shared = malloc(gamma_size * 2)
if b_shared is NULL:
b_shared = malloc(gamma_size * 2)
r = malloc(gamma_size * 2) if threadsafe else r_shared
g = malloc(gamma_size * 2) if threadsafe else g_shared
b = malloc(gamma_size * 2) if threadsafe else b_shared
if (r is NULL) or (g is NULL) or (b is NULL):
raise MemoryError()
for i in range(gamma_size):
r[i] = r_curve[i] & 0xFFFF
g[i] = g_curve[i] & 0xFFFF
b[i] = b_curve[i] & 0xFFFF
rc = 0
for crtc_index in crtc_indices:
rc |= blueshift_drm_set_gamma_ramps(connection, crtc_index, gamma_size, r, g, b)
if threadsafe:
free(r)
free(g)
free(b)
return rc
def drm_open_connector(int connection, int connector_index):
'''
Acquire information about a connector
@param connection The identifier for the connection to the card
@param connector_index The index of the connector
'''
blueshift_drm_open_connector(connection, connector_index)
def drm_close_connector(int connection, int connector_index):
'''
Release information about a connector
@param connection The identifier for the connection to the card
@param connector_index The index of the connector
'''
blueshift_drm_close_connector(connection, connector_index)
def drm_get_width(int connection, int connector_index):
'''
Get the physical width the monitor connected to a connector
@param connection The identifier for the connection to the card
@param connector_index The index of the connector
@return :int The physical width of the monitor in millimetres, 0 if unknown or not connected
'''
return blueshift_drm_get_width(connection, connector_index)
def drm_get_height(int connection, int connector_index):
'''
Get the physical height the monitor connected to a connector
@param connection The identifier for the connection to the card
@param connector_index The index of the connector
@return :int The physical height of the monitor in millimetres, 0 if unknown or not connected
'''
return blueshift_drm_get_height(connection, connector_index)
def drm_is_connected(int connection, int connector_index):
'''
Get whether a monitor is connected to a connector
@param connection The identifier for the connection to the card
@param connector_index The index of the connector
@return :int 1 if there is a connection, 0 otherwise, -1 if unknown
'''
return blueshift_drm_is_connected(connection, connector_index)
def drm_get_crtc(int connection, int connector_index):
'''
Get the index of the CRTC of the monitor connected to a connector
@param connection The identifier for the connection to the card
@param connector_index The index of the connector
@return :int The index of the CRTC
'''
return blueshift_drm_get_crtc(connection, connector_index)
def drm_get_connector_type_index(int connection, int connector_index):
'''
Get the index of the type of a connector
@param connection The identifier for the connection to the card
@param connector_index The index of the connector
@return :int The connector type by index, 0 for unknown
'''
return blueshift_drm_get_connector_type_index(connection, connector_index)
def drm_get_connector_type_name(int connection, int connector_index):
'''
Get the name of the type of a connector
@param connection The identifier for the connection to the card
@param connector_index The index of the connector
@return :str The connector type by name, "Unknown" if not identifiable,
"Unrecognised" if Blueshift does not recognise it.
'''
return (blueshift_drm_get_connector_type_name(connection, connector_index)).decode('utf-8', 'replace')
def drm_get_edid(int connection, int connector_index):
'''
Get the extended display identification data for the monitor connected to a connector
@param connection The identifier for the connection to the card
@param connector_index The index of the connector
@return :str? The extended display identification data for the monitor
'''
global edid_shared
cdef long int size
cdef long int got
cdef char* edid
cdef bytes rc
size = 256
edid = malloc(size + 1)
if edid is NULL:
raise MemoryError()
got = blueshift_drm_get_edid(connection, connector_index, edid, size, 1)
if got == 0:
free(edid)
return None
if got * 2 > size:
size = got
blueshift_drm_get_edid(connection, connector_index, edid, size, 1)
edid[got * 2] = 0
rc = edid
free(edid)
return rc.decode('utf-8', 'replace')