summaryrefslogtreecommitdiff
path: root/tests/util.c
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2013-10-18 14:51:33 +0300
committerAlon Levy <alevy@redhat.com>2013-10-20 00:31:32 +0300
commit11ddba4b09bc2e3024cfd1c9f0d78948d004bb40 (patch)
treec1cf1dc0c1cf16352efde5fba7ca081b429dcceb /tests/util.c
parent421cfdab3bc123c7a8d31946be2b6b6e34ac0e0a (diff)
channel-cursor: mono cursors edge highlighting
Fix 998529, mono (invert) cursors not visible on a black background, by doing simple edge detection on the cursor (this is done once when the cursor is changed and then cached, cursors are 32x32 generally) and thus having a cursor with contrast on both dark and light backgrounds. When (if) GDK gets invert cursor support (wayland?) then we can just use the cursor as is. Until then X doesn't provide any way I see of solving this otherwise. The end result was tested with the I beam cursor that the original bug was referring to (run putty on a windows 7 vm) and looks ok to me. Moving the core function to spice-util for testing.
Diffstat (limited to 'tests/util.c')
-rw-r--r--tests/util.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/tests/util.c b/tests/util.c
index 86109aa..922818a 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -78,12 +78,129 @@ static void test_unix2dos(void)
}
}
+static const struct {
+ unsigned width;
+ unsigned height;
+ guint8 *and;
+ guint8 *xor;
+ guint8 *dest;
+} mono[] = {
+ {
+ 8, 6,
+ "11111111"
+ "11111111"
+ "11111111"
+ "11111111"
+ "11111111"
+ "11111111"
+ ,
+ "00000000"
+ "00000000"
+ "00000100"
+ "00000100"
+ "00000000"
+ "00000000"
+ ,
+ "0000" "0000" "0000" "0000" "0000" "0000" "0000" "0000"
+ "0000" "0000" "0000" "0000" "0001" "0001" "0001" "0000"
+ "0000" "0000" "0000" "0000" "0001" "1111" "0001" "0000"
+ "0000" "0000" "0000" "0000" "0001" "1111" "0001" "0000"
+ "0000" "0000" "0000" "0000" "0001" "0001" "0001" "0000"
+ "0000" "0000" "0000" "0000" "0000" "0000" "0000" "0000"
+ }
+};
+
+static void set_bit(guint8 *d, unsigned bit, unsigned value)
+{
+ if (value) {
+ *d |= (0x80 >> bit);
+ } else {
+ *d &= ~(0x80 >> bit);
+ }
+}
+
+static void test_set_bit(void)
+{
+ struct {
+ unsigned len;
+ guint8 *src;
+ guint8 *dest;
+ } tests[] = {
+ {
+ 4,
+ "1111",
+ "\xf0",
+ },
+ {
+ 16,
+ "1111011100110001",
+ "\xf7\x31",
+ }
+ };
+ int i, j, bit;
+ guint8 *dest;
+ int bytes;
+
+ for (i = 0 ; i < G_N_ELEMENTS(tests); ++i) {
+ bytes = (tests[i].len + 7) / 8;
+ dest = g_malloc0(bytes);
+ for (j = 0 ; j < tests[i].len;) {
+ for (bit = 0 ; bit < 8 && j < tests[i].len; ++bit, ++j) {
+ set_bit(&dest[j / 8], bit, tests[i].src[j] == '0' ? 0 : 1);
+ }
+ }
+ for (j = 0 ; j < bytes; ++j) {
+ g_assert(dest[j] == tests[i].dest[j]);
+ }
+ g_free(dest);
+ }
+}
+
+static void test_mono_edge_highlight(void)
+{
+ int i, j, bit;
+ guint8 *and;
+ guint8 *xor;
+ guint8 *dest;
+ guint8 *dest_correct;
+ int size, pixels;
+
+ test_set_bit();
+
+ for (i = 0 ; i < G_N_ELEMENTS(mono); ++i) {
+ pixels = mono[i].width * mono[i].height;
+ size = (pixels + 7) / 8;
+ and = g_malloc0(size);
+ xor = g_malloc0(size);
+ dest = g_malloc0(pixels * 4);
+ dest_correct = g_malloc(pixels * 4);
+ for (j = 0 ; j < pixels;) {
+ for (bit = 0; bit < 8 && j < pixels; ++bit, ++j) {
+ set_bit(&and[j / 8], bit, mono[i].and[j] == '0' ? 0 : 1);
+ set_bit(&xor[j / 8], bit, mono[i].xor[j] == '0' ? 0 : 1);
+ }
+ }
+ for (j = 0 ; j < pixels * 4 ; ++j) {
+ dest_correct[j] = mono[i].dest[j] == '0' ? 0x00 : 0xff;
+ }
+ spice_mono_edge_highlight(mono[i].width, mono[i].height, and, xor, dest);
+ for (j = 0; j < pixels; ++j) {
+ g_assert(dest[j] == dest_correct[j]);
+ }
+ g_free(and);
+ g_free(xor);
+ g_free(dest);
+ g_free(dest_correct);
+ }
+}
+
int main(int argc, char* argv[])
{
g_test_init(&argc, &argv, NULL);
g_test_add_func("/util/dos2unix", test_dos2unix);
g_test_add_func("/util/unix2dos", test_unix2dos);
+ g_test_add_func("/util/mono_edge_highlight", test_mono_edge_highlight);
return g_test_run ();
}