aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/gamma-linux-drm.c135
-rw-r--r--src/libgamma-error.h10
-rw-r--r--src/libgamma-facade.c4
-rw-r--r--src/libgamma-method.h75
4 files changed, 183 insertions, 41 deletions
diff --git a/src/gamma-linux-drm.c b/src/gamma-linux-drm.c
index 13ad91f..4ce803f 100644
--- a/src/gamma-linux-drm.c
+++ b/src/gamma-linux-drm.c
@@ -179,7 +179,7 @@ int libgamma_linux_drm_site_restore(libgamma_site_state_t* restrict this)
*/
int libgamma_linux_drm_partition_initialise(libgamma_partition_state_t* restrict this,
libgamma_site_state_t* restrict site, size_t partition)
-{ /* FIXME: This function is too large. */
+{
int rc = 0;
libgamma_drm_card_data_t* data;
char pathname[PATH_MAX];
@@ -372,63 +372,127 @@ int libgamma_linux_drm_crtc_restore(libgamma_crtc_state_t* restrict this)
/**
* Get the size of the gamma ramps for a CRTC
*
- * @param this Instance of a data structure to fill with the information about the CRTC
+ * @param out Instance of a data structure to fill with the information about the CRTC
* @param crtc The state of the CRTC whose information should be read
- * @return The value stored in `this->gamma_size_error`
+ * @return The value stored in `out->gamma_size_error`
*/
-static int get_gamma_ramp_size(libgamma_crtc_information_t* restrict this, libgamma_crtc_state_t* restrict crtc)
+static int get_gamma_ramp_size(libgamma_crtc_information_t* restrict out, const libgamma_crtc_state_t* restrict crtc)
{
libgamma_drm_card_data_t* card = crtc->partition->data;
uint32_t crtc_id = card->res->crtcs[crtc->crtc];
drmModeCrtc* crtc_info;
errno = 0;
crtc_info = drmModeGetCrtc(card->fd, crtc_id);
- this->gamma_size_error = crtc_info == NULL ? errno : 0;
- if (this->gamma_size_error == 0)
+ out->gamma_size_error = crtc_info == NULL ? errno : 0;
+ if (out->gamma_size_error == 0)
{
- this->red_gamma_size = (size_t)(crtc_info->gamma_size);
- this->green_gamma_size = (size_t)(crtc_info->gamma_size);
- this->blue_gamma_size = (size_t)(crtc_info->gamma_size);
- this->gamma_size_error = crtc_info->gamma_size < 2 ? LIBGAMMA_SINGLETON_GAMMA_RAMP : 0;
+ out->red_gamma_size = (size_t)(crtc_info->gamma_size);
+ out->green_gamma_size = (size_t)(crtc_info->gamma_size);
+ out->blue_gamma_size = (size_t)(crtc_info->gamma_size);
+ out->gamma_size_error = crtc_info->gamma_size < 2 ? LIBGAMMA_SINGLETON_GAMMA_RAMP : 0;
drmModeFreeCrtc(crtc_info);
}
- return this->gamma_size_error;
+ return out->gamma_size_error;
}
-static int read_connector_data(libgamma_crtc_information_t* restrict this,
- drmModeConnector* connector, int32_t fields)
+/**
+ * Read information from the CRTC's conncetor
+ *
+ * @param out Instance of a data structure to fill with the information about the CRTC
+ * @param connector The CRTC's connector
+ * @param fields OR:ed identifiers for the information about the CRTC that should be read
+ * @return Non-zero if at least on error occured
+ */
+static int read_connector_data(libgamma_crtc_information_t* restrict out, const drmModeConnector* connector, int32_t fields)
{
+ const char* connector_name_base = NULL;
+
if (connector == NULL)
- {
- this->width_mm_error = this->height_mm_error = this->connector_type = this->active =
- this->active_error = this->connector_name = LIBGAMMA_CONNECTOR_UNKNOWN;
- return LIBGAMMA_CONNECTOR_UNKNOWN;
- }
+ return out->width_mm_error = out->height_mm_error = out->connector_type = out->subpixel_order_error =
+ out->active_error = out->connector_name_error = LIBGAMMA_CONNECTOR_UNKNOWN;
- if ((fields & (CRTC_INFO_WIDTH_MM | CRTC_INFO_HEIGHT_MM | CRTC_INFO_CONNECTOR_TYPE | CRTC_INFO_ACTIVE)))
+ /* Get some information that does not require too much work. */
+ if ((fields & (CRTC_INFO_WIDTH_MM | CRTC_INFO_HEIGHT_MM | CRTC_INFO_CONNECTOR_TYPE |
+ CRTC_INFO_ACTIVE | CRTC_INFO_SUBPIXEL_ORDER)))
{
- this->width_mm = connector->mmWidth;
- this->height_mm = connector->mmHeight;
- this->connector_type = (int)(connector->connector_type); /* TODO: needs abstraction */
- this->active = connector->connection == DRM_MODE_CONNECTED;
- this->active_error = connector->connection == DRM_MODE_UNKNOWNCONNECTION ? LIBGAMMA_STATE_UNKNOWN : 0;
+ /* Get viewport dimension. */
+ out->width_mm = connector->mmWidth;
+ out->height_mm = connector->mmHeight;
+
+ /* Get connector type. */
+#define __select(incase, type, name) \
+ case incase: out->connector_type = LIBGAMMA_CONNECTOR_TYPE_ ## type, connector_name_base = name; break
+ switch (connector->connector_type)
+ {
+#ifndef DRM_MODE_CONNECTOR_VIRTUAL
+# define DRM_MODE_CONNECTOR_VIRTUAL 15
+#endif
+#ifndef DRM_MODE_CONNECTOR_DSI
+# define DRM_MODE_CONNECTOR_DSI 16
+#endif
+ __select (DRM_MODE_CONNECTOR_Unknown, Unknown, "Unknown" );
+ __select (DRM_MODE_CONNECTOR_VGA, VGA, "VGA" );
+ __select (DRM_MODE_CONNECTOR_DVII, DVII, "DVI-I" );
+ __select (DRM_MODE_CONNECTOR_DVID, DVID, "DVI-D" );
+ __select (DRM_MODE_CONNECTOR_DVIA, DVIA, "DVI-A" );
+ __select (DRM_MODE_CONNECTOR_Composite, Composite, "Composite");
+ __select (DRM_MODE_CONNECTOR_SVIDEO, SVIDEO, "SVIDEO" );
+ __select (DRM_MODE_CONNECTOR_LVDS, LVDS, "LVDS" );
+ __select (DRM_MODE_CONNECTOR_Component, Component, "Component");
+ __select (DRM_MODE_CONNECTOR_9PinDIN, 9PinDIN, "DIN" );
+ __select (DRM_MODE_CONNECTOR_DisplayPort, DisplayPort, "DP" );
+ __select (DRM_MODE_CONNECTOR_HDMIA, HDMIA, "HDMI-A" );
+ __select (DRM_MODE_CONNECTOR_HDMIB, HDMIB, "HDMI-B" );
+ __select (DRM_MODE_CONNECTOR_TV, TV, "TV" );
+ __select (DRM_MODE_CONNECTOR_eDP, eDP, "eDP" );
+ __select (DRM_MODE_CONNECTOR_VIRTUAL, VIRTUAL, "VIRTUAL" );
+ __select (DRM_MODE_CONNECTOR_DSI, DSI, "DSI" );
+ default:
+ out->connector_type_error = LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED;
+ out->connector_name_error = LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED;
+ break;
+ }
+#undef __select
+
+ /* Get subpixel order. */
+#define __select(value) \
+ case DRM_MODE_SUBPIXEL_ ## value: out->subpixel_order = LIBGAMMA_SUBPIXEL_ORDER_ ## value; break
+ switch (connector->subpixel)
+ {
+ __select (UNKNOWN);
+ __select (HORIZONTAL_RGB);
+ __select (HORIZONTAL_BGR);
+ __select (VERTICAL_RGB);
+ __select (VERTICAL_BGR);
+ __select (NONE);
+ default:
+ out->subpixel_order_error = LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED;
+ break;
+ }
+#undef __select
+
+ /* Get whether or not a monitor is plugged in. */
+ out->active = connector->connection == DRM_MODE_CONNECTED;
+ out->active_error = connector->connection == DRM_MODE_UNKNOWNCONNECTION ? LIBGAMMA_STATE_UNKNOWN : 0;
}
- if ((fields & CRTC_INFO_CONNECTOR_NAME))
+ /* Get the connector's name. */
+ if ((fields & CRTC_INFO_CONNECTOR_NAME) && (out->connector_name_error == 0))
{
- static const char* TYPE_NAMES[] = /* FIXME: What names does Linux itself use? */
+ out->connector_name = malloc((strlen(connector_name_base) + 12) * sizeof(char));
+ if (out->connector_name == NULL)
+ out->connector_name_error = errno;
+ else
{
- "Unknown", "VGA", "DVII", "DVID", "DVIA", "Composite", "SVIDEO", "LVDS", "Component",
- "9PinDIN", "DisplayPort", "HDMIA", "HDMIB", "TV", "eDP", "VIRTUAL", "DSI"
- };
- this->connector_name = (size_t)(this->connector_type) < sizeof(TYPE_NAMES) / sizeof(char*)
- ? TYPE_NAMES[(size_t)(this->connector_type)] : "Unrecognised" /*TODO:error*/;
- /* FIXME : add index */
+ sprintf(out->connector_name, "%s", connector_name_base);
+ /* FIXME : add index */
+ }
}
- return 0;
+ /* Did something go wrong? */
+ return out->subpixel_order_error | out->active_error | out->connector_name_error;
}
@@ -463,14 +527,13 @@ int libgamma_linux_drm_get_crtc_information(libgamma_crtc_information_t* restric
/* Figure out whether we require the connector to get all information we want. */
require_connector = fields & (CRTC_INFO_WIDTH_MM | CRTC_INFO_HEIGHT_MM |
- CRTC_INFO_SUBPIXEL_ORDER/*(?)*/ | CRTC_INFO_CONNECTOR_TYPE);
+ CRTC_INFO_SUBPIXEL_ORDER | CRTC_INFO_CONNECTOR_TYPE);
e |= this->edid_error = _E(CRTC_INFO_EDID); /* TODO */
e |= this->width_mm_edid_error = _E(CRTC_INFO_WIDTH_MM_EDID); /* TODO */
e |= this->height_mm_edid_error = _E(CRTC_INFO_HEIGHT_MM_EDID); /* TODO */
e |= this->gamma_error = _E(CRTC_INFO_GAMMA); /* TODO */
e |= require_connector ? read_connector_data(this, connector, fields) : 0;
- e |= this->subpixel_order_error = _E(CRTC_INFO_SUBPIXEL_ORDER); /* TODO */
e |= (fields & CRTC_INFO_GAMMA_SIZE) ? get_gamma_ramp_size(this, crtc) : 0;
this->gamma_depth = 16;
e |= this->gamma_support_error = _E(CRTC_INFO_GAMMA_SUPPORT);
@@ -550,7 +613,7 @@ int libgamma_linux_drm_crtc_set_gamma_ramps(libgamma_crtc_state_t* restrict this
case ENODEV:
case ENXIO:
/* XXX: I have not actually tested removing my graphics card or,
- * monitor but I imagine either of these is what would happen. */
+ * monitor but I imagine either of these is what would happen. */
return LIBGAMMA_GRAPHICS_CARD_REMOVED;
default:
diff --git a/src/libgamma-error.h b/src/libgamma-error.h
index ddb71d2..ba8ec86 100644
--- a/src/libgamma-error.h
+++ b/src/libgamma-error.h
@@ -169,6 +169,16 @@ extern const char* libgamma_group_name;
*/
#define LIBGAMMA_CONNECTOR_UNKNOWN (-25)
+/**
+ * The detected connector type is not listed in this library and has to be updated
+ */
+#define LIBGAMMA_CONNECTOR_TYPE_NOT_RECOGNISED (-26)
+
+/**
+ * The detected subpixel order is not listed in this library and has to be updated
+ */
+#define LIBGAMMA_SUBPIXEL_ORDER_NOT_RECOGNISED (-27)
+
#endif
diff --git a/src/libgamma-facade.c b/src/libgamma-facade.c
index 3ef4e71..9f95c50 100644
--- a/src/libgamma-facade.c
+++ b/src/libgamma-facade.c
@@ -786,10 +786,12 @@ int libgamma_get_crtc_information(libgamma_crtc_information_t* restrict this,
libgamma_crtc_state_t* restrict crtc, int32_t fields)
{
#ifdef HAVE_NO_GAMMA_METHODS
- (void) this;
(void) fields;
#endif
+ this->edid = NULL;
+ this->connector_name = NULL;
+
switch (crtc->partition->site->method)
{
#ifdef HAVE_GAMMA_METHOD_DUMMY
diff --git a/src/libgamma-method.h b/src/libgamma-method.h
index 58b364d..c1b58b2 100644
--- a/src/libgamma-method.h
+++ b/src/libgamma-method.h
@@ -315,6 +315,73 @@ typedef struct libgamma_crtc_state
} libgamma_crtc_state_t;
+/**
+ * Types for connectors
+ */
+typedef enum libgamma_connector_type
+ {
+ /*
+ * The adjustment method does not know the connector's type
+ * (This could be considered an error)
+ */
+ LIBGAMMA_CONNECTOR_TYPE_Unknown,
+ LIBGAMMA_CONNECTOR_TYPE_VGA,
+ LIBGAMMA_CONNECTOR_TYPE_DVII,
+ LIBGAMMA_CONNECTOR_TYPE_DVID,
+ LIBGAMMA_CONNECTOR_TYPE_DVIA,
+ LIBGAMMA_CONNECTOR_TYPE_Composite,
+ LIBGAMMA_CONNECTOR_TYPE_SVIDEO,
+ LIBGAMMA_CONNECTOR_TYPE_LVDS,
+ LIBGAMMA_CONNECTOR_TYPE_Component,
+ LIBGAMMA_CONNECTOR_TYPE_9PinDIN,
+ LIBGAMMA_CONNECTOR_TYPE_DisplayPort,
+ LIBGAMMA_CONNECTOR_TYPE_HDMIA,
+ LIBGAMMA_CONNECTOR_TYPE_HDMIB,
+ LIBGAMMA_CONNECTOR_TYPE_TV,
+ LIBGAMMA_CONNECTOR_TYPE_eDP,
+ LIBGAMMA_CONNECTOR_TYPE_VIRTUAL,
+ LIBGAMMA_CONNECTOR_TYPE_DSI
+ } libgamma_connector_type_t;
+
+/**
+ * Orders for subpixels. Currently the possible values are
+ * very biased to LCD, Plasma and monochrome monitors.
+ */
+typedef enum libgamma_subpixel_order
+ {
+ /**
+ * The adjustment method does not know the order of the subpixels
+ * (This could be considered an error)
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_UNKNOWN,
+
+ /**
+ * There are no subpixels in the monitor
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_NONE,
+
+ /**
+ * The subpixels are ordered red, green and then blue, from left to right
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_RGB,
+
+ /**
+ * The subpixels are ordered blue, green and then red, from left to right
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_HORIZONTAL_BGR,
+
+ /**
+ * The subpixels are ordered red, green and then blue, from the top down
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_RGB,
+
+ /**
+ * The subpixels are ordered blue, green and then red, from the top down
+ */
+ LIBGAMMA_SUBPIXEL_ORDER_VERTICAL_BGR
+
+ } libgamma_subpixel_order_t;
+
/**
* For a `libgamma_crtc_information_t` fill in the
@@ -554,10 +621,10 @@ typedef struct libgamma_crtc_information
/**
* The layout of the subpixels.
- * You cannot count on this value, but it is provided
- * anyway as a means of distinguishing monitors.
+ * You cannot count on this value — especially for CRT:s —
+ * but it is provided anyway as a means of distinguishing monitors.
*/
- int subpixel_order;
+ libgamma_subpixel_order_t subpixel_order;
/**
* Zero on success, positive it holds the value `errno` had
@@ -598,7 +665,7 @@ typedef struct libgamma_crtc_information
/**
* The type of the connector that is associated with the CRTC
*/
- int connector_type;
+ libgamma_connector_type_t connector_type;
/**
* Zero on success, positive it holds the value `errno` had