| 1 |
# WinDictator: |
|---|
| 2 |
# Dictate in Windows, have the text typed in Linux via X faked keystroke events |
|---|
| 3 |
# |
|---|
| 4 |
# Copyright (C) 2005-2006 by Edwin A. Suominen, http://www.eepatents.com |
|---|
| 5 |
# |
|---|
| 6 |
# This program is free software; you can redistribute it and/or modify it under |
|---|
| 7 |
# the terms of the GNU General Public License as published by the Free Software |
|---|
| 8 |
# Foundation; either version 2 of the License, or (at your option) any later |
|---|
| 9 |
# version. |
|---|
| 10 |
# |
|---|
| 11 |
# This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 12 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|---|
| 13 |
# FOR A PARTICULAR PURPOSE. See the file COPYING for more details. |
|---|
| 14 |
# |
|---|
| 15 |
# You should have received a copy of the GNU General Public License along with |
|---|
| 16 |
# this program; if not, write to the Free Software Foundation, Inc., 51 |
|---|
| 17 |
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
""" |
|---|
| 21 |
Twisted Perspective Broker server that runs as a Windows service, waiting for a |
|---|
| 22 |
Linux client to connect to it and accept text for virtual typing. |
|---|
| 23 |
""" |
|---|
| 24 |
|
|---|
| 25 |
from twisted.spread.pb import Root, PBServerFactory |
|---|
| 26 |
from twisted.internet import defer, reactor |
|---|
| 27 |
|
|---|
| 28 |
import dictate |
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
class Server(Root): |
|---|
| 32 |
""" |
|---|
| 33 |
I provide a method for remote clients to tell me their root object, if no |
|---|
| 34 |
other clients are connected, and a data sink method for sending text to the |
|---|
| 35 |
connected remote client. |
|---|
| 36 |
|
|---|
| 37 |
@ivar d: A C{Deferred} that fires when my GUI application shuts down. |
|---|
| 38 |
""" |
|---|
| 39 |
def __init__(self): |
|---|
| 40 |
""" |
|---|
| 41 |
Instantiates me with a GUI application window and a C{Deferred} that |
|---|
| 42 |
will fire when the GUI application shuts down. |
|---|
| 43 |
""" |
|---|
| 44 |
self.window = dictate.TextWindow() |
|---|
| 45 |
|
|---|
| 46 |
def remote_greeter(self, clientRoot): |
|---|
| 47 |
""" |
|---|
| 48 |
First remote method run by client. If another client is connected, |
|---|
| 49 |
returns an informative rejection. Otherwise, sets my clientRoot |
|---|
| 50 |
attribute to the remote client's root object |
|---|
| 51 |
|
|---|
| 52 |
""" |
|---|
| 53 |
if getattr(self, 'clientRoot', None) is not None: |
|---|
| 54 |
# Status: No connection |
|---|
| 55 |
return False |
|---|
| 56 |
else: |
|---|
| 57 |
# The text updater |
|---|
| 58 |
updater = dictate.TextUpdater(clientRoot) |
|---|
| 59 |
# Get the application running, and chain my deferred to its |
|---|
| 60 |
# shutdown deferred |
|---|
| 61 |
self.window.run(updater) |
|---|
| 62 |
# Indicate that we're connected |
|---|
| 63 |
self.window.label("Connected") |
|---|
| 64 |
# Status: Connected |
|---|
| 65 |
return True |
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 |
class ServerFactory(PBServerFactory): |
|---|
| 69 |
""" |
|---|
| 70 |
Customized version of L{PBServerFactory} that provides a disconnection |
|---|
| 71 |
callback. |
|---|
| 72 |
""" |
|---|
| 73 |
def __init__(self, serverRoot): |
|---|
| 74 |
self.__serverRoot = serverRoot |
|---|
| 75 |
PBServerFactory.__init__(self, serverRoot) |
|---|
| 76 |
|
|---|
| 77 |
def clientConnectionMade(self, protocol): |
|---|
| 78 |
""" |
|---|
| 79 |
This method is intended to be defined by L{PBServerFactory} subclasses, |
|---|
| 80 |
and does so here to take care of my special disconnection needs. |
|---|
| 81 |
""" |
|---|
| 82 |
def disconnected(): |
|---|
| 83 |
self.__serverRoot.clientRoot = None |
|---|
| 84 |
self.__serverRoot.window.label("Disconnected") |
|---|
| 85 |
|
|---|
| 86 |
protocol.notifyOnDisconnect(disconnected) |
|---|
| 87 |
|
|---|
| 88 |
|
|---|
| 89 |
def startServer(port): |
|---|
| 90 |
""" |
|---|
| 91 |
Starts a PB server and sits around. Does NOT return. |
|---|
| 92 |
""" |
|---|
| 93 |
serverRoot = Server() |
|---|
| 94 |
reactor.listenTCP(port, ServerFactory(serverRoot)) |
|---|
| 95 |
reactor.run() |
|---|
| 96 |
# Here there be Tygers |
|---|