diff options
author | libdlo <libdlo@displaylink.com> | 2009-05-29 09:15:45 -0700 |
---|---|---|
committer | libdlo <libdlo@displaylink.com> | 2009-05-29 09:15:45 -0700 |
commit | f5673eb2765d72718b961ae76899e37932a89fe0 (patch) | |
tree | 88e54be831506710164ffbab737a33cf3c022590 | |
parent | 1c47e4dbe05ea5b2a153b1c584a6ac23b50d7218 (diff) |
Clean up those pesky newlines to ease patching, etc.
-rw-r--r-- | src/dlo_base.h | 114 | ||||
-rw-r--r-- | src/dlo_data.h | 1414 | ||||
-rw-r--r-- | src/dlo_defs.h | 316 | ||||
-rw-r--r-- | src/dlo_grfx.c | 1686 | ||||
-rw-r--r-- | src/dlo_grfx.h | 186 | ||||
-rw-r--r-- | src/dlo_mode.c | 1852 | ||||
-rw-r--r-- | src/dlo_mode.h | 254 | ||||
-rw-r--r-- | src/dlo_structs.h | 184 | ||||
-rw-r--r-- | src/dlo_usb.c | 1122 | ||||
-rw-r--r-- | src/dlo_usb.h | 268 | ||||
-rw-r--r-- | src/exported_symbols | 28 | ||||
-rw-r--r-- | src/libdlo.c | 1786 | ||||
-rw-r--r-- | src/libdlo.h | 1500 |
13 files changed, 5355 insertions, 5355 deletions
diff --git a/src/dlo_base.h b/src/dlo_base.h index 3ce2ba4..c515ec0 100644 --- a/src/dlo_base.h +++ b/src/dlo_base.h @@ -1,57 +1,57 @@ -/** @file dlo_base.h
- *
- * @brief Global header file for the core functions of libdlo.
- *
- * This file defines anything which is not a part of the API that libdlo publishes
- * up to software using the library (in libdlo.h). It is intended that any functions,
- * variables and structures defined herein are only for internal use by the libdlo
- * sources.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DLO_BASE_H
-#define DLO_BASE_H /**< Avoid multiple inclusion. */
-
-#include "dlo_structs.h"
-
-
-/** Claim and initialise a new device structure.
- *
- * @param type Device type.
- * @param serial Pointer to serial number string for the device (assumed to be unique to each device).
- *
- * @return Pointer to new @a dlo_device_t structure or NULL if failed.
- */
-extern dlo_device_t *dlo_new_device(const dlo_devtype_t type, const char * const serial);
-
-
-/** Given a unique ID for a device, see if we have it in our device list @a dev_list.
- *
- * @param serial Pointer to serial number string for the device (assumed to be unique to each device).
- *
- * @return Pointer to @a dlo_device_t structure or NULL if not in @a dev_list.
- *
- * A side-effect of this call is to update the @a dev->check variable to the current value
- * of @a check_state so that any devices on @a dev_list which weren't added or looked-up by
- * the end of an enumeration call can be spotted.
- */
-extern dlo_device_t *dlo_device_lookup(const char * const serial);
-
-
-#endif
+/** @file dlo_base.h + * + * @brief Global header file for the core functions of libdlo. + * + * This file defines anything which is not a part of the API that libdlo publishes + * up to software using the library (in libdlo.h). It is intended that any functions, + * variables and structures defined herein are only for internal use by the libdlo + * sources. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef DLO_BASE_H +#define DLO_BASE_H /**< Avoid multiple inclusion. */ + +#include "dlo_structs.h" + + +/** Claim and initialise a new device structure. + * + * @param type Device type. + * @param serial Pointer to serial number string for the device (assumed to be unique to each device). + * + * @return Pointer to new @a dlo_device_t structure or NULL if failed. + */ +extern dlo_device_t *dlo_new_device(const dlo_devtype_t type, const char * const serial); + + +/** Given a unique ID for a device, see if we have it in our device list @a dev_list. + * + * @param serial Pointer to serial number string for the device (assumed to be unique to each device). + * + * @return Pointer to @a dlo_device_t structure or NULL if not in @a dev_list. + * + * A side-effect of this call is to update the @a dev->check variable to the current value + * of @a check_state so that any devices on @a dev_list which weren't added or looked-up by + * the end of an enumeration call can be spotted. + */ +extern dlo_device_t *dlo_device_lookup(const char * const serial); + + +#endif diff --git a/src/dlo_data.h b/src/dlo_data.h index dd7fa90..231e847 100644 --- a/src/dlo_data.h +++ b/src/dlo_data.h @@ -1,707 +1,707 @@ -/** @file dlo_data.h
- *
- * @brief Hard-wired screen mode-related data blocks.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DLO_DLODATA_H
-#define DLO_DLODATA_H /**< Avoid multiple inclusion. */
-
-
-/** Screen mode 640x480 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_640_480_60_24_0 "" \
- "\x79\x7C\xAD\x97\xAD\xFE\x4B\xDE\x1A\x2F\xA2\x94\x2C\xD5\xD3\x5C"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_640_480_60_24_0 "" \
- "\xE5\xDF\xC0\x52\x4F\xE1\xE6\xB4\xE3\xED\xC4\x21\x5E\x56\xC2\x53" \
- "\x35\x1C\xE8\xF2\xDF\xEF\x7F\x37\xF5\xA5\x4B\x56\xEB\xED\x34\x7B" \
- "\xFB\x89\xA3\x17\xE4\x69\xFF\x39\xD2\xAE\x09\xB6\xC0\xBE\x4D\xBC" \
- "\x84\x6D\x99\xDA\x6B\x28\xBD\xE1\x0E\xC2\xDD\xB0\xDB\x63\xAE\x27" \
- "\x17\x9C\xD6\xD8\xCC\xC5\x44\xFD\x1C\xEF\x49\x9B\xE8\x69\x69\xCA" \
- "\xA5\x9E\xC5\x6B\xF9\x71\xC1\x1B\x8F\x8C\x41\x6B\xC4\xBE\x2A\x6F" \
- "\x56\x82\x37\xC8\x83\x92\x27\x20\x08\x62\x76\x24\x41\xEE\x38\x33" \
- "\x20\x5C\xAA\xA7\x04\x95\xFA\x8F\xE9\xBA\xEE\xD4\x6C\x8F\x82\x42" \
- "\x4E\x0F\xB3\xFC\x5D\x25\x9D\x33\xB4\x6F\xBF\x54\xB7\xEB\x16\xF3" \
- "\xE9\x7C"
-
-/** Screen mode 640x480 (at 73 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_640_480_73_24_0 "" \
- "\xA7\xA6\x78\x54\xA4\xC3\x33\xBF\xF3\xD5\x53\x1F\xAA\x27\x7B\x91"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_640_480_73_24_0 "" \
- "\x61\x1A\x38\x7B\x68\x45\x20\x90\x34\x5D\x1D\x6C\x9D\xC4\xA6\x0E" \
- "\xA3\xEA\x7F\xD9\x70\xAD\xE5\x53\xBE\xB4\x0B\xEC\xB5\xE4\xA1\xAC" \
- "\x5D\x7D\x06\x9A\x97\xE8\x3D\xFC\x7E\x81\x02\x07\xB1\x30\xC1\xAB" \
- "\x9C\xC3\x08\xEA\x79\xAA\xBD\x8F\xC1\x2B\xAA\x69\xD5\x17\xF3\x60" \
- "\x3B\x9F\x86\x86\x2C\x88\x02\x3F\x60\xF4\xA9\xFC\xD6\x8D\x41\x2E" \
- "\xDE\x64\x6F\xA2\x1F\x33\xB2\x76\x95\xF9\x89\xCC\x71\xEC\x00\x5E" \
- "\xFC\x9F\xC6\x32\xE3\xAB\x8D\xCA\xC6\x3D\xC9\x4E\xD2\xD5\x83\x7B" \
- "\x2F\x0C\x78\xE7\x3E\xE3\xEE\xD6\xCB\x95\x54\x02\x83\x46\x01\x78" \
- "\x1B\x33\xF7\x12\x47\x16\x05\xAF\x99\x56\x87\xF9\xFA\x3F\x93\x0C" \
- "\x79\xA6"
-
-/** Screen mode 640x480 (at 75 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_640_480_75_24_0 "" \
- "\xBC\xD1\x26\x61\x95\x59\x20\x88\x2E\x73\xA7\xD9\x9A\x22\x6A\xFB"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_640_480_75_24_0 "" \
- "\xAA\xCE\xFB\xD4\xC3\x07\xC1\xBF\xAD\xA3\xEF\xA9\x2B\x77\xBD\x5D" \
- "\x03\xBE\x67\xF4\x99\xA1\xA3\x53\x25\x5B\x50\x6D\x0C\x3A\xA7\x4C" \
- "\xB0\x86\x04\x60\x01\x8C\xED\xBC\x5A\xF9\x3A\x0E\x1B\x10\xFF\x55" \
- "\x8B\x23\xAC\xDE\xEA\xB2\x2E\x8B\x02\x4E\xF1\x67\x9C\x85\x5D\x3B" \
- "\xE1\xC1\xAC\x3B\x26\xE2\xC3\x13\x25\xF4\xCC\xBC\xF0\xD9\x1F\x27" \
- "\x0C\xF0\x42\x6C\x18\x3B\x20\xC6\x29\xD7\x6C\x0A\x4B\xDC\x44\x3C" \
- "\x46\xDB\x6E\x78\xEB\xAB\x7A\xF5\x63\xE2\xAD\x77\x03\xA0\x9F\xCB" \
- "\x22\x4D\x03\x66\x0B\xF8\xE7\x26\xA4\x15\xF4\xF9\x13\xE7\x14\x97" \
- "\xF1\x98\xD0\x8B\x4E\xDB\xA5\xC6\x4E\x74\x19\x2C\xB2\x97\x55\xA4" \
- "\x0E\x61"
-
-/** Screen mode 640x480 (at 85 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_640_480_85_24_0 "" \
- "\x6D\x0D\x6A\x02\x66\x8A\x8A\x94\xFD\x31\x6D\x98\x53\xD7\x93\x25"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_640_480_85_24_0 "" \
- "\xC6\x8C\x42\x4C\x95\xDA\xB4\x2F\xBD\xD9\x9E\x7C\x8F\x7B\x69\xA8" \
- "\x1B\xDA\x06\x96\x23\x9E\x94\xE2\xC2\xE9\xBB\xD3\x13\x6B\x9B\x21" \
- "\xC1\x4E\xD8\x3F\x81\x49\x6E\xD1\xAF\xB2\x4E\x8C\x24\x1A\xA8\xB6" \
- "\x4E\x11\x75\xB3\xE6\xC9\x3D\x36\x9A\xCC\x3B\xAA\x1F\xC4\x97\xD5" \
- "\x4A\x9D\xAA\xE0\x04\xF0\xB6\x2C\xBD\xE4\x41\x19\xF8\xA2\x77\x7C" \
- "\x46\x9D\x3A\xBD\x73\xC0\x64\x70\x84\x2B\xD7\x11\xF3\x43\xB5\xFB" \
- "\xE9\x0B\xB3\x4B\x2B\x80\x98\xEF\xDC\xDA\x46\xD6\xEC\xBD\x0B\x4D" \
- "\x64\x20\xF7\x17\x17\x33\x75\xB5\x30\x26\xDD\x0A\xA0\x99\x23\x11" \
- "\xF1\xDE\x80\xB0\xD6\xB0\xB7\x5A\xA9\xBD\x6D\x29\x42\x74\x75\x73" \
- "\xC5\x27"
-
-/** Screen mode 720x400 (at 70 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_720_400_70_24_0 "" \
- "\x9C\xC5\x1C\x02\x4F\xA6\x97\x4D\xD7\x04\xE5\x2A\xDC\x78\x4F\x24"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_720_400_70_24_0 "" \
- "\xC4\x2C\x84\x13\xDD\xB8\x82\xCB\x62\xA3\x40\xFA\x41\x8B\x5E\x1B" \
- "\x74\x02\x11\xDD\x90\xB8\x14\x51\xE1\x28\x7E\x3B\x42\x6A\x6B\x9C" \
- "\x7E\x4B\xFC\x8A\x19\x8D\xF4\x23\xB4\x98\x96\x55\x68\x8F\xDA\x88" \
- "\x9C\xE0\x20\x5D\xB5\x9F\x34\x9B\xB2\xCF\x10\x6B\x2D\x66\x63\x0B" \
- "\xDE\x3C\xC4\x90\x3C\xB4\x23\xF9\x5C\x93\x6F\x43\x29\x20\x54\x90" \
- "\x94\xB8\x78\xED\x33\xC7\xDD\x8B\xAA\xD0\xF6\xDC\x78\xEB\x50\x23" \
- "\x83\x00\x6F\x42\x83\x58\xD7\x1C\xA0\xDF\x41\x9E\x69\xB5\xA4\x3A" \
- "\x31\x79\xCB\xDF\x59\x5E\x76\xFB\x89\x32\x2B\x00\xE5\xDF\x16\x52" \
- "\x4F\xE1\xCC\xB7\xE3\xED\xEE\xC1\x5E\x56\xDF\x4E\x35\x1C\x14\x99" \
- "\xDF\x6F"
-
-/** Screen mode 720x400 (at 85 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_720_400_85_24_0 "" \
- "\x4E\xEB\x46\x9D\x91\xDD\xEA\x68\xE2\xCF\x92\xBE\x47\xE1\xE2\x7C"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_720_400_85_24_0 "" \
- "\xE6\x20\x16\xD8\xFE\x44\x88\xBF\x44\x7B\xBE\x98\xA3\xC9\x56\x4E" \
- "\xBC\x98\x6B\x8B\xCD\x50\xB0\xB8\x4D\x95\x32\xF7\xB8\xDE\x45\x3D" \
- "\x87\xD4\x13\xBF\x42\xE6\xC5\x86\x4E\x9D\xD7\x11\xD6\x1F\x1E\x11" \
- "\x55\x5E\xD5\x2E\xFE\x02\xD4\xB0\xDC\x10\xA0\x45\x44\x00\x2E\x0B" \
- "\x4C\x7B\x47\x1B\x06\x16\x20\x18\x6D\xED\x65\xC9\xC0\x11\xDD\x76" \
- "\x78\x8E\x2D\x5D\xD7\x5E\xF7\x6E\x17\x75\x14\x74\xA8\x4D\xFC\x6F" \
- "\x47\x50\x69\x15\x01\x3D\x92\xF5\x1D\xF6\x03\x4A\x89\xC5\x2D\x1E" \
- "\x3A\xBB\x25\x83\x3A\xFD\x72\xBD\xA2\x96\x61\x84\x45\x5F\x19\x21" \
- "\xB5\xBC\x3A\xF4\x7E\xFA\xBF\x0A\x5E\x82\xC8\xF6\x26\x4D\xA4\x06" \
- "\xD9\x97"
-
-/** Screen mode 800x480 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_800_480_60_24_0 "" \
- "\x7A\x12\x36\x0B\xEF\x21\x74\xD1\xF0\x06\x8F\x38\xE8\x71\xB4\xCE"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_800_480_60_24_0 "" \
- "\x78\x67\x19\xF3\xB3\xD6\x5D\x7B\x4C\xCA\x26\x78\x41\x19\x19\xAC" \
- "\xFF\x38\xB3\x10\x71\x89\x6A\xEC\xA8\xC1\x4F\x1F\x77\x86\x5D\x7E" \
- "\xCE\xAF\x65\x7D\xFC\x30\x51\x67\x1F\x48\x30\x8E\x7A\x4B\x8A\xD4" \
- "\xCB\x62\x45\x58\x5C\x22\x1D\x56\x6E\x2F\x60\xE2\x06\x6D\xA1\xE3" \
- "\x82\x5F\x67\x95\x7A\x9F\x87\x43\xD8\x33\xEF\x0B\x5A\xDA\x09\x4F" \
- "\xD7\x25\x6F\xBC\xF8\xC7\x09\x9C\x12\xC3\xA7\x6F\xE7\xED\xA8\x70" \
- "\x8C\xB9\x65\x53\xDD\xA6\x7D\xDE\xD9\x4F\xDD\xD4\x6F\x28\xD6\x14" \
- "\xDC\x2D\x41\x53\x33\xD9\x0A\x86\x11\x3C\x41\x5A\x56\x48\xF9\x85" \
- "\x2B\x2F\x22\x66\x20\x39\xDA\xA1\x50\xCB\x5A\x58\x7D\x97\xFA\x2C" \
- "\x64\x9D"
-
-/** Screen mode 800x600 (at 56 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_800_600_56_24_0 "" \
- "\x19\xFC\x59\x09\x1D\xCD\xDA\x0D\xD3\x6A\x45\xBB\xDB\xF9\x8A\x57"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_800_600_56_24_0 "" \
- "\xD7\x63\xD3\x78\x60\xAC\x0F\xFE\xF5\x0A\xC7\xF0\x17\x0E\x9C\x6C" \
- "\x47\xFF\xF5\x36\xFD\xDE\x22\xE6\xA1\x80\x4F\x0D\x90\x72\xE6\xAD" \
- "\x49\x95\x4B\xD4\x6A\x31\xF9\x6E\x6F\x6E\x93\xF5\x44\x46\x7A\x84" \
- "\xD4\x10\x51\x7A\xE1\xDF\x48\x32\x9D\x0E\x59\xD9\x0B\x57\x45\x7C" \
- "\x58\xF6\x72\x8D\xAF\x91\x7F\xBE\xE8\x2F\x3A\x7F\x3D\xF5\xD6\x39" \
- "\x1E\xB8\xB2\x1D\x7F\x6F\x60\xBC\x0F\xF8\xAD\x43\x76\xFA\x75\x19" \
- "\xFB\x5D\xA4\xCD\xF7\x38\x5F\x11\xD4\x56\x11\x9E\x79\xB4\x4A\x4D" \
- "\x7A\xC7\x03\xAC\xFB\xB4\x4F\x98\x93\xB0\xDC\xE2\x8F\xE9\x05\xB2" \
- "\x90\xE0\x8D\x41\xC2\xAF\xC5\xEE\x8B\x00\x90\x7C\x26\x87\x54\x4A" \
- "\x71\x2A"
-
-/** Screen mode 800x600 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_800_600_60_24_0 "" \
- "\x02\x18\xF5\x1F\xE5\xCF\x2C\xB9\x39\x72\x74\x15\x6B\xFE\x6C\x71"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_800_600_60_24_0 "" \
- "\xC0\x2C\xFF\x8C\x0F\x57\x30\xD7\x8A\x19\xCE\xB2\x47\x2B\xE3\xFA" \
- "\xEE\x8F\x95\xF7\xA7\x78\x44\x39\x29\x78\xF4\x0C\xB7\x3F\xF8\xD4" \
- "\xFA\xAD\x2C\xB8\xF2\x1C\xBB\x16\x10\xCC\xF5\xD5\x53\x6C\x2E\x4E" \
- "\xEF\xB5\xF5\x81\x0A\xE1\x8F\x32\xC5\xB9\x96\xAB\x8C\xC2\xE3\xA7" \
- "\x32\x14\x76\xD5\x63\xC1\x8E\xD6\xCF\x95\x1B\x0C\x51\xA9\x88\xEB" \
- "\xF3\x89\x40\xB7\x41\xB6\x87\x10\x03\xDB\x09\xFE\xCD\xFF\x2A\x7C" \
- "\xB1\x76\x8C\x27\x04\xA8\x09\x3B\x9E\x63\xDE\xE0\x31\xC8\x9B\x5E" \
- "\x1E\x51\x5A\xB3\x1B\xE7\xEE\xAE\x54\x47\xBB\xF0\x9F\xAE\xBB\xF6" \
- "\x43\x35\x57\xAE\x87\x8C\x88\x8B\x61\x61\x47\xA9\x87\xF7\xC3\x86" \
- "\x8E\x53"
-
-/** Screen mode 800x600 (at 72 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_800_600_72_24_0 "" \
- "\x81\x59\xC0\x67\x29\xEC\x20\x62\x5E\x94\x77\xCA\x93\xE3\x3B\xA5"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_800_600_72_24_0 "" \
- "\x3B\xD9\x26\xBF\xB4\xE3\x00\x22\x87\x3D\xCD\xDE\x26\x6E\x71\x13" \
- "\x15\x22\xFB\xA0\x3F\x4B\xE1\x33\xED\x36\x15\x71\x8E\xB6\x3A\xE5" \
- "\x69\x27\xF8\x8E\xBA\x43\x42\xC3\xB8\x6F\x25\xCD\xC0\xDB\x35\xE6" \
- "\xD0\x33\x02\xF8\xFF\x05\x73\x60\x06\x50\x6D\xB0\xF5\x86\x68\xC3" \
- "\x27\xD8\xB4\x63\x88\x6D\x0E\x55\x1C\x18\x76\xDF\x37\x0D\x50\x62" \
- "\xD0\x82\x75\x66\xB8\x0A\x40\x2D\x94\x85\xB1\x04\x44\x1E\xD1\xCA" \
- "\xF7\x97\xD8\x21\x28\xB5\xBE\x91\xC5\xC2\x1F\x48\x63\x70\xED\x4F" \
- "\x88\x9A\x02\xD0\xC3\x7C\x7A\x6A\x42\x11\xD7\xEA\x91\xF9\xCE\xAC" \
- "\xA3\x03\x8E\xBE\x14\x25\x74\x4B\xE5\x0B\x37\xEA\x5C\xB0\xA9\xD5" \
- "\xE5\x95"
-
-/** Screen mode 800x600 (at 75 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_800_600_75_24_0 "" \
- "\x3F\xDB\xEE\x68\xC7\x0E\xCA\x26\xA3\x42\xF0\x36\x25\x2B\xDB\x48"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_800_600_75_24_0 "" \
- "\xB5\x2E\xA8\x75\xF5\xC0\x36\xD8\xBF\xB3\xA8\x4F\x6F\xA4\x68\x06" \
- "\xEC\xFB\x44\x53\xFC\x4B\xC2\x44\xF0\xFA\x20\x47\xC0\xC5\xDE\xB1" \
- "\x6B\xDF\x89\x24\xD1\xA6\xE1\x86\xAE\x7F\x19\xA5\x56\xE7\x52\xBC" \
- "\xD7\xCC\xAF\xED\x9C\x4F\xAF\x77\x49\x7C\x99\xA9\x0E\xB9\x41\xAE" \
- "\x34\xD1\xB3\x33\xAD\x12\x91\xFC\x6C\x78\x85\xD5\x91\x6B\xB2\x1E" \
- "\x28\x39\x15\x41\xF5\x14\x35\x9E\xAC\xE2\x0C\x9C\x69\x5C\x76\x86" \
- "\x55\xF1\x41\x36\x02\xE1\x6C\xAA\x60\x66\xE4\x1F\x5D\xB7\xED\x16" \
- "\x3F\x55\x21\x57\x56\xDA\xB3\x00\xA0\x15\x8F\x26\xC1\x08\xA6\x8B" \
- "\x19\x22\x5E\xD2\x48\x7B\x18\xA6\xD4\xF9\x9D\xD4\x85\x57\x05\xD9" \
- "\xC6\x31"
-
-/** Screen mode 800x600 (at 85 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_800_600_85_24_0 "" \
- "\x51\x11\x2B\x19\x1F\xF6\x3F\xC2\x38\x2F\xF8\x5D\x5A\xD3\xA6\x0D"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_800_600_85_24_0 "" \
- "\x87\x1E\x1B\x28\xEA\x5B\xFA\xAB\x66\xC6\x43\x53\xC7\x3A\x77\xF4" \
- "\x08\x95\x51\x50\x9E\x8A\x19\x38\x55\x40\x3C\x31\x45\xEE\x59\xBA" \
- "\xF2\xB3\x3C\xFD\xEC\x2F\x58\xED\xEF\x1A\x7F\xDB\xF6\x02\x25\xCA" \
- "\x79\xCF\xC2\x7C\x95\x75\x30\xBB\x41\x3A\x3E\x27\x33\x0D\x37\x48" \
- "\x02\x6D\xDB\x86\x50\xB0\xCA\xAA\x92\x25\x08\xB7\xDE\x93\x51\x87" \
- "\xC0\x57\x8C\xA1\xE0\xE5\x38\xC1\x30\x97\x82\x6B\xE7\x96\x37\xA5" \
- "\x63\x0B\x79\xB8\x67\x28\x25\x60\x79\xF2\x1D\x98\xE2\xAC\x2E\x1B" \
- "\x1C\x7D\x3C\x9B\x63\x53\xFD\x73\x44\xAF\x8D\xDE\xB0\x98\xCD\x6E" \
- "\xBA\x60\x48\xC2\x74\x5A\x8E\x9A\xB3\x3F\x9A\x2B\x28\x42\x66\x93" \
- "\x1A\x26"
-
-/** Screen mode 848x480 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_848_480_60_24_0 "" \
- "\x06\x53\xBC\x25\x49\xFB\xE8\x81\x2A\xE0\xDF\x85\xB4\x85\x92\x4C"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_848_480_60_24_0 "" \
- "\x27\x9E\x14\x5B\x10\x06\x0C\xE8\xFB\xD1\x12\x84\xC7\xEE\x60\x2E" \
- "\x1B\xC4\xE1\xE0\x98\x72\x13\xE1\xEC\x4A\x2D\xC2\xBB\x44\xEB\xCC" \
- "\x62\x2F\xE6\xC1\x71\x5D\x71\xD9\xBB\x90\xF3\xCC\x71\x7E\x5B\x71" \
- "\x77\xA5\x78\xCF\x02\x9A\xE7\xDF\x8F\xD4\xEE\xCF\xE7\x39\xA7\x75" \
- "\x9F\xE8\xCD\xCE\xDB\x5E\x7F\x61\x60\x45\xC6\x97\x91\x82\x6A\xFD" \
- "\x4C\xB1\xAB\xAA\xAE\xAB\x13\x92\x45\xB6\xFD\x8F\xD1\x34\xB8\x34" \
- "\x25\x45\xA5\xD7\xB7\xD6\x3E\x05\x9E\x25\x8E\xC5\xA9\xA3\x89\xC7" \
- "\xF9\x98\x2E\xB6\xEB\x04\xCE\x79\x9F\x01\x3F\x3C\xBF\xD6\xF8\xDA" \
- "\x3B\xFA\xDB\xA1\x78\xD6\xA2\x3D\xF4\xD9\x69\x37\xDE\x1F\x1C\x70" \
- "\xF0\x01"
-
-/** Screen mode 1024x768 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1024_768_60_24_0 "" \
- "\xB6\xF8\xFC\x00\xF3\xE4\x81\x1E\xC5\x60\xA3\x79\xE5\x35\xC5\x15"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1024_768_60_24_0 "" \
- "\xDD\x2A\x3A\x49\xE9\x99\xE3\xC8\xA0\xBA\x23\x3A\x3D\xEB\x21\xE4" \
- "\xA5\x54\x25\x0D\x51\xCC\xE6\x52\xA7\xD7\xCD\xFA\xD5\x9B\x5B\x41" \
- "\x0B\x49\xAB\xC6\xE3\x1A\xF2\x87\x81\x32\xF0\x3E\x40\x00\x51\x40" \
- "\x9E\x94\xF1\x22\xEE\xAC\xB2\xA2\x6B\x4D\xC4\x41\x5A\x9C\x45\x62" \
- "\x4F\x4E\x61\xDB\x1F\x0E\x79\x66\xE2\x20\x83\x9E\x2C\xAB\x28\x38" \
- "\xAC\xC1\x22\x81\xA5\x69\xFD\xFB\x26\x15\xF9\xC9\xFA\x90\xF2\x66" \
- "\x85\xC5\xAA\xA6\x4D\x8B\xC8\xA6\x03\x32\xDF\x98\xA9\x77\x9E\x57" \
- "\xEA\xC9\x9E\x29\xED\xFC\xC4\x78\x26\x0B\x2E\xC2\x41\x7C\x4A\xA3" \
- "\xAB\x66\x01\xA0\xE5\xA4\x8B\x80\xA0\x53\xE5\x5D\x59\x63\x62\xE8" \
- "\xFE\x6B"
-
-/** Screen mode 1024x768 (at 70 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1024_768_70_24_0 "" \
- "\x2B\x71\x0C\x1F\x55\x8E\x3D\x1A\xEE\xE0\x93\xD4\x15\x58\xE9\x00"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1024_768_70_24_0 "" \
- "\xE9\x15\xBC\xBE\x90\x6C\x07\x34\xF2\x79\xCA\x43\x44\x92\x65\x9A" \
- "\xC7\x41\xE9\x56\xE7\x27\x4A\x9C\x24\x04\x40\x97\xF5\xFD\xFF\x99" \
- "\xC8\x6A\xA0\xF3\x32\xE3\x4E\x40\xBC\xA5\xAE\x37\xBA\x89\xB0\xDD" \
- "\x10\xD2\x10\x76\xE8\x80\xAF\x15\xC1\x16\x65\x80\xA2\xCE\xFD\x14" \
- "\x66\xD8\xAA\x83\x7C\xD6\xE2\xF2\x26\x36\xD5\xF2\x36\xA5\x7F\x4D" \
- "\xF6\x21\x14\x58\xB5\xFA\x54\x07\xE6\x91\x93\xB9\xB9\x4B\xB5\x0C" \
- "\xD6\xAE\x6C\x2D\x12\x51\xED\x13\x6C\xD7\x07\x15\x6D\x88\x10\x62" \
- "\x94\x4F\x77\xB7\xEC\xA3\xD4\xAD\xDF\xCC\x76\x2D\x39\x90\xEE\xB1" \
- "\x98\x09\xA2\x28\x03\xF8\x1F\x1C\x01\xCA\xAA\xC0\xC2\x92\xDE\xD8" \
- "\xFC\x59"
-
-/** Screen mode 1024x768 (at 75 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1024_768_75_24_0 "" \
- "\x10\xFC\xF8\x65\x8A\x35\x80\x78\x15\x13\x4C\x2A\x6C\x35\x2B\x74"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1024_768_75_24_0 "" \
- "\xE6\xB2\x51\x5B\x75\x7E\x2A\xBC\xA5\x4A\xC0\xC0\xEA\x20\x67\xCC" \
- "\x89\x74\x5D\x3B\x7D\xB4\x29\x82\xA8\x28\x97\x86\x13\x0E\xE3\xCC" \
- "\x95\x10\x43\x65\x15\x64\xA0\xF9\xA7\x20\xFE\x61\x0A\xFF\x6E\xEC" \
- "\x7E\x55\x17\x4F\xA2\x61\x77\x7E\x9A\x3B\x04\xFF\xC0\xA0\xAE\x82" \
- "\x3F\x81\x1A\xEB\x45\x8B\x37\x99\xA6\xED\xB1\x66\x78\x02\x8C\xB3" \
- "\xE7\x88\xD5\x57\xD8\xE7\xFD\x7F\x49\x8B\xBE\xC6\xD1\xDD\x60\xB5" \
- "\x41\xCD\x1B\x3E\xEC\x69\x18\xE9\x77\x71\x7F\x0E\x11\xCB\x47\x82" \
- "\x89\x2C\xCA\x54\x5E\x33\x9C\x60\x61\x42\x55\xB4\x4B\xC2\x9C\x37" \
- "\xFD\x37\xD4\x47\xC5\x08\xDF\x14\xCB\xCD\xD9\xCD\xA0\xC1\x42\x21" \
- "\xD2\xD9"
-
-/** Screen mode 1024x768 (at 85 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1024_768_85_24_0 "" \
- "\x02\x10\x92\x8C\x45\x12\x05\x5A\x25\x51\x85\x91\x87\xB0\x05\x8C"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1024_768_85_24_0 "" \
- "\xA7\xC9\xD0\x6E\x6E\x77\xDA\xD3\x25\xEA\x3B\xA4\x4B\x35\x88\x4E" \
- "\x22\x53\xC4\x82\xB0\x14\x40\x54\x8A\xB6\x42\xF2\xBB\xC8\x4B\x24" \
- "\x52\xF9\xC3\x37\xBE\xCF\x99\x01\x5A\x56\xB2\xA8\xE7\xF3\x53\x7B" \
- "\x37\x55\xFE\x97\xF3\x05\xFF\xC0\x71\x60\xBB\xD9\xCC\x49\xFA\x73" \
- "\x2C\x39\x72\x25\x27\xFB\x83\x7D\x44\x58\x86\x5D\x6F\xFC\xCF\xD4" \
- "\xCF\x7C\xC1\x33\x35\x21\x30\x70\xA8\x36\x60\xBB\xA8\xE2\x74\x05" \
- "\xBB\xB3\xC5\x60\xBD\x4B\xC0\x6C\x04\x41\xD2\xE6\xFA\xEB\x67\x02" \
- "\x6A\x77\x82\x4D\xF7\x05\xAC\xA8\xA3\x8F\x21\xCA\x24\xF3\x53\x52" \
- "\x2A\x99\xEA\xE5\xBD\x76\x3C\x85\x73\x98\xD8\x46\xA7\xAC\xA8\xB7" \
- "\x3A\xA9"
-
-/** Screen mode 1152x864 (at 75 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1152_864_75_24_0 "" \
- "\xAE\xFE\x44\xF3\x10\x49\x4E\x35\x9B\xD3\xC7\x22\x83\xCC\xAE\x40"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1152_864_75_24_0 "" \
- "\x65\xB5\xCB\x8E\x46\x49\x3E\xFB\x60\x91\xC1\x32\x82\xD3\xCA\x2F" \
- "\x4A\x49\xB1\xA8\x17\xA1\x12\x37\xBB\x1C\x5F\x69\x41\xA8\x72\xB2" \
- "\xB8\x37\x9C\x7E\xE3\x5C\xA2\xD3\x19\x59\xE2\x75\xA7\xC9\x25\xBB" \
- "\x6E\x77\xD1\x2D\x25\xEA\x36\x43\x4B\x35\x87\xB3\x22\x53\xC9\xB5" \
- "\xB0\x14\x4B\x1D\x8A\xB6\x57\x78\xBB\xC8\x5C\x3B\x52\xF9\xD6\x3C" \
- "\xBE\xCF\x82\xCB\x5A\x56\xAF\x2E\xE7\xF3\x4C\x85\x37\x55\xE3\x91" \
- "\xF3\x05\xE4\x3C\x71\x60\xAE\xB6\xCC\x49\xEF\x6A\x2C\x39\x61\x75" \
- "\x27\xFB\xB0\x7D\x44\x58\xB3\x32\x6F\xFC\xF8\xBF\xCF\x7C\xFB\xCC" \
- "\x35\x21\x0E\x8B\xA8\x36\x5E\xC4\xA8\xE2\x7D\xFC\xBB\xB3\x2D\x9C" \
- "\xBD\xCB"
-
-/** Screen mode 1280x768 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1280_768_60_24_0 "" \
- "\x73\x9D\x25\x83\xE6\x73\xB8\x81\x46\x7F\xA3\xC9\x4C\x52\x09\xB4"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1280_768_60_24_0 "" \
- "\xB0\x52\xEB\x22\x12\xDD\x55\x65\x5C\x01\x38\xD9\xA2\x1A\xE6\x1F" \
- "\x75\x89\x16\x6E\x7A\x2E\xFC\x28\x9F\x3C\xD0\xE6\xC8\x0F\xD9\xCE" \
- "\x66\xBD\xDA\xE1\x28\x88\x61\x5B\xB2\x1B\x03\x5B\x3E\x37\xD7\x54" \
- "\xD8\xC4\xCA\xBC\x85\xBE\x2E\x50\xA2\x39\xC1\xB1\xB9\xBC\x92\xA9" \
- "\x09\xCA\x4D\xFA\x67\x4D\x55\x1E\x2D\xAC\x8C\xBB\x76\x81\xEE\xEE" \
- "\x14\xEF\xBC\xD8\x4D\xB6\x0B\xB0\x74\xEB\xDF\xDB\xF4\x30\xB8\xF2" \
- "\xBA\x97\x4A\x67\xAB\x3E\x84\x6B\xC6\x23\x2E\x3A\x69\x39\x04\x67" \
- "\x01\xAF\xEE\xE6\x96\xCC\x9E\xFF\x68\xF4\x6A\x0F\x73\x52\x1E\x0A" \
- "\x0F\x11\x4A\xE8\x12\x72\xF6\x0E\xA0\xE2\x8A\xC3\x1E\x6C\x49\xA5" \
- "\x6C\xBE"
-
-/** Screen mode 1280x1024 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1280_1024_60_24_0 "" \
- "\x6A\xF0\x37\x50\x63\xEF\xD2\xA9\x6F\x75\x72\xBB\xC7\x7B\x6F\x1A"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1280_1024_60_24_0 "" \
- "\x23\x4A\x78\x7C\xD1\xB8\x0E\x6B\x15\x93\x96\x77\x78\x44\xCC\x16" \
- "\x7F\xE3\xD7\x39\x3F\x2E\x99\xD2\xB9\x68\x8E\xC4\x1A\x9B\xF4\x35" \
- "\x61\xB5\x48\x5C\x94\xA6\x84\xB2\x88\x2B\x47\x84\x84\x73\x7F\x2C" \
- "\xD0\xC4\x3D\x5D\x20\x61\x4A\xB1\x73\x4C\xDD\x6A\xB4\xFD\xE9\x94" \
- "\x3C\xD1\x44\x0A\x08\xCD\xF5\xE5\xBD\x0D\x99\xCD\x9C\x2A\xC9\x06" \
- "\x1D\x22\x1C\xB1\x9A\x94\x95\x65\x3C\x43\x19\x73\x83\xF7\x51\x1F" \
- "\x5C\x3C\xE1\x59\xD5\xC3\xF2\x27\x28\xCE\x22\x7B\x2A\x70\x04\xE4" \
- "\xD9\xFE\x8A\x6E\x28\x27\xC5\x40\x4E\xF8\x83\x5B\x82\x41\xA6\x62" \
- "\xC1\x73\x3A\x5C\xF6\x90\x43\x39\xF2\xF5\x74\x80\x74\x44\xBD\xB1" \
- "\x08\x53"
-
-/** Screen mode 1280x1024 (at 75 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1280_1024_75_24_0 "" \
- "\xDB\xCF\xE1\x3F\xBE\xB3\xE8\x2D\x29\x5B\xE8\xF0\xD6\x57\x0B\xFF"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1280_1024_75_24_0 "" \
- "\xBA\x89\x45\x90\x10\xD2\x1B\x50\xE8\x80\xA2\xE9\xC1\x16\x6A\x6D" \
- "\xA2\xCE\xF0\xD4\x66\xD8\xA1\x18\x7C\xD6\xF7\xD8\x26\x36\xC2\x7E" \
- "\x36\xA5\x6A\x9A\xF6\x21\x0F\xF3\xB5\xFA\x49\x07\xE6\x91\x8C\x4B" \
- "\xB9\x4B\xA8\x0C\xD6\xAE\x77\xD1\x12\x51\xF8\x21\x6C\xD7\x12\xED" \
- "\x6D\x88\x03\x5D\x94\x4F\x44\xB7\xEC\xA3\xE1\x3F\xDF\xCC\x41\x85" \
- "\x39\x90\xD4\x4E\x98\x09\x9C\xD3\x03\xF8\x21\xE3\x01\xCA\xA3\x39" \
- "\xC2\x92\x36\x23\xFC\xD9\x99\x08\x7B\xC0\x9C\xCE\x21\xF4\xBA\xBE" \
- "\x22\x36\x9C\xB4\xE4\x4A\xFB\xC1\x1E\x9B\xAC\xFF\xB3\x5A\xD4\x0D" \
- "\x7C\x1C\x28\xBB\x8E\x8B\xD8\x8E\x1E\xFE\xEE\xD9\xE7\x04\x99\x20" \
- "\xE8\xB1"
-
-/** Screen mode 1280x1024 (at 85 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1280_1024_85_24_0 "" \
- "\xE4\xE9\xAF\xA2\x9D\x98\xD0\xC6\xF3\xB8\xB6\xC9\x10\xC1\xC8\xA6"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1280_1024_85_24_0 "" \
- "\x93\xB0\x06\xA2\x8F\xE9\x2C\xB3\x90\xE0\xA6\x66\xC2\xAF\xEC\x00" \
- "\x8B\x00\x8C\x0B\x26\x87\xAF\x8A\x71\xAA\x43\x0F\x64\xF4\xC5\xF3" \
- "\x04\x62\xE6\x7A\x36\xDE\xFA\x1A\x19\x93\x12\xD1\x0F\x74\x12\xAF" \
- "\x46\x2C\x4D\x23\x34\xCF\x57\x3B\x16\xFE\x0B\xDC\x42\xDB\x0C\x80" \
- "\x39\x44\xDF\x0C\x8B\x58\x28\xB3\x05\x00\x2F\xB9\xB8\xC0\xB6\xA1" \
- "\x3C\x38\x80\xA1\x6C\x45\x4F\xF1\xE6\xB2\xBB\xA4\x75\x7E\x3C\x44" \
- "\xA5\x4A\xD6\x28\xEA\x20\x7D\x78\x89\x74\x45\x97\x7D\xB4\x31\xB5" \
- "\xA8\x28\xB1\xB0\x13\x0E\xC1\xCC\x95\x10\x61\x62\x15\x64\x81\x4A" \
- "\xA7\x20\xDD\x3A\x0A\xFF\x4F\x39\x7E\x55\x03\xB0\xA2\x61\x84\x7E" \
- "\x9A\xBB"
-
-/** Screen mode 1280x768 (at 75 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1280_768_75_24_0 "" \
- "\x87\x94\x88\x24\x2C\x58\xEA\x1F\x10\xA1\xE9\x20\x62\xB1\xC6\x43"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1280_768_75_24_0 "" \
- "\x20\x5C\x76\xA7\x04\x95\xDE\x8B\xE9\xBA\xCA\x66\x6C\x8F\xA9\x5B" \
- "\x4E\x0F\x9A\xCA\x5D\x25\xB2\x6C\xB4\x6F\xA5\xE4\xB7\xEB\xEF\x58" \
- "\xE9\xFC\x9C\xD2\xF4\xE4\xB1\x47\xA9\xC6\xE4\xF6\xAD\xC6\x9C\x38" \
- "\x7F\x29\x2F\x59\x97\x93\xA6\x07\x91\x33\x1A\x1F\x0B\xBE\x9D\xE7" \
- "\x3C\x7E\xCC\x60\xF4\x2E\x59\x92\x01\x7B\xCB\xB2\x85\x9D\x18\xA7" \
- "\x6E\x0C\x56\xFF\xCA\x58\x32\xAB\xF1\xBB\xC7\x6B\x82\xEE\x11\x9C" \
- "\x3D\x90\xAB\x2D\x4A\xE6\x22\x30\xEB\x42\xA1\xA6\x07\x6A\x14\x4F" \
- "\x58\x1F\x86\xDF\xCB\x19\xF5\x7F\xB3\x90\x28\x41\xD4\xA1\x1C\x1B" \
- "\xA6\xD0\x45\x85\x0F\xDB\xBB\xA1\xBA\xCF\xF5\xAB\x88\xB9\xF6\x32" \
- "\x0F\xC9"
-
-/** Screen mode 1280x768 (at 85 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1280_768_85_24_0 "" \
- "\x74\xE4\x58\xA1\x3C\x43\xC0\x4D\xE4\xA9\x6D\x46\x5B\x34\x89\xE5"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1280_768_85_24_0 "" \
- "\x5B\xA6\xDC\x6E\xE2\xD7\xAD\xE3\xF3\xCF\x02\x6D\xD9\xDD\x83\xEB" \
- "\xE4\x12\x6B\xC6\x3D\x1C\x18\x54\x7A\x30\x1A\x0C\x24\xD0\x54\x05" \
- "\xE6\xAC\x4E\x76\xCE\x92\xA5\x1D\x8B\xE9\x5E\x53\x42\x0F\x1F\x9C" \
- "\x2A\x15\x6B\xB1\x8D\xA0\x3E\x8E\xBC\x0A\x22\xB2\x46\x6A\x18\x18" \
- "\xAC\xA4\x46\x5D\xF1\x37\x62\xE3\xB2\x38\x33\xFD\xF2\x02\x46\xF2" \
- "\xAB\x20\x68\x60\x7D\xCF\xA6\xE3\x47\x9A\x9B\xA7\xA9\x80\xAB\x54" \
- "\x35\xAD\x93\xFB\x98\xE0\x48\x7D\x67\x70\x91\x3B\x5A\x75\x8F\x97" \
- "\x2B\xC6\xF3\x34\x44\xB1\x6B\x60\x0B\x74\x46\x54\x94\xC3\xDD\xC0" \
- "\xDC\x75\xFF\x99\x10\x5E\x90\x26\xD8\x56\x99\x1E\x0E\x84\x7F\x8B" \
- "\x43\x88"
-
-/** Screen mode 1280x800 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1280_800_60_24_0 "" \
- "\x59\xFF\xC3\x96\x42\x84\xE3\x26\x2D\x50\x6C\x88\x84\xF6\x6E\x2A"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1280_800_60_24_0 "" \
- "\x55\x5E\x21\x5E\xFE\x02\xD8\x84\xDC\x10\xAC\xF6\x44\x00\x22\x46" \
- "\x4C\x7B\x4B\xCC\x06\x16\x34\xFC\x6D\xED\x71\x58\xC0\x11\xC9\xA4" \
- "\x78\x8E\x39\xC3\xD7\x5E\xEB\x67\x17\x75\x08\x14\xA8\x4D\xE0\x5C" \
- "\x47\x50\x75\x35\x01\x3D\x86\x42\x1D\xF6\x15\x09\x89\xC5\x3F\xFA" \
- "\x3A\xBB\x09\x86\x3A\xFD\x46\xB8\xA2\x96\x55\x2B\x45\x5F\x22\x94" \
- "\xB5\xBC\x03\x09\x7E\xFA\x80\x25\x5E\x82\xC2\x09\x26\x4D\x4D\x33" \
- "\xD9\x17\x66\x3C\x4C\xAF\x47\x81\x15\x47\x9B\x39\x6B\x15\x62\x30" \
- "\x79\x1B\xFD\x3B\x86\x24\xA8\xD1\x47\xC2\x1C\x97\x8A\x07\x01\x66" \
- "\xFC\xC7\x4C\xF9\xC0\x2C\x2B\x8C\x0F\x57\x2F\xD6\x8A\x19\x30\x6D" \
- "\x47\xAB"
-
-/** Screen mode 1280x960 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1280_960_60_24_0 "" \
- "\x42\xAB\xE3\x84\x2F\xC6\xAA\x5D\x17\x17\xE5\x9B\x0D\x53\xC5\xA6"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1280_960_60_24_0 "" \
- "\x3D\xAD\x8C\xC7\x3D\x3F\x34\x45\xB6\x05\x97\xE1\x57\x34\xEA\x4E" \
- "\x1E\xDD\xDA\x98\x2B\x31\xEB\xEF\x9B\xD5\x73\xB1\x7E\x68\xD5\xCC" \
- "\xD5\xB8\x72\xBD\xC7\x7C\x2D\x07\x90\xFE\x49\xD7\x79\x43\x63\x49" \
- "\xA5\xA3\x12\x82\x8E\xA8\xD7\x6C\xD2\xCB\x75\x03\x94\xE0\xD2\x9E" \
- "\x10\x40\x53\xD7\x63\xBA\x11\x24\x20\x27\x07\xE4\xEB\x27\xD0\x8A" \
- "\x53\x34\x80\x2D\xCC\x32\x7F\x27\xC3\x8B\x74\x36\x9D\x75\xDD\x82" \
- "\xE4\xE5\x40\xA2\xE2\x78\x3D\x48\x0F\x2C\xB4\x64\x65\xAB\xCF\x2E" \
- "\xFD\xA5\x9A\xC0\x4E\x32\x72\x1D\x2A\xFC\x9D\xC7\xE9\x28\xA5\x57" \
- "\xE7\xB5\x23\x44\xAF\x3E\xCC\xF4\x14\xCC\x98\x3A\x81\x83\x69\xFE" \
- "\x07\x8F"
-
-/** Screen mode 1280x960 (at 85 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1280_960_85_24_0 "" \
- "\xF6\x75\x37\x25\x3C\xE1\x82\x53\xF8\x68\xEE\x05\xBB\xB4\xAB\xBC"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1280_960_85_24_0 "" \
- "\x58\x1F\x5A\xDF\xCB\x19\xD1\x74\xB3\x90\x0C\x65\xD4\xA1\x37\xD5" \
- "\xA6\xD0\x6C\xF7\x0F\xDB\x94\x9E\xBA\xCF\xEF\x01\x88\xB9\x0F\x2B" \
- "\x0F\x49\xD0\x81\x31\xF5\x40\x7E\x69\x88\x7E\x59\x46\xA0\xEC\xCF" \
- "\x04\x19\x75\x02\xD9\x6C\xE2\x12\xA3\x1D\x4E\x73\xAF\xC9\xD6\x37" \
- "\xCB\xA8\xB1\xEE\xF4\x9F\x36\x0C\x46\x74\xE0\x54\x17\x48\xDC\xCE" \
- "\xDF\x94\xF7\x1D\x1A\x17\x46\xE8\x51\x63\x7F\xD7\x5B\x34\x72\x14" \
- "\x69\xED\x18\xE2\x12\xFE\x65\xB9\x90\x34\xAB\xFE\xD1\xFE\x42\x25" \
- "\x8D\xF8\xA6\x73\x9F\x8D\x9E\xE1\x8F\x00\xD1\xE3\xF4\x68\x30\xA9" \
- "\x99\x10\xE2\xC7\x62\x54\x55\x6F\x9E\xEF\x7A\xD7\x01\x1E\x5D\x87" \
- "\xD1\x43"
-
-/** Screen mode 1360x768 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1360_768_60_24_0 "" \
- "\x84\x36\xDB\xC0\x18\x5D\x13\x10\xC5\x02\x16\x81\xB6\xC1\x3D\xA6"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1360_768_60_24_0 "" \
- "\x99\xDA\xC7\x8E\xCA\xE9\x49\xCB\xB6\xB4\xF8\x21\x10\x3B\xC1\x42" \
- "\x8C\x08\x1E\x52\x9A\xA9\x4A\x17\x4B\x9A\x07\x0A\xDE\xB0\x6D\x89" \
- "\x0C\x62\x11\x38\x93\x01\x9E\x33\xC8\xE6\x0E\x17\x02\x35\x69\x2B" \
- "\x73\x37\x44\xD3\x5B\x4F\xF7\xC0\x86\x5F\x1E\x9D\xA8\x70\x2B\x3C" \
- "\x30\x89\x7F\x65\x5C\x7A\xB6\x36\x4D\xA8\xE9\xFB\xCF\x07\x5F\x65" \
- "\xDA\x93\x2B\x98\x12\xB8\x39\xBD\x08\x5F\xB7\x99\x36\x37\x3C\x9E" \
- "\x7D\x1B\xB2\xA7\x54\xCB\x26\xC7\xAF\x78\xAC\x03\x8C\xA7\x89\xE4" \
- "\x66\x4A\xC1\x04\xF7\xEC\x74\xFB\xC7\x07\x9F\x81\x7F\x4C\x75\x5E" \
- "\xC3\xCD\x1B\xF7\x05\x1E\xF2\xB7\x03\x2C\x3C\xA4\x12\x9B\xFA\xA0" \
- "\xC4\xEA"
-
-/** Screen mode 1366x768 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1366_768_60_24_0 "" \
- "\x6E\xF3\xC9\x86\x50\xDD\x97\x16\xDF\xAD\x97\x95\x6E\xD4\x3B\x46"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1366_768_60_24_0 "" \
- "\x2A\x70\xE7\xB0\xD9\xFE\xA9\x6F\x28\x27\xE0\x53\x4E\xF8\xA4\x45" \
- "\x82\x41\x8C\x7D\xC1\x73\x14\xE9\xF6\x90\x6D\xAA\xF2\xF5\x6D\xE0" \
- "\x74\x44\x45\x0E\x08\xD3\x0A\x6A\x06\xE1\x06\x5B\xB2\x89\x47\x47" \
- "\xB5\x0D\x74\x4F\x39\xF5\xB3\xA5\xCC\x57\x1E\x01\x97\xD5\xF4\xE4" \
- "\x09\x58\x0A\x79\xEC\x77\xF7\x4B\xCC\x9D\xF2\xB1\x3F\x68\xDF\x67" \
- "\x21\x03\x8A\x8D\xFD\x52\x92\x9A\x91\x56\x7A\x3A\x5F\xE0\x1E\x6D" \
- "\xA8\x53\x1A\x61\xFC\xBC\xE1\x2E\x2F\x9E\x07\xFE\xB5\xD9\x74\x92" \
- "\x2A\xA4\x2C\x08\xCA\xAF\x3D\xFB\x2E\xDF\xCE\xE9\xF7\xF2\x9E\x05" \
- "\x7C\xEB\x17\x1E\x51\xEF\xE1\x09\x6B\xE2\x5E\xD4\xA6\x7F\x18\x15" \
- "\xF3\xB8"
-
-/** Screen mode 1400x1050 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1400_1050_60_24_0 "" \
- "\x95\xCB\x91\xE5\xA8\x28\xFB\x87\xD5\x92\x1C\x44\x66\x57\x8A\x98"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1400_1050_60_24_0 "" \
- "\xC6\x8C\x42\x4C\x95\xDA\xB4\x2F\xBD\xD9\x9E\xAD\x8F\x7B\x69\x15" \
- "\x1B\xDA\x06\x79\x23\x9E\x94\xF2\xC2\xE9\xBB\x34\x13\x6B\x9B\xB2" \
- "\xC1\x4E\xD8\x69\x81\x49\x6E\x64\xAF\xB2\x4E\x69\x24\x1A\xA8\xBB" \
- "\x4E\x11\x75\x38\xE6\xC9\x3D\xE9\x9A\xCC\x3B\xAA\x1F\xC4\x97\xD5" \
- "\x4A\x9D\xAA\xE7\x04\xF0\xB6\xD4\xBD\xE4\x41\xCF\xF8\xA2\x77\x0B" \
- "\x46\x9D\x3A\xBD\x73\xC0\x64\x76\x84\x2B\xD7\x11\xF3\x43\xB5\xF6" \
- "\xE9\x0B\xB3\x4E\x2B\x80\x98\x15\xDC\xDA\x46\xE8\xEC\xBD\x0B\x0E" \
- "\x64\x20\xF7\x17\x17\x33\x75\xBA\x30\x26\xDD\xFA\xA0\x99\x23\x11" \
- "\xF1\xDE\x80\xB7\xD6\xB0\xB7\xA2\xA9\xBD\x6D\x29\x42\x74\x75\x73" \
- "\xC5\x27"
-
-/** Screen mode 1400x1050 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1400_1050_60_24_1 "" \
- "\xCB\xA2\x00\x73\xCB\xFC\xFB\xA0\x8E\x17\xE4\xF5\x6F\x6F\x8D\x1D"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1400_1050_60_24_1 "" \
- "\xDA\x01\x80\xE4\x99\x82\x8F\x40\xE9\x6E\xDD\xA6\x7F\xDE\x19\xFC" \
- "\x48\xF7\x90\x61\xE4\x2F\xA3\x72\x4A\xC5\x17\xBE\x27\x77\x35\x6A" \
- "\x74\x8E\xB5\x45\xA0\x6E\x3D\x58\x2E\xBA\x9A\xB6\xA3\xAC\x26\xD4" \
- "\xE8\xC6\xF8\xE3\x59\x7D\x76\x1C\x45\x07\x8A\x82\x96\x3B\x8B\x45" \
- "\xB7\x90\x79\xDB\x06\x4E\x97\x7F\x4E\x6A\xF0\xE7\x09\x7B\x3F\x05" \
- "\x20\x42\x7D\xAC\xBF\x79\x4D\x42\xC7\x19\x48\x2A\xC4\xA0\xCD\x9B" \
- "\xED\x6E\xB0\xF7\xAD\x31\xB1\xDB\xA0\x4D\x06\x41\xE2\x8F\x06\x63" \
- "\xD0\x48\xB5\xD5\x10\xB7\x47\x7D\xBC\xDE\x1D\x05\x55\x3B\x8F\x78" \
- "\xAA\x5C\x69\x52\x48\x3D\x48\xC5\x4C\x92\x8F\x48\x62\x9E\x71\xDC" \
- "\x36\xD2"
-
-/** Screen mode 1400x1050 (at 75 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1400_1050_75_24_0 "" \
- "\x8E\x2F\xD0\x59\x2B\xCB\xFA\xB9\xE2\xDE\xAE\x51\x4D\x3C\x6E\x4D"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1400_1050_75_24_0 "" \
- "\x25\xF4\x22\x48\xF0\xD9\x0D\xA9\x0C\xF0\x50\x5D\x18\x3B\x36\x2D" \
- "\x29\xD7\x7A\x1D\x4B\xDC\x56\xA2\x46\xDB\x7C\x33\xEB\xAB\x64\xBB" \
- "\x63\xE2\xB1\x4C\x03\xA0\x8B\xBB\x22\x4D\x29\x10\x0B\xF8\xC9\x3F" \
- "\xA4\x15\xDA\xCB\x13\xE7\x31\xF7\xF1\x98\xF7\x76\x4E\xDB\x80\xB9" \
- "\x4E\x74\x09\x29\xB2\x97\xBA\x23\x0E\xE1\xE9\x69\x17\x56\x3B\xD0" \
- "\x64\x78\x70\x27\x34\xB4\xD0\xE9\xF9\x4C\x0F\xF1\xF8\x55\x4C\x12" \
- "\x99\xF9\x07\x97\x06\xDC\xD8\x9E\xC5\x50\x58\x3B\xE8\x4A\x4F\x12" \
- "\x69\xAB\x7C\xDA\x8A\x95\x4B\xEF\x77\xFD\xE1\x0F\x21\x1D\x57\x86" \
- "\x46\xBE\x2B\x5A\xBF\xF5\xD2\xBF\xF7\xCF\x67\xEC\x0B\x32\xCC\x90" \
- "\x0C\x28"
-
-/** Screen mode 1400x1050 (at 85 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1400_1050_85_24_0 "" \
- "\x66\xC2\x92\x91\x8D\x8C\x4A\x6F\x6A\xF9\xC1\xB8\x35\x2F\x05\xD7"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1400_1050_85_24_0 "" \
- "\x73\x98\x38\x46\xA7\xAC\x57\x49\x3A\x29\x40\xA6\xB1\xC7\xF6\xC8" \
- "\x43\xA7\x39\x93\x0C\xB6\x05\xD3\x80\x50\x23\x08\xCE\x1E\x0B\x6B" \
- "\xBB\x3F\x75\xCE\x8D\x9D\xF5\x67\xCB\xD3\x28\x29\x1B\x2D\x30\x40" \
- "\xFC\xFA\xA2\x75\xB7\xF5\x02\xC2\x52\x10\x11\x2A\xDA\x47\x21\x20" \
- "\x01\xE9\x92\xD8\x0E\xA7\xB8\x11\x8F\x3D\x2A\xDB\x83\xB1\x05\x48" \
- "\xC4\x57\xF7\x3E\x32\x0A\x8A\xDD\xD8\x2D\x0C\x33\xE1\x36\x8A\x6E" \
- "\xF9\x86\xFD\x46\x50\xE8\x75\x5F\xB1\xA2\x97\xA1\x17\xF9\xBD\x70" \
- "\x98\x9B\xEC\xAF\x88\xC2\xB2\x15\xE0\xFB\xEE\x3A\x8B\x7B\x39\xAE" \
- "\xC9\x35\x9D\x58\xCB\x24\x35\xE4\xC4\x49\x1C\x35\x89\xE6\xE6\xE7" \
- "\xF6\x0E"
-
-/* DL160 modes... */
-
-/** Screen mode 1600x1200 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1600_1200_60_24_0 "" \
- "\x3C\x79\x81\x0F\xF2\xAB\x85\xC7\x3A\xE8\xEB\xCB\xF3\x32\x12\x9C"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1600_1200_60_24_0 "" \
- "\x85\x2C\x9A\xF4\x29\x03\x6E\x4C\x58\x8D\xE3\x93\x40\x23\x71\xD2" \
- "\x52\xA1\x70\x77\x9D\x48\x00\xDC\x93\x3C\x5C\x80\xBF\x3F\x0F\xF8" \
- "\x5F\x72\x48\x38\x23\x69\xA7\x4A\x1D\x8D\x8E\x55\x66\x77\x27\xBF" \
- "\x80\x35\x55\x7A\x9A\x40\x9A\xDD\x2F\x12\xB1\xFD\x85\x0F\x43\x23" \
- "\xE5\x36\xE8\x05\x2B\x69\x48\x1E\xB8\x52\xF2\xFF\xB7\x02\x23\x0A" \
- "\x8D\x74\x36\xFB\xAF\x5B\x8B\x2D\x40\x92\x09\x17\x15\xAE\x4E\xFF" \
- "\x0F\x9D\xD7\x9E\x22\xA4\xE0\x87\x6F\x70\x66\x58\xFF\xAA\xEB\x8B" \
- "\xFA\xB3\xEF\x84\x49\xF0\x10\xE7\x3E\x6F\x4F\x24\xFB\x43\x7D\x3B" \
- "\x4C\xD4\xEA\x75\xFA\xF5\xB7\xFF\xD1\x9B\x39\x77\xD9\xA6\xE1\x5E" \
- "\x0B\x20"
-
-/** Screen mode 1920x1080 (at 60 Hz, 24 bpp).
- */
-#define DLO_MODE_ENABLE_1920_1080_60_24_0 "" \
- "\xC1\xCA\xC3\xB3\x75\x48\x7A\xAF\x30\x65\x7B\x24\x97\x8D\xC0\x64"
-
-/** Mode data.
- */
-#define DLO_MODE_DATA_1920_1080_60_24_0 "" \
- "\x0D\x58\x81\xE3\x3E\x98\x55\x00\x24\x27\x6C\x99\x39\xC8\x72\xD8" \
- "\xBB\x8E\x1E\xA2\xCA\x92\xD2\xAB\x59\x06\xE0\x65\xAA\xB5\x9D\xAC" \
- "\x2C\xB5\xDA\x17\x17\x2D\xBE\x19\x8B\xCA\x76\x3D\x8E\x3A\x96\x8F" \
- "\x59\xF1\xD1\xA6\x75\xD1\xAE\xB7\x59\xA9\x60\xA4\x56\x56\x39\x8E" \
- "\x90\xC3\x80\x58\x0E\x9A\x77\x00\xF8\xE4\x24\x74\xDE\xF6\x29\x34" \
- "\x94\x09\x17\x73\x74\xC8\xF6\xC0\x38\x05\x32\xD7\xC9\x73\xF1\x99" \
- "\x53\x4F\x1B\x04\x23\x80\x6F\x08\x79\x05\x22\x2F\x3D\xC8\x17\x9D" \
- "\x69\x61\x8C\x96\x22\x28\x7C\x4F\x5F\xA6\x7D\xF1\x30\x38\x36\xFE" \
- "\x1B\x75\xA7\x2C\xDF\x7D\x17\x33\x7E\x9F\xF3\xFC\x0A\xDC\xB3\xDB" \
- "\xB2\xE0"
-
-/** Data to send after a mode change.
- */
-#define DLO_MODE_POSTAMBLE "\x57\xCD\xDC\xA7\x1C\x88\x5E\x15\x60\xFE\xC6\x97\x16\x3D\x47\xF2"
-
-/** Number of entries in the @a dlo_mode_data array.
- */
-#define DLO_MODE_DATA_NUM (35u)
-
-/** Lowest mode number supported by the DL120.
- */
-#define DLO_DL120_MODES (2u)
-
-
-#endif
+/** @file dlo_data.h + * + * @brief Hard-wired screen mode-related data blocks. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef DLO_DLODATA_H +#define DLO_DLODATA_H /**< Avoid multiple inclusion. */ + + +/** Screen mode 640x480 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_640_480_60_24_0 "" \ + "\x79\x7C\xAD\x97\xAD\xFE\x4B\xDE\x1A\x2F\xA2\x94\x2C\xD5\xD3\x5C" + +/** Mode data. + */ +#define DLO_MODE_DATA_640_480_60_24_0 "" \ + "\xE5\xDF\xC0\x52\x4F\xE1\xE6\xB4\xE3\xED\xC4\x21\x5E\x56\xC2\x53" \ + "\x35\x1C\xE8\xF2\xDF\xEF\x7F\x37\xF5\xA5\x4B\x56\xEB\xED\x34\x7B" \ + "\xFB\x89\xA3\x17\xE4\x69\xFF\x39\xD2\xAE\x09\xB6\xC0\xBE\x4D\xBC" \ + "\x84\x6D\x99\xDA\x6B\x28\xBD\xE1\x0E\xC2\xDD\xB0\xDB\x63\xAE\x27" \ + "\x17\x9C\xD6\xD8\xCC\xC5\x44\xFD\x1C\xEF\x49\x9B\xE8\x69\x69\xCA" \ + "\xA5\x9E\xC5\x6B\xF9\x71\xC1\x1B\x8F\x8C\x41\x6B\xC4\xBE\x2A\x6F" \ + "\x56\x82\x37\xC8\x83\x92\x27\x20\x08\x62\x76\x24\x41\xEE\x38\x33" \ + "\x20\x5C\xAA\xA7\x04\x95\xFA\x8F\xE9\xBA\xEE\xD4\x6C\x8F\x82\x42" \ + "\x4E\x0F\xB3\xFC\x5D\x25\x9D\x33\xB4\x6F\xBF\x54\xB7\xEB\x16\xF3" \ + "\xE9\x7C" + +/** Screen mode 640x480 (at 73 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_640_480_73_24_0 "" \ + "\xA7\xA6\x78\x54\xA4\xC3\x33\xBF\xF3\xD5\x53\x1F\xAA\x27\x7B\x91" + +/** Mode data. + */ +#define DLO_MODE_DATA_640_480_73_24_0 "" \ + "\x61\x1A\x38\x7B\x68\x45\x20\x90\x34\x5D\x1D\x6C\x9D\xC4\xA6\x0E" \ + "\xA3\xEA\x7F\xD9\x70\xAD\xE5\x53\xBE\xB4\x0B\xEC\xB5\xE4\xA1\xAC" \ + "\x5D\x7D\x06\x9A\x97\xE8\x3D\xFC\x7E\x81\x02\x07\xB1\x30\xC1\xAB" \ + "\x9C\xC3\x08\xEA\x79\xAA\xBD\x8F\xC1\x2B\xAA\x69\xD5\x17\xF3\x60" \ + "\x3B\x9F\x86\x86\x2C\x88\x02\x3F\x60\xF4\xA9\xFC\xD6\x8D\x41\x2E" \ + "\xDE\x64\x6F\xA2\x1F\x33\xB2\x76\x95\xF9\x89\xCC\x71\xEC\x00\x5E" \ + "\xFC\x9F\xC6\x32\xE3\xAB\x8D\xCA\xC6\x3D\xC9\x4E\xD2\xD5\x83\x7B" \ + "\x2F\x0C\x78\xE7\x3E\xE3\xEE\xD6\xCB\x95\x54\x02\x83\x46\x01\x78" \ + "\x1B\x33\xF7\x12\x47\x16\x05\xAF\x99\x56\x87\xF9\xFA\x3F\x93\x0C" \ + "\x79\xA6" + +/** Screen mode 640x480 (at 75 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_640_480_75_24_0 "" \ + "\xBC\xD1\x26\x61\x95\x59\x20\x88\x2E\x73\xA7\xD9\x9A\x22\x6A\xFB" + +/** Mode data. + */ +#define DLO_MODE_DATA_640_480_75_24_0 "" \ + "\xAA\xCE\xFB\xD4\xC3\x07\xC1\xBF\xAD\xA3\xEF\xA9\x2B\x77\xBD\x5D" \ + "\x03\xBE\x67\xF4\x99\xA1\xA3\x53\x25\x5B\x50\x6D\x0C\x3A\xA7\x4C" \ + "\xB0\x86\x04\x60\x01\x8C\xED\xBC\x5A\xF9\x3A\x0E\x1B\x10\xFF\x55" \ + "\x8B\x23\xAC\xDE\xEA\xB2\x2E\x8B\x02\x4E\xF1\x67\x9C\x85\x5D\x3B" \ + "\xE1\xC1\xAC\x3B\x26\xE2\xC3\x13\x25\xF4\xCC\xBC\xF0\xD9\x1F\x27" \ + "\x0C\xF0\x42\x6C\x18\x3B\x20\xC6\x29\xD7\x6C\x0A\x4B\xDC\x44\x3C" \ + "\x46\xDB\x6E\x78\xEB\xAB\x7A\xF5\x63\xE2\xAD\x77\x03\xA0\x9F\xCB" \ + "\x22\x4D\x03\x66\x0B\xF8\xE7\x26\xA4\x15\xF4\xF9\x13\xE7\x14\x97" \ + "\xF1\x98\xD0\x8B\x4E\xDB\xA5\xC6\x4E\x74\x19\x2C\xB2\x97\x55\xA4" \ + "\x0E\x61" + +/** Screen mode 640x480 (at 85 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_640_480_85_24_0 "" \ + "\x6D\x0D\x6A\x02\x66\x8A\x8A\x94\xFD\x31\x6D\x98\x53\xD7\x93\x25" + +/** Mode data. + */ +#define DLO_MODE_DATA_640_480_85_24_0 "" \ + "\xC6\x8C\x42\x4C\x95\xDA\xB4\x2F\xBD\xD9\x9E\x7C\x8F\x7B\x69\xA8" \ + "\x1B\xDA\x06\x96\x23\x9E\x94\xE2\xC2\xE9\xBB\xD3\x13\x6B\x9B\x21" \ + "\xC1\x4E\xD8\x3F\x81\x49\x6E\xD1\xAF\xB2\x4E\x8C\x24\x1A\xA8\xB6" \ + "\x4E\x11\x75\xB3\xE6\xC9\x3D\x36\x9A\xCC\x3B\xAA\x1F\xC4\x97\xD5" \ + "\x4A\x9D\xAA\xE0\x04\xF0\xB6\x2C\xBD\xE4\x41\x19\xF8\xA2\x77\x7C" \ + "\x46\x9D\x3A\xBD\x73\xC0\x64\x70\x84\x2B\xD7\x11\xF3\x43\xB5\xFB" \ + "\xE9\x0B\xB3\x4B\x2B\x80\x98\xEF\xDC\xDA\x46\xD6\xEC\xBD\x0B\x4D" \ + "\x64\x20\xF7\x17\x17\x33\x75\xB5\x30\x26\xDD\x0A\xA0\x99\x23\x11" \ + "\xF1\xDE\x80\xB0\xD6\xB0\xB7\x5A\xA9\xBD\x6D\x29\x42\x74\x75\x73" \ + "\xC5\x27" + +/** Screen mode 720x400 (at 70 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_720_400_70_24_0 "" \ + "\x9C\xC5\x1C\x02\x4F\xA6\x97\x4D\xD7\x04\xE5\x2A\xDC\x78\x4F\x24" + +/** Mode data. + */ +#define DLO_MODE_DATA_720_400_70_24_0 "" \ + "\xC4\x2C\x84\x13\xDD\xB8\x82\xCB\x62\xA3\x40\xFA\x41\x8B\x5E\x1B" \ + "\x74\x02\x11\xDD\x90\xB8\x14\x51\xE1\x28\x7E\x3B\x42\x6A\x6B\x9C" \ + "\x7E\x4B\xFC\x8A\x19\x8D\xF4\x23\xB4\x98\x96\x55\x68\x8F\xDA\x88" \ + "\x9C\xE0\x20\x5D\xB5\x9F\x34\x9B\xB2\xCF\x10\x6B\x2D\x66\x63\x0B" \ + "\xDE\x3C\xC4\x90\x3C\xB4\x23\xF9\x5C\x93\x6F\x43\x29\x20\x54\x90" \ + "\x94\xB8\x78\xED\x33\xC7\xDD\x8B\xAA\xD0\xF6\xDC\x78\xEB\x50\x23" \ + "\x83\x00\x6F\x42\x83\x58\xD7\x1C\xA0\xDF\x41\x9E\x69\xB5\xA4\x3A" \ + "\x31\x79\xCB\xDF\x59\x5E\x76\xFB\x89\x32\x2B\x00\xE5\xDF\x16\x52" \ + "\x4F\xE1\xCC\xB7\xE3\xED\xEE\xC1\x5E\x56\xDF\x4E\x35\x1C\x14\x99" \ + "\xDF\x6F" + +/** Screen mode 720x400 (at 85 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_720_400_85_24_0 "" \ + "\x4E\xEB\x46\x9D\x91\xDD\xEA\x68\xE2\xCF\x92\xBE\x47\xE1\xE2\x7C" + +/** Mode data. + */ +#define DLO_MODE_DATA_720_400_85_24_0 "" \ + "\xE6\x20\x16\xD8\xFE\x44\x88\xBF\x44\x7B\xBE\x98\xA3\xC9\x56\x4E" \ + "\xBC\x98\x6B\x8B\xCD\x50\xB0\xB8\x4D\x95\x32\xF7\xB8\xDE\x45\x3D" \ + "\x87\xD4\x13\xBF\x42\xE6\xC5\x86\x4E\x9D\xD7\x11\xD6\x1F\x1E\x11" \ + "\x55\x5E\xD5\x2E\xFE\x02\xD4\xB0\xDC\x10\xA0\x45\x44\x00\x2E\x0B" \ + "\x4C\x7B\x47\x1B\x06\x16\x20\x18\x6D\xED\x65\xC9\xC0\x11\xDD\x76" \ + "\x78\x8E\x2D\x5D\xD7\x5E\xF7\x6E\x17\x75\x14\x74\xA8\x4D\xFC\x6F" \ + "\x47\x50\x69\x15\x01\x3D\x92\xF5\x1D\xF6\x03\x4A\x89\xC5\x2D\x1E" \ + "\x3A\xBB\x25\x83\x3A\xFD\x72\xBD\xA2\x96\x61\x84\x45\x5F\x19\x21" \ + "\xB5\xBC\x3A\xF4\x7E\xFA\xBF\x0A\x5E\x82\xC8\xF6\x26\x4D\xA4\x06" \ + "\xD9\x97" + +/** Screen mode 800x480 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_800_480_60_24_0 "" \ + "\x7A\x12\x36\x0B\xEF\x21\x74\xD1\xF0\x06\x8F\x38\xE8\x71\xB4\xCE" + +/** Mode data. + */ +#define DLO_MODE_DATA_800_480_60_24_0 "" \ + "\x78\x67\x19\xF3\xB3\xD6\x5D\x7B\x4C\xCA\x26\x78\x41\x19\x19\xAC" \ + "\xFF\x38\xB3\x10\x71\x89\x6A\xEC\xA8\xC1\x4F\x1F\x77\x86\x5D\x7E" \ + "\xCE\xAF\x65\x7D\xFC\x30\x51\x67\x1F\x48\x30\x8E\x7A\x4B\x8A\xD4" \ + "\xCB\x62\x45\x58\x5C\x22\x1D\x56\x6E\x2F\x60\xE2\x06\x6D\xA1\xE3" \ + "\x82\x5F\x67\x95\x7A\x9F\x87\x43\xD8\x33\xEF\x0B\x5A\xDA\x09\x4F" \ + "\xD7\x25\x6F\xBC\xF8\xC7\x09\x9C\x12\xC3\xA7\x6F\xE7\xED\xA8\x70" \ + "\x8C\xB9\x65\x53\xDD\xA6\x7D\xDE\xD9\x4F\xDD\xD4\x6F\x28\xD6\x14" \ + "\xDC\x2D\x41\x53\x33\xD9\x0A\x86\x11\x3C\x41\x5A\x56\x48\xF9\x85" \ + "\x2B\x2F\x22\x66\x20\x39\xDA\xA1\x50\xCB\x5A\x58\x7D\x97\xFA\x2C" \ + "\x64\x9D" + +/** Screen mode 800x600 (at 56 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_800_600_56_24_0 "" \ + "\x19\xFC\x59\x09\x1D\xCD\xDA\x0D\xD3\x6A\x45\xBB\xDB\xF9\x8A\x57" + +/** Mode data. + */ +#define DLO_MODE_DATA_800_600_56_24_0 "" \ + "\xD7\x63\xD3\x78\x60\xAC\x0F\xFE\xF5\x0A\xC7\xF0\x17\x0E\x9C\x6C" \ + "\x47\xFF\xF5\x36\xFD\xDE\x22\xE6\xA1\x80\x4F\x0D\x90\x72\xE6\xAD" \ + "\x49\x95\x4B\xD4\x6A\x31\xF9\x6E\x6F\x6E\x93\xF5\x44\x46\x7A\x84" \ + "\xD4\x10\x51\x7A\xE1\xDF\x48\x32\x9D\x0E\x59\xD9\x0B\x57\x45\x7C" \ + "\x58\xF6\x72\x8D\xAF\x91\x7F\xBE\xE8\x2F\x3A\x7F\x3D\xF5\xD6\x39" \ + "\x1E\xB8\xB2\x1D\x7F\x6F\x60\xBC\x0F\xF8\xAD\x43\x76\xFA\x75\x19" \ + "\xFB\x5D\xA4\xCD\xF7\x38\x5F\x11\xD4\x56\x11\x9E\x79\xB4\x4A\x4D" \ + "\x7A\xC7\x03\xAC\xFB\xB4\x4F\x98\x93\xB0\xDC\xE2\x8F\xE9\x05\xB2" \ + "\x90\xE0\x8D\x41\xC2\xAF\xC5\xEE\x8B\x00\x90\x7C\x26\x87\x54\x4A" \ + "\x71\x2A" + +/** Screen mode 800x600 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_800_600_60_24_0 "" \ + "\x02\x18\xF5\x1F\xE5\xCF\x2C\xB9\x39\x72\x74\x15\x6B\xFE\x6C\x71" + +/** Mode data. + */ +#define DLO_MODE_DATA_800_600_60_24_0 "" \ + "\xC0\x2C\xFF\x8C\x0F\x57\x30\xD7\x8A\x19\xCE\xB2\x47\x2B\xE3\xFA" \ + "\xEE\x8F\x95\xF7\xA7\x78\x44\x39\x29\x78\xF4\x0C\xB7\x3F\xF8\xD4" \ + "\xFA\xAD\x2C\xB8\xF2\x1C\xBB\x16\x10\xCC\xF5\xD5\x53\x6C\x2E\x4E" \ + "\xEF\xB5\xF5\x81\x0A\xE1\x8F\x32\xC5\xB9\x96\xAB\x8C\xC2\xE3\xA7" \ + "\x32\x14\x76\xD5\x63\xC1\x8E\xD6\xCF\x95\x1B\x0C\x51\xA9\x88\xEB" \ + "\xF3\x89\x40\xB7\x41\xB6\x87\x10\x03\xDB\x09\xFE\xCD\xFF\x2A\x7C" \ + "\xB1\x76\x8C\x27\x04\xA8\x09\x3B\x9E\x63\xDE\xE0\x31\xC8\x9B\x5E" \ + "\x1E\x51\x5A\xB3\x1B\xE7\xEE\xAE\x54\x47\xBB\xF0\x9F\xAE\xBB\xF6" \ + "\x43\x35\x57\xAE\x87\x8C\x88\x8B\x61\x61\x47\xA9\x87\xF7\xC3\x86" \ + "\x8E\x53" + +/** Screen mode 800x600 (at 72 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_800_600_72_24_0 "" \ + "\x81\x59\xC0\x67\x29\xEC\x20\x62\x5E\x94\x77\xCA\x93\xE3\x3B\xA5" + +/** Mode data. + */ +#define DLO_MODE_DATA_800_600_72_24_0 "" \ + "\x3B\xD9\x26\xBF\xB4\xE3\x00\x22\x87\x3D\xCD\xDE\x26\x6E\x71\x13" \ + "\x15\x22\xFB\xA0\x3F\x4B\xE1\x33\xED\x36\x15\x71\x8E\xB6\x3A\xE5" \ + "\x69\x27\xF8\x8E\xBA\x43\x42\xC3\xB8\x6F\x25\xCD\xC0\xDB\x35\xE6" \ + "\xD0\x33\x02\xF8\xFF\x05\x73\x60\x06\x50\x6D\xB0\xF5\x86\x68\xC3" \ + "\x27\xD8\xB4\x63\x88\x6D\x0E\x55\x1C\x18\x76\xDF\x37\x0D\x50\x62" \ + "\xD0\x82\x75\x66\xB8\x0A\x40\x2D\x94\x85\xB1\x04\x44\x1E\xD1\xCA" \ + "\xF7\x97\xD8\x21\x28\xB5\xBE\x91\xC5\xC2\x1F\x48\x63\x70\xED\x4F" \ + "\x88\x9A\x02\xD0\xC3\x7C\x7A\x6A\x42\x11\xD7\xEA\x91\xF9\xCE\xAC" \ + "\xA3\x03\x8E\xBE\x14\x25\x74\x4B\xE5\x0B\x37\xEA\x5C\xB0\xA9\xD5" \ + "\xE5\x95" + +/** Screen mode 800x600 (at 75 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_800_600_75_24_0 "" \ + "\x3F\xDB\xEE\x68\xC7\x0E\xCA\x26\xA3\x42\xF0\x36\x25\x2B\xDB\x48" + +/** Mode data. + */ +#define DLO_MODE_DATA_800_600_75_24_0 "" \ + "\xB5\x2E\xA8\x75\xF5\xC0\x36\xD8\xBF\xB3\xA8\x4F\x6F\xA4\x68\x06" \ + "\xEC\xFB\x44\x53\xFC\x4B\xC2\x44\xF0\xFA\x20\x47\xC0\xC5\xDE\xB1" \ + "\x6B\xDF\x89\x24\xD1\xA6\xE1\x86\xAE\x7F\x19\xA5\x56\xE7\x52\xBC" \ + "\xD7\xCC\xAF\xED\x9C\x4F\xAF\x77\x49\x7C\x99\xA9\x0E\xB9\x41\xAE" \ + "\x34\xD1\xB3\x33\xAD\x12\x91\xFC\x6C\x78\x85\xD5\x91\x6B\xB2\x1E" \ + "\x28\x39\x15\x41\xF5\x14\x35\x9E\xAC\xE2\x0C\x9C\x69\x5C\x76\x86" \ + "\x55\xF1\x41\x36\x02\xE1\x6C\xAA\x60\x66\xE4\x1F\x5D\xB7\xED\x16" \ + "\x3F\x55\x21\x57\x56\xDA\xB3\x00\xA0\x15\x8F\x26\xC1\x08\xA6\x8B" \ + "\x19\x22\x5E\xD2\x48\x7B\x18\xA6\xD4\xF9\x9D\xD4\x85\x57\x05\xD9" \ + "\xC6\x31" + +/** Screen mode 800x600 (at 85 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_800_600_85_24_0 "" \ + "\x51\x11\x2B\x19\x1F\xF6\x3F\xC2\x38\x2F\xF8\x5D\x5A\xD3\xA6\x0D" + +/** Mode data. + */ +#define DLO_MODE_DATA_800_600_85_24_0 "" \ + "\x87\x1E\x1B\x28\xEA\x5B\xFA\xAB\x66\xC6\x43\x53\xC7\x3A\x77\xF4" \ + "\x08\x95\x51\x50\x9E\x8A\x19\x38\x55\x40\x3C\x31\x45\xEE\x59\xBA" \ + "\xF2\xB3\x3C\xFD\xEC\x2F\x58\xED\xEF\x1A\x7F\xDB\xF6\x02\x25\xCA" \ + "\x79\xCF\xC2\x7C\x95\x75\x30\xBB\x41\x3A\x3E\x27\x33\x0D\x37\x48" \ + "\x02\x6D\xDB\x86\x50\xB0\xCA\xAA\x92\x25\x08\xB7\xDE\x93\x51\x87" \ + "\xC0\x57\x8C\xA1\xE0\xE5\x38\xC1\x30\x97\x82\x6B\xE7\x96\x37\xA5" \ + "\x63\x0B\x79\xB8\x67\x28\x25\x60\x79\xF2\x1D\x98\xE2\xAC\x2E\x1B" \ + "\x1C\x7D\x3C\x9B\x63\x53\xFD\x73\x44\xAF\x8D\xDE\xB0\x98\xCD\x6E" \ + "\xBA\x60\x48\xC2\x74\x5A\x8E\x9A\xB3\x3F\x9A\x2B\x28\x42\x66\x93" \ + "\x1A\x26" + +/** Screen mode 848x480 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_848_480_60_24_0 "" \ + "\x06\x53\xBC\x25\x49\xFB\xE8\x81\x2A\xE0\xDF\x85\xB4\x85\x92\x4C" + +/** Mode data. + */ +#define DLO_MODE_DATA_848_480_60_24_0 "" \ + "\x27\x9E\x14\x5B\x10\x06\x0C\xE8\xFB\xD1\x12\x84\xC7\xEE\x60\x2E" \ + "\x1B\xC4\xE1\xE0\x98\x72\x13\xE1\xEC\x4A\x2D\xC2\xBB\x44\xEB\xCC" \ + "\x62\x2F\xE6\xC1\x71\x5D\x71\xD9\xBB\x90\xF3\xCC\x71\x7E\x5B\x71" \ + "\x77\xA5\x78\xCF\x02\x9A\xE7\xDF\x8F\xD4\xEE\xCF\xE7\x39\xA7\x75" \ + "\x9F\xE8\xCD\xCE\xDB\x5E\x7F\x61\x60\x45\xC6\x97\x91\x82\x6A\xFD" \ + "\x4C\xB1\xAB\xAA\xAE\xAB\x13\x92\x45\xB6\xFD\x8F\xD1\x34\xB8\x34" \ + "\x25\x45\xA5\xD7\xB7\xD6\x3E\x05\x9E\x25\x8E\xC5\xA9\xA3\x89\xC7" \ + "\xF9\x98\x2E\xB6\xEB\x04\xCE\x79\x9F\x01\x3F\x3C\xBF\xD6\xF8\xDA" \ + "\x3B\xFA\xDB\xA1\x78\xD6\xA2\x3D\xF4\xD9\x69\x37\xDE\x1F\x1C\x70" \ + "\xF0\x01" + +/** Screen mode 1024x768 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1024_768_60_24_0 "" \ + "\xB6\xF8\xFC\x00\xF3\xE4\x81\x1E\xC5\x60\xA3\x79\xE5\x35\xC5\x15" + +/** Mode data. + */ +#define DLO_MODE_DATA_1024_768_60_24_0 "" \ + "\xDD\x2A\x3A\x49\xE9\x99\xE3\xC8\xA0\xBA\x23\x3A\x3D\xEB\x21\xE4" \ + "\xA5\x54\x25\x0D\x51\xCC\xE6\x52\xA7\xD7\xCD\xFA\xD5\x9B\x5B\x41" \ + "\x0B\x49\xAB\xC6\xE3\x1A\xF2\x87\x81\x32\xF0\x3E\x40\x00\x51\x40" \ + "\x9E\x94\xF1\x22\xEE\xAC\xB2\xA2\x6B\x4D\xC4\x41\x5A\x9C\x45\x62" \ + "\x4F\x4E\x61\xDB\x1F\x0E\x79\x66\xE2\x20\x83\x9E\x2C\xAB\x28\x38" \ + "\xAC\xC1\x22\x81\xA5\x69\xFD\xFB\x26\x15\xF9\xC9\xFA\x90\xF2\x66" \ + "\x85\xC5\xAA\xA6\x4D\x8B\xC8\xA6\x03\x32\xDF\x98\xA9\x77\x9E\x57" \ + "\xEA\xC9\x9E\x29\xED\xFC\xC4\x78\x26\x0B\x2E\xC2\x41\x7C\x4A\xA3" \ + "\xAB\x66\x01\xA0\xE5\xA4\x8B\x80\xA0\x53\xE5\x5D\x59\x63\x62\xE8" \ + "\xFE\x6B" + +/** Screen mode 1024x768 (at 70 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1024_768_70_24_0 "" \ + "\x2B\x71\x0C\x1F\x55\x8E\x3D\x1A\xEE\xE0\x93\xD4\x15\x58\xE9\x00" + +/** Mode data. + */ +#define DLO_MODE_DATA_1024_768_70_24_0 "" \ + "\xE9\x15\xBC\xBE\x90\x6C\x07\x34\xF2\x79\xCA\x43\x44\x92\x65\x9A" \ + "\xC7\x41\xE9\x56\xE7\x27\x4A\x9C\x24\x04\x40\x97\xF5\xFD\xFF\x99" \ + "\xC8\x6A\xA0\xF3\x32\xE3\x4E\x40\xBC\xA5\xAE\x37\xBA\x89\xB0\xDD" \ + "\x10\xD2\x10\x76\xE8\x80\xAF\x15\xC1\x16\x65\x80\xA2\xCE\xFD\x14" \ + "\x66\xD8\xAA\x83\x7C\xD6\xE2\xF2\x26\x36\xD5\xF2\x36\xA5\x7F\x4D" \ + "\xF6\x21\x14\x58\xB5\xFA\x54\x07\xE6\x91\x93\xB9\xB9\x4B\xB5\x0C" \ + "\xD6\xAE\x6C\x2D\x12\x51\xED\x13\x6C\xD7\x07\x15\x6D\x88\x10\x62" \ + "\x94\x4F\x77\xB7\xEC\xA3\xD4\xAD\xDF\xCC\x76\x2D\x39\x90\xEE\xB1" \ + "\x98\x09\xA2\x28\x03\xF8\x1F\x1C\x01\xCA\xAA\xC0\xC2\x92\xDE\xD8" \ + "\xFC\x59" + +/** Screen mode 1024x768 (at 75 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1024_768_75_24_0 "" \ + "\x10\xFC\xF8\x65\x8A\x35\x80\x78\x15\x13\x4C\x2A\x6C\x35\x2B\x74" + +/** Mode data. + */ +#define DLO_MODE_DATA_1024_768_75_24_0 "" \ + "\xE6\xB2\x51\x5B\x75\x7E\x2A\xBC\xA5\x4A\xC0\xC0\xEA\x20\x67\xCC" \ + "\x89\x74\x5D\x3B\x7D\xB4\x29\x82\xA8\x28\x97\x86\x13\x0E\xE3\xCC" \ + "\x95\x10\x43\x65\x15\x64\xA0\xF9\xA7\x20\xFE\x61\x0A\xFF\x6E\xEC" \ + "\x7E\x55\x17\x4F\xA2\x61\x77\x7E\x9A\x3B\x04\xFF\xC0\xA0\xAE\x82" \ + "\x3F\x81\x1A\xEB\x45\x8B\x37\x99\xA6\xED\xB1\x66\x78\x02\x8C\xB3" \ + "\xE7\x88\xD5\x57\xD8\xE7\xFD\x7F\x49\x8B\xBE\xC6\xD1\xDD\x60\xB5" \ + "\x41\xCD\x1B\x3E\xEC\x69\x18\xE9\x77\x71\x7F\x0E\x11\xCB\x47\x82" \ + "\x89\x2C\xCA\x54\x5E\x33\x9C\x60\x61\x42\x55\xB4\x4B\xC2\x9C\x37" \ + "\xFD\x37\xD4\x47\xC5\x08\xDF\x14\xCB\xCD\xD9\xCD\xA0\xC1\x42\x21" \ + "\xD2\xD9" + +/** Screen mode 1024x768 (at 85 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1024_768_85_24_0 "" \ + "\x02\x10\x92\x8C\x45\x12\x05\x5A\x25\x51\x85\x91\x87\xB0\x05\x8C" + +/** Mode data. + */ +#define DLO_MODE_DATA_1024_768_85_24_0 "" \ + "\xA7\xC9\xD0\x6E\x6E\x77\xDA\xD3\x25\xEA\x3B\xA4\x4B\x35\x88\x4E" \ + "\x22\x53\xC4\x82\xB0\x14\x40\x54\x8A\xB6\x42\xF2\xBB\xC8\x4B\x24" \ + "\x52\xF9\xC3\x37\xBE\xCF\x99\x01\x5A\x56\xB2\xA8\xE7\xF3\x53\x7B" \ + "\x37\x55\xFE\x97\xF3\x05\xFF\xC0\x71\x60\xBB\xD9\xCC\x49\xFA\x73" \ + "\x2C\x39\x72\x25\x27\xFB\x83\x7D\x44\x58\x86\x5D\x6F\xFC\xCF\xD4" \ + "\xCF\x7C\xC1\x33\x35\x21\x30\x70\xA8\x36\x60\xBB\xA8\xE2\x74\x05" \ + "\xBB\xB3\xC5\x60\xBD\x4B\xC0\x6C\x04\x41\xD2\xE6\xFA\xEB\x67\x02" \ + "\x6A\x77\x82\x4D\xF7\x05\xAC\xA8\xA3\x8F\x21\xCA\x24\xF3\x53\x52" \ + "\x2A\x99\xEA\xE5\xBD\x76\x3C\x85\x73\x98\xD8\x46\xA7\xAC\xA8\xB7" \ + "\x3A\xA9" + +/** Screen mode 1152x864 (at 75 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1152_864_75_24_0 "" \ + "\xAE\xFE\x44\xF3\x10\x49\x4E\x35\x9B\xD3\xC7\x22\x83\xCC\xAE\x40" + +/** Mode data. + */ +#define DLO_MODE_DATA_1152_864_75_24_0 "" \ + "\x65\xB5\xCB\x8E\x46\x49\x3E\xFB\x60\x91\xC1\x32\x82\xD3\xCA\x2F" \ + "\x4A\x49\xB1\xA8\x17\xA1\x12\x37\xBB\x1C\x5F\x69\x41\xA8\x72\xB2" \ + "\xB8\x37\x9C\x7E\xE3\x5C\xA2\xD3\x19\x59\xE2\x75\xA7\xC9\x25\xBB" \ + "\x6E\x77\xD1\x2D\x25\xEA\x36\x43\x4B\x35\x87\xB3\x22\x53\xC9\xB5" \ + "\xB0\x14\x4B\x1D\x8A\xB6\x57\x78\xBB\xC8\x5C\x3B\x52\xF9\xD6\x3C" \ + "\xBE\xCF\x82\xCB\x5A\x56\xAF\x2E\xE7\xF3\x4C\x85\x37\x55\xE3\x91" \ + "\xF3\x05\xE4\x3C\x71\x60\xAE\xB6\xCC\x49\xEF\x6A\x2C\x39\x61\x75" \ + "\x27\xFB\xB0\x7D\x44\x58\xB3\x32\x6F\xFC\xF8\xBF\xCF\x7C\xFB\xCC" \ + "\x35\x21\x0E\x8B\xA8\x36\x5E\xC4\xA8\xE2\x7D\xFC\xBB\xB3\x2D\x9C" \ + "\xBD\xCB" + +/** Screen mode 1280x768 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1280_768_60_24_0 "" \ + "\x73\x9D\x25\x83\xE6\x73\xB8\x81\x46\x7F\xA3\xC9\x4C\x52\x09\xB4" + +/** Mode data. + */ +#define DLO_MODE_DATA_1280_768_60_24_0 "" \ + "\xB0\x52\xEB\x22\x12\xDD\x55\x65\x5C\x01\x38\xD9\xA2\x1A\xE6\x1F" \ + "\x75\x89\x16\x6E\x7A\x2E\xFC\x28\x9F\x3C\xD0\xE6\xC8\x0F\xD9\xCE" \ + "\x66\xBD\xDA\xE1\x28\x88\x61\x5B\xB2\x1B\x03\x5B\x3E\x37\xD7\x54" \ + "\xD8\xC4\xCA\xBC\x85\xBE\x2E\x50\xA2\x39\xC1\xB1\xB9\xBC\x92\xA9" \ + "\x09\xCA\x4D\xFA\x67\x4D\x55\x1E\x2D\xAC\x8C\xBB\x76\x81\xEE\xEE" \ + "\x14\xEF\xBC\xD8\x4D\xB6\x0B\xB0\x74\xEB\xDF\xDB\xF4\x30\xB8\xF2" \ + "\xBA\x97\x4A\x67\xAB\x3E\x84\x6B\xC6\x23\x2E\x3A\x69\x39\x04\x67" \ + "\x01\xAF\xEE\xE6\x96\xCC\x9E\xFF\x68\xF4\x6A\x0F\x73\x52\x1E\x0A" \ + "\x0F\x11\x4A\xE8\x12\x72\xF6\x0E\xA0\xE2\x8A\xC3\x1E\x6C\x49\xA5" \ + "\x6C\xBE" + +/** Screen mode 1280x1024 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1280_1024_60_24_0 "" \ + "\x6A\xF0\x37\x50\x63\xEF\xD2\xA9\x6F\x75\x72\xBB\xC7\x7B\x6F\x1A" + +/** Mode data. + */ +#define DLO_MODE_DATA_1280_1024_60_24_0 "" \ + "\x23\x4A\x78\x7C\xD1\xB8\x0E\x6B\x15\x93\x96\x77\x78\x44\xCC\x16" \ + "\x7F\xE3\xD7\x39\x3F\x2E\x99\xD2\xB9\x68\x8E\xC4\x1A\x9B\xF4\x35" \ + "\x61\xB5\x48\x5C\x94\xA6\x84\xB2\x88\x2B\x47\x84\x84\x73\x7F\x2C" \ + "\xD0\xC4\x3D\x5D\x20\x61\x4A\xB1\x73\x4C\xDD\x6A\xB4\xFD\xE9\x94" \ + "\x3C\xD1\x44\x0A\x08\xCD\xF5\xE5\xBD\x0D\x99\xCD\x9C\x2A\xC9\x06" \ + "\x1D\x22\x1C\xB1\x9A\x94\x95\x65\x3C\x43\x19\x73\x83\xF7\x51\x1F" \ + "\x5C\x3C\xE1\x59\xD5\xC3\xF2\x27\x28\xCE\x22\x7B\x2A\x70\x04\xE4" \ + "\xD9\xFE\x8A\x6E\x28\x27\xC5\x40\x4E\xF8\x83\x5B\x82\x41\xA6\x62" \ + "\xC1\x73\x3A\x5C\xF6\x90\x43\x39\xF2\xF5\x74\x80\x74\x44\xBD\xB1" \ + "\x08\x53" + +/** Screen mode 1280x1024 (at 75 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1280_1024_75_24_0 "" \ + "\xDB\xCF\xE1\x3F\xBE\xB3\xE8\x2D\x29\x5B\xE8\xF0\xD6\x57\x0B\xFF" + +/** Mode data. + */ +#define DLO_MODE_DATA_1280_1024_75_24_0 "" \ + "\xBA\x89\x45\x90\x10\xD2\x1B\x50\xE8\x80\xA2\xE9\xC1\x16\x6A\x6D" \ + "\xA2\xCE\xF0\xD4\x66\xD8\xA1\x18\x7C\xD6\xF7\xD8\x26\x36\xC2\x7E" \ + "\x36\xA5\x6A\x9A\xF6\x21\x0F\xF3\xB5\xFA\x49\x07\xE6\x91\x8C\x4B" \ + "\xB9\x4B\xA8\x0C\xD6\xAE\x77\xD1\x12\x51\xF8\x21\x6C\xD7\x12\xED" \ + "\x6D\x88\x03\x5D\x94\x4F\x44\xB7\xEC\xA3\xE1\x3F\xDF\xCC\x41\x85" \ + "\x39\x90\xD4\x4E\x98\x09\x9C\xD3\x03\xF8\x21\xE3\x01\xCA\xA3\x39" \ + "\xC2\x92\x36\x23\xFC\xD9\x99\x08\x7B\xC0\x9C\xCE\x21\xF4\xBA\xBE" \ + "\x22\x36\x9C\xB4\xE4\x4A\xFB\xC1\x1E\x9B\xAC\xFF\xB3\x5A\xD4\x0D" \ + "\x7C\x1C\x28\xBB\x8E\x8B\xD8\x8E\x1E\xFE\xEE\xD9\xE7\x04\x99\x20" \ + "\xE8\xB1" + +/** Screen mode 1280x1024 (at 85 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1280_1024_85_24_0 "" \ + "\xE4\xE9\xAF\xA2\x9D\x98\xD0\xC6\xF3\xB8\xB6\xC9\x10\xC1\xC8\xA6" + +/** Mode data. + */ +#define DLO_MODE_DATA_1280_1024_85_24_0 "" \ + "\x93\xB0\x06\xA2\x8F\xE9\x2C\xB3\x90\xE0\xA6\x66\xC2\xAF\xEC\x00" \ + "\x8B\x00\x8C\x0B\x26\x87\xAF\x8A\x71\xAA\x43\x0F\x64\xF4\xC5\xF3" \ + "\x04\x62\xE6\x7A\x36\xDE\xFA\x1A\x19\x93\x12\xD1\x0F\x74\x12\xAF" \ + "\x46\x2C\x4D\x23\x34\xCF\x57\x3B\x16\xFE\x0B\xDC\x42\xDB\x0C\x80" \ + "\x39\x44\xDF\x0C\x8B\x58\x28\xB3\x05\x00\x2F\xB9\xB8\xC0\xB6\xA1" \ + "\x3C\x38\x80\xA1\x6C\x45\x4F\xF1\xE6\xB2\xBB\xA4\x75\x7E\x3C\x44" \ + "\xA5\x4A\xD6\x28\xEA\x20\x7D\x78\x89\x74\x45\x97\x7D\xB4\x31\xB5" \ + "\xA8\x28\xB1\xB0\x13\x0E\xC1\xCC\x95\x10\x61\x62\x15\x64\x81\x4A" \ + "\xA7\x20\xDD\x3A\x0A\xFF\x4F\x39\x7E\x55\x03\xB0\xA2\x61\x84\x7E" \ + "\x9A\xBB" + +/** Screen mode 1280x768 (at 75 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1280_768_75_24_0 "" \ + "\x87\x94\x88\x24\x2C\x58\xEA\x1F\x10\xA1\xE9\x20\x62\xB1\xC6\x43" + +/** Mode data. + */ +#define DLO_MODE_DATA_1280_768_75_24_0 "" \ + "\x20\x5C\x76\xA7\x04\x95\xDE\x8B\xE9\xBA\xCA\x66\x6C\x8F\xA9\x5B" \ + "\x4E\x0F\x9A\xCA\x5D\x25\xB2\x6C\xB4\x6F\xA5\xE4\xB7\xEB\xEF\x58" \ + "\xE9\xFC\x9C\xD2\xF4\xE4\xB1\x47\xA9\xC6\xE4\xF6\xAD\xC6\x9C\x38" \ + "\x7F\x29\x2F\x59\x97\x93\xA6\x07\x91\x33\x1A\x1F\x0B\xBE\x9D\xE7" \ + "\x3C\x7E\xCC\x60\xF4\x2E\x59\x92\x01\x7B\xCB\xB2\x85\x9D\x18\xA7" \ + "\x6E\x0C\x56\xFF\xCA\x58\x32\xAB\xF1\xBB\xC7\x6B\x82\xEE\x11\x9C" \ + "\x3D\x90\xAB\x2D\x4A\xE6\x22\x30\xEB\x42\xA1\xA6\x07\x6A\x14\x4F" \ + "\x58\x1F\x86\xDF\xCB\x19\xF5\x7F\xB3\x90\x28\x41\xD4\xA1\x1C\x1B" \ + "\xA6\xD0\x45\x85\x0F\xDB\xBB\xA1\xBA\xCF\xF5\xAB\x88\xB9\xF6\x32" \ + "\x0F\xC9" + +/** Screen mode 1280x768 (at 85 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1280_768_85_24_0 "" \ + "\x74\xE4\x58\xA1\x3C\x43\xC0\x4D\xE4\xA9\x6D\x46\x5B\x34\x89\xE5" + +/** Mode data. + */ +#define DLO_MODE_DATA_1280_768_85_24_0 "" \ + "\x5B\xA6\xDC\x6E\xE2\xD7\xAD\xE3\xF3\xCF\x02\x6D\xD9\xDD\x83\xEB" \ + "\xE4\x12\x6B\xC6\x3D\x1C\x18\x54\x7A\x30\x1A\x0C\x24\xD0\x54\x05" \ + "\xE6\xAC\x4E\x76\xCE\x92\xA5\x1D\x8B\xE9\x5E\x53\x42\x0F\x1F\x9C" \ + "\x2A\x15\x6B\xB1\x8D\xA0\x3E\x8E\xBC\x0A\x22\xB2\x46\x6A\x18\x18" \ + "\xAC\xA4\x46\x5D\xF1\x37\x62\xE3\xB2\x38\x33\xFD\xF2\x02\x46\xF2" \ + "\xAB\x20\x68\x60\x7D\xCF\xA6\xE3\x47\x9A\x9B\xA7\xA9\x80\xAB\x54" \ + "\x35\xAD\x93\xFB\x98\xE0\x48\x7D\x67\x70\x91\x3B\x5A\x75\x8F\x97" \ + "\x2B\xC6\xF3\x34\x44\xB1\x6B\x60\x0B\x74\x46\x54\x94\xC3\xDD\xC0" \ + "\xDC\x75\xFF\x99\x10\x5E\x90\x26\xD8\x56\x99\x1E\x0E\x84\x7F\x8B" \ + "\x43\x88" + +/** Screen mode 1280x800 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1280_800_60_24_0 "" \ + "\x59\xFF\xC3\x96\x42\x84\xE3\x26\x2D\x50\x6C\x88\x84\xF6\x6E\x2A" + +/** Mode data. + */ +#define DLO_MODE_DATA_1280_800_60_24_0 "" \ + "\x55\x5E\x21\x5E\xFE\x02\xD8\x84\xDC\x10\xAC\xF6\x44\x00\x22\x46" \ + "\x4C\x7B\x4B\xCC\x06\x16\x34\xFC\x6D\xED\x71\x58\xC0\x11\xC9\xA4" \ + "\x78\x8E\x39\xC3\xD7\x5E\xEB\x67\x17\x75\x08\x14\xA8\x4D\xE0\x5C" \ + "\x47\x50\x75\x35\x01\x3D\x86\x42\x1D\xF6\x15\x09\x89\xC5\x3F\xFA" \ + "\x3A\xBB\x09\x86\x3A\xFD\x46\xB8\xA2\x96\x55\x2B\x45\x5F\x22\x94" \ + "\xB5\xBC\x03\x09\x7E\xFA\x80\x25\x5E\x82\xC2\x09\x26\x4D\x4D\x33" \ + "\xD9\x17\x66\x3C\x4C\xAF\x47\x81\x15\x47\x9B\x39\x6B\x15\x62\x30" \ + "\x79\x1B\xFD\x3B\x86\x24\xA8\xD1\x47\xC2\x1C\x97\x8A\x07\x01\x66" \ + "\xFC\xC7\x4C\xF9\xC0\x2C\x2B\x8C\x0F\x57\x2F\xD6\x8A\x19\x30\x6D" \ + "\x47\xAB" + +/** Screen mode 1280x960 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1280_960_60_24_0 "" \ + "\x42\xAB\xE3\x84\x2F\xC6\xAA\x5D\x17\x17\xE5\x9B\x0D\x53\xC5\xA6" + +/** Mode data. + */ +#define DLO_MODE_DATA_1280_960_60_24_0 "" \ + "\x3D\xAD\x8C\xC7\x3D\x3F\x34\x45\xB6\x05\x97\xE1\x57\x34\xEA\x4E" \ + "\x1E\xDD\xDA\x98\x2B\x31\xEB\xEF\x9B\xD5\x73\xB1\x7E\x68\xD5\xCC" \ + "\xD5\xB8\x72\xBD\xC7\x7C\x2D\x07\x90\xFE\x49\xD7\x79\x43\x63\x49" \ + "\xA5\xA3\x12\x82\x8E\xA8\xD7\x6C\xD2\xCB\x75\x03\x94\xE0\xD2\x9E" \ + "\x10\x40\x53\xD7\x63\xBA\x11\x24\x20\x27\x07\xE4\xEB\x27\xD0\x8A" \ + "\x53\x34\x80\x2D\xCC\x32\x7F\x27\xC3\x8B\x74\x36\x9D\x75\xDD\x82" \ + "\xE4\xE5\x40\xA2\xE2\x78\x3D\x48\x0F\x2C\xB4\x64\x65\xAB\xCF\x2E" \ + "\xFD\xA5\x9A\xC0\x4E\x32\x72\x1D\x2A\xFC\x9D\xC7\xE9\x28\xA5\x57" \ + "\xE7\xB5\x23\x44\xAF\x3E\xCC\xF4\x14\xCC\x98\x3A\x81\x83\x69\xFE" \ + "\x07\x8F" + +/** Screen mode 1280x960 (at 85 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1280_960_85_24_0 "" \ + "\xF6\x75\x37\x25\x3C\xE1\x82\x53\xF8\x68\xEE\x05\xBB\xB4\xAB\xBC" + +/** Mode data. + */ +#define DLO_MODE_DATA_1280_960_85_24_0 "" \ + "\x58\x1F\x5A\xDF\xCB\x19\xD1\x74\xB3\x90\x0C\x65\xD4\xA1\x37\xD5" \ + "\xA6\xD0\x6C\xF7\x0F\xDB\x94\x9E\xBA\xCF\xEF\x01\x88\xB9\x0F\x2B" \ + "\x0F\x49\xD0\x81\x31\xF5\x40\x7E\x69\x88\x7E\x59\x46\xA0\xEC\xCF" \ + "\x04\x19\x75\x02\xD9\x6C\xE2\x12\xA3\x1D\x4E\x73\xAF\xC9\xD6\x37" \ + "\xCB\xA8\xB1\xEE\xF4\x9F\x36\x0C\x46\x74\xE0\x54\x17\x48\xDC\xCE" \ + "\xDF\x94\xF7\x1D\x1A\x17\x46\xE8\x51\x63\x7F\xD7\x5B\x34\x72\x14" \ + "\x69\xED\x18\xE2\x12\xFE\x65\xB9\x90\x34\xAB\xFE\xD1\xFE\x42\x25" \ + "\x8D\xF8\xA6\x73\x9F\x8D\x9E\xE1\x8F\x00\xD1\xE3\xF4\x68\x30\xA9" \ + "\x99\x10\xE2\xC7\x62\x54\x55\x6F\x9E\xEF\x7A\xD7\x01\x1E\x5D\x87" \ + "\xD1\x43" + +/** Screen mode 1360x768 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1360_768_60_24_0 "" \ + "\x84\x36\xDB\xC0\x18\x5D\x13\x10\xC5\x02\x16\x81\xB6\xC1\x3D\xA6" + +/** Mode data. + */ +#define DLO_MODE_DATA_1360_768_60_24_0 "" \ + "\x99\xDA\xC7\x8E\xCA\xE9\x49\xCB\xB6\xB4\xF8\x21\x10\x3B\xC1\x42" \ + "\x8C\x08\x1E\x52\x9A\xA9\x4A\x17\x4B\x9A\x07\x0A\xDE\xB0\x6D\x89" \ + "\x0C\x62\x11\x38\x93\x01\x9E\x33\xC8\xE6\x0E\x17\x02\x35\x69\x2B" \ + "\x73\x37\x44\xD3\x5B\x4F\xF7\xC0\x86\x5F\x1E\x9D\xA8\x70\x2B\x3C" \ + "\x30\x89\x7F\x65\x5C\x7A\xB6\x36\x4D\xA8\xE9\xFB\xCF\x07\x5F\x65" \ + "\xDA\x93\x2B\x98\x12\xB8\x39\xBD\x08\x5F\xB7\x99\x36\x37\x3C\x9E" \ + "\x7D\x1B\xB2\xA7\x54\xCB\x26\xC7\xAF\x78\xAC\x03\x8C\xA7\x89\xE4" \ + "\x66\x4A\xC1\x04\xF7\xEC\x74\xFB\xC7\x07\x9F\x81\x7F\x4C\x75\x5E" \ + "\xC3\xCD\x1B\xF7\x05\x1E\xF2\xB7\x03\x2C\x3C\xA4\x12\x9B\xFA\xA0" \ + "\xC4\xEA" + +/** Screen mode 1366x768 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1366_768_60_24_0 "" \ + "\x6E\xF3\xC9\x86\x50\xDD\x97\x16\xDF\xAD\x97\x95\x6E\xD4\x3B\x46" + +/** Mode data. + */ +#define DLO_MODE_DATA_1366_768_60_24_0 "" \ + "\x2A\x70\xE7\xB0\xD9\xFE\xA9\x6F\x28\x27\xE0\x53\x4E\xF8\xA4\x45" \ + "\x82\x41\x8C\x7D\xC1\x73\x14\xE9\xF6\x90\x6D\xAA\xF2\xF5\x6D\xE0" \ + "\x74\x44\x45\x0E\x08\xD3\x0A\x6A\x06\xE1\x06\x5B\xB2\x89\x47\x47" \ + "\xB5\x0D\x74\x4F\x39\xF5\xB3\xA5\xCC\x57\x1E\x01\x97\xD5\xF4\xE4" \ + "\x09\x58\x0A\x79\xEC\x77\xF7\x4B\xCC\x9D\xF2\xB1\x3F\x68\xDF\x67" \ + "\x21\x03\x8A\x8D\xFD\x52\x92\x9A\x91\x56\x7A\x3A\x5F\xE0\x1E\x6D" \ + "\xA8\x53\x1A\x61\xFC\xBC\xE1\x2E\x2F\x9E\x07\xFE\xB5\xD9\x74\x92" \ + "\x2A\xA4\x2C\x08\xCA\xAF\x3D\xFB\x2E\xDF\xCE\xE9\xF7\xF2\x9E\x05" \ + "\x7C\xEB\x17\x1E\x51\xEF\xE1\x09\x6B\xE2\x5E\xD4\xA6\x7F\x18\x15" \ + "\xF3\xB8" + +/** Screen mode 1400x1050 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1400_1050_60_24_0 "" \ + "\x95\xCB\x91\xE5\xA8\x28\xFB\x87\xD5\x92\x1C\x44\x66\x57\x8A\x98" + +/** Mode data. + */ +#define DLO_MODE_DATA_1400_1050_60_24_0 "" \ + "\xC6\x8C\x42\x4C\x95\xDA\xB4\x2F\xBD\xD9\x9E\xAD\x8F\x7B\x69\x15" \ + "\x1B\xDA\x06\x79\x23\x9E\x94\xF2\xC2\xE9\xBB\x34\x13\x6B\x9B\xB2" \ + "\xC1\x4E\xD8\x69\x81\x49\x6E\x64\xAF\xB2\x4E\x69\x24\x1A\xA8\xBB" \ + "\x4E\x11\x75\x38\xE6\xC9\x3D\xE9\x9A\xCC\x3B\xAA\x1F\xC4\x97\xD5" \ + "\x4A\x9D\xAA\xE7\x04\xF0\xB6\xD4\xBD\xE4\x41\xCF\xF8\xA2\x77\x0B" \ + "\x46\x9D\x3A\xBD\x73\xC0\x64\x76\x84\x2B\xD7\x11\xF3\x43\xB5\xF6" \ + "\xE9\x0B\xB3\x4E\x2B\x80\x98\x15\xDC\xDA\x46\xE8\xEC\xBD\x0B\x0E" \ + "\x64\x20\xF7\x17\x17\x33\x75\xBA\x30\x26\xDD\xFA\xA0\x99\x23\x11" \ + "\xF1\xDE\x80\xB7\xD6\xB0\xB7\xA2\xA9\xBD\x6D\x29\x42\x74\x75\x73" \ + "\xC5\x27" + +/** Screen mode 1400x1050 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1400_1050_60_24_1 "" \ + "\xCB\xA2\x00\x73\xCB\xFC\xFB\xA0\x8E\x17\xE4\xF5\x6F\x6F\x8D\x1D" + +/** Mode data. + */ +#define DLO_MODE_DATA_1400_1050_60_24_1 "" \ + "\xDA\x01\x80\xE4\x99\x82\x8F\x40\xE9\x6E\xDD\xA6\x7F\xDE\x19\xFC" \ + "\x48\xF7\x90\x61\xE4\x2F\xA3\x72\x4A\xC5\x17\xBE\x27\x77\x35\x6A" \ + "\x74\x8E\xB5\x45\xA0\x6E\x3D\x58\x2E\xBA\x9A\xB6\xA3\xAC\x26\xD4" \ + "\xE8\xC6\xF8\xE3\x59\x7D\x76\x1C\x45\x07\x8A\x82\x96\x3B\x8B\x45" \ + "\xB7\x90\x79\xDB\x06\x4E\x97\x7F\x4E\x6A\xF0\xE7\x09\x7B\x3F\x05" \ + "\x20\x42\x7D\xAC\xBF\x79\x4D\x42\xC7\x19\x48\x2A\xC4\xA0\xCD\x9B" \ + "\xED\x6E\xB0\xF7\xAD\x31\xB1\xDB\xA0\x4D\x06\x41\xE2\x8F\x06\x63" \ + "\xD0\x48\xB5\xD5\x10\xB7\x47\x7D\xBC\xDE\x1D\x05\x55\x3B\x8F\x78" \ + "\xAA\x5C\x69\x52\x48\x3D\x48\xC5\x4C\x92\x8F\x48\x62\x9E\x71\xDC" \ + "\x36\xD2" + +/** Screen mode 1400x1050 (at 75 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1400_1050_75_24_0 "" \ + "\x8E\x2F\xD0\x59\x2B\xCB\xFA\xB9\xE2\xDE\xAE\x51\x4D\x3C\x6E\x4D" + +/** Mode data. + */ +#define DLO_MODE_DATA_1400_1050_75_24_0 "" \ + "\x25\xF4\x22\x48\xF0\xD9\x0D\xA9\x0C\xF0\x50\x5D\x18\x3B\x36\x2D" \ + "\x29\xD7\x7A\x1D\x4B\xDC\x56\xA2\x46\xDB\x7C\x33\xEB\xAB\x64\xBB" \ + "\x63\xE2\xB1\x4C\x03\xA0\x8B\xBB\x22\x4D\x29\x10\x0B\xF8\xC9\x3F" \ + "\xA4\x15\xDA\xCB\x13\xE7\x31\xF7\xF1\x98\xF7\x76\x4E\xDB\x80\xB9" \ + "\x4E\x74\x09\x29\xB2\x97\xBA\x23\x0E\xE1\xE9\x69\x17\x56\x3B\xD0" \ + "\x64\x78\x70\x27\x34\xB4\xD0\xE9\xF9\x4C\x0F\xF1\xF8\x55\x4C\x12" \ + "\x99\xF9\x07\x97\x06\xDC\xD8\x9E\xC5\x50\x58\x3B\xE8\x4A\x4F\x12" \ + "\x69\xAB\x7C\xDA\x8A\x95\x4B\xEF\x77\xFD\xE1\x0F\x21\x1D\x57\x86" \ + "\x46\xBE\x2B\x5A\xBF\xF5\xD2\xBF\xF7\xCF\x67\xEC\x0B\x32\xCC\x90" \ + "\x0C\x28" + +/** Screen mode 1400x1050 (at 85 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1400_1050_85_24_0 "" \ + "\x66\xC2\x92\x91\x8D\x8C\x4A\x6F\x6A\xF9\xC1\xB8\x35\x2F\x05\xD7" + +/** Mode data. + */ +#define DLO_MODE_DATA_1400_1050_85_24_0 "" \ + "\x73\x98\x38\x46\xA7\xAC\x57\x49\x3A\x29\x40\xA6\xB1\xC7\xF6\xC8" \ + "\x43\xA7\x39\x93\x0C\xB6\x05\xD3\x80\x50\x23\x08\xCE\x1E\x0B\x6B" \ + "\xBB\x3F\x75\xCE\x8D\x9D\xF5\x67\xCB\xD3\x28\x29\x1B\x2D\x30\x40" \ + "\xFC\xFA\xA2\x75\xB7\xF5\x02\xC2\x52\x10\x11\x2A\xDA\x47\x21\x20" \ + "\x01\xE9\x92\xD8\x0E\xA7\xB8\x11\x8F\x3D\x2A\xDB\x83\xB1\x05\x48" \ + "\xC4\x57\xF7\x3E\x32\x0A\x8A\xDD\xD8\x2D\x0C\x33\xE1\x36\x8A\x6E" \ + "\xF9\x86\xFD\x46\x50\xE8\x75\x5F\xB1\xA2\x97\xA1\x17\xF9\xBD\x70" \ + "\x98\x9B\xEC\xAF\x88\xC2\xB2\x15\xE0\xFB\xEE\x3A\x8B\x7B\x39\xAE" \ + "\xC9\x35\x9D\x58\xCB\x24\x35\xE4\xC4\x49\x1C\x35\x89\xE6\xE6\xE7" \ + "\xF6\x0E" + +/* DL160 modes... */ + +/** Screen mode 1600x1200 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1600_1200_60_24_0 "" \ + "\x3C\x79\x81\x0F\xF2\xAB\x85\xC7\x3A\xE8\xEB\xCB\xF3\x32\x12\x9C" + +/** Mode data. + */ +#define DLO_MODE_DATA_1600_1200_60_24_0 "" \ + "\x85\x2C\x9A\xF4\x29\x03\x6E\x4C\x58\x8D\xE3\x93\x40\x23\x71\xD2" \ + "\x52\xA1\x70\x77\x9D\x48\x00\xDC\x93\x3C\x5C\x80\xBF\x3F\x0F\xF8" \ + "\x5F\x72\x48\x38\x23\x69\xA7\x4A\x1D\x8D\x8E\x55\x66\x77\x27\xBF" \ + "\x80\x35\x55\x7A\x9A\x40\x9A\xDD\x2F\x12\xB1\xFD\x85\x0F\x43\x23" \ + "\xE5\x36\xE8\x05\x2B\x69\x48\x1E\xB8\x52\xF2\xFF\xB7\x02\x23\x0A" \ + "\x8D\x74\x36\xFB\xAF\x5B\x8B\x2D\x40\x92\x09\x17\x15\xAE\x4E\xFF" \ + "\x0F\x9D\xD7\x9E\x22\xA4\xE0\x87\x6F\x70\x66\x58\xFF\xAA\xEB\x8B" \ + "\xFA\xB3\xEF\x84\x49\xF0\x10\xE7\x3E\x6F\x4F\x24\xFB\x43\x7D\x3B" \ + "\x4C\xD4\xEA\x75\xFA\xF5\xB7\xFF\xD1\x9B\x39\x77\xD9\xA6\xE1\x5E" \ + "\x0B\x20" + +/** Screen mode 1920x1080 (at 60 Hz, 24 bpp). + */ +#define DLO_MODE_ENABLE_1920_1080_60_24_0 "" \ + "\xC1\xCA\xC3\xB3\x75\x48\x7A\xAF\x30\x65\x7B\x24\x97\x8D\xC0\x64" + +/** Mode data. + */ +#define DLO_MODE_DATA_1920_1080_60_24_0 "" \ + "\x0D\x58\x81\xE3\x3E\x98\x55\x00\x24\x27\x6C\x99\x39\xC8\x72\xD8" \ + "\xBB\x8E\x1E\xA2\xCA\x92\xD2\xAB\x59\x06\xE0\x65\xAA\xB5\x9D\xAC" \ + "\x2C\xB5\xDA\x17\x17\x2D\xBE\x19\x8B\xCA\x76\x3D\x8E\x3A\x96\x8F" \ + "\x59\xF1\xD1\xA6\x75\xD1\xAE\xB7\x59\xA9\x60\xA4\x56\x56\x39\x8E" \ + "\x90\xC3\x80\x58\x0E\x9A\x77\x00\xF8\xE4\x24\x74\xDE\xF6\x29\x34" \ + "\x94\x09\x17\x73\x74\xC8\xF6\xC0\x38\x05\x32\xD7\xC9\x73\xF1\x99" \ + "\x53\x4F\x1B\x04\x23\x80\x6F\x08\x79\x05\x22\x2F\x3D\xC8\x17\x9D" \ + "\x69\x61\x8C\x96\x22\x28\x7C\x4F\x5F\xA6\x7D\xF1\x30\x38\x36\xFE" \ + "\x1B\x75\xA7\x2C\xDF\x7D\x17\x33\x7E\x9F\xF3\xFC\x0A\xDC\xB3\xDB" \ + "\xB2\xE0" + +/** Data to send after a mode change. + */ +#define DLO_MODE_POSTAMBLE "\x57\xCD\xDC\xA7\x1C\x88\x5E\x15\x60\xFE\xC6\x97\x16\x3D\x47\xF2" + +/** Number of entries in the @a dlo_mode_data array. + */ +#define DLO_MODE_DATA_NUM (35u) + +/** Lowest mode number supported by the DL120. + */ +#define DLO_DL120_MODES (2u) + + +#endif diff --git a/src/dlo_defs.h b/src/dlo_defs.h index 08baf21..974c295 100644 --- a/src/dlo_defs.h +++ b/src/dlo_defs.h @@ -1,158 +1,158 @@ -/** @file dlo_defs.h
- *
- * @brief This file defines common macros and so on for the DisplayLink libdlo library.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DLO_DLOCOMMON_H
-#define DLO_DLOCOMMON_H /**< Avoid multiple inclusion. */
-
-#include <stdint.h>
-#include <stdio.h>
-
-#ifdef DEBUG
-
-/** Assert that a given expression evaluates to a non-zero number.
- *
- * @param expr The expression to test.
- */
-#define ASSERT(expr) if (!(expr)) { printf("<%s:%u>\n Assertion '%s' failed.\n", __FILE__, __LINE__, #expr); exit(1); }
-
-/** Variadic debugging printf() implementation.
- *
- * @param fmt Format string for printed output.
- */
-#define DPRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
-
-#else
-
-/** Non-debug assert - does nothing.
- *
- * @param expr The expression to test.
- */
-#define ASSERT(expr)
-
-/** Non-debug printf - does nothing.
- *
- * @param fmt Format string for printed output.
- */
-#define DPRINTF(fmt, ...)
-
-#endif
-
-/** Get a couple of required attributes into a handy format. */
-#if __GNUC__ >= 3
-
-/* Check for portable attribute definitions and create them if they are missing */
-#ifndef inline
-#define inline inline __attribute__ ((always_inline))
-#endif
-#ifndef __packed
-#define __packed __attribute__ ((packed))
-#endif
-
-#else
-
-/* Toolchain is too old or doesn't support the attributes we need */
-#ifndef inline
-#define inline TOOLCHAIN_ERROR_NO_INLINE
-#endif
-#ifndef __packed
-#define __packed TOOLCHAIN_ERROR_NO_PACKED
-#endif
-
-#endif
-
-/** Read an unsigned 32 bit value from the address given (may be unaligned). */
-#define RD_L(ptr) (*(__packed uint32_t *)(ptr))
-
-/** Read an unsigned 16 bit value from the address given (may be unaligned). */
-#define RD_S(ptr) (*(__packed uint16_t *)(ptr))
-
-/** Read an unsigned byte from the address given. */
-#define RD_B(ptr) (*(uint8_t *)(ptr))
-
-/** Surpress warnings about unused variables. */
-#define IGNORE(x) do { (void) (x); } while (0)
-
-/** Record the line and source file associated with a particular type of error event. */
-#define REC_ERR() { snprintf(&err_file[0], 1024, "%s", __FILE__); err_line = __LINE__; }
-
-/** If a called function (cmd) returns an error code, return the error code from the calling function. */
-#define ERR(cmd) do { dlo_retcode_t __err = (cmd); if (__err != dlo_ok) return __err; } while(0)
-
-/** If a usb_ function call returns an error code, return an error and store the code in the @a usberr global. */
-#define UERR(cmd) do { usberr = (cmd); if (usberr < 0) return usb_error_grab(); } while (0)
-
-/** If a memory-allocating call returns NULL, return with a memory allocation error code. */
-#define NERR(ptr) do { if (!(ptr)) { REC_ERR(); return dlo_err_memory; } } while (0)
-
-/** If a function call (cmd) returns an error code, jump to the "error" label. Requires variable declaration: dlo_retcode_t err; */
-#define ERR_GOTO(cmd) do { err = (cmd); if (err != dlo_ok) goto error; } while(0)
-
-/** If a usb_ function call returns an error code, jump to the "error" label and store the usb error code in the @a usberr global. */
-#define UERR_GOTO(cmd) do { usberr = (cmd); if (usberr < 0) { err = usb_error_grab(); goto error; } } while(0)
-
-/** If a memory-allocating call returns NULL, jump to the "error" label with a memory allocation error code. */
-#define NERR_GOTO(ptr) do { if (!(ptr)) { REC_ERR(); err = dlo_err_memory; goto error; } } while(0)
-
-/** Return the size of a hash-defined string, excluding the terminator (unlike strlen(), it does count null bytes in the string). */
-#define DSIZEOF(str) (sizeof(str) - 1)
-
-/** Swap two integer values (assumes they are the same size). */
-#define SWAP(a, b) do { (a) = (a) ^ (b); (b) = (a) ^ (b); (a) = (a) ^ (b); } while (0)
-
-/** Magic macro for calling functions from pointer tables (after first checking the device structure pointer and the function pointer). */
-#define CALL(dev, fn, ...) dev ? ( dev->fn ? dev->fn(dev, ##__VA_ARGS__) : dlo_err_unsupported ) : dlo_err_bad_device
-
-/** Number of bytes per 16 bpp pixel! */
-#define BYTES_PER_16BPP (2)
-
-/** Number of bytes per 8 bpp pixel! */
-#define BYTES_PER_8BPP (1)
-
-/** Convert a framebuffer pixel format into a number of bytes per pixel. */
-#define FORMAT_TO_BYTES_PER_PIXEL(fmt) ((unsigned int)fmt > 1023u ? 1 : ((fmt) & DLO_PIXFMT_BYPP_MSK) >> DLO_PIXFMT_BYPP_SFT)
-
-/** Default buffer size for sending commands to the device. */
-#define BUF_SIZE (64*1024u)
-
-/** Threshold (bytes away from being full) for flushing the command buffer before adding any more commands to it. */
-#define BUF_HIGH_WATER_MARK (1*1024u)
-
-/** A 16 bits per pixel colour number (not normally used outside libdlo). */
-typedef uint16_t dlo_col16_t;
-
-/** An 8 bits per pixel colour number (2_rrrggbbb - not normally used outside libdlo). */
-typedef uint8_t dlo_col8_t;
-
-/** Integer used to store error number for last failed call to a dlo_usb_ function. */
-extern int32_t usberr;
-
-/** Integer used to store error number for last failed call to a dlo_eth_ function. */
-extern int32_t etherr;
-
-/** Source file name for the last recorded error event. */
-extern char err_file[1024];
-
-/** Source line number for last recorded error event. */
-extern uint32_t err_line;
-
-
-#endif
+/** @file dlo_defs.h + * + * @brief This file defines common macros and so on for the DisplayLink libdlo library. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef DLO_DLOCOMMON_H +#define DLO_DLOCOMMON_H /**< Avoid multiple inclusion. */ + +#include <stdint.h> +#include <stdio.h> + +#ifdef DEBUG + +/** Assert that a given expression evaluates to a non-zero number. + * + * @param expr The expression to test. + */ +#define ASSERT(expr) if (!(expr)) { printf("<%s:%u>\n Assertion '%s' failed.\n", __FILE__, __LINE__, #expr); exit(1); } + +/** Variadic debugging printf() implementation. + * + * @param fmt Format string for printed output. + */ +#define DPRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__) + +#else + +/** Non-debug assert - does nothing. + * + * @param expr The expression to test. + */ +#define ASSERT(expr) + +/** Non-debug printf - does nothing. + * + * @param fmt Format string for printed output. + */ +#define DPRINTF(fmt, ...) + +#endif + +/** Get a couple of required attributes into a handy format. */ +#if __GNUC__ >= 3 + +/* Check for portable attribute definitions and create them if they are missing */ +#ifndef inline +#define inline inline __attribute__ ((always_inline)) +#endif +#ifndef __packed +#define __packed __attribute__ ((packed)) +#endif + +#else + +/* Toolchain is too old or doesn't support the attributes we need */ +#ifndef inline +#define inline TOOLCHAIN_ERROR_NO_INLINE +#endif +#ifndef __packed +#define __packed TOOLCHAIN_ERROR_NO_PACKED +#endif + +#endif + +/** Read an unsigned 32 bit value from the address given (may be unaligned). */ +#define RD_L(ptr) (*(__packed uint32_t *)(ptr)) + +/** Read an unsigned 16 bit value from the address given (may be unaligned). */ +#define RD_S(ptr) (*(__packed uint16_t *)(ptr)) + +/** Read an unsigned byte from the address given. */ +#define RD_B(ptr) (*(uint8_t *)(ptr)) + +/** Surpress warnings about unused variables. */ +#define IGNORE(x) do { (void) (x); } while (0) + +/** Record the line and source file associated with a particular type of error event. */ +#define REC_ERR() { snprintf(&err_file[0], 1024, "%s", __FILE__); err_line = __LINE__; } + +/** If a called function (cmd) returns an error code, return the error code from the calling function. */ +#define ERR(cmd) do { dlo_retcode_t __err = (cmd); if (__err != dlo_ok) return __err; } while(0) + +/** If a usb_ function call returns an error code, return an error and store the code in the @a usberr global. */ +#define UERR(cmd) do { usberr = (cmd); if (usberr < 0) return usb_error_grab(); } while (0) + +/** If a memory-allocating call returns NULL, return with a memory allocation error code. */ +#define NERR(ptr) do { if (!(ptr)) { REC_ERR(); return dlo_err_memory; } } while (0) + +/** If a function call (cmd) returns an error code, jump to the "error" label. Requires variable declaration: dlo_retcode_t err; */ +#define ERR_GOTO(cmd) do { err = (cmd); if (err != dlo_ok) goto error; } while(0) + +/** If a usb_ function call returns an error code, jump to the "error" label and store the usb error code in the @a usberr global. */ +#define UERR_GOTO(cmd) do { usberr = (cmd); if (usberr < 0) { err = usb_error_grab(); goto error; } } while(0) + +/** If a memory-allocating call returns NULL, jump to the "error" label with a memory allocation error code. */ +#define NERR_GOTO(ptr) do { if (!(ptr)) { REC_ERR(); err = dlo_err_memory; goto error; } } while(0) + +/** Return the size of a hash-defined string, excluding the terminator (unlike strlen(), it does count null bytes in the string). */ +#define DSIZEOF(str) (sizeof(str) - 1) + +/** Swap two integer values (assumes they are the same size). */ +#define SWAP(a, b) do { (a) = (a) ^ (b); (b) = (a) ^ (b); (a) = (a) ^ (b); } while (0) + +/** Magic macro for calling functions from pointer tables (after first checking the device structure pointer and the function pointer). */ +#define CALL(dev, fn, ...) dev ? ( dev->fn ? dev->fn(dev, ##__VA_ARGS__) : dlo_err_unsupported ) : dlo_err_bad_device + +/** Number of bytes per 16 bpp pixel! */ +#define BYTES_PER_16BPP (2) + +/** Number of bytes per 8 bpp pixel! */ +#define BYTES_PER_8BPP (1) + +/** Convert a framebuffer pixel format into a number of bytes per pixel. */ +#define FORMAT_TO_BYTES_PER_PIXEL(fmt) ((unsigned int)fmt > 1023u ? 1 : ((fmt) & DLO_PIXFMT_BYPP_MSK) >> DLO_PIXFMT_BYPP_SFT) + +/** Default buffer size for sending commands to the device. */ +#define BUF_SIZE (64*1024u) + +/** Threshold (bytes away from being full) for flushing the command buffer before adding any more commands to it. */ +#define BUF_HIGH_WATER_MARK (1*1024u) + +/** A 16 bits per pixel colour number (not normally used outside libdlo). */ +typedef uint16_t dlo_col16_t; + +/** An 8 bits per pixel colour number (2_rrrggbbb - not normally used outside libdlo). */ +typedef uint8_t dlo_col8_t; + +/** Integer used to store error number for last failed call to a dlo_usb_ function. */ +extern int32_t usberr; + +/** Integer used to store error number for last failed call to a dlo_eth_ function. */ +extern int32_t etherr; + +/** Source file name for the last recorded error event. */ +extern char err_file[1024]; + +/** Source line number for last recorded error event. */ +extern uint32_t err_line; + + +#endif diff --git a/src/dlo_grfx.c b/src/dlo_grfx.c index cb0dd48..822ec9b 100644 --- a/src/dlo_grfx.c +++ b/src/dlo_grfx.c @@ -1,843 +1,843 @@ -/** @file dlo_grfx.c
- *
- * @brief This file implements the graphics primitive operations.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <string.h>
-#include "dlo_defs.h"
-#include "dlo_grfx.h"
-#include "dlo_usb.h"
-
-
-/* File-scope defines ------------------------------------------------------------------*/
-
-
-/** Maximum number of pixels that can be supplied to a raw write command. */
-#define RAW_MAX_PIXELS (256)
-
-/** Maximum number of pixels that will fit into the scrape buffer. */
-#define SCRAPE_MAX_PIXELS (2048)
-
-/** Simple wrapper around the @c dlo_free() call to first check the pointer and zero it after the free. */
-#define FREE(ptr) { if (ptr) { dlo_free(ptr); ptr = NULL; } }
-
-/** Return red/green component of a 16 bpp colour number. */
-#define DLO_RG16(red, grn) (uint8_t)((((red) & 0xF8) | ((grn) >> 5)) & 0xFF)
-
-/** Return green/blue component of a 16 bpp colour number. */
-#define DLO_GB16(grn, blu) (uint8_t)(((((grn) & 0x1C) << 3) | ((blu) >> 3)) & 0xFF)
-
-/** Return 8 bpp colour number from red, green and blue components. */
-#define DLO_RGB8(red, grn, blu) ((((red) << 5) | (((grn) & 3) << 3) | ((blu) & 7)) & 0xFF)
-
-
-/* File-scope inline functions ---------------------------------------------------------*/
-
-
-/** Build a "plot horizontal line" command in a buffer.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param base Destination address in device for start of line.
- * @param remain Line length.
- * @param col Colour of point to plot.
- *
- * @return Return code, zero for no error.
- */
-inline dlo_retcode_t cmd_hline16(dlo_device_t * const dev, const dlo_ptr_t base, const uint32_t remain, const dlo_col16_t col)
-{
- if (dev->bufend - dev->bufptr < 9)
- return dlo_err_buf_full;
-
- *(dev->bufptr)++ = WRITE_RL16[0];
- *(dev->bufptr)++ = WRITE_RL16[1];
- *(dev->bufptr)++ = (char)(base >> 16);
- *(dev->bufptr)++ = (char)(base >> 8);
- *(dev->bufptr)++ = (char)base;
- *(dev->bufptr)++ = (char)remain;
- *(dev->bufptr)++ = (char)remain;
- *(dev->bufptr)++ = (char)(col >> 8);
- *(dev->bufptr)++ = (char)col;
-
- return dlo_ok;
-}
-
-
-
-/** Build a "plot horizontal line" command in a buffer for fine detail colour space.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param base Destination address in device for start of line.
- * @param remain Line length.
- * @param col Colour of point to plot.
- *
- * @return Return code, zero for no error.
- */
-inline dlo_retcode_t cmd_hline8(dlo_device_t * const dev, const dlo_ptr_t base, const uint32_t remain, const dlo_col8_t col)
-{
- if (dev->bufend - dev->bufptr < 8)
- return dlo_err_buf_full;
-
- *(dev->bufptr)++ = WRITE_RL8[0];
- *(dev->bufptr)++ = WRITE_RL8[1];
- *(dev->bufptr)++ = (char)(base >> 16);
- *(dev->bufptr)++ = (char)(base >> 8);
- *(dev->bufptr)++ = (char)base;
- *(dev->bufptr)++ = (char)remain;
- *(dev->bufptr)++ = (char)remain;
- *(dev->bufptr)++ = (char)col;
-
- return dlo_ok;
-}
-
-
-/** Build a "copy horizontal line" command in a buffer.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param src Source address in device for start of copy.
- * @param len Copy length.
- * @param dest Destination address in device for copy.
- *
- * @return Return code, zero for no error.
- */
-inline dlo_retcode_t cmd_copy16(dlo_device_t * const dev, const dlo_ptr_t src, const uint32_t len, const dlo_ptr_t dest)
-{
- if (dev->bufend - dev->bufptr < 9)
- return dlo_err_buf_full;
-
- *(dev->bufptr)++ = WRITE_COPY16[0];
- *(dev->bufptr)++ = WRITE_COPY16[1];
- *(dev->bufptr)++ = (char)(dest >> 16);
- *(dev->bufptr)++ = (char)(dest >> 8);
- *(dev->bufptr)++ = (char)dest;
- *(dev->bufptr)++ = len == 256 ? '\0' : (char)len;
- *(dev->bufptr)++ = (char)(src >> 16);
- *(dev->bufptr)++ = (char)(src >> 8);
- *(dev->bufptr)++ = (char)src;
-
- return dlo_ok;
-}
-
-
-/** Build a "copy horizontal line" command in a buffer for fine detail colour space.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param src Source address in device for start of copy.
- * @param len Copy length.
- * @param dest Destination address in device for copy.
- *
- * @return Return code, zero for no error.
- */
-inline dlo_retcode_t cmd_copy8(dlo_device_t * const dev, const dlo_ptr_t src, const uint32_t len, const dlo_ptr_t dest)
-{
- if (dev->bufend - dev->bufptr < 9)
- return dlo_err_buf_full;
-
- *(dev->bufptr)++ = WRITE_COPY8[0];
- *(dev->bufptr)++ = WRITE_COPY8[1];
- *(dev->bufptr)++ = (char)(dest >> 16);
- *(dev->bufptr)++ = (char)(dest >> 8);
- *(dev->bufptr)++ = (char)dest;
- *(dev->bufptr)++ = len == 256 ? '\0' : (char)len;
- *(dev->bufptr)++ = (char)(src >> 16);
- *(dev->bufptr)++ = (char)(src >> 8);
- *(dev->bufptr)++ = (char)src;
-
- return dlo_ok;
-}
-
-
-/* Ensure the inline functions get compiled somewhere in case they cannot be inlined */
-extern dlo_retcode_t cmd_hline16(dlo_device_t * const dev, const dlo_ptr_t base, const uint32_t remain, const dlo_col16_t col);
-extern dlo_retcode_t cmd_hline8( dlo_device_t * const dev, const dlo_ptr_t base, const uint32_t remain, const dlo_col8_t col);
-extern dlo_retcode_t cmd_copy16( dlo_device_t * const dev, const dlo_ptr_t src, const uint32_t len, const dlo_ptr_t dest);
-extern dlo_retcode_t cmd_copy8( dlo_device_t * const dev, const dlo_ptr_t src, const uint32_t len, const dlo_ptr_t dest);
-
-
-/* File-scope types --------------------------------------------------------------------*/
-
-
-/** Function pointer for functions to convert a pixel into a colour number.
- *
- * @param ptr Pointer to pixel.
- * @param swap Flag to indicate red and blue components need to be swapped.
- *
- * @return Colour number for read pixel.
- */
-typedef dlo_col32_t (*read_pixel_t) (const uint8_t * const ptr, const bool swap);
-
-
-/* File-scope variables ----------------------------------------------------------------*/
-
-
-/** Look-up table of function pointers for a specified pixel format.
- */
-static read_pixel_t fmt_to_fn[DLO_PIXFMT_MAX];
-
-
-/** Standard look-up table for converting 8 bpp pixels in bgr323 format into colour numbers.
- */
-static dlo_col32_t lut8bpp[256];
-
-
-/** Look-up table to use when reading 8 bpp pixels - required by @c read_pixel_323().
- */
-static dlo_col32_t *lut = lut8bpp;
-
-
-/** Pointer to an array for storing a stripe of 16bpp pixel information.
- */
-static dlo_col16_t *stripe16 = NULL;
-
-
-/** Pointer to an array for storing a stripe of 8bpp pixel information.
- */
-static dlo_col8_t *stripe8 = NULL;
-
-
-/* External-scope variables ------------------------------------------------------------*/
-
-
-/* File-scope function declarations ----------------------------------------------------*/
-
-
-/** Plot a section of horizontal line in the specified colour at 24 bpp.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param base16 Base address of destination 16 bpp pixel data.
- * @param base8 Base address of destination 8 bpp pixel data.
- * @param len Length of the line (pixels).
- * @param col Colour of the line.
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t hline_24bpp(dlo_device_t * const dev, dlo_ptr_t base16, dlo_ptr_t base8, const uint32_t len, const dlo_col32_t col);
-
-
-/** Copy a section of horizontal line from one location to another at 24 bpp.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param src_base16 Base address of source 16 bpp pixel data.
- * @param dest_base16 Base address of destination 16 bpp pixel data.
- * @param src_base8 Base address of source 8 bpp pixel data.
- * @param dest_base8 Base address of destination 8 bpp pixel data.
- * @param len Length of the line (pixels).
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t copy_24bpp(dlo_device_t * const dev, dlo_ptr_t src_base16, dlo_ptr_t dest_base16, dlo_ptr_t src_base8, dlo_ptr_t dest_base8, const uint32_t len);
-
-
-/** Scrape a horizontal line of host-resident pixels at 24 bpp into the device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param rdpx Pointer to the pixel reading function.
- * @param bypp Bytes per pixel of the source pixels.
- * @param swap Flag: swap the red/blue component order.
- * @param src_base Base address of the source.
- * @param dest_base16 Base address of destination 16 bpp pixel data.
- * @param dest_base8 Base address of destination 8 bpp pixel data.
- * @param width Width of the scrape (pixels).
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t scrape_24bpp(dlo_device_t * const dev, const read_pixel_t rdpx, const uint32_t bypp, const bool swap,
- const uint8_t *src_base, dlo_ptr_t dest_base16, dlo_ptr_t dest_base8, const uint32_t width);
-
-
-/** Dump the contents of the scrape buffers as a horizontal pixel row at 24 bpp.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param base16 Base address of destination 16 bpp pixel data.
- * @param base8 Base address of destination 8 bpp pixel data.
- * @param width Width of the scrape (pixels).
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t cmd_stripe24(dlo_device_t * const dev, dlo_ptr_t base16, dlo_ptr_t base8, const uint32_t width);
-
-
-/** Given a 32 bpp colour number, return an 8 bpp colour number.
- *
- * @param col 32 bpp colour number.
- *
- * @return 8 bpp colour number.
- */
-static dlo_col8_t rgb8(dlo_col32_t col);
-
-
-/** Given a 32 bpp colour number, return a 16 bpp colour number.
- *
- * @param col 32 bpp colour number.
- *
- * @return 16 bpp colour number.
- */
-static dlo_col16_t rgb16(dlo_col32_t col);
-
-
-/** Dummy pixel reading function for an uninitialised entry.
- *
- * @param ptr Pointer to pixel.
- * @param swap Flag to indicate red and blue components need to be swapped.
- *
- * @return Colour number for read pixel.
- */
-static dlo_col32_t read_pixel_NULL(const uint8_t * const ptr, const bool swap);
-
-
-/** Read an 8 bpp pixel in 323 format.
- *
- * @param ptr Pointer to pixel.
- * @param swap Flag to indicate red and blue components need to be swapped.
- *
- * @return Colour number for read pixel.
- */
-static dlo_col32_t read_pixel_323(const uint8_t * const ptr, const bool swap);
-
-
-/** Read a 16 bpp pixel in 565 format.
- *
- * @param ptr Pointer to pixel.
- * @param swap Flag to indicate red and blue components need to be swapped.
- *
- * @return Colour number for read pixel.
- */
-static dlo_col32_t read_pixel_565(const uint8_t * const ptr, const bool swap);
-
-
-/** Read a 16 bpp pixel in 1555 format.
- *
- * @param ptr Pointer to pixel.
- * @param swap Flag to indicate red and blue components need to be swapped.
- *
- * @return Colour number for read pixel.
- */
-static dlo_col32_t read_pixel_1555(const uint8_t * const ptr, const bool swap);
-
-
-/** Read a 24 bpp pixel in 888 format.
- *
- * @param ptr Pointer to pixel.
- * @param swap Flag to indicate red and blue components need to be swapped.
- *
- * @return Colour number for read pixel.
- */
-static dlo_col32_t read_pixel_888(const uint8_t * const ptr, const bool swap);
-
-
-/** Read a 32 bpp pixel in 8888 format.
- *
- * @param ptr Pointer to pixel.
- * @param swap Flag to indicate red and blue components need to be swapped.
- *
- * @return Colour number for read pixel.
- */
-static dlo_col32_t read_pixel_8888(const uint8_t * const ptr, const bool swap);
-
-
-/* Public function definitions ---------------------------------------------------------*/
-
-
-dlo_retcode_t dlo_grfx_init(const dlo_init_t flags)
-{
- uint32_t i;
- uint8_t red, grn, blu;
- uint8_t red8, grn8, blu8;
-
- stripe16 = malloc(SCRAPE_MAX_PIXELS * sizeof(dlo_col16_t));
- NERR(stripe16);
- stripe8 = malloc(SCRAPE_MAX_PIXELS * sizeof(dlo_col8_t));
- NERR(stripe8);
-
- /* Initialise the default look-up table for 8 bpp in bgr323 format */
- for (red = 0; red < 8; red++)
- for (grn = 0; grn < 4; grn++)
- for (blu = 0; blu < 8; blu++)
- {
- uint8_t idx = red + (grn << 3) + (blu << 5);
-
- red8 = (red << 5) | (red << 2) | (red >> 1);
- grn8 = (grn << 6) | (grn << 4) | (grn << 2) | grn;
- blu8 = (blu << 5) | (blu << 2) | (blu >> 1);
- lut8bpp[idx] = DLO_RGB(red8, grn8, blu8);
- }
-
- /* Initialise the look-up table of pixel formats to pixel reading functions */
- for (i = 0; i < DLO_PIXFMT_MAX; i++)
- fmt_to_fn[i] = read_pixel_NULL;
- fmt_to_fn[dlo_pixfmt_bgr323] = read_pixel_323;
- fmt_to_fn[dlo_pixfmt_rgb323] = read_pixel_323;
- fmt_to_fn[dlo_pixfmt_bgr565] = read_pixel_565;
- fmt_to_fn[dlo_pixfmt_rgb565] = read_pixel_565;
- fmt_to_fn[dlo_pixfmt_sbgr1555] = read_pixel_1555;
- fmt_to_fn[dlo_pixfmt_srgb1555] = read_pixel_1555;
- fmt_to_fn[dlo_pixfmt_bgr888] = read_pixel_888;
- fmt_to_fn[dlo_pixfmt_rgb888] = read_pixel_888;
- fmt_to_fn[dlo_pixfmt_abgr8888] = read_pixel_8888;
- fmt_to_fn[dlo_pixfmt_argb8888] = read_pixel_8888;
-
- return dlo_ok;
-}
-
-
-dlo_retcode_t dlo_grfx_final(const dlo_final_t flags)
-{
- FREE(stripe16);
- FREE(stripe8);
-
- return dlo_ok;
-}
-
-
-dlo_retcode_t dlo_grfx_fill_rect(dlo_device_t * const dev, const dlo_area_t * const area, const dlo_col32_t col)
-{
- dlo_ptr_t base16, base8;
- uint32_t end;
-
- ASSERT(dev && area)
- ASSERT(area->view.width && area->view.height);
-
- /* Only 24 bpp is supported */
- if (area->view.bpp != 24)
- return dlo_err_bad_col;
-
- /* Compute some useful values */
- base16 = area->view.base;
- base8 = area->base8;
- end = base16 + (BYTES_PER_16BPP * area->stride * area->view.height);
-
- /* Plot the rectangle, one pixel row at a time */
- for (; base16 < end; base16 += BYTES_PER_16BPP * area->stride)
- {
- ERR(hline_24bpp(dev, base16, base8, area->view.width, col));
- base8 += BYTES_PER_8BPP * area->stride;
- }
- return dlo_usb_write(dev);
-}
-
-
-dlo_retcode_t dlo_grfx_copy_rect(dlo_device_t * const dev, const dlo_area_t * const src_area, const dlo_area_t * const dest_area, const bool overlap)
-{
- dlo_ptr_t src_base16, src_base8;
- dlo_ptr_t dest_base16, dest_base8;
- uint32_t end;
-
- ASSERT(dev && src_area && dest_area);
- ASSERT(src_area->view.width && src_area->view.height);
- ASSERT(src_area->view.width == dest_area->view.width && src_area->view.height == dest_area->view.height);
- ASSERT(src_area->view.bpp == dest_area->view.bpp);
-
- /* Only 24 bpp is supported */
- if (src_area->view.bpp != 24)
- return dlo_err_bad_col;
-
- /* Quick exit if we're copying to and from the same location */
- if (src_area->view.base == dest_area->view.base)
- return dlo_ok;
-
- /* Compute some useful values */
- if (src_area->view.base < dest_area->view.base)
- {
- uint32_t y;
-
- src_base16 = src_area->view.base + (BYTES_PER_16BPP * src_area->stride * src_area->view.height);
- src_base8 = src_area->base8 + (BYTES_PER_8BPP * src_area->stride * src_area->view.height);
- dest_base16 = dest_area->view.base + (BYTES_PER_16BPP * dest_area->stride * dest_area->view.height);
- dest_base8 = dest_area->base8 + (BYTES_PER_8BPP * dest_area->stride * dest_area->view.height);
-
- /* Copy the rectangle, one pixel row at a time */
- for (y = src_area->view.height; y > 0; y--)
- {
- src_base16 -= BYTES_PER_16BPP * src_area->stride;
- src_base8 -= BYTES_PER_8BPP * src_area->stride;
- dest_base16 -= BYTES_PER_16BPP * dest_area->stride;
- dest_base8 -= BYTES_PER_8BPP * dest_area->stride;
- ERR(copy_24bpp(dev, src_base16, dest_base16, src_base8, dest_base8, src_area->view.width));
-// if (overlap)
-// ERR(dlo_usb_write(dev));
- }
- }
- else
- {
- src_base16 = src_area->view.base;
- src_base8 = src_area->base8;
- dest_base16 = dest_area->view.base;
- dest_base8 = dest_area->base8;
- end = src_base16 + (BYTES_PER_16BPP * src_area->stride * src_area->view.height);
-
- /* Copy the rectangle, one pixel row at a time */
- for (; src_base16 < end; src_base16 += BYTES_PER_16BPP * src_area->stride)
- {
- ERR(copy_24bpp(dev, src_base16, dest_base16, src_base8, dest_base8, src_area->view.width));
- src_base8 += BYTES_PER_8BPP * src_area->stride;
- dest_base16 += BYTES_PER_16BPP * dest_area->stride;
- dest_base8 += BYTES_PER_8BPP * dest_area->stride;
-// if (overlap)
-// ERR(dlo_usb_write(dev));
- }
- }
- return dlo_usb_write(dev);
-}
-
-
-dlo_retcode_t dlo_grfx_copy_host_bmp(dlo_device_t * const dev, const dlo_bmpflags_t flags, const dlo_fbuf_t const *fbuf, const dlo_area_t * const area)
-{
- uint8_t *src_base;
- uint8_t *end;
- dlo_ptr_t dest_base16, dest_base8;
- uint32_t bypp;
- read_pixel_t rdpx;
- bool swap;
-
- ASSERT(dev && fbuf && area);
- ASSERT(fbuf->width && fbuf->height && fbuf->base && fbuf->stride);
- ASSERT(fbuf->width == area->view.width && fbuf->height == area->view.height)
-
- /* Only 24 bpp is supported */
- if (area->view.bpp != 24)
- return dlo_err_bad_col;
-
- /* Get a pixel reading function pointer for the fbuf */
- if (fbuf->fmt >> DLO_PIXFMT_PTR_SFT)
- {
- bypp = 1;
- rdpx = read_pixel_323;
- swap = false;
- lut = (dlo_col32_t *)fbuf->fmt;
- }
- else
- {
- if ((int)fbuf->fmt > (int)dlo_pixfmt_argb8888)
- return dlo_err_bad_fmt;
-
- bypp = FORMAT_TO_BYTES_PER_PIXEL(fbuf->fmt);
- rdpx = fmt_to_fn[fbuf->fmt];
- swap = fbuf->fmt & DLO_PIXFMT_SWP ? true : false;
- lut = lut8bpp; /* For unpaletted bitmaps, the LUT is our standard colour palette */
- }
-
- /* Check that a row from the bitmap will fit into the scrape buffers */
- if (fbuf->width > SCRAPE_MAX_PIXELS)
- return dlo_err_big_scrape;
-
- /* Set up the destination pointers in the device memory */
- dest_base16 = area->view.base;
- dest_base8 = area->base8;
-
- /* Either copy down or up the bitmap, depending upon whether we are doing a vertical flip */
- if (flags.v_flip)
- {
- src_base = (uint8_t *)fbuf->base + (bypp * fbuf->stride * (area->view.height - 1));
- end = (uint8_t *)fbuf->base;
-
- for (; src_base >= end; src_base -= bypp * fbuf->stride)
- {
- ERR(scrape_24bpp(dev, rdpx, bypp, swap, src_base, dest_base16, dest_base8, fbuf->width));
- dest_base16 += BYTES_PER_16BPP * area->stride;
- dest_base8 += BYTES_PER_8BPP * area->stride;
- }
- }
- else
- {
- src_base = (uint8_t *)fbuf->base;
- end = src_base + (bypp * fbuf->stride * area->view.height);
-
- for (; src_base < end; src_base += bypp * fbuf->stride)
- {
- ERR(scrape_24bpp(dev, rdpx, bypp, swap, src_base, dest_base16, dest_base8, fbuf->width));
- dest_base16 += BYTES_PER_16BPP * area->stride;
- dest_base8 += BYTES_PER_8BPP * area->stride;
- }
- }
- return dlo_usb_write(dev);
-}
-
-
-/* File-scope function definitions -----------------------------------------------------*/
-
-
-static dlo_retcode_t hline_24bpp(dlo_device_t * const dev, dlo_ptr_t base16, dlo_ptr_t base8, const uint32_t len, const dlo_col32_t col)
-{
- dlo_col16_t col16 = rgb16(col);
- dlo_col8_t col8 = rgb8(col);
- uint32_t rem = len % 256;
-
- /* Flush the command buffer if it's getting full */
- if (dev->bufend - dev->bufptr < BUF_HIGH_WATER_MARK)
- ERR(dlo_usb_write(dev));
-
- /* Is this a short line segment? */
- if (len < 256)
- {
- ERR(cmd_hline16(dev, base16, len, col16));
- ERR(cmd_hline8( dev, base8, len, col8));
- }
- else
- {
- /* Longer line segments require a few commands to complete */
- uint32_t roff16 = base16 + (BYTES_PER_16BPP * (len - rem));
- uint32_t roff8 = base8 + (BYTES_PER_8BPP * (len - rem));
-
- for (; base16 < roff16; base16 += BYTES_PER_16BPP * 256)
- {
- ERR(cmd_hline16(dev, base16, 0, col16));
- ERR(cmd_hline8( dev, base8, 0, col8));
- base8 += BYTES_PER_8BPP * 256;
- }
- if (rem)
- {
- ERR(cmd_hline16(dev, roff16, rem, col16));
- ERR(cmd_hline8( dev, roff8, rem, col8));
- }
- }
- return dlo_ok;
-}
-
-
-static dlo_retcode_t copy_24bpp(dlo_device_t * const dev, dlo_ptr_t src_base16, dlo_ptr_t dest_base16, dlo_ptr_t src_base8, dlo_ptr_t dest_base8, const uint32_t len)
-{
- uint32_t rem = len % 256;
-
- /* Flush the command buffer if it's getting full */
- if (dev->bufend - dev->bufptr < BUF_HIGH_WATER_MARK)
- ERR(dlo_usb_write(dev));
-
- /* Is this a short line segment? */
- if (len < 256)
- {
- ERR(cmd_copy16(dev, src_base16, len, dest_base16));
- ERR(cmd_copy8( dev, src_base8, len, dest_base8));
- }
- else
- {
- /* Longer line segments require a few commands to complete */
- uint32_t src_roff16 = src_base16 + (BYTES_PER_16BPP * (len - rem));
- uint32_t dest_roff16 = dest_base16 + (BYTES_PER_16BPP * (len - rem));
- uint32_t src_roff8 = src_base8 + (BYTES_PER_8BPP * (len - rem));
- uint32_t dest_roff8 = dest_base8 + (BYTES_PER_8BPP * (len - rem));
-
- for (; src_base16 < src_roff16; src_base16 += BYTES_PER_16BPP * 256)
- {
- ERR(cmd_copy16(dev, src_base16, 0, dest_base16));
- ERR(cmd_copy8( dev, src_base8, 0, dest_base8));
- dest_base16 += BYTES_PER_16BPP * 256;
- src_base8 += BYTES_PER_8BPP * 256;
- dest_base8 += BYTES_PER_8BPP * 256;
- }
- if (rem)
- {
- ERR(cmd_copy16(dev, src_roff16, rem, dest_roff16));
- ERR(cmd_copy8( dev, src_roff8, rem, dest_roff8));
- }
- }
- return dlo_ok;
-}
-
-
-static dlo_retcode_t scrape_24bpp(dlo_device_t * const dev, const read_pixel_t rdpx, const uint32_t bypp, const bool swap,
- const uint8_t *src_base, dlo_ptr_t dest_base16, dlo_ptr_t dest_base8, const uint32_t width)
-{
- const uint8_t *end = src_base + (bypp * width);
- dlo_col16_t *ptr_col16 = stripe16;
- dlo_col8_t *ptr_col8 = stripe8;
-
- /* Read a stripe from the source bitmap into the internal colour format */
- for (; src_base < end; src_base += bypp)
- {
- dlo_col32_t col = rdpx(src_base, swap);
-
- *ptr_col16++ = rgb16(col);
- *ptr_col8++ = rgb8(col);
- }
- return cmd_stripe24(dev, dest_base16, dest_base8, width);
-}
-
-
-static dlo_retcode_t cmd_stripe24(dlo_device_t * const dev, dlo_ptr_t base16, dlo_ptr_t base8, const uint32_t width)
-{
- dlo_col16_t *ptr_col16 = stripe16;
- dlo_col8_t *ptr_col8 = stripe8;
- dlo_ptr_t end = base16 + (BYTES_PER_16BPP * width);
- uint32_t rem = width;
- uint32_t pix;
-
- /* Flush the command buffer if it's getting full */
- if (dev->bufend - dev->bufptr < BUF_HIGH_WATER_MARK)
- ERR(dlo_usb_write(dev));
-
- for (; base16 < end; base16 += BYTES_PER_16BPP * RAW_MAX_PIXELS)
- {
- *(dev->bufptr)++ = WRITE_RAW16[0];
- *(dev->bufptr)++ = WRITE_RAW16[1];
- *(dev->bufptr)++ = (char)(base16 >> 16);
- *(dev->bufptr)++ = (char)(base16 >> 8);
- *(dev->bufptr)++ = (char)(base16 & 0xFF);
- *(dev->bufptr)++ = rem >= RAW_MAX_PIXELS ? 0 : rem;
-
- /* Flush the command buffer if it's getting full */
- if (dev->bufend - dev->bufptr - BYTES_PER_16BPP * RAW_MAX_PIXELS < BUF_HIGH_WATER_MARK)
- ERR(dlo_usb_write(dev));
-
- for (pix = 0; pix < (rem >= RAW_MAX_PIXELS ? RAW_MAX_PIXELS : rem); pix++)
- {
- dlo_col16_t col = *ptr_col16++;
-
- *(dev->bufptr)++ = (char)(col >> 8);
- *(dev->bufptr)++ = (char)(col & 0xFF);
- }
- rem -= RAW_MAX_PIXELS;
- }
-
- end = base8 + (BYTES_PER_8BPP * width);
-
- for (; base8 < end; base8 += BYTES_PER_8BPP * RAW_MAX_PIXELS)
- {
- *(dev->bufptr)++ = WRITE_RAW8[0];
- *(dev->bufptr)++ = WRITE_RAW8[1];
- *(dev->bufptr)++ = (char)(base8 >> 16);
- *(dev->bufptr)++ = (char)(base8 >> 8);
- *(dev->bufptr)++ = (char)(base8 & 0xFF);
- *(dev->bufptr)++ = rem >= RAW_MAX_PIXELS ? 0 : rem;
-
- /* Flush the command buffer if it's getting full */
- if (dev->bufend - dev->bufptr - BYTES_PER_8BPP * RAW_MAX_PIXELS < BUF_HIGH_WATER_MARK)
- ERR(dlo_usb_write(dev));
-
- for (pix = 0; pix < (rem >= RAW_MAX_PIXELS ? RAW_MAX_PIXELS : rem); pix++)
- *(dev->bufptr)++ = (char)(*ptr_col8++);
-
- rem -= RAW_MAX_PIXELS;
- }
- return dlo_ok;
-}
-
-
-static dlo_col32_t read_pixel_NULL(const uint8_t * const ptr, const bool swap)
-{
- DPRINTF("grfx: WARNING: unknown dlo_pixfmt_t doesn't map to a read_pixel_*() function\n");
- return DLO_RGB(0, 0, 0);
-}
-
-
-static dlo_col32_t read_pixel_323(const uint8_t * const ptr, const bool swap)
-{
- dlo_col32_t col = lut[*ptr];
-
- if (swap)
- {
- uint8_t red, grn, blu;
-
- red = DLO_RGB_GETRED(col);
- grn = DLO_RGB_GETGRN(col);
- blu = DLO_RGB_GETBLU(col);
- return DLO_RGB(blu, grn, red);
- }
- return col;
-}
-
-
-static dlo_col32_t read_pixel_565(const uint8_t * const ptr, const bool swap)
-{
- dlo_col32_t col;
- uint16_t *pix = (uint16_t *)ptr;
- uint8_t red, grn, blu;
-
- col = *pix;
- red = (col & 0x001F) << 3;
- grn = (col & 0x07E0) >> 3;
- blu = (col & 0xF800) >> 8;
- red = red | (red >> 5);
- grn = grn | (grn >> 5);
- blu = blu | (blu >> 5);
-
- return swap ? DLO_RGB(blu, grn, red) : DLO_RGB(red, grn, blu);
-}
-
-
-static dlo_col32_t read_pixel_1555(const uint8_t * const ptr, const bool swap)
-{
- dlo_col32_t col;
- uint16_t *pix = (uint16_t *)ptr;
- uint8_t red, grn, blu;
-
- col = *pix;
- red = (col & 0x001F) << 3;
- grn = (col & 0x03E0) >> 2;
- blu = (col & 0x7C00) >> 7;
- red = red | (red >> 5);
- grn = grn | (grn >> 5);
- blu = blu | (blu >> 5);
-
- return swap ? DLO_RGB(blu, grn, red) : DLO_RGB(red, grn, blu);
-}
-
-
-static dlo_col32_t read_pixel_888(const uint8_t * const ptr, const bool swap)
-{
- uint8_t red, grn, blu;
-
- red = ptr[0];
- grn = ptr[1];
- blu = ptr[2];
-
- return swap ? DLO_RGB(blu, grn, red) : DLO_RGB(red, grn, blu);
-}
-
-
-static dlo_col32_t read_pixel_8888(const uint8_t * const ptr, const bool swap)
-{
- dlo_col32_t col;
- uint32_t *pix = (uint32_t *)ptr;
-
- col = (dlo_col32_t) *pix;
-
- if (swap)
- {
- uint8_t red, grn, blu;
-
- red = DLO_RGB_GETRED(col);
- grn = DLO_RGB_GETGRN(col);
- blu = DLO_RGB_GETBLU(col);
- return DLO_RGB(blu, grn, red);
- }
- return col;
-}
-
-
-static dlo_col8_t rgb8(dlo_col32_t col)
-{
- uint8_t red = DLO_RGB_GETRED(col);
- uint8_t grn = DLO_RGB_GETGRN(col);
- uint8_t blu = DLO_RGB_GETBLU(col);
-
- return DLO_RGB8(red, grn, blu);
-}
-
-
-static dlo_col16_t rgb16(dlo_col32_t col)
-{
- uint8_t red = DLO_RGB_GETRED(col);
- uint8_t grn = DLO_RGB_GETGRN(col);
- uint8_t blu = DLO_RGB_GETBLU(col);
-
- return (DLO_RG16(red, grn) << 8) + DLO_GB16(grn, blu);
-}
-
-
-/* End of file -------------------------------------------------------------------------*/
+/** @file dlo_grfx.c + * + * @brief This file implements the graphics primitive operations. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <string.h> +#include "dlo_defs.h" +#include "dlo_grfx.h" +#include "dlo_usb.h" + + +/* File-scope defines ------------------------------------------------------------------*/ + + +/** Maximum number of pixels that can be supplied to a raw write command. */ +#define RAW_MAX_PIXELS (256) + +/** Maximum number of pixels that will fit into the scrape buffer. */ +#define SCRAPE_MAX_PIXELS (2048) + +/** Simple wrapper around the @c dlo_free() call to first check the pointer and zero it after the free. */ +#define FREE(ptr) { if (ptr) { dlo_free(ptr); ptr = NULL; } } + +/** Return red/green component of a 16 bpp colour number. */ +#define DLO_RG16(red, grn) (uint8_t)((((red) & 0xF8) | ((grn) >> 5)) & 0xFF) + +/** Return green/blue component of a 16 bpp colour number. */ +#define DLO_GB16(grn, blu) (uint8_t)(((((grn) & 0x1C) << 3) | ((blu) >> 3)) & 0xFF) + +/** Return 8 bpp colour number from red, green and blue components. */ +#define DLO_RGB8(red, grn, blu) ((((red) << 5) | (((grn) & 3) << 3) | ((blu) & 7)) & 0xFF) + + +/* File-scope inline functions ---------------------------------------------------------*/ + + +/** Build a "plot horizontal line" command in a buffer. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param base Destination address in device for start of line. + * @param remain Line length. + * @param col Colour of point to plot. + * + * @return Return code, zero for no error. + */ +inline dlo_retcode_t cmd_hline16(dlo_device_t * const dev, const dlo_ptr_t base, const uint32_t remain, const dlo_col16_t col) +{ + if (dev->bufend - dev->bufptr < 9) + return dlo_err_buf_full; + + *(dev->bufptr)++ = WRITE_RL16[0]; + *(dev->bufptr)++ = WRITE_RL16[1]; + *(dev->bufptr)++ = (char)(base >> 16); + *(dev->bufptr)++ = (char)(base >> 8); + *(dev->bufptr)++ = (char)base; + *(dev->bufptr)++ = (char)remain; + *(dev->bufptr)++ = (char)remain; + *(dev->bufptr)++ = (char)(col >> 8); + *(dev->bufptr)++ = (char)col; + + return dlo_ok; +} + + + +/** Build a "plot horizontal line" command in a buffer for fine detail colour space. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param base Destination address in device for start of line. + * @param remain Line length. + * @param col Colour of point to plot. + * + * @return Return code, zero for no error. + */ +inline dlo_retcode_t cmd_hline8(dlo_device_t * const dev, const dlo_ptr_t base, const uint32_t remain, const dlo_col8_t col) +{ + if (dev->bufend - dev->bufptr < 8) + return dlo_err_buf_full; + + *(dev->bufptr)++ = WRITE_RL8[0]; + *(dev->bufptr)++ = WRITE_RL8[1]; + *(dev->bufptr)++ = (char)(base >> 16); + *(dev->bufptr)++ = (char)(base >> 8); + *(dev->bufptr)++ = (char)base; + *(dev->bufptr)++ = (char)remain; + *(dev->bufptr)++ = (char)remain; + *(dev->bufptr)++ = (char)col; + + return dlo_ok; +} + + +/** Build a "copy horizontal line" command in a buffer. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param src Source address in device for start of copy. + * @param len Copy length. + * @param dest Destination address in device for copy. + * + * @return Return code, zero for no error. + */ +inline dlo_retcode_t cmd_copy16(dlo_device_t * const dev, const dlo_ptr_t src, const uint32_t len, const dlo_ptr_t dest) +{ + if (dev->bufend - dev->bufptr < 9) + return dlo_err_buf_full; + + *(dev->bufptr)++ = WRITE_COPY16[0]; + *(dev->bufptr)++ = WRITE_COPY16[1]; + *(dev->bufptr)++ = (char)(dest >> 16); + *(dev->bufptr)++ = (char)(dest >> 8); + *(dev->bufptr)++ = (char)dest; + *(dev->bufptr)++ = len == 256 ? '\0' : (char)len; + *(dev->bufptr)++ = (char)(src >> 16); + *(dev->bufptr)++ = (char)(src >> 8); + *(dev->bufptr)++ = (char)src; + + return dlo_ok; +} + + +/** Build a "copy horizontal line" command in a buffer for fine detail colour space. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param src Source address in device for start of copy. + * @param len Copy length. + * @param dest Destination address in device for copy. + * + * @return Return code, zero for no error. + */ +inline dlo_retcode_t cmd_copy8(dlo_device_t * const dev, const dlo_ptr_t src, const uint32_t len, const dlo_ptr_t dest) +{ + if (dev->bufend - dev->bufptr < 9) + return dlo_err_buf_full; + + *(dev->bufptr)++ = WRITE_COPY8[0]; + *(dev->bufptr)++ = WRITE_COPY8[1]; + *(dev->bufptr)++ = (char)(dest >> 16); + *(dev->bufptr)++ = (char)(dest >> 8); + *(dev->bufptr)++ = (char)dest; + *(dev->bufptr)++ = len == 256 ? '\0' : (char)len; + *(dev->bufptr)++ = (char)(src >> 16); + *(dev->bufptr)++ = (char)(src >> 8); + *(dev->bufptr)++ = (char)src; + + return dlo_ok; +} + + +/* Ensure the inline functions get compiled somewhere in case they cannot be inlined */ +extern dlo_retcode_t cmd_hline16(dlo_device_t * const dev, const dlo_ptr_t base, const uint32_t remain, const dlo_col16_t col); +extern dlo_retcode_t cmd_hline8( dlo_device_t * const dev, const dlo_ptr_t base, const uint32_t remain, const dlo_col8_t col); +extern dlo_retcode_t cmd_copy16( dlo_device_t * const dev, const dlo_ptr_t src, const uint32_t len, const dlo_ptr_t dest); +extern dlo_retcode_t cmd_copy8( dlo_device_t * const dev, const dlo_ptr_t src, const uint32_t len, const dlo_ptr_t dest); + + +/* File-scope types --------------------------------------------------------------------*/ + + +/** Function pointer for functions to convert a pixel into a colour number. + * + * @param ptr Pointer to pixel. + * @param swap Flag to indicate red and blue components need to be swapped. + * + * @return Colour number for read pixel. + */ +typedef dlo_col32_t (*read_pixel_t) (const uint8_t * const ptr, const bool swap); + + +/* File-scope variables ----------------------------------------------------------------*/ + + +/** Look-up table of function pointers for a specified pixel format. + */ +static read_pixel_t fmt_to_fn[DLO_PIXFMT_MAX]; + + +/** Standard look-up table for converting 8 bpp pixels in bgr323 format into colour numbers. + */ +static dlo_col32_t lut8bpp[256]; + + +/** Look-up table to use when reading 8 bpp pixels - required by @c read_pixel_323(). + */ +static dlo_col32_t *lut = lut8bpp; + + +/** Pointer to an array for storing a stripe of 16bpp pixel information. + */ +static dlo_col16_t *stripe16 = NULL; + + +/** Pointer to an array for storing a stripe of 8bpp pixel information. + */ +static dlo_col8_t *stripe8 = NULL; + + +/* External-scope variables ------------------------------------------------------------*/ + + +/* File-scope function declarations ----------------------------------------------------*/ + + +/** Plot a section of horizontal line in the specified colour at 24 bpp. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param base16 Base address of destination 16 bpp pixel data. + * @param base8 Base address of destination 8 bpp pixel data. + * @param len Length of the line (pixels). + * @param col Colour of the line. + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t hline_24bpp(dlo_device_t * const dev, dlo_ptr_t base16, dlo_ptr_t base8, const uint32_t len, const dlo_col32_t col); + + +/** Copy a section of horizontal line from one location to another at 24 bpp. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param src_base16 Base address of source 16 bpp pixel data. + * @param dest_base16 Base address of destination 16 bpp pixel data. + * @param src_base8 Base address of source 8 bpp pixel data. + * @param dest_base8 Base address of destination 8 bpp pixel data. + * @param len Length of the line (pixels). + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t copy_24bpp(dlo_device_t * const dev, dlo_ptr_t src_base16, dlo_ptr_t dest_base16, dlo_ptr_t src_base8, dlo_ptr_t dest_base8, const uint32_t len); + + +/** Scrape a horizontal line of host-resident pixels at 24 bpp into the device. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param rdpx Pointer to the pixel reading function. + * @param bypp Bytes per pixel of the source pixels. + * @param swap Flag: swap the red/blue component order. + * @param src_base Base address of the source. + * @param dest_base16 Base address of destination 16 bpp pixel data. + * @param dest_base8 Base address of destination 8 bpp pixel data. + * @param width Width of the scrape (pixels). + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t scrape_24bpp(dlo_device_t * const dev, const read_pixel_t rdpx, const uint32_t bypp, const bool swap, + const uint8_t *src_base, dlo_ptr_t dest_base16, dlo_ptr_t dest_base8, const uint32_t width); + + +/** Dump the contents of the scrape buffers as a horizontal pixel row at 24 bpp. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param base16 Base address of destination 16 bpp pixel data. + * @param base8 Base address of destination 8 bpp pixel data. + * @param width Width of the scrape (pixels). + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t cmd_stripe24(dlo_device_t * const dev, dlo_ptr_t base16, dlo_ptr_t base8, const uint32_t width); + + +/** Given a 32 bpp colour number, return an 8 bpp colour number. + * + * @param col 32 bpp colour number. + * + * @return 8 bpp colour number. + */ +static dlo_col8_t rgb8(dlo_col32_t col); + + +/** Given a 32 bpp colour number, return a 16 bpp colour number. + * + * @param col 32 bpp colour number. + * + * @return 16 bpp colour number. + */ +static dlo_col16_t rgb16(dlo_col32_t col); + + +/** Dummy pixel reading function for an uninitialised entry. + * + * @param ptr Pointer to pixel. + * @param swap Flag to indicate red and blue components need to be swapped. + * + * @return Colour number for read pixel. + */ +static dlo_col32_t read_pixel_NULL(const uint8_t * const ptr, const bool swap); + + +/** Read an 8 bpp pixel in 323 format. + * + * @param ptr Pointer to pixel. + * @param swap Flag to indicate red and blue components need to be swapped. + * + * @return Colour number for read pixel. + */ +static dlo_col32_t read_pixel_323(const uint8_t * const ptr, const bool swap); + + +/** Read a 16 bpp pixel in 565 format. + * + * @param ptr Pointer to pixel. + * @param swap Flag to indicate red and blue components need to be swapped. + * + * @return Colour number for read pixel. + */ +static dlo_col32_t read_pixel_565(const uint8_t * const ptr, const bool swap); + + +/** Read a 16 bpp pixel in 1555 format. + * + * @param ptr Pointer to pixel. + * @param swap Flag to indicate red and blue components need to be swapped. + * + * @return Colour number for read pixel. + */ +static dlo_col32_t read_pixel_1555(const uint8_t * const ptr, const bool swap); + + +/** Read a 24 bpp pixel in 888 format. + * + * @param ptr Pointer to pixel. + * @param swap Flag to indicate red and blue components need to be swapped. + * + * @return Colour number for read pixel. + */ +static dlo_col32_t read_pixel_888(const uint8_t * const ptr, const bool swap); + + +/** Read a 32 bpp pixel in 8888 format. + * + * @param ptr Pointer to pixel. + * @param swap Flag to indicate red and blue components need to be swapped. + * + * @return Colour number for read pixel. + */ +static dlo_col32_t read_pixel_8888(const uint8_t * const ptr, const bool swap); + + +/* Public function definitions ---------------------------------------------------------*/ + + +dlo_retcode_t dlo_grfx_init(const dlo_init_t flags) +{ + uint32_t i; + uint8_t red, grn, blu; + uint8_t red8, grn8, blu8; + + stripe16 = malloc(SCRAPE_MAX_PIXELS * sizeof(dlo_col16_t)); + NERR(stripe16); + stripe8 = malloc(SCRAPE_MAX_PIXELS * sizeof(dlo_col8_t)); + NERR(stripe8); + + /* Initialise the default look-up table for 8 bpp in bgr323 format */ + for (red = 0; red < 8; red++) + for (grn = 0; grn < 4; grn++) + for (blu = 0; blu < 8; blu++) + { + uint8_t idx = red + (grn << 3) + (blu << 5); + + red8 = (red << 5) | (red << 2) | (red >> 1); + grn8 = (grn << 6) | (grn << 4) | (grn << 2) | grn; + blu8 = (blu << 5) | (blu << 2) | (blu >> 1); + lut8bpp[idx] = DLO_RGB(red8, grn8, blu8); + } + + /* Initialise the look-up table of pixel formats to pixel reading functions */ + for (i = 0; i < DLO_PIXFMT_MAX; i++) + fmt_to_fn[i] = read_pixel_NULL; + fmt_to_fn[dlo_pixfmt_bgr323] = read_pixel_323; + fmt_to_fn[dlo_pixfmt_rgb323] = read_pixel_323; + fmt_to_fn[dlo_pixfmt_bgr565] = read_pixel_565; + fmt_to_fn[dlo_pixfmt_rgb565] = read_pixel_565; + fmt_to_fn[dlo_pixfmt_sbgr1555] = read_pixel_1555; + fmt_to_fn[dlo_pixfmt_srgb1555] = read_pixel_1555; + fmt_to_fn[dlo_pixfmt_bgr888] = read_pixel_888; + fmt_to_fn[dlo_pixfmt_rgb888] = read_pixel_888; + fmt_to_fn[dlo_pixfmt_abgr8888] = read_pixel_8888; + fmt_to_fn[dlo_pixfmt_argb8888] = read_pixel_8888; + + return dlo_ok; +} + + +dlo_retcode_t dlo_grfx_final(const dlo_final_t flags) +{ + FREE(stripe16); + FREE(stripe8); + + return dlo_ok; +} + + +dlo_retcode_t dlo_grfx_fill_rect(dlo_device_t * const dev, const dlo_area_t * const area, const dlo_col32_t col) +{ + dlo_ptr_t base16, base8; + uint32_t end; + + ASSERT(dev && area) + ASSERT(area->view.width && area->view.height); + + /* Only 24 bpp is supported */ + if (area->view.bpp != 24) + return dlo_err_bad_col; + + /* Compute some useful values */ + base16 = area->view.base; + base8 = area->base8; + end = base16 + (BYTES_PER_16BPP * area->stride * area->view.height); + + /* Plot the rectangle, one pixel row at a time */ + for (; base16 < end; base16 += BYTES_PER_16BPP * area->stride) + { + ERR(hline_24bpp(dev, base16, base8, area->view.width, col)); + base8 += BYTES_PER_8BPP * area->stride; + } + return dlo_usb_write(dev); +} + + +dlo_retcode_t dlo_grfx_copy_rect(dlo_device_t * const dev, const dlo_area_t * const src_area, const dlo_area_t * const dest_area, const bool overlap) +{ + dlo_ptr_t src_base16, src_base8; + dlo_ptr_t dest_base16, dest_base8; + uint32_t end; + + ASSERT(dev && src_area && dest_area); + ASSERT(src_area->view.width && src_area->view.height); + ASSERT(src_area->view.width == dest_area->view.width && src_area->view.height == dest_area->view.height); + ASSERT(src_area->view.bpp == dest_area->view.bpp); + + /* Only 24 bpp is supported */ + if (src_area->view.bpp != 24) + return dlo_err_bad_col; + + /* Quick exit if we're copying to and from the same location */ + if (src_area->view.base == dest_area->view.base) + return dlo_ok; + + /* Compute some useful values */ + if (src_area->view.base < dest_area->view.base) + { + uint32_t y; + + src_base16 = src_area->view.base + (BYTES_PER_16BPP * src_area->stride * src_area->view.height); + src_base8 = src_area->base8 + (BYTES_PER_8BPP * src_area->stride * src_area->view.height); + dest_base16 = dest_area->view.base + (BYTES_PER_16BPP * dest_area->stride * dest_area->view.height); + dest_base8 = dest_area->base8 + (BYTES_PER_8BPP * dest_area->stride * dest_area->view.height); + + /* Copy the rectangle, one pixel row at a time */ + for (y = src_area->view.height; y > 0; y--) + { + src_base16 -= BYTES_PER_16BPP * src_area->stride; + src_base8 -= BYTES_PER_8BPP * src_area->stride; + dest_base16 -= BYTES_PER_16BPP * dest_area->stride; + dest_base8 -= BYTES_PER_8BPP * dest_area->stride; + ERR(copy_24bpp(dev, src_base16, dest_base16, src_base8, dest_base8, src_area->view.width)); +// if (overlap) +// ERR(dlo_usb_write(dev)); + } + } + else + { + src_base16 = src_area->view.base; + src_base8 = src_area->base8; + dest_base16 = dest_area->view.base; + dest_base8 = dest_area->base8; + end = src_base16 + (BYTES_PER_16BPP * src_area->stride * src_area->view.height); + + /* Copy the rectangle, one pixel row at a time */ + for (; src_base16 < end; src_base16 += BYTES_PER_16BPP * src_area->stride) + { + ERR(copy_24bpp(dev, src_base16, dest_base16, src_base8, dest_base8, src_area->view.width)); + src_base8 += BYTES_PER_8BPP * src_area->stride; + dest_base16 += BYTES_PER_16BPP * dest_area->stride; + dest_base8 += BYTES_PER_8BPP * dest_area->stride; +// if (overlap) +// ERR(dlo_usb_write(dev)); + } + } + return dlo_usb_write(dev); +} + + +dlo_retcode_t dlo_grfx_copy_host_bmp(dlo_device_t * const dev, const dlo_bmpflags_t flags, const dlo_fbuf_t const *fbuf, const dlo_area_t * const area) +{ + uint8_t *src_base; + uint8_t *end; + dlo_ptr_t dest_base16, dest_base8; + uint32_t bypp; + read_pixel_t rdpx; + bool swap; + + ASSERT(dev && fbuf && area); + ASSERT(fbuf->width && fbuf->height && fbuf->base && fbuf->stride); + ASSERT(fbuf->width == area->view.width && fbuf->height == area->view.height) + + /* Only 24 bpp is supported */ + if (area->view.bpp != 24) + return dlo_err_bad_col; + + /* Get a pixel reading function pointer for the fbuf */ + if (fbuf->fmt >> DLO_PIXFMT_PTR_SFT) + { + bypp = 1; + rdpx = read_pixel_323; + swap = false; + lut = (dlo_col32_t *)fbuf->fmt; + } + else + { + if ((int)fbuf->fmt > (int)dlo_pixfmt_argb8888) + return dlo_err_bad_fmt; + + bypp = FORMAT_TO_BYTES_PER_PIXEL(fbuf->fmt); + rdpx = fmt_to_fn[fbuf->fmt]; + swap = fbuf->fmt & DLO_PIXFMT_SWP ? true : false; + lut = lut8bpp; /* For unpaletted bitmaps, the LUT is our standard colour palette */ + } + + /* Check that a row from the bitmap will fit into the scrape buffers */ + if (fbuf->width > SCRAPE_MAX_PIXELS) + return dlo_err_big_scrape; + + /* Set up the destination pointers in the device memory */ + dest_base16 = area->view.base; + dest_base8 = area->base8; + + /* Either copy down or up the bitmap, depending upon whether we are doing a vertical flip */ + if (flags.v_flip) + { + src_base = (uint8_t *)fbuf->base + (bypp * fbuf->stride * (area->view.height - 1)); + end = (uint8_t *)fbuf->base; + + for (; src_base >= end; src_base -= bypp * fbuf->stride) + { + ERR(scrape_24bpp(dev, rdpx, bypp, swap, src_base, dest_base16, dest_base8, fbuf->width)); + dest_base16 += BYTES_PER_16BPP * area->stride; + dest_base8 += BYTES_PER_8BPP * area->stride; + } + } + else + { + src_base = (uint8_t *)fbuf->base; + end = src_base + (bypp * fbuf->stride * area->view.height); + + for (; src_base < end; src_base += bypp * fbuf->stride) + { + ERR(scrape_24bpp(dev, rdpx, bypp, swap, src_base, dest_base16, dest_base8, fbuf->width)); + dest_base16 += BYTES_PER_16BPP * area->stride; + dest_base8 += BYTES_PER_8BPP * area->stride; + } + } + return dlo_usb_write(dev); +} + + +/* File-scope function definitions -----------------------------------------------------*/ + + +static dlo_retcode_t hline_24bpp(dlo_device_t * const dev, dlo_ptr_t base16, dlo_ptr_t base8, const uint32_t len, const dlo_col32_t col) +{ + dlo_col16_t col16 = rgb16(col); + dlo_col8_t col8 = rgb8(col); + uint32_t rem = len % 256; + + /* Flush the command buffer if it's getting full */ + if (dev->bufend - dev->bufptr < BUF_HIGH_WATER_MARK) + ERR(dlo_usb_write(dev)); + + /* Is this a short line segment? */ + if (len < 256) + { + ERR(cmd_hline16(dev, base16, len, col16)); + ERR(cmd_hline8( dev, base8, len, col8)); + } + else + { + /* Longer line segments require a few commands to complete */ + uint32_t roff16 = base16 + (BYTES_PER_16BPP * (len - rem)); + uint32_t roff8 = base8 + (BYTES_PER_8BPP * (len - rem)); + + for (; base16 < roff16; base16 += BYTES_PER_16BPP * 256) + { + ERR(cmd_hline16(dev, base16, 0, col16)); + ERR(cmd_hline8( dev, base8, 0, col8)); + base8 += BYTES_PER_8BPP * 256; + } + if (rem) + { + ERR(cmd_hline16(dev, roff16, rem, col16)); + ERR(cmd_hline8( dev, roff8, rem, col8)); + } + } + return dlo_ok; +} + + +static dlo_retcode_t copy_24bpp(dlo_device_t * const dev, dlo_ptr_t src_base16, dlo_ptr_t dest_base16, dlo_ptr_t src_base8, dlo_ptr_t dest_base8, const uint32_t len) +{ + uint32_t rem = len % 256; + + /* Flush the command buffer if it's getting full */ + if (dev->bufend - dev->bufptr < BUF_HIGH_WATER_MARK) + ERR(dlo_usb_write(dev)); + + /* Is this a short line segment? */ + if (len < 256) + { + ERR(cmd_copy16(dev, src_base16, len, dest_base16)); + ERR(cmd_copy8( dev, src_base8, len, dest_base8)); + } + else + { + /* Longer line segments require a few commands to complete */ + uint32_t src_roff16 = src_base16 + (BYTES_PER_16BPP * (len - rem)); + uint32_t dest_roff16 = dest_base16 + (BYTES_PER_16BPP * (len - rem)); + uint32_t src_roff8 = src_base8 + (BYTES_PER_8BPP * (len - rem)); + uint32_t dest_roff8 = dest_base8 + (BYTES_PER_8BPP * (len - rem)); + + for (; src_base16 < src_roff16; src_base16 += BYTES_PER_16BPP * 256) + { + ERR(cmd_copy16(dev, src_base16, 0, dest_base16)); + ERR(cmd_copy8( dev, src_base8, 0, dest_base8)); + dest_base16 += BYTES_PER_16BPP * 256; + src_base8 += BYTES_PER_8BPP * 256; + dest_base8 += BYTES_PER_8BPP * 256; + } + if (rem) + { + ERR(cmd_copy16(dev, src_roff16, rem, dest_roff16)); + ERR(cmd_copy8( dev, src_roff8, rem, dest_roff8)); + } + } + return dlo_ok; +} + + +static dlo_retcode_t scrape_24bpp(dlo_device_t * const dev, const read_pixel_t rdpx, const uint32_t bypp, const bool swap, + const uint8_t *src_base, dlo_ptr_t dest_base16, dlo_ptr_t dest_base8, const uint32_t width) +{ + const uint8_t *end = src_base + (bypp * width); + dlo_col16_t *ptr_col16 = stripe16; + dlo_col8_t *ptr_col8 = stripe8; + + /* Read a stripe from the source bitmap into the internal colour format */ + for (; src_base < end; src_base += bypp) + { + dlo_col32_t col = rdpx(src_base, swap); + + *ptr_col16++ = rgb16(col); + *ptr_col8++ = rgb8(col); + } + return cmd_stripe24(dev, dest_base16, dest_base8, width); +} + + +static dlo_retcode_t cmd_stripe24(dlo_device_t * const dev, dlo_ptr_t base16, dlo_ptr_t base8, const uint32_t width) +{ + dlo_col16_t *ptr_col16 = stripe16; + dlo_col8_t *ptr_col8 = stripe8; + dlo_ptr_t end = base16 + (BYTES_PER_16BPP * width); + uint32_t rem = width; + uint32_t pix; + + /* Flush the command buffer if it's getting full */ + if (dev->bufend - dev->bufptr < BUF_HIGH_WATER_MARK) + ERR(dlo_usb_write(dev)); + + for (; base16 < end; base16 += BYTES_PER_16BPP * RAW_MAX_PIXELS) + { + *(dev->bufptr)++ = WRITE_RAW16[0]; + *(dev->bufptr)++ = WRITE_RAW16[1]; + *(dev->bufptr)++ = (char)(base16 >> 16); + *(dev->bufptr)++ = (char)(base16 >> 8); + *(dev->bufptr)++ = (char)(base16 & 0xFF); + *(dev->bufptr)++ = rem >= RAW_MAX_PIXELS ? 0 : rem; + + /* Flush the command buffer if it's getting full */ + if (dev->bufend - dev->bufptr - BYTES_PER_16BPP * RAW_MAX_PIXELS < BUF_HIGH_WATER_MARK) + ERR(dlo_usb_write(dev)); + + for (pix = 0; pix < (rem >= RAW_MAX_PIXELS ? RAW_MAX_PIXELS : rem); pix++) + { + dlo_col16_t col = *ptr_col16++; + + *(dev->bufptr)++ = (char)(col >> 8); + *(dev->bufptr)++ = (char)(col & 0xFF); + } + rem -= RAW_MAX_PIXELS; + } + + end = base8 + (BYTES_PER_8BPP * width); + + for (; base8 < end; base8 += BYTES_PER_8BPP * RAW_MAX_PIXELS) + { + *(dev->bufptr)++ = WRITE_RAW8[0]; + *(dev->bufptr)++ = WRITE_RAW8[1]; + *(dev->bufptr)++ = (char)(base8 >> 16); + *(dev->bufptr)++ = (char)(base8 >> 8); + *(dev->bufptr)++ = (char)(base8 & 0xFF); + *(dev->bufptr)++ = rem >= RAW_MAX_PIXELS ? 0 : rem; + + /* Flush the command buffer if it's getting full */ + if (dev->bufend - dev->bufptr - BYTES_PER_8BPP * RAW_MAX_PIXELS < BUF_HIGH_WATER_MARK) + ERR(dlo_usb_write(dev)); + + for (pix = 0; pix < (rem >= RAW_MAX_PIXELS ? RAW_MAX_PIXELS : rem); pix++) + *(dev->bufptr)++ = (char)(*ptr_col8++); + + rem -= RAW_MAX_PIXELS; + } + return dlo_ok; +} + + +static dlo_col32_t read_pixel_NULL(const uint8_t * const ptr, const bool swap) +{ + DPRINTF("grfx: WARNING: unknown dlo_pixfmt_t doesn't map to a read_pixel_*() function\n"); + return DLO_RGB(0, 0, 0); +} + + +static dlo_col32_t read_pixel_323(const uint8_t * const ptr, const bool swap) +{ + dlo_col32_t col = lut[*ptr]; + + if (swap) + { + uint8_t red, grn, blu; + + red = DLO_RGB_GETRED(col); + grn = DLO_RGB_GETGRN(col); + blu = DLO_RGB_GETBLU(col); + return DLO_RGB(blu, grn, red); + } + return col; +} + + +static dlo_col32_t read_pixel_565(const uint8_t * const ptr, const bool swap) +{ + dlo_col32_t col; + uint16_t *pix = (uint16_t *)ptr; + uint8_t red, grn, blu; + + col = *pix; + red = (col & 0x001F) << 3; + grn = (col & 0x07E0) >> 3; + blu = (col & 0xF800) >> 8; + red = red | (red >> 5); + grn = grn | (grn >> 5); + blu = blu | (blu >> 5); + + return swap ? DLO_RGB(blu, grn, red) : DLO_RGB(red, grn, blu); +} + + +static dlo_col32_t read_pixel_1555(const uint8_t * const ptr, const bool swap) +{ + dlo_col32_t col; + uint16_t *pix = (uint16_t *)ptr; + uint8_t red, grn, blu; + + col = *pix; + red = (col & 0x001F) << 3; + grn = (col & 0x03E0) >> 2; + blu = (col & 0x7C00) >> 7; + red = red | (red >> 5); + grn = grn | (grn >> 5); + blu = blu | (blu >> 5); + + return swap ? DLO_RGB(blu, grn, red) : DLO_RGB(red, grn, blu); +} + + +static dlo_col32_t read_pixel_888(const uint8_t * const ptr, const bool swap) +{ + uint8_t red, grn, blu; + + red = ptr[0]; + grn = ptr[1]; + blu = ptr[2]; + + return swap ? DLO_RGB(blu, grn, red) : DLO_RGB(red, grn, blu); +} + + +static dlo_col32_t read_pixel_8888(const uint8_t * const ptr, const bool swap) +{ + dlo_col32_t col; + uint32_t *pix = (uint32_t *)ptr; + + col = (dlo_col32_t) *pix; + + if (swap) + { + uint8_t red, grn, blu; + + red = DLO_RGB_GETRED(col); + grn = DLO_RGB_GETGRN(col); + blu = DLO_RGB_GETBLU(col); + return DLO_RGB(blu, grn, red); + } + return col; +} + + +static dlo_col8_t rgb8(dlo_col32_t col) +{ + uint8_t red = DLO_RGB_GETRED(col); + uint8_t grn = DLO_RGB_GETGRN(col); + uint8_t blu = DLO_RGB_GETBLU(col); + + return DLO_RGB8(red, grn, blu); +} + + +static dlo_col16_t rgb16(dlo_col32_t col) +{ + uint8_t red = DLO_RGB_GETRED(col); + uint8_t grn = DLO_RGB_GETGRN(col); + uint8_t blu = DLO_RGB_GETBLU(col); + + return (DLO_RG16(red, grn) << 8) + DLO_GB16(grn, blu); +} + + +/* End of file -------------------------------------------------------------------------*/ diff --git a/src/dlo_grfx.h b/src/dlo_grfx.h index 15ce3b9..58147c6 100644 --- a/src/dlo_grfx.h +++ b/src/dlo_grfx.h @@ -1,93 +1,93 @@ -/** @file dlo_grfx.h
- *
- * @brief This file defines the external API of the DisplayLink libdlo graphics functions.
- *
- * This API is used by clients of the Bitmap Manager (e.g. other parts of libdlo) to access its
- * features. It is intended that all implementation details are abstracted-away by this interface.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DLO_GRFX_H
-#define DLO_GRFX_H /**< Avoid multiple inclusion. */
-
-#include "dlo_structs.h"
-
-
-#define WRITE_RAW8 "\xAF\x60" /**< 8 bit raw write command. */
-#define WRITE_RL8 "\xAF\x61" /**< 8 bit run length write command. */
-#define WRITE_COPY8 "\xAF\x62" /**< 8 bit copy command. */
-#define WRITE_RAW16 "\xAF\x68" /**< 16 bit raw write command. */
-#define WRITE_RL16 "\xAF\x69" /**< 16 bit run length write command. */
-#define WRITE_COPY16 "\xAF\x6A" /**< 16 bit copy command. */
-
-
-/** Initialise the graphics primitive routines.
- *
- * @param flags Initialisation flags word (unused flags ignored).
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_grfx_init(const dlo_init_t flags);
-
-
-/** Finalisation call for graphics primitive routines.
- *
- * @param flags Finalisation flags word (unused flags ignored).
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_grfx_final(const dlo_final_t flags);
-
-
-/** Plot a filled rectangle into the specified device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param area Struct pointer: area within device memory to fill.
- * @param col Colour of filled rectangle.
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_grfx_fill_rect(dlo_device_t * const dev, const dlo_area_t * const area, const dlo_col32_t col);
-
-
-/** Copy a rectangular area within the device from one location to another.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param src_area Struct pointer: area within device memory to copy from.
- * @param dest_area Struct pointer: area within device memory to copy to.
- * @param overlap true if rectangles overlap or false if not.
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_grfx_copy_rect(dlo_device_t * const dev, const dlo_area_t * const src_area, const dlo_area_t * const dest_area, const bool overlap);
-
-
-/** Copy (and translate pixel formats) a rectangular area from host memory into the device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param flags Flags word indicating special behaviour (unused flags should be zero).
- * @param fbuf Struct pointer: area within host memory to copy from.
- * @param area Struct pointer: area within device memory to copy into.
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_grfx_copy_host_bmp(dlo_device_t * const dev, const dlo_bmpflags_t flags, const dlo_fbuf_t const *fbuf, const dlo_area_t * const area);
-
-
-#endif
+/** @file dlo_grfx.h + * + * @brief This file defines the external API of the DisplayLink libdlo graphics functions. + * + * This API is used by clients of the Bitmap Manager (e.g. other parts of libdlo) to access its + * features. It is intended that all implementation details are abstracted-away by this interface. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef DLO_GRFX_H +#define DLO_GRFX_H /**< Avoid multiple inclusion. */ + +#include "dlo_structs.h" + + +#define WRITE_RAW8 "\xAF\x60" /**< 8 bit raw write command. */ +#define WRITE_RL8 "\xAF\x61" /**< 8 bit run length write command. */ +#define WRITE_COPY8 "\xAF\x62" /**< 8 bit copy command. */ +#define WRITE_RAW16 "\xAF\x68" /**< 16 bit raw write command. */ +#define WRITE_RL16 "\xAF\x69" /**< 16 bit run length write command. */ +#define WRITE_COPY16 "\xAF\x6A" /**< 16 bit copy command. */ + + +/** Initialise the graphics primitive routines. + * + * @param flags Initialisation flags word (unused flags ignored). + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_grfx_init(const dlo_init_t flags); + + +/** Finalisation call for graphics primitive routines. + * + * @param flags Finalisation flags word (unused flags ignored). + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_grfx_final(const dlo_final_t flags); + + +/** Plot a filled rectangle into the specified device. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param area Struct pointer: area within device memory to fill. + * @param col Colour of filled rectangle. + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_grfx_fill_rect(dlo_device_t * const dev, const dlo_area_t * const area, const dlo_col32_t col); + + +/** Copy a rectangular area within the device from one location to another. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param src_area Struct pointer: area within device memory to copy from. + * @param dest_area Struct pointer: area within device memory to copy to. + * @param overlap true if rectangles overlap or false if not. + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_grfx_copy_rect(dlo_device_t * const dev, const dlo_area_t * const src_area, const dlo_area_t * const dest_area, const bool overlap); + + +/** Copy (and translate pixel formats) a rectangular area from host memory into the device. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param flags Flags word indicating special behaviour (unused flags should be zero). + * @param fbuf Struct pointer: area within host memory to copy from. + * @param area Struct pointer: area within device memory to copy into. + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_grfx_copy_host_bmp(dlo_device_t * const dev, const dlo_bmpflags_t flags, const dlo_fbuf_t const *fbuf, const dlo_area_t * const area); + + +#endif diff --git a/src/dlo_mode.c b/src/dlo_mode.c index 68d27a4..c5ade6e 100644 --- a/src/dlo_mode.c +++ b/src/dlo_mode.c @@ -1,926 +1,926 @@ -/** @file dlo_mode.c
- *
- * @brief Implementation of the screen mode-related functions.
- *
- * See dlo_mode.h for more information.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "dlo_defs.h"
-#include "dlo_mode.h"
-#include "dlo_data.h"
-#include "dlo_usb.h"
-
-
-/* File-scope defines ------------------------------------------------------------------*/
-
-
-/** Pre-defined EDID header used to check that data read from a device is valid.
- */
-const uint8_t header[8] =
-{
- 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00
-};
-
-/** Constant used for deciding if a host is big- or little endian.
- */
-const uint32_t endian = 1;
-
-/** Unlock video registers command.
- */
-#define WRITE_VIDREG_LOCK "\xAF\x20\xFF\x00"
-
-/** Lock video registers command.
- */
-#define WRITE_VIDREG_UNLOCK "\xAF\x20\xFF\xFF\xAF\xA0"
-
-/** Return non-zero if the host is big endian or zero if the host is little endian.
- */
-#define IS_BIGENDIAN() ((*(char*)&endian) == '\0')
-
-/** Convert a 32 bit little endian value into a host byte-order value.
- *
- * @param val Little-endian 32 bit value to convert.
- *
- * @return Value in host byte order.
- */
-#define LETOHL(val) (IS_BIGENDIAN() ? swap_endian_l(val) : val)
-
-/** Convert a 16 bit little endian value into a host byte-order value.
- *
- * @param val Little-endian 16 bit value to convert.
- *
- * @return Value in host byte order.
- */
-#define LETOHS(val) (IS_BIGENDIAN() ? swap_endian_s(val) : val)
-
-/** Initialise a @a dlo_mode_data array entry.
- *
- * @param idx Array index.
- * @param mwidth Mode width (pixels).
- * @param mheight Mode height (pixels).
- * @param mrefresh Mode refresh rate (Hz).
- * @param mbpp Mode colour depth (bits per pixel).
- */
-#define init_mode(idx, mwidth, mheight, mrefresh, mbpp) \
-{ \
- dlo_mode_data[idx].width = mwidth; \
- dlo_mode_data[idx].height = mheight; \
- dlo_mode_data[idx].refresh = mrefresh; \
- dlo_mode_data[idx].bpp = mbpp; \
- dlo_mode_data[idx].data = DLO_MODE_DATA_##mwidth##_##mheight##_##mrefresh##_##mbpp##_0; \
- dlo_mode_data[idx].data_sz = DSIZEOF(DLO_MODE_DATA_##mwidth##_##mheight##_##mrefresh##_##mbpp##_0); \
- dlo_mode_data[idx].mode_en = DLO_MODE_ENABLE_##mwidth##_##mheight##_##mrefresh##_##mbpp##_0; \
- dlo_mode_data[idx].mode_en_sz = DSIZEOF(DLO_MODE_ENABLE_##mwidth##_##mheight##_##mrefresh##_##mbpp##_0); \
- dlo_mode_data[idx].low_blank = false; \
-}
-
-
-/* External-scope inline functions -----------------------------------------------------*/
-
-
-/** Swap the endianness of a long (four byte) integer.
- *
- * @param val Integer to alter.
- *
- * @return Value with swapped endianness.
- */
-inline uint32_t swap_endian_l(uint32_t val)
-{
- return ((val & 0xFF) << 24) | ((val & 0xFF00) << 8) | ((val & 0xFF0000) >> 8) | (( val >> 24) & 0xFF);
-}
-
-
-/** Swap the endianness of a short (two byte) integer.
- *
- * @param val Integer to alter.
- *
- * @return Value with swapped endianness.
- */
-inline uint16_t swap_endian_s(uint16_t val)
-{
- return ((val >> 8) & 0xFF) | ((val << 8) & 0xFF00);
-}
-
-
-extern uint32_t swap_endian_l(uint32_t val);
-extern uint16_t swap_endian_s(uint16_t val);
-
-
-/* File-scope types --------------------------------------------------------------------*/
-
-
-/** Structure to hold information about a specific screen mode.
- */
-typedef struct dlo_mode_data_s
-{
- uint16_t width; /**< Width (pixels). */
- uint16_t height; /**< Height (pixels). */
- uint8_t refresh; /**< Refresh rate (Hz). */
- uint8_t bpp; /**< Colour depth (bits per pixel). */
- char *data; /**< Block of mode data. */
- size_t data_sz; /**< Size of mode data block (bytes). */
- char *mode_en; /**< Block of mode enable data. */
- size_t mode_en_sz; /**< Size of mode enable data block (bytes). */
- bool low_blank; /**< Screen mode has reduced blanking. */
-} dlo_mode_data_t; /**< A struct @a dlo_mode_data_s. */
-
-
-/** Established timing information, derived from EDID.
- */
-typedef struct est_timing_s
-{
- uint16_t width; /**< Width of mode (pixels). */
- uint16_t height; /**< Height of mode (pixels). */
- uint8_t refresh; /**< Mode refresh rate (Hz). */
-} est_timing_t; /**< A struct @a est_timings_s. */
-
-
-/** Vendor/product information.
- */
-typedef struct edid_prod_id_s
-{
- uint16_t manuf_name; /**< ID manufacturer code. */
- uint16_t prod_code; /**< ID product code. */
- uint32_t serial_num; /**< ID serial number. */
- uint8_t manuf_wk; /**< Week of manufacture. */
- uint8_t manuf_yr; /**< Year of manufacture. */
-} edid_prod_id_t; /**< A struct @a edid_prod_id_s. */
-
-
-/** EDID structure information.
- */
-typedef struct edid_struct_vsn_s
-{
- uint8_t number; /**< Version number. */
- uint8_t revision; /**< Revision number. */
-} edid_struct_vsn_t; /**< A struct @a edid_struct_vsn_s. */
-
-
-/** Basic dislpay parameters/features.
- */
-typedef struct edid_basic_params_s
-{
- uint8_t input_def; /**< Video input definition. */
- uint8_t max_horiz_sz; /**< Maximum horizontal image size (cm). */
- uint8_t max_vert_sz; /**< Maximum vertical image size (cm). */
- float gamma; /**< Display transfer characteristic (gamma). */
- uint8_t features; /**< Feature support. */
-} edid_basic_params_t; /**< A struct @a edid_basic_params_s. */
-
-
-/** Colour characteristics.
- */
-typedef struct edid_colours_s
-{
- uint16_t red_grn_low; /**< Red/green low bits. */
- uint16_t blu_wht_low; /**< Blue/white low bits. */
- uint16_t red_x; /**< Red-x (bits 9-2). */
- uint16_t red_y; /**< Red-y (bits 9-2). */
- uint16_t grn_x; /**< Green-x (bits 9-2). */
- uint16_t grn_y; /**< Green-y (bits 9-2). */
- uint16_t blu_x; /**< Blue-x (bits 9-2). */
- uint16_t blu_y; /**< Blue-y (bits 9-2). */
- uint16_t wht_x; /**< White-x (bits 9-2). */
- uint16_t wht_y; /**< White-y (bits 9-2). */
-} edid_colours_t; /**< A struct @a edid_colours_s. */
-
-
-/** Established timings.
- */
-typedef struct edid_est_timings_s
-{
- uint8_t timings[2]; /**< Bitfields of established timings. */
- uint8_t resvd; /**< Manufacturer's reserved timings. */
-} edid_est_timings_t; /**< A struct @a edid_est_timings_s. */
-
-
-/** Standard timing identification.
- */
-typedef struct edid_std_timing_s
-{
- uint16_t timing_id[8]; /**< Standard timing identification. */
-} edid_std_timing_t; /**< A struct @a edid_std_timing_s. */
-
-
-/** Detailed timing description.
- */
-typedef struct edid_detail_s
-{
- bool is_detail; /**< Flag is set to true - the structure is an @a edid_detail_t. */
- float pixclk; /**< Timing parameter. */
- uint32_t hactl; /**< Timing parameter. */
- uint32_t hblankl; /**< Timing parameter. */
- uint32_t hactblankh; /**< Timing parameter. */
- uint32_t vactl; /**< Timing parameter. */
- uint32_t vblankl; /**< Timing parameter. */
- uint32_t vactblankh; /**< Timing parameter. */
- uint32_t hsyncoffl; /**< Timing parameter. */
- uint32_t hsyncwl; /**< Timing parameter. */
- uint32_t vsyncoffvsyncwl; /**< Timing parameter. */
- uint32_t synch; /**< Timing parameter. */
- uint32_t hsizel; /**< Timing parameter. */
- uint32_t vsizel; /**< Timing parameter. */
- uint32_t hvsizeh; /**< Timing parameter. */
- uint8_t hbord; /**< Timing parameter. */
- uint8_t vbord; /**< Timing parameter. */
- uint8_t flags; /**< Timing parameter. */
-} edid_detail_t; /**< A struct @a edid_detail_s. */
-
-
-/** Monitor descriptor.
- */
-typedef struct edid_monitor_desc_s
-{
- bool is_detail; /**< Flag is set to false - the structure is not an @a edid_detail_t. */
- uint8_t unknown[18]; /**< Contents of block are unknown. */
-} edid_monitor_desc_t; /**< A struct @a edid_monitor_desc_s. */
-
-
-/** A timing description block may be either a @a edid_detail_t or a @a edid_monitor_desc_t.
- */
-typedef union edid_timing_desc_u
-{
- edid_detail_t detail; /**< Either a detailed timing description. */
- edid_monitor_desc_t desc; /**< Or a monitor descriptor. */
-} edid_timing_desc_t; /**< A struct @a edid_timing_desc_s. */
-
-
-/** An EDID extension block.
- */
-typedef struct edid_ext_block_s
-{
- uint8_t unknown[128]; /**< Contents of block are unknown. */
-} edid_ext_block_t; /**< A struct @a edid_ext_block_s. */
-
-
-/** An EDID structure.
- */
-typedef struct edid_format_s
-{
- edid_prod_id_t product; /**< Vendor/product information. */
- edid_struct_vsn_t version; /**< EDID structure information. */
- edid_basic_params_t basic; /**< Basic dislpay parameters/features. */
- edid_colours_t colours; /**< Colour characteristics. */
- edid_est_timings_t est_timings; /**< Established timings. */
- edid_std_timing_t std_timings; /**< Standard timing identification. */
- edid_timing_desc_t timings[4]; /**< Timing descriptions. */
- uint8_t ext_blocks; /**< Number of extension blocks. */
-} edid_format_t; /**< A struct @a edid_format_s. */
-
-
-/* External scope variables ------------------------------------------------------------*/
-
-
-/* File-scope variables ----------------------------------------------------------------*/
-
-
-/** Array of hard-wired screen mode definitions.
- */
-static dlo_mode_data_t dlo_mode_data[DLO_MODE_DATA_NUM];
-
-
-/** Mode information corresponding with flag bits in EDID establisted timings bytes.
- */
-const est_timing_t est_timings[24] =
-{
- { 800, 600, 60 }, /* bit 0 */
- { 800, 600, 56 }, /* bit 1 */
- { 640, 480, 75 }, /* bit 2 */
- { 640, 480, 72 }, /* bit 3 */
- { 640, 480, 67 }, /* bit 4 */
- { 640, 480, 60 }, /* bit 5 */
- { 720, 400, 88 }, /* bit 6 */
- { 720, 400, 70 }, /* bit 7 */
- { 1280, 1024, 75 }, /* bit 8 */
- { 1024, 768, 75 }, /* bit 9 */
- { 1024, 768, 70 }, /* bit 10 */
- { 1024, 768, 60 }, /* bit 11 */
- { 1024, 768, 87 }, /* bit 12 */
- { 832, 624, 75 }, /* bit 13 */
- { 800, 600, 75 }, /* bit 14 */
- { 800, 600, 72 }, /* bit 15 */
- { 0, 0, 0 }, /* bit 16 */
- { 0, 0, 0 }, /* bit 17 */
- { 0, 0, 0 }, /* bit 18 */
- { 0, 0, 0 }, /* bit 19 */
- { 0, 0, 0 }, /* bit 20 */
- { 0, 0, 0 }, /* bit 21 */
- { 0, 0, 0 }, /* bit 22 */
- { 1152, 870, 75 } /* bit 23 */
-};
-
-
-/* File-scope function declarations ----------------------------------------------------*/
-
-
-/** Append a video register setting command onto the specified char block.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param reg Register number (0..255).
- * @param val Value to set (byte).
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t vreg(dlo_device_t * const dev, uint8_t reg, uint8_t val);
-
-
-/** Append a video register setting command onto the specified char block.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param reg Register number (0..255).
- * @param val Value to set (byte).
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t vbuf(dlo_device_t * const dev, const char * const buf, size_t len);
-
-
-/** Check an EDID checksum to see if it is invalid.
- *
- * @param ptr Pointer to base of EDID structure data.
- * @param size Size of data (bytes).
- *
- * @return true if checksum is incorrect, false if OK.
- */
-static bool bad_edid_checksum(const uint8_t * const ptr, const size_t size);
-
-
-/** Parse an EDID detailed timing descriptor/mode descriptor.
- *
- * @param desc Pointer to descriptor structure to initialise.
- * @param ptr Pointer to base of descriptor in EDID data to parse.
- */
-static void parse_edid_detail_desc(edid_timing_desc_t * const desc, const uint8_t * const ptr);
-
-
-/** Parse EDID colour characteristics.
- *
- * @param cols Pointer to colour structure to initialise.
- * @param ptr Pointer to base of colour characteristics block to parse from EDID data.
- */
-static void parse_edid_colours(edid_colours_t * const cols, const uint8_t * const ptr);
-
-
-/** Look for a mode definition amongst the list of known modes.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param width Width of desired display (pixels).
- * @param height Hieght of desired display (pixels) - zero to select first available.
- * @param refresh Desired refresh rate (Hz) - zero to select first available.
- * @param bpp Colour depth (bits per pixel) - zero to select first available.
- *
- * @return Mode number of the best matching mode definition (or @a DLO_INVALID_MODE if none found).
- */
-static dlo_modenum_t get_mode_number(dlo_device_t * const dev, const uint16_t width, const uint16_t height, const uint8_t refresh, const uint8_t bpp);
-
-
-/** Given a bitmap and a mode number, set the current screen mode.
- *
- * @param bmp Bitmap to set as the current rastered display mode.
- * @param mode Mode number for best match to the supplied bitmap.
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t mode_select(dlo_device_t * const dev, const dlo_mode_t * const desc, const dlo_modenum_t mode);
-
-
-/** Look up the specified mode and add to the supported list if found.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param idx Index - incrememnted if the mode was found.
- * @param width Width of the mode to look for (pixels).
- * @param height Height of the mode to look for (pixels).
- * @param refresh Refresh rate of the mode to look for (Hz).
- *
- * @return Updated index (as @a idx if mode not found, else incremented by one).
- */
-static uint16_t add_supported(dlo_device_t * const dev, uint16_t idx, const uint16_t width, const uint16_t height, const uint8_t refresh);
-
-
-/** Build a list of supported modes, based upon the supplied EDID information.
- *
- * @param dev Device to update.
- * @param edid Pointer to structure holding parsed EDID information.
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t lookup_edid_modes(dlo_device_t * const dev, const edid_format_t * const edid);
-
-
-/** Program the base addresses of the video display in the device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param base Address of the base of the 16 bpp segment.
- * @param base8 Address of the base of the 8 bpp segment.
- *
- * @return Return code, zero for no error.
- *
- * Note: this call first will cause any buffered commands to be sent to the device then
- * the set base commands are sent. The buffer to that device is thus flushed.
- */
-static dlo_retcode_t set_base(dlo_device_t * const dev, const dlo_ptr_t base, const dlo_ptr_t base8);
-
-
-/* Public function definitions ---------------------------------------------------------*/
-
-
-dlo_retcode_t dlo_mode_init(const dlo_init_t flags)
-{
- init_mode(0, 1920, 1080, 60, 24);
- init_mode(1, 1600, 1200, 60, 24);
- init_mode(2, 1400, 1050, 85, 24);
- init_mode(3, 1400, 1050, 75, 24);
- init_mode(4, 1400, 1050, 60, 24);
- init_mode(5, 1400, 1050, 60, 24);
- init_mode(6, 1366, 768, 60, 24);
- init_mode(7, 1360, 768, 60, 24);
- init_mode(8, 1280, 960, 85, 24);
- init_mode(9, 1280, 960, 60, 24);
- init_mode(10, 1280, 800, 60, 24);
- init_mode(11, 1280, 768, 85, 24);
- init_mode(12, 1280, 768, 75, 24);
- init_mode(13, 1280, 1024, 85, 24);
- init_mode(14, 1280, 1024, 75, 24);
- init_mode(15, 1280, 1024, 60, 24);
- init_mode(16, 1280, 768, 60, 24);
- init_mode(17, 1152, 864, 75, 24);
- init_mode(18, 1024, 768, 85, 24);
- init_mode(19, 1024, 768, 75, 24);
- init_mode(20, 1024, 768, 70, 24);
- init_mode(21, 1024, 768, 60, 24);
- init_mode(22, 848, 480, 60, 24);
- init_mode(23, 800, 600, 85, 24);
- init_mode(24, 800, 600, 75, 24);
- init_mode(25, 800, 600, 72, 24);
- init_mode(26, 800, 600, 60, 24);
- init_mode(27, 800, 600, 56, 24);
- init_mode(28, 800, 480, 60, 24);
- init_mode(29, 720, 400, 85, 24);
- init_mode(30, 720, 400, 70, 24);
- init_mode(31, 640, 480, 85, 24);
- init_mode(32, 640, 480, 75, 24);
- init_mode(33, 640, 480, 73, 24);
- init_mode(34, 640, 480, 60, 24);
-
- return dlo_ok;
-}
-
-
-dlo_retcode_t dlo_mode_final(const dlo_final_t flags)
-{
- return dlo_ok;
-}
-
-
-dlo_mode_t *dlo_mode_from_number(const dlo_modenum_t num)
-{
- static dlo_mode_t mode;
-
- if (num < DLO_MODE_DATA_NUM)
- {
- mode.view.width = dlo_mode_data[num].width;
- mode.view.height = dlo_mode_data[num].height;
- mode.view.bpp = dlo_mode_data[num].bpp;
- mode.view.base = 0;
- mode.refresh = dlo_mode_data[num].refresh;
- return &mode;
- }
- return NULL;
-}
-
-
-dlo_modenum_t dlo_mode_lookup(dlo_device_t * const dev, const uint16_t width, const uint16_t height, const uint8_t refresh, uint8_t bpp)
-{
- /* Check that the requested screen mode is supported */
- //DPRINTF("mode: lookup: %ux%u @ %u Hz, %u bpp\n", width, height, refresh, bpp);
- return bpp != 24 ? DLO_INVALID_MODE : get_mode_number(dev, width, height, refresh, bpp);
-}
-
-
-dlo_retcode_t dlo_mode_change(dlo_device_t * const dev, const dlo_mode_t * const desc, dlo_modenum_t mode)
-{
- /* If no mode number was specified on entry, try looking one up for the supplied bitmap */
- if (mode == DLO_INVALID_MODE)
- mode = get_mode_number(dev, desc->view.width, desc->view.height, 0, desc->view.bpp);
-
- /* Change mode or return an error */
- return mode_select(dev, desc, mode);
-}
-
-
-dlo_retcode_t dlo_mode_parse_edid(dlo_device_t * const dev, const uint8_t * const ptr, const size_t size)
-{
- static edid_format_t edid;
- uint32_t i;
-
- /* Copy the header bytes straight into our structure (assumes the structure is correct size!) */
- ASSERT(EDID_STRUCT_SZ == size);
- if (memcmp(header, ptr, sizeof(header)))
- return dlo_err_edid_fail;
-
- if (bad_edid_checksum(ptr, size))
- return dlo_err_edid_fail;
-
-#if (defined(DEBUG) && 0) /* If you really want this verbose debug output, change the 0 to a 1 */
- uint32_t j;
- /* Parse the vendor/product information */
- for (j = 0; j < 128; j += 8)
- {
- DPRINTF("mode: edid: raw: ");
- for (i = 0; i < 8; i++)
- DPRINTF("%02X=%02X ", i + j, RD_B(ptr + i + j));
- DPRINTF("\n");
- }
-#endif
-
- edid.product.manuf_name = LETOHS(RD_S(ptr + 0x08));
- edid.product.prod_code = LETOHS(RD_S(ptr + 0x0A));
- edid.product.serial_num = LETOHL(RD_L(ptr + 0x0C));
- edid.product.manuf_wk = RD_B(ptr + 0x10);
- edid.product.manuf_yr = RD_B(ptr + 0x11);
- //DPRINTF("mode: edid: manuf &%X prod &%X serial &%X wk %u yr %u\n",
- // edid.product.manuf_name, edid.product.prod_code, edid.product.serial_num,
- // edid.product.manuf_wk, edid.product.manuf_yr + 1990);
-
- /* Parse the EDID structure information */
- edid.version.number = RD_B(ptr + 0x12);
- edid.version.revision = RD_B(ptr + 0x13);
- //DPRINTF("edid: version &%02X revision &%02X\n", edid.version.number, edid.version.revision);
-
- /* Parse the basic dislpay parameters/features */
- edid.basic.input_def = RD_B(ptr + 0x14);
- edid.basic.max_horiz_sz = RD_B(ptr + 0x15);
- edid.basic.max_vert_sz = RD_B(ptr + 0x16);
- edid.basic.gamma = (100.0 + RD_B(ptr + 0x17)) / 100.0;
- edid.basic.features = RD_B(ptr + 0x18);
-
- /* Parse the colour characteristics */
- parse_edid_colours(&(edid.colours), ptr + 0x19);
-
- /* Parse the established timings */
- edid.est_timings.timings[0] = RD_B(ptr + 0x23);
- edid.est_timings.timings[1] = RD_B(ptr + 0x24);
- edid.est_timings.resvd = RD_B(ptr + 0x25);
-
- /* Parse the bits at the end of the EDID structure */
- edid.ext_blocks = RD_B(ptr + 0x7E);
-
- /* Parse all of the standard timing identification */
- for (i = 0; i < sizeof(edid.std_timings.timing_id); i++)
- edid.std_timings.timing_id[i] = RD_B(ptr + 0x26 + i);
-
- /* Parse all of the detailed timing descriptions (or monitor descriptors) */
- for (i = 0; i < 4; i++)
- parse_edid_detail_desc(&(edid.timings[i]), ptr + 0x36 + (i * 0x12));
-
- return lookup_edid_modes(dev, &edid);
-}
-
-
-void use_default_modes(dlo_device_t * const dev)
-{
- uint32_t i;
-
- for (i = 0; i < DLO_MODE_DATA_NUM; i++)
- dev->supported[i] = (dlo_modenum_t)i;
-}
-
-
-/* File-scope function definitions -----------------------------------------------------*/
-
-
-static dlo_retcode_t vreg(dlo_device_t * const dev, uint8_t reg, uint8_t val)
-{
- if (dev->bufend - dev->bufptr < 4)
- return dlo_err_buf_full;
-
- *(dev->bufptr)++ = '\xAF';
- *(dev->bufptr)++ = '\x20';
- *(dev->bufptr)++ = reg;
- *(dev->bufptr)++ = val;
-
- return dlo_ok;
-}
-
-
-static dlo_retcode_t vbuf(dlo_device_t * const dev, const char * buf, size_t len)
-{
- if (dev->bufend - dev->bufptr < len)
- return dlo_err_buf_full;
-
- while (len--)
- *(dev->bufptr)++ = *buf++;
-
- return dlo_ok;
-}
-
-
-static dlo_modenum_t get_mode_number(dlo_device_t * const dev, const uint16_t width, const uint16_t height, const uint8_t refresh, const uint8_t bpp)
-{
- dlo_modenum_t idx;
- uint32_t num;
-
- /* Look for all matching modes in our array of video timing structures.
- *
- * Note: if we don't have EDID data for the monitor attached to the device
- * we simply look through all the modes we have, rather than only looking
- * at the supported modes list.
- */
- for (idx = 0; idx < DLO_MODE_DATA_NUM; idx++)
- {
- /* Read the mode number from the device's supported modes array */
- num = dev->supported[idx];
- if (num == DLO_INVALID_MODE)
- break;
-
- /* This sequence of if statements looks odd, take care if you decide to 'optimise' it! */
- if (dlo_mode_data[num].width != width)
- continue;
- if (bpp && dlo_mode_data[num].bpp != bpp)
- continue;
- if (height && dlo_mode_data[num].height != height)
- continue;
- if (refresh && dlo_mode_data[num].refresh != refresh)
- continue;
-
- /* If we're satisfied with the tests above, then return the mode number */
- return num;
- }
-
- /* No matches found, return an invalid mode number */
- return DLO_INVALID_MODE;
-}
-
-
-static dlo_retcode_t mode_select(dlo_device_t * const dev, const dlo_mode_t * const desc, const dlo_modenum_t mode)
-{
- if (mode >= DLO_MODE_DATA_NUM || mode == DLO_INVALID_MODE)
- return dlo_err_bad_mode;
-
- /* Base address must be aligned to a two byte boundary */
- if (desc->view.base & 1)
- return dlo_err_bad_mode;
-
- /* Flush the command buffer */
- if (dlo_ok != dlo_usb_write(dev))
- return DLO_INVALID_MODE;
-
- dev->mode.view.base = desc->view.base;
- dev->base8 = desc->view.base + (BYTES_PER_16BPP * desc->view.width * desc->view.height);
- ERR(set_base(dev, dev->mode.view.base, dev->base8));
-
- /* Only change mode if the new raster bitmap's characteristics differ from the current.
- *
- * Note: don't compare reduced blanking flag because if the rest is the same, we can use the
- * same blanking type. However, there's an outside chance that the low_blank hint was changed
- * since entering the current mode in which case you may well want a mode change to happen but
- * we'll just hope that never happens (seems like a very unlikely scenario).
- */
- if (desc->view.width != dev->mode.view.width ||
- desc->view.height != dev->mode.view.height ||
- desc->view.bpp != dev->mode.view.bpp)
- {
- ERR(dlo_usb_chan_sel(dev, dlo_mode_data[mode].mode_en, dlo_mode_data[mode].mode_en_sz));
- ERR(dlo_usb_write_buf(dev, dlo_mode_data[mode].data, dlo_mode_data[mode].data_sz));
- ERR(dlo_usb_chan_sel(dev, DLO_MODE_POSTAMBLE, DSIZEOF(DLO_MODE_POSTAMBLE)));
- }
-
- /* Update the device with the new mode details */
- dev->mode = *desc;
- dev->mode.refresh = dlo_mode_data[mode].refresh;
- dev->low_blank = dlo_mode_data[mode].low_blank;
-
- //DPRINTF("mode: select: %ux%u @ %u Hz %u bpp (base &%X base8 &%X low? %s)\n",
- // dev->mode.view.width, dev->mode.view.height, dev->mode.refresh, dev->mode.view.bpp,
- // dev->mode.view.base, dev->base8, dev->low_blank ? "yes" : "no");
-
- /* Flush the command buffer */
- ERR(dlo_usb_write(dev));
-
- /* Return a warning for DL160 modes */
- return (mode < DLO_DL120_MODES) ? dlo_warn_dl160_mode : dlo_ok;
-}
-
-
-static uint16_t add_supported(dlo_device_t * const dev, uint16_t idx, const uint16_t width, const uint16_t height, const uint8_t refresh)
-{
- dlo_modenum_t num;
-
- num = get_mode_number(dev, width, height, refresh, 24);
- if (num != DLO_INVALID_MODE)
- dev->supported[idx++] = num;
-
-// DPRINTF("mode: add_supt: %ux%u @ %u Hz, %u bpp = num %u\n", width, height, refresh, 24, (int)num);
-
- return idx;
-}
-
-
-static dlo_retcode_t lookup_edid_modes(dlo_device_t * const dev, const edid_format_t * const edid)
-{
- uint32_t timings, bit;
- uint32_t idx = 0;
-
- /* Clear the native mode information for the device */
- (void) dlo_memset(&dev->native, 0, sizeof(dlo_mode_t));
-
- /* Add mode numbers for any supported established timing modes */
- timings = edid->est_timings.timings[0] | (edid->est_timings.timings[1] << 8) | (edid->est_timings.resvd << 16);
- for (bit = 0; bit < 24; bit++)
- {
- if (est_timings[bit].width)
- idx = add_supported(dev, idx, est_timings[bit].width, est_timings[bit].height, est_timings[bit].refresh);
- }
-
- /* Add further support from the detailed timing descriptions */
- for (timings = 0; timings < 4; timings++)
- {
- const edid_detail_t * const detail = &(edid->timings[timings].detail);
-
- if (detail->is_detail)
- {
- uint8_t hz;
-
- for (hz = 50; hz < 100; hz++)
- {
- uint32_t prev = idx;
- uint32_t width = detail->hactl + ((detail->hactblankh & 0xF0) << 4);
- uint32_t height = detail->vactl + ((detail->vactblankh & 0xF0) << 4);
-
- idx = add_supported(dev, idx, width, height, hz);
-
- /* Have we added a mode definition for the native resolution reported by the display? */
- if (idx != prev)
- {
- dlo_modenum_t num = dev->supported[prev];
-
- dev->native.view.base = 0;
- dev->native.view.width = dlo_mode_data[num].width;
- dev->native.view.height = dlo_mode_data[num].height;
- dev->native.view.bpp = dlo_mode_data[num].bpp;
- dev->native.refresh = dlo_mode_data[num].refresh;
- DPRINTF("mode: lookup: native mode %u (%ux%u @ %u bpp, %uHz base &%X)\n",
- num,
- dev->native.view.width,
- dev->native.view.height,
- dev->native.view.bpp,
- dev->native.refresh,
- (int)dev->native.view.base);
- }
- }
- }
- }
-
- /* Fill any remaining array entries with the invalid mode constant */
- while (idx < DLO_MODE_DATA_NUM - 1)
- dev->supported[idx++] = DLO_INVALID_MODE;
-
- return dlo_ok;
-}
-
-
-static dlo_retcode_t set_base(dlo_device_t * const dev, const dlo_ptr_t base, const dlo_ptr_t base8)
-{
- //DPRINTF("mode: set_base: base=&%X base8=&%X\n", base, base8);
- ERR(vbuf(dev, WRITE_VIDREG_LOCK, DSIZEOF(WRITE_VIDREG_LOCK)));
- ERR(vreg(dev, 0x20, base >> 16));
- ERR(vreg(dev, 0x21, base >> 8));
- ERR(vreg(dev, 0x22, base));
- ERR(vreg(dev, 0x26, base8 >> 16));
- ERR(vreg(dev, 0x27, base8 >> 8));
- ERR(vreg(dev, 0x28, base8));
- ERR(vbuf(dev, WRITE_VIDREG_UNLOCK, DSIZEOF(WRITE_VIDREG_UNLOCK)));
- ERR(dlo_usb_write(dev));
-
- return dlo_ok;
-}
-
-
-static bool bad_edid_checksum(const uint8_t * const ptr, const size_t size)
-{
- uint32_t i;
- uint8_t csum = 0;
-
- for (i = 0; i < size; i++)
- csum += ptr[i];
-
- return 0 != csum;
-}
-
-
-static void parse_edid_detail_desc(edid_timing_desc_t * const desc, const uint8_t * const ptr)
-{
- if (RD_B(ptr) || RD_B(ptr + 1) || RD_B(ptr + 2))
- {
- //DPRINTF("edid: found timing detail (&%04X)\n", LETOHS(RD_S(ptr)));
- desc->detail.is_detail = true;
- desc->detail.pixclk = (float)LETOHS(RD_S(ptr)) / 100.0;
- desc->detail.hactl = RD_B(ptr + 0x02);
- desc->detail.hblankl = RD_B(ptr + 0x03);
- desc->detail.hactblankh = RD_B(ptr + 0x04);
- desc->detail.vactl = RD_B(ptr + 0x05);
- desc->detail.vblankl = RD_B(ptr + 0x06);
- desc->detail.vactblankh = RD_B(ptr + 0x07);
- desc->detail.hsyncoffl = RD_B(ptr + 0x08);
- desc->detail.hsyncwl = RD_B(ptr + 0x09);
- desc->detail.vsyncoffvsyncwl = RD_B(ptr + 0x0A);
- desc->detail.synch = RD_B(ptr + 0x0B);
- desc->detail.hsizel = RD_B(ptr + 0x0C);
- desc->detail.vsizel = RD_B(ptr + 0x0D);
- desc->detail.hvsizeh = RD_B(ptr + 0x0E);
- desc->detail.hbord = RD_B(ptr + 0x0F);
- desc->detail.vbord = RD_B(ptr + 0x10);
- desc->detail.flags = RD_B(ptr + 0x11);
-
- //DPRINTF("edid: Pixel Clock: %f MHz\n", (float)desc->detail.pixclk);
- //DPRINTF("edid: H Active pixels: %d\n", desc->detail.hactl + ((desc->detail.hactblankh & 0xF0) << 4));
- //DPRINTF("edid: H Blank pixels: %d\n", desc->detail.hblankl + ((desc->detail.hactblankh & 0x0F) << 8));
- //DPRINTF("edid: V Active pixels: %d\n", desc->detail.vactl + ((desc->detail.vactblankh & 0xF0) << 4));
- //DPRINTF("edid: V Blank pixels: %d\n", desc->detail.vblankl + ((desc->detail.vactblankh & 0x0F) << 8));
- //DPRINTF("edid: H Sync Off: %d\n", desc->detail.hsyncoffl + ((desc->detail.synch & 0xC0) << 2));
- //DPRINTF("edid: H Sync Width: %d\n", desc->detail.hsyncwl + ((desc->detail.synch & 0x30) << 4));
- //DPRINTF("edid: V Sync Off: %d\n", (desc->detail.vsyncoffvsyncwl >> 4) + ((desc->detail.synch & 0x0C) << 6));
- //DPRINTF("edid: V Sync Width: %d\n", (desc->detail.vsyncoffvsyncwl & 0xF) + ((desc->detail.synch & 0x03) << 8));
- //DPRINTF("edid: H size: %d mm\n", desc->detail.hsizel + ((desc->detail.hvsizeh & 0xF0) << 4));
- //DPRINTF("edid: V size: %d mm\n", desc->detail.vsizel + ((desc->detail.hvsizeh & 0x0F) << 8));
- }
- else
- {
- /* It's a mode descriptor - ignore for now */
- //DPRINTF("edid: found a mode descriptor type &%02X\n", RD_B(ptr+3));
- desc->desc.is_detail = false;
- switch (RD_B(ptr+3))
- {
- case 0xFC:
- case 0xFE:
- case 0xFF:
- {
- char buf[14];
- char *chr;
-
- snprintf(buf, 13, "%s", ptr + 5);
- buf[13] = '\0';
- chr = strchr(buf, '\n');
- if (chr)
- *chr = '\0';
- //DPRINTF("edid: monitor string '%s'\n", buf);
- break;
- }
- default:
- {
- //uint32_t i;
- //DPRINTF("edid: ");
- //for (i = 0; i < 0x12; i++)
- // DPRINTF("%02X ", RD_B(ptr+i));
- //DPRINTF("\n");
- }
- }
- }
-}
-
-static void parse_edid_colours(edid_colours_t * const cols, const uint8_t * const ptr)
-{
- /* Read the raw data */
- cols->red_grn_low = RD_B(ptr + 0x19);
- cols->blu_wht_low = RD_B(ptr + 0x1A);
- cols->red_x = RD_B(ptr + 0x1B);
- cols->red_y = RD_B(ptr + 0x1C);
- cols->grn_x = RD_B(ptr + 0x1D);
- cols->grn_y = RD_B(ptr + 0x1E);
- cols->blu_x = RD_B(ptr + 0x1F);
- cols->blu_y = RD_B(ptr + 0x20);
- cols->wht_x = RD_B(ptr + 0x21);
- cols->wht_y = RD_B(ptr + 0x22);
-
- /* Do the expansion */
- cols->red_x = ((cols->red_grn_low & 0xC0) >> 6) + (cols->red_x << 2);
- cols->red_y = ((cols->red_grn_low & 0x30) >> 4) + (cols->red_y << 2);
- cols->grn_x = ((cols->red_grn_low & 0x0C) >> 2) + (cols->grn_x << 2);
- cols->grn_y = ((cols->red_grn_low & 0x03) >> 0) + (cols->grn_y << 2);
- cols->blu_x = ((cols->blu_wht_low & 0xC0) >> 6) + (cols->blu_x << 2);
- cols->blu_y = ((cols->blu_wht_low & 0x40) >> 4) + (cols->blu_y << 2);
- cols->wht_x = ((cols->blu_wht_low & 0x0C) >> 2) + (cols->wht_y << 2);
- cols->wht_y = ((cols->blu_wht_low & 0x03) >> 0) + (cols->wht_y << 2);
-}
-
-
-/* End of file -------------------------------------------------------------------------*/
+/** @file dlo_mode.c + * + * @brief Implementation of the screen mode-related functions. + * + * See dlo_mode.h for more information. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <stdio.h> +#include <string.h> +#include "dlo_defs.h" +#include "dlo_mode.h" +#include "dlo_data.h" +#include "dlo_usb.h" + + +/* File-scope defines ------------------------------------------------------------------*/ + + +/** Pre-defined EDID header used to check that data read from a device is valid. + */ +const uint8_t header[8] = +{ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 +}; + +/** Constant used for deciding if a host is big- or little endian. + */ +const uint32_t endian = 1; + +/** Unlock video registers command. + */ +#define WRITE_VIDREG_LOCK "\xAF\x20\xFF\x00" + +/** Lock video registers command. + */ +#define WRITE_VIDREG_UNLOCK "\xAF\x20\xFF\xFF\xAF\xA0" + +/** Return non-zero if the host is big endian or zero if the host is little endian. + */ +#define IS_BIGENDIAN() ((*(char*)&endian) == '\0') + +/** Convert a 32 bit little endian value into a host byte-order value. + * + * @param val Little-endian 32 bit value to convert. + * + * @return Value in host byte order. + */ +#define LETOHL(val) (IS_BIGENDIAN() ? swap_endian_l(val) : val) + +/** Convert a 16 bit little endian value into a host byte-order value. + * + * @param val Little-endian 16 bit value to convert. + * + * @return Value in host byte order. + */ +#define LETOHS(val) (IS_BIGENDIAN() ? swap_endian_s(val) : val) + +/** Initialise a @a dlo_mode_data array entry. + * + * @param idx Array index. + * @param mwidth Mode width (pixels). + * @param mheight Mode height (pixels). + * @param mrefresh Mode refresh rate (Hz). + * @param mbpp Mode colour depth (bits per pixel). + */ +#define init_mode(idx, mwidth, mheight, mrefresh, mbpp) \ +{ \ + dlo_mode_data[idx].width = mwidth; \ + dlo_mode_data[idx].height = mheight; \ + dlo_mode_data[idx].refresh = mrefresh; \ + dlo_mode_data[idx].bpp = mbpp; \ + dlo_mode_data[idx].data = DLO_MODE_DATA_##mwidth##_##mheight##_##mrefresh##_##mbpp##_0; \ + dlo_mode_data[idx].data_sz = DSIZEOF(DLO_MODE_DATA_##mwidth##_##mheight##_##mrefresh##_##mbpp##_0); \ + dlo_mode_data[idx].mode_en = DLO_MODE_ENABLE_##mwidth##_##mheight##_##mrefresh##_##mbpp##_0; \ + dlo_mode_data[idx].mode_en_sz = DSIZEOF(DLO_MODE_ENABLE_##mwidth##_##mheight##_##mrefresh##_##mbpp##_0); \ + dlo_mode_data[idx].low_blank = false; \ +} + + +/* External-scope inline functions -----------------------------------------------------*/ + + +/** Swap the endianness of a long (four byte) integer. + * + * @param val Integer to alter. + * + * @return Value with swapped endianness. + */ +inline uint32_t swap_endian_l(uint32_t val) +{ + return ((val & 0xFF) << 24) | ((val & 0xFF00) << 8) | ((val & 0xFF0000) >> 8) | (( val >> 24) & 0xFF); +} + + +/** Swap the endianness of a short (two byte) integer. + * + * @param val Integer to alter. + * + * @return Value with swapped endianness. + */ +inline uint16_t swap_endian_s(uint16_t val) +{ + return ((val >> 8) & 0xFF) | ((val << 8) & 0xFF00); +} + + +extern uint32_t swap_endian_l(uint32_t val); +extern uint16_t swap_endian_s(uint16_t val); + + +/* File-scope types --------------------------------------------------------------------*/ + + +/** Structure to hold information about a specific screen mode. + */ +typedef struct dlo_mode_data_s +{ + uint16_t width; /**< Width (pixels). */ + uint16_t height; /**< Height (pixels). */ + uint8_t refresh; /**< Refresh rate (Hz). */ + uint8_t bpp; /**< Colour depth (bits per pixel). */ + char *data; /**< Block of mode data. */ + size_t data_sz; /**< Size of mode data block (bytes). */ + char *mode_en; /**< Block of mode enable data. */ + size_t mode_en_sz; /**< Size of mode enable data block (bytes). */ + bool low_blank; /**< Screen mode has reduced blanking. */ +} dlo_mode_data_t; /**< A struct @a dlo_mode_data_s. */ + + +/** Established timing information, derived from EDID. + */ +typedef struct est_timing_s +{ + uint16_t width; /**< Width of mode (pixels). */ + uint16_t height; /**< Height of mode (pixels). */ + uint8_t refresh; /**< Mode refresh rate (Hz). */ +} est_timing_t; /**< A struct @a est_timings_s. */ + + +/** Vendor/product information. + */ +typedef struct edid_prod_id_s +{ + uint16_t manuf_name; /**< ID manufacturer code. */ + uint16_t prod_code; /**< ID product code. */ + uint32_t serial_num; /**< ID serial number. */ + uint8_t manuf_wk; /**< Week of manufacture. */ + uint8_t manuf_yr; /**< Year of manufacture. */ +} edid_prod_id_t; /**< A struct @a edid_prod_id_s. */ + + +/** EDID structure information. + */ +typedef struct edid_struct_vsn_s +{ + uint8_t number; /**< Version number. */ + uint8_t revision; /**< Revision number. */ +} edid_struct_vsn_t; /**< A struct @a edid_struct_vsn_s. */ + + +/** Basic dislpay parameters/features. + */ +typedef struct edid_basic_params_s +{ + uint8_t input_def; /**< Video input definition. */ + uint8_t max_horiz_sz; /**< Maximum horizontal image size (cm). */ + uint8_t max_vert_sz; /**< Maximum vertical image size (cm). */ + float gamma; /**< Display transfer characteristic (gamma). */ + uint8_t features; /**< Feature support. */ +} edid_basic_params_t; /**< A struct @a edid_basic_params_s. */ + + +/** Colour characteristics. + */ +typedef struct edid_colours_s +{ + uint16_t red_grn_low; /**< Red/green low bits. */ + uint16_t blu_wht_low; /**< Blue/white low bits. */ + uint16_t red_x; /**< Red-x (bits 9-2). */ + uint16_t red_y; /**< Red-y (bits 9-2). */ + uint16_t grn_x; /**< Green-x (bits 9-2). */ + uint16_t grn_y; /**< Green-y (bits 9-2). */ + uint16_t blu_x; /**< Blue-x (bits 9-2). */ + uint16_t blu_y; /**< Blue-y (bits 9-2). */ + uint16_t wht_x; /**< White-x (bits 9-2). */ + uint16_t wht_y; /**< White-y (bits 9-2). */ +} edid_colours_t; /**< A struct @a edid_colours_s. */ + + +/** Established timings. + */ +typedef struct edid_est_timings_s +{ + uint8_t timings[2]; /**< Bitfields of established timings. */ + uint8_t resvd; /**< Manufacturer's reserved timings. */ +} edid_est_timings_t; /**< A struct @a edid_est_timings_s. */ + + +/** Standard timing identification. + */ +typedef struct edid_std_timing_s +{ + uint16_t timing_id[8]; /**< Standard timing identification. */ +} edid_std_timing_t; /**< A struct @a edid_std_timing_s. */ + + +/** Detailed timing description. + */ +typedef struct edid_detail_s +{ + bool is_detail; /**< Flag is set to true - the structure is an @a edid_detail_t. */ + float pixclk; /**< Timing parameter. */ + uint32_t hactl; /**< Timing parameter. */ + uint32_t hblankl; /**< Timing parameter. */ + uint32_t hactblankh; /**< Timing parameter. */ + uint32_t vactl; /**< Timing parameter. */ + uint32_t vblankl; /**< Timing parameter. */ + uint32_t vactblankh; /**< Timing parameter. */ + uint32_t hsyncoffl; /**< Timing parameter. */ + uint32_t hsyncwl; /**< Timing parameter. */ + uint32_t vsyncoffvsyncwl; /**< Timing parameter. */ + uint32_t synch; /**< Timing parameter. */ + uint32_t hsizel; /**< Timing parameter. */ + uint32_t vsizel; /**< Timing parameter. */ + uint32_t hvsizeh; /**< Timing parameter. */ + uint8_t hbord; /**< Timing parameter. */ + uint8_t vbord; /**< Timing parameter. */ + uint8_t flags; /**< Timing parameter. */ +} edid_detail_t; /**< A struct @a edid_detail_s. */ + + +/** Monitor descriptor. + */ +typedef struct edid_monitor_desc_s +{ + bool is_detail; /**< Flag is set to false - the structure is not an @a edid_detail_t. */ + uint8_t unknown[18]; /**< Contents of block are unknown. */ +} edid_monitor_desc_t; /**< A struct @a edid_monitor_desc_s. */ + + +/** A timing description block may be either a @a edid_detail_t or a @a edid_monitor_desc_t. + */ +typedef union edid_timing_desc_u +{ + edid_detail_t detail; /**< Either a detailed timing description. */ + edid_monitor_desc_t desc; /**< Or a monitor descriptor. */ +} edid_timing_desc_t; /**< A struct @a edid_timing_desc_s. */ + + +/** An EDID extension block. + */ +typedef struct edid_ext_block_s +{ + uint8_t unknown[128]; /**< Contents of block are unknown. */ +} edid_ext_block_t; /**< A struct @a edid_ext_block_s. */ + + +/** An EDID structure. + */ +typedef struct edid_format_s +{ + edid_prod_id_t product; /**< Vendor/product information. */ + edid_struct_vsn_t version; /**< EDID structure information. */ + edid_basic_params_t basic; /**< Basic dislpay parameters/features. */ + edid_colours_t colours; /**< Colour characteristics. */ + edid_est_timings_t est_timings; /**< Established timings. */ + edid_std_timing_t std_timings; /**< Standard timing identification. */ + edid_timing_desc_t timings[4]; /**< Timing descriptions. */ + uint8_t ext_blocks; /**< Number of extension blocks. */ +} edid_format_t; /**< A struct @a edid_format_s. */ + + +/* External scope variables ------------------------------------------------------------*/ + + +/* File-scope variables ----------------------------------------------------------------*/ + + +/** Array of hard-wired screen mode definitions. + */ +static dlo_mode_data_t dlo_mode_data[DLO_MODE_DATA_NUM]; + + +/** Mode information corresponding with flag bits in EDID establisted timings bytes. + */ +const est_timing_t est_timings[24] = +{ + { 800, 600, 60 }, /* bit 0 */ + { 800, 600, 56 }, /* bit 1 */ + { 640, 480, 75 }, /* bit 2 */ + { 640, 480, 72 }, /* bit 3 */ + { 640, 480, 67 }, /* bit 4 */ + { 640, 480, 60 }, /* bit 5 */ + { 720, 400, 88 }, /* bit 6 */ + { 720, 400, 70 }, /* bit 7 */ + { 1280, 1024, 75 }, /* bit 8 */ + { 1024, 768, 75 }, /* bit 9 */ + { 1024, 768, 70 }, /* bit 10 */ + { 1024, 768, 60 }, /* bit 11 */ + { 1024, 768, 87 }, /* bit 12 */ + { 832, 624, 75 }, /* bit 13 */ + { 800, 600, 75 }, /* bit 14 */ + { 800, 600, 72 }, /* bit 15 */ + { 0, 0, 0 }, /* bit 16 */ + { 0, 0, 0 }, /* bit 17 */ + { 0, 0, 0 }, /* bit 18 */ + { 0, 0, 0 }, /* bit 19 */ + { 0, 0, 0 }, /* bit 20 */ + { 0, 0, 0 }, /* bit 21 */ + { 0, 0, 0 }, /* bit 22 */ + { 1152, 870, 75 } /* bit 23 */ +}; + + +/* File-scope function declarations ----------------------------------------------------*/ + + +/** Append a video register setting command onto the specified char block. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param reg Register number (0..255). + * @param val Value to set (byte). + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t vreg(dlo_device_t * const dev, uint8_t reg, uint8_t val); + + +/** Append a video register setting command onto the specified char block. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param reg Register number (0..255). + * @param val Value to set (byte). + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t vbuf(dlo_device_t * const dev, const char * const buf, size_t len); + + +/** Check an EDID checksum to see if it is invalid. + * + * @param ptr Pointer to base of EDID structure data. + * @param size Size of data (bytes). + * + * @return true if checksum is incorrect, false if OK. + */ +static bool bad_edid_checksum(const uint8_t * const ptr, const size_t size); + + +/** Parse an EDID detailed timing descriptor/mode descriptor. + * + * @param desc Pointer to descriptor structure to initialise. + * @param ptr Pointer to base of descriptor in EDID data to parse. + */ +static void parse_edid_detail_desc(edid_timing_desc_t * const desc, const uint8_t * const ptr); + + +/** Parse EDID colour characteristics. + * + * @param cols Pointer to colour structure to initialise. + * @param ptr Pointer to base of colour characteristics block to parse from EDID data. + */ +static void parse_edid_colours(edid_colours_t * const cols, const uint8_t * const ptr); + + +/** Look for a mode definition amongst the list of known modes. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param width Width of desired display (pixels). + * @param height Hieght of desired display (pixels) - zero to select first available. + * @param refresh Desired refresh rate (Hz) - zero to select first available. + * @param bpp Colour depth (bits per pixel) - zero to select first available. + * + * @return Mode number of the best matching mode definition (or @a DLO_INVALID_MODE if none found). + */ +static dlo_modenum_t get_mode_number(dlo_device_t * const dev, const uint16_t width, const uint16_t height, const uint8_t refresh, const uint8_t bpp); + + +/** Given a bitmap and a mode number, set the current screen mode. + * + * @param bmp Bitmap to set as the current rastered display mode. + * @param mode Mode number for best match to the supplied bitmap. + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t mode_select(dlo_device_t * const dev, const dlo_mode_t * const desc, const dlo_modenum_t mode); + + +/** Look up the specified mode and add to the supported list if found. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param idx Index - incrememnted if the mode was found. + * @param width Width of the mode to look for (pixels). + * @param height Height of the mode to look for (pixels). + * @param refresh Refresh rate of the mode to look for (Hz). + * + * @return Updated index (as @a idx if mode not found, else incremented by one). + */ +static uint16_t add_supported(dlo_device_t * const dev, uint16_t idx, const uint16_t width, const uint16_t height, const uint8_t refresh); + + +/** Build a list of supported modes, based upon the supplied EDID information. + * + * @param dev Device to update. + * @param edid Pointer to structure holding parsed EDID information. + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t lookup_edid_modes(dlo_device_t * const dev, const edid_format_t * const edid); + + +/** Program the base addresses of the video display in the device. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param base Address of the base of the 16 bpp segment. + * @param base8 Address of the base of the 8 bpp segment. + * + * @return Return code, zero for no error. + * + * Note: this call first will cause any buffered commands to be sent to the device then + * the set base commands are sent. The buffer to that device is thus flushed. + */ +static dlo_retcode_t set_base(dlo_device_t * const dev, const dlo_ptr_t base, const dlo_ptr_t base8); + + +/* Public function definitions ---------------------------------------------------------*/ + + +dlo_retcode_t dlo_mode_init(const dlo_init_t flags) +{ + init_mode(0, 1920, 1080, 60, 24); + init_mode(1, 1600, 1200, 60, 24); + init_mode(2, 1400, 1050, 85, 24); + init_mode(3, 1400, 1050, 75, 24); + init_mode(4, 1400, 1050, 60, 24); + init_mode(5, 1400, 1050, 60, 24); + init_mode(6, 1366, 768, 60, 24); + init_mode(7, 1360, 768, 60, 24); + init_mode(8, 1280, 960, 85, 24); + init_mode(9, 1280, 960, 60, 24); + init_mode(10, 1280, 800, 60, 24); + init_mode(11, 1280, 768, 85, 24); + init_mode(12, 1280, 768, 75, 24); + init_mode(13, 1280, 1024, 85, 24); + init_mode(14, 1280, 1024, 75, 24); + init_mode(15, 1280, 1024, 60, 24); + init_mode(16, 1280, 768, 60, 24); + init_mode(17, 1152, 864, 75, 24); + init_mode(18, 1024, 768, 85, 24); + init_mode(19, 1024, 768, 75, 24); + init_mode(20, 1024, 768, 70, 24); + init_mode(21, 1024, 768, 60, 24); + init_mode(22, 848, 480, 60, 24); + init_mode(23, 800, 600, 85, 24); + init_mode(24, 800, 600, 75, 24); + init_mode(25, 800, 600, 72, 24); + init_mode(26, 800, 600, 60, 24); + init_mode(27, 800, 600, 56, 24); + init_mode(28, 800, 480, 60, 24); + init_mode(29, 720, 400, 85, 24); + init_mode(30, 720, 400, 70, 24); + init_mode(31, 640, 480, 85, 24); + init_mode(32, 640, 480, 75, 24); + init_mode(33, 640, 480, 73, 24); + init_mode(34, 640, 480, 60, 24); + + return dlo_ok; +} + + +dlo_retcode_t dlo_mode_final(const dlo_final_t flags) +{ + return dlo_ok; +} + + +dlo_mode_t *dlo_mode_from_number(const dlo_modenum_t num) +{ + static dlo_mode_t mode; + + if (num < DLO_MODE_DATA_NUM) + { + mode.view.width = dlo_mode_data[num].width; + mode.view.height = dlo_mode_data[num].height; + mode.view.bpp = dlo_mode_data[num].bpp; + mode.view.base = 0; + mode.refresh = dlo_mode_data[num].refresh; + return &mode; + } + return NULL; +} + + +dlo_modenum_t dlo_mode_lookup(dlo_device_t * const dev, const uint16_t width, const uint16_t height, const uint8_t refresh, uint8_t bpp) +{ + /* Check that the requested screen mode is supported */ + //DPRINTF("mode: lookup: %ux%u @ %u Hz, %u bpp\n", width, height, refresh, bpp); + return bpp != 24 ? DLO_INVALID_MODE : get_mode_number(dev, width, height, refresh, bpp); +} + + +dlo_retcode_t dlo_mode_change(dlo_device_t * const dev, const dlo_mode_t * const desc, dlo_modenum_t mode) +{ + /* If no mode number was specified on entry, try looking one up for the supplied bitmap */ + if (mode == DLO_INVALID_MODE) + mode = get_mode_number(dev, desc->view.width, desc->view.height, 0, desc->view.bpp); + + /* Change mode or return an error */ + return mode_select(dev, desc, mode); +} + + +dlo_retcode_t dlo_mode_parse_edid(dlo_device_t * const dev, const uint8_t * const ptr, const size_t size) +{ + static edid_format_t edid; + uint32_t i; + + /* Copy the header bytes straight into our structure (assumes the structure is correct size!) */ + ASSERT(EDID_STRUCT_SZ == size); + if (memcmp(header, ptr, sizeof(header))) + return dlo_err_edid_fail; + + if (bad_edid_checksum(ptr, size)) + return dlo_err_edid_fail; + +#if (defined(DEBUG) && 0) /* If you really want this verbose debug output, change the 0 to a 1 */ + uint32_t j; + /* Parse the vendor/product information */ + for (j = 0; j < 128; j += 8) + { + DPRINTF("mode: edid: raw: "); + for (i = 0; i < 8; i++) + DPRINTF("%02X=%02X ", i + j, RD_B(ptr + i + j)); + DPRINTF("\n"); + } +#endif + + edid.product.manuf_name = LETOHS(RD_S(ptr + 0x08)); + edid.product.prod_code = LETOHS(RD_S(ptr + 0x0A)); + edid.product.serial_num = LETOHL(RD_L(ptr + 0x0C)); + edid.product.manuf_wk = RD_B(ptr + 0x10); + edid.product.manuf_yr = RD_B(ptr + 0x11); + //DPRINTF("mode: edid: manuf &%X prod &%X serial &%X wk %u yr %u\n", + // edid.product.manuf_name, edid.product.prod_code, edid.product.serial_num, + // edid.product.manuf_wk, edid.product.manuf_yr + 1990); + + /* Parse the EDID structure information */ + edid.version.number = RD_B(ptr + 0x12); + edid.version.revision = RD_B(ptr + 0x13); + //DPRINTF("edid: version &%02X revision &%02X\n", edid.version.number, edid.version.revision); + + /* Parse the basic dislpay parameters/features */ + edid.basic.input_def = RD_B(ptr + 0x14); + edid.basic.max_horiz_sz = RD_B(ptr + 0x15); + edid.basic.max_vert_sz = RD_B(ptr + 0x16); + edid.basic.gamma = (100.0 + RD_B(ptr + 0x17)) / 100.0; + edid.basic.features = RD_B(ptr + 0x18); + + /* Parse the colour characteristics */ + parse_edid_colours(&(edid.colours), ptr + 0x19); + + /* Parse the established timings */ + edid.est_timings.timings[0] = RD_B(ptr + 0x23); + edid.est_timings.timings[1] = RD_B(ptr + 0x24); + edid.est_timings.resvd = RD_B(ptr + 0x25); + + /* Parse the bits at the end of the EDID structure */ + edid.ext_blocks = RD_B(ptr + 0x7E); + + /* Parse all of the standard timing identification */ + for (i = 0; i < sizeof(edid.std_timings.timing_id); i++) + edid.std_timings.timing_id[i] = RD_B(ptr + 0x26 + i); + + /* Parse all of the detailed timing descriptions (or monitor descriptors) */ + for (i = 0; i < 4; i++) + parse_edid_detail_desc(&(edid.timings[i]), ptr + 0x36 + (i * 0x12)); + + return lookup_edid_modes(dev, &edid); +} + + +void use_default_modes(dlo_device_t * const dev) +{ + uint32_t i; + + for (i = 0; i < DLO_MODE_DATA_NUM; i++) + dev->supported[i] = (dlo_modenum_t)i; +} + + +/* File-scope function definitions -----------------------------------------------------*/ + + +static dlo_retcode_t vreg(dlo_device_t * const dev, uint8_t reg, uint8_t val) +{ + if (dev->bufend - dev->bufptr < 4) + return dlo_err_buf_full; + + *(dev->bufptr)++ = '\xAF'; + *(dev->bufptr)++ = '\x20'; + *(dev->bufptr)++ = reg; + *(dev->bufptr)++ = val; + + return dlo_ok; +} + + +static dlo_retcode_t vbuf(dlo_device_t * const dev, const char * buf, size_t len) +{ + if (dev->bufend - dev->bufptr < len) + return dlo_err_buf_full; + + while (len--) + *(dev->bufptr)++ = *buf++; + + return dlo_ok; +} + + +static dlo_modenum_t get_mode_number(dlo_device_t * const dev, const uint16_t width, const uint16_t height, const uint8_t refresh, const uint8_t bpp) +{ + dlo_modenum_t idx; + uint32_t num; + + /* Look for all matching modes in our array of video timing structures. + * + * Note: if we don't have EDID data for the monitor attached to the device + * we simply look through all the modes we have, rather than only looking + * at the supported modes list. + */ + for (idx = 0; idx < DLO_MODE_DATA_NUM; idx++) + { + /* Read the mode number from the device's supported modes array */ + num = dev->supported[idx]; + if (num == DLO_INVALID_MODE) + break; + + /* This sequence of if statements looks odd, take care if you decide to 'optimise' it! */ + if (dlo_mode_data[num].width != width) + continue; + if (bpp && dlo_mode_data[num].bpp != bpp) + continue; + if (height && dlo_mode_data[num].height != height) + continue; + if (refresh && dlo_mode_data[num].refresh != refresh) + continue; + + /* If we're satisfied with the tests above, then return the mode number */ + return num; + } + + /* No matches found, return an invalid mode number */ + return DLO_INVALID_MODE; +} + + +static dlo_retcode_t mode_select(dlo_device_t * const dev, const dlo_mode_t * const desc, const dlo_modenum_t mode) +{ + if (mode >= DLO_MODE_DATA_NUM || mode == DLO_INVALID_MODE) + return dlo_err_bad_mode; + + /* Base address must be aligned to a two byte boundary */ + if (desc->view.base & 1) + return dlo_err_bad_mode; + + /* Flush the command buffer */ + if (dlo_ok != dlo_usb_write(dev)) + return DLO_INVALID_MODE; + + dev->mode.view.base = desc->view.base; + dev->base8 = desc->view.base + (BYTES_PER_16BPP * desc->view.width * desc->view.height); + ERR(set_base(dev, dev->mode.view.base, dev->base8)); + + /* Only change mode if the new raster bitmap's characteristics differ from the current. + * + * Note: don't compare reduced blanking flag because if the rest is the same, we can use the + * same blanking type. However, there's an outside chance that the low_blank hint was changed + * since entering the current mode in which case you may well want a mode change to happen but + * we'll just hope that never happens (seems like a very unlikely scenario). + */ + if (desc->view.width != dev->mode.view.width || + desc->view.height != dev->mode.view.height || + desc->view.bpp != dev->mode.view.bpp) + { + ERR(dlo_usb_chan_sel(dev, dlo_mode_data[mode].mode_en, dlo_mode_data[mode].mode_en_sz)); + ERR(dlo_usb_write_buf(dev, dlo_mode_data[mode].data, dlo_mode_data[mode].data_sz)); + ERR(dlo_usb_chan_sel(dev, DLO_MODE_POSTAMBLE, DSIZEOF(DLO_MODE_POSTAMBLE))); + } + + /* Update the device with the new mode details */ + dev->mode = *desc; + dev->mode.refresh = dlo_mode_data[mode].refresh; + dev->low_blank = dlo_mode_data[mode].low_blank; + + //DPRINTF("mode: select: %ux%u @ %u Hz %u bpp (base &%X base8 &%X low? %s)\n", + // dev->mode.view.width, dev->mode.view.height, dev->mode.refresh, dev->mode.view.bpp, + // dev->mode.view.base, dev->base8, dev->low_blank ? "yes" : "no"); + + /* Flush the command buffer */ + ERR(dlo_usb_write(dev)); + + /* Return a warning for DL160 modes */ + return (mode < DLO_DL120_MODES) ? dlo_warn_dl160_mode : dlo_ok; +} + + +static uint16_t add_supported(dlo_device_t * const dev, uint16_t idx, const uint16_t width, const uint16_t height, const uint8_t refresh) +{ + dlo_modenum_t num; + + num = get_mode_number(dev, width, height, refresh, 24); + if (num != DLO_INVALID_MODE) + dev->supported[idx++] = num; + +// DPRINTF("mode: add_supt: %ux%u @ %u Hz, %u bpp = num %u\n", width, height, refresh, 24, (int)num); + + return idx; +} + + +static dlo_retcode_t lookup_edid_modes(dlo_device_t * const dev, const edid_format_t * const edid) +{ + uint32_t timings, bit; + uint32_t idx = 0; + + /* Clear the native mode information for the device */ + (void) dlo_memset(&dev->native, 0, sizeof(dlo_mode_t)); + + /* Add mode numbers for any supported established timing modes */ + timings = edid->est_timings.timings[0] | (edid->est_timings.timings[1] << 8) | (edid->est_timings.resvd << 16); + for (bit = 0; bit < 24; bit++) + { + if (est_timings[bit].width) + idx = add_supported(dev, idx, est_timings[bit].width, est_timings[bit].height, est_timings[bit].refresh); + } + + /* Add further support from the detailed timing descriptions */ + for (timings = 0; timings < 4; timings++) + { + const edid_detail_t * const detail = &(edid->timings[timings].detail); + + if (detail->is_detail) + { + uint8_t hz; + + for (hz = 50; hz < 100; hz++) + { + uint32_t prev = idx; + uint32_t width = detail->hactl + ((detail->hactblankh & 0xF0) << 4); + uint32_t height = detail->vactl + ((detail->vactblankh & 0xF0) << 4); + + idx = add_supported(dev, idx, width, height, hz); + + /* Have we added a mode definition for the native resolution reported by the display? */ + if (idx != prev) + { + dlo_modenum_t num = dev->supported[prev]; + + dev->native.view.base = 0; + dev->native.view.width = dlo_mode_data[num].width; + dev->native.view.height = dlo_mode_data[num].height; + dev->native.view.bpp = dlo_mode_data[num].bpp; + dev->native.refresh = dlo_mode_data[num].refresh; + DPRINTF("mode: lookup: native mode %u (%ux%u @ %u bpp, %uHz base &%X)\n", + num, + dev->native.view.width, + dev->native.view.height, + dev->native.view.bpp, + dev->native.refresh, + (int)dev->native.view.base); + } + } + } + } + + /* Fill any remaining array entries with the invalid mode constant */ + while (idx < DLO_MODE_DATA_NUM - 1) + dev->supported[idx++] = DLO_INVALID_MODE; + + return dlo_ok; +} + + +static dlo_retcode_t set_base(dlo_device_t * const dev, const dlo_ptr_t base, const dlo_ptr_t base8) +{ + //DPRINTF("mode: set_base: base=&%X base8=&%X\n", base, base8); + ERR(vbuf(dev, WRITE_VIDREG_LOCK, DSIZEOF(WRITE_VIDREG_LOCK))); + ERR(vreg(dev, 0x20, base >> 16)); + ERR(vreg(dev, 0x21, base >> 8)); + ERR(vreg(dev, 0x22, base)); + ERR(vreg(dev, 0x26, base8 >> 16)); + ERR(vreg(dev, 0x27, base8 >> 8)); + ERR(vreg(dev, 0x28, base8)); + ERR(vbuf(dev, WRITE_VIDREG_UNLOCK, DSIZEOF(WRITE_VIDREG_UNLOCK))); + ERR(dlo_usb_write(dev)); + + return dlo_ok; +} + + +static bool bad_edid_checksum(const uint8_t * const ptr, const size_t size) +{ + uint32_t i; + uint8_t csum = 0; + + for (i = 0; i < size; i++) + csum += ptr[i]; + + return 0 != csum; +} + + +static void parse_edid_detail_desc(edid_timing_desc_t * const desc, const uint8_t * const ptr) +{ + if (RD_B(ptr) || RD_B(ptr + 1) || RD_B(ptr + 2)) + { + //DPRINTF("edid: found timing detail (&%04X)\n", LETOHS(RD_S(ptr))); + desc->detail.is_detail = true; + desc->detail.pixclk = (float)LETOHS(RD_S(ptr)) / 100.0; + desc->detail.hactl = RD_B(ptr + 0x02); + desc->detail.hblankl = RD_B(ptr + 0x03); + desc->detail.hactblankh = RD_B(ptr + 0x04); + desc->detail.vactl = RD_B(ptr + 0x05); + desc->detail.vblankl = RD_B(ptr + 0x06); + desc->detail.vactblankh = RD_B(ptr + 0x07); + desc->detail.hsyncoffl = RD_B(ptr + 0x08); + desc->detail.hsyncwl = RD_B(ptr + 0x09); + desc->detail.vsyncoffvsyncwl = RD_B(ptr + 0x0A); + desc->detail.synch = RD_B(ptr + 0x0B); + desc->detail.hsizel = RD_B(ptr + 0x0C); + desc->detail.vsizel = RD_B(ptr + 0x0D); + desc->detail.hvsizeh = RD_B(ptr + 0x0E); + desc->detail.hbord = RD_B(ptr + 0x0F); + desc->detail.vbord = RD_B(ptr + 0x10); + desc->detail.flags = RD_B(ptr + 0x11); + + //DPRINTF("edid: Pixel Clock: %f MHz\n", (float)desc->detail.pixclk); + //DPRINTF("edid: H Active pixels: %d\n", desc->detail.hactl + ((desc->detail.hactblankh & 0xF0) << 4)); + //DPRINTF("edid: H Blank pixels: %d\n", desc->detail.hblankl + ((desc->detail.hactblankh & 0x0F) << 8)); + //DPRINTF("edid: V Active pixels: %d\n", desc->detail.vactl + ((desc->detail.vactblankh & 0xF0) << 4)); + //DPRINTF("edid: V Blank pixels: %d\n", desc->detail.vblankl + ((desc->detail.vactblankh & 0x0F) << 8)); + //DPRINTF("edid: H Sync Off: %d\n", desc->detail.hsyncoffl + ((desc->detail.synch & 0xC0) << 2)); + //DPRINTF("edid: H Sync Width: %d\n", desc->detail.hsyncwl + ((desc->detail.synch & 0x30) << 4)); + //DPRINTF("edid: V Sync Off: %d\n", (desc->detail.vsyncoffvsyncwl >> 4) + ((desc->detail.synch & 0x0C) << 6)); + //DPRINTF("edid: V Sync Width: %d\n", (desc->detail.vsyncoffvsyncwl & 0xF) + ((desc->detail.synch & 0x03) << 8)); + //DPRINTF("edid: H size: %d mm\n", desc->detail.hsizel + ((desc->detail.hvsizeh & 0xF0) << 4)); + //DPRINTF("edid: V size: %d mm\n", desc->detail.vsizel + ((desc->detail.hvsizeh & 0x0F) << 8)); + } + else + { + /* It's a mode descriptor - ignore for now */ + //DPRINTF("edid: found a mode descriptor type &%02X\n", RD_B(ptr+3)); + desc->desc.is_detail = false; + switch (RD_B(ptr+3)) + { + case 0xFC: + case 0xFE: + case 0xFF: + { + char buf[14]; + char *chr; + + snprintf(buf, 13, "%s", ptr + 5); + buf[13] = '\0'; + chr = strchr(buf, '\n'); + if (chr) + *chr = '\0'; + //DPRINTF("edid: monitor string '%s'\n", buf); + break; + } + default: + { + //uint32_t i; + //DPRINTF("edid: "); + //for (i = 0; i < 0x12; i++) + // DPRINTF("%02X ", RD_B(ptr+i)); + //DPRINTF("\n"); + } + } + } +} + +static void parse_edid_colours(edid_colours_t * const cols, const uint8_t * const ptr) +{ + /* Read the raw data */ + cols->red_grn_low = RD_B(ptr + 0x19); + cols->blu_wht_low = RD_B(ptr + 0x1A); + cols->red_x = RD_B(ptr + 0x1B); + cols->red_y = RD_B(ptr + 0x1C); + cols->grn_x = RD_B(ptr + 0x1D); + cols->grn_y = RD_B(ptr + 0x1E); + cols->blu_x = RD_B(ptr + 0x1F); + cols->blu_y = RD_B(ptr + 0x20); + cols->wht_x = RD_B(ptr + 0x21); + cols->wht_y = RD_B(ptr + 0x22); + + /* Do the expansion */ + cols->red_x = ((cols->red_grn_low & 0xC0) >> 6) + (cols->red_x << 2); + cols->red_y = ((cols->red_grn_low & 0x30) >> 4) + (cols->red_y << 2); + cols->grn_x = ((cols->red_grn_low & 0x0C) >> 2) + (cols->grn_x << 2); + cols->grn_y = ((cols->red_grn_low & 0x03) >> 0) + (cols->grn_y << 2); + cols->blu_x = ((cols->blu_wht_low & 0xC0) >> 6) + (cols->blu_x << 2); + cols->blu_y = ((cols->blu_wht_low & 0x40) >> 4) + (cols->blu_y << 2); + cols->wht_x = ((cols->blu_wht_low & 0x0C) >> 2) + (cols->wht_y << 2); + cols->wht_y = ((cols->blu_wht_low & 0x03) >> 0) + (cols->wht_y << 2); +} + + +/* End of file -------------------------------------------------------------------------*/ diff --git a/src/dlo_mode.h b/src/dlo_mode.h index 822cd0a..9932139 100644 --- a/src/dlo_mode.h +++ b/src/dlo_mode.h @@ -1,127 +1,127 @@ -/** @file dlo_mode.h
- *
- * @brief Definitions for the screen mode-related functions.
- *
- * These functions have been separated-out into a distinct compilation unit so that
- * it would be possible to build a distribution of the DisplayLink library which
- * inludes the object(s) associated with this unit as pre-built binaries (i.e.
- * without the dlo_mode.c source file included).
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DLO_MODE_H
-#define DLO_MODE_H /**< Avoid multiple inclusion. */
-
-#include "dlo_structs.h"
-
-
-/** Size of an EDID structure, as read from a device (bytes).
- */
-#define EDID_STRUCT_SZ (128)
-
-
-/** An undefined mode number. Used to indicate a failed look-up or an unknown mode.
- */
-#define DLO_INVALID_MODE ((dlo_modenum_t)-1)
-
-
-/** Initialise the screen mode handling functions.
- *
- * @param flags Initialisation flags word (unused flags ignored).
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_mode_init(const dlo_init_t flags);
-
-
-/** Finalisation call for the screen mode handling functions.
- *
- * @param flags Finalisation flags word (unused flags ignored).
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_mode_final(const dlo_final_t flags);
-
-
-/** Return a block of mode information for a given mode number.
- *
- * @param num Mode number for best match to the supplied bitmap.
- *
- * @return Pointer to mode information block (in static workspace), or NULL if error.
- */
-extern dlo_mode_t *dlo_mode_from_number(const dlo_modenum_t num);
-
-
-/** Select a display mode given a set of parameters.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param width Width of desired display (pixels).
- * @param height Hieght of desired display (pixels) - zero to select first available.
- * @param refresh Desired refresh rate (Hz) - zero to select first available.
- * @param bpp Colour depth (bits per pixel) - zero to select first available.
- *
- * @return Return code, zero for no error.
- *
- * Will find the best match it can from the VESA timings, given the parameters specified.
- * If no matching mode can be found, an error will be returned and the device's screen
- * mode will not be changed.
- */
-extern dlo_modenum_t dlo_mode_lookup(dlo_device_t * const dev, const uint16_t width, const uint16_t height, const uint8_t refresh, uint8_t bpp);
-
-
-/** Perform a mode change into the specified mode number.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param desc Pointer to mode description structure.
- * @param mode Mode number for best match to the mode descriptor (or @a DLO_INVALID_MODE if not known).
- *
- * @return Return code, zero for no error.
- *
- * This call will change the screen mode into the specified mode number (if one was given)
- * or look for one which matches the specified mode description. Chaging mode does not imply
- * clearing the screen!
- *
- * Note: this call will cause any buffered commands to be sent to the device.
- */
-extern dlo_retcode_t dlo_mode_change(dlo_device_t * const dev, const dlo_mode_t * const desc, dlo_modenum_t mode);
-
-
-/** Parse the EDID structure read from a display device and build a list of supported modes.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param ptr Pointer to EDID structure.
- * @param size Size of EDID structure (bytes).
- *
- * @return Return code, zero for no error.
- *
- * This call updates the @a dlo_device_t structure by constructing a list of supported
- * modes. Any modes which were not supplied in the EDID structure will be refused for
- * that device.
- */
-extern dlo_retcode_t dlo_mode_parse_edid(dlo_device_t * const dev, const uint8_t * const ptr, const size_t size);
-
-
-/** Reset the supported modes array for a device to include all of the default VESA mode timings.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- */
-extern void use_default_modes(dlo_device_t * const dev);
-
-
-#endif
+/** @file dlo_mode.h + * + * @brief Definitions for the screen mode-related functions. + * + * These functions have been separated-out into a distinct compilation unit so that + * it would be possible to build a distribution of the DisplayLink library which + * inludes the object(s) associated with this unit as pre-built binaries (i.e. + * without the dlo_mode.c source file included). + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef DLO_MODE_H +#define DLO_MODE_H /**< Avoid multiple inclusion. */ + +#include "dlo_structs.h" + + +/** Size of an EDID structure, as read from a device (bytes). + */ +#define EDID_STRUCT_SZ (128) + + +/** An undefined mode number. Used to indicate a failed look-up or an unknown mode. + */ +#define DLO_INVALID_MODE ((dlo_modenum_t)-1) + + +/** Initialise the screen mode handling functions. + * + * @param flags Initialisation flags word (unused flags ignored). + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_mode_init(const dlo_init_t flags); + + +/** Finalisation call for the screen mode handling functions. + * + * @param flags Finalisation flags word (unused flags ignored). + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_mode_final(const dlo_final_t flags); + + +/** Return a block of mode information for a given mode number. + * + * @param num Mode number for best match to the supplied bitmap. + * + * @return Pointer to mode information block (in static workspace), or NULL if error. + */ +extern dlo_mode_t *dlo_mode_from_number(const dlo_modenum_t num); + + +/** Select a display mode given a set of parameters. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param width Width of desired display (pixels). + * @param height Hieght of desired display (pixels) - zero to select first available. + * @param refresh Desired refresh rate (Hz) - zero to select first available. + * @param bpp Colour depth (bits per pixel) - zero to select first available. + * + * @return Return code, zero for no error. + * + * Will find the best match it can from the VESA timings, given the parameters specified. + * If no matching mode can be found, an error will be returned and the device's screen + * mode will not be changed. + */ +extern dlo_modenum_t dlo_mode_lookup(dlo_device_t * const dev, const uint16_t width, const uint16_t height, const uint8_t refresh, uint8_t bpp); + + +/** Perform a mode change into the specified mode number. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param desc Pointer to mode description structure. + * @param mode Mode number for best match to the mode descriptor (or @a DLO_INVALID_MODE if not known). + * + * @return Return code, zero for no error. + * + * This call will change the screen mode into the specified mode number (if one was given) + * or look for one which matches the specified mode description. Chaging mode does not imply + * clearing the screen! + * + * Note: this call will cause any buffered commands to be sent to the device. + */ +extern dlo_retcode_t dlo_mode_change(dlo_device_t * const dev, const dlo_mode_t * const desc, dlo_modenum_t mode); + + +/** Parse the EDID structure read from a display device and build a list of supported modes. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param ptr Pointer to EDID structure. + * @param size Size of EDID structure (bytes). + * + * @return Return code, zero for no error. + * + * This call updates the @a dlo_device_t structure by constructing a list of supported + * modes. Any modes which were not supplied in the EDID structure will be refused for + * that device. + */ +extern dlo_retcode_t dlo_mode_parse_edid(dlo_device_t * const dev, const uint8_t * const ptr, const size_t size); + + +/** Reset the supported modes array for a device to include all of the default VESA mode timings. + * + * @param dev Pointer to @a dlo_device_t structure. + */ +extern void use_default_modes(dlo_device_t * const dev); + + +#endif diff --git a/src/dlo_structs.h b/src/dlo_structs.h index d639a59..35e600d 100644 --- a/src/dlo_structs.h +++ b/src/dlo_structs.h @@ -1,92 +1,92 @@ -/** @file dlo_structs.h
- *
- * @brief This file defines all of the internal structures used by libdlo.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DLO_STRUCTS_H
-#define DLO_STRUCTS_H /**< Avoid multiple inclusion. */
-
-#include "libdlo.h"
-#include "dlo_data.h"
-
-
-/** Structure holding all of the information specific to a particular device.
- */
-typedef struct dlo_device_s dlo_device_t;
-
-
-/** A mode number used to index a specific mode from the list defined in dlo_mode_data.c.
- */
-typedef uint32_t dlo_modenum_t;
-
-
-/** Structure used internally by dlo_usb.c (stored as dev->cnct in @a dlo_device_t structure).
- *
- * This is required to keep track of which USB device a given @a dlo_device_t structure
- * represents so that our various functions can do their stuff with libusb.
- */
-typedef struct dlo_usb_dev_s
-{
- struct usb_device *udev; /**< Pointer to USB device structure for given device. */
- usb_dev_handle *uhand; /**< USB device handle (once device is "opened"). */
-} dlo_usb_dev_t; /**< A struct @a dlo_usb_dev_s. */
-
-
-/** An internal representation of a viewport within the DisplayLink device.
- *
- * An area is generated from a viewport and a rectangle within that viewport (which
- * has no parts lying outside but may cover the complete extent of the viewport). It
- * has a base address for both the 16 bpp component of a pixel's colour and the 8 bpp
- * fine detail component. It also requires a stride in the case where the rectangle
- * didn't fully occupy the horizontal extent of the viewport.
- */
-typedef struct dlo_area_s
-{
- dlo_view_t view; /**< Viewport information (normalised to a specific rectangle within a viewport). */
- dlo_ptr_t base8; /**< The base address of the 8 bpp fine detail colour information. */
- uint32_t stride; /**< The stride (pixels) from one pixel in the area to the one directly below. */
-} dlo_area_t; /**< A struct @a dlo_area_s. */
-
-
-/** Structure holding all of the information specific to a particular device.
- */
-struct dlo_device_s
-{
- dlo_device_t *prev; /**< Pointer to previous node on device list. */
- dlo_device_t *next; /**< Pointer to next node on device list. */
- dlo_devtype_t type; /**< Type of DisplayLink device. */
- char *serial; /**< Pointer to device serial number string. */
- bool claimed; /**< Has the device been claimed by someone? */
- bool check; /**< Flag is toggled for each enumeration to spot dead nodes in device list. */
- uint32_t timeout; /**< Timeout for bulk communications (milliseconds). */
- uint32_t memory; /**< Total size of storage in the device (bytes). */
- char *buffer; /**< Pointer to the base of the command buffer. */
- char *bufptr; /**< Pointer to the first free byte in the command buffer. */
- char *bufend; /**< Pointer to the byte after the end byte of the command buffer. */
- dlo_usb_dev_t *cnct; /**< Private word for connection specific data or structure pointer. */
- dlo_mode_t mode; /**< Current display mode information. */
- dlo_ptr_t base8; /**< Pointer to the base of the 8bpp segment (if any). */
- bool low_blank; /**< The current raster screen mode has reduced blanking. */
- dlo_mode_t native; /**< Mode number of the display's native screen mode (if any). */
- dlo_modenum_t supported[DLO_MODE_DATA_NUM]; /**< Array of supported mode numbers. */
-};
-
-
-#endif
+/** @file dlo_structs.h + * + * @brief This file defines all of the internal structures used by libdlo. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef DLO_STRUCTS_H +#define DLO_STRUCTS_H /**< Avoid multiple inclusion. */ + +#include "libdlo.h" +#include "dlo_data.h" + + +/** Structure holding all of the information specific to a particular device. + */ +typedef struct dlo_device_s dlo_device_t; + + +/** A mode number used to index a specific mode from the list defined in dlo_mode_data.c. + */ +typedef uint32_t dlo_modenum_t; + + +/** Structure used internally by dlo_usb.c (stored as dev->cnct in @a dlo_device_t structure). + * + * This is required to keep track of which USB device a given @a dlo_device_t structure + * represents so that our various functions can do their stuff with libusb. + */ +typedef struct dlo_usb_dev_s +{ + struct usb_device *udev; /**< Pointer to USB device structure for given device. */ + usb_dev_handle *uhand; /**< USB device handle (once device is "opened"). */ +} dlo_usb_dev_t; /**< A struct @a dlo_usb_dev_s. */ + + +/** An internal representation of a viewport within the DisplayLink device. + * + * An area is generated from a viewport and a rectangle within that viewport (which + * has no parts lying outside but may cover the complete extent of the viewport). It + * has a base address for both the 16 bpp component of a pixel's colour and the 8 bpp + * fine detail component. It also requires a stride in the case where the rectangle + * didn't fully occupy the horizontal extent of the viewport. + */ +typedef struct dlo_area_s +{ + dlo_view_t view; /**< Viewport information (normalised to a specific rectangle within a viewport). */ + dlo_ptr_t base8; /**< The base address of the 8 bpp fine detail colour information. */ + uint32_t stride; /**< The stride (pixels) from one pixel in the area to the one directly below. */ +} dlo_area_t; /**< A struct @a dlo_area_s. */ + + +/** Structure holding all of the information specific to a particular device. + */ +struct dlo_device_s +{ + dlo_device_t *prev; /**< Pointer to previous node on device list. */ + dlo_device_t *next; /**< Pointer to next node on device list. */ + dlo_devtype_t type; /**< Type of DisplayLink device. */ + char *serial; /**< Pointer to device serial number string. */ + bool claimed; /**< Has the device been claimed by someone? */ + bool check; /**< Flag is toggled for each enumeration to spot dead nodes in device list. */ + uint32_t timeout; /**< Timeout for bulk communications (milliseconds). */ + uint32_t memory; /**< Total size of storage in the device (bytes). */ + char *buffer; /**< Pointer to the base of the command buffer. */ + char *bufptr; /**< Pointer to the first free byte in the command buffer. */ + char *bufend; /**< Pointer to the byte after the end byte of the command buffer. */ + dlo_usb_dev_t *cnct; /**< Private word for connection specific data or structure pointer. */ + dlo_mode_t mode; /**< Current display mode information. */ + dlo_ptr_t base8; /**< Pointer to the base of the 8bpp segment (if any). */ + bool low_blank; /**< The current raster screen mode has reduced blanking. */ + dlo_mode_t native; /**< Mode number of the display's native screen mode (if any). */ + dlo_modenum_t supported[DLO_MODE_DATA_NUM]; /**< Array of supported mode numbers. */ +}; + + +#endif diff --git a/src/dlo_usb.c b/src/dlo_usb.c index a2e1bf1..4fbf282 100644 --- a/src/dlo_usb.c +++ b/src/dlo_usb.c @@ -1,561 +1,561 @@ -/** @file dlo_usb.c
- *
- * @brief Implements the USB-specific connectivity functions.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <string.h>
-#include "netinet/in.h"
-#include "dlo_defs.h"
-#include "dlo_usb.h"
-#include "dlo_base.h"
-#include "dlo_mode.h"
-
-
-/* File-scope defines ------------------------------------------------------------------*/
-
-
-#define NR_USB_REQUEST_STATUS_DW (0x06) /**< USB control message: request type. */
-#define NR_USB_REQUEST_CHANNEL (0x12) /**< USB control message: request type. */
-#define NR_USB_REQUEST_I2C_SUB_IO (0x02) /**< USB control message: request type. */
-
-/** USB VendorID for a DisplayLink device.
- */
-#define VENDORID_DISPLAYLINK (0x17E9)
-
-/** Number of milliseconds to wait before timing-out a USB control message.
- */
-#define CTRL_TIMEOUT (100u)
-
-/** Number of milliseconds to wait before timing-out channel selection message.
- */
-#define CHANSEL_TIMEOUT (5000u)
-
-/** Number of milliseconds to wait before timing-out a USB bulk transfer.
- */
-#define WRITE_TIMEOUT (10000u)
-
-/** Number of milliseconds to wait before timing-out a request for the device type.
- */
-#define ID_TIMEOUT (1000u)
-
-/** Byte sequence to send to the device to select the default communication channel.
- */
-#define STD_CHANNEL "\x57\xCD\xDC\xA7\x1C\x88\x5E\x15\x60\xFE\xC6\x97\x16\x3D\x47\xF2"
-
-
-/* File-scope types --------------------------------------------------------------------*/
-
-
-/* External scope variables ------------------------------------------------------------*/
-
-
-int32_t usberr = 0;
-
-
-/* File-scope variables ----------------------------------------------------------------*/
-
-
-/** Pointer to a copy of the last error message string read out of libusb (or NULL).
- */
-static char *usb_err_str = NULL;
-
-
-/* File-scope function declarations ----------------------------------------------------*/
-
-
-/** Connect to a device, read information about it and then disconnect again.
- *
- * @param dev USB device structure pointer.
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t check_device(struct usb_device *dev);
-
-
-/** Attempt to read the EDID structure from the monitor attached to the specified device.
- *
- * @param dev Device structure pointer.
- * @param uhand USB device handle.
- *
- * @return Return code, zero for no error.
- */
-static dlo_retcode_t read_edid(dlo_device_t * const dev, usb_dev_handle *uhand);
-
-
-/** Make a note of any error returned by libusb.
- *
- * @return Return code to indicate a USB-related error.
- *
- * Often, by the time we have returned from a function, the error code stored in libusb
- * has been lost because our tidy-up code will call more libusb functions after an error
- * is spotted. As such, this function is called automatically by the @c UERR() and
- * @c UERR_GOTO() macros in order to make a note of the error number and message from
- * libusb at the moment the error is caught. This information is stored locally for
- * retrieval by @c dlo_usb_strerror().
- */
-static dlo_retcode_t usb_error_grab(void);
-
-
-/* Public function definitions ---------------------------------------------------------*/
-
-
-char *dlo_usb_strerror(void)
-{
- //DPRINTF("usb: error lookup %d\n", usberr);
- return usb_err_str;
-}
-
-
-dlo_retcode_t dlo_usb_init(const dlo_init_t flags)
-{
- /* Initialise libusb */
- //DPRINTF("usb: init\n");
- usb_init();
-
- /* Add nodes onto the device list for any DisplayLink devices we find */
- //DPRINTF("usb: init: enum\n");
- ERR(dlo_usb_enumerate(true));
-
- return dlo_ok;
-}
-
-
-dlo_retcode_t dlo_usb_final(const dlo_final_t flags)
-{
- if (usb_err_str)
- dlo_free(usb_err_str);
-
- return dlo_ok;
-}
-
-dlo_retcode_t dlo_usb_enumerate(const bool init)
-{
- struct usb_bus *bus;
- struct usb_device *dev = NULL;
- int32_t db = usb_find_busses();
- int32_t dd = usb_find_devices();
- DPRINTF("usb: dlo_usb_enumerate\n");
-
- /* We should do this even if it looks like there are no changes on the bus because
- * an open() call might call the above functions just to check it's safe to use the
- * USB device structure pointer. Yuck!
- *
- * If this isn't the first enumeration and there are no changes on the bus, don't touch the list
- *
- * if (!init && !db && !dd)
- * return dlo_ok;
- */
- IGNORE(db);
- IGNORE(dd);
-
- /* Look for all DisplayLink devices on the USB busses */
- for (bus = usb_get_busses(); bus; bus = bus->next)
- for (dev = bus->devices; dev; dev = dev->next)
- ERR(check_device(dev)); /* Check to see if it's a DisplayLink device. If it is, add to or update the dev_list */
-
- return dlo_ok;
-}
-
-
-static dlo_retcode_t check_device(struct usb_device *udev)
-{
- static char string[255];
- usb_dev_handle *uhand = usb_open(udev);
- dlo_retcode_t err = dlo_ok;
- dlo_device_t *dev = NULL;
- bool not_root = false;
- uint8_t buf[4];
- dlo_devtype_t type;
-
- //DPRINTF("usb: check: check dev &%X\n", (int)dev);
-
- if (!uhand) {
- // this may not be our device. We just can't open it
- return dlo_ok;
- }
-
- //DPRINTF("usb: check: uhand &%X vendorID &%X\n", (int)uhand, udev->descriptor.idVendor);
-
- /* Reject devices that don't have the DisplayLink VendorID */
- if (udev->descriptor.idVendor != VENDORID_DISPLAYLINK)
- {
- UERR(usb_close(uhand));
- return dlo_ok;
- }
- //DPRINTF("usb: check: get type\n");
-
- /* Ask the device for some status information */
- not_root = true; /* Special case error handling here */
- UERR_GOTO(usb_control_msg(/* handle */ uhand,
- /* requestType */ USB_ENDPOINT_IN | USB_TYPE_VENDOR,
- /* request */ NR_USB_REQUEST_STATUS_DW,
- /* value */ 0,
- /* index */ 0,
- /* bytes */ (char *)buf,
- /* size */ sizeof(buf),
- /* timeout */ ID_TIMEOUT));
- not_root = false; /* Back to normal error handling */
- //DPRINTF("usb: check: type buf[3] = &%X\n", buf[3]);
-
- /* Determine what type of device we are connected to */
- switch ((buf[3] >> 4) & 0xF)
- {
- case dlo_dev_base:
- type = dlo_dev_base;
- break;
- case dlo_dev_alex:
- type = dlo_dev_alex;
- break;
- default:
- if (buf[3] == dlo_dev_ollie)
- type = dlo_dev_ollie;
- else
- type = dlo_dev_unknown;
- }
-
- /* Read the device serial number as a string */
- UERR_GOTO(usb_get_string_simple(uhand, udev->descriptor.iSerialNumber, string, sizeof(string)));
- //DPRINTF("usb: check: type &%X serial '%s'\n", (int)type, string);
-
- /* See if this device is already in our device list */
- dev = dlo_device_lookup(string);
- if (dev)
- {
- /* Use this opportunity to update the USB device structure pointer, just in
- * case it has moved.
- */
- dev->cnct->udev = udev;
- //DPRINTF("usb: check: already in list\n");
- }
- else
- {
- /* Add a new device to the device list */
- //DPRINTF("usb: check: create new device\n");
- dev = dlo_new_device(type, string);
- NERR_GOTO(dev);
-
- /* It's not. Create and initialise a new list node for the device */
- dev->cnct = (dlo_usb_dev_t *)dlo_malloc(sizeof(dlo_usb_dev_t));
- NERR_GOTO(dev->cnct);
- dev->cnct->udev = udev;
- dev->cnct->uhand = NULL;
- }
- //DPRINTF("usb: check: dlpp node &%X\n", (int)dev);
-
- /* Close our temporary handle for the device. If this errors, we'll have a duff entry in
- * the device list but at least the list integrity will be OK.
- */
- UERR_GOTO(usb_close(uhand));
-
- return dlo_ok;
-
-error:
- /* Free our dev->cnct USB information structure */
- if (dev)
- {
- if (dev->cnct)
- dlo_free(dev->cnct);
- dev->cnct = NULL;
- }
-
- /* Close our temporary handle for the device */
- (void) usb_close(uhand);
-
- /* If the executable wasn't run as root, this is where it normally falls over.
- * So we'll special case that particular error to help indicate this problem.
- */
- if (not_root)
- return dlo_err_not_root;
-
- return err;
-}
-
-
-dlo_retcode_t dlo_usb_open(dlo_device_t * const dev)
-{
- dlo_retcode_t err;
- usb_dev_handle *uhand;
- char* driver_name;
- int usb_configuration;
- int i;
- int32_t db = usb_find_busses();
- int32_t dd = usb_find_devices();
-
- /* Do we trust the USB device pointer? Not if the structures may have changed under us... */
- if (db || dd)
- return dlo_err_reenum;
-
- /* Open the device */
- uhand = usb_open(dev->cnct->udev);
- DPRINTF("usb: open: uhand &%X\n", (int)uhand);
-
- if (!uhand)
- return dlo_err_open;
-
- /* Store the USB device handle in our dev->cnct word */
- dev->cnct->uhand = uhand;
-
- /* Establish the connection with the device */
- //DPRINTF("usb: open: setting config...\n");
-
- /*
- * Because some displaylink devices may report
- * a class code (like HID or MSC) that gets
- * matched by a kernel driver, we must detach
- * those drivers before libusb can successfully
- * set configuration or talk to those devices.
- * For now, we kick everyone off our device,
- * but that includes cases we're intentionally
- * a composite device with HID interfaces that
- * control something (e.g. a button on a dock).
- * And the code below is blindly unloading
- * the kernel HID drivers for those. May want
- * to get more sophisticated in the future.
- */
- driver_name = dlo_malloc(128);
- for (i=0; i < dev->cnct->udev->config->bNumInterfaces; i++)
- {
- memset(driver_name, 0, 128);
- if (usb_get_driver_np(uhand, i, driver_name, 128) == 0)
- {
- DPRINTF("usb: driver (%s) already attached to device\n", driver_name);
-
- // Reports are that this call can return error even if successful
- usb_detach_kernel_driver_np(uhand,i);
- }
- }
-
- UERR(usb_set_configuration(uhand, 1));
-
- //DPRINTF("usb: open: claiming iface...\n");
- UERR(usb_claim_interface(uhand, 0));
-
- /* Mark the device as claimed */
- dev->claimed = true;
-
- /* Allocate a buffer to hold commands before they are sent to the device */
- if (!dev->buffer)
- {
- //DPRINTF("usb: open: alloc buffer...\n");
- dev->buffer = dlo_malloc(BUF_SIZE);
- NERR(dev->buffer);
- dev->bufptr = dev->buffer;
- dev->bufend = dev->buffer + BUF_SIZE;
- }
- //DPRINTF("usb: open: buffer &%X, &%X, &%X\n", (int)dev->buffer, (int)dev->bufptr, (int)dev->bufend);
-
- /* Use the default timeout if none was specified */
- if (!dev->timeout)
- dev->timeout = WRITE_TIMEOUT;
- //DPRINTF("usb: open: timeout %u ms\n", dev->timeout);
-
- /* Initialise the supported modes array for this device to include all our pre-defined modes */
- use_default_modes(dev);
-
- /* Attempt to read the EDID information, to refine the supported modes array contents */
- err = read_edid(dev, uhand);
-#ifdef DEBUG
- if (err != dlo_ok)
- DPRINTF("usb: open: edid error %u '%s'\n", (int)err, dlo_strerror(err));
-#endif
-
- return dlo_ok;
-}
-
-
-dlo_retcode_t dlo_usb_close(dlo_device_t * const dev)
-{
- if (dev->claimed)
- {
- if (dev->buffer)
- {
- dlo_free(dev->buffer);
- dev->buffer = NULL;
- dev->bufptr = NULL;
- dev->bufend = NULL;
- }
- dev->claimed = false;
- UERR(usb_release_interface(dev->cnct->uhand, 0));
- UERR(usb_close(dev->cnct->uhand));
- }
- return dlo_ok;
-}
-
-
-dlo_retcode_t dlo_usb_chan_sel(const dlo_device_t * const dev, const char * const buf, const size_t size)
-{
- if (size)
- UERR(usb_control_msg(/* handle */ dev->cnct->uhand,
- /* requestType */ USB_TYPE_VENDOR,
- /* request */ NR_USB_REQUEST_CHANNEL,
- /* value */ 0,
- /* index */ 0,
- /* bytes */ (char *)buf,
- /* size */ size,
- /* timeout */ CHANSEL_TIMEOUT));
- return dlo_ok;
-}
-
-
-dlo_retcode_t dlo_usb_std_chan(const dlo_device_t * const dev)
-{
- dlo_retcode_t err;
-
- ASSERT(strlen(STD_CHANNEL) == 16);
- err = dlo_usb_chan_sel(dev, STD_CHANNEL, DSIZEOF(STD_CHANNEL));
-
- return err;
-}
-
-
-dlo_retcode_t dlo_usb_write(dlo_device_t * const dev)
-{
- dlo_retcode_t err = dlo_usb_write_buf(dev, dev->buffer, dev->bufptr - dev->buffer);
-
- dev->bufptr = dev->buffer;
-
- return err;
-}
-
-
-dlo_retcode_t dlo_usb_write_buf(dlo_device_t * const dev, char * buf, size_t size)
-{
-#ifdef DEBUG_DUMP
- static char outfile[64];
- static uint32_t outnum = 0;
- FILE *out = NULL;
-#endif
-
- if (!dev->claimed)
- return dlo_err_unclaimed;
-
- if (!size)
- return dlo_ok;
-
-#ifdef WRITE_BUF_BODGE
- /* If the buffer to write is fewer than 513 bytes in size, copy into 513 byte buffer and pad with zeros */
- if (size < WRITE_BUF_BODGE)
- {
- dlo_retcode_t err;
- uint32_t rem = WRITE_BUF_BODGE - size;
- char *cpy = dlo_malloc(WRITE_BUF_BODGE);
-
- NERR(cpy);
- dlo_memcpy(cpy, buf, size);
- dlo_memset(cpy + size, 0, rem);
- err = dlo_usb_write_buf(dev, cpy, size + rem);
- dlo_free(cpy);
-
- return err;
- }
-#endif
-
- while (size)
- {
- size_t num = size > BUF_SIZE ? BUF_SIZE : size;
-
-#ifdef DEBUG_DUMP
- (void) snprintf(outfile, sizeof(outfile), "dump/%02X/bulk%03X.dat", outnum & 0xFF, outnum >> 8);
- outnum++;
- out = fopen(outfile, "wb");
- if (out)
- {
- (void) fwrite(buf, num, 1, out);
- (void) fclose(out);
- out = NULL;
- }
-#endif
-
- UERR(usb_bulk_write(/* handle */ dev->cnct->uhand,
- /* endpoint */ 1,
- /* bytes */ buf,
- /* size */ num,
- /* timeout */ dev->timeout));
- buf += num;
- size -= num;
- }
- return dlo_ok;
-}
-
-
-/* File-scope function definitions -----------------------------------------------------*/
-
-
-static dlo_retcode_t usb_error_grab(void)
-{
- char *str = usb_strerror();
-
- /* If we have a previous USB error message stored, free it */
- if (usb_err_str)
- dlo_free(usb_err_str);
-
- if (str)
- {
- /* Allocate memory for the new error message and store that */
- usb_err_str = dlo_malloc(1 + strlen(str));
- if (usb_err_str)
- strcpy(usb_err_str, str);
- }
-
- /* Always return the generic USB error code */
- return dlo_err_usb;
-}
-
-
-
-static dlo_retcode_t read_edid(dlo_device_t * const dev, usb_dev_handle *uhand)
-{
- dlo_retcode_t err;
- uint32_t i;
- uint8_t buf[2];
- uint8_t *edid;
-
- /* Allocate a buffer to hold the EDID structure */
- edid = dlo_malloc(EDID_STRUCT_SZ);
- NERR(edid);
-
- /* Attempt to read the EDID structure from the device */
- for (i = 0; i < EDID_STRUCT_SZ; i++)
- {
- UERR_GOTO(usb_control_msg(/* handle */ uhand,
- /* requestType */ USB_ENDPOINT_IN | USB_TYPE_VENDOR,
- /* request */ NR_USB_REQUEST_I2C_SUB_IO,
- /* value */ i << 8,
- /* index */ 0xA1,
- /* bytes */ (char *)buf,
- /* size */ sizeof(buf),
- /* timeout */ dev->timeout));
- if (buf[0])
- ERR_GOTO(dlo_err_iic_op);
- //DPRINTF("usb: edid[%u]=&%02X\n", i, buf[1]);
- edid[i] = buf[1];
- }
-
- /* Supply the prospective EDID structure to the parser */
- ERR_GOTO(dlo_mode_parse_edid(dev, edid, EDID_STRUCT_SZ));
-
-error:
- dlo_free(edid);
-
- return err;
-}
-
-
-/* End of file -------------------------------------------------------------------------*/
+/** @file dlo_usb.c + * + * @brief Implements the USB-specific connectivity functions. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <string.h> +#include "netinet/in.h" +#include "dlo_defs.h" +#include "dlo_usb.h" +#include "dlo_base.h" +#include "dlo_mode.h" + + +/* File-scope defines ------------------------------------------------------------------*/ + + +#define NR_USB_REQUEST_STATUS_DW (0x06) /**< USB control message: request type. */ +#define NR_USB_REQUEST_CHANNEL (0x12) /**< USB control message: request type. */ +#define NR_USB_REQUEST_I2C_SUB_IO (0x02) /**< USB control message: request type. */ + +/** USB VendorID for a DisplayLink device. + */ +#define VENDORID_DISPLAYLINK (0x17E9) + +/** Number of milliseconds to wait before timing-out a USB control message. + */ +#define CTRL_TIMEOUT (100u) + +/** Number of milliseconds to wait before timing-out channel selection message. + */ +#define CHANSEL_TIMEOUT (5000u) + +/** Number of milliseconds to wait before timing-out a USB bulk transfer. + */ +#define WRITE_TIMEOUT (10000u) + +/** Number of milliseconds to wait before timing-out a request for the device type. + */ +#define ID_TIMEOUT (1000u) + +/** Byte sequence to send to the device to select the default communication channel. + */ +#define STD_CHANNEL "\x57\xCD\xDC\xA7\x1C\x88\x5E\x15\x60\xFE\xC6\x97\x16\x3D\x47\xF2" + + +/* File-scope types --------------------------------------------------------------------*/ + + +/* External scope variables ------------------------------------------------------------*/ + + +int32_t usberr = 0; + + +/* File-scope variables ----------------------------------------------------------------*/ + + +/** Pointer to a copy of the last error message string read out of libusb (or NULL). + */ +static char *usb_err_str = NULL; + + +/* File-scope function declarations ----------------------------------------------------*/ + + +/** Connect to a device, read information about it and then disconnect again. + * + * @param dev USB device structure pointer. + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t check_device(struct usb_device *dev); + + +/** Attempt to read the EDID structure from the monitor attached to the specified device. + * + * @param dev Device structure pointer. + * @param uhand USB device handle. + * + * @return Return code, zero for no error. + */ +static dlo_retcode_t read_edid(dlo_device_t * const dev, usb_dev_handle *uhand); + + +/** Make a note of any error returned by libusb. + * + * @return Return code to indicate a USB-related error. + * + * Often, by the time we have returned from a function, the error code stored in libusb + * has been lost because our tidy-up code will call more libusb functions after an error + * is spotted. As such, this function is called automatically by the @c UERR() and + * @c UERR_GOTO() macros in order to make a note of the error number and message from + * libusb at the moment the error is caught. This information is stored locally for + * retrieval by @c dlo_usb_strerror(). + */ +static dlo_retcode_t usb_error_grab(void); + + +/* Public function definitions ---------------------------------------------------------*/ + + +char *dlo_usb_strerror(void) +{ + //DPRINTF("usb: error lookup %d\n", usberr); + return usb_err_str; +} + + +dlo_retcode_t dlo_usb_init(const dlo_init_t flags) +{ + /* Initialise libusb */ + //DPRINTF("usb: init\n"); + usb_init(); + + /* Add nodes onto the device list for any DisplayLink devices we find */ + //DPRINTF("usb: init: enum\n"); + ERR(dlo_usb_enumerate(true)); + + return dlo_ok; +} + + +dlo_retcode_t dlo_usb_final(const dlo_final_t flags) +{ + if (usb_err_str) + dlo_free(usb_err_str); + + return dlo_ok; +} + +dlo_retcode_t dlo_usb_enumerate(const bool init) +{ + struct usb_bus *bus; + struct usb_device *dev = NULL; + int32_t db = usb_find_busses(); + int32_t dd = usb_find_devices(); + DPRINTF("usb: dlo_usb_enumerate\n"); + + /* We should do this even if it looks like there are no changes on the bus because + * an open() call might call the above functions just to check it's safe to use the + * USB device structure pointer. Yuck! + * + * If this isn't the first enumeration and there are no changes on the bus, don't touch the list + * + * if (!init && !db && !dd) + * return dlo_ok; + */ + IGNORE(db); + IGNORE(dd); + + /* Look for all DisplayLink devices on the USB busses */ + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) + ERR(check_device(dev)); /* Check to see if it's a DisplayLink device. If it is, add to or update the dev_list */ + + return dlo_ok; +} + + +static dlo_retcode_t check_device(struct usb_device *udev) +{ + static char string[255]; + usb_dev_handle *uhand = usb_open(udev); + dlo_retcode_t err = dlo_ok; + dlo_device_t *dev = NULL; + bool not_root = false; + uint8_t buf[4]; + dlo_devtype_t type; + + //DPRINTF("usb: check: check dev &%X\n", (int)dev); + + if (!uhand) { + // this may not be our device. We just can't open it + return dlo_ok; + } + + //DPRINTF("usb: check: uhand &%X vendorID &%X\n", (int)uhand, udev->descriptor.idVendor); + + /* Reject devices that don't have the DisplayLink VendorID */ + if (udev->descriptor.idVendor != VENDORID_DISPLAYLINK) + { + UERR(usb_close(uhand)); + return dlo_ok; + } + //DPRINTF("usb: check: get type\n"); + + /* Ask the device for some status information */ + not_root = true; /* Special case error handling here */ + UERR_GOTO(usb_control_msg(/* handle */ uhand, + /* requestType */ USB_ENDPOINT_IN | USB_TYPE_VENDOR, + /* request */ NR_USB_REQUEST_STATUS_DW, + /* value */ 0, + /* index */ 0, + /* bytes */ (char *)buf, + /* size */ sizeof(buf), + /* timeout */ ID_TIMEOUT)); + not_root = false; /* Back to normal error handling */ + //DPRINTF("usb: check: type buf[3] = &%X\n", buf[3]); + + /* Determine what type of device we are connected to */ + switch ((buf[3] >> 4) & 0xF) + { + case dlo_dev_base: + type = dlo_dev_base; + break; + case dlo_dev_alex: + type = dlo_dev_alex; + break; + default: + if (buf[3] == dlo_dev_ollie) + type = dlo_dev_ollie; + else + type = dlo_dev_unknown; + } + + /* Read the device serial number as a string */ + UERR_GOTO(usb_get_string_simple(uhand, udev->descriptor.iSerialNumber, string, sizeof(string))); + //DPRINTF("usb: check: type &%X serial '%s'\n", (int)type, string); + + /* See if this device is already in our device list */ + dev = dlo_device_lookup(string); + if (dev) + { + /* Use this opportunity to update the USB device structure pointer, just in + * case it has moved. + */ + dev->cnct->udev = udev; + //DPRINTF("usb: check: already in list\n"); + } + else + { + /* Add a new device to the device list */ + //DPRINTF("usb: check: create new device\n"); + dev = dlo_new_device(type, string); + NERR_GOTO(dev); + + /* It's not. Create and initialise a new list node for the device */ + dev->cnct = (dlo_usb_dev_t *)dlo_malloc(sizeof(dlo_usb_dev_t)); + NERR_GOTO(dev->cnct); + dev->cnct->udev = udev; + dev->cnct->uhand = NULL; + } + //DPRINTF("usb: check: dlpp node &%X\n", (int)dev); + + /* Close our temporary handle for the device. If this errors, we'll have a duff entry in + * the device list but at least the list integrity will be OK. + */ + UERR_GOTO(usb_close(uhand)); + + return dlo_ok; + +error: + /* Free our dev->cnct USB information structure */ + if (dev) + { + if (dev->cnct) + dlo_free(dev->cnct); + dev->cnct = NULL; + } + + /* Close our temporary handle for the device */ + (void) usb_close(uhand); + + /* If the executable wasn't run as root, this is where it normally falls over. + * So we'll special case that particular error to help indicate this problem. + */ + if (not_root) + return dlo_err_not_root; + + return err; +} + + +dlo_retcode_t dlo_usb_open(dlo_device_t * const dev) +{ + dlo_retcode_t err; + usb_dev_handle *uhand; + char* driver_name; + int usb_configuration; + int i; + int32_t db = usb_find_busses(); + int32_t dd = usb_find_devices(); + + /* Do we trust the USB device pointer? Not if the structures may have changed under us... */ + if (db || dd) + return dlo_err_reenum; + + /* Open the device */ + uhand = usb_open(dev->cnct->udev); + DPRINTF("usb: open: uhand &%X\n", (int)uhand); + + if (!uhand) + return dlo_err_open; + + /* Store the USB device handle in our dev->cnct word */ + dev->cnct->uhand = uhand; + + /* Establish the connection with the device */ + //DPRINTF("usb: open: setting config...\n"); + + /* + * Because some displaylink devices may report + * a class code (like HID or MSC) that gets + * matched by a kernel driver, we must detach + * those drivers before libusb can successfully + * set configuration or talk to those devices. + * For now, we kick everyone off our device, + * but that includes cases we're intentionally + * a composite device with HID interfaces that + * control something (e.g. a button on a dock). + * And the code below is blindly unloading + * the kernel HID drivers for those. May want + * to get more sophisticated in the future. + */ + driver_name = dlo_malloc(128); + for (i=0; i < dev->cnct->udev->config->bNumInterfaces; i++) + { + memset(driver_name, 0, 128); + if (usb_get_driver_np(uhand, i, driver_name, 128) == 0) + { + DPRINTF("usb: driver (%s) already attached to device\n", driver_name); + + // Reports are that this call can return error even if successful + usb_detach_kernel_driver_np(uhand,i); + } + } + + UERR(usb_set_configuration(uhand, 1)); + + //DPRINTF("usb: open: claiming iface...\n"); + UERR(usb_claim_interface(uhand, 0)); + + /* Mark the device as claimed */ + dev->claimed = true; + + /* Allocate a buffer to hold commands before they are sent to the device */ + if (!dev->buffer) + { + //DPRINTF("usb: open: alloc buffer...\n"); + dev->buffer = dlo_malloc(BUF_SIZE); + NERR(dev->buffer); + dev->bufptr = dev->buffer; + dev->bufend = dev->buffer + BUF_SIZE; + } + //DPRINTF("usb: open: buffer &%X, &%X, &%X\n", (int)dev->buffer, (int)dev->bufptr, (int)dev->bufend); + + /* Use the default timeout if none was specified */ + if (!dev->timeout) + dev->timeout = WRITE_TIMEOUT; + //DPRINTF("usb: open: timeout %u ms\n", dev->timeout); + + /* Initialise the supported modes array for this device to include all our pre-defined modes */ + use_default_modes(dev); + + /* Attempt to read the EDID information, to refine the supported modes array contents */ + err = read_edid(dev, uhand); +#ifdef DEBUG + if (err != dlo_ok) + DPRINTF("usb: open: edid error %u '%s'\n", (int)err, dlo_strerror(err)); +#endif + + return dlo_ok; +} + + +dlo_retcode_t dlo_usb_close(dlo_device_t * const dev) +{ + if (dev->claimed) + { + if (dev->buffer) + { + dlo_free(dev->buffer); + dev->buffer = NULL; + dev->bufptr = NULL; + dev->bufend = NULL; + } + dev->claimed = false; + UERR(usb_release_interface(dev->cnct->uhand, 0)); + UERR(usb_close(dev->cnct->uhand)); + } + return dlo_ok; +} + + +dlo_retcode_t dlo_usb_chan_sel(const dlo_device_t * const dev, const char * const buf, const size_t size) +{ + if (size) + UERR(usb_control_msg(/* handle */ dev->cnct->uhand, + /* requestType */ USB_TYPE_VENDOR, + /* request */ NR_USB_REQUEST_CHANNEL, + /* value */ 0, + /* index */ 0, + /* bytes */ (char *)buf, + /* size */ size, + /* timeout */ CHANSEL_TIMEOUT)); + return dlo_ok; +} + + +dlo_retcode_t dlo_usb_std_chan(const dlo_device_t * const dev) +{ + dlo_retcode_t err; + + ASSERT(strlen(STD_CHANNEL) == 16); + err = dlo_usb_chan_sel(dev, STD_CHANNEL, DSIZEOF(STD_CHANNEL)); + + return err; +} + + +dlo_retcode_t dlo_usb_write(dlo_device_t * const dev) +{ + dlo_retcode_t err = dlo_usb_write_buf(dev, dev->buffer, dev->bufptr - dev->buffer); + + dev->bufptr = dev->buffer; + + return err; +} + + +dlo_retcode_t dlo_usb_write_buf(dlo_device_t * const dev, char * buf, size_t size) +{ +#ifdef DEBUG_DUMP + static char outfile[64]; + static uint32_t outnum = 0; + FILE *out = NULL; +#endif + + if (!dev->claimed) + return dlo_err_unclaimed; + + if (!size) + return dlo_ok; + +#ifdef WRITE_BUF_BODGE + /* If the buffer to write is fewer than 513 bytes in size, copy into 513 byte buffer and pad with zeros */ + if (size < WRITE_BUF_BODGE) + { + dlo_retcode_t err; + uint32_t rem = WRITE_BUF_BODGE - size; + char *cpy = dlo_malloc(WRITE_BUF_BODGE); + + NERR(cpy); + dlo_memcpy(cpy, buf, size); + dlo_memset(cpy + size, 0, rem); + err = dlo_usb_write_buf(dev, cpy, size + rem); + dlo_free(cpy); + + return err; + } +#endif + + while (size) + { + size_t num = size > BUF_SIZE ? BUF_SIZE : size; + +#ifdef DEBUG_DUMP + (void) snprintf(outfile, sizeof(outfile), "dump/%02X/bulk%03X.dat", outnum & 0xFF, outnum >> 8); + outnum++; + out = fopen(outfile, "wb"); + if (out) + { + (void) fwrite(buf, num, 1, out); + (void) fclose(out); + out = NULL; + } +#endif + + UERR(usb_bulk_write(/* handle */ dev->cnct->uhand, + /* endpoint */ 1, + /* bytes */ buf, + /* size */ num, + /* timeout */ dev->timeout)); + buf += num; + size -= num; + } + return dlo_ok; +} + + +/* File-scope function definitions -----------------------------------------------------*/ + + +static dlo_retcode_t usb_error_grab(void) +{ + char *str = usb_strerror(); + + /* If we have a previous USB error message stored, free it */ + if (usb_err_str) + dlo_free(usb_err_str); + + if (str) + { + /* Allocate memory for the new error message and store that */ + usb_err_str = dlo_malloc(1 + strlen(str)); + if (usb_err_str) + strcpy(usb_err_str, str); + } + + /* Always return the generic USB error code */ + return dlo_err_usb; +} + + + +static dlo_retcode_t read_edid(dlo_device_t * const dev, usb_dev_handle *uhand) +{ + dlo_retcode_t err; + uint32_t i; + uint8_t buf[2]; + uint8_t *edid; + + /* Allocate a buffer to hold the EDID structure */ + edid = dlo_malloc(EDID_STRUCT_SZ); + NERR(edid); + + /* Attempt to read the EDID structure from the device */ + for (i = 0; i < EDID_STRUCT_SZ; i++) + { + UERR_GOTO(usb_control_msg(/* handle */ uhand, + /* requestType */ USB_ENDPOINT_IN | USB_TYPE_VENDOR, + /* request */ NR_USB_REQUEST_I2C_SUB_IO, + /* value */ i << 8, + /* index */ 0xA1, + /* bytes */ (char *)buf, + /* size */ sizeof(buf), + /* timeout */ dev->timeout)); + if (buf[0]) + ERR_GOTO(dlo_err_iic_op); + //DPRINTF("usb: edid[%u]=&%02X\n", i, buf[1]); + edid[i] = buf[1]; + } + + /* Supply the prospective EDID structure to the parser */ + ERR_GOTO(dlo_mode_parse_edid(dev, edid, EDID_STRUCT_SZ)); + +error: + dlo_free(edid); + + return err; +} + + +/* End of file -------------------------------------------------------------------------*/ diff --git a/src/dlo_usb.h b/src/dlo_usb.h index 744375d..84f1532 100644 --- a/src/dlo_usb.h +++ b/src/dlo_usb.h @@ -1,134 +1,134 @@ -/** @file dlo_usb.h
- *
- * @brief Header file for the USB-specific connectivity functions.
- *
- * This file defines the API between the libdlo.c and the USB driver implementation. This
- * example implementation uses libusb but it should be simple to replace dlo_usb.c with
- * some alternative implementation.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef DLO_USB_H
-#define DLO_USB_H /**< Avoid multiple inclusion. */
-
-#include "usb.h"
-#include "dlo_structs.h"
-
-
-/** Return the meaning of the last USB-related error as a human-readable string.
- *
- * @return Pointer to error message string (zero-terminated).
- */
-extern char * dlo_usb_strerror(void);
-
-
-/** Initialise the USB communications routines.
- *
- * @param flags Initialisation flags word (unused flags ignored).
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_usb_init(const dlo_init_t flags);
-
-
-/** Finalisation call for USB communications routines.
- *
- * @param flags Finalisation flags word (unused flags ignored).
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_usb_final(const dlo_final_t flags);
-
-
-/** Update or create nodes on the device list for any DisplayLink devices found.
- *
- * @param init Is this the first call to the enumeration function?
- *
- * @return Return code, zero for no error.
- *
- * This call will look for any DisplayLink devices which use the particular connection
- * implementation and either add nodes onto the device list or update nodes if they are
- * already present.
- *
- * Once enumeration is complete for all connection types, any nodes on the list which
- * haven't just been added or updated are removed (as the correponding device can no
- * longer be found).
- */
-extern dlo_retcode_t dlo_usb_enumerate(const bool init);
-
-
-/** Open a connection to the specified device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_usb_open(dlo_device_t * const dev);
-
-
-/** Close the connection with a specified device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_usb_close(dlo_device_t * const dev);
-
-
-/** Select the input channel in the specified device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param buf Pointer to the buffer containing the channel information.
- * @param size Size of the buffer (bytes).
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_usb_chan_sel(const dlo_device_t * const dev, const char * const buf, const size_t size);
-
-
-/** Switch to the default input channel in the specified device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_usb_std_chan(const dlo_device_t * const dev);
-
-
-/** Flush the command buffer contents to the specified device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_usb_write(dlo_device_t * const dev);
-
-
-/** Write the contents of a specified command buffer to the specified device.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param buf Pointer to the buffer containing commands to write.
- * @param size Size of the buffer (bytes).
- *
- * @return Return code, zero for no error.
- */
-extern dlo_retcode_t dlo_usb_write_buf(dlo_device_t * const dev, char * buf, size_t size);
-
-
-#endif
+/** @file dlo_usb.h + * + * @brief Header file for the USB-specific connectivity functions. + * + * This file defines the API between the libdlo.c and the USB driver implementation. This + * example implementation uses libusb but it should be simple to replace dlo_usb.c with + * some alternative implementation. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef DLO_USB_H +#define DLO_USB_H /**< Avoid multiple inclusion. */ + +#include "usb.h" +#include "dlo_structs.h" + + +/** Return the meaning of the last USB-related error as a human-readable string. + * + * @return Pointer to error message string (zero-terminated). + */ +extern char * dlo_usb_strerror(void); + + +/** Initialise the USB communications routines. + * + * @param flags Initialisation flags word (unused flags ignored). + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_usb_init(const dlo_init_t flags); + + +/** Finalisation call for USB communications routines. + * + * @param flags Finalisation flags word (unused flags ignored). + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_usb_final(const dlo_final_t flags); + + +/** Update or create nodes on the device list for any DisplayLink devices found. + * + * @param init Is this the first call to the enumeration function? + * + * @return Return code, zero for no error. + * + * This call will look for any DisplayLink devices which use the particular connection + * implementation and either add nodes onto the device list or update nodes if they are + * already present. + * + * Once enumeration is complete for all connection types, any nodes on the list which + * haven't just been added or updated are removed (as the correponding device can no + * longer be found). + */ +extern dlo_retcode_t dlo_usb_enumerate(const bool init); + + +/** Open a connection to the specified device. + * + * @param dev Pointer to @a dlo_device_t structure. + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_usb_open(dlo_device_t * const dev); + + +/** Close the connection with a specified device. + * + * @param dev Pointer to @a dlo_device_t structure. + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_usb_close(dlo_device_t * const dev); + + +/** Select the input channel in the specified device. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param buf Pointer to the buffer containing the channel information. + * @param size Size of the buffer (bytes). + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_usb_chan_sel(const dlo_device_t * const dev, const char * const buf, const size_t size); + + +/** Switch to the default input channel in the specified device. + * + * @param dev Pointer to @a dlo_device_t structure. + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_usb_std_chan(const dlo_device_t * const dev); + + +/** Flush the command buffer contents to the specified device. + * + * @param dev Pointer to @a dlo_device_t structure. + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_usb_write(dlo_device_t * const dev); + + +/** Write the contents of a specified command buffer to the specified device. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param buf Pointer to the buffer containing commands to write. + * @param size Size of the buffer (bytes). + * + * @return Return code, zero for no error. + */ +extern dlo_retcode_t dlo_usb_write_buf(dlo_device_t * const dev, char * buf, size_t size); + + +#endif diff --git a/src/exported_symbols b/src/exported_symbols index d790885..6fe1217 100644 --- a/src/exported_symbols +++ b/src/exported_symbols @@ -1,14 +1,14 @@ -dlo_strerror
-dlo_init
-dlo_final
-dlo_lookup_device
-dlo_enumerate_devices
-dlo_claim_device
-dlo_claim_first_device
-dlo_release_device
-dlo_device_info
-dlo_set_mode
-dlo_get_mode
-dlo_fill_rect
-dlo_copy_rect
-dlo_copy_host_bmp
+dlo_strerror +dlo_init +dlo_final +dlo_lookup_device +dlo_enumerate_devices +dlo_claim_device +dlo_claim_first_device +dlo_release_device +dlo_device_info +dlo_set_mode +dlo_get_mode +dlo_fill_rect +dlo_copy_rect +dlo_copy_host_bmp diff --git a/src/libdlo.c b/src/libdlo.c index eef7719..19f7b1e 100644 --- a/src/libdlo.c +++ b/src/libdlo.c @@ -1,469 +1,469 @@ -/** @file libdlo.c
- *
- * @brief This file implements the high-level API for the DisplayLink libdlo library.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <string.h>
-#include "dlo_defs.h"
-#include "dlo_grfx.h"
-#include "dlo_mode.h"
-#include "dlo_usb.h"
-
-
-/* File-scope defines ------------------------------------------------------------------*/
-
-
-/** Structure to hold information about how a rectangle may have been clipped
- */
-typedef struct clip_s
-{
- uint32_t left; /**< Number of pixels clipped from left edge. */
- uint32_t right; /**< Number of pixels clipped from right edge. */
- uint32_t below; /**< Number of pixels clipped from bottom edge. */
- uint32_t above; /**< Number of pixels clipped from top edge. */
-} clip_t; /**< A struct @a clip_s. */
-
-
-/** Return value from function to check source and destination viewports in the rectangle copy function.
- */
-typedef enum
-{
- vstat_good_view = 0, /**< Viewports are both good, not overlapping. */
- vstat_good_overlap, /**< Viewports are both the same. */
- vstat_bad_view, /**< Something is wrong with one or other viewport. */
- vstat_bad_overlap /**< Viewports overlap but are not identical. */
-} vstat_t;
-
-
-/* File-scope inline functions ---------------------------------------------------------*/
-
-
-/* File-scope types --------------------------------------------------------------------*/
-
-
-/* External-scope variables ------------------------------------------------------------*/
-
-
-char err_file[1024] = { '\0' };
-
-
-uint32_t err_line = 0;
-
-
-/* File-scope variables ----------------------------------------------------------------*/
-
-
-/** Pointer to the head node in the device list.
- */
-static dlo_device_t *dev_list = NULL;
-
-
-/** Flag is toggled at each enumeration to spot removed devices.
- */
-static bool check_state = false;
-
-
-/* File-scope function declarations ----------------------------------------------------*/
-
-
-/** Check that the specified device (pointer) corresponds to a current list node.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- *
- * @return true if the device is in the device list, else false.
- *
- * This is a less-than-perfect test because although the device structure may have
- * been removed from the list, a new device structure may have been allocated into
- * the same address at some later point.
- *
- * Ideally, this library should hold structures which themselves point to a device
- * structure and include a flag saying whether the pointer is still valid (which is
- * cleared when the device structure is freed). The UID passed into dlo calls would
- * be a pointer to this (small) structure. The (small) structures are leaked so that
- * it is possible to spot stale pointers from the caller.
- */
-static bool valid_device(const dlo_device_t * const dev);
-
-
-/** Remove the specified device from the device list.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- *
- * @return Return code, zero for no error.
- *
- * This call will delink the specified device structure from the device list
- * and free any resources associated with the device (including "releasing"
- * the device).
- *
- * NOTE: the @a dev_list variable is updated as a side-effect of this function.
- */
-static dlo_retcode_t remove_device(dlo_device_t *dev);
-
-
-/** Initialise an area structure based upon a viewport and rectangle within it.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param view Pointer to the viewport structure (may be NULL).
- * @param rec Pointer to a rectangle structure (may be NULL).
- * @param area Pointer to area structure to initialise from @a view and @a rec.
- * @param clip Pointer to list of offsets that the source rectangle was clipped by.
- *
- * @return true if the area still has extent, false if it was clipped to nothing.
- *
- * Given a viewport and rectangle within that viewport, calculate the corresponding area
- * structure by clipping the rectangle as required so that no part of it lies outside of
- * the viewport.
- *
- * Where the viewport is NULL on entry, the viewport for the current display screen is
- * used. Where the rectangle is NULL on entry, the whole of the viewport is used.
- *
- * This call also updates the contents of the @a clip structure as a side-effect to
- * indicate how many pixels were clipped from each edge of the rectangle in order to
- * arrive at the output area. This is useful if another rectangle needs to be clipped
- * to match the output rectangle.
- */
-static bool sanitise_view_rect(const dlo_device_t * const dev, const dlo_view_t * const view, const dlo_rect_t * const rec, dlo_area_t * const area, clip_t * const clip);
-
-
-/** For the rectangle copy, check that overlapping rectangles have exactly the same viewport.
- *
- * @param dev Pointer to @a dlo_device_t structure.
- * @param src_view Pointer to source viewport structure.
- * @param dest_view Pointer to destination viewport structure.
- *
- * @return true if they don't overlap, or do overlap and are identical. Else returns false.
- */
-static vstat_t check_overlaps(const dlo_device_t * const dev, const dlo_view_t * const src_view, const dlo_view_t * const dest_view);
-
-
-/* Public function definitions ---------------------------------------------------------*/
-
-
-#if 0
-static uint32_t total_alloc = 0;
-
-void *my_malloc(size_t size)
-{
- uint32_t *blk = malloc(size + sizeof(uint32_t));
-
- if (blk)
- {
- *blk = size;
- total_alloc += size;
- blk++;
- }
- DPRINTF("alloc: malloc &%X is %u bytes (total %u)\n", (uint32_t)blk, size, total_alloc);
-
- return (void *)blk;
-}
-
-
-void *my_realloc(void *blk, size_t size)
-{
- uint32_t *myblk = (uint32_t *)blk;
-
- if (myblk)
- {
- myblk--;
- if (size)
- {
- myblk = realloc(myblk, size + sizeof(uint32_t));
- if (myblk)
- {
- total_alloc -= *myblk;
- total_alloc += size;
- *myblk = size;
- myblk++;
- }
- }
- else
- {
- /* Free a block */
- total_alloc -= *myblk;
- myblk = realloc(myblk, 0);
- }
- }
- else
- {
- /* Claim a new block */
- myblk = realloc(NULL, size + sizeof(uint32_t));
- if (myblk)
- {
- *myblk = size;
- total_alloc += size;
- myblk++;
- }
- }
- DPRINTF("alloc: realloc &%X to %u bytes (total %u)\n", (uint32_t)myblk, size, total_alloc);
-
- return (void *)myblk;
-}
-
-
-void my_free(void *blk)
-{
- uint32_t *myblk = (uint32_t *)blk;
-
- myblk--;
- total_alloc -= *myblk;
- free(myblk);
-
- DPRINTF("alloc: free &%X (total %u)\n", (uint32_t)blk, total_alloc);
-}
-
-
-uint32_t my_used(void)
-{
- return total_alloc;
-}
-#endif
-
-
-const char *dlo_strerror(const dlo_retcode_t err)
-{
- static char str[1024];
- char *msg;
-
- switch (err)
- {
- /* Success... */
- case dlo_ok: return "Successful";
- /* Errors... */
- case dlo_err_memory: break;
- case dlo_err_bad_area: return "An invalid area was specified (e.g. of zero width or height)";
- case dlo_err_bad_col: return "Unsupported colour depth";
- case dlo_err_bad_device: return "Unknown device, possibly disconnected or powered down";
- case dlo_err_bad_fbuf: return "Null pointer passed as local bitmap data";
- case dlo_err_bad_fmt: return "Unsupported bitmap pixel format";
- case dlo_err_bad_mode: return "Call to dlo_set_mode() failed due to unsupported mode parameters";
- case dlo_err_bad_view: return "Invalid viewport specified (is screen mode set up?)";
- case dlo_err_big_scrape: return "Bitmap is too wide for copy buffer";
- case dlo_err_buf_full: return "Command buffer is full";
- case dlo_err_claimed: return "Device is already claimed";
- case dlo_err_edid_fail: return "Attempt to access EDID information failed";
- case dlo_err_iic_op: return "IIC operation with device failed";
- case dlo_err_not_root: return "Executable should be run as root (e.g. using 'su root' or 'sudo')";
- case dlo_err_open: return "Attempt to open connection to device failed";
- case dlo_err_overlap: return "Source and destination viewports cannot overlap (unless the same)";
- case dlo_err_reenum: return "Reenumeration required before device can be claimed";
- case dlo_err_unclaimed: return "Device cannot be written to: unclaimed";
- case dlo_err_unsupported: return "Requested feature is not supported";
- case dlo_err_usb: return dlo_usb_strerror();
- /* Warnings... */
- case dlo_warn_dl160_mode: return "This screen mode may not display correctly on DL120 devices";
- default: return "Unknown error";
- }
-
- /* Memory allocation errors should have more information associated with them */
- msg = "A memory claim operation failed; out of memory";
- if (err_file[0])
- snprintf(&str[0], sizeof(str), "%s:%u: %s", &err_file[0], err_line, msg);
- else
- snprintf(&str[0], sizeof(str), "%s", msg);
- err_file[0] = '\0';
- err_line = 0;
- return str;
-}
-
-
-dlo_retcode_t dlo_init(const dlo_init_t flags)
-{
- /* Initialise the graphics primitives */
- DPRINTF("dlo: grfx_init\n");
- ERR(dlo_grfx_init(flags));
-
- /* Initialise the screen mode timings array */
- DPRINTF("dlo: mode_init\n");
- ERR(dlo_mode_init(flags));
-
- /* Initialise the USB comms code and function pointer table */
- DPRINTF("dlo: usb_init\n");
- ERR(dlo_usb_init(flags));
-
- return dlo_ok;
-}
-
-
-dlo_retcode_t dlo_final(const dlo_final_t flags)
-{
- /* Free all claimed structures */
- while (dev_list)
- {
- (void) remove_device(dev_list);
- }
-
- ERR(dlo_grfx_final(flags));
- ERR(dlo_mode_final(flags));
- ERR(dlo_usb_final(flags));
-
- return dlo_ok;
-}
-
-
-dlo_devlist_t *dlo_enumerate_devices(void)
-{
- dlo_devlist_t *out = NULL;
- dlo_device_t *dev;
- dlo_retcode_t err;
- uint32_t num;
-
- check_state = !check_state;
-
- /* Check USB for all DisplayLink devices that we can find. If there is an error returned,
- * then it is likely that the devlist could become out of step with reality. For that
- * reason, after any error, we throw away all unclaimed devices from the devlist to try to
- * minimise the chances.
- */
- //DPRINTF("dlo: enum: enumerating USB devices\n");
- ERR_GOTO(dlo_usb_enumerate(false));
-
- /* Remove all devices which weren't updated or added during this enumeration and
- * build the list of device information to return. Note: if a dlo_malloc() call
- * fails during this operation, we note it and continue otherwise the dev_list could
- * get out of step with reality.
- */
- dev = dev_list;
- out = NULL;
- num = 0;
- while (dev)
- {
- dlo_device_t *next = dev->next;
-
- if (dev->check == check_state)
- {
- dlo_devlist_t *tmp = (dlo_devlist_t *)dlo_malloc(sizeof(dlo_devlist_t));
-
- /* Add a node to the output list */
- if (tmp)
- {
- tmp->next = out;
- tmp->dev.uid = (dlo_dev_t)dev;
- tmp->dev.serial = dev->serial;
- tmp->dev.type = dev->type;
- tmp->dev.claimed = dev->claimed;
- out = tmp;
- num++;
- }
- else
- err = dlo_err_memory;
- }
- else
- {
- // DPRINTF("dlo: enum: removed device &%X (%s)\n", (int)dev, dev->serial);
- (void) remove_device(dev);
- }
- dev = next;
- }
-
- /* Return pointer to output list if operation was successful */
- if (!err)
- {
- // DPRINTF("dlo: enum: return list of %u entries\n", num);
- return out;
- }
-
-error:
- DPRINTF("dlo: enum: error &%X (usberr &%X)\n", err, usberr);
-
- /* Throw the output list away */
- while (out)
- {
- dlo_devlist_t *next = out->next;
-
- dlo_free(out);
- out = next;
- }
-
- /* Remove all unclaimed devices from our list */
- dev = dev_list;
- while (dev)
- {
- dlo_device_t *next = dev->next;
-
- if (!dev->claimed)
- (void) remove_device(dev);
- dev = next;
- }
- return NULL;
-}
-
-
-dlo_dev_t dlo_claim_device(const dlo_dev_t uid, const dlo_claim_t flags, const uint32_t timeout)
-{
- dlo_device_t *dev = (dlo_device_t *)uid;
- dlo_retcode_t err;
-
- if (!dev)
- ERR_GOTO(dlo_err_bad_device);
-
- /* Confirm that the device structure pointer still exists */
- if (!valid_device(dev))
- ERR_GOTO(dlo_err_bad_device);
-
- /* Return error if device has already been claimed */
- if (dev->claimed)
- ERR_GOTO(dlo_err_claimed);
-
- dev->timeout = timeout;
-
- /* Attempt to open a connection to the device */
- err = dlo_usb_open(dev);
- while (err == dlo_err_reenum)
- {
- DPRINTF("dlo_usb_open failed with dlo_err_reenum. Retry\n");
-
- /* If the USB bus devices have changed, do the enumeration again */
- dlo_devlist_t *out = dlo_enumerate_devices();
-
- /* Throw the output list away */
- while (out)
- {
- dlo_devlist_t *next = out->next;
-
- dlo_free(out);
- out = next;
- }
-
- /* Confirm that the device structure pointer still exists */
- if (!valid_device(dev))
- ERR_GOTO(dlo_err_bad_device);
-
- /* Now try opening the connection again */
- err = dlo_usb_open(dev);
- }
- /* Any other errors from opening the connection get returned to the caller */
- ERR_GOTO(err);
-
- /* Select the standard output channel */
- ERR_GOTO(dlo_usb_std_chan(dev));
-
- /* Attempt to change mode into the native resolution of the display (if we have one) */
- if (dev->native.view.width)
- ERR_GOTO(dlo_mode_change(dev, &dev->native, DLO_INVALID_MODE));
-
- return uid;
-
-error:
- DPRINTF("dlo: claim: error %u '%s'\n", (int)err, dlo_strerror(err));
-
- return (dlo_dev_t)0;
+/** @file libdlo.c + * + * @brief This file implements the high-level API for the DisplayLink libdlo library. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <string.h> +#include "dlo_defs.h" +#include "dlo_grfx.h" +#include "dlo_mode.h" +#include "dlo_usb.h" + + +/* File-scope defines ------------------------------------------------------------------*/ + + +/** Structure to hold information about how a rectangle may have been clipped + */ +typedef struct clip_s +{ + uint32_t left; /**< Number of pixels clipped from left edge. */ + uint32_t right; /**< Number of pixels clipped from right edge. */ + uint32_t below; /**< Number of pixels clipped from bottom edge. */ + uint32_t above; /**< Number of pixels clipped from top edge. */ +} clip_t; /**< A struct @a clip_s. */ + + +/** Return value from function to check source and destination viewports in the rectangle copy function. + */ +typedef enum +{ + vstat_good_view = 0, /**< Viewports are both good, not overlapping. */ + vstat_good_overlap, /**< Viewports are both the same. */ + vstat_bad_view, /**< Something is wrong with one or other viewport. */ + vstat_bad_overlap /**< Viewports overlap but are not identical. */ +} vstat_t; + + +/* File-scope inline functions ---------------------------------------------------------*/ + + +/* File-scope types --------------------------------------------------------------------*/ + + +/* External-scope variables ------------------------------------------------------------*/ + + +char err_file[1024] = { '\0' }; + + +uint32_t err_line = 0; + + +/* File-scope variables ----------------------------------------------------------------*/ + + +/** Pointer to the head node in the device list. + */ +static dlo_device_t *dev_list = NULL; + + +/** Flag is toggled at each enumeration to spot removed devices. + */ +static bool check_state = false; + + +/* File-scope function declarations ----------------------------------------------------*/ + + +/** Check that the specified device (pointer) corresponds to a current list node. + * + * @param dev Pointer to @a dlo_device_t structure. + * + * @return true if the device is in the device list, else false. + * + * This is a less-than-perfect test because although the device structure may have + * been removed from the list, a new device structure may have been allocated into + * the same address at some later point. + * + * Ideally, this library should hold structures which themselves point to a device + * structure and include a flag saying whether the pointer is still valid (which is + * cleared when the device structure is freed). The UID passed into dlo calls would + * be a pointer to this (small) structure. The (small) structures are leaked so that + * it is possible to spot stale pointers from the caller. + */ +static bool valid_device(const dlo_device_t * const dev); + + +/** Remove the specified device from the device list. + * + * @param dev Pointer to @a dlo_device_t structure. + * + * @return Return code, zero for no error. + * + * This call will delink the specified device structure from the device list + * and free any resources associated with the device (including "releasing" + * the device). + * + * NOTE: the @a dev_list variable is updated as a side-effect of this function. + */ +static dlo_retcode_t remove_device(dlo_device_t *dev); + + +/** Initialise an area structure based upon a viewport and rectangle within it. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param view Pointer to the viewport structure (may be NULL). + * @param rec Pointer to a rectangle structure (may be NULL). + * @param area Pointer to area structure to initialise from @a view and @a rec. + * @param clip Pointer to list of offsets that the source rectangle was clipped by. + * + * @return true if the area still has extent, false if it was clipped to nothing. + * + * Given a viewport and rectangle within that viewport, calculate the corresponding area + * structure by clipping the rectangle as required so that no part of it lies outside of + * the viewport. + * + * Where the viewport is NULL on entry, the viewport for the current display screen is + * used. Where the rectangle is NULL on entry, the whole of the viewport is used. + * + * This call also updates the contents of the @a clip structure as a side-effect to + * indicate how many pixels were clipped from each edge of the rectangle in order to + * arrive at the output area. This is useful if another rectangle needs to be clipped + * to match the output rectangle. + */ +static bool sanitise_view_rect(const dlo_device_t * const dev, const dlo_view_t * const view, const dlo_rect_t * const rec, dlo_area_t * const area, clip_t * const clip); + + +/** For the rectangle copy, check that overlapping rectangles have exactly the same viewport. + * + * @param dev Pointer to @a dlo_device_t structure. + * @param src_view Pointer to source viewport structure. + * @param dest_view Pointer to destination viewport structure. + * + * @return true if they don't overlap, or do overlap and are identical. Else returns false. + */ +static vstat_t check_overlaps(const dlo_device_t * const dev, const dlo_view_t * const src_view, const dlo_view_t * const dest_view); + + +/* Public function definitions ---------------------------------------------------------*/ + + +#if 0 +static uint32_t total_alloc = 0; + +void *my_malloc(size_t size) +{ + uint32_t *blk = malloc(size + sizeof(uint32_t)); + + if (blk) + { + *blk = size; + total_alloc += size; + blk++; + } + DPRINTF("alloc: malloc &%X is %u bytes (total %u)\n", (uint32_t)blk, size, total_alloc); + + return (void *)blk; +} + + +void *my_realloc(void *blk, size_t size) +{ + uint32_t *myblk = (uint32_t *)blk; + + if (myblk) + { + myblk--; + if (size) + { + myblk = realloc(myblk, size + sizeof(uint32_t)); + if (myblk) + { + total_alloc -= *myblk; + total_alloc += size; + *myblk = size; + myblk++; + } + } + else + { + /* Free a block */ + total_alloc -= *myblk; + myblk = realloc(myblk, 0); + } + } + else + { + /* Claim a new block */ + myblk = realloc(NULL, size + sizeof(uint32_t)); + if (myblk) + { + *myblk = size; + total_alloc += size; + myblk++; + } + } + DPRINTF("alloc: realloc &%X to %u bytes (total %u)\n", (uint32_t)myblk, size, total_alloc); + + return (void *)myblk; +} + + +void my_free(void *blk) +{ + uint32_t *myblk = (uint32_t *)blk; + + myblk--; + total_alloc -= *myblk; + free(myblk); + + DPRINTF("alloc: free &%X (total %u)\n", (uint32_t)blk, total_alloc); +} + + +uint32_t my_used(void) +{ + return total_alloc; +} +#endif + + +const char *dlo_strerror(const dlo_retcode_t err) +{ + static char str[1024]; + char *msg; + + switch (err) + { + /* Success... */ + case dlo_ok: return "Successful"; + /* Errors... */ + case dlo_err_memory: break; + case dlo_err_bad_area: return "An invalid area was specified (e.g. of zero width or height)"; + case dlo_err_bad_col: return "Unsupported colour depth"; + case dlo_err_bad_device: return "Unknown device, possibly disconnected or powered down"; + case dlo_err_bad_fbuf: return "Null pointer passed as local bitmap data"; + case dlo_err_bad_fmt: return "Unsupported bitmap pixel format"; + case dlo_err_bad_mode: return "Call to dlo_set_mode() failed due to unsupported mode parameters"; + case dlo_err_bad_view: return "Invalid viewport specified (is screen mode set up?)"; + case dlo_err_big_scrape: return "Bitmap is too wide for copy buffer"; + case dlo_err_buf_full: return "Command buffer is full"; + case dlo_err_claimed: return "Device is already claimed"; + case dlo_err_edid_fail: return "Attempt to access EDID information failed"; + case dlo_err_iic_op: return "IIC operation with device failed"; + case dlo_err_not_root: return "Executable should be run as root (e.g. using 'su root' or 'sudo')"; + case dlo_err_open: return "Attempt to open connection to device failed"; + case dlo_err_overlap: return "Source and destination viewports cannot overlap (unless the same)"; + case dlo_err_reenum: return "Reenumeration required before device can be claimed"; + case dlo_err_unclaimed: return "Device cannot be written to: unclaimed"; + case dlo_err_unsupported: return "Requested feature is not supported"; + case dlo_err_usb: return dlo_usb_strerror(); + /* Warnings... */ + case dlo_warn_dl160_mode: return "This screen mode may not display correctly on DL120 devices"; + default: return "Unknown error"; + } + + /* Memory allocation errors should have more information associated with them */ + msg = "A memory claim operation failed; out of memory"; + if (err_file[0]) + snprintf(&str[0], sizeof(str), "%s:%u: %s", &err_file[0], err_line, msg); + else + snprintf(&str[0], sizeof(str), "%s", msg); + err_file[0] = '\0'; + err_line = 0; + return str; +} + + +dlo_retcode_t dlo_init(const dlo_init_t flags) +{ + /* Initialise the graphics primitives */ + DPRINTF("dlo: grfx_init\n"); + ERR(dlo_grfx_init(flags)); + + /* Initialise the screen mode timings array */ + DPRINTF("dlo: mode_init\n"); + ERR(dlo_mode_init(flags)); + + /* Initialise the USB comms code and function pointer table */ + DPRINTF("dlo: usb_init\n"); + ERR(dlo_usb_init(flags)); + + return dlo_ok; +} + + +dlo_retcode_t dlo_final(const dlo_final_t flags) +{ + /* Free all claimed structures */ + while (dev_list) + { + (void) remove_device(dev_list); + } + + ERR(dlo_grfx_final(flags)); + ERR(dlo_mode_final(flags)); + ERR(dlo_usb_final(flags)); + + return dlo_ok; +} + + +dlo_devlist_t *dlo_enumerate_devices(void) +{ + dlo_devlist_t *out = NULL; + dlo_device_t *dev; + dlo_retcode_t err; + uint32_t num; + + check_state = !check_state; + + /* Check USB for all DisplayLink devices that we can find. If there is an error returned, + * then it is likely that the devlist could become out of step with reality. For that + * reason, after any error, we throw away all unclaimed devices from the devlist to try to + * minimise the chances. + */ + //DPRINTF("dlo: enum: enumerating USB devices\n"); + ERR_GOTO(dlo_usb_enumerate(false)); + + /* Remove all devices which weren't updated or added during this enumeration and + * build the list of device information to return. Note: if a dlo_malloc() call + * fails during this operation, we note it and continue otherwise the dev_list could + * get out of step with reality. + */ + dev = dev_list; + out = NULL; + num = 0; + while (dev) + { + dlo_device_t *next = dev->next; + + if (dev->check == check_state) + { + dlo_devlist_t *tmp = (dlo_devlist_t *)dlo_malloc(sizeof(dlo_devlist_t)); + + /* Add a node to the output list */ + if (tmp) + { + tmp->next = out; + tmp->dev.uid = (dlo_dev_t)dev; + tmp->dev.serial = dev->serial; + tmp->dev.type = dev->type; + tmp->dev.claimed = dev->claimed; + out = tmp; + num++; + } + else + err = dlo_err_memory; + } + else + { + // DPRINTF("dlo: enum: removed device &%X (%s)\n", (int)dev, dev->serial); + (void) remove_device(dev); + } + dev = next; + } + + /* Return pointer to output list if operation was successful */ + if (!err) + { + // DPRINTF("dlo: enum: return list of %u entries\n", num); + return out; + } + +error: + DPRINTF("dlo: enum: error &%X (usberr &%X)\n", err, usberr); + + /* Throw the output list away */ + while (out) + { + dlo_devlist_t *next = out->next; + + dlo_free(out); + out = next; + } + + /* Remove all unclaimed devices from our list */ + dev = dev_list; + while (dev) + { + dlo_device_t *next = dev->next; + + if (!dev->claimed) + (void) remove_device(dev); + dev = next; + } + return NULL; +} + + +dlo_dev_t dlo_claim_device(const dlo_dev_t uid, const dlo_claim_t flags, const uint32_t timeout) +{ + dlo_device_t *dev = (dlo_device_t *)uid; + dlo_retcode_t err; + + if (!dev) + ERR_GOTO(dlo_err_bad_device); + + /* Confirm that the device structure pointer still exists */ + if (!valid_device(dev)) + ERR_GOTO(dlo_err_bad_device); + + /* Return error if device has already been claimed */ + if (dev->claimed) + ERR_GOTO(dlo_err_claimed); + + dev->timeout = timeout; + + /* Attempt to open a connection to the device */ + err = dlo_usb_open(dev); + while (err == dlo_err_reenum) + { + DPRINTF("dlo_usb_open failed with dlo_err_reenum. Retry\n"); + + /* If the USB bus devices have changed, do the enumeration again */ + dlo_devlist_t *out = dlo_enumerate_devices(); + + /* Throw the output list away */ + while (out) + { + dlo_devlist_t *next = out->next; + + dlo_free(out); + out = next; + } + + /* Confirm that the device structure pointer still exists */ + if (!valid_device(dev)) + ERR_GOTO(dlo_err_bad_device); + + /* Now try opening the connection again */ + err = dlo_usb_open(dev); + } + /* Any other errors from opening the connection get returned to the caller */ + ERR_GOTO(err); + + /* Select the standard output channel */ + ERR_GOTO(dlo_usb_std_chan(dev)); + + /* Attempt to change mode into the native resolution of the display (if we have one) */ + if (dev->native.view.width) + ERR_GOTO(dlo_mode_change(dev, &dev->native, DLO_INVALID_MODE)); + + return uid; + +error: + DPRINTF("dlo: claim: error %u '%s'\n", (int)err, dlo_strerror(err)); + + return (dlo_dev_t)0; } @@ -512,12 +512,12 @@ dlo_dev_t dlo_claim_default_device(int *argc_p, char *argv[], dlo_devlist_t *node; dlo_devlist_t *next; dlo_dev_t uid = 0; -
- /* Look for a DisplayLink device to connect to - note the first one which is unclaimed */
- node = dlo_enumerate_devices();
-
- // dlo_enumerate_devices allocates memory for each node, which we must free
- while (node)
+ + /* Look for a DisplayLink device to connect to - note the first one which is unclaimed */ + node = dlo_enumerate_devices(); + + // dlo_enumerate_devices allocates memory for each node, which we must free + while (node) { dlo_device_t *dev = (dlo_device_t *)node->dev.uid; @@ -526,424 +526,424 @@ dlo_dev_t dlo_claim_default_device(int *argc_p, char *argv[], { uid = dlo_claim_device(node->dev.uid, flags, timeout); } -
- /* If we haven't claimed a device, move on to the next one */
- next = node->next;
- dlo_free(node);
- node = next;
- }
- return uid;
-}
-
-
-dlo_retcode_t dlo_release_device(const dlo_dev_t uid)
-{
- dlo_device_t *dev = (dlo_device_t *)uid;
-
- return dev ? dlo_usb_close(dev) : dlo_err_bad_device;
-}
-
-
-dlo_devinfo_t *dlo_device_info(const dlo_dev_t uid)
-{
- static dlo_devinfo_t info;
- dlo_device_t *dev = (dlo_device_t *)uid;
-
- if (!dev)
- return NULL;
-
- info.uid = uid;
- info.serial = dev->serial;
- info.type = dev->type;
- info.claimed = dev->claimed;
-
- return &info;
-}
-
-
-dlo_retcode_t dlo_set_mode(const dlo_dev_t uid, const dlo_mode_t * const desc)
-{
- dlo_device_t *dev = (dlo_device_t *)uid;
- dlo_modenum_t num;
-
- if (!dev)
- return dlo_err_bad_device;
-
- /* See if we can provide a mode which matches the required parameters */
- num = dlo_mode_lookup(dev, desc->view.width, desc->view.height, desc->refresh, desc->view.bpp);
- DPRINTF("dlo: set_mode: lookup %d\n", (int32_t)num);
-
- return num == DLO_INVALID_MODE ? dlo_err_bad_mode : dlo_mode_change(dev, desc, num);
-}
-
-
-dlo_mode_t *dlo_get_mode(const dlo_dev_t uid)
-{
- dlo_device_t *dev = (dlo_device_t *)uid;
-
- return dev ? &(dev->mode) : NULL;
-}
-
-
-dlo_retcode_t dlo_fill_rect(const dlo_dev_t uid, const dlo_view_t * const view, const dlo_rect_t * const rec, const dlo_col32_t col)
-{
- static clip_t clip;
- static dlo_area_t area;
- dlo_device_t * const dev = (dlo_device_t *)uid;
-
- if (!dev)
- return dlo_err_bad_device;
-
- /* Clip the rectangle to its viewport edges */
- if (!sanitise_view_rect(dev, view, rec, &area, &clip))
- return dlo_ok;
-
- return dlo_grfx_fill_rect(dev, &area, col);
-}
-
-
-dlo_retcode_t dlo_copy_rect(const dlo_dev_t uid,
- const dlo_view_t * const src_view, const dlo_rect_t * const src_rec,
- const dlo_view_t * const dest_view, const dlo_dot_t * const dest_pos)
-{
- static clip_t clip;
- static dlo_area_t src_area;
- static dlo_area_t dest_area;
- static dlo_rect_t dest_rec;
- dlo_device_t * const dev = (dlo_device_t *)uid;
- bool overlap = false;
-
- if (!dev)
- return dlo_err_bad_device;
-
- /* Check to see if (and how) the source and destination viewports overlap */
- switch (check_overlaps(dev, src_view, dest_view))
- {
- case vstat_good_view:
- break;
- case vstat_bad_view:
- return dlo_err_bad_view;
- case vstat_bad_overlap:
- return dlo_err_overlap;
- default:
- {
- DPRINTF("dlo: copy_rec: src_view == dest_view... overlap? ");
- overlap = (dest_pos->x + src_rec->width > src_rec->origin.x) &&
- (dest_pos->y + src_rec->height > src_rec->origin.y) &&
- (dest_pos->x < src_rec->origin.x + src_rec->width) &&
- (dest_pos->y < src_rec->origin.y + src_rec->height);
- DPRINTF("%s\n", overlap ? "yes" : "no");
- }
- }
-
- /* Clip the source rectangle to its viewport edges */
- if (!sanitise_view_rect(dev, src_view, src_rec, &src_area, &clip))
- return dlo_ok;
-
- /* Clip the destination rectangle by the same amounts as we needed to clip the source */
- dest_rec.origin.x = dest_pos ? dest_pos->x + clip.left : clip.left;
- dest_rec.origin.y = dest_pos ? dest_pos->y + clip.below : clip.below;
- dest_rec.width = src_area.view.width;
- dest_rec.height = src_area.view.height;
-
- /* Further clip the destination rectangle to its viewport edges */
- if (!sanitise_view_rect(dev, dest_view, &dest_rec, &dest_area, &clip))
- return dlo_ok;
-
- /* Further clip the source area by the same amounts as we needed to clip the destination */
- src_area.view.base += (BYTES_PER_16BPP * clip.left) + (BYTES_PER_16BPP * clip.below * src_area.stride);
- src_area.base8 += (BYTES_PER_8BPP * clip.left) + (BYTES_PER_8BPP * clip.below * src_area.stride);
- src_area.view.width = dest_area.view.width;
- src_area.view.height = dest_area.view.height;
-
- return dlo_grfx_copy_rect(dev, &src_area, &dest_area, overlap);
-}
-
-
-dlo_retcode_t dlo_copy_host_bmp(const dlo_dev_t uid, const dlo_bmpflags_t flags,
- const dlo_fbuf_t * const fbuf,
- const dlo_view_t * const dest_view, const dlo_dot_t * const dest_pos)
-{
- static clip_t clip;
- static dlo_area_t dest_area;
- static dlo_rect_t dest_rec;
- static dlo_fbuf_t src_fbuf;
- dlo_device_t * const dev = (dlo_device_t *)uid;
- uint32_t off;
-
- /* Do some sanity checks */
- if (!dev)
- return dlo_err_bad_device;
-
- if (!fbuf)
- return dlo_err_bad_fbuf;
-
- if (!fbuf->width || !fbuf->height)
- return dlo_ok;
-
- /* Clip the destination rectangle to its viewport edges */
- src_fbuf = *fbuf;
- dest_rec.origin.x = dest_pos ? dest_pos->x : 0;
- dest_rec.origin.y = dest_pos ? dest_pos->y : 0;
- dest_rec.width = src_fbuf.width;
- dest_rec.height = src_fbuf.height;
- if (!sanitise_view_rect(dev, dest_view, &dest_rec, &dest_area, &clip))
- return dlo_ok;
-
- /* Update the source framebuffer information if the destination was clipped */
- off = clip.left + (clip.below * src_fbuf.stride);
- off *= FORMAT_TO_BYTES_PER_PIXEL(src_fbuf.fmt);
- src_fbuf.base = (void *)((unsigned long)src_fbuf.base + (unsigned long)off);
- src_fbuf.width -= clip.left + clip.right;
- src_fbuf.height -= clip.below + clip.above;
-
- return dlo_grfx_copy_host_bmp(dev, flags, &src_fbuf, &dest_area);
-}
-
-
-dlo_device_t *dlo_new_device(const dlo_devtype_t type, const char * const serial)
-{
- dlo_device_t *dev = (dlo_device_t *)dlo_malloc(sizeof(dlo_device_t));
- char *str = NULL;
- dlo_retcode_t err;
-
- NERR_GOTO(dev);
-
- /* Copy the serial number string and keep a pointer to it */
- str = dlo_malloc(1 + strlen(serial));
- NERR_GOTO(str);
- dev->serial = str;
- strcpy(dev->serial, serial);
-
- /* Link into the device list structure */
- dev->prev = NULL;
- dev->next = dev_list;
- dev_list = dev;
- dev->claimed = false;
-
- /* Defaults are for an "Alex" device via USB */
- dev->type = type;
- dev->check = check_state;
- dev->timeout = 0;
-
- /* Mode-dependent attributes and function pointers */
- dev->mode.view.width = 0;
- dev->mode.view.height = 0;
- dev->mode.view.bpp = 0;
- dev->mode.refresh = 0;
- dev->mode.view.base = 0;
- dev->base8 = 0;
- dev->low_blank = false;
-
- /* Device-dependent attributes */
- dev->buffer = NULL;
-
- /* Connection-dependent attributes.
- *
- * It is up to the communications code (re)initialise this values to something which
- * makes sense to it.
- */
- dev->cnct = NULL;
-
- /* Set up some feature flags based upon what we know about DisplayLink device types.
- *
- * NOTE: this section will probably become more refined as more features are added
- * to libdlo. Currently, it assumes all devices are the same.
- */
- dev->memory = 16 * 1024 * 1024;
-
- DPRINTF("dlo: new_device: initialised &%X\n", (int)dev);
-
- return dev;
-
-error:
- if (str)
- dlo_free(str);
- if (dev)
- dlo_free(dev);
-
- return NULL;
-}
-
-
-dlo_device_t *dlo_device_lookup(const char * const serial)
-{
- dlo_device_t *dev = dev_list;
-
- //DPRINTF("dlo: lookup: '%s' dev_list &%X\n", serial, (int)dev_list);
-
- while (dev)
- {
- //DPRINTF("dlo: lookup: dev &%X serial '%s'\n", (int)dev, dev->serial);
- if (0 == strcmp(dev->serial, serial))
- {
- dev->check = check_state;
- return dev;
- }
- dev = dev->next;
- }
- return NULL;
-}
-
-
-/* File-scope function definitions -----------------------------------------------------*/
-
-
-static bool valid_device(const dlo_device_t * const dev)
-{
- dlo_device_t *node = dev_list;
-
- while (node)
- {
- if (node == dev)
- return true;
- node = node->next;
- }
- return false;
-}
-
-
-static dlo_retcode_t remove_device(dlo_device_t *dev)
-{
- dlo_retcode_t err;
- dlo_device_t *prev = dev->prev;
- dlo_device_t *next = dev->next;
-
- /* Delink the device from the device list */
- if (prev)
- prev->next = next;
- else
- dev_list = next;
- if (next)
- next->prev = prev;
-
- /* Disconnect from the device (if connected) */
- if (dev->claimed)
- err = dlo_usb_close(dev);
- else
- err = dlo_ok;
-
- /* Free the structure (and associated data) even if there was an error */
- if (dev->serial)
- dlo_free(dev->serial);
- dlo_free(dev);
-
- return err;
-}
-
-
-static bool sanitise_view_rect(const dlo_device_t * const dev, const dlo_view_t * const view, const dlo_rect_t * const rec, dlo_area_t * const area, clip_t * const clip)
-{
- static dlo_rect_t my_rec;
- const dlo_view_t * const my_view = view ? view : &(dev->mode.view);
- uint32_t pix_off;
-
- /* Exit here if my_view is still NULL (i.e. no screen mode is set up yet) */
- if (!my_view)
- return false;
-
- /* Default the rectangle to the whole of the the view, if none was specified */
- if (rec)
- my_rec = *rec;
- else
- {
- my_rec.origin.x = 0;
- my_rec.origin.y = 0;
- my_rec.width = my_view->width;
- my_rec.height = my_view->height;
- }
-
- /* Exit here if the source rectangle is never going to appear in the viewport */
- if (my_rec.origin.x + (int32_t)my_rec.width < 0 || my_rec.origin.y + (int32_t)my_rec.height < 0)
- return false;
- if (my_rec.origin.x >= (int32_t)my_view->width || my_rec.origin.y >= (int32_t)my_view->height)
- return false;
-
- /* Initialise the clip structure to empty */
- clip->left = 0;
- clip->right = 0;
- clip->below = 0;
- clip->above = 0;
-
- /* Now clip the rectangle to lie within the viewport */
- if (my_rec.origin.x + (int32_t)my_rec.width > (int32_t)my_view->width)
- {
- clip->right = my_rec.width - (my_view->width - my_rec.origin.x);
- my_rec.width = my_view->width - my_rec.origin.x;
- }
- if (my_rec.origin.y + (int32_t)my_rec.height > (int32_t)my_view->height)
- {
- clip->above = my_rec.height - (my_view->height - my_rec.origin.y);
- my_rec.height = my_view->height - my_rec.origin.y;
- }
- if (my_rec.origin.x < 0)
- {
- clip->left = -my_rec.origin.x;
- my_rec.width += my_rec.origin.x;
- my_rec.origin.x = 0;
- }
- if (my_rec.origin.y < 0)
- {
- clip->below = -my_rec.origin.y;
- my_rec.height += my_rec.origin.y;
- my_rec.origin.y = 0;
- }
-
- /* Exit here if we've clipped the rectangle away to nothing */
- if (!my_rec.width || !my_rec.height)
- return false;
-
- /* Create the clipped area structure */
- pix_off = my_rec.origin.x + (my_rec.origin.y * my_view->width);
- area->view.width = my_rec.width;
- area->view.height = my_rec.height;
- area->view.bpp = my_view->bpp;
- area->view.base = my_view->base + (BYTES_PER_16BPP * pix_off);
- area->base8 = my_view->base + (BYTES_PER_16BPP * my_view->width * my_view->height) + pix_off;
- area->stride = my_view->width;
-
- return true;
-}
-
-
-static vstat_t check_overlaps(const dlo_device_t * const dev, const dlo_view_t * const src_view, const dlo_view_t * const dest_view)
-{
- const dlo_view_t * const src = src_view ? src_view : &(dev->mode.view);
- const dlo_view_t * const dest = dest_view ? dest_view : &(dev->mode.view);
- dlo_ptr_t src_end;
- dlo_ptr_t dest_end;
-
- /* If no display mode is set up, we should stop here to avoid null dereferences */
- if (!src || !dest)
- return vstat_bad_view;
-
- /* If base addresses are the same, the other attributes must also be the same */
- if (src->base == dest->base)
- {
- return (src->width == dest->width &&
- src->height == dest->height &&
- src->bpp == dest->bpp) ? vstat_good_overlap : vstat_bad_overlap;
- }
-
- /* Ensure we're happy with the source bits per pixel */
- if (src->bpp != 16 && src->bpp != 24)
- return vstat_bad_view;
-
- /* Ensure we're happy with the destination bits per pixel */
- if (dest->bpp != 16 && dest->bpp != 24)
- return vstat_bad_view;
-
- /* Compute the end addresses of both views */
- src_end = src->base + (BYTES_PER_16BPP * src->width * src->height);
- dest_end = dest->base + (BYTES_PER_16BPP * dest->width * dest->height);
- if (src->bpp == 24)
- src_end += BYTES_PER_8BPP * src->width * src->height;
- if (dest->bpp == 24)
- dest_end += BYTES_PER_8BPP * dest->width * dest->height;
-
- /* Any overlap in address range means we have a problem */
- return (dest_end <= src->base || dest->base >= src_end) ? vstat_good_view : vstat_bad_overlap;
-}
-
-
-/* End of file -------------------------------------------------------------------------*/
+ + /* If we haven't claimed a device, move on to the next one */ + next = node->next; + dlo_free(node); + node = next; + } + return uid; +} + + +dlo_retcode_t dlo_release_device(const dlo_dev_t uid) +{ + dlo_device_t *dev = (dlo_device_t *)uid; + + return dev ? dlo_usb_close(dev) : dlo_err_bad_device; +} + + +dlo_devinfo_t *dlo_device_info(const dlo_dev_t uid) +{ + static dlo_devinfo_t info; + dlo_device_t *dev = (dlo_device_t *)uid; + + if (!dev) + return NULL; + + info.uid = uid; + info.serial = dev->serial; + info.type = dev->type; + info.claimed = dev->claimed; + + return &info; +} + + +dlo_retcode_t dlo_set_mode(const dlo_dev_t uid, const dlo_mode_t * const desc) +{ + dlo_device_t *dev = (dlo_device_t *)uid; + dlo_modenum_t num; + + if (!dev) + return dlo_err_bad_device; + + /* See if we can provide a mode which matches the required parameters */ + num = dlo_mode_lookup(dev, desc->view.width, desc->view.height, desc->refresh, desc->view.bpp); + DPRINTF("dlo: set_mode: lookup %d\n", (int32_t)num); + + return num == DLO_INVALID_MODE ? dlo_err_bad_mode : dlo_mode_change(dev, desc, num); +} + + +dlo_mode_t *dlo_get_mode(const dlo_dev_t uid) +{ + dlo_device_t *dev = (dlo_device_t *)uid; + + return dev ? &(dev->mode) : NULL; +} + + +dlo_retcode_t dlo_fill_rect(const dlo_dev_t uid, const dlo_view_t * const view, const dlo_rect_t * const rec, const dlo_col32_t col) +{ + static clip_t clip; + static dlo_area_t area; + dlo_device_t * const dev = (dlo_device_t *)uid; + + if (!dev) + return dlo_err_bad_device; + + /* Clip the rectangle to its viewport edges */ + if (!sanitise_view_rect(dev, view, rec, &area, &clip)) + return dlo_ok; + + return dlo_grfx_fill_rect(dev, &area, col); +} + + +dlo_retcode_t dlo_copy_rect(const dlo_dev_t uid, + const dlo_view_t * const src_view, const dlo_rect_t * const src_rec, + const dlo_view_t * const dest_view, const dlo_dot_t * const dest_pos) +{ + static clip_t clip; + static dlo_area_t src_area; + static dlo_area_t dest_area; + static dlo_rect_t dest_rec; + dlo_device_t * const dev = (dlo_device_t *)uid; + bool overlap = false; + + if (!dev) + return dlo_err_bad_device; + + /* Check to see if (and how) the source and destination viewports overlap */ + switch (check_overlaps(dev, src_view, dest_view)) + { + case vstat_good_view: + break; + case vstat_bad_view: + return dlo_err_bad_view; + case vstat_bad_overlap: + return dlo_err_overlap; + default: + { + DPRINTF("dlo: copy_rec: src_view == dest_view... overlap? "); + overlap = (dest_pos->x + src_rec->width > src_rec->origin.x) && + (dest_pos->y + src_rec->height > src_rec->origin.y) && + (dest_pos->x < src_rec->origin.x + src_rec->width) && + (dest_pos->y < src_rec->origin.y + src_rec->height); + DPRINTF("%s\n", overlap ? "yes" : "no"); + } + } + + /* Clip the source rectangle to its viewport edges */ + if (!sanitise_view_rect(dev, src_view, src_rec, &src_area, &clip)) + return dlo_ok; + + /* Clip the destination rectangle by the same amounts as we needed to clip the source */ + dest_rec.origin.x = dest_pos ? dest_pos->x + clip.left : clip.left; + dest_rec.origin.y = dest_pos ? dest_pos->y + clip.below : clip.below; + dest_rec.width = src_area.view.width; + dest_rec.height = src_area.view.height; + + /* Further clip the destination rectangle to its viewport edges */ + if (!sanitise_view_rect(dev, dest_view, &dest_rec, &dest_area, &clip)) + return dlo_ok; + + /* Further clip the source area by the same amounts as we needed to clip the destination */ + src_area.view.base += (BYTES_PER_16BPP * clip.left) + (BYTES_PER_16BPP * clip.below * src_area.stride); + src_area.base8 += (BYTES_PER_8BPP * clip.left) + (BYTES_PER_8BPP * clip.below * src_area.stride); + src_area.view.width = dest_area.view.width; + src_area.view.height = dest_area.view.height; + + return dlo_grfx_copy_rect(dev, &src_area, &dest_area, overlap); +} + + +dlo_retcode_t dlo_copy_host_bmp(const dlo_dev_t uid, const dlo_bmpflags_t flags, + const dlo_fbuf_t * const fbuf, + const dlo_view_t * const dest_view, const dlo_dot_t * const dest_pos) +{ + static clip_t clip; + static dlo_area_t dest_area; + static dlo_rect_t dest_rec; + static dlo_fbuf_t src_fbuf; + dlo_device_t * const dev = (dlo_device_t *)uid; + uint32_t off; + + /* Do some sanity checks */ + if (!dev) + return dlo_err_bad_device; + + if (!fbuf) + return dlo_err_bad_fbuf; + + if (!fbuf->width || !fbuf->height) + return dlo_ok; + + /* Clip the destination rectangle to its viewport edges */ + src_fbuf = *fbuf; + dest_rec.origin.x = dest_pos ? dest_pos->x : 0; + dest_rec.origin.y = dest_pos ? dest_pos->y : 0; + dest_rec.width = src_fbuf.width; + dest_rec.height = src_fbuf.height; + if (!sanitise_view_rect(dev, dest_view, &dest_rec, &dest_area, &clip)) + return dlo_ok; + + /* Update the source framebuffer information if the destination was clipped */ + off = clip.left + (clip.below * src_fbuf.stride); + off *= FORMAT_TO_BYTES_PER_PIXEL(src_fbuf.fmt); + src_fbuf.base = (void *)((unsigned long)src_fbuf.base + (unsigned long)off); + src_fbuf.width -= clip.left + clip.right; + src_fbuf.height -= clip.below + clip.above; + + return dlo_grfx_copy_host_bmp(dev, flags, &src_fbuf, &dest_area); +} + + +dlo_device_t *dlo_new_device(const dlo_devtype_t type, const char * const serial) +{ + dlo_device_t *dev = (dlo_device_t *)dlo_malloc(sizeof(dlo_device_t)); + char *str = NULL; + dlo_retcode_t err; + + NERR_GOTO(dev); + + /* Copy the serial number string and keep a pointer to it */ + str = dlo_malloc(1 + strlen(serial)); + NERR_GOTO(str); + dev->serial = str; + strcpy(dev->serial, serial); + + /* Link into the device list structure */ + dev->prev = NULL; + dev->next = dev_list; + dev_list = dev; + dev->claimed = false; + + /* Defaults are for an "Alex" device via USB */ + dev->type = type; + dev->check = check_state; + dev->timeout = 0; + + /* Mode-dependent attributes and function pointers */ + dev->mode.view.width = 0; + dev->mode.view.height = 0; + dev->mode.view.bpp = 0; + dev->mode.refresh = 0; + dev->mode.view.base = 0; + dev->base8 = 0; + dev->low_blank = false; + + /* Device-dependent attributes */ + dev->buffer = NULL; + + /* Connection-dependent attributes. + * + * It is up to the communications code (re)initialise this values to something which + * makes sense to it. + */ + dev->cnct = NULL; + + /* Set up some feature flags based upon what we know about DisplayLink device types. + * + * NOTE: this section will probably become more refined as more features are added + * to libdlo. Currently, it assumes all devices are the same. + */ + dev->memory = 16 * 1024 * 1024; + + DPRINTF("dlo: new_device: initialised &%X\n", (int)dev); + + return dev; + +error: + if (str) + dlo_free(str); + if (dev) + dlo_free(dev); + + return NULL; +} + + +dlo_device_t *dlo_device_lookup(const char * const serial) +{ + dlo_device_t *dev = dev_list; + + //DPRINTF("dlo: lookup: '%s' dev_list &%X\n", serial, (int)dev_list); + + while (dev) + { + //DPRINTF("dlo: lookup: dev &%X serial '%s'\n", (int)dev, dev->serial); + if (0 == strcmp(dev->serial, serial)) + { + dev->check = check_state; + return dev; + } + dev = dev->next; + } + return NULL; +} + + +/* File-scope function definitions -----------------------------------------------------*/ + + +static bool valid_device(const dlo_device_t * const dev) +{ + dlo_device_t *node = dev_list; + + while (node) + { + if (node == dev) + return true; + node = node->next; + } + return false; +} + + +static dlo_retcode_t remove_device(dlo_device_t *dev) +{ + dlo_retcode_t err; + dlo_device_t *prev = dev->prev; + dlo_device_t *next = dev->next; + + /* Delink the device from the device list */ + if (prev) + prev->next = next; + else + dev_list = next; + if (next) + next->prev = prev; + + /* Disconnect from the device (if connected) */ + if (dev->claimed) + err = dlo_usb_close(dev); + else + err = dlo_ok; + + /* Free the structure (and associated data) even if there was an error */ + if (dev->serial) + dlo_free(dev->serial); + dlo_free(dev); + + return err; +} + + +static bool sanitise_view_rect(const dlo_device_t * const dev, const dlo_view_t * const view, const dlo_rect_t * const rec, dlo_area_t * const area, clip_t * const clip) +{ + static dlo_rect_t my_rec; + const dlo_view_t * const my_view = view ? view : &(dev->mode.view); + uint32_t pix_off; + + /* Exit here if my_view is still NULL (i.e. no screen mode is set up yet) */ + if (!my_view) + return false; + + /* Default the rectangle to the whole of the the view, if none was specified */ + if (rec) + my_rec = *rec; + else + { + my_rec.origin.x = 0; + my_rec.origin.y = 0; + my_rec.width = my_view->width; + my_rec.height = my_view->height; + } + + /* Exit here if the source rectangle is never going to appear in the viewport */ + if (my_rec.origin.x + (int32_t)my_rec.width < 0 || my_rec.origin.y + (int32_t)my_rec.height < 0) + return false; + if (my_rec.origin.x >= (int32_t)my_view->width || my_rec.origin.y >= (int32_t)my_view->height) + return false; + + /* Initialise the clip structure to empty */ + clip->left = 0; + clip->right = 0; + clip->below = 0; + clip->above = 0; + + /* Now clip the rectangle to lie within the viewport */ + if (my_rec.origin.x + (int32_t)my_rec.width > (int32_t)my_view->width) + { + clip->right = my_rec.width - (my_view->width - my_rec.origin.x); + my_rec.width = my_view->width - my_rec.origin.x; + } + if (my_rec.origin.y + (int32_t)my_rec.height > (int32_t)my_view->height) + { + clip->above = my_rec.height - (my_view->height - my_rec.origin.y); + my_rec.height = my_view->height - my_rec.origin.y; + } + if (my_rec.origin.x < 0) + { + clip->left = -my_rec.origin.x; + my_rec.width += my_rec.origin.x; + my_rec.origin.x = 0; + } + if (my_rec.origin.y < 0) + { + clip->below = -my_rec.origin.y; + my_rec.height += my_rec.origin.y; + my_rec.origin.y = 0; + } + + /* Exit here if we've clipped the rectangle away to nothing */ + if (!my_rec.width || !my_rec.height) + return false; + + /* Create the clipped area structure */ + pix_off = my_rec.origin.x + (my_rec.origin.y * my_view->width); + area->view.width = my_rec.width; + area->view.height = my_rec.height; + area->view.bpp = my_view->bpp; + area->view.base = my_view->base + (BYTES_PER_16BPP * pix_off); + area->base8 = my_view->base + (BYTES_PER_16BPP * my_view->width * my_view->height) + pix_off; + area->stride = my_view->width; + + return true; +} + + +static vstat_t check_overlaps(const dlo_device_t * const dev, const dlo_view_t * const src_view, const dlo_view_t * const dest_view) +{ + const dlo_view_t * const src = src_view ? src_view : &(dev->mode.view); + const dlo_view_t * const dest = dest_view ? dest_view : &(dev->mode.view); + dlo_ptr_t src_end; + dlo_ptr_t dest_end; + + /* If no display mode is set up, we should stop here to avoid null dereferences */ + if (!src || !dest) + return vstat_bad_view; + + /* If base addresses are the same, the other attributes must also be the same */ + if (src->base == dest->base) + { + return (src->width == dest->width && + src->height == dest->height && + src->bpp == dest->bpp) ? vstat_good_overlap : vstat_bad_overlap; + } + + /* Ensure we're happy with the source bits per pixel */ + if (src->bpp != 16 && src->bpp != 24) + return vstat_bad_view; + + /* Ensure we're happy with the destination bits per pixel */ + if (dest->bpp != 16 && dest->bpp != 24) + return vstat_bad_view; + + /* Compute the end addresses of both views */ + src_end = src->base + (BYTES_PER_16BPP * src->width * src->height); + dest_end = dest->base + (BYTES_PER_16BPP * dest->width * dest->height); + if (src->bpp == 24) + src_end += BYTES_PER_8BPP * src->width * src->height; + if (dest->bpp == 24) + dest_end += BYTES_PER_8BPP * dest->width * dest->height; + + /* Any overlap in address range means we have a problem */ + return (dest_end <= src->base || dest->base >= src_end) ? vstat_good_view : vstat_bad_overlap; +} + + +/* End of file -------------------------------------------------------------------------*/ diff --git a/src/libdlo.h b/src/libdlo.h index 286cc88..08cdc69 100644 --- a/src/libdlo.h +++ b/src/libdlo.h @@ -1,606 +1,606 @@ -/** @file libdlo.h
- *
- * @brief This file defines the high-level API for the DisplayLink libdlo library.
- *
- * It is a simplified abstraction layer to allow programs to talk to DisplayLink
- * compatible devices.
- *
- * DisplayLink Open Source Software (libdlo)
- * Copyright (C) 2009, DisplayLink
- * www.displaylink.com
- *
- * This library is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Library General Public License as published by the Free
- * Software Foundation; LGPL version 2, dated June 1991.
- *
- * This library 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 Library General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/** @mainpage DisplayLink Open Source Software (libdlo)
- * @anchor dlppdoxygenmain
- *
- * This documentation covers the DisplayLink Open Source Software (libdlo) library (libdlo).
- * It covers the following items:
- *
- * @li File by file information
- * @li Function by function information
- * @li Global variables, defines and structures
- *
- * <hr>
- *
- * <b>Overview</b>
- *
- * <p>
- * This library is stuctured as illustrated below, in order to help clarify the major
- * functional areas and simplify the task of porting or reimplementing these functions
- * to other platforms. At the very least, it should serve as a reference implementation
- * which can be replaced in its entirety.
- * </p>
- *
- * @image html libdlo.gif "libdlo internal structure"
- *
- * <p>
- * All communications with libdlo are through the API published in libdlo.h. This API
- * allows third party software to find DisplayLink devices, connect to them, perform
- * graphical operations and then disconnect as required. There are a number of graphical
- * primitives available, including rectangle plotting and copying (rectangular) areas of
- * screen.
- * </p>
- *
- * <hr>
- * <b>Implementation Notes: Functions</b>
- *
- * <p>
- * There are primarily three types of function used within all of the libdlo sources:
- * </p>
- *
- * @li A void function or non-error returning function
- * @li A pointer-returning function
- * @li A function returning a return code
- *
- * <p>
- * Void and non-error returning functions are used in situations where there is no
- * possibility or an error being raised or where there would be no value in returning it.
- * Examples might include functions which simply perform a computation or those which
- * dispose of a structure and are expected to fail silently.
- * </p>
- *
- * <p>
- * Pointer returning functions will conventionally return a NULL pointer if there is
- * an error. Normally the error will be due to memory allocation failure (out of
- * memory) but this is not always the case. As a NULL pointer it not very informative
- * about the nature of the failure, the use of pointer-returning functions within
- * libdlo has been kept to a minimum.
- * </p>
- *
- * <p>
- * The majority of functions return an code of type @a dlo_retcode_t to indicate
- * success or the nature of failure. All return codes have an associated textual string
- * so they can be decoded in a human-readable format by calling @c dlo_strerror().
- * </p>
- *
- * <hr>
- * <b>Implementation Notes: Error Handling</b>
- *
- * <p>
- * In order to keep the handling of errors consistent, there are a number of handy
- * macros defined in dlo_defs.h. There are a few which collect any non-zero return
- * value from a given function call and return it from the calling function (there
- * is also a version of this call which checks for NULL pointer returns and converts
- * it into an memory allocation failure return code). These macros are:
- * </p>
- *
- * @li @c ERR()
- * @li @c NERR()
- * @li @c UERR()
- *
- * <p>
- * A second set of macros are defined which, instead of returning a return code from
- * the calling function, they store the error in a local variable "err" and jump to
- * a label called "error". This allows the function to perform whatever tidy-up
- * operations it needs to before returning "err". These macros are:
- * </p>
- *
- * @li @c ERR_GOTO()
- * @li @c NERR_GOTO()
- * @li @c UERR_GOTO()
- *
- * <p>
- * Both of these sets of macros are used throughout the libdlo sources in order to
- * make the handling of errors consistent.
- * </p>
- *
- * <hr>
- * Copyright © 2008, DisplayLink
- * All rights reserved.
- */
-
-#ifndef DLO_LIBDLO_H
-#define DLO_LIBDLO_H /**< Avoid multiple inclusion. */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include "usb.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if 0
-#define dlo_malloc my_malloc
-#define dlo_realloc my_realloc
-#define dlo_free my_free
-
-/** Alternative malloc routine.
- *
- * @param size As per @c malloc().
- *
- * @return As per @c malloc().
- */
-extern void *my_malloc(size_t size);
-
-/** Alternative realloc routine.
- *
- * @param blk As per @c realloc().
- * @param size As per @c realloc().
- *
- * @return As per @c realloc().
- */
-extern void *my_realloc(void *blk, size_t size);
-
-/** Alternative free routine.
- *
- * @param blk As per @c free().
- */
-extern void my_free(void *blk);
-
-/** Return total size of allocated blocks.
- *
- * @return Size of all current allocations (bytes).
- */
-extern uint32_t my_used(void);
-#endif
-
-
-/** Allow the use of the standard C library @a malloc() function to be overridden.
- */
-#ifndef dlo_malloc
-#define dlo_malloc malloc
-#endif
-
-/** Allow the use of the standard C library @a realloc() function to be overridden.
- */
-#ifndef dlo_realloc
-#define dlo_realloc realloc
-#endif
-
-/** Allow the use of the standard C library @a free() function to be overridden.
- */
-#ifndef dlo_free
-#define dlo_free free
-#endif
-
-/** Allow the use of the standard C library @a memset() function to be overridden.
- */
-#ifndef dlo_memset
-#define dlo_memset (void) memset
-#endif
-
-/** Allow the use of the standard C library @a memcpy() function to be overridden.
- */
-#ifndef dlo_memcpy
-#define dlo_memcpy (void) memcpy
-#endif
-
-/** Allow the use of the standard C library @a memmove() function to be overridden.
- */
-#ifndef dlo_memmove
-#define dlo_memmove (void) memmove
-#endif
-
-
-/** An opaque device handle. */
-typedef void *dlo_dev_t;
-
-
-/** Return codes used within the libdlo sources. Note: libdlo will never return top-bit-set return
- * codes so these can safely be allocated within your own programs for your own purposes.
- *
- * Return code 0x00000000 represents a successful return without error or warning.
- * Return codes in the range 0x00000001..0x0FFFFFFF represent an error condition.
- * Return codes in the range 0x10000000..0x7FFFFFFF represent a warning.
- * Return codes in the range 0x80000000..0xFFFFFFFF are free for caller allocation.
- */
-typedef enum
-{
- /* Success... */
- dlo_ok = 0u, /**< Successful. */
- /* Errors... */
- dlo_err_memory = 1u, /**< A memory claim operation failed; out of memory. */
- dlo_err_bad_area, /**< An invalid area was specified (e.g. of zero width or height). */
- dlo_err_bad_col, /**< Unsupported colour depth. */
- dlo_err_bad_device, /**< Unknown device - has been disconnected or powered down. */
- dlo_err_bad_fbuf, /**< Null pointer passed as local bitmap data. */
- dlo_err_bad_fmt, /**< Unsupported bitmap pixel format. */
- dlo_err_bad_mode, /**< Call to @c set_mode() failed due to unsupported mode parameters. */
- dlo_err_bad_view, /**< Invalid viewport specified (is screen mode set up?). */
- dlo_err_big_scrape, /**< Bitmap is too wide for copy buffer.*/
- dlo_err_buf_full, /**< Command buffer is full. */
- dlo_err_claimed, /**< Device cannot be claimed - it's already been claimed. */
- dlo_err_edid_fail, /**< EDID communication with monitor failed. */
- dlo_err_iic_op, /**< An IIC operation with the device failed. */
- dlo_err_not_root, /**< Executable should be run as root (e.g. using 'su root' or 'sudo'). */
- dlo_err_open, /**< Attempt to open a connection to the device failed. */
- dlo_err_overlap, /**< Source and destination viewports cannot overlap (unless the same). */
- dlo_err_reenum, /**< Reenumeration required before device can be claimed. */
- dlo_err_unclaimed, /**< Device cannot be written to: unclaimed. */
- dlo_err_unsupported, /**< Requested feature is not supported. */
- dlo_err_usb, /**< A USB-related error: call @c dlo_usb_strerror() for further info. */
- /* Warnings... */
- dlo_warn_dl160_mode = 0x10000000u, /**< This screen mode may not display correctly on DL120 devices. */
- /* User return codes... */
- dlo_user_example = 0x80000000 /**< Return codes 0x80000000 to 0xFFFFFFFF are free for user allocation. */
-} dlo_retcode_t; /**< Return codes. Used to indicate the success or otherwise of a call to the library. */
-
-
-/** A 32 bits per pixel colour number (0x00bbggrr, little endian). Note: most significant byte is undefined. */
-typedef uint32_t dlo_col32_t;
-
-
-/** Return a 32 bpp colour number when given the three RGB components. */
-#define DLO_RGB(red,grn,blu) (dlo_col32_t)(((red) & 0xFF) | (((grn) & 0xFF) << 8) | (((blu) & 0xFF) << 16))
-
-/** Set the red component (0..255) of a 32 bpp colour. */
-#define DLO_RGB_SETRED(col,red) (dlo_col32_t)(((col) & ~0xFF) | ((red) & 0xFF))
-
-/** Set the green component (0..255) of a 32 bpp colour. */
-#define DLO_RGB_SETGRN(col,grn) (dlo_col32_t)(((col) & ~0xFF00) | (((grn) & 0xFF) << 8))
-
-/** Set the blue component (0..255) of a 32 bpp colour. */
-#define DLO_RGB_SETBLU(col,blu) (dlo_col32_t)(((col) & ~0xFF0000) | (((blu) & 0xFF) << 16))
-
-/** Read the red component (0..255) of a 32 bpp colour. */
-#define DLO_RGB_GETRED(col) (uint8_t)((col) & 0xFF)
-
-/** Read the green component (0..255) of a 32 bpp colour. */
-#define DLO_RGB_GETGRN(col) (uint8_t)(((col) >> 8) & 0xFF)
-
-/** Read the blue component (0..255) of a 32 bpp colour. */
-#define DLO_RGB_GETBLU(col) (uint8_t)(((col) >> 16) & 0xFF)
-
-
-/** Types of DisplayLink device. */
-typedef enum
-{
- dlo_dev_unknown = 0, /**< Unknown device type. */
- dlo_dev_base = 0xB, /**< Base platform. */
- dlo_dev_alex = 0xF, /**< Alex chipset. */
- dlo_dev_ollie = 0xF1 /**< Ollie chipset. */
-} dlo_devtype_t; /**< A struct @a dlo_devtype_s. */
-
-
-/** A structure containing information about a specific device. */
-typedef struct dlo_devinfo_s
-{
- dlo_dev_t uid; /**< Unique ID for referencing the device. */
- char *serial; /**< Pointer to serial number string for device. */
- dlo_devtype_t type; /**< Device type. */
- bool claimed; /**< Flag indicating whether someone has claimed the device. */
-} dlo_devinfo_t; /**< A struct @a dlo_devinfo_s. */
-
-
-/** A list of devices, as returned by the enumeration call. */
-typedef struct dlo_devlist_s dlo_devlist_t;
-
-/** A list of devices, as returned by the enumeration call. */
-struct dlo_devlist_s
-{
- dlo_devlist_t *next; /**< Pointer to next node in the device list (or NULL). */
- dlo_devinfo_t dev; /**< Device information structure. */
-}; /**< A struct @a dlo_devlist_s. */
-
-
-/** Flags word for the initialisation function (no flags defined at present). */
-typedef struct dlo_init_s
-{
- unsigned undef :1; /**< Undefined flag (placeholder). */
-} dlo_init_t; /**< A struct @a dlo_init_s. */
-
-
-/** Flags word for the finalisation function (no flags defined at present). */
-typedef struct dlo_final_s
-{
- unsigned undef :1; /**< Undefined flag (placeholder). */
-} dlo_final_t; /**< A struct @a dlo_final_s. */
-
-
-/** Flags word to configure the device connection (no flags defined at present). */
-typedef struct dlo_claim_s
-{
- unsigned undef :1; /**< Undefined flag (placeholder). */
-} dlo_claim_t; /**< A struct @a dlo_claim_s. */
-
-
-/** Flags word to configure the @c dlo_copy_host_bmp() call. */
-typedef struct dlo_bmpflags_s
-{
- unsigned v_flip :1; /**< Vertically flip the bitmap during the copy. */
-} dlo_bmpflags_t; /**< A struct @a dlo_bmpflags_s. */
-
-
-/** Shift (bits) for position of bytes-per-pixel data in pixel format word.
- */
-#define DLO_PIXFMT_BYPP_SFT (6u)
-
-/** Bit mask for extracting bytes-per-pixel data from pixel format word.
- */
-#define DLO_PIXFMT_BYPP_MSK (0x7 << DLO_PIXFMT_BYPP_SFT)
-
-/** Shift (bits) for position of red/blue swap flag in pixel format word.
- */
-#define DLO_PIXFMT_SWP_SFT (9u)
-
-/** Shift (bits) for position of pointer data (most significant bits).
- */
-#define DLO_PIXFMT_PTR_SFT (10u)
-
-/** Maximum number of pixel format variations.
- */
-#define DLO_PIXFMT_MAX (1u << DLO_PIXFMT_PTR_SFT)
-
-/** Pixel format has one byte per pixel.
- */
-#define DLO_PIXFMT_1BYPP (1u << DLO_PIXFMT_BYPP_SFT)
-
-/** Pixel format has two bytes per pixel.
- */
-#define DLO_PIXFMT_2BYPP (2u << DLO_PIXFMT_BYPP_SFT)
-
-/** Pixel format has three bytes per pixel.
- */
-#define DLO_PIXFMT_3BYPP (3u << DLO_PIXFMT_BYPP_SFT)
-
-/** Pixel format has four bytes per pixel.
- */
-#define DLO_PIXFMT_4BYPP (4u << DLO_PIXFMT_BYPP_SFT)
-
-/** Pixel format has red and blue colour components reversed.
- */
-#define DLO_PIXFMT_SWP (1u << DLO_PIXFMT_SWP_SFT)
-
-/** Supported source pixel format information (e.g. bits per pixel, colour component order, etc).
- *
- * Each value in this enum encodes the pixel RGB vs BGR colour component order and
- * the number of bytes per pixel. There is one function for reading each pixel format
- * (but the RGB vs BGR is passed in as a flag) and the bytes per pixel is required to
- * advance the pixel pointer in a framebuffer after a pixel has been read.
- *
- * Bits 0..5 contain the pixel format code
- * Bits 6..8 contain the number of bytes per pixel
- * Bit 9 contains the swap flag for RGB vs BGR
- * Bits 10.. if non-zero, then the pixel format is actually a pointer to an 8 bit LUT
- *
- * The pixel format can also simply be a pointer to a 256 entry LUT of dlo_col32_t
- * colours in the case where the local framebuffer contains 8bpp bitmap data which
- * uses a palette. Simply cast the LUT pointer to a dlo_pixfmt_t (this assumes that
- * your LUT isn't stored in the bottom 1KB of the logical address space!). E.g.
- *
- * static dlo_col32_t mylut[256]; // this is the palette for my 8bpp bitmap
- * static dlo_pixfmt_t mypixfmt = (dlo_pixfmt_t)mylut;
- */
-typedef enum
-{
- dlo_pixfmt_bgr323 = 0 | DLO_PIXFMT_1BYPP, /**< 8 bit per pixel 2_bbbggrrr. */
- dlo_pixfmt_rgb323 = 0 | DLO_PIXFMT_1BYPP | DLO_PIXFMT_SWP, /**< 8 bit per pixel 2_rrrggbbb. */
- dlo_pixfmt_bgr565 = 1 | DLO_PIXFMT_2BYPP, /**< 16 bit per pixel 2_bbbbbggggggrrrrr. */
- dlo_pixfmt_rgb565 = 1 | DLO_PIXFMT_2BYPP | DLO_PIXFMT_SWP, /**< 16 bit per pixel 2_rrrrrggggggbbbbb. */
- dlo_pixfmt_sbgr1555 = 2 | DLO_PIXFMT_2BYPP, /**< 16 bit per pixel 2_Sbbbbbgggggrrrrr (S is supremacy/transparancy bit). */
- dlo_pixfmt_srgb1555 = 2 | DLO_PIXFMT_2BYPP | DLO_PIXFMT_SWP, /**< 16 bit per pixel 2_Srrrrrgggggbbbbb (S is supremacy/transparancy bit). */
- dlo_pixfmt_bgr888 = 3 | DLO_PIXFMT_3BYPP, /**< 24 bit per pixel 0xbbggrr. */
- dlo_pixfmt_rgb888 = 3 | DLO_PIXFMT_3BYPP | DLO_PIXFMT_SWP, /**< 24 bit per pixel 0xrrggbb. */
- dlo_pixfmt_abgr8888 = 4 | DLO_PIXFMT_4BYPP, /**< 32 bit per pixel 0xaabbggrr. */
- dlo_pixfmt_argb8888 = 4 | DLO_PIXFMT_4BYPP | DLO_PIXFMT_SWP /**< 32 bit per pixel 0xaarrggbb. */
- /* Any value greater than 1023 is assumed to be a pointer to: dlo_col32_t palette[256]
- * for translating paletted 8 bits per pixel data into colour numbers.
- */
-} dlo_pixfmt_t; /**< A struct @a dlo_pixfmt_s. */
-
-
-/** A local (host-resident) bitmap or framebuffer. */
-typedef struct dlo_fbuf_s
-{
- uint16_t width; /**< Width (pixels). */
- uint16_t height; /**< Height (pixels). */
- dlo_pixfmt_t fmt; /**< Pixel format (e.g. bits per pixel, colour component order, etc). */
- void *base; /**< Base address in host memory. */
- uint32_t stride; /**< Stride (pixels) from a pixel to the one directly below. */
-} dlo_fbuf_t; /**< A struct @a dlo_fbuf_s. */
-
-
-/** An pointer to a location in the DisplayLink device logical memory map. */
-typedef uint32_t dlo_ptr_t;
-
-
-/** A viewport (bitmap) in a contiguous block of device memory.
- *
- * A viewport describes the contents of a contiguous block of device memory (of which there
- * is normally 16 MB available). It represents a rectangular bitmap which may be large
- * enough to use as a screen mode or of any other non-zero size.
- *
- * It is the responsibility of the caller to organise one or more viewports in the device
- * memory and use the @c dlo_set_mode() call to determine which is visible on the screen
- * at any given time.
- *
- * When a device is first claimed, the EDID data for any connected display will be
- * read. If successful, then an initial screen mode is set up using the native mode timings
- * of the display. This will result in an initial viewport being defined at base address 0.
- * Details of the initial viewport can be discovered by the caller using the
- * @c dlo_get_mode() call. If no initial mode was set up by libdlo, then the caller must do
- * so by making an appropriate call to @c dlo_set_mode().
- *
- * Setting the screen mode does not result in the screen being cleared; the caller must make
- * a call to @c dlo_fill_rect() to achieve this, e.g.
- *
- * dlo_fill_rect(uid, NULL, NULL, DLO_RGB(0,0,0))
- *
- * to clear the whole of the viewport for the current screen mode to black.
- *
- * Overlapping viewports should be avoided because they do not include the concept of a
- * 'stride' (to get from one pixel to the pixel immediately below). They must also have a
- * base address which starts on a two byte boundary. Aside from these constraints, viewports
- * can be arranged at any locations within the device memory.
- *
- * The caller should not assume anything about the format of the pixels stored in the device
- * memory or how pixels are arranged within a given viewport's address range. It is safe to
- * assume that the pixels will require three bytes each (in a 24 bpp viewport) so a viewport
- * which is 1280 x 1024 pixels in size, starting at base address 0x000000 in the device
- * memory will end at address 1280*1024*3 = 0x3C0000.
- *
- * Thus, the caller may set up two screen banks by maintaining two viewports of the same
- * dimensions, one starting at base address 0x000000 (for example) and another starting at
- * base address 0x3C0000 (assuming they are 1280x1024 pixels in size). These two banks can
- * be plotted to independently of each other and displayed using the @c dlo_set_mode() call.
- */
-typedef struct dlo_view_s
-{
- uint16_t width; /**< Width (pixels). */
- uint16_t height; /**< Height (pixels). */
- uint8_t bpp; /**< Colour depth (bits per pixel). */
- dlo_ptr_t base; /**< Base address in the device memory. */
-} dlo_view_t; /**< A struct @a dlo_view_s. */
-
-
-/** Descriptor for reading or setting the current screen mode. */
-typedef struct dlo_mode_s
-{
- dlo_view_t view; /**< The @a dlo_view_t associated with the screen mode. */
- uint8_t refresh; /**< Refresh rate (Hz). */
-} dlo_mode_t; /**< A struct @a dlo_mode_s. */
-
-
-/** Co-ordinates of a point/pixel relative to the origin, top-left, of a given @a dlo_view_t. */
-typedef struct dlo_dot_s
-{
- int32_t x; /**< X co-ordinate of the dot, pixels from left edge of screen (+ve is right). */
- int32_t y; /**< Y co-ordinate of the dot, pixels down from top edge of screen (-ve is up). */
-} dlo_dot_t; /**< A struct @a dlo_dot_s. */
-
-
-/** A rectangle relative to a given @a dlo_view_t. */
-typedef struct dlo_rect_s
-{
- dlo_dot_t origin; /**< Origin co-ordinates (top-left of the rectangle). */
- uint16_t width; /**< Width (pixels) of rectangle (all pixels from origin.x to origin.x+width-1 inclusive). */
- uint16_t height; /**< Height (pixels) of rectangle (all pixels from origin.y to origin.x+height-1 inclusive). */
-} dlo_rect_t; /**< A struct @a dlo_rect_s. */
-
-
-/** Return the meaning of the specified return code as a human-readable string.
- *
- * @param err Return code.
- *
- * @return Pointer to zero-terminated (error) message string.
- *
- * The string is held in libdlo's static workspace so no attempt should be made
- * by the caller to free it.
- */
-extern const char *dlo_strerror(const dlo_retcode_t err);
-
-
-/** Initialisation call for libdlo.
- *
- * @param flags Initialisation flags word (unused flags should be zero).
- *
- * @return Return code, zero for no error.
- *
- * This function must be called by libdlo users before any other functions
- * are called or they may result in undefined behaviour. It will ignore any
- * flag bits which it does not currently understand.
- *
- * The @a vsn value indicates the library API version number. As the API
- * defined within this header file is evolved, the API version number will
- * be incremented.
- */
-extern dlo_retcode_t dlo_init(const dlo_init_t flags);
-
-
-/** Finalisation call for libdlo.
- *
- * @param flags Finalisation flags word (unused flags should be zero).
- *
- * @return Return code, zero for no error.
- *
- * This function should be called when a program no longer needs to use libdlo
- * (e.g. when it exits) in order to free up any system resources which have been
- * claimed by this library. It will ignore any flag bits which it does not
- * currently understand.
- */
-extern dlo_retcode_t dlo_final(const dlo_final_t flags);
-
-
-/** Map the caller's pointer to a udev structure from libusb to a unique ID in libdlo.
- *
- * @param udev Pointer to USB device structure for given device (from libusb).
- *
- * @return Unique ID of the corresponding device for libdlo calls.
- *
- * This call is intended for use by a caller that has already used libusb in order
- * to identify a particular device that they want to connect to.
- */
-extern dlo_dev_t dlo_lookup_device(struct usb_device *udev);
-
-
-/** Enumerate all connected DisplayLink-compatible devices.
- *
- * @return Pointer to linked list of device information structures (or NULL if none).
- *
- * This function will return a pointer to one or more @a devlist_t structures if
- * there are any active DisplayLink compatible devices connected to the computer.
- * It will return a NULL pointer if none are found or if there was an error during
- * the enumeration process.
- *
- * It is the caller's responsibility to free the memory associated with this list
- * by calling the @c dlo_free() function on each list item (but not for any
- * strings pointed to by items in the list, as these strings are maintained by
- * libdlo).
- */
-extern dlo_devlist_t *dlo_enumerate_devices(void);
-
-
-/** Claim the specified device.
- *
- * @param uid Unique ID of the device to claim.
- * @param flags Flags word describing how the device is to be accessed.
- * @param timeout Timeout in milliseconds (zero for infinite).
- *
- * @return Unique ID of the claimed device (or NULL if failed).
- *
- * Before accessing a device, it should be claimed in order to avoid clashes
- * where multiple programs are trying to write to the same device (however,
- * abstraction of that sort would be implemented above this API).
- *
- * If the device is connected to a display which supports the EDID standard, then
- * this call will also attempt to set up the display mode to the native resolution
- * of the display - equivalent to a call to @c dlo_set_mode(). It will not clear
- * the screen contents; you should call @c dlo_fill_rect() for that.
- *
- * It is possible to specify a @a timeout value for this call. If a non-zero timeout
- * is specified, the same value will be used for any further calls to the device.
- * Passing in a zero timeout means that libdlo should use its default timeouts.
- * The @a timeout value is only used for specific transactions with the device; in
- * some special cases libdlo will still use its own internal timeout values.
- *
- * Devices should be released with a call to @c release_device() when they are no
- * longer required.
- */
+/** @file libdlo.h + * + * @brief This file defines the high-level API for the DisplayLink libdlo library. + * + * It is a simplified abstraction layer to allow programs to talk to DisplayLink + * compatible devices. + * + * DisplayLink Open Source Software (libdlo) + * Copyright (C) 2009, DisplayLink + * www.displaylink.com + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Library General Public License as published by the Free + * Software Foundation; LGPL version 2, dated June 1991. + * + * This library 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 Library General Public License for more + * details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** @mainpage DisplayLink Open Source Software (libdlo) + * @anchor dlppdoxygenmain + * + * This documentation covers the DisplayLink Open Source Software (libdlo) library (libdlo). + * It covers the following items: + * + * @li File by file information + * @li Function by function information + * @li Global variables, defines and structures + * + * <hr> + * + * <b>Overview</b> + * + * <p> + * This library is stuctured as illustrated below, in order to help clarify the major + * functional areas and simplify the task of porting or reimplementing these functions + * to other platforms. At the very least, it should serve as a reference implementation + * which can be replaced in its entirety. + * </p> + * + * @image html libdlo.gif "libdlo internal structure" + * + * <p> + * All communications with libdlo are through the API published in libdlo.h. This API + * allows third party software to find DisplayLink devices, connect to them, perform + * graphical operations and then disconnect as required. There are a number of graphical + * primitives available, including rectangle plotting and copying (rectangular) areas of + * screen. + * </p> + * + * <hr> + * <b>Implementation Notes: Functions</b> + * + * <p> + * There are primarily three types of function used within all of the libdlo sources: + * </p> + * + * @li A void function or non-error returning function + * @li A pointer-returning function + * @li A function returning a return code + * + * <p> + * Void and non-error returning functions are used in situations where there is no + * possibility or an error being raised or where there would be no value in returning it. + * Examples might include functions which simply perform a computation or those which + * dispose of a structure and are expected to fail silently. + * </p> + * + * <p> + * Pointer returning functions will conventionally return a NULL pointer if there is + * an error. Normally the error will be due to memory allocation failure (out of + * memory) but this is not always the case. As a NULL pointer it not very informative + * about the nature of the failure, the use of pointer-returning functions within + * libdlo has been kept to a minimum. + * </p> + * + * <p> + * The majority of functions return an code of type @a dlo_retcode_t to indicate + * success or the nature of failure. All return codes have an associated textual string + * so they can be decoded in a human-readable format by calling @c dlo_strerror(). + * </p> + * + * <hr> + * <b>Implementation Notes: Error Handling</b> + * + * <p> + * In order to keep the handling of errors consistent, there are a number of handy + * macros defined in dlo_defs.h. There are a few which collect any non-zero return + * value from a given function call and return it from the calling function (there + * is also a version of this call which checks for NULL pointer returns and converts + * it into an memory allocation failure return code). These macros are: + * </p> + * + * @li @c ERR() + * @li @c NERR() + * @li @c UERR() + * + * <p> + * A second set of macros are defined which, instead of returning a return code from + * the calling function, they store the error in a local variable "err" and jump to + * a label called "error". This allows the function to perform whatever tidy-up + * operations it needs to before returning "err". These macros are: + * </p> + * + * @li @c ERR_GOTO() + * @li @c NERR_GOTO() + * @li @c UERR_GOTO() + * + * <p> + * Both of these sets of macros are used throughout the libdlo sources in order to + * make the handling of errors consistent. + * </p> + * + * <hr> + * Copyright © 2008, DisplayLink + * All rights reserved. + */ + +#ifndef DLO_LIBDLO_H +#define DLO_LIBDLO_H /**< Avoid multiple inclusion. */ + +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> +#include "usb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if 0 +#define dlo_malloc my_malloc +#define dlo_realloc my_realloc +#define dlo_free my_free + +/** Alternative malloc routine. + * + * @param size As per @c malloc(). + * + * @return As per @c malloc(). + */ +extern void *my_malloc(size_t size); + +/** Alternative realloc routine. + * + * @param blk As per @c realloc(). + * @param size As per @c realloc(). + * + * @return As per @c realloc(). + */ +extern void *my_realloc(void *blk, size_t size); + +/** Alternative free routine. + * + * @param blk As per @c free(). + */ +extern void my_free(void *blk); + +/** Return total size of allocated blocks. + * + * @return Size of all current allocations (bytes). + */ +extern uint32_t my_used(void); +#endif + + +/** Allow the use of the standard C library @a malloc() function to be overridden. + */ +#ifndef dlo_malloc +#define dlo_malloc malloc +#endif + +/** Allow the use of the standard C library @a realloc() function to be overridden. + */ +#ifndef dlo_realloc +#define dlo_realloc realloc +#endif + +/** Allow the use of the standard C library @a free() function to be overridden. + */ +#ifndef dlo_free +#define dlo_free free +#endif + +/** Allow the use of the standard C library @a memset() function to be overridden. + */ +#ifndef dlo_memset +#define dlo_memset (void) memset +#endif + +/** Allow the use of the standard C library @a memcpy() function to be overridden. + */ +#ifndef dlo_memcpy +#define dlo_memcpy (void) memcpy +#endif + +/** Allow the use of the standard C library @a memmove() function to be overridden. + */ +#ifndef dlo_memmove +#define dlo_memmove (void) memmove +#endif + + +/** An opaque device handle. */ +typedef void *dlo_dev_t; + + +/** Return codes used within the libdlo sources. Note: libdlo will never return top-bit-set return + * codes so these can safely be allocated within your own programs for your own purposes. + * + * Return code 0x00000000 represents a successful return without error or warning. + * Return codes in the range 0x00000001..0x0FFFFFFF represent an error condition. + * Return codes in the range 0x10000000..0x7FFFFFFF represent a warning. + * Return codes in the range 0x80000000..0xFFFFFFFF are free for caller allocation. + */ +typedef enum +{ + /* Success... */ + dlo_ok = 0u, /**< Successful. */ + /* Errors... */ + dlo_err_memory = 1u, /**< A memory claim operation failed; out of memory. */ + dlo_err_bad_area, /**< An invalid area was specified (e.g. of zero width or height). */ + dlo_err_bad_col, /**< Unsupported colour depth. */ + dlo_err_bad_device, /**< Unknown device - has been disconnected or powered down. */ + dlo_err_bad_fbuf, /**< Null pointer passed as local bitmap data. */ + dlo_err_bad_fmt, /**< Unsupported bitmap pixel format. */ + dlo_err_bad_mode, /**< Call to @c set_mode() failed due to unsupported mode parameters. */ + dlo_err_bad_view, /**< Invalid viewport specified (is screen mode set up?). */ + dlo_err_big_scrape, /**< Bitmap is too wide for copy buffer.*/ + dlo_err_buf_full, /**< Command buffer is full. */ + dlo_err_claimed, /**< Device cannot be claimed - it's already been claimed. */ + dlo_err_edid_fail, /**< EDID communication with monitor failed. */ + dlo_err_iic_op, /**< An IIC operation with the device failed. */ + dlo_err_not_root, /**< Executable should be run as root (e.g. using 'su root' or 'sudo'). */ + dlo_err_open, /**< Attempt to open a connection to the device failed. */ + dlo_err_overlap, /**< Source and destination viewports cannot overlap (unless the same). */ + dlo_err_reenum, /**< Reenumeration required before device can be claimed. */ + dlo_err_unclaimed, /**< Device cannot be written to: unclaimed. */ + dlo_err_unsupported, /**< Requested feature is not supported. */ + dlo_err_usb, /**< A USB-related error: call @c dlo_usb_strerror() for further info. */ + /* Warnings... */ + dlo_warn_dl160_mode = 0x10000000u, /**< This screen mode may not display correctly on DL120 devices. */ + /* User return codes... */ + dlo_user_example = 0x80000000 /**< Return codes 0x80000000 to 0xFFFFFFFF are free for user allocation. */ +} dlo_retcode_t; /**< Return codes. Used to indicate the success or otherwise of a call to the library. */ + + +/** A 32 bits per pixel colour number (0x00bbggrr, little endian). Note: most significant byte is undefined. */ +typedef uint32_t dlo_col32_t; + + +/** Return a 32 bpp colour number when given the three RGB components. */ +#define DLO_RGB(red,grn,blu) (dlo_col32_t)(((red) & 0xFF) | (((grn) & 0xFF) << 8) | (((blu) & 0xFF) << 16)) + +/** Set the red component (0..255) of a 32 bpp colour. */ +#define DLO_RGB_SETRED(col,red) (dlo_col32_t)(((col) & ~0xFF) | ((red) & 0xFF)) + +/** Set the green component (0..255) of a 32 bpp colour. */ +#define DLO_RGB_SETGRN(col,grn) (dlo_col32_t)(((col) & ~0xFF00) | (((grn) & 0xFF) << 8)) + +/** Set the blue component (0..255) of a 32 bpp colour. */ +#define DLO_RGB_SETBLU(col,blu) (dlo_col32_t)(((col) & ~0xFF0000) | (((blu) & 0xFF) << 16)) + +/** Read the red component (0..255) of a 32 bpp colour. */ +#define DLO_RGB_GETRED(col) (uint8_t)((col) & 0xFF) + +/** Read the green component (0..255) of a 32 bpp colour. */ +#define DLO_RGB_GETGRN(col) (uint8_t)(((col) >> 8) & 0xFF) + +/** Read the blue component (0..255) of a 32 bpp colour. */ +#define DLO_RGB_GETBLU(col) (uint8_t)(((col) >> 16) & 0xFF) + + +/** Types of DisplayLink device. */ +typedef enum +{ + dlo_dev_unknown = 0, /**< Unknown device type. */ + dlo_dev_base = 0xB, /**< Base platform. */ + dlo_dev_alex = 0xF, /**< Alex chipset. */ + dlo_dev_ollie = 0xF1 /**< Ollie chipset. */ +} dlo_devtype_t; /**< A struct @a dlo_devtype_s. */ + + +/** A structure containing information about a specific device. */ +typedef struct dlo_devinfo_s +{ + dlo_dev_t uid; /**< Unique ID for referencing the device. */ + char *serial; /**< Pointer to serial number string for device. */ + dlo_devtype_t type; /**< Device type. */ + bool claimed; /**< Flag indicating whether someone has claimed the device. */ +} dlo_devinfo_t; /**< A struct @a dlo_devinfo_s. */ + + +/** A list of devices, as returned by the enumeration call. */ +typedef struct dlo_devlist_s dlo_devlist_t; + +/** A list of devices, as returned by the enumeration call. */ +struct dlo_devlist_s +{ + dlo_devlist_t *next; /**< Pointer to next node in the device list (or NULL). */ + dlo_devinfo_t dev; /**< Device information structure. */ +}; /**< A struct @a dlo_devlist_s. */ + + +/** Flags word for the initialisation function (no flags defined at present). */ +typedef struct dlo_init_s +{ + unsigned undef :1; /**< Undefined flag (placeholder). */ +} dlo_init_t; /**< A struct @a dlo_init_s. */ + + +/** Flags word for the finalisation function (no flags defined at present). */ +typedef struct dlo_final_s +{ + unsigned undef :1; /**< Undefined flag (placeholder). */ +} dlo_final_t; /**< A struct @a dlo_final_s. */ + + +/** Flags word to configure the device connection (no flags defined at present). */ +typedef struct dlo_claim_s +{ + unsigned undef :1; /**< Undefined flag (placeholder). */ +} dlo_claim_t; /**< A struct @a dlo_claim_s. */ + + +/** Flags word to configure the @c dlo_copy_host_bmp() call. */ +typedef struct dlo_bmpflags_s +{ + unsigned v_flip :1; /**< Vertically flip the bitmap during the copy. */ +} dlo_bmpflags_t; /**< A struct @a dlo_bmpflags_s. */ + + +/** Shift (bits) for position of bytes-per-pixel data in pixel format word. + */ +#define DLO_PIXFMT_BYPP_SFT (6u) + +/** Bit mask for extracting bytes-per-pixel data from pixel format word. + */ +#define DLO_PIXFMT_BYPP_MSK (0x7 << DLO_PIXFMT_BYPP_SFT) + +/** Shift (bits) for position of red/blue swap flag in pixel format word. + */ +#define DLO_PIXFMT_SWP_SFT (9u) + +/** Shift (bits) for position of pointer data (most significant bits). + */ +#define DLO_PIXFMT_PTR_SFT (10u) + +/** Maximum number of pixel format variations. + */ +#define DLO_PIXFMT_MAX (1u << DLO_PIXFMT_PTR_SFT) + +/** Pixel format has one byte per pixel. + */ +#define DLO_PIXFMT_1BYPP (1u << DLO_PIXFMT_BYPP_SFT) + +/** Pixel format has two bytes per pixel. + */ +#define DLO_PIXFMT_2BYPP (2u << DLO_PIXFMT_BYPP_SFT) + +/** Pixel format has three bytes per pixel. + */ +#define DLO_PIXFMT_3BYPP (3u << DLO_PIXFMT_BYPP_SFT) + +/** Pixel format has four bytes per pixel. + */ +#define DLO_PIXFMT_4BYPP (4u << DLO_PIXFMT_BYPP_SFT) + +/** Pixel format has red and blue colour components reversed. + */ +#define DLO_PIXFMT_SWP (1u << DLO_PIXFMT_SWP_SFT) + +/** Supported source pixel format information (e.g. bits per pixel, colour component order, etc). + * + * Each value in this enum encodes the pixel RGB vs BGR colour component order and + * the number of bytes per pixel. There is one function for reading each pixel format + * (but the RGB vs BGR is passed in as a flag) and the bytes per pixel is required to + * advance the pixel pointer in a framebuffer after a pixel has been read. + * + * Bits 0..5 contain the pixel format code + * Bits 6..8 contain the number of bytes per pixel + * Bit 9 contains the swap flag for RGB vs BGR + * Bits 10.. if non-zero, then the pixel format is actually a pointer to an 8 bit LUT + * + * The pixel format can also simply be a pointer to a 256 entry LUT of dlo_col32_t + * colours in the case where the local framebuffer contains 8bpp bitmap data which + * uses a palette. Simply cast the LUT pointer to a dlo_pixfmt_t (this assumes that + * your LUT isn't stored in the bottom 1KB of the logical address space!). E.g. + * + * static dlo_col32_t mylut[256]; // this is the palette for my 8bpp bitmap + * static dlo_pixfmt_t mypixfmt = (dlo_pixfmt_t)mylut; + */ +typedef enum +{ + dlo_pixfmt_bgr323 = 0 | DLO_PIXFMT_1BYPP, /**< 8 bit per pixel 2_bbbggrrr. */ + dlo_pixfmt_rgb323 = 0 | DLO_PIXFMT_1BYPP | DLO_PIXFMT_SWP, /**< 8 bit per pixel 2_rrrggbbb. */ + dlo_pixfmt_bgr565 = 1 | DLO_PIXFMT_2BYPP, /**< 16 bit per pixel 2_bbbbbggggggrrrrr. */ + dlo_pixfmt_rgb565 = 1 | DLO_PIXFMT_2BYPP | DLO_PIXFMT_SWP, /**< 16 bit per pixel 2_rrrrrggggggbbbbb. */ + dlo_pixfmt_sbgr1555 = 2 | DLO_PIXFMT_2BYPP, /**< 16 bit per pixel 2_Sbbbbbgggggrrrrr (S is supremacy/transparancy bit). */ + dlo_pixfmt_srgb1555 = 2 | DLO_PIXFMT_2BYPP | DLO_PIXFMT_SWP, /**< 16 bit per pixel 2_Srrrrrgggggbbbbb (S is supremacy/transparancy bit). */ + dlo_pixfmt_bgr888 = 3 | DLO_PIXFMT_3BYPP, /**< 24 bit per pixel 0xbbggrr. */ + dlo_pixfmt_rgb888 = 3 | DLO_PIXFMT_3BYPP | DLO_PIXFMT_SWP, /**< 24 bit per pixel 0xrrggbb. */ + dlo_pixfmt_abgr8888 = 4 | DLO_PIXFMT_4BYPP, /**< 32 bit per pixel 0xaabbggrr. */ + dlo_pixfmt_argb8888 = 4 | DLO_PIXFMT_4BYPP | DLO_PIXFMT_SWP /**< 32 bit per pixel 0xaarrggbb. */ + /* Any value greater than 1023 is assumed to be a pointer to: dlo_col32_t palette[256] + * for translating paletted 8 bits per pixel data into colour numbers. + */ +} dlo_pixfmt_t; /**< A struct @a dlo_pixfmt_s. */ + + +/** A local (host-resident) bitmap or framebuffer. */ +typedef struct dlo_fbuf_s +{ + uint16_t width; /**< Width (pixels). */ + uint16_t height; /**< Height (pixels). */ + dlo_pixfmt_t fmt; /**< Pixel format (e.g. bits per pixel, colour component order, etc). */ + void *base; /**< Base address in host memory. */ + uint32_t stride; /**< Stride (pixels) from a pixel to the one directly below. */ +} dlo_fbuf_t; /**< A struct @a dlo_fbuf_s. */ + + +/** An pointer to a location in the DisplayLink device logical memory map. */ +typedef uint32_t dlo_ptr_t; + + +/** A viewport (bitmap) in a contiguous block of device memory. + * + * A viewport describes the contents of a contiguous block of device memory (of which there + * is normally 16 MB available). It represents a rectangular bitmap which may be large + * enough to use as a screen mode or of any other non-zero size. + * + * It is the responsibility of the caller to organise one or more viewports in the device + * memory and use the @c dlo_set_mode() call to determine which is visible on the screen + * at any given time. + * + * When a device is first claimed, the EDID data for any connected display will be + * read. If successful, then an initial screen mode is set up using the native mode timings + * of the display. This will result in an initial viewport being defined at base address 0. + * Details of the initial viewport can be discovered by the caller using the + * @c dlo_get_mode() call. If no initial mode was set up by libdlo, then the caller must do + * so by making an appropriate call to @c dlo_set_mode(). + * + * Setting the screen mode does not result in the screen being cleared; the caller must make + * a call to @c dlo_fill_rect() to achieve this, e.g. + * + * dlo_fill_rect(uid, NULL, NULL, DLO_RGB(0,0,0)) + * + * to clear the whole of the viewport for the current screen mode to black. + * + * Overlapping viewports should be avoided because they do not include the concept of a + * 'stride' (to get from one pixel to the pixel immediately below). They must also have a + * base address which starts on a two byte boundary. Aside from these constraints, viewports + * can be arranged at any locations within the device memory. + * + * The caller should not assume anything about the format of the pixels stored in the device + * memory or how pixels are arranged within a given viewport's address range. It is safe to + * assume that the pixels will require three bytes each (in a 24 bpp viewport) so a viewport + * which is 1280 x 1024 pixels in size, starting at base address 0x000000 in the device + * memory will end at address 1280*1024*3 = 0x3C0000. + * + * Thus, the caller may set up two screen banks by maintaining two viewports of the same + * dimensions, one starting at base address 0x000000 (for example) and another starting at + * base address 0x3C0000 (assuming they are 1280x1024 pixels in size). These two banks can + * be plotted to independently of each other and displayed using the @c dlo_set_mode() call. + */ +typedef struct dlo_view_s +{ + uint16_t width; /**< Width (pixels). */ + uint16_t height; /**< Height (pixels). */ + uint8_t bpp; /**< Colour depth (bits per pixel). */ + dlo_ptr_t base; /**< Base address in the device memory. */ +} dlo_view_t; /**< A struct @a dlo_view_s. */ + + +/** Descriptor for reading or setting the current screen mode. */ +typedef struct dlo_mode_s +{ + dlo_view_t view; /**< The @a dlo_view_t associated with the screen mode. */ + uint8_t refresh; /**< Refresh rate (Hz). */ +} dlo_mode_t; /**< A struct @a dlo_mode_s. */ + + +/** Co-ordinates of a point/pixel relative to the origin, top-left, of a given @a dlo_view_t. */ +typedef struct dlo_dot_s +{ + int32_t x; /**< X co-ordinate of the dot, pixels from left edge of screen (+ve is right). */ + int32_t y; /**< Y co-ordinate of the dot, pixels down from top edge of screen (-ve is up). */ +} dlo_dot_t; /**< A struct @a dlo_dot_s. */ + + +/** A rectangle relative to a given @a dlo_view_t. */ +typedef struct dlo_rect_s +{ + dlo_dot_t origin; /**< Origin co-ordinates (top-left of the rectangle). */ + uint16_t width; /**< Width (pixels) of rectangle (all pixels from origin.x to origin.x+width-1 inclusive). */ + uint16_t height; /**< Height (pixels) of rectangle (all pixels from origin.y to origin.x+height-1 inclusive). */ +} dlo_rect_t; /**< A struct @a dlo_rect_s. */ + + +/** Return the meaning of the specified return code as a human-readable string. + * + * @param err Return code. + * + * @return Pointer to zero-terminated (error) message string. + * + * The string is held in libdlo's static workspace so no attempt should be made + * by the caller to free it. + */ +extern const char *dlo_strerror(const dlo_retcode_t err); + + +/** Initialisation call for libdlo. + * + * @param flags Initialisation flags word (unused flags should be zero). + * + * @return Return code, zero for no error. + * + * This function must be called by libdlo users before any other functions + * are called or they may result in undefined behaviour. It will ignore any + * flag bits which it does not currently understand. + * + * The @a vsn value indicates the library API version number. As the API + * defined within this header file is evolved, the API version number will + * be incremented. + */ +extern dlo_retcode_t dlo_init(const dlo_init_t flags); + + +/** Finalisation call for libdlo. + * + * @param flags Finalisation flags word (unused flags should be zero). + * + * @return Return code, zero for no error. + * + * This function should be called when a program no longer needs to use libdlo + * (e.g. when it exits) in order to free up any system resources which have been + * claimed by this library. It will ignore any flag bits which it does not + * currently understand. + */ +extern dlo_retcode_t dlo_final(const dlo_final_t flags); + + +/** Map the caller's pointer to a udev structure from libusb to a unique ID in libdlo. + * + * @param udev Pointer to USB device structure for given device (from libusb). + * + * @return Unique ID of the corresponding device for libdlo calls. + * + * This call is intended for use by a caller that has already used libusb in order + * to identify a particular device that they want to connect to. + */ +extern dlo_dev_t dlo_lookup_device(struct usb_device *udev); + + +/** Enumerate all connected DisplayLink-compatible devices. + * + * @return Pointer to linked list of device information structures (or NULL if none). + * + * This function will return a pointer to one or more @a devlist_t structures if + * there are any active DisplayLink compatible devices connected to the computer. + * It will return a NULL pointer if none are found or if there was an error during + * the enumeration process. + * + * It is the caller's responsibility to free the memory associated with this list + * by calling the @c dlo_free() function on each list item (but not for any + * strings pointed to by items in the list, as these strings are maintained by + * libdlo). + */ +extern dlo_devlist_t *dlo_enumerate_devices(void); + + +/** Claim the specified device. + * + * @param uid Unique ID of the device to claim. + * @param flags Flags word describing how the device is to be accessed. + * @param timeout Timeout in milliseconds (zero for infinite). + * + * @return Unique ID of the claimed device (or NULL if failed). + * + * Before accessing a device, it should be claimed in order to avoid clashes + * where multiple programs are trying to write to the same device (however, + * abstraction of that sort would be implemented above this API). + * + * If the device is connected to a display which supports the EDID standard, then + * this call will also attempt to set up the display mode to the native resolution + * of the display - equivalent to a call to @c dlo_set_mode(). It will not clear + * the screen contents; you should call @c dlo_fill_rect() for that. + * + * It is possible to specify a @a timeout value for this call. If a non-zero timeout + * is specified, the same value will be used for any further calls to the device. + * Passing in a zero timeout means that libdlo should use its default timeouts. + * The @a timeout value is only used for specific transactions with the device; in + * some special cases libdlo will still use its own internal timeout values. + * + * Devices should be released with a call to @c release_device() when they are no + * longer required. + */ extern dlo_dev_t dlo_claim_device(const dlo_dev_t uid, const dlo_claim_t flags, const uint32_t timeout); @@ -632,150 +632,150 @@ extern dlo_dev_t dlo_claim_default_device(int *argc_p, char *argv[], /** Release the specified device. - *
- * @param uid Unique ID of the device to release.
- *
- * @return Return code, zero for no error.
- *
- * When a program is no longer interested in using a device which it earlier had
- * claimed, it should release it with this call. This should still be called even
- * in the case where communications with a device have failed (because the error
- * may have been temporary). You can ignore errors from this call if you wish.
- */
-extern dlo_retcode_t dlo_release_device(const dlo_dev_t uid);
-
-
-/** Given the device unique ID, return the associated device information structure.
- *
- * @param uid Unique ID of the device to access.
- *
- * @return Pointer to device information structure.
- *
- * Note: the caller should not attempt to free the returned structure as it is
- * maintained by libdlo.
- */
-extern dlo_devinfo_t *dlo_device_info(const dlo_dev_t uid);
-
-
-/** Set the screen mode by selecting the best matching mode available.
- *
- * @param uid Unique ID of the device to access.
- * @param mode Mode descriptor structure pointer.
- *
- * @return Return code, zero for no error.
- *
- * This function will select a screen mode from the list of those supported by
- * the specified device (if the display connected to a device supports EDID,
- * then the supported mode list will be derived from the EDID information).
- *
- * The @a mode parameter describes the desired mode parameters, some of which
- * are optional and may be left as zero/NULL:
- *
- * @li width in pixels (always required)
- * @li height in pixels (or zero to use first available of specified width)
- * @li colour depth in bits per pixel (currently, only 24 is supported)
- * @li base address in the device memory (of the origin of the mode's viewport)
- * @li refresh rate, in Hz (or zero to select the first available)
- *
- * This call will not cause the screen area to be cleared to a 'background'
- * colour.
- */
-extern dlo_retcode_t dlo_set_mode(const dlo_dev_t uid, const dlo_mode_t * const mode);
-
-
-/** Returns a block of information about the current screen mode.
- *
- * @param uid Unique ID of the device to access (or zero).
- *
- * @return Pointer to a mode description structure.
- *
- * This function will return a pointer to a structure describing the current
- * screen mode for the specified device. Note: if no mode has been set since
- * the device was claimed, this structure will be initialised to contain all
- * zeros.
- *
- * Note: the caller should not attempt to free the returned structure as it
- * is maintained by libdlo.
- */
-extern dlo_mode_t *dlo_get_mode(const dlo_dev_t uid);
-
-
-/** Plot a filled rectangle into the specified device.
- *
- * @param uid Unique ID of the device to access.
- * @param view Struct pointer: the destination viewport.
- * @param rec Struct pointer: co-ordinates of rectangle to plot (relative to viewport).
- * @param col Colour of filled rectangle.
- *
- * @return Return code, zero for no error.
- *
- * Plot a filled rectangle in the specified colour into a viewport on the device. The
- * rectangle specified is relative to the viewport's origin and will be clipped if any
- * parts of it lie outside of the viewport's extent. Setting both @a view and @a rec to
- * NULL will effectively clear the current screen to the specified colour.
- *
- * If @a view is NULL, then the current visible screen is used as the destination viewport.
- * If @a rec is NULL, then the whole of the destination viewport is filled.
- */
-extern dlo_retcode_t dlo_fill_rect(const dlo_dev_t uid,
- const dlo_view_t * const view, const dlo_rect_t * const rec,
- const dlo_col32_t col);
-
-
-/** Copy a rectangular area within the device from one location to another.
- *
- * @param uid Unique ID of the device to access.
- * @param src_view Struct pointer: source viewport.
- * @param src_rec Struct pointer: co-ordinates of rectangle to copy (relative to source viewport).
- * @param dest_view Struct pointer: destination viewport.
- * @param dest_pos Struct pointer: origin of copy destination (relative to destination viewport).
- *
- * @return Return code, zero for no error.
- *
- * Copy a rectangular area of pixels from one location in the device to another. The source
- * and destination rectangles may lie in the same viewport or different viewports - it is up
- * to the caller to maintain their own list of how the device memory is organised in terms of
- * viewports.
- *
- * The source and destination viewports must not reference overlapping memory regions in the
- * device, except in the case where both viewports describe exactly the same memory region.
- * There are no constraints relating to whether or not source and destination rectangles
- * overlap.
- *
- * If @a src_view is NULL, then the current visible screen is used as the source viewport.
- * If @a src_rec is NULL, then the whole of the source viewport is used as the source rectangle.
- * If @a dest_view is NULL, then the current visible screen is used as the destination viewport.
- * If @a dest_pos is NULL, then the origin (top-left) of the destination viewport is used.
- */
-extern dlo_retcode_t dlo_copy_rect(const dlo_dev_t uid,
- const dlo_view_t * const src_view, const dlo_rect_t * const src_rec,
- const dlo_view_t * const dest_view, const dlo_dot_t * const dest_pos);
-
-
-/** Copy (and translate pixel formats) a rectangular area from host memory into the device.
- *
- * @param uid Unique ID of the device to access.
- * @param flags Flags word indicating special behaviour (unused flags should be zero).
- * @param fbuf Struct pointer: information about source bitmap in host memory.
- * @param dest_view Struct pointer: destination viewport.
- * @param dest_pos Struct pointer: origin of copy destination (relative to destination viewport).
- *
- * @return Return code, zero for no error.
- *
- * Transfer a bitmap held in the host memory to the device. The bitmap is treated as a rectangular
- * area of pixels, possibly within a larger bitmap/framebuffer and will be plotted at the desired
- * co-ordinates relative to the origin of the specified viewport. If any part of the bitmap falls
- * outside of the viewport's extent, the region will be clipped.
- *
- * If @a dest_view is NULL, then the current visible screen is used as the destination viewport.
- * If @a dest_pos is NULL, then the origin (top-left) of the destination viewport is used.
- */
-extern dlo_retcode_t dlo_copy_host_bmp(const dlo_dev_t uid, const dlo_bmpflags_t flags,
- const dlo_fbuf_t * const fbuf,
- const dlo_view_t * const dest_view, const dlo_dot_t * const dest_pos);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif
+ * + * @param uid Unique ID of the device to release. + * + * @return Return code, zero for no error. + * + * When a program is no longer interested in using a device which it earlier had + * claimed, it should release it with this call. This should still be called even + * in the case where communications with a device have failed (because the error + * may have been temporary). You can ignore errors from this call if you wish. + */ +extern dlo_retcode_t dlo_release_device(const dlo_dev_t uid); + + +/** Given the device unique ID, return the associated device information structure. + * + * @param uid Unique ID of the device to access. + * + * @return Pointer to device information structure. + * + * Note: the caller should not attempt to free the returned structure as it is + * maintained by libdlo. + */ +extern dlo_devinfo_t *dlo_device_info(const dlo_dev_t uid); + + +/** Set the screen mode by selecting the best matching mode available. + * + * @param uid Unique ID of the device to access. + * @param mode Mode descriptor structure pointer. + * + * @return Return code, zero for no error. + * + * This function will select a screen mode from the list of those supported by + * the specified device (if the display connected to a device supports EDID, + * then the supported mode list will be derived from the EDID information). + * + * The @a mode parameter describes the desired mode parameters, some of which + * are optional and may be left as zero/NULL: + * + * @li width in pixels (always required) + * @li height in pixels (or zero to use first available of specified width) + * @li colour depth in bits per pixel (currently, only 24 is supported) + * @li base address in the device memory (of the origin of the mode's viewport) + * @li refresh rate, in Hz (or zero to select the first available) + * + * This call will not cause the screen area to be cleared to a 'background' + * colour. + */ +extern dlo_retcode_t dlo_set_mode(const dlo_dev_t uid, const dlo_mode_t * const mode); + + +/** Returns a block of information about the current screen mode. + * + * @param uid Unique ID of the device to access (or zero). + * + * @return Pointer to a mode description structure. + * + * This function will return a pointer to a structure describing the current + * screen mode for the specified device. Note: if no mode has been set since + * the device was claimed, this structure will be initialised to contain all + * zeros. + * + * Note: the caller should not attempt to free the returned structure as it + * is maintained by libdlo. + */ +extern dlo_mode_t *dlo_get_mode(const dlo_dev_t uid); + + +/** Plot a filled rectangle into the specified device. + * + * @param uid Unique ID of the device to access. + * @param view Struct pointer: the destination viewport. + * @param rec Struct pointer: co-ordinates of rectangle to plot (relative to viewport). + * @param col Colour of filled rectangle. + * + * @return Return code, zero for no error. + * + * Plot a filled rectangle in the specified colour into a viewport on the device. The + * rectangle specified is relative to the viewport's origin and will be clipped if any + * parts of it lie outside of the viewport's extent. Setting both @a view and @a rec to + * NULL will effectively clear the current screen to the specified colour. + * + * If @a view is NULL, then the current visible screen is used as the destination viewport. + * If @a rec is NULL, then the whole of the destination viewport is filled. + */ +extern dlo_retcode_t dlo_fill_rect(const dlo_dev_t uid, + const dlo_view_t * const view, const dlo_rect_t * const rec, + const dlo_col32_t col); + + +/** Copy a rectangular area within the device from one location to another. + * + * @param uid Unique ID of the device to access. + * @param src_view Struct pointer: source viewport. + * @param src_rec Struct pointer: co-ordinates of rectangle to copy (relative to source viewport). + * @param dest_view Struct pointer: destination viewport. + * @param dest_pos Struct pointer: origin of copy destination (relative to destination viewport). + * + * @return Return code, zero for no error. + * + * Copy a rectangular area of pixels from one location in the device to another. The source + * and destination rectangles may lie in the same viewport or different viewports - it is up + * to the caller to maintain their own list of how the device memory is organised in terms of + * viewports. + * + * The source and destination viewports must not reference overlapping memory regions in the + * device, except in the case where both viewports describe exactly the same memory region. + * There are no constraints relating to whether or not source and destination rectangles + * overlap. + * + * If @a src_view is NULL, then the current visible screen is used as the source viewport. + * If @a src_rec is NULL, then the whole of the source viewport is used as the source rectangle. + * If @a dest_view is NULL, then the current visible screen is used as the destination viewport. + * If @a dest_pos is NULL, then the origin (top-left) of the destination viewport is used. + */ +extern dlo_retcode_t dlo_copy_rect(const dlo_dev_t uid, + const dlo_view_t * const src_view, const dlo_rect_t * const src_rec, + const dlo_view_t * const dest_view, const dlo_dot_t * const dest_pos); + + +/** Copy (and translate pixel formats) a rectangular area from host memory into the device. + * + * @param uid Unique ID of the device to access. + * @param flags Flags word indicating special behaviour (unused flags should be zero). + * @param fbuf Struct pointer: information about source bitmap in host memory. + * @param dest_view Struct pointer: destination viewport. + * @param dest_pos Struct pointer: origin of copy destination (relative to destination viewport). + * + * @return Return code, zero for no error. + * + * Transfer a bitmap held in the host memory to the device. The bitmap is treated as a rectangular + * area of pixels, possibly within a larger bitmap/framebuffer and will be plotted at the desired + * co-ordinates relative to the origin of the specified viewport. If any part of the bitmap falls + * outside of the viewport's extent, the region will be clipped. + * + * If @a dest_view is NULL, then the current visible screen is used as the destination viewport. + * If @a dest_pos is NULL, then the origin (top-left) of the destination viewport is used. + */ +extern dlo_retcode_t dlo_copy_host_bmp(const dlo_dev_t uid, const dlo_bmpflags_t flags, + const dlo_fbuf_t * const fbuf, + const dlo_view_t * const dest_view, const dlo_dot_t * const dest_pos); + +#ifdef __cplusplus +}; +#endif + +#endif |