Hi,

I've successfully used xpra 0.0.5 (and now 0.0.6 on which these patches
are based) on that other OS using the new TCP mode.
(it may be possible to use ssh mode with plink - I haven't tried that)
You will obviously need to install python, pygtk, etc...

First patch moves some common stuff out of lowlevel (should be pretty
uncontroversial)
The second one is just annoying: "Due to limitations in the winsock
API..." , see:
http://faq.pygtk.org/index.py?req=all#20.20
so this patch re-creates a new listener (for both read and write) when
there are pending writes and re-creates the read-only listener when
not... it's not pretty, but it works and it only does anything when
running on Windows, on Linux the behaviour should be completely unchanged.
Next, we can't import some of the keyboard related stuff from lowlevel
into wimpiggy/keys.py so we load it (and use it) only on non "win*"
platforms. We probably need to do something to replace its
functionality, but since I don't really understand this part... maybe
later. Or maybe when this whole area gets revamped?
We currently ignore sendClientMessage from lowlevel on windows.
We remove an unused import from client.py and disable the new clipboard
(bummer!) as it uses some lowlevel X calls... (will try a better
approach for that later)
Finally, we obviously can't compile the pyrex/X stuff, so we need to
take this out when building on windows (building on windows will need
some more work so just build it on Linux and copy over for now)

Please consider applying (at least some of) these patches.

Thanks
Antoine
--- parti-all-0.0.6-as-sent/xpra/client.py	2009-03-22 22:19:43.000000000 +0700
+++ parti-all-0.0.6-dev/xpra/client.py	2009-03-22 23:07:43.000000000 +0700
@@ -8,11 +8,11 @@
 import cairo
 import os
 import os.path
+import sys
 
 from wimpiggy.util import (one_arg_signal,
                            gtk_main_quit_really,
                            gtk_main_quit_on_fatal_exceptions_enable)
-from wimpiggy.prop import prop_get
 from wimpiggy.keys import grok_modifier_map
 from wimpiggy.event import add_event_receiver
 
@@ -21,7 +21,6 @@
 
 from xpra.protocol import Protocol
 from xpra.keys import mask_to_names
-from xpra.clipboard import ClipboardProtocolHelper
 
 import xpra
 default_capabilities = {"deflate": 3,
@@ -292,7 +291,11 @@
         self._keymap.connect("keys-changed", self._keys_changed)
         self._keys_changed()
 
-        self._clipboard_helper = ClipboardProtocolHelper(self.send)
+        if not sys.platform.startswith("win"):
+            from xpra.clipboard import ClipboardProtocolHelper
+            self._clipboard_helper = ClipboardProtocolHelper(self.send)
+        else:
+            self._clipboard_helper = None    
 
         self._focused = None
 
@@ -330,7 +333,8 @@
         if capabilities.get("__prerelease_version") != xpra.__version__:
             log.error("sorry, I only know how to talk to v%s servers",
                       xpra.__version__)
-        self._clipboard_helper.send_all_tokens()
+        if self._clipboard_helper:
+            self._clipboard_helper.send_all_tokens()
 
     def _process_new_common(self, packet, override_redirect):
         (_, id, x, y, w, h, metadata) = packet
@@ -389,7 +393,8 @@
         packet_type = packet[0]
         if (isinstance(packet_type, str)
             and packet_type.startswith("clipboard-")):
-            self._clipboard_helper.process_clipboard_packet(packet)
+            if self._clipboard_helper:
+                self._clipboard_helper.process_clipboard_packet(packet)
         else:
             self._packet_handlers[packet_type](self, packet)
 
--- parti-all-0.0.6-as-sent/setup.py	2009-03-22 16:34:43.000000000 +0700
+++ parti-all-0.0.6-dev/setup.py	2009-03-22 22:33:47.000000000 +0700
@@ -15,8 +15,7 @@
 
 from distutils.core import setup
 from distutils.extension import Extension
-from Pyrex.Distutils import build_ext
-import commands, os
+import commands, os, sys
 
 # Tweaked from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/502261
 def pkgconfig(*packages, **kw):
@@ -53,6 +52,25 @@
   xpra:
     %s""" % (wimpiggy_desc, parti_desc, xpra_desc)
 
+if not sys.platform.startswith("win"):
+    from Pyrex.Distutils import build_ext
+    ext_modules=[ 
+      Extension("wimpiggy.lowlevel.bindings",
+                ["wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx"],
+                **pkgconfig("pygobject-2.0", "gdk-x11-2.0", "gtk+-x11-2.0",
+                            "xtst", "xfixes", "xcomposite", "xdamage")
+                ),
+      Extension("xpra.wait_for_x_server",
+                ["xpra/xpra.wait_for_x_server.pyx"],
+                **pkgconfig("x11")
+                ),
+      ]
+    # Turn on Pyrex-sensitivity:
+    cmdclass = {'build_ext': build_ext}
+else:
+    ext_modules=None
+    cmdclass={}
+
 setup(
     name="parti-all",
     author="Nathaniel Smith",
@@ -70,17 +88,6 @@
              "scripts/xpra",
              ],
     data_files = [("share/man/man1", ["xpra.1"])],
-    ext_modules=[ 
-      Extension("wimpiggy.lowlevel.bindings",
-                ["wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx"],
-                **pkgconfig("pygobject-2.0", "gdk-x11-2.0", "gtk+-x11-2.0",
-                            "xtst", "xfixes", "xcomposite", "xdamage")
-                ),
-      Extension("xpra.wait_for_x_server",
-                ["xpra/xpra.wait_for_x_server.pyx"],
-                **pkgconfig("x11")
-                ),
-      ],
-    # Turn on Pyrex-sensitivity:
-    cmdclass = {'build_ext': build_ext}
+    ext_modules=ext_modules,
+    cmdclass = cmdclass
     )
--- parti-all-0.0.6-as-sent/wimpiggy/lowlevel/__init__.py	2009-03-22 16:36:19.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/lowlevel/__init__.py	2009-03-22 22:47:47.000000000 +0700
@@ -3,11 +3,15 @@
 # Parti is released under the terms of the GNU GPL v2, or, at your option, any
 # later version. See the file COPYING for details.
 
-from wimpiggy.lowlevel.bindings import *
 
 from wimpiggy.log import Logger
 log = Logger()
 
+sendClientMessage=pass
+if not sys.platform.startswith("win"):
+    sendClientMessage = wimpiggy.lowlevel.bindings.sendClientMessage
+
+
 def send_wm_take_focus(target, time):
     log("sending WM_TAKE_FOCUS")
     sendClientMessage(target, False, 0,
Binary files parti-all-0.0.6-as-sent/wimpiggy/__init__.pyc and parti-all-0.0.6-dev/wimpiggy/__init__.pyc differ
diff -urN parti-all-0.0.6-as-sent/wimpiggy/keys.py parti-all-0.0.6-dev/wimpiggy/keys.py
--- parti-all-0.0.6-as-sent/wimpiggy/keys.py	2009-03-22 20:07:53.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/keys.py	2009-03-22 21:39:22.000000000 +0700
@@ -7,13 +7,14 @@
 import gtk
 from wimpiggy.util import one_arg_signal
 from wimpiggy.error import *
-from wimpiggy.lowlevel import (get_modifier_map, grab_key, ungrab_all_keys)
-
 from wimpiggy.event import add_event_receiver, remove_event_receiver
 from wimpiggy.util import get_display_for
 from wimpiggy.log import Logger
 log = Logger()
 
+get_modifier_map = None
+grab_key = None
+ungrab_all_keys = None
 class HotkeyManager(gobject.GObject):
     __gsignals__ = {
         "hotkey": (gobject.SIGNAL_RUN_LAST | gobject.SIGNAL_DETAILED,
@@ -26,6 +27,13 @@
         gobject.GObject.__init__(self)
         self.window = window
         self.hotkeys = {}
+        if not sys.platform.startswith("win"):
+                global get_modifier_map
+                global grab_key
+                global ungrab_all_keys
+		get_modifier_map = wimpiggy.lowlevel.get_modifier_map
+		grab_key = wimpiggy.lowlevel.grab_key
+		ungrab_all_keys = wimpiggy.lowlevel.ungrab_all_keys
 
         disp = get_display_for(self.window)
         self.keymap = gtk.gdk.keymap_get_for_display(disp)
@@ -61,7 +69,8 @@
             gtk.gdk.x11_ungrab_server()
 
     def _unbind_all(self):
-        ungrab_all_keys(self.window)
+        if ungrab_all_keys:
+            ungrab_all_keys(self.window)
 
     def _bind_all(self):
         self.normalized_hotkeys = {}
@@ -71,8 +80,9 @@
             for keycode in keycodes:
                 # Claim a passive grab on all the different forms of this key
                 for nuisance_mask in self.nuisances:
-                    grab_key(self.window, keycode,
-                             modifier_mask | nuisance_mask)
+                    if grab_key:
+                        grab_key(self.window, keycode,
+                                 modifier_mask | nuisance_mask)
                 # Save off the normalized form to make it easy to lookup later
                 # when we see the key appear
                 unparsed = unparse_key(modifier_mask, keycode,
@@ -134,21 +144,22 @@
         }
 
     disp = get_display_for(display_source)
-    (max_keypermod, keycodes) = get_modifier_map(disp)
-    assert len(keycodes) == 8 * max_keypermod
-    keymap = gtk.gdk.keymap_get_for_display(disp)
-    for i in range(8):
-        for j in range(max_keypermod):
-            keycode = keycodes[i * max_keypermod + j]
-            if keycode:
-                entries = keymap.get_entries_for_keycode(keycode)
-                if entries is None:
-                    # This keycode has no entry in the keymap:
-                    continue
-                for (keyval, _, _, _) in entries:
-                    keyval_name = gtk.gdk.keyval_name(keyval)
-                    if keyval_name in meanings:
-                        modifier_map[meanings[keyval_name]] |= (1 << i)
+    if get_modifier_map:
+        (max_keypermod, keycodes) = get_modifier_map(disp)
+        assert len(keycodes) == 8 * max_keypermod
+        keymap = gtk.gdk.keymap_get_for_display(disp)
+        for i in range(8):
+            for j in range(max_keypermod):
+                keycode = keycodes[i * max_keypermod + j]
+                if keycode:
+                    entries = keymap.get_entries_for_keycode(keycode)
+                    if entries is None:
+                        # This keycode has no entry in the keymap:
+                        continue
+                    for (keyval, _, _, _) in entries:
+                        keyval_name = gtk.gdk.keyval_name(keyval)
+                        if keyval_name in meanings:
+                            modifier_map[meanings[keyval_name]] |= (1 << i)
     modifier_map["nuisance"] = (modifier_map["lock"]
                                 | modifier_map["scroll"]
                                 | modifier_map["num"])
diff -urN parti-all-0.0.6-vanilla/wimpiggy/composite.py parti-all-0.0.6-dev/wimpiggy/composite.py
--- parti-all-0.0.6-vanilla/wimpiggy/composite.py	2009-03-22 16:35:46.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/composite.py	2009-03-22 20:03:35.000000000 +0700
@@ -12,9 +12,9 @@
                                xcomposite_name_window_pixmap,
                                xdamage_start, xdamage_stop,
                                xdamage_acknowledge,
-                               add_event_receiver, remove_event_receiver,
                                get_parent, addXSelectInput, const,
                                geometry_with_border)
+from wimpiggy.event import add_event_receiver, remove_event_receiver
 
 from wimpiggy.log import Logger
 log = Logger()
diff -urN parti-all-0.0.6-vanilla/wimpiggy/event.py parti-all-0.0.6-dev/wimpiggy/event.py
--- parti-all-0.0.6-vanilla/wimpiggy/event.py	1970-01-01 07:00:00.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/event.py	2009-03-22 19:47:27.000000000 +0700
@@ -0,0 +1,45 @@
+# This file is part of Parti.
+# Copyright (C) 2008, 2009 Nathaniel Smith <[email protected]>
+# Parti is released under the terms of the GNU GPL v2, or, at your option, any
+# later version. See the file COPYING for details.
+
+import types
+import gobject
+from wimpiggy.log import Logger
+log = Logger()
+
+_ev_receiver_key = "wimpiggy-route-events-to"
+def add_event_receiver(window, receiver):
+    receivers = window.get_data(_ev_receiver_key)
+    if receivers is None:
+        receivers = set()
+    if receiver not in receivers:
+        receivers.add(receiver)
+    window.set_data(_ev_receiver_key, receivers)
+
+def remove_event_receiver(window, receiver):
+    receivers = window.get_data(_ev_receiver_key)
+    if receivers is None:
+        return
+    receivers.discard(receiver)
+    if not receivers:
+        receivers = None
+    window.set_data(_ev_receiver_key, receivers)
+
+def _maybe_send_event(window, signal, event):
+    handlers = window.get_data(_ev_receiver_key)
+    if handlers is not None:
+        # Copy the 'handlers' list, because signal handlers might cause items
+        # to be added or removed from it while we are iterating:
+        for handler in list(handlers):
+            if signal in gobject.signal_list_names(handler):
+                log("  forwarding event to a %s handler's %s signal",
+                    type(handler).__name__, signal)
+                handler.emit(signal, event)
+                log("  forwarded")
+            else:
+                log("  not forwarding to %s handler, it has no %s signal",
+                    type(handler).__name__, signal)
+    else:
+        log("  no handler registered for this window, ignoring event")
+
diff -urN parti-all-0.0.6-vanilla/wimpiggy/keys.py parti-all-0.0.6-dev/wimpiggy/keys.py
--- parti-all-0.0.6-vanilla/wimpiggy/keys.py	2009-03-22 16:35:58.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/keys.py	2009-03-22 19:57:37.000000000 +0700
@@ -7,10 +7,10 @@
 import gtk
 from wimpiggy.util import one_arg_signal
 from wimpiggy.error import *
-from wimpiggy.lowlevel import (get_display_for,
-                               get_modifier_map, grab_key, ungrab_all_keys,
-                               add_event_receiver, remove_event_receiver)
+from wimpiggy.lowlevel import (get_modifier_map, grab_key, ungrab_all_keys)
 
+from wimpiggy.event import add_event_receiver, remove_event_receiver
+from wimpiggy.util import get_display_for
 from wimpiggy.log import Logger
 log = Logger()
 
diff -urN parti-all-0.0.6-vanilla/wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx parti-all-0.0.6-dev/wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx
--- parti-all-0.0.6-vanilla/wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx	2009-03-22 16:36:25.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/lowlevel/wimpiggy.lowlevel.bindings.pyx	2009-03-22 20:02:49.000000000 +0700
@@ -14,7 +14,8 @@
 import gtk
 import gtk.gdk
 
-from wimpiggy.util import dump_exc, LameStruct, gtk_main_quit_really
+from wimpiggy.util import dump_exc, LameStruct, gtk_main_quit_really, get_display_for
+from wimpiggy.event import _maybe_send_event
 from wimpiggy.error import trap, XError
 
 from wimpiggy.log import Logger
@@ -336,16 +337,6 @@
         raise XError, BadWindow
     return win
 
-def get_display_for(obj):
-    if isinstance(obj, gtk.gdk.Display):
-        return obj
-    elif isinstance(obj, (gtk.gdk.Drawable,
-                          gtk.Widget,
-                          gtk.Clipboard)):
-        return obj.get_display()
-    else:
-        raise TypeError, "Don't know how to get a display from %r" % (obj,)
-
 cdef cGdkDisplay * get_raw_display_for(obj) except? NULL:
     return <cGdkDisplay*> unwrap(get_display_for(obj), gtk.gdk.Display)
 
@@ -1125,41 +1116,6 @@
 # client that owns the window they are sent to, otherwise they go to any
 # clients that are selecting for that mask they are sent with.
 
-_ev_receiver_key = "wimpiggy-route-events-to"
-def add_event_receiver(window, receiver):
-    receivers = window.get_data(_ev_receiver_key)
-    if receivers is None:
-        receivers = set()
-    if receiver not in receivers:
-        receivers.add(receiver)
-    window.set_data(_ev_receiver_key, receivers)
-
-def remove_event_receiver(window, receiver):
-    receivers = window.get_data(_ev_receiver_key)
-    if receivers is None:
-        return
-    receivers.discard(receiver)
-    if not receivers:
-        receivers = None
-    window.set_data(_ev_receiver_key, receivers)
-
-def _maybe_send_event(window, signal, event):
-    handlers = window.get_data(_ev_receiver_key)
-    if handlers is not None:
-        # Copy the 'handlers' list, because signal handlers might cause items
-        # to be added or removed from it while we are iterating:
-        for handler in list(handlers):
-            if signal in gobject.signal_list_names(handler):
-                log("  forwarding event to a %s handler's %s signal",
-                    type(handler).__name__, signal)
-                handler.emit(signal, event)
-                log("  forwarded")
-            else:
-                log("  not forwarding to %s handler, it has no %s signal",
-                    type(handler).__name__, signal)
-    else:
-        log("  no handler registered for this window, ignoring event")
-
 def _route_event(event, signal, parent_signal):
     # Sometimes we get GDK events with event.window == None, because they are
     # for windows we have never created a GdkWindow object for, and GDK
diff -urN parti-all-0.0.6-vanilla/wimpiggy/prop.py parti-all-0.0.6-dev/wimpiggy/prop.py
--- parti-all-0.0.6-vanilla/wimpiggy/prop.py	2009-03-22 16:36:30.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/prop.py	2009-03-22 19:53:12.000000000 +0700
@@ -16,7 +16,7 @@
 from wimpiggy.lowlevel import \
      XGetWindowProperty, XChangeProperty, PropertyError, \
      get_xatom, get_pyatom, get_xwindow, get_pywindow, const, \
-     get_display_for, premultiply_argb_in_place
+     premultiply_argb_in_place
 from wimpiggy.error import trap, XError
 from wimpiggy.log import Logger
 log = Logger()
diff -urN parti-all-0.0.6-vanilla/wimpiggy/selection.py parti-all-0.0.6-dev/wimpiggy/selection.py
--- parti-all-0.0.6-vanilla/wimpiggy/selection.py	2009-03-22 16:36:36.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/selection.py	2009-03-22 19:59:57.000000000 +0700
@@ -15,8 +15,8 @@
 
 from wimpiggy.util import no_arg_signal, one_arg_signal
 from wimpiggy.lowlevel import (get_xatom, get_pywindow, sendClientMessage,
-                               myGetSelectionOwner, const,
-                               add_event_receiver, remove_event_receiver)
+                               myGetSelectionOwner, const)
+from wimpiggy.event import add_event_receiver, remove_event_receiver
 from wimpiggy.error import *
 
 from wimpiggy.log import Logger
diff -urN parti-all-0.0.6-vanilla/wimpiggy/test_selection.py parti-all-0.0.6-dev/wimpiggy/test_selection.py
--- parti-all-0.0.6-vanilla/wimpiggy/test_selection.py	2009-03-22 16:36:56.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/test_selection.py	2009-03-22 20:00:28.000000000 +0700
@@ -6,6 +6,7 @@
 from wimpiggy.test import *
 from wimpiggy.selection import ManagerSelection, AlreadyOwned
 import wimpiggy.lowlevel
+from wimpiggy.event import add_event_receiver
 
 import struct
 
@@ -46,7 +47,7 @@
         d2 = self.clone_display()
         root2 = d2.get_default_screen().get_root_window()
         root2.set_events(gtk.gdk.STRUCTURE_MASK)
-        wimpiggy.lowlevel.add_event_receiver(root2, self)
+        add_event_receiver(root2, self)
         d2.flush()
         self.event = None
 
diff -urN parti-all-0.0.6-vanilla/wimpiggy/util.py parti-all-0.0.6-dev/wimpiggy/util.py
--- parti-all-0.0.6-as-sent/wimpiggy/util.py	2009-03-22 20:07:53.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/util.py	2009-03-22 21:35:48.000000000 +0700
@@ -7,6 +7,7 @@
 import sys
 import types
 import gobject
+import gtk
 
 class AutoPropGObjectMixin(object):
     """Mixin for automagic property support in GObjects.
--- parti-all-0.0.6-vanilla/wimpiggy/util.py	2009-03-22 16:37:05.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/util.py	2009-03-22 19:48:09.000000000 +0700
@@ -60,6 +60,16 @@
 one_arg_signal = n_arg_signal(1)
 
 
+def get_display_for(obj):
+    if isinstance(obj, gtk.gdk.Display):
+        return obj
+    elif isinstance(obj, (gtk.gdk.Drawable,
+                          gtk.Widget,
+                          gtk.Clipboard)):
+        return obj.get_display()
+    else:
+        raise TypeError, "Don't know how to get a display from %r" % (obj,)
+
 # Collects the results from signal handlers for a given signal into a list,
 # ignoring all handlers that return None.  (This filtering is useful because
 # the intended use of this method is to "poll" all connected objects, so it's
diff -urN parti-all-0.0.6-vanilla/wimpiggy/window.py parti-all-0.0.6-dev/wimpiggy/window.py
--- parti-all-0.0.6-vanilla/wimpiggy/window.py	2009-03-22 16:37:10.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/window.py	2009-03-22 19:59:27.000000000 +0700
@@ -20,6 +20,8 @@
 from wimpiggy.util import (AutoPropGObjectMixin,
                            one_arg_signal, n_arg_signal,
                            non_none_list_accumulator)
+from wimpiggy.event import add_event_receiver, remove_event_receiver
+from wimpiggy.util import get_display_for
 from wimpiggy.error import *
 from wimpiggy.prop import prop_get, prop_set
 from wimpiggy.composite import CompositeHelper
@@ -214,7 +216,7 @@
 
         self.client_window = client_window
         self._internal_set_property("client-window", client_window)
-        wimpiggy.lowlevel.add_event_receiver(client_window, self)
+        add_event_receiver(client_window, self)
 
         def setup():
             # Keith Packard says that composite state is undefined following a
@@ -256,7 +258,7 @@
         self.emit("unmanaged", exiting)
 
     def do_unmanaged(self, wm_exiting):
-        wimpiggy.lowlevel.remove_event_receiver(self.client_window, self)
+        remove_event_receiver(self.client_window, self)
         self._composite.disconnect(self._damage_forward_handle)
         self._composite.destroy()
 
@@ -419,7 +421,7 @@
                                             wclass=gtk.gdk.INPUT_OUTPUT,
                                             event_mask=gtk.gdk.PROPERTY_CHANGE_MASK)
         wimpiggy.lowlevel.substructureRedirect(self.corral_window)
-        wimpiggy.lowlevel.add_event_receiver(self.corral_window, self)
+        add_event_receiver(self.corral_window, self)
         log("created corral window 0x%x", self.corral_window.xid)
 
         # The WM_HINTS input field
@@ -686,7 +688,7 @@
             # actually display-clean.  Oh well.
             pixmap = gtk.gdk.Pixmap(None,
                                     surf.get_width(), surf.get_height(), 32)
-            screen = wimpiggy.lowlevel.get_display_for(pixmap).get_default_screen()
+            screen = get_display_for(pixmap).get_default_screen()
             pixmap.set_colormap(screen.get_rgba_colormap())
             cr = pixmap.cairo_create()
             cr.set_source_surface(surf)
diff -urN parti-all-0.0.6-vanilla/wimpiggy/wm.py parti-all-0.0.6-dev/wimpiggy/wm.py
--- parti-all-0.0.6-vanilla/wimpiggy/wm.py	2009-03-22 16:37:13.000000000 +0700
+++ parti-all-0.0.6-dev/wimpiggy/wm.py	2009-03-22 19:58:18.000000000 +0700
@@ -14,6 +14,7 @@
 import wimpiggy.lowlevel
 from wimpiggy.prop import prop_set
 from wimpiggy.util import no_arg_signal, one_arg_signal
+from wimpiggy.event import add_event_receiver
 
 from wimpiggy.window import WindowModel, Unmanageable
 
@@ -177,7 +178,7 @@
 
         # Okay, ready to select for SubstructureRedirect and then load in all
         # the existing clients.
-        wimpiggy.lowlevel.add_event_receiver(self._root, self)
+        add_event_receiver(self._root, self)
         wimpiggy.lowlevel.substructureRedirect(self._root)
 
         for w in wimpiggy.lowlevel.get_children(self._root):
diff -urN parti-all-0.0.6-vanilla/xpra/client.py parti-all-0.0.6-dev/xpra/client.py
--- parti-all-0.0.6-vanilla/xpra/client.py	2009-03-22 16:43:35.000000000 +0700
+++ parti-all-0.0.6-dev/xpra/client.py	2009-03-22 20:03:51.000000000 +0700
@@ -14,7 +14,7 @@
                            gtk_main_quit_on_fatal_exceptions_enable)
 from wimpiggy.prop import prop_get
 from wimpiggy.keys import grok_modifier_map
-from wimpiggy.lowlevel import add_event_receiver, remove_event_receiver
+from wimpiggy.event import add_event_receiver
 
 from wimpiggy.log import Logger
 log = Logger()
diff -urN parti-all-0.0.6-vanilla/xpra/server.py parti-all-0.0.6-dev/xpra/server.py
--- parti-all-0.0.6-vanilla/xpra/server.py	2009-03-22 16:44:21.000000000 +0700
+++ parti-all-0.0.6-dev/xpra/server.py	2009-03-22 20:04:19.000000000 +0700
@@ -25,8 +25,8 @@
                                xtest_fake_key,
                                xtest_fake_button,
                                is_override_redirect, is_mapped,
-                               add_event_receiver,
                                get_children)
+from wimpiggy.event import add_event_receiver
 from wimpiggy.window import OverrideRedirectWindowModel, Unmanageable
 from wimpiggy.keys import grok_modifier_map
 from wimpiggy.error import XError, trap
--- parti-all-0.0.6-as-sent/xpra/client.py	2009-03-22 22:19:43.000000000 +0700
+++ parti-all-0.0.6-dev/xpra/client.py	2009-03-22 22:59:16.000000000 +0700
@@ -12,7 +12,6 @@
 from wimpiggy.util import (one_arg_signal,
                            gtk_main_quit_really,
                            gtk_main_quit_on_fatal_exceptions_enable)
-from wimpiggy.prop import prop_get
 from wimpiggy.keys import grok_modifier_map
 from wimpiggy.event import add_event_receiver
 
diff -urN parti-all-0.0.6-as-sent/xpra/protocol.py parti-all-0.0.6-dev/xpra/protocol.py
--- parti-all-0.0.6-as-sent/xpra/protocol.py	2009-03-22 16:43:54.000000000 +0700
+++ parti-all-0.0.6-dev/xpra/protocol.py	2009-03-22 20:54:36.000000000 +0700
@@ -13,6 +13,10 @@
 from wimpiggy.log import Logger
 log = Logger()
 
+import sys
+winsock = sys.platform.startswith("win")
+
+
 def repr_ellipsized(obj, limit):
     if isinstance(obj, str) and len(obj) > limit:
         return repr(obj[:limit]) + "..."
@@ -50,11 +54,23 @@
         if want_write == write_armed:
             return
         if want_write:
-            self._write_tag = gobject.io_add_watch(self._sock, gobject.IO_OUT,
+            if winsock:
+		# winsock is limited to one io watch, so we must re-create one for both read and write
+                gobject.source_remove(self._read_tag)
+                self._write_tag = gobject.io_add_watch(self._sock, gobject.IO_OUT | gobject.IO_IN,
+                                                   self._socket_rw)
+
+            else:
+                self._write_tag = gobject.io_add_watch(self._sock, gobject.IO_OUT,
                                                    self._socket_writeable)
         else:
             gobject.source_remove(self._write_tag)
             self._write_tag = None
+            if winsock:
+		# winsock: must create a new read watch
+                self._read_tag = gobject.io_add_watch(self._sock, gobject.IO_IN,
+                                              self._socket_readable)
+
 
     def _flush_one_packet_into_buffer(self):
         if not self.source:
@@ -73,12 +89,22 @@
         self._accept_packets = False
         self._process_packet_cb(self, [Protocol.CONNECTION_LOST])
 
+    def _socket_rw(self, source, cb_condition, *args):
+        assert winsock
+        if cb_condition & gobject.IO_OUT:
+            self._socket_writeable(source, cb_condition, args)
+        if cb_condition & gobject.IO_IN:
+            self._socket_readable(source, cb_condition, args)
+        return True
+
     def _socket_writeable(self, *args):
         if not self._write_buf:
             # Underflow: refill buffer from source.
-            # We can't get into this function at all unless either _write_buf
-            # is non-empty, or _source_has_more == True, because of the guard
-            # in _update_write_watch.
+            # On non-winsock platforms we can't get into this function at all
+            # unless either _write_buf is non-empty, or _source_has_more == True,
+            # because of the guard in _update_write_watch.
+            if winsock and not self._source_has_more:
+                return
             assert self._source_has_more
             self._flush_one_packet_into_buffer()
         try:

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Parti-discuss mailing list
[email protected]
http://lists.partiwm.org/cgi-bin/mailman/listinfo/parti-discuss

Reply via email to