summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2013-06-14 20:22:17 +0100
committerJon TURNEY <jon.turney@dronecode.org.uk>2013-06-16 13:32:29 +0100
commit04475105a6a9cc1f78e51d3d782d1dd7c080d431 (patch)
tree6a0e341b63f7ca1a960b77ddc75dbb254fcd08fa
parent71189a1a58e3190ec736cec3be36038e73ffba9c (diff)
more testcases
-rw-r--r--busycursor.c16
-rwxr-xr-xqt4_clip.cpp153
-rw-r--r--test-invalid-net-wm-icon.c59
-rw-r--r--test-postion-window.c22
-rw-r--r--test.py40
5 files changed, 286 insertions, 4 deletions
diff --git a/busycursor.c b/busycursor.c
index c093808..fcc72fe 100644
--- a/busycursor.c
+++ b/busycursor.c
@@ -1,4 +1,4 @@
-/* gcc -o busycursor `pkg-config --cflags --libs gtk+-2.0` busycursor.c */
+/* gcc -o busycursor busycursor.c `pkg-config --cflags --libs gtk+-2.0` */
#include <gtk/gtk.h>
/* This is a callback function. The data arguments are ignored
@@ -8,8 +8,16 @@ static void hello( GtkWidget *widget,
{
g_print ("Hello World\n");
- GdkCursor *busy_cursor = gdk_cursor_new(GDK_WATCH);
- gdk_window_set_cursor(GTK_WIDGET(widget)->window, busy_cursor);
+ GdkCursor *cursor;
+ static int toggle = 0;
+ toggle = !toggle;
+
+ if (toggle)
+ cursor = gdk_cursor_new(GDK_WATCH);
+ else
+ cursor = gdk_cursor_new(GDK_X_CURSOR);
+
+ gdk_window_set_cursor(GTK_WIDGET(widget)->window, cursor);
gdk_flush();
}
@@ -28,7 +36,7 @@ static gboolean delete_event( GtkWidget *widget,
/* Change TRUE to FALSE and the main window will be destroyed with
* a "delete_event". */
- return TRUE;
+ return FALSE;
}
/* Another callback */
diff --git a/qt4_clip.cpp b/qt4_clip.cpp
new file mode 100755
index 0000000..c489e0b
--- /dev/null
+++ b/qt4_clip.cpp
@@ -0,0 +1,153 @@
+// Compile: g++ -I/usr/include/qt4 -L/usr/lib/qt4/lib -o qt4_clip qt4_clip.cpp -lQtGui -lQtCore
+#include <QtCore/QString>
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <unistd.h>
+
+// Abstract class to define a generic clipboard accessor.
+class CClipboardAccess
+{
+public:
+ explicit CClipboardAccess(const std::string &name) : Name(name) {}
+ virtual ~CClipboardAccess() {}
+ inline const std::string& GetName() const { return this->Name; }
+
+ virtual void ClearClipboard() const = 0;
+ virtual void SetClipboard(const std::string &str) const = 0;
+ virtual std::string GetClipboard() const = 0;
+
+private:
+ std::string Name;
+};
+
+// A class to access the clipboard using the Qt QClipboard.
+class CQtClipboardAccess : public CClipboardAccess
+{
+public:
+ explicit CQtClipboardAccess(QApplication &app) : CClipboardAccess("QClipboard"), pApp(&app), pClip(QApplication::clipboard()) {}
+ virtual ~CQtClipboardAccess() {}
+
+ virtual void ClearClipboard() const
+ {
+ this->pApp->processEvents();
+ this->pClip->clear(QClipboard::Clipboard);
+ if (this->pClip->supportsSelection())
+ this->pClip->clear(QClipboard::Selection);
+ }
+
+ virtual void SetClipboard(const std::string &str) const
+ {
+ this->pApp->processEvents();
+ this->pClip->setText(str.c_str(), QClipboard::Clipboard);
+ if (this->pClip->supportsSelection())
+ this->pClip->setText(str.c_str(), QClipboard::Selection);
+ }
+
+ virtual std::string GetClipboard() const
+ {
+ this->pApp->processEvents();
+ return this->pClip->text(QClipboard::Clipboard).toStdString();
+ }
+
+private:
+ QApplication *pApp;
+ QClipboard *pClip;
+};
+
+// A class to access the clipboard by reading / writing to '/dev/clipboard'.
+class CCygwinClipboardAccess : public CClipboardAccess
+{
+public:
+ CCygwinClipboardAccess() : CClipboardAccess("/dev/clipboard") {}
+ virtual ~CCygwinClipboardAccess() {}
+
+ virtual void ClearClipboard() const
+ {
+ this->SetClipboard("");
+ }
+
+ virtual void SetClipboard(const std::string &str) const
+ {
+ std::ofstream out(this->GetName().c_str());
+ if (!out)
+ std::cerr << "Unable to write to '" << this->GetName() << "'." << std::endl;
+ else
+ out << str;
+ }
+
+ virtual std::string GetClipboard() const
+ {
+ std::string line;
+ std::ifstream in(this->GetName().c_str());
+ if (!in)
+ std::cerr << "Unable to read '" << this->GetName() << "'." << std::endl;
+ else
+ std::getline(in, line);
+ return line;
+ }
+};
+
+class CTest : public QApplication
+{
+public:
+ CTest(int argc, char **pargv) : QApplication(argc, pargv) {}
+ virtual ~CTest() {}
+
+ void GoTest()
+ {
+ CQtClipboardAccess qt_clip(*this);
+ CCygwinClipboardAccess cygwin_clip;
+
+ // The tests.
+ //
+ // With 64-bit XWin, test 3 always fails, but for 32-bit XWin the same test passes.
+ // This is true, irrespective of whether this code is compiled and run from 32-bit Cygwin or 64-bit Cygwin.
+ //
+ // Test 2 always fails, but I don't understand why.
+ // Tests 1 and 4 always pass.
+ this->RunTest(qt_clip, qt_clip, "Mary had a little lamb");
+ this->RunTest(qt_clip, cygwin_clip, "Whose fleece was as white as snow");
+ this->RunTest(cygwin_clip, qt_clip, "And everywhere that Mary went");
+ this->RunTest(cygwin_clip, cygwin_clip, "The lamb was sure to go");
+ }
+
+private:
+ // Procedure to run a test.
+ // The string in 'str' is written to the clipboard using 'write'.
+ // Then the clipboard is read using 'read'.
+ // The string read should match 'str', i.e. we read back from the clipboard the same string we wrote to it.
+ void RunTest(const CClipboardAccess &write, const CClipboardAccess &read, const std::string &str)
+ {
+ static unsigned int count = 0;
+ std::cout << std::endl << "TEST " << (++count)
+ << ": Write using " << write.GetName()
+ << ", read using " << read.GetName() << '.' << std::endl;
+
+ write.ClearClipboard();
+ sleep(1);
+ read.ClearClipboard();
+ sleep(1);
+
+ std::cout << ">>> Setting " << write.GetName() << " to '" << str << "'." << std::endl;
+ write.SetClipboard(str);
+ sleep(1);
+ const std::string result = read.GetClipboard();
+ std::cout << ">>> Read " << read.GetName() << " = '" << result << "'." << std::endl;
+
+ if (result == str)
+ std::cout << ">>> OK - strings match." << std::endl;
+ else
+ std::cout << "*** FAILED." << std::endl;
+ }
+};
+
+int main(int argc, char **pargv)
+{
+ CTest test(argc, pargv);
+ test.GoTest();
+ return 0;
+}
+
diff --git a/test-invalid-net-wm-icon.c b/test-invalid-net-wm-icon.c
new file mode 100644
index 0000000..7ce9829
--- /dev/null
+++ b/test-invalid-net-wm-icon.c
@@ -0,0 +1,59 @@
+/* gcc test-invalid-net-wm-icon.c -o test-invalid-net-wm-icon.exe -lX11 */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include <X11/Xlib.h>
+
+Display *d;
+Window w;
+Atom net_wm_icon;
+Atom cardinal;
+
+void test(unsigned int *buffer, unsigned int buffer_length)
+{
+ int length = buffer_length/sizeof(unsigned int);
+ XChangeProperty(d, w, net_wm_icon, cardinal, 32,
+ PropModeReplace, (const unsigned char*) buffer, length);
+
+ XFlush(d);
+ sleep(1);
+}
+
+int main(int argc, char **argv)
+{
+ /* Invalid _NET_WM_ICO icons */
+ d = XOpenDisplay(0);
+ int s = DefaultScreen(d);
+ net_wm_icon = XInternAtom(d, "_NET_WM_ICON", False);
+ cardinal = XInternAtom(d, "CARDINAL", False);
+ XEvent e;
+ w = XCreateWindow(d, RootWindow(d, s), 0, 0, 200, 200, 0,
+ CopyFromParent, InputOutput, CopyFromParent, 0, 0);
+
+ XMapWindow(d, w);
+ XFlush(d);
+ sleep(1);
+
+ // sizes are just absurd
+ unsigned int buffer[] = {-1, -1, 0xFFFFFFFF, 0xFFFFFFFF};
+ test(buffer, sizeof(buffer));
+
+ // property should be 256K, but is only 64K
+ int propsize = 0x10000;
+ unsigned int *buffer2 = malloc(propsize);
+ buffer2[0] = 512;
+ buffer2[1] = 512;
+ test(buffer2, propsize);
+
+ // property is absurdly large, but still not enough for icon
+ propsize = 0x100000;
+ unsigned int *buffer3 = malloc(propsize);
+ assert(buffer3);
+ buffer2[0] = 0x3000;
+ buffer2[1] = 0x3000;
+ test(buffer3, propsize);
+
+ while(1) XNextEvent(d, &e);
+}
diff --git a/test-postion-window.c b/test-postion-window.c
new file mode 100644
index 0000000..e215b5f
--- /dev/null
+++ b/test-postion-window.c
@@ -0,0 +1,22 @@
+/*
+ gcc -Wall -o test-postion-window test-postion-window.c `pkg-config --cflags --libs gtk+-2.0`
+*/
+
+#include <gtk/gtk.h>
+
+int main( int argc,
+ char *argv[] )
+{
+ GtkWidget *tool_window;
+
+ gtk_init (&argc, &argv);
+
+ tool_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_container_set_border_width (GTK_CONTAINER (tool_window), 10);
+ gtk_window_move (GTK_WINDOW (tool_window), 100, 100);
+ gtk_widget_show (tool_window);
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/test.py b/test.py
new file mode 100644
index 0000000..efdd245
--- /dev/null
+++ b/test.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+import gtk
+import gio
+import pynotify
+
+
+def make_menu(event_button, event_time, icon):
+ menu = gtk.Menu()
+ item = gtk.MenuItem('quit')
+ item.connect('activate', quit, 'test')
+ item.show()
+ menu.append(item)
+ menu.popup(None, None,
+ gtk.status_icon_position_menu, event_button,
+ event_time, icon)
+
+def quit(menu_item, text):
+ print(text)
+ gtk.main_quit()
+
+def on_right_click(icon, event_button, event_time):
+ make_menu(event_button, event_time, icon)
+
+def help_cb(n, action):
+ print "action_callback"
+ gtk.main_quit()
+
+def StatusIconDemo(parent=None):
+ icon = gtk.status_icon_new_from_gicon(gio.ThemedIcon('calc'))
+ icon.connect('popup-menu', on_right_click)
+ pynotify.init("Test_PyNotify")
+ notification = pynotify.Notification("Test", "blubbels", "info")
+ notification.attach_to_status_icon(icon)
+ notification.show()
+
+if __name__ == '__main__':
+ StatusIconDemo()
+ gtk.main()
+