summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2012-11-07 21:01:31 +0000
committerJon TURNEY <jon.turney@dronecode.org.uk>2012-11-07 22:00:29 +0000
commit45f7e04bb0f53223a5d05d93aa42b3faa6a97d76 (patch)
tree92e837e579092ffd55c0affb96a5f63d91a65ea8
testcases
-rw-r--r--README1
-rw-r--r--Xlocale.c16
-rw-r--r--busycursor.c96
-rw-r--r--decorations.c81
-rw-r--r--helloworld.py47
-rw-r--r--hidecursor.c38
-rw-r--r--makecurrenttest.c85
-rw-r--r--makecurrenttest2.c86
-rw-r--r--net_wm_state_skip_taskbar.c112
-rw-r--r--ogl.c27
-rw-r--r--option_menu.c48
-rw-r--r--quick_window.c46
-rw-r--r--skip_taskbar_toggle.c65
-rw-r--r--test-gtk-move-3.c95
-rw-r--r--test-net-wm-icons.c176
-rw-r--r--test-warp.c59
-rw-r--r--test_xsync.c21
-rw-r--r--urgency_test.c50
-rw-r--r--wm_state_atom.c21
-rw-r--r--xinerama_test.c35
20 files changed, 1205 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..d718ec9
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+A collection of small X programs for testing, mainly for window manager behaviour
diff --git a/Xlocale.c b/Xlocale.c
new file mode 100644
index 0000000..b8dc76b
--- /dev/null
+++ b/Xlocale.c
@@ -0,0 +1,16 @@
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xlocale.h>
+#include <stdio.h>
+
+// gcc Xlocale.c -lX11 -o Xlocale
+
+main()
+{
+ char *s = setlocale (LC_ALL, "");
+ printf("Setting locale from LANG %s\n", (s != NULL) ? "succeeded" : "failed");
+ char *l = setlocale (LC_ALL, NULL);
+ printf("Locale is %s\n", l);
+ int r = XSupportsLocale();
+ printf("XSupportsLocale returned %s\n", r ? "true" : "false");
+}
diff --git a/busycursor.c b/busycursor.c
new file mode 100644
index 0000000..c093808
--- /dev/null
+++ b/busycursor.c
@@ -0,0 +1,96 @@
+/* gcc -o busycursor `pkg-config --cflags --libs gtk+-2.0` busycursor.c */
+#include <gtk/gtk.h>
+
+/* This is a callback function. The data arguments are ignored
+ * in this example. More on callbacks below. */
+static void hello( GtkWidget *widget,
+ gpointer data )
+{
+ g_print ("Hello World\n");
+
+ GdkCursor *busy_cursor = gdk_cursor_new(GDK_WATCH);
+ gdk_window_set_cursor(GTK_WIDGET(widget)->window, busy_cursor);
+ gdk_flush();
+
+}
+
+static gboolean delete_event( GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data )
+{
+ /* If you return FALSE in the "delete_event" signal handler,
+ * GTK will emit the "destroy" signal. Returning TRUE means
+ * you don't want the window to be destroyed.
+ * This is useful for popping up 'are you sure you want to quit?'
+ * type dialogs. */
+
+ g_print ("delete event occurred\n");
+
+ /* Change TRUE to FALSE and the main window will be destroyed with
+ * a "delete_event". */
+ return TRUE;
+}
+
+/* Another callback */
+static void destroy( GtkWidget *widget,
+ gpointer data )
+{
+ gtk_main_quit ();
+}
+
+int main( int argc,
+ char *argv[] )
+{
+ /* GtkWidget is the storage type for widgets */
+ GtkWidget *window;
+ GtkWidget *button;
+
+ /* This is called in all GTK applications. Arguments are parsed
+ * from the command line and are returned to the application. */
+ gtk_init (&argc, &argv);
+
+ /* create a new window */
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ /* When the window is given the "delete_event" signal (this is given
+ * by the window manager, usually by the "close" option, or on the
+ * titlebar), we ask it to call the delete_event () function
+ * as defined above. The data passed to the callback
+ * function is NULL and is ignored in the callback function. */
+ g_signal_connect (G_OBJECT (window), "delete_event",
+ G_CALLBACK (delete_event), NULL);
+
+ /* Here we connect the "destroy" event to a signal handler.
+ * This event occurs when we call gtk_widget_destroy() on the window,
+ * or if we return FALSE in the "delete_event" callback. */
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (destroy), NULL);
+
+ /* Sets the border width of the window. */
+ gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+
+ /* Creates a new button with the label "Hello World". */
+ button = gtk_button_new_with_label ("Hello World");
+
+ /* When the button receives the "clicked" signal, it will call the
+ * function hello() passing it NULL as its argument. The hello()
+ * function is defined above. */
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (hello), NULL);
+
+ /* This packs the button into the window (a gtk container). */
+ gtk_container_add (GTK_CONTAINER (window), button);
+
+ /* The final step is to display this newly created widget. */
+ gtk_widget_show (button);
+
+ /* and the window */
+ gtk_widget_show (window);
+
+ /* All GTK applications must have a gtk_main(). Control ends here
+ * and waits for an event to occur (like a key press or
+ * mouse event). */
+ gtk_main ();
+
+ return 0;
+}
diff --git a/decorations.c b/decorations.c
new file mode 100644
index 0000000..cd3e711
--- /dev/null
+++ b/decorations.c
@@ -0,0 +1,81 @@
+/* from https://bugs.kde.org/show_bug.cgi?id=201523 */
+
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+/* Compile with "gcc -o decorations -Wall decorations.c -lX11" */
+
+/* Set the decorations part of a window's _MOTIF_WM_HINTS property to
+ * enable or disable window decorations. */
+static void SetMotifDecorationsHint(
+ Display* display, Window win, int show_decorations) {
+ fprintf(stderr, "Setting hint to %s decorations on 0x%x\n",
+ (show_decorations ? "show" : "hide"), win);
+ int values[3] = {
+ 1 << 1, /* flags */
+ 0, /* functions */
+ show_decorations
+ };
+ Atom atom = XInternAtom(display, "_MOTIF_WM_HINTS", False);
+ XChangeProperty(
+ display,
+ win,
+ atom, /* property */
+ atom, /* type */
+ 32, /* format */
+ PropModeReplace,
+ (unsigned char*) values,
+ 3); /* nelements */
+}
+
+int main(int argc, char** argv) {
+ if (argc != 2 || strcmp(argv[1], "-h") == 0) {
+ fprintf(stderr, "Usage: %s [show_decorations]\n", argv[0]);
+ return 1;
+ }
+
+ Display* display = XOpenDisplay(NULL);
+ if (!display) {
+ fprintf(stderr, "Couldn't open display\n");
+ return 1;
+ }
+ int screen = DefaultScreen(display);
+
+ const int width = 300, height = 200;
+
+ unsigned long black = BlackPixel(display, screen);
+ unsigned long white = WhitePixel(display, screen);
+
+ Window win = XCreateSimpleWindow(display,
+ RootWindow(display, screen),
+ 0, /* x */
+ 0, /* y */
+ width,
+ height,
+ 0, /* border_width */
+ black, /* border */
+ white); /* background */
+
+ int showing_decorations = (strcmp(argv[1], "0") != 0);
+ SetMotifDecorationsHint(display, win, showing_decorations);
+
+ XSelectInput(display, win, ButtonPressMask);
+ XMapWindow(display, win);
+
+ while (1) {
+ XEvent event;
+ XNextEvent(display, &event);
+
+ if (event.type == ButtonPress) {
+ XButtonEvent be = event.xbutton;
+ if (be.button == 2) {
+ showing_decorations = !showing_decorations;
+ SetMotifDecorationsHint(display, win, showing_decorations);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/helloworld.py b/helloworld.py
new file mode 100644
index 0000000..a810598
--- /dev/null
+++ b/helloworld.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+# This is the basic helloworld from PyGTK, with the GTK window decoration hint
+# set to false. The window manager should not draw any window decorations if
+# this is set.
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+class HelloWorld:
+
+ def delete_event(self, widget, event, data=None):
+ return False
+
+ def window_state_event(self, window, event):
+ print 'gtk.window.get_decorated(): ',
+ print str(self.window.get_decorated())
+
+ def destroy(self, widget, data=None):
+ gtk.main_quit()
+
+ def __init__(self):
+ self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+
+ # Decoration hint.
+ self.window.set_decorated(False)
+
+ self.window.connect("delete_event", self.delete_event)
+ self.window.connect("destroy", self.destroy)
+ self.window.connect('window-state-event', self.window_state_event)
+
+ self.label = gtk.Label("Maximize (Alt+F10) and unmaximize (Alt+F10) to reproduce " +
+ "the decoration error")
+
+ self.window.set_default_size(600, 100)
+
+ self.window.add(self.label)
+ self.label.show()
+ self.window.show()
+
+ def main(self):
+ gtk.main()
+
+if __name__ == "__main__":
+ hello = HelloWorld()
+ hello.main()
diff --git a/hidecursor.c b/hidecursor.c
new file mode 100644
index 0000000..1293b36
--- /dev/null
+++ b/hidecursor.c
@@ -0,0 +1,38 @@
+/* gcc -o hidecursor `pkg-config --cflags --libs x11 xfixes` */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xfixes.h>
+
+static Display* display;
+static int stop;
+
+static void sighandler(int sig) {
+ stop = 1;
+}
+
+int main (int argc, char** argv)
+{
+ display = XOpenDisplay(NULL);
+ signal(SIGINT, sighandler);
+
+ XFixesHideCursor(display, DefaultRootWindow(display));
+ XFlush(display);
+
+ printf("waiting. Ctrl + C to continue\n");
+ while(!stop) { }
+
+ stop = 0;
+ XFixesShowCursor(display, DefaultRootWindow(display));
+ XFlush(display);
+
+ printf("waiting. Ctrl + C to continue\n");
+
+ while(!stop) { }
+
+ XCloseDisplay(display);
+ return Success;
+}
+
diff --git a/makecurrenttest.c b/makecurrenttest.c
new file mode 100644
index 0000000..cb28458
--- /dev/null
+++ b/makecurrenttest.c
@@ -0,0 +1,85 @@
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+
+//
+// gcc -g -Wall -o makecurrenttest makecurrenttest.c -lX11 -lGL
+//
+// test case for a window which only exists briefly
+// causing a X server segfault
+//
+
+static Window make_rgb_db_window( Display *dpy, XVisualInfo *visinfo,
+ unsigned int width, unsigned int height )
+{
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+
+ scrnum = DefaultScreen( dpy );
+ root = RootWindow( dpy, scrnum );
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( dpy, root, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+
+ return win;
+}
+
+
+int main()
+{
+ // Open the display
+ Display *dpy = XOpenDisplay(NULL);
+ assert(dpy);
+
+ int attrib[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+
+ XVisualInfo *visinfo;
+ visinfo = glXChooseVisual( dpy, DefaultScreen(dpy), attrib );
+ if (!visinfo) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ assert(0);
+ }
+
+ // Create the window
+ Window w = make_rgb_db_window(dpy,visinfo,200,100);
+
+ // Map the window
+ XMapWindow(dpy, w);
+
+ GLXContext ctx = glXCreateContext(dpy, visinfo, NULL, True );
+ if (!ctx) {
+ printf("Error: glXCreateContext failed\n");
+ assert(0);
+ }
+
+ glXMakeCurrent(dpy, w, ctx);
+
+ XDestroyWindow(dpy, w);
+
+ glXMakeCurrent(dpy, None, NULL);
+
+ XFlush(dpy);
+
+ return 0;
+}
diff --git a/makecurrenttest2.c b/makecurrenttest2.c
new file mode 100644
index 0000000..f40f89f
--- /dev/null
+++ b/makecurrenttest2.c
@@ -0,0 +1,86 @@
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+
+//
+// gcc -g -Wall -o makecurrenttest makecurrenttest.c -lX11 -lGL
+//
+
+static Window make_rgb_db_window( Display *dpy, XVisualInfo *visinfo,
+ unsigned int width, unsigned int height )
+{
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+
+ scrnum = DefaultScreen( dpy );
+ root = RootWindow( dpy, scrnum );
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( dpy, root, 0, 0, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+
+ return win;
+}
+
+
+int main()
+{
+ int i;
+
+ // Open the display
+ Display *dpy = XOpenDisplay(NULL);
+ assert(dpy);
+
+ int attrib[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ None };
+
+ XVisualInfo *visinfo;
+ visinfo = glXChooseVisual( dpy, DefaultScreen(dpy), attrib );
+ if (!visinfo) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ assert(0);
+ }
+
+ for (i=0; i < 2; i++)
+ {
+ // Create the window
+ Window w = make_rgb_db_window(dpy,visinfo,200,100);
+
+ // Map the window
+ XMapWindow(dpy, w);
+
+ // Create context
+ GLXContext ctx = glXCreateContext(dpy, visinfo, NULL, True );
+ if (!ctx) {
+ printf("Error: glXCreateContext failed\n");
+ assert(0);
+ }
+
+ // Make current
+ glXMakeCurrent(dpy, w, ctx);
+
+ // Destroy window
+ XDestroyWindow(dpy, w);
+ }
+
+ return 0;
+}
diff --git a/net_wm_state_skip_taskbar.c b/net_wm_state_skip_taskbar.c
new file mode 100644
index 0000000..46a3056
--- /dev/null
+++ b/net_wm_state_skip_taskbar.c
@@ -0,0 +1,112 @@
+// gcc -o net_wm_state_skip_taskbar net_wm_state_skip_taskbar.c -lX11 `pkg-config --cflags --libs gtk+-2.0`
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <assert.h>
+#include <stdio.h>
+
+// gcc net_wm_state_skip_taskbar.c -lX11
+//
+// test case for _NET_WM_STATE_SKIP_TASKBAR
+//
+#if 0
+int main()
+{
+ // Open the display
+ Display *dpy = XOpenDisplay(NULL);
+ assert(dpy);
+
+ // Get some colors
+ int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
+ int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
+
+ // Create the window
+ Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200, 100, 0, blackColor, blackColor);
+
+ // Set the properties
+ Atom skip_taskbar = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR",False);
+ Atom net_wm_state = XInternAtom(dpy, "_NET_WM_STATE",False);
+
+ // Map the window
+ XMapWindow(dpy, w);
+
+ XFlush(dpy);
+
+ XChangeProperty(dpy, w, net_wm_state, XA_ATOM, 32,
+ PropModeAppend, (unsigned char *)&skip_taskbar, 1);
+
+ XFlush(dpy);
+
+ // Wait for ever
+ while (1)
+ {
+ sleep(1);
+ }
+}
+#endif
+
+//
+// gcc -Wall -o skip_taskbar net_wm_state_skip_taskbar.c `pkg-config --cflags --libs gtk+-2.0 glib-2.0`
+//
+
+#include <glib/gprintf.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+GtkWidget *main_window;
+
+static void toggle_prop( GtkWidget *widget,
+ gpointer data )
+{
+ static Bool toggle = TRUE;
+ Display *dpy = GDK_DISPLAY();
+ Window w = GDK_WINDOW_XWINDOW(main_window->window);
+
+ Atom skip_taskbar = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR",False);
+ Atom net_wm_state = XInternAtom(dpy, "_NET_WM_STATE",False);
+
+ if (toggle)
+ {
+ XChangeProperty(dpy, w, net_wm_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&skip_taskbar, 1);
+ }
+ else
+ {
+ XDeleteProperty(dpy, w, net_wm_state);
+ }
+
+ toggle = !toggle;
+
+ XFlush(dpy);
+}
+
+static void destroy( GtkWidget *widget,
+ gpointer data )
+{
+ gtk_main_quit ();
+}
+
+int main( int argc,
+ char *argv[] )
+{
+ GtkWidget *button;
+ gtk_init (&argc, &argv);
+
+ main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_decorated (GTK_WINDOW(main_window), TRUE);
+
+ g_signal_connect (G_OBJECT (main_window), "destroy",
+ G_CALLBACK (destroy), NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (main_window), 10);
+
+ button = gtk_button_new_with_label ("Toggle");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (toggle_prop), NULL);
+
+ gtk_container_add (GTK_CONTAINER (main_window), button);
+ gtk_widget_show (button);
+ gtk_widget_show (main_window);
+
+ gtk_main ();
+ return 0;
+}
diff --git a/ogl.c b/ogl.c
new file mode 100644
index 0000000..3610050
--- /dev/null
+++ b/ogl.c
@@ -0,0 +1,27 @@
+/* gcc ogl.c -lGL -lX11 */
+/* fd.o bugzilla #8443 */
+
+#include <GL/glx.h>
+int main()
+{
+ Display *gdi_display = XOpenDisplay(NULL);
+ int screen = DefaultScreen(gdi_display);
+ Window win = RootWindow(gdi_display, screen);
+ Visual *visual;
+ XVisualInfo template;
+ XVisualInfo *vis;
+ int num;
+
+ GLXContext ctx = NULL;
+ visual = DefaultVisual(gdi_display, screen);
+ template.visualid = XVisualIDFromVisual(visual);
+ vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num);
+ if (vis)
+ ctx = glXCreateContext(gdi_display, vis, None, GL_TRUE);
+ if (ctx)
+ glXMakeCurrent(gdi_display, win, ctx);
+ glXMakeCurrent(gdi_display, None, NULL);
+ XCloseDisplay(gdi_display);
+ return 0;
+}
+
diff --git a/option_menu.c b/option_menu.c
new file mode 100644
index 0000000..f515058
--- /dev/null
+++ b/option_menu.c
@@ -0,0 +1,48 @@
+// gcc option_menu.c -lXt -lXm
+
+
+#include <Xm/Xm.h>
+#include <Xm/Form.h>
+#include <Xm/PushB.h>
+
+Boolean ViewerCheck()
+{
+ usleep(100000);
+ return False;
+}
+
+int main()
+{
+ Widget TopLevel,form,wdg1,wdg2,wdg3,wdg4;
+ XtAppContext app;
+ int argc=0;
+ char *argv[1];
+
+ XtSetLanguageProc(NULL,NULL,NULL);
+ TopLevel = XtVaAppInitialize(&app,"Test",NULL,0,&argc,argv,NULL,NULL);
+
+ form = XtVaCreateManagedWidget( "Test",
+ xmFormWidgetClass, TopLevel,
+ XmNwidth, 100,
+ XmNheight, 60);
+
+ wdg1 = XmCreatePulldownMenu(form, "pulldown", NULL, 0);
+
+ wdg2 = XtVaCreateManagedWidget("1", xmPushButtonWidgetClass, wdg1,
+ XmNwidth, 60);
+
+ wdg3 = XtVaCreateManagedWidget("2", xmPushButtonWidgetClass, wdg1,
+ XmNwidth, 60);
+
+ wdg4 = XmCreateOptionMenu(form, "TEST", NULL, 0);
+ XtVaSetValues(wdg4, XmNsubMenuId, wdg1);
+ XtManageChild(wdg4);
+
+ XtRealizeWidget(TopLevel);
+ XtAppAddWorkProc(app, (XtWorkProc) ViewerCheck, (XtPointer) NULL);
+ XtAppMainLoop(app);
+
+ return 0;
+}
+
+
diff --git a/quick_window.c b/quick_window.c
new file mode 100644
index 0000000..ad7eeae
--- /dev/null
+++ b/quick_window.c
@@ -0,0 +1,46 @@
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+//
+// gcc -g -Wall -o quick_window quick_window.c -lX11
+//
+// test case for a window which only exists briefly
+// causing a X server segfault
+//
+
+int main()
+{
+ // Open the display
+ Display *dpy = XOpenDisplay(NULL);
+ assert(dpy);
+
+ // Get some colors
+ int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
+
+ while (1)
+ {
+ int t;
+
+ // Create the window
+ Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200, 100, 0, blackColor, blackColor);
+
+ // Map the window
+ XMapWindow(dpy, w);
+ XFlush(dpy);
+
+ t = rand() % 500000;
+ usleep(t);
+
+ XDestroyWindow(dpy, w);
+ XFlush(dpy);
+
+ t = rand() % 500000;
+ usleep(t);
+ }
+
+ return 0;
+}
diff --git a/skip_taskbar_toggle.c b/skip_taskbar_toggle.c
new file mode 100644
index 0000000..3d06522
--- /dev/null
+++ b/skip_taskbar_toggle.c
@@ -0,0 +1,65 @@
+#include <X11/Xatom.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+//
+// gcc -Wall -o skip_taskbar_toggle skip_taskbar_toggle.c `pkg-config --cflags --libs gtk+-2.0 glib-2.0`
+//
+
+GtkWidget *main_window;
+
+static void toggle_prop( GtkWidget *widget,
+ gpointer data )
+{
+ static Bool toggle = TRUE;
+ Display *dpy = GDK_DISPLAY();
+ Window w = GDK_WINDOW_XWINDOW(main_window->window);
+
+ Atom skip_taskbar = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR",False);
+ Atom net_wm_state = XInternAtom(dpy, "_NET_WM_STATE",False);
+
+ if (toggle)
+ {
+ XChangeProperty(dpy, w, net_wm_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&skip_taskbar, 1);
+ }
+ else
+ {
+ XDeleteProperty(dpy, w, net_wm_state);
+ }
+
+ toggle = !toggle;
+
+ XFlush(dpy);
+}
+
+static void destroy( GtkWidget *widget,
+ gpointer data )
+{
+ gtk_main_quit ();
+}
+
+int main( int argc,
+ char *argv[] )
+{
+ GtkWidget *button;
+ gtk_init (&argc, &argv);
+
+ main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_decorated (GTK_WINDOW(main_window), TRUE);
+
+ g_signal_connect (G_OBJECT (main_window), "destroy",
+ G_CALLBACK (destroy), NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (main_window), 10);
+
+ button = gtk_button_new_with_label ("Toggle");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (toggle_prop), NULL);
+
+ gtk_container_add (GTK_CONTAINER (main_window), button);
+
+ gtk_widget_show (button);
+ gtk_widget_show (main_window);
+
+ gtk_main ();
+ return 0;
+}
diff --git a/test-gtk-move-3.c b/test-gtk-move-3.c
new file mode 100644
index 0000000..d985739
--- /dev/null
+++ b/test-gtk-move-3.c
@@ -0,0 +1,95 @@
+/* Testcase for: Dialogs that save their positions when closing
+ keep drifting downwards.
+
+ To compile:
+ gcc -Wall -o test-gtk-move-3 test-gtk-move-3.c `pkg-config --cflags --libs gtk+-2.0 glib-2.0`
+
+ To use:
+
+ X -multiwindow &
+ export DISPLAY=:0
+ ./test-gtk-move-3
+
+ Press 'Show', then close the dialog, then press 'Show' again.
+ The dialog should reopen at the same place.
+ In fact, it will reopen a little lower each time. Repeated execution
+ will cause it to drift downwards.
+*/
+
+#include <glib/gprintf.h>
+#include <gtk/gtk.h>
+
+GtkWidget *main_window;
+GtkWidget *tool_window;
+
+/* Hold the last dialog position */
+gint tool_x = 100, tool_y = 100;
+
+static gboolean delete_tool_window( GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data )
+{
+ /* At closing time, save the dialog position */
+ gtk_window_get_position (GTK_WINDOW (tool_window), &tool_x, &tool_y);
+ g_printf("My position was: %d,%d\n",tool_x,tool_y);
+ return FALSE;
+}
+
+static void destroy_tool_window( GtkWidget *widget,
+ gpointer data )
+{
+ tool_window = NULL;
+}
+
+static void create_tool_window()
+{
+ tool_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (G_OBJECT (tool_window), "delete-event",
+ G_CALLBACK (delete_tool_window), NULL);
+ g_signal_connect (G_OBJECT (tool_window), "destroy",
+ G_CALLBACK (destroy_tool_window), NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (tool_window), 10);
+}
+
+static void show_tool_window( GtkWidget *widget,
+ gpointer data )
+{
+ /* If the dialog is closed, create it. */
+ if (!tool_window)
+ create_tool_window();
+ else {
+ gtk_window_get_position (GTK_WINDOW (tool_window), &tool_x, &tool_y);
+ g_printf("My position is: %d,%d\n",tool_x,tool_y);
+ }
+ /* Move it to the saved position */
+ /* We move it before it is shown, to avoid flicker */
+ gtk_window_move (GTK_WINDOW (tool_window), tool_x, tool_y);
+ /* Show the window */
+ gtk_widget_show (tool_window);
+}
+
+static void destroy( GtkWidget *widget,
+ gpointer data )
+{
+ gtk_main_quit ();
+}
+
+int main( int argc,
+ char *argv[] )
+{
+ GtkWidget *button;
+ gtk_init (&argc, &argv);
+ main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_decorated (GTK_WINDOW(main_window), TRUE);
+ g_signal_connect (G_OBJECT (main_window), "destroy",
+ G_CALLBACK (destroy), NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (main_window), 10);
+ button = gtk_button_new_with_label ("Show");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (show_tool_window), NULL);
+ gtk_container_add (GTK_CONTAINER (main_window), button);
+ gtk_widget_show (button);
+ gtk_widget_show (main_window);
+ gtk_main ();
+ return 0;
+}
diff --git a/test-net-wm-icons.c b/test-net-wm-icons.c
new file mode 100644
index 0000000..2e67cc3
--- /dev/null
+++ b/test-net-wm-icons.c
@@ -0,0 +1,176 @@
+/* gcc test-net-wm-icons.c -o test-net-wm-icons.exe -lX11 */
+
+#include <stdlib.h>
+#include <X11/Xlib.h>
+
+int main(int argc, char **argv)
+{
+/* Two test ARGB _NET_WM_ICO icons 16x16 and 32x32 */
+ unsigned int buffer[] = {16, 16, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 338034905, 3657433343, 0, 184483840, \
+234881279, 3053453567, 3221225727, 1879048447, 0, 0, 0, 0, 0, 0, 0, 1224737023, \
+3305111807, 3875537151,0, 0, 2063597823, 1291845887, 0, 67109119, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+50266112, 3422552319, 0, 0, 3070230783, 2063597823, 2986344703, 771752191, 0, 0, 0, \
+0, 0, 0, 0, 0, 0, 3422552319, 0, 0, 3372220671, 1509949695, 704643327, 3355443455, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 0, 3422552319, 0, 134152192, 3187671295, 251658495, 0, 3439329535, 0, 0, \
+0, 0, 0, 0, 0, 0, 0, 3422552319, 0, 0, 2332033279, 1342177535, 167772415, 3338666239, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 0, 3422552319, 0, 0, 436207871, 3322085628, 3456106751, 1375731967, \
+4278255360, 4026597120, 3758161664, 3489726208, 3204513536, 2952855296, 2684419840, \
+2399207168, 2130771712, 1845559040, 1593900800, 1308688128, 1040252672, 755040000, \
+486604544, 234946304, 4278255360, 4043374336, 3774938880, 3506503424, 3221290752, \
+2952855296, 2667642624, 2399207168, 2130771712, 1862336256, 1627453957, 1359017481, \
+1073805064, 788591627, 503379721, 218169088, 4278255360, 4043374336, 3758161664, \
+3506503424, 3221290752, 2952855296, 2684419840, 2415984384, 2130771712, 1862336256, \
+1577123584, 1308688128, 1040252672, 755040000, 486604544, 218169088, 4278190335, \
+4026532095, 3758096639, 3489661183, 3221225727, 2952790271, 2667577599, 2415919359, \
+2130706687, 1862271231, 1593835775, 1325400319, 1056964863, 771752191, 520093951, \
+234881279, 4278190335, 4026532095, 3758096639, 3489661183, 3221225727, 2952790271, \
+2667577599, 2415919359, 2130706687, 1862271231, 1593835775, 1325400319, 1056964863, \
+771752191, 503316735, 234881279, 4278190335, 4026532095, 3758096639, 3489661183, \
+3221225727, 2952790271, 2684354815, 2399142143, 2130706687, 1862271231, 1593835775, \
+1325400319, 1040187647, 771752191, 520093951, 234881279, 4294901760, 4043243520, \
+3774808064, 3506372608, 3221159936, 2952724480, 2684289024, 2399076352, 2147418112, \
+1862205440, 1593769984, 1308557312, 1040121856, 771686400, 503250944, 234815488, \
+4294901760, 4060020736, 3758030848, 3506372608, 3221159936, 2952724480, 2684289024, \
+2415853568, 2130640896, 1862205440, 1593769984, 1308557312, 1040121856, 771686400, \
+503250944, 234815488, 4294901760, 4043243520, 3774808064, 3489595392, 3237937152, \
+2952724480, 2684289024, 2415853568, 2147418112, 1862205440, 1593769984, 1325334528, \
+1056899072, 788463616, 503250944, 234815488, 32, 32, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+0, 0, 0, 0, 0, 0, 0, 0, 0, 268369920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 1509949695, 3120562431, 4009754879, 4194304255, 3690987775, 2130706687, \
+83886335, 0, 50331903, 1694499071, 3170894079, 3992977663, 4211081471, 3657433343, \
+1879048447, 16777471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3087007999, \
+2281701631, 1191182591, 1040187647, 2030043391, 4127195391, 2566914303, 0, 16777471, \
+3254780159, 2181038335, 1191182591, 973078783, 2030043391,4177527039, 2130706687, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 0, 0, 0, 0, 0, 2214592767, 4093640959, 0, 0, 0, 0, 0, 0, 0, \
+2298478847, 3909091583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+0, 2214592767, 3607101695, 0, 0, 0, 0, 0, 0, 0, 1946157311, 4093640959, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 0, 0, 536871167, 1191182591, 2281701631,3019899135, 637534463, 0, 0, 0, \
+100597760, 251592704, 33488896, 0, 3321889023, 2919235839, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+0, 0, 0, 0, 0, 0, 0, 0, 0, 2550137087, 4278190335, 4278190335, 3405775103, 570425599, \
+0, 0, 0, 0, 0, 0, 2046820607, 4043309311, 620757247, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+33488896, 0, 0, 218104063, 1291845887, 3841982719, 3388997887, 0, 0, 0, 0, 0, \
+1996488959, 4093640959, 1073742079, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+0, 0, 0, 0, 0, 0, 1761607935, 4278190335, 150995199, 0, 0, 67109119, 2550137087, \
+3909091583, 889192703, 0, 0, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 0, 0, 0, 0, 0, \
+2181038335, 3925868799, 0, 0, 218104063, 3070230783, 3623878911, 570425599, 0, 0, 0, \
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 805306623, 3288334591, 1795162367, \
+1040187647, 1023410431, 2231369983, 4211081471, 1694499071, 0, 369099007, 3456106751, \
+3825205503, 1174405375, 872415487, 872415487, 872415487, 872415487, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 4294901760, \
+4293984270, 2046951677, 3422552319, 4110418175, 4177527039, 3405775103, 1409286399, \
+0, 0, 1409286399, 4278190335, 4278190335, 4278190335, 4278190335, 4278190335, \
+4278190335, 4278190335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4294901760, 4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760,4294901760, 4294901760, 4294901760, \
+4294901760, 4294901760, 4294901760, 4294901760, 4294901760, 0, 0, 0, 0, 0, 0, 0, 0, \
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, \
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4278255360, 4144037632, 4009819904, \
+3875602176, 3741384448, 3607166720, 3472948992, 3338731264, 3204513536, 3053518592, \
+2936078080, 2801860352, 2650865408, 2516647680, 2382429952, 2264989440, 2113994496, \
+1996553984, 1862336256, 1728118528, 1577123584, 1459683072, 1325465344, 1191247616, \
+1040252672, 922812160, 771817216, 637599488, 503381760, 385941248, 234946304, \
+100728576, 4278255360, 4144037632, 4009819904, 3875602176, 3724607232, 3607166720, \
+3472948992, 3338731264, 3204513536, 3070295808, 2936078080, 2801860352, 2667642624, \
+2516647680, 2399207168, 2264989440, 2130771712, 1996553984, 1845559040, 1728118528, \
+1593900800, 1459683072, 1308688128, 1191247616, 1057029888, 922812160, 788594432, \
+637599488, 503381760, 369164032, 234946304, 117505792, 4278255360, 4144037632, \
+4009819904, 3875602176, 3741384448, 3607166720, 3472948992, 3338731264, 3204513536, \
+3053518592, 2919300864, 2801860352, 2650865408, 2533424896, 2399207168, 2264989440, \
+2113994496, 1996553984, 1862336256, 1728118528,1593900800, 1459683072, 1325465344, \
+1191247616, 1040252672, 906034944, 771817216, 654376704, 503381760, 369164032, \
+234946304, 117505792, 4278255360, 4144037632, 4009819904, 3858824960, 3741384448, \
+3607166720, 3472948992, 3338731264, 3204513536, 3070295808, 2936078080, 2801860352, \
+2667642624, 2533424896, 2382429952, 2264989440, 2130771712, 1979776768, 1862336256, \
+1728118528, 1577123584, 1442905856, 1325465344, 1191247616, 1040252672, 922812160, \
+771817216, 637599488, 503381760, 369164032, 234946304, 100728576, 4278255360, \
+4144037632, 4009819904, 3875602176, 3741384448, 3607166720, 3472948992, 3338731264, \
+3204513536, 3070295808, 2919300864, 2801860352, 2667642624, 2533424896, 2399207168, \
+2264989440, 2113994496, 1996553984, 1862336256, 1728118528, 1593900800, 1442905856, \
+1342241795, 1174470400, 1057029888, 906034944, 788594432, 654376704, 503381760, \
+385941248, 251723520, 100728576, 4278190335, 4160749823, 4026532095, 3892314367, \
+3741319423, 3623878911, 3472883967, 3338666239, 3221225727, 3070230783, 2952790271, \
+2818572543, 2667577599, 2533359871, 2399142143, 2264924415, 2147483903, 1996488959, \
+1862271231, 1728053503, 1593835775, 1459618047, 1325400319, 1191182591, 1056964863, \
+922747135, 788529407, 654311679, 520093951,385876223, 251658495, 117440767, \
+4278190335, 4160749823, 4026532095, 3892314367, 3741319423, 3623878911, 3489661183, \
+3355443455, 3221225727, 3087007999, 2936013055, 2801795327, 2667577599, 2533359871, \
+2399142143, 2281701631, 2130706687, 1996488959, 1862271231, 1728053503, \
+1593835775,1459618047, 1325400319, 1191182591, 1056964863, 922747135, 788529407, \
+654311679, 520093951, 385876223, 234881279, 100663551, 4278190335, 4160749823, \
+4026532095, 3892314367, 3758096639, 3623878911, 3489661183, 3355443455, 3221225727, \
+3087007999, 2936013055, 2801795327, 2667577599, 2550137087, 2415919359, 2264924415, \
+2130706687, 1996488959, 1862271231, 1728053503, 1593835775, 1459618047, 1325400319, \
+1191182591, 1056964863, 922747135, 788529407, 654311679, 503316735, 369099007, \
+251658495, 100663551, 4278190335, 4160749823, 4026532095, 3892314367, 3758096639, \
+3623878911, 3489661183, 3355443455, 3204448511, 3087007999, 2936013055, 2818572543, \
+2667577599, 2533359871, 2399142143, 2264924415, 2130706687, 1996488959, 1879048447, \
+1728053503, 1593835775, 1459618047, 1325400319, 1191182591, 1056964863, 922747135, \
+788529407, 654311679, 520093951, 385876223, 251658495, 117440767, 4278190335, \
+4160749823, 4026532095, 3892314367, 3758096639, 3623878911, 3489661183, 3355443455, \
+3221225727, 3087007999, 2952790271, 2818572543, 2667577599, 2533359871, 2399142143, \
+2264924415, 2147483903, 2013266175, 1862271231, 1744830719, 1610612991, 1476395263, \
+1342177535, 1191182591, 1056964863, 922747135, 788529407, 654311679, 520093951, \
+385876223, 251658495, 100663551, 4294901760, 4160684032, 4026466304, 3909025792, \
+3774808064, 3623813120, 3489595392, 3355377664, 3237937152, 3103719424, 2952724480, \
+2818506752, 2684289024, 2550071296, 2415853568, 2281635840, 2147418112, 2013200384, \
+1878982656, 1744764928, 1593769984, 1476329472,1325334528, 1207894016, 1056899072, \
+939458560, 788463616, 654245888, 520028160, 385810432, 251592704, 117374976, \
+4294901760, 4177461248, 4043243520, 3909025792, 3774808064, 3640590336, 3506372608, \
+3355377664, 3221159936, 3086942208, 2952724480, 2818506752, 2701066240, 2550071296, \
+2415853568, 2281635840, 2147418112, 2013200384, 1878982656, 1727987712, 1610547200, \
+1476329472, 1325334528, 1191116800, 1073676288, 922681344, 788463616, 654245888, \
+520028160, 385810432, 251592704, 100597760, 4294901760, 4177461248, 4043243520, \
+3909025792, 3774808064, 3640590336, 3489595392, 3372154880, 3237937152, 3103719424, \
+2952724480, 2818506752, 2700935170, 2550071296, 2415853568, 2281635840, 2147418112, \
+2013200384, 1878982656, 1744764928, 1610547200, 1459552256, 1342111744, 1191116800, \
+1056899072, 922681344, 788463616, 671023104, 520028160, 385810432, 251592704, \
+100597760, 4294901760, 4177461248, 4043243520, 3909025792, 3774808064, 3640590336, \
+3489595392, 3372154880, 3237937152, 3086942208, 2969501696, 2818506752, 2684289024, \
+2550071296, 2432630784, 2281635840, 2147418112, 2013200384, 1862205440, 1744764928, \
+1610547200, 1476329472, 1342111744, 1191116800, 1056899072, 922681344, 788463616, \
+654245888, 520028160, 385810432, 251592704, 117374976, 4294901760, 4177461248, \
+4043243520, 3909025792, 3774808064, 3623813120, 3506372608, 3372154880, 3237937152, \
+3103719424, 2952724480, 2835283968, 2684289024, 2550071296, 2432630784, 2281635840, \
+2147418112, 2046492676, 1862205440, 1744764928, 1610547200, 1476329472, \
+1342111744,1207894016, 1056899072, 939458560, 788463616, 654245888, 536281096, \
+385810432, 251592704, 134152192};
+
+ Display *d = XOpenDisplay(0);
+ int s = DefaultScreen(d);
+ Atom net_wm_icon = XInternAtom(d, "_NET_WM_ICON", False);
+ Atom cardinal = XInternAtom(d, "CARDINAL", False);
+ Window w;
+ XEvent e;
+ w = XCreateWindow(d, RootWindow(d, s), 0, 0, 200, 200, 0,
+ CopyFromParent, InputOutput, CopyFromParent, 0, 0);
+
+ XMapWindow(d, w);
+ XFlush(d);
+ sleep(20);
+
+ int length = 2 + 16 * 16 + 2 + 32 * 32;
+ XChangeProperty(d, w, net_wm_icon, cardinal, 32,
+ PropModeReplace, (const unsigned char*) buffer, length);
+
+
+ while(1) XNextEvent(d, &e);
+}
diff --git a/test-warp.c b/test-warp.c
new file mode 100644
index 0000000..20871f0
--- /dev/null
+++ b/test-warp.c
@@ -0,0 +1,59 @@
+/*
+ Testcase for: Cursor warping
+
+ To compile:
+ gcc -Wall -o test-warp test-warp.c `pkg-config --cflags --libs gtk+-2.0 glib-2.0`
+
+ To use:
+
+ X -multiwindow &
+ export DISPLAY=:0
+ ./test-warp
+
+ Press 'Warp' button, cursor should move elsewhere
+
+*/
+
+#include <glib/gprintf.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+GtkWidget *main_window;
+
+static void warp_cursor( GtkWidget *widget,
+ gpointer data )
+{
+ Display *dpy = GDK_DISPLAY();
+ XWarpPointer(dpy, None, None, 0,0,0,0, +100,+100);
+}
+
+static void destroy( GtkWidget *widget,
+ gpointer data )
+{
+ gtk_main_quit ();
+}
+
+int main( int argc,
+ char *argv[] )
+{
+ GtkWidget *button;
+ gtk_init (&argc, &argv);
+
+ main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_decorated (GTK_WINDOW(main_window), TRUE);
+
+ g_signal_connect (G_OBJECT (main_window), "destroy",
+ G_CALLBACK (destroy), NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (main_window), 10);
+
+ button = gtk_button_new_with_label ("Warp");
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (warp_cursor), NULL);
+
+ gtk_container_add (GTK_CONTAINER (main_window), button);
+ gtk_widget_show (button);
+ gtk_widget_show (main_window);
+
+ gtk_main ();
+ return 0;
+}
diff --git a/test_xsync.c b/test_xsync.c
new file mode 100644
index 0000000..c3c5089
--- /dev/null
+++ b/test_xsync.c
@@ -0,0 +1,21 @@
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <time.h>
+#include <assert.h>
+
+//
+// gcc -g test_xsync.c -lX11 -o test_xsync
+//
+int main()
+{
+ // Open the display
+ Display *dpy = XOpenDisplay(NULL);
+ assert(dpy);
+
+ // loop for ever
+ while (1)
+ {
+ sleep(0);
+ XSync(dpy, 0);
+ }
+}
diff --git a/urgency_test.c b/urgency_test.c
new file mode 100644
index 0000000..cf403a9
--- /dev/null
+++ b/urgency_test.c
@@ -0,0 +1,50 @@
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+
+
+//
+// gcc -g -Wall -o urgency_test urgency_test.c -lX11
+//
+// test case for urgency hint
+//
+
+int main()
+{
+ // Open the display
+ Display *dpy = XOpenDisplay(NULL);
+ assert(dpy);
+
+ // Get some colors
+ int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
+
+ // Create the window
+ Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200, 100, 0, blackColor, blackColor);
+
+ // Map the window
+ XMapWindow(dpy, w);
+ XFlush(dpy);
+
+ sleep(2);
+
+ printf("Setting the urgency hint\n");
+
+ XWMHints *h;
+ h = XAllocWMHints();
+ h->initial_state = NormalState;
+ // = XGetWMHints(dpy, w);
+ h->flags |= XUrgencyHint;
+ // h->flags &= ~XUrgencyHint;
+ XSetWMHints(dpy, w, h);
+ XFlush(dpy);
+
+ while (1)
+ {
+ sleep(1);
+ }
+
+ return 0;
+}
diff --git a/wm_state_atom.c b/wm_state_atom.c
new file mode 100644
index 0000000..409abc9
--- /dev/null
+++ b/wm_state_atom.c
@@ -0,0 +1,21 @@
+
+#include <X11/Xlib.h>
+
+//
+// gcc wm_state_atom.c -lX11 -o wm_state_atom
+//
+
+int main (int argc, char *argv[])
+{
+ Display *dpy;
+ Atom a;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy)
+ return -1;
+
+ a = XInternAtom(dpy, "WM_STATE", 0);
+ printf("atom %d\n", a);
+}
+
+
diff --git a/xinerama_test.c b/xinerama_test.c
new file mode 100644
index 0000000..4f546b5
--- /dev/null
+++ b/xinerama_test.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xinerama.h>
+
+//
+// gcc xinerama_test.c -lX11 -lXinerama -o xinerama_test
+//
+
+int main (int argc, char *argv[])
+{
+ XineramaScreenInfo *info;
+ int numOfHeads;
+ Display *dpy;
+
+ dpy = XOpenDisplay(NULL);
+ if (!dpy)
+ return -1;
+
+ info = XineramaQueryScreens(dpy, &numOfHeads);
+ if (!info)
+ printf("Xinerama not available\n");
+ else
+ {
+ int i;
+ for (i = 0; i < numOfHeads; i++)
+ printf("Head %d: num %d, Origin %d %d, Size %d %d\n", i,
+ info[i].screen_number, info[i].x_org, info[i].y_org,
+ info[i].width, info[i].height);
+ XFree(info);
+ }
+
+ XCloseDisplay(dpy);
+
+ return 0;
+}