summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile27
-rw-r--r--tests/Makefile.am29
-rw-r--r--tests/auth.c137
-rw-r--r--tests/drmtest.c83
-rw-r--r--tests/drmtest.h37
-rw-r--r--tests/getclient.c60
-rw-r--r--tests/getstats.c51
-rw-r--r--tests/getversion.c47
-rw-r--r--tests/lock.c263
-rw-r--r--tests/mode/Makefile11
-rw-r--r--tests/mode/modetest.c337
-rwxr-xr-xtests/mode/test1
-rw-r--r--tests/openclose.c37
-rw-r--r--tests/setversion.c84
-rw-r--r--tests/updatedraw.c148
15 files changed, 1325 insertions, 27 deletions
diff --git a/tests/Makefile b/tests/Makefile
deleted file mode 100644
index b406e0ad..00000000
--- a/tests/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-
-# These definitions are for handling dependencies in the out of kernel build.
-
-PROGS = dristat drmstat
-
-CLEANFILES = *.o *.ko $(PROGS) .depend .*.flags .*.d
-
-# Build test utilities
-
-PRGCFLAGS = $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \
- -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \
- -I. -I../libdrm -I../shared-core
-
-DRMSTATLIBS = -L../libdrm -ldrm
-
-
-programs: $(PROGS)
-
-dristat: dristat.c
- $(CC) $(PRGCFLAGS) $< -o $@
-
-drmstat: drmstat.c
- $(CC) $(PRGCFLAGS) $< -o $@ $(DRMSTATLIBS)
-
-clean:
- rm -f $(CLEANFILES)
-
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 00000000..dce1754e
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,29 @@
+AM_CFLAGS = \
+ -I $(top_srcdir)/shared-core \
+ -I $(top_srcdir)/libdrm
+
+noinst_PROGRAMS = \
+ dristat \
+ drmstat
+
+EXTRA_LTLIBRARIES = libdrmtest.la
+libdrmtest_la_SOURCES = \
+ drmtest.c \
+ drmtest.h
+libdrmtest_la_LIBADD = \
+ $(top_builddir)/libdrm/libdrm.la
+
+LDADD = libdrmtest.la
+
+TESTS = auth \
+ openclose \
+ getversion \
+ getclient \
+ getstats \
+ lock \
+ setversion \
+ updatedraw
+
+EXTRA_PROGRAMS = $(TESTS)
+CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LTLIBRARIES)
+
diff --git a/tests/auth.c b/tests/auth.c
new file mode 100644
index 00000000..9b6fca94
--- /dev/null
+++ b/tests/auth.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <limits.h>
+#include "drmtest.h"
+
+enum auth_event {
+ SERVER_READY,
+ CLIENT_MAGIC,
+ CLIENT_DONE,
+};
+
+int commfd[2];
+
+static void wait_event(int pipe, enum auth_event expected_event)
+{
+ int ret;
+ enum auth_event event;
+ unsigned char in;
+
+ ret = read(commfd[pipe], &in, 1);
+ if (ret == -1)
+ err(1, "read error");
+ event = in;
+
+ if (event != expected_event)
+ errx(1, "unexpected event: %d\n", event);
+}
+
+static void
+send_event(int pipe, enum auth_event send_event)
+{
+ int ret;
+ unsigned char event;
+
+ event = send_event;
+ ret = write(commfd[pipe], &event, 1);
+ if (ret == -1)
+ err(1, "failed to send event %d", event);
+}
+
+static void client()
+{
+ struct drm_auth auth;
+ int drmfd, ret;
+
+ /* XXX: Should make sure we open the same DRM as the master */
+ wait_event(0, SERVER_READY);
+
+ drmfd = drm_open_any();
+
+ /* Get a client magic number and pass it to the master for auth. */
+ auth.magic = 0; /* Quiet valgrind */
+ ret = ioctl(drmfd, DRM_IOCTL_GET_MAGIC, &auth);
+ if (ret == -1)
+ err(1, "Couldn't get client magic");
+ send_event(0, CLIENT_MAGIC);
+ ret = write(commfd[0], &auth.magic, sizeof(auth.magic));
+ if (ret == -1)
+ err(1, "Couldn't write auth data");
+
+ /* Signal that the client is completely done. */
+ send_event(0, CLIENT_DONE);
+}
+
+static void server()
+{
+ int drmfd, ret;
+ struct drm_auth auth;
+
+ drmfd = drm_open_any_master();
+
+ auth.magic = 0xd0d0d0d0;
+ ret = ioctl(drmfd, DRM_IOCTL_AUTH_MAGIC, &auth);
+ if (ret != -1 || errno != EINVAL)
+ errx(1, "Authenticating bad magic succeeded\n");
+
+ send_event(1, SERVER_READY);
+
+ wait_event(1, CLIENT_MAGIC);
+ ret = read(commfd[1], &auth.magic, sizeof(auth.magic));
+ if (ret == -1)
+ err(1, "Failure to read client magic");
+
+ ret = ioctl(drmfd, DRM_IOCTL_AUTH_MAGIC, &auth);
+ if (ret == -1)
+ err(1, "Failure to authenticate client magic\n");
+
+ wait_event(1, CLIENT_DONE);
+}
+
+/**
+ * Checks DRM authentication mechanisms.
+ */
+int main(int argc, char **argv)
+{
+ int ret;
+
+ ret = pipe(commfd);
+ if (ret == -1)
+ err(1, "Couldn't create pipe");
+
+ ret = fork();
+ if (ret == -1)
+ err(1, "failure to fork client");
+ if (ret == 0)
+ client();
+ else
+ server();
+
+ return 0;
+}
+
diff --git a/tests/drmtest.c b/tests/drmtest.c
new file mode 100644
index 00000000..cae99a0c
--- /dev/null
+++ b/tests/drmtest.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <fcntl.h>
+#include "drmtest.h"
+
+/** Open the first DRM device we can find, searching up to 16 device nodes */
+int drm_open_any(void)
+{
+ char name[20];
+ int i, fd;
+
+ for (i = 0; i < 16; i++) {
+ sprintf(name, "/dev/dri/card%d", i);
+ fd = open(name, O_RDWR);
+ if (fd != -1)
+ return fd;
+ }
+ abort();
+}
+
+
+/**
+ * Open the first DRM device we can find where we end up being the master.
+ */
+int drm_open_any_master(void)
+{
+ char name[20];
+ int i, fd;
+
+ for (i = 0; i < 16; i++) {
+ drm_client_t client;
+ int ret;
+
+ sprintf(name, "/dev/dri/card%d", i);
+ fd = open(name, O_RDWR);
+ if (fd == -1)
+ continue;
+
+ /* Check that we're the only opener and authed. */
+ client.idx = 0;
+ ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
+ assert (ret == 0);
+ if (!client.auth) {
+ close(fd);
+ continue;
+ }
+ client.idx = 1;
+ ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
+ if (ret != -1 || errno != EINVAL) {
+ close(fd);
+ continue;
+ }
+ return fd;
+ }
+ fprintf(stderr, "Couldn't find an un-controlled DRM device\n");
+ abort();
+}
+
diff --git a/tests/drmtest.h b/tests/drmtest.h
new file mode 100644
index 00000000..afa0df4a
--- /dev/null
+++ b/tests/drmtest.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "xf86drm.h"
+
+int drm_open_any(void);
+int drm_open_any_master(void);
diff --git a/tests/getclient.c b/tests/getclient.c
new file mode 100644
index 00000000..349c16ec
--- /dev/null
+++ b/tests/getclient.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <limits.h>
+#include "drmtest.h"
+
+/**
+ * Checks DRM_IOCTL_GET_CLIENT.
+ */
+int main(int argc, char **argv)
+{
+ int fd, ret;
+ drm_client_t client;
+
+ fd = drm_open_any();
+
+ /* Look for client index 0. This should exist whether we're operating
+ * on an otherwise unused drm device, or the X Server is running on
+ * the device.
+ */
+ client.idx = 0;
+ ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
+ assert(ret == 0);
+
+ /* Look for some absurd client index and make sure it's invalid.
+ * The DRM drivers currently always return data, so the user has
+ * no real way to detect when the list has terminated. That's bad,
+ * and this test is XFAIL as a result.
+ */
+ client.idx = 0x7fffffff;
+ ret = ioctl(fd, DRM_IOCTL_GET_CLIENT, &client);
+ assert(ret == -1 && errno == EINVAL);
+
+ close(fd);
+ return 0;
+}
diff --git a/tests/getstats.c b/tests/getstats.c
new file mode 100644
index 00000000..bd55b12e
--- /dev/null
+++ b/tests/getstats.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <limits.h>
+#include "drmtest.h"
+
+/**
+ * Checks DRM_IOCTL_GET_STATS.
+ *
+ * I don't care too much about the actual contents, just that the kernel
+ * doesn't crash.
+ */
+int main(int argc, char **argv)
+{
+ int fd, ret;
+ drm_stats_t stats;
+
+ fd = drm_open_any();
+
+ ret = ioctl(fd, DRM_IOCTL_GET_STATS, &stats);
+ assert(ret == 0);
+
+ assert(stats.count >= 0);
+
+ close(fd);
+ return 0;
+}
diff --git a/tests/getversion.c b/tests/getversion.c
new file mode 100644
index 00000000..3de90de6
--- /dev/null
+++ b/tests/getversion.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include "drmtest.h"
+
+/**
+ * Checks DRM_IOCTL_GET_VERSION and libdrm's drmGetVersion() interface to it.
+ */
+int main(int argc, char **argv)
+{
+ int fd;
+ drmVersionPtr v;
+
+ fd = drm_open_any();
+ v = drmGetVersion(fd);
+ assert(strlen(v->name) != 0);
+ assert(strlen(v->date) != 0);
+ assert(strlen(v->desc) != 0);
+ assert(v->version_major >= 1);
+ drmFree(v);
+ close(fd);
+ return 0;
+}
diff --git a/tests/lock.c b/tests/lock.c
new file mode 100644
index 00000000..86caa281
--- /dev/null
+++ b/tests/lock.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/** @file lock.c
+ * Tests various potential failures of the DRM locking mechanisms
+ */
+
+#include <limits.h>
+#include "drmtest.h"
+
+enum auth_event {
+ SERVER_READY,
+ CLIENT_MAGIC,
+ SERVER_LOCKED,
+ CLIENT_LOCKED,
+};
+
+int commfd[2];
+unsigned int lock1 = 0x00001111;
+unsigned int lock2 = 0x00002222;
+
+/* return time in milliseconds */
+static unsigned int
+get_millis()
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+static void
+wait_event(int pipe, enum auth_event expected_event)
+{
+ int ret;
+ enum auth_event event;
+ unsigned char in;
+
+ ret = read(commfd[pipe], &in, 1);
+ if (ret == -1)
+ err(1, "read error");
+ event = in;
+
+ if (event != expected_event)
+ errx(1, "unexpected event: %d\n", event);
+}
+
+static void
+send_event(int pipe, enum auth_event send_event)
+{
+ int ret;
+ unsigned char event;
+
+ event = send_event;
+ ret = write(commfd[pipe], &event, 1);
+ if (ret == -1)
+ err(1, "failed to send event %d", event);
+}
+
+static void
+client_auth(int drmfd)
+{
+ struct drm_auth auth;
+ int ret;
+
+ /* Get a client magic number and pass it to the master for auth. */
+ ret = ioctl(drmfd, DRM_IOCTL_GET_MAGIC, &auth);
+ if (ret == -1)
+ err(1, "Couldn't get client magic");
+ send_event(0, CLIENT_MAGIC);
+ ret = write(commfd[0], &auth.magic, sizeof(auth.magic));
+ if (ret == -1)
+ err(1, "Couldn't write auth data");
+}
+
+static void
+server_auth(int drmfd)
+{
+ struct drm_auth auth;
+ int ret;
+
+ send_event(1, SERVER_READY);
+ wait_event(1, CLIENT_MAGIC);
+ ret = read(commfd[1], &auth.magic, sizeof(auth.magic));
+ if (ret == -1)
+ err(1, "Failure to read client magic");
+
+ ret = ioctl(drmfd, DRM_IOCTL_AUTH_MAGIC, &auth);
+ if (ret == -1)
+ err(1, "Failure to authenticate client magic\n");
+}
+
+/** Tests that locking is successful in normal conditions */
+static void
+test_lock_unlock(int drmfd)
+{
+ int ret;
+
+ ret = drmGetLock(drmfd, lock1, 0);
+ if (ret != 0)
+ err(1, "Locking failed");
+ ret = drmUnlock(drmfd, lock1);
+ if (ret != 0)
+ err(1, "Unlocking failed");
+}
+
+/** Tests that unlocking the lock while it's not held works correctly */
+static void
+test_unlock_unlocked(int drmfd)
+{
+ int ret;
+
+ ret = drmUnlock(drmfd, lock1);
+ if (ret == 0)
+ err(1, "Unlocking unlocked lock succeeded");
+}
+
+/** Tests that unlocking a lock held by another context fails appropriately */
+static void
+test_unlock_unowned(int drmfd)
+{
+ int ret;
+
+ ret = drmGetLock(drmfd, lock1, 0);
+ assert(ret == 0);
+ ret = drmUnlock(drmfd, lock2);
+ if (ret == 0)
+ errx(1, "Unlocking other context's lock succeeded");
+ ret = drmUnlock(drmfd, lock1);
+ assert(ret == 0);
+}
+
+/**
+ * Tests that an open/close by the same process doesn't result in the lock
+ * being dropped.
+ */
+static void test_open_close_locked(drmfd)
+{
+ int ret, tempfd;
+
+ ret = drmGetLock(drmfd, lock1, 0);
+ assert(ret == 0);
+ /* XXX: Need to make sure that this is the same device as drmfd */
+ tempfd = drm_open_any();
+ close(tempfd);
+ ret = drmUnlock(drmfd, lock1);
+ if (ret != 0)
+ errx(1, "lock lost during open/close by same pid");
+}
+
+static void client()
+{
+ int drmfd, ret;
+ unsigned int time;
+
+ wait_event(0, SERVER_READY);
+
+ /* XXX: Should make sure we open the same DRM as the master */
+ drmfd = drm_open_any();
+
+ client_auth(drmfd);
+
+ /* Wait for the server to grab the lock, then grab it ourselves (to
+ * contest it). Hopefully we hit it within the window of when the
+ * server locks.
+ */
+ wait_event(0, SERVER_LOCKED);
+ ret = drmGetLock(drmfd, lock2, 0);
+ time = get_millis();
+ if (ret != 0)
+ err(1, "Failed to get lock on client\n");
+ drmUnlock(drmfd, lock2);
+
+ /* Tell the server that our locking completed, and when it did */
+ send_event(0, CLIENT_LOCKED);
+ ret = write(commfd[0], &time, sizeof(time));
+
+ close(drmfd);
+ exit(0);
+}
+
+static void server()
+{
+ int drmfd, tempfd, ret;
+ unsigned int client_time, unlock_time;
+
+ drmfd = drm_open_any_master();
+
+ test_lock_unlock(drmfd);
+ test_unlock_unlocked(drmfd);
+ test_unlock_unowned(drmfd);
+ test_open_close_locked(drmfd);
+
+ /* Perform the authentication sequence with the client. */
+ server_auth(drmfd);
+
+ /* Now, test that the client attempting to lock while the server
+ * holds the lock works correctly.
+ */
+ ret = drmGetLock(drmfd, lock1, 0);
+ assert(ret == 0);
+ send_event(1, SERVER_LOCKED);
+ /* Wait a while for the client to do its thing */
+ sleep(1);
+ ret = drmUnlock(drmfd, lock1);
+ assert(ret == 0);
+ unlock_time = get_millis();
+
+ wait_event(1, CLIENT_LOCKED);
+ ret = read(commfd[1], &client_time, sizeof(client_time));
+ if (ret == -1)
+ err(1, "Failure to read client magic");
+
+ if (client_time < unlock_time)
+ errx(1, "Client took lock before server released it");
+
+ close(drmfd);
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+
+ ret = pipe(commfd);
+ if (ret == -1)
+ err(1, "Couldn't create pipe");
+
+ ret = fork();
+ if (ret == -1)
+ err(1, "failure to fork client");
+ if (ret == 0)
+ client();
+ else
+ server();
+
+ return 0;
+}
+
diff --git a/tests/mode/Makefile b/tests/mode/Makefile
new file mode 100644
index 00000000..205c2ba1
--- /dev/null
+++ b/tests/mode/Makefile
@@ -0,0 +1,11 @@
+
+all: modetest
+
+#CFLAGS = -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \
+# -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \
+
+modetest: modetest.c
+ @gcc -o modetest -Wall -I../../libdrm -I../../shared-core -L../../libdrm/.libs -ldrm modetest.c
+
+clean:
+ @rm -f modetest
diff --git a/tests/mode/modetest.c b/tests/mode/modetest.c
new file mode 100644
index 00000000..bf1a5169
--- /dev/null
+++ b/tests/mode/modetest.c
@@ -0,0 +1,337 @@
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "xf86drm.h"
+#include "xf86drmMode.h"
+
+const char* getConnectionText(drmModeConnection conn)
+{
+ switch (conn) {
+ case DRM_MODE_CONNECTED:
+ return "connected";
+ case DRM_MODE_DISCONNECTED:
+ return "disconnected";
+ default:
+ return "unknown";
+ }
+
+}
+
+struct drm_mode_modeinfo* findMode(drmModeResPtr res, uint32_t id)
+{
+ int i;
+ for (i = 0; i < res->count_modes; i++) {
+ if (res->modes[i].id == id)
+ return &res->modes[i];
+ }
+
+ return 0;
+}
+
+int printMode(struct drm_mode_modeinfo *mode)
+{
+#if 0
+ printf("Mode: %s\n", mode->name);
+ printf("\tclock : %i\n", mode->clock);
+ printf("\thdisplay : %i\n", mode->hdisplay);
+ printf("\thsync_start : %i\n", mode->hsync_start);
+ printf("\thsync_end : %i\n", mode->hsync_end);
+ printf("\thtotal : %i\n", mode->htotal);
+ printf("\thskew : %i\n", mode->hskew);
+ printf("\tvdisplay : %i\n", mode->vdisplay);
+ printf("\tvsync_start : %i\n", mode->vsync_start);
+ printf("\tvsync_end : %i\n", mode->vsync_end);
+ printf("\tvtotal : %i\n", mode->vtotal);
+ printf("\tvscan : %i\n", mode->vscan);
+ printf("\tvrefresh : %i\n", mode->vrefresh);
+ printf("\tflags : %i\n", mode->flags);
+#else
+ printf("Mode: %i \"%s\" %ix%i %.0f\n", mode->id, mode->name,
+ mode->hdisplay, mode->vdisplay, mode->vrefresh / 1000.0);
+#endif
+ return 0;
+}
+
+int printOutput(int fd, drmModeResPtr res, drmModeOutputPtr output, uint32_t id)
+{
+ int i = 0;
+ struct drm_mode_modeinfo *mode = NULL;
+
+ printf("Output: %s\n", output->name);
+ printf("\tid : %i\n", id);
+ printf("\tcrtc id : %i\n", output->crtc);
+ printf("\tconn : %s\n", getConnectionText(output->connection));
+ printf("\tsize : %ix%i (mm)\n", output->mmWidth, output->mmHeight);
+ printf("\tcount_crtcs : %i\n", output->count_crtcs);
+ printf("\tcrtcs : %i\n", output->crtcs);
+ printf("\tcount_clones : %i\n", output->count_clones);
+ printf("\tclones : %i\n", output->clones);
+ printf("\tcount_modes : %i\n", output->count_modes);
+
+ for (i = 0; i < output->count_modes; i++) {
+ mode = findMode(res, output->modes[i]);
+
+ if (mode)
+ printf("\t\tmode: %i \"%s\" %ix%i %.0f\n", mode->id, mode->name,
+ mode->hdisplay, mode->vdisplay, mode->vrefresh / 1000.0);
+ else
+ printf("\t\tmode: Invalid mode %i\n", output->modes[i]);
+ }
+
+ return 0;
+}
+
+int printCrtc(int fd, drmModeResPtr res, drmModeCrtcPtr crtc, uint32_t id)
+{
+ printf("Crtc\n");
+ printf("\tid : %i\n", id);
+ printf("\tx : %i\n", crtc->x);
+ printf("\ty : %i\n", crtc->y);
+ printf("\twidth : %i\n", crtc->width);
+ printf("\theight : %i\n", crtc->height);
+ printf("\tmode : %i\n", crtc->mode);
+ printf("\tnum outputs : %i\n", crtc->count_outputs);
+ printf("\toutputs : %i\n", crtc->outputs);
+ printf("\tnum possible : %i\n", crtc->count_possibles);
+ printf("\tpossibles : %i\n", crtc->possibles);
+
+ return 0;
+}
+
+int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb)
+{
+ printf("Framebuffer\n");
+ printf("\thandle : %i\n", fb->handle);
+ printf("\twidth : %i\n", fb->width);
+ printf("\theight : %i\n", fb->height);
+ printf("\tpitch : %i\n", fb->pitch);;
+ printf("\tbpp : %i\n", fb->bpp);
+ printf("\tdepth : %i\n", fb->depth);
+ printf("\tbuffer_id : %i\n", fb->buffer_id);
+
+ return 0;
+}
+
+int printRes(int fd, drmModeResPtr res)
+{
+ int i;
+ drmModeOutputPtr output;
+ drmModeCrtcPtr crtc;
+ drmModeFBPtr fb;
+
+ for (i = 0; i < res->count_modes; i++) {
+ printMode(&res->modes[i]);
+ }
+
+ for (i = 0; i < res->count_outputs; i++) {
+ output = drmModeGetOutput(fd, res->outputs[i]);
+
+ if (!output)
+ printf("Could not get output %i\n", i);
+ else {
+ printOutput(fd, res, output, res->outputs[i]);
+ drmModeFreeOutput(output);
+ }
+ }
+
+ for (i = 0; i < res->count_crtcs; i++) {
+ crtc = drmModeGetCrtc(fd, res->crtcs[i]);
+
+ if (!crtc)
+ printf("Could not get crtc %i\n", i);
+ else {
+ printCrtc(fd, res, crtc, res->crtcs[i]);
+ drmModeFreeCrtc(crtc);
+ }
+ }
+
+ for (i = 0; i < res->count_fbs; i++) {
+ fb = drmModeGetFB(fd, res->fbs[i]);
+
+ if (!fb)
+ printf("Could not get fb %i\n", res->fbs[i]);
+ else {
+ printFrameBuffer(fd, res, fb);
+ drmModeFreeFB(fb);
+ }
+ }
+
+ return 0;
+}
+
+static struct drm_mode_modeinfo mode = {
+ .name = "Test mode",
+ .clock = 25200,
+ .hdisplay = 640,
+ .hsync_start = 656,
+ .hsync_end = 752,
+ .htotal = 800,
+ .hskew = 0,
+ .vdisplay = 480,
+ .vsync_start = 490,
+ .vsync_end = 492,
+ .vtotal = 525,
+ .vscan = 0,
+ .vrefresh = 60000, /* vertical refresh * 1000 */
+ .flags = 10,
+};
+
+int testMode(int fd, drmModeResPtr res)
+{
+ uint32_t output = res->outputs[0];
+ uint32_t newMode = 0;
+ int ret = 0;
+ int error = 0;
+
+ printf("Test: adding mode to output %i\n", output);
+
+ /* printMode(&mode); */
+
+ printf("\tAdding mode\n");
+ newMode = drmModeAddMode(fd, &mode);
+ if (!newMode)
+ goto err;
+
+ printf("\tAttaching mode %i to output %i\n", newMode, output);
+
+ ret = drmModeAttachMode(fd, output, newMode);
+
+ if (ret)
+ goto err_mode;
+
+ printf("\tDetaching mode %i from output %i\n", newMode, output);
+ ret = drmModeDetachMode(fd, output, newMode);
+
+ if (ret)
+ goto err_mode;
+
+ printf("\tRemoveing new mode %i\n", newMode);
+ ret = drmModeRmMode(fd, newMode);
+ if (ret)
+ goto err;
+
+ return 0;
+
+err_mode:
+ error = drmModeRmMode(fd, newMode);
+
+err:
+ printf("\tFailed\n");
+
+ if (error)
+ printf("\tFailed to delete mode %i\n", newMode);
+
+ return 1;
+}
+
+/*
+int testFrameBufferGet(int fd, uint32_t fb)
+{
+ drmModeFBPtr frame;
+
+ printf("Test: get framebuffer %i\n", fb);
+
+ frame = drmModeGetFB(fd, fb);
+
+ if (!frame) {
+ printf("\tFailed\n");
+ } else {
+ printFrameBuffer(fd, frame);
+ drmModeFreeFB(frame);
+ }
+
+ return 0;
+}
+*/
+
+int testFrameBufferAdd(int fd, drmModeResPtr res)
+{
+ uint32_t fb = 0;
+ int ret = 0;
+ drmModeFBPtr frame = 0;
+ drmBO bo;
+
+ printf("Test: adding framebuffer\n");
+
+ printf("\tCreating BO\n");
+
+ /* TODO */
+ ret = 1;
+ if (ret)
+ goto err;
+
+ printf("\tAdding FB\n");
+ ret = drmModeAddFB(fd, 640, 480, 32, 8, 0, &bo, &fb);
+ if (ret)
+ goto err_bo;
+
+ frame = drmModeGetFB(fd, fb);
+
+ if (!frame) {
+ printf("Couldn't retrive created framebuffer\n");
+ } else {
+ printFrameBuffer(fd, res, frame);
+ drmModeFreeFB(frame);
+ }
+
+ printf("\tRemoveing FB\n");
+
+ ret = drmModeRmFB(fd, fb);
+
+ if (ret) {
+ printf("\tFailed this shouldn't happen!\n");
+ goto err_bo;
+ }
+
+ printf("\tRemoveing BO\n");
+
+ ret = drmBODestroy(fb, &bo);
+
+ return 0;
+
+err_bo:
+ drmBODestroy(fd, &bo);
+
+err:
+ printf("\tFailed\n");
+
+ return 1;
+}
+
+
+int main(int argc, char **argv)
+{
+ int fd;
+ const char *driver = "i915"; /* hardcoded for now */
+ drmModeResPtr res;
+
+ printf("Starting test\n");
+
+ fd = drmOpen(driver, NULL);
+
+ if (fd < 0) {
+ printf("Failed to open the card fb\n");
+ return 1;
+ }
+
+ res = drmModeGetResources(fd);
+ if (res == 0) {
+ printf("Failed to get resources from card\n");
+ drmClose(fd);
+ return 1;
+ }
+
+ printRes(fd, res);
+
+ testMode(fd, res);
+
+ testFrameBufferAdd(fd, res);
+
+ drmModeFreeResources(res);
+ printf("Ok\n");
+
+ return 0;
+}
diff --git a/tests/mode/test b/tests/mode/test
new file mode 100755
index 00000000..fa155f4e
--- /dev/null
+++ b/tests/mode/test
@@ -0,0 +1 @@
+LD_PRELOAD=../../libdrm/.libs/libdrm.so ./modetest
diff --git a/tests/openclose.c b/tests/openclose.c
new file mode 100644
index 00000000..946a4459
--- /dev/null
+++ b/tests/openclose.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include "drmtest.h"
+
+int main(int argc, char **argv)
+{
+ int fd;
+
+ fd = drm_open_any();
+ close(fd);
+ return 0;
+}
diff --git a/tests/setversion.c b/tests/setversion.c
new file mode 100644
index 00000000..f4bfbfba
--- /dev/null
+++ b/tests/setversion.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <limits.h>
+#include "drmtest.h"
+
+/**
+ * Checks DRM_IOCTL_SET_VERSION.
+ *
+ * This tests that we can get the actual version out, and that setting invalid
+ * major/minor numbers fails appropriately. It does not check the actual
+ * behavior differenses resulting from an increased DI version.
+ */
+int main(int argc, char **argv)
+{
+ int fd, ret;
+ drm_set_version_t sv, version;
+
+ fd = drm_open_any_master();
+
+ /* First, check that we can get the DD/DI versions. */
+ memset(&version, 0, sizeof(version));
+ version.drm_di_major = -1;
+ version.drm_di_minor = -1;
+ version.drm_dd_major = -1;
+ version.drm_dd_minor = -1;
+ ret = ioctl(fd, DRM_IOCTL_SET_VERSION, &version);
+ assert(ret == 0);
+ assert(version.drm_di_major != -1);
+ assert(version.drm_di_minor != -1);
+ assert(version.drm_dd_major != -1);
+ assert(version.drm_dd_minor != -1);
+
+ /* Check that an invalid DI major fails */
+ sv = version;
+ sv.drm_di_major++;
+ ret = ioctl(fd, DRM_IOCTL_SET_VERSION, &sv);
+ assert(ret == -1 && errno == EINVAL);
+
+ /* Check that an invalid DI minor fails */
+ sv = version;
+ sv.drm_di_major++;
+ ret = ioctl(fd, DRM_IOCTL_SET_VERSION, &sv);
+ assert(ret == -1 && errno == EINVAL);
+
+ /* Check that an invalid DD major fails */
+ sv = version;
+ sv.drm_dd_major++;
+ ret = ioctl(fd, DRM_IOCTL_SET_VERSION, &sv);
+ assert(ret == -1 && errno == EINVAL);
+
+ /* Check that an invalid DD minor fails */
+ sv = version;
+ sv.drm_dd_minor++;
+ ret = ioctl(fd, DRM_IOCTL_SET_VERSION, &sv);
+ assert(ret == -1 && errno == EINVAL);
+
+ close(fd);
+ return 0;
+}
diff --git a/tests/updatedraw.c b/tests/updatedraw.c
new file mode 100644
index 00000000..2f22fef2
--- /dev/null
+++ b/tests/updatedraw.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include "drmtest.h"
+
+static void
+set_draw_cliprects_empty(int fd, int drawable)
+{
+ int ret;
+ struct drm_update_draw update;
+
+ update.handle = drawable;
+ update.type = DRM_DRAWABLE_CLIPRECTS;
+ update.num = 0;
+ update.data = 0;
+
+ ret = ioctl(fd, DRM_IOCTL_UPDATE_DRAW, &update);
+ assert(ret == 0);
+}
+
+static void
+set_draw_cliprects_empty_fail(int fd, int drawable)
+{
+ int ret;
+ struct drm_update_draw update;
+
+ update.handle = drawable;
+ update.type = DRM_DRAWABLE_CLIPRECTS;
+ update.num = 0;
+ update.data = 0;
+
+ ret = ioctl(fd, DRM_IOCTL_UPDATE_DRAW, &update);
+ assert(ret == -1 && errno == EINVAL);
+}
+
+static void
+set_draw_cliprects_2(int fd, int drawable)
+{
+ int ret;
+ struct drm_update_draw update;
+ drm_clip_rect_t rects[2];
+
+ rects[0].x1 = 0;
+ rects[0].y1 = 0;
+ rects[0].x2 = 10;
+ rects[0].y2 = 10;
+
+ rects[1].x1 = 10;
+ rects[1].y1 = 10;
+ rects[1].x2 = 20;
+ rects[1].y2 = 20;
+
+ update.handle = drawable;
+ update.type = DRM_DRAWABLE_CLIPRECTS;
+ update.num = 2;
+ update.data = (unsigned long long)(uintptr_t)&rects;
+
+ ret = ioctl(fd, DRM_IOCTL_UPDATE_DRAW, &update);
+ assert(ret == 0);
+}
+
+static int add_drawable(int fd)
+{
+ drm_draw_t drawarg;
+ int ret;
+
+ /* Create a drawable.
+ * IOCTL_ADD_DRAW is RDWR, though it should really just be RD
+ */
+ drawarg.handle = 0;
+ ret = ioctl(fd, DRM_IOCTL_ADD_DRAW, &drawarg);
+ assert(ret == 0);
+ return drawarg.handle;
+}
+
+static int rm_drawable(int fd, int drawable, int fail)
+{
+ drm_draw_t drawarg;
+ int ret;
+
+ /* Create a drawable.
+ * IOCTL_ADD_DRAW is RDWR, though it should really just be RD
+ */
+ drawarg.handle = drawable;
+ ret = ioctl(fd, DRM_IOCTL_RM_DRAW, &drawarg);
+ if (!fail)
+ assert(ret == 0);
+ else
+ assert(ret == -1 && errno == EINVAL);
+
+ return drawarg.handle;
+}
+
+/**
+ * Tests drawable management: adding, removing, and updating the cliprects of
+ * drawables.
+ */
+int main(int argc, char **argv)
+{
+ int fd, ret, d1, d2;
+
+ fd = drm_open_any_master();
+
+ d1 = add_drawable(fd);
+ d2 = add_drawable(fd);
+ /* Do a series of cliprect updates */
+ set_draw_cliprects_empty(fd, d1);
+ set_draw_cliprects_empty(fd, d2);
+ set_draw_cliprects_2(fd, d1);
+ set_draw_cliprects_empty(fd, d1);
+
+ /* Remove our drawables */
+ rm_drawable(fd, d1, 0);
+ rm_drawable(fd, d2, 0);
+
+ /* Check that removing an unknown drawable returns error */
+ rm_drawable(fd, 0x7fffffff, 1);
+
+ /* Attempt to set cliprects on a nonexistent drawable */
+ set_draw_cliprects_empty_fail(fd, d1);
+
+ close(fd);
+ return 0;
+}