commit do client
authorJônatas Isvi <jonatas@nona-desktop.(none)>
Thu, 4 Jun 2009 05:12:33 +0000 (01:12 -0400)
committerJônatas Isvi <jonatas@nona-desktop.(none)>
Thu, 4 Jun 2009 05:12:33 +0000 (01:12 -0400)
17 files changed:
pcremote-client/connection/__init__.py [new file with mode: 0755]
pcremote-client/connection/bluetoothconnectionmanager.py [new file with mode: 0755]
pcremote-client/connection/genericconnectionmanager.py [new file with mode: 0755]
pcremote-client/connection/iconnection.py [new file with mode: 0755]
pcremote-client/connection/wirelessconnectionmanager.py [new file with mode: 0755]
pcremote-client/edje_objects.py [new file with mode: 0755]
pcremote-client/kineticlist.py [new file with mode: 0755]
pcremote-client/pcremote-client.py [new file with mode: 0755]
pcremote-client/pcremote.edj [new file with mode: 0755]
pcremote-client/pcremote26.png [new file with mode: 0755]
pcremote-client/pcremote40.png [new file with mode: 0755]
pcremote-client/pcremote64.png [new file with mode: 0755]
pcremote-client/screenmanager.py [new file with mode: 0755]
pcremote-client/slide.edj [new file with mode: 0755]
pcremote-client/tablet.edj [new file with mode: 0755]
pcremote-client/utils/__init__.py [new file with mode: 0755]
pcremote-client/utils/labels.py [new file with mode: 0755]

diff --git a/pcremote-client/connection/__init__.py b/pcremote-client/connection/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/pcremote-client/connection/bluetoothconnectionmanager.py b/pcremote-client/connection/bluetoothconnectionmanager.py
new file mode 100755 (executable)
index 0000000..dc23b72
--- /dev/null
@@ -0,0 +1,216 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : Jônatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Version      : 1.0
+#  Description  : BluetoothConnectionManager
+#  ============================================================================
+
+
+import bluetooth
+from exceptions import *
+from   genericconnectionmanager import *
+
+class BluetoothConnectionError(Exception):
+    pass
+
+class BluetoothConnectionManager(GenericConnectionManager):
+
+        def __init__(self):    
+               GenericConnectionManager.__init__(self)
+               print "BluetoothConnectionManager iniciado."
+               # globals data variables
+               self.sock           =    None
+               self.port           =    None
+               self.address        =    None
+               self.client_sock    =    None
+               self.client_address =    None           
+
+       # fast way to create a simple server
+       def create_server(self, protocol, port):
+               self.create_socket(protocol)
+               self.set_port(port)
+               self.bind()
+               self.listen()
+               self.accept()
+
+       # fast way to create a simple client    
+       def create_client(self, protocol, address, port):
+               self.create_socket(protocol)
+               self.set_address(address)
+               self.set_port(port)
+               self.connect()
+
+       # search for all devices
+       def find_devices(self, time=8):
+               list_devices = bluetooth.discover_devices(lookup_names = True, duration=time)
+               if list_devices:
+                       return list_devices
+               else:
+                       raise BluetoothConnectionError, "Device were not found." 
+       
+        # search the device port
+       def find_port(self, addr):
+               port = None
+               aux = addr.split(":")
+               if len(aux) == 6:
+                       services = bluetooth.find_service(address=addr)
+                       for i in range(len(services)):
+                               port = services[i]['port']
+                
+                       if port != None:        
+                               return port
+                       else:
+                               raise BluetoothConnectionError, "Port not found."
+                               
+               else:
+                       raise BluetoothConnectionError, "Invalid address."
+        
+        # search device services
+       def find_services(self, service=None, addr=None):
+               if service == None and addr == None:
+                       list = bluetooth.find_service()
+                       # returns all services
+                       return list
+               elif service != None and addr == None:
+                       list = bluetooth.find_service(name=service)
+                       # returns only the device services indicated by name
+                       if list != []:
+                               return list
+                       else:
+                               raise BluetoothConnectionError, "Name of the service does not exist."
+               elif service == None and addr != None:
+                       number = addr.split(":")
+                       # returns only the device services indicated by address
+                       if(len(number) == 6):
+                               list = bluetooth.find_service(address=addr)
+                               if list != []:
+                                       return list
+                               else:
+                                       raise BluetoothConnectionError, "Services not found."
+                       else:
+                               raise BluetoothConnectionError, "Invalid address."
+               elif service != None and addr != None:
+                       number = addr.split(":")
+                       # returns only the device service indicated by address
+                       if(len(number) == 6):
+                               list = bluetooth.find_service(name=service, address=addr)
+                               if list != []:
+                                       return list
+                               else:
+                                       raise BluetoothConnectionError, "Services not found."
+                       else:
+                               raise BluetoothConnectionError, "Invalid address."
+       
+
+       # search the device indicated by name
+       def find_device_address_by_name(self, device_name):     
+               list = bluetooth.discover_devices()
+               addr = None
+               
+               for address in list:
+                       if device_name == bluetooth.lookup_name(address):
+                               addr = address
+                               break
+               if addr:
+                       return addr
+               else:
+                       raise BluetoothConnectionError, "Device name not found."
+       
+
+       def find_devices_only_names(self):
+               list = self.find_devices()
+               list_names = []
+               for address, names in list:
+                       list_names += [names]
+       
+               if list_names:
+                       return list_names
+               else:
+                       raise BluetoothConnectionError, "Devices were not found."
+
+       # get the client address
+       def get_client_address(self):
+               return self.client_address      
+
+       # set the port to communicate
+       def set_port(self, port):
+               self.port = port
+
+       # get the port to communicate
+       def get_port(self):
+               return self.port
+
+       # set the device address
+       def set_address(self, address):
+               aux = address.split(":")
+               if len(aux) == 6:
+                       self.address = address
+               else:
+                       raise BluetoothConnectionError, "Invalid address."
+
+       # get the device address
+       def get_address(self):
+               return self.address
+
+       # create a socket with a determinated protocol
+       def create_socket(self, protocol=None):
+               if protocol == 'rfcomm' or protocol == 'RFCOMM':
+                       self.sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
+               elif protocol == 'l2cap' or protocol == 'L2CAP':
+                       self.sock = bluetooth.BluetoothSocket(bluetooth.L2CAP)
+               else:   
+                       raise BluetoothConnectionError, "Undefined Protocol."
+
+       # bind the communication
+       def bind(self):
+               self.sock.bind(("", self.get_port()))
+
+       # just listen the tube, only to server
+       def listen(self):
+               self.sock.listen(1)
+
+       # accept the client communication
+       # returns an object 
+       def accept(self):
+               self.client_sock, self.client_address = self.sock.accept()
+               
+       # connect devices
+        def connect(self):
+               self.sock.connect((self.get_address(), self.get_port()))
+
+       # send string message           
+       def send_message(self, msg=None):
+               self.sock.send(msg)
+
+       # receive string message
+       def received_message(self):
+               return self.client_sock.recv(1024)
+
+       # close connection
+       def close(self):
+               if self.sock != None and self.client_sock != None:
+                       self.client_sock.close()
+                       self.sock.close()       
+               elif self.sock != None and self.client_sock == None:
+                       self.sock.close()
+               else:
+                       self.client_sock.close()
+
diff --git a/pcremote-client/connection/genericconnectionmanager.py b/pcremote-client/connection/genericconnectionmanager.py
new file mode 100755 (executable)
index 0000000..9eb3f85
--- /dev/null
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : André Portela
+#  Email        : andre_portela@hotmail.com
+#  Version      : 1.0
+#  Description  : GenericConnectionManager Class
+#  ============================================================================
+
+
+class GenericConnectionManager:
+       
+       def __init__(self):
+               print "GenericConnectionManager iniciado."
+               self.tipo = "generico"
+
+       def identify_app(self):
+               print "identify_app"
diff --git a/pcremote-client/connection/iconnection.py b/pcremote-client/connection/iconnection.py
new file mode 100755 (executable)
index 0000000..118358d
--- /dev/null
@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : André Portela
+#  Email        : andre_portela_@hotmail.com
+#  Reviewer     : Jônatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Version      : 1.0
+#  Description  : Interface Class, connection manager
+#  ============================================================================
+
+from wirelessconnectionmanager import *
+from bluetoothconnectionmanager import *
+from exceptions import *
+
+
+# connections aliases
+_btconst   = ['bluetooth', 'BLUETOOTH', 'blue']
+_wificonst = ['wireless', 'WIRELESS', 'wifi']
+
+class Iconnection:
+       def __init__(self, string):
+               self.string = string
+               if(self.string in _btconst):
+                       self.obj = BluetoothConnectionManager()
+               elif(self.string in _wificonst):
+                       self.obj = WirelessConnectionManager()
+               else:
+                       raise IconnectionError, "Undefined type."
+       
+       
+       # ********************************************************************************
+       # Generic methods -> Wireless and Bluetooth                                      *
+       # ********************************************************************************
+
+       # create a socket with defined protocol
+       def create_socket(self, protocol=None):
+               self.obj.create_socket(protocol)
+
+       # connect device
+       def connect(self):
+               self.obj.connect()
+
+       # accept the connection
+       def accept(self):
+               return self.obj.accept()
+
+       # send a message to device
+       def send_message(self, msg=None):
+               self.obj.send_message(msg)
+       
+       # received a message 
+       def received_message(self):
+               return self.obj.received_message()
+       
+       # bind the connection
+       def bind(self):
+               self.obj.bind()
+
+       # listen the connection
+       def listen(self):
+               self.obj.listen()
+
+       # close connection
+       def close(self):
+               self.obj.close()
+
+       # set the port to communicate
+       def set_port(self, port):
+               self.obj.set_port(port)
+
+       # get the port to communicate
+       def get_port(self):
+               return self.obj.get_port()
+
+       # set the device address
+       def set_address(self, address):
+               self.obj.set_address(address)
+
+       # get the device address
+       def get_address(self):
+               return self.obj.get_address()
+
+       # get the client address
+       def get_client_address(self):
+               return self.obj.get_client_address()
+
+       # ************************************************************************************
+       # Bluetooth methods - All methods for bluetooth services                             *
+       # ************************************************************************************
+       
+       # fast way to create a simple server
+       def bt_create_server(self, protocol, port):
+               if self.string in _btconst:
+                       return self.obj.create_server(protocol, port)
+               else:
+                       raise IconnectionError, "Only method used by Bluetooth connections."
+
+       # fast way to create a simple client
+       def bt_create_client(self, protocol, address, port):
+               if self.string in _btconst:
+                       return self.obj.create_client(protocol, address, port)
+               else:
+                       raise IconnectionError, "Only method used by Bluetooth connections."
+
+       # search for all devices
+       def bt_find_devices(self, time=8):
+               if self.string in _btconst:
+                       return self.obj.find_devices(time)
+               else:
+                       raise IconnectionError, "Only method used by Bluetooth connections."
+
+       # search only devices names
+       def bt_find_devices_only_names(self):
+               if self.string in _btconst:
+                       return self.obj.find_devices_only_names()
+               else:   
+                       raise IconnectionError, "Only method used by Bluetooth connections."
+
+       
+       # search the device port
+       def bt_find_port(self, addr):
+               if self.string in _btconst:
+                       return self.obj.find_port(addr)
+               else:   
+                       raise IconnectionError, "Only method used by Bluetooth connections."
+
+
+       # search device services
+       def bt_find_services(self, service=None, addr=None):
+               if self.string in _btconst:
+                       return self.obj.find_services(service, addr)
+               else:
+                       raise IconnectionError, "Only method used by Bluetooth connections."
+
+
+       # search the device indicated by name
+       def bt_find_device_address_by_name(self, device_name=None):
+               if self.string in _btconst:
+                       return self.obj.find_device_address_by_name(device_name)
+               else:
+                       raise IconnectionError, "Only method used by Bluetooth connections."
+
+
+
+       # ***********************************************************************************
+       # Wireless method - All methods for wireless services                               * 
+       # ***********************************************************************************
diff --git a/pcremote-client/connection/wirelessconnectionmanager.py b/pcremote-client/connection/wirelessconnectionmanager.py
new file mode 100755 (executable)
index 0000000..7b94774
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : André Portela
+#  Email        : andre_portela_@hotmail.com
+#  Version      : 0.1
+#  Description  : Tablet Application Wireless Connection Manager Class
+#  ============================================================================
+
+from genericconnectionmanager import * 
+
+class WirelessConnectionManager(GenericConnectionManager):
+       def __init__(self):
+               GenericConnectionManager.__init__(self)
+               #para acessar facilmente qualquer metodo generico
+               #self.super = generico()
+               print "init do Wireless"
+               self.tipo = "wireless"
+
+       def metodo(self):
+               print "(Wireless)Metodo do", self.tipo
+
+
diff --git a/pcremote-client/edje_objects.py b/pcremote-client/edje_objects.py
new file mode 100755 (executable)
index 0000000..1cd5244
--- /dev/null
@@ -0,0 +1,359 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# ****************************************************************************
+# Copyright (c) 2008 INdT/Fucapi.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# ============================================================================
+# Project Name :PC Remote
+# Author       :André Portela
+# Email        :andre_portela_@hotmail.com
+# Version      :1.0
+# Module       :main
+# Class        :PCRemote custom Edje object with it's own call backs for the
+#               main screen
+# ============================================================================
+
+import thread
+import ecore
+import ecore.evas
+import evas.decorators
+import edje
+import edje.decorators
+import time
+from connection.iconnection import Iconnection
+from kineticlist import *
+
+class EvasCanvas(object):
+
+    def __init__(self, fullscreen, engine, size):
+        #f = ecore.evas.SoftwareX11
+        self.evas_obj = engine(w=size[0], h=size[1])
+        self.evas_obj.callback_delete_request = self.on_delete_request
+        self.evas_obj.callback_resize = self.on_resize
+
+        self.evas_obj.title = "PCRemote"
+        self.evas_obj.name_class = ('PC Remote', 'main')
+        self.evas_obj.fullscreen = fullscreen
+        self.evas_obj.size = size
+        self.evas_obj.show()
+        
+    def on_resize(self, evas_obj):
+        x, y, w, h = evas_obj.evas.viewport
+        size = (w, h)
+        for key in evas_obj.data.keys():
+            evas_obj.data[key].size = size
+
+    def on_delete_request(self, evas_obj):
+        ecore.main_loop_quit()
+        
+    def show(self):
+        self.evas_obj.show()
+
+class EdjeObject(edje.Edje):
+
+    def __init__(self, canvas_class, file, group='main',name='edje'):
+        self.canvas_class = canvas_class
+        self.x11 = canvas_class.evas_obj
+        self.canvas = self.x11.evas
+        edje.Edje.__init__(self, self.canvas, file = file, group = group)
+        self.size = self.canvas.size
+        self.x11.data[name] = self
+
+class MainScreen(EdjeObject):
+
+    def __init__(self, canvas, file, group, name, connection):
+        EdjeObject.__init__(self, canvas, file = file, group = group,name = name)
+
+        self.file = file
+        self.on_key_down_add(self.key_down_cb, self.x11)
+        self.sock_address = None
+        #flag that sync the discovery device's thread
+        self.flag = False
+        #flag that sync the connecting device's thread
+        self.connecting_flag = False
+        #lista de dispositivos descobertos
+        self.lista_dispositivos = []
+        #objeto que cria a conexao bluetooth
+        self.conexao = connection
+        self.kineticlist = False
+        #portela mock object
+        self.lista_teste = ['Andre Portela', 'Juliana Dias', 'Victor Hugo', 'Lucina Dias', 'Rosa Dias', 'James Italiano', 'Nona Izvi', 'Fergus Mao', 'Mauricio Brilhante', 'Edward Ordonez', 'Brankinhu', 'Banco Real', 'Banco Itaú', 'ABN-AMRO BANK']
+
+    def key_down_cb(self, bg, event, ee):
+        k = event.key
+        if k == "Escape":
+            ecore.main_loop_quit()
+        elif k == "F6":
+            ee.fullscreen = not ee.fullscreen
+        elif k == "F8":
+            print "-"
+        elif k == "F7":
+            print "+"
+      
+    def mkKineticList(self):
+        #kinetic list (the item values are tied with the part "item_background" of the "list_item" group)
+        #self.kineticlist = KineticList(self.canvas, file=self.file, item_width=407, item_height=38, father=self)
+        self.kineticlist = KineticList(self.canvas, file=self.file, item_height=57, father=self)
+        self.kineticlist.freeze()
+        #portela - test kinetic list with several devices
+        #for item in self.lista_teste:
+        #populates the list with the device's names
+        for item in self.lista_dispositivos:
+            self.kineticlist.row_add(item)
+        #reorganize and draw the list
+        self.kineticlist.thaw()
+        #embed the list in the edje object
+        self.part_swallow("list", self.kineticlist);
+
+    @edje.decorators.signal_callback("connect_to","choice")
+    def connect_to(self, emission, source):
+        self.sock_address = self.part_text_get(source)
+        #flag that sync the connecting device's thread
+        self.connecting_flag = False
+        self.signal_emit("start","device_connect")
+        thread.start_new_thread(MainScreen.threaded_connection,(self,))
+        
+    def threaded_connection(self):
+        self.conexao.create_socket('l2cap')
+        print 'connecting to: %s' % self.sock_address
+        self.conexao.set_address(self.conexao.bt_find_device_address_by_name(self.sock_address))
+        self.conexao.set_port(0x1001)
+        self.conexao.connect()
+        self.connecting_flag = True
+
+    @edje.decorators.signal_callback("connecting","device")
+    def connecting_check(self, emission, source):
+        if self.connecting_flag:
+            self.connecting_flag = False
+            self.signal_emit("stop","device_connect")
+            #we are sending a signal to main edje (there is time to animate the device locking)
+            self.signal_emit("begin","init")
+    @edje.decorators.signal_callback("animation_still_loading", "loading")
+    def still_loading_cb(self, emission, source):
+        if self.flag:
+            self.flag = False
+            self.signal_emit("program,stop","loading")
+            if self.lista_dispositivos != []:
+                self.mkKineticList()
+            else:
+                self.no_device_found()
+
+    @edje.decorators.signal_callback("animation_sair_ended", "sair")
+    def saida(self, signal, source):
+        ecore.main_loop_quit()
+
+    @edje.decorators.signal_callback("animation_rastrear_ended", "rastrear")
+    def rastrear_key_down(self, signal, source):
+        thread.start_new_thread(MainScreen.rastrear_dispositivos,(self,None))
+
+    @edje.decorators.signal_callback("program,start", "novodevice")
+    def search_devices_again(self, signal, source):
+        self.part_unswallow(self.kineticlist)
+        del self.kineticlist
+        MainScreen.rastrear_key_down(self, None, None)
+
+    def rastrear_dispositivos(self,arg):
+        try:
+            self.lista_dispositivos = self.conexao.bt_find_devices_only_names()
+        except:
+            self.lista_dispositivos = []
+        self.flag = True
+
+    def no_device_found(self):
+        self.signal_emit("program,start","no_device")
+
+class TabletScreen(EdjeObject):
+
+    def __init__(self, canvas, file, group,name, connection):
+        EdjeObject.__init__(self, canvas, file = file, group = group,name = name)
+        self.on_key_down_add(self.key_down_cb, self.x11)
+        #emitt events only if the mouse is inside the touch object area
+        (self.part_object_get('touch')).pointer_mode_set(evas.EVAS_OBJECT_POINTER_MODE_NOGRAB)
+        #assign the mouse_move_cb method as a mouse move callback for the touch part of the edje object
+        (self.part_object_get('touch')).on_mouse_move_add(self.mouse_move_cb)
+        #self.on_mouse_move_add(TabletScreen.mouse_move_cb)
+        self.sock = connection
+        #this flag indicates either the user are grabing something or not on the target
+        self.drag_flag = False
+        #this float indicates the wich the method left_click_down was called, and will be
+        #calculated against lcu_time in left_click_up method
+        self.lcd_time = 0.0
+       #tecla alt
+       self.alt_flag = False
+       #tecla shift
+       self.iso_shift_flag = False
+       #lista de aliases das teclas de comando Alt+F(x)
+        #self.fletters = ['p', 'q', 'w', '', 'r', '', '', '', '', 'o'] 
+        self.keys_dict = {'q':1, 'w':2, 'e':3, 'r':4, 't':5, 'y':6, 'u':7, 'i':8, 'o':9, 'p':0, \
+                         'a':'Shift_L+1', 's':'', 'd':'Shift_L+2', 'f':'Shift_L+3', 'g':'backslash', \
+                         'h':'slash', 'j':'Shift_L+9', 'k': 'Shift_L+0', 'l':'Shift_L+8', '\'':'Shift_L+slash',\
+                         'z':'', 'x':'Shift_L+6', 'c':'', 'v':'Shift_L+5', 'b':'Shift_L+7', 'n':'Shift_L+4', \
+                         'm':'', ';':'', '-':'Shift_L+minus', '+':'equal'}
+
+    @edje.decorators.signal_callback('mouse,down,1', 'tablet_bt-L_area')
+    def left_click_down(self, signal, source):
+        self.lcd_time = time.time()
+        #if the user are grabing something, release it
+        if self.drag_flag:
+            self.drag_flag = False
+            self.sock.send_message("Mouse:#left_click")
+
+    @edje.decorators.signal_callback('mouse,up,1', 'tablet_bt-L_area')
+    def left_click_up(self, signal, source):
+        lcu_time = time.time()
+        #threshold of 0.5 seconds to grab something on the target
+        elapsed_time = lcu_time - self.lcd_time
+        if elapsed_time < 0.5:
+            #do a simple click
+            self.sock.send_message("Mouse:#left_click")
+            self.sock.send_message("Mouse:#left_click")
+        else:
+            #do mouse grab
+            self.sock.send_message("Mouse:#left_click")
+            self.drag_flag = True
+
+    @edje.decorators.signal_callback('mouse,up,1', 'tablet_bt-R_area')
+    def rigth_click(self, signal, source):
+        self.sock.send_message("Mouse:#right_click")
+        self.sock.send_message("Mouse:#right_click")
+
+    def key_down_cb(self, bg, event, ee):
+        k = event.key
+       print k
+        if k == "Escape":
+           self.sock.send_message("Keyboard:Escape")
+        elif k == "F6":
+            ee.fullscreen = not ee.fullscreen
+        elif k == "F8":
+            self.sock.send_message("Keyboard:Up")
+        elif k == "F7":
+            self.sock.send_message("Keyboard:Down")
+       elif k == "Return":
+           self.alt_flag = True
+       elif k == "ISO_Level3_Shift":
+           self.iso_shift_flag = True
+        else:
+           if self.alt_flag:
+               #if k in self.fletters:
+                #    self.sock.send_message("Keyboard:Alt+F%s" % (self.fletters.index(k)))
+               #    self.alt_flag = False
+               #elif k == 'space':
+               #    self.sock.send_message("Keyboard:Alt+Space")
+               #    self.alt_flag = False
+               #else:
+               #    self.alt_flag = False
+               if self.keys_dict.has_key(k) and isinstance(self.keys_dict[k], int):
+                   self.sock.send_message("Keyboard:Alt_L")
+                   self.sock.send_message("Keyboard:F%s" % (self.keys_dict[k]))
+                   self.alt_flag = False
+               elif k == 'space':
+                   self.sock.send_message("Keyboard:Alt_L")
+                   self.sock.send_message("Keyboard:space")
+                   self.alt_flag = False
+               else:
+                   self.alt_flag = False
+           #else:
+               #self.sock.send_message("Keyboard:%s" % k)
+           elif self.iso_shift_flag:
+               if self.keys_dict.has_key(k) and self.keys_dict[k] and isinstance(self.keys_dict[k], str):
+                   lst = self.keys_dict[k].split('+')
+                   for cmd in lst:
+                       self.sock.send_message("Keyboard:%s" % cmd)
+                       self.iso_shift_flag = False
+               elif self.keys_dict.has_key(k) and self.keys_dict and isinstance(self.keys_dict[k], int):
+                   self.sock.send_message("Keyboard:%s" % self.keys_dict[k])
+                   self.iso_shift_flag = False
+               else:
+                   self.iso_shift_flag = False
+           else:
+               self.sock.send_message("Keyboard:%s" % k)
+
+    def mouse_move_cb(self, part, event):
+        x, y = event.position.output[0], event.position.output[1]
+        self.sock.send_message("Mouse:"+str(x)+","+str(y))
+
+class SlideScreen(EdjeObject):
+
+    def __init__(self, canvas, file, group,name, connection):
+        EdjeObject.__init__(self, canvas, file = file, group = group,name = name)
+        self.on_key_down_add(self.key_down_cb, self.x11)
+        #emitt events only if the mouse is inside the touch object area
+        (self.part_object_get('touch')).pointer_mode_set(evas.EVAS_OBJECT_POINTER_MODE_NOGRAB)
+        #assign the mouse_move_cb method as a mouse move callback for the touch part of the edje object
+        (self.part_object_get('touch')).on_mouse_move_add(self.mouse_move_cb)
+        #self.on_mouse_move_add(TabletScreen.mouse_move_cb)
+        self.sock = connection
+        #this flag indicates either the user are grabing something or not on the target
+        self.drag_flag = False
+        #helps to coordenate presentation
+        self.keyboard_flag = True
+        #this float indicates the wich the method left_click_down was called, and will be
+        #calculated against lcu_time in left_click_up method
+        self.lcd_time = 0.0
+
+    @edje.decorators.signal_callback('mouse,down,1', 'slide_bt-left_area')
+    def left_click_down(self, signal, source):
+        if self.keyboard_flag:
+            self.lcd_time = time.time()
+            #if the user are grabing something, release it
+            if self.drag_flag:
+                self.drag_flag = False
+                self.sock.send_message("Mouse:#left_click")
+
+    @edje.decorators.signal_callback('mouse,up,1', 'slide_bt-left_area')
+    def left_click_up(self, signal, source):
+        if self.keyboard_flag:
+            lcu_time = time.time()
+            #threshold of 0.5 seconds to grab something on the target
+            elapsed_time = lcu_time - self.lcd_time
+            if elapsed_time < 0.5:
+                #do a simple click
+                self.sock.send_message("Mouse:#left_click")
+                self.sock.send_message("Mouse:#left_click")
+            else:
+                #do mouse grab
+                self.sock.send_message("Mouse:#left_click")
+                self.drag_flag = True
+        else:
+            self.sock.send_message("Keyboard:%s" % "Left")
+
+    @edje.decorators.signal_callback('mouse,up,1', 'slide_bt-right_area')
+    def rigth_click(self, signal, source):
+        if self.keyboard_flag:
+            self.sock.send_message("Mouse:#right_click")
+            self.sock.send_message("Mouse:#right_click")
+        else:
+            self.sock.send_message("Keyboard:%s" % "Right")
+
+    def key_down_cb(self, bg, event, ee):
+        k = event.key
+       print k
+        if k == "Escape":
+           self.sock.send_message("Keyboard:Escape")
+        elif k == "F6":
+            self.keyboard_flag = not self.keyboard_flag
+            self.sock.send_message("Keyboard:F5")
+        elif k == "F8":
+            self.sock.send_message("Keyboard:Up")
+        elif k == "F7":
+            self.sock.send_message("Keyboard:Down")
+        else:
+            self.sock.send_message("Keyboard:%s" % k)
+
+    def mouse_move_cb(self, part, event):
+        x, y = event.position.output[0], event.position.output[1]
+        self.sock.send_message("Mouse:"+str(x)+","+str(y))
diff --git a/pcremote-client/kineticlist.py b/pcremote-client/kineticlist.py
new file mode 100755 (executable)
index 0000000..4234176
--- /dev/null
@@ -0,0 +1,400 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# ****************************************************************************
+# Copyright (c) 2008 INdT/Fucapi.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# ============================================================================
+# Project Name :PC Remote
+# Author       :Gustavo Sverzut Barbieri ; André Luiz do Canto Portela
+# Email        :barbieri@gmail.com ; andre_portela_@hotmail.com
+# Version      :1.0
+# Module       :main
+# Class        :This class are an adaptation of barbieri's demo 03 of edje
+#              :python-bindings
+# ============================================================================
+
+import evas
+import edje
+import ecore
+import time
+
+class KineticList(evas.ClippedSmartObject):
+    (
+        SCROLL_PAGE_FORWARD,
+        SCROLL_PAGE_BACKWARD,
+        SCROLL_STEP_FORWARD,
+        SCROLL_STEP_BACKWARD,
+        SCROLL_PIXELS_DOWN,
+        SCROLL_PIXELS_UP
+    ) = range(6)
+
+
+    def __init__(self, ecanvas, file, item_width=-1, item_height=-1, father=None):
+        '''
+        if item_width or item_height is left out the width (resp. height)
+        of the List element is used.
+        '''
+        self.father = father
+        evas.ClippedSmartObject.__init__(self, ecanvas)
+        self.elements = []
+        self.objects = []
+        self.w = 32
+        self.h = 32
+
+        self.realized = False
+
+        self.top_pos = 0
+        self.last_top_pos = 0
+        self.last_start_row = -1
+
+        self.canvas = ecanvas
+        self.edje_file = file
+
+        self.row_width = item_width
+        self.row_height = item_height
+
+        self.__manage_objects()
+
+        self.mouse_down = False
+        self.last_y_pos = 0
+        self.start_pos = 0
+        self.mouse_moved = False
+        self.continue_scrolling = False
+        self.is_scrolling = False
+        self.do_freeze = False
+
+    def freeze(self):
+        self.do_freeze = True
+
+    def thaw(self):
+        self.do_freeze = False
+        if self.realized:
+            self.__update_variables_after_new_elements()
+            self.__update_screen()
+
+    def scroll(self, scroll_type, amount=1):
+        self.continue_scrolling = False
+
+        if scroll_type == self.SCROLL_PAGE_FORWARD:
+            self.top_pos += amount * self.row_height * self.max_visible_rows
+        elif scroll_type == self.SCROLL_PAGE_BACKWARD:
+            self.top_pos -= amount * self.row_height * self.max_visible_rows
+        elif scroll_type == self.SCROLL_STEP_FORWARD:
+            self.top_pos += amount * self.row_height
+        elif scroll_type == self.SCROLL_STEP_BACKWARD:
+            self.top_pos -= amount * self.row_height
+        elif scroll_type == self.SCROLL_PIXELS_DOWN:
+            self.top_pos += amount
+        elif scroll_type == self.SCROLL_PIXELS_UP:
+            self.top_pos -= amount
+        else:
+            return
+
+        self.__update_screen()
+
+    def __on_mouse_clicked(self, edje_obj, emission, source, data=None):
+        #for obj in self.objects:
+        #    if obj != edje_obj:
+        #        obj.signal_emit("fadeout", "")
+
+        #edje_obj.signal_emit("open", "")
+        #TODO:portela - it works! :D
+        edje_obj.signal_emit("program,start","label")
+        #we are setting up the choice's text on the main edje object 
+        self.parent_get().part_text_set("choice",edje_obj.part_text_get("label"))
+
+    def __on_mouse_move(self, edje_obj, emission, source, data=None):
+        if self.mouse_down:
+            x_pos, y_pos = self.canvas.pointer_canvas_xy
+            diff = int(self.last_y_pos - y_pos)
+
+            if diff == 0:
+                return
+
+            self.mouse_moved = True
+
+            # Reset the data if the direction of the mouse move is changed
+            if self.last_diff != -1 and (diff < 0) != (self.last_diff < 0):
+                self.last_y_pos = y_pos
+                self.start_pos = y_pos
+                self.start_time = time.time()
+
+            self.last_diff = diff
+            self.top_pos += diff
+
+            self.last_y_pos = y_pos
+            self.__update_screen()
+            self.last_update_time = time.time()
+
+    #TODO: portela mod
+    def __on_blink_ended(self, edje_obj, emission, source, data=None):
+        for obj in self.objects:
+            obj.signal_emit("program,start,fade,out","label")
+        #we are sending a signal for the application connect the target
+        self.parent_get().signal_emit("connect_to","choice")
+
+    #TODO: portela mod
+
+    def show_list(self):
+        for obj in self.objects:
+            obj.signal_emit("program,start,fade,in","label")
+
+    def __on_mouse_down(self, edje_obj, emission, source, data=None):
+        if not self.is_scrolling:
+            self.mouse_moved = False
+
+        self.continue_scrolling = False
+        self.mouse_down = True
+
+        x_pos, y_pos = self.canvas.pointer_canvas_xy
+
+        self.last_diff = -1
+        self.last_y_pos = y_pos
+        self.start_pos = y_pos
+        self.start_time = time.time()
+        self.last_update_time = time.time()
+
+    def __on_mouse_up(self, edje_obj, emission, source, data=None):
+        if self.mouse_down:
+            self.mouse_down = False
+
+            x_pos, end_pos = self.canvas.pointer_canvas_xy
+
+            if not self.mouse_moved and not self.is_scrolling:
+                #self.__on_mouse_clicked(edje_obj, emission, source)
+                return
+
+            self.mouse_moved = False
+            self.is_scrolling = False
+
+            # do not scroll automatically if the finger was paused
+            if time.time() - self.last_update_time > 0.1:
+                return
+
+            end_time = time.time()
+
+            pos_diff =  end_pos - self.start_pos
+            time_diff = end_time - self.start_time
+
+            self.pixel_per_sec = pos_diff / time_diff
+            self.continue_scrolling = True
+            self.__do_scroll()
+
+    def __do_scroll(self):
+        self.is_scrolling = True
+
+        if self.continue_scrolling == False:
+            return
+
+        diff = int(self.pixel_per_sec / 10)
+
+        if abs(self.pixel_per_sec) - diff <= self.row_height:
+            offset = self.top_pos % self.row_height
+
+            if offset >= self.row_height / 2:
+                self.sign = 1
+                offset = self.row_height - offset
+            else:
+                self.sign = -1
+
+            self.pixels_left = offset
+            self.__do_magnetic_scroll()
+
+            return
+
+        if diff != 0:
+            self.top_pos -= diff
+            self.pixel_per_sec -= self.pixel_per_sec / 10
+            self.__update_screen()
+
+        ecore.timer_add(0.02, self.__do_scroll)
+
+    def __do_magnetic_scroll(self):
+        if self.pixels_left <= 0 or abs(self.pixel_per_sec) < 1:
+            self.mouse_moved = False
+            self.is_scrolling = False
+            return
+
+        self.pixel_per_sec -= (self.pixel_per_sec / 10)
+
+        pixels_to_substract = int(abs(self.pixel_per_sec / 10))
+        if abs(pixels_to_substract) < 1:
+            pixels_to_substract = 1
+
+        if self.pixels_left - pixels_to_substract > 0:
+            self.pixels_left -= pixels_to_substract
+            self.top_pos += self.sign * pixels_to_substract
+        else:
+            self.top_pos += self.sign * self.pixels_left
+            self.pixels_left = 0
+
+        self.__update_screen()
+        ecore.timer_add(0.1, self.__do_magnetic_scroll)
+
+    def row_add(self, label):
+        self.elements.append(label)
+
+        if not self.do_freeze:
+            self.__update_variables_after_new_elements()
+            self.__update_screen()
+
+    def __manage_objects(self):
+        remain = (self.h % self.row_height) > 1
+        needed_objects = ((self.h / self.row_height) + 1 + remain) * (self.w / self.row_width)
+        current_objects = len(self.objects)
+
+        if current_objects < needed_objects:
+            for i in range(current_objects, needed_objects):
+                obj = edje.Edje(self.canvas);
+                obj.file_set(self.edje_file, "list_item");
+
+                obj.signal_callback_add("mouse,move", "*",
+                                        self.__on_mouse_move)
+                obj.signal_callback_add("mouse,down,*", "*",
+                                        self.__on_mouse_down)
+                obj.signal_callback_add("mouse,up,*", "*",
+                                        self.__on_mouse_up)
+                #TODO: portela mod
+                obj.signal_callback_add("animation_blink_ended", "label",
+                                        self.__on_blink_ended)
+                obj.signal_callback_add("mouse,clicked,*", "label",
+                                        self.__on_mouse_clicked)
+                obj.size = (self.row_width, self.row_height)
+                obj.clip = self
+                self.objects.append(obj)
+
+        elif needed_objects < current_objects:
+            for i in range(needed_objects, current_objects):
+                pass # Make this work, it throws exception that makes
+                     # things stop working properly
+                #del self.objects[i]
+
+    def __update_variables_after_resize(self):
+        self.max_visible_rows = (self.h / self.row_height) + 1
+        self.max_horiz_elements = (self.w / self.row_width)
+        self.max_visible_elements = self.max_visible_rows * \
+                                    self.max_horiz_elements
+
+        # Invalidate variable in order to repaint all rows
+        # Some might not have been painted before (Didn't
+        # fit on the screen
+        self.last_start_row = -1
+
+        self.__update_variables_after_new_elements()
+
+    def __update_variables_after_new_elements(self):
+        if not self.realized:
+            return
+
+        self.min_pos = 0
+        remainer1 = (len(self.elements) % self.max_horiz_elements) > 0
+        remainer2 = (self.h % self.row_height) > 0
+        self.row_amount = (len(self.elements) / self.max_horiz_elements) + \
+                          remainer1 + remainer2
+        self.max_pos = self.row_height * \
+                       (self.row_amount - self.max_visible_rows + 1)
+
+    def __update_screen(self):
+        remainer = (self.h % self.row_height) > 0
+        row_offset = (self.top_pos / self.row_height)
+        pixel_offset = - (self.top_pos % self.row_height)
+        start_row = row_offset
+        end_row = self.max_visible_rows + row_offset + remainer
+
+        SCROLL_DOWN = self.top_pos > self.last_top_pos
+        SCROLL_UP = self.top_pos < self.last_top_pos
+
+        # Let's not move over the last element
+        if SCROLL_DOWN and self.last_top_pos >= self.max_pos:
+            self.top_pos = self.max_pos
+            self.last_top_pos = self.top_pos
+            self.continue_scrolling = False
+            return
+
+        # Let's not move over the first element
+        if SCROLL_UP and self.last_top_pos <= self.min_pos:
+            self.top_pos = self.min_pos
+            self.last_top_pos = self.top_pos
+            self.continue_scrolling = False
+            return
+
+        # Overflow scrolling down
+        if SCROLL_DOWN and end_row > self.row_amount:
+            offset = end_row - self.row_amount
+            end_row -= offset
+            start_row -= offset
+            row_offset -= offset - 1
+            self.top_pos = self.max_pos
+            pixel_offset = 0
+
+        # Overflow scrolling up
+        if SCROLL_UP and start_row < 0:
+            self.top_pos = self.min_pos
+            end_row -= start_row
+            start_row = 0
+            row_offset = 0
+            pixel_offset = 0
+
+        self.last_top_pos = self.top_pos
+
+        if start_row != self.last_start_row:
+            for i in range(0, len(self.objects)):
+                self.objects[i].hide()
+
+        for i in range(start_row, end_row):
+            row_iter = i - start_row
+
+            for k in range(self.max_horiz_elements):
+                obj_iter = row_iter * self.max_horiz_elements + k
+                data_iter = i * self.max_horiz_elements + k
+
+                try:
+                    label = self.elements[data_iter]
+                except Exception, e:
+                    break;
+
+                offset = (self.w %
+                          (self.row_width * self.max_horiz_elements)) / 2
+                x = self.row_width * k + self.top_left[0] + offset
+                y = self.top_left[1] + self.row_height * (i - row_offset) - \
+                    5 + pixel_offset
+
+                self.objects[obj_iter].move(x, y)
+
+                if start_row != self.last_start_row:
+                    self.objects[obj_iter].part_text_set("label", label)
+                    self.objects[obj_iter].show()
+
+        self.last_start_row = start_row
+
+    def resize(self, w, h):
+        if self.row_width == -1 or self.row_width == self.w:
+            self.row_width = w
+
+        if self.row_height == -1 or self.row_height == self.h:
+            self.row_height = h
+
+        self.w = w
+        self.h = h
+
+        self.__manage_objects()
+
+        for obj in self.objects:
+            obj.size = (self.row_width, self.row_height)
+
+        self.realized = True
+        self.__update_variables_after_resize()
+        self.__update_screen()
diff --git a/pcremote-client/pcremote-client.py b/pcremote-client/pcremote-client.py
new file mode 100755 (executable)
index 0000000..14e5a9e
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# ****************************************************************************
+# Copyright (c) 2008  Zagaia - INdT/Fucapi.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# ============================================================================
+# Project Name :PC Remote
+# Author       :Andre Portela
+# Email        :andre_portela_@hotmail.com
+# Version      :1.0
+# Module       :main
+# Class        :PCRemote custom Edje object with it's own call backs for the
+#               main screen
+# ============================================================================
+
+from ecore import main_loop_begin
+import ecore.evas
+import sys
+import os
+from edje_objects import *
+from connection.iconnection import Iconnection
+from screenmanager import ScreenManager
+
+width, height = 800, 480
+
+#any argument deactivates fullscreen
+if sys.argv.__len__() > 1:
+    screen = False
+else:
+    screen = True
+#if x11_16 is present, get it, otherwise get x11
+if ecore.evas.engine_type_supported_get("software_x11_16"):
+    engine = ecore.evas.SoftwareX11_16
+else:
+    engine = ecore.evas.SoftwareX11
+#create the evas canvas
+canvas = EvasCanvas(fullscreen=screen,engine=engine,size=(width, height))
+#main .edj path
+edje_file = os.path.join(os.path.dirname(sys.argv[0]), "pcremote.edj")
+#the bluetooth socket object shared by all screens
+sock = Iconnection('bluetooth')
+#main edje object
+main = MainScreen(canvas=canvas, file=edje_file, group="Main",name="Main", connection = sock)
+main.show()
+#future edje objects
+tablet, slide, player, torrent = None, None, None, None
+#focus on main edje object
+main.focus = True
+#this object connects all screens together
+manager = ScreenManager(main, tablet, slide, player, torrent, sock)
+
+ecore.main_loop_begin()
+
diff --git a/pcremote-client/pcremote.edj b/pcremote-client/pcremote.edj
new file mode 100755 (executable)
index 0000000..ce5640f
Binary files /dev/null and b/pcremote-client/pcremote.edj differ
diff --git a/pcremote-client/pcremote26.png b/pcremote-client/pcremote26.png
new file mode 100755 (executable)
index 0000000..e5e8183
Binary files /dev/null and b/pcremote-client/pcremote26.png differ
diff --git a/pcremote-client/pcremote40.png b/pcremote-client/pcremote40.png
new file mode 100755 (executable)
index 0000000..22b5640
Binary files /dev/null and b/pcremote-client/pcremote40.png differ
diff --git a/pcremote-client/pcremote64.png b/pcremote-client/pcremote64.png
new file mode 100755 (executable)
index 0000000..2e13bd7
Binary files /dev/null and b/pcremote-client/pcremote64.png differ
diff --git a/pcremote-client/screenmanager.py b/pcremote-client/screenmanager.py
new file mode 100755 (executable)
index 0000000..367f17b
--- /dev/null
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# ****************************************************************************
+# Copyright (c) 2008 INdT/Fucapi.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# ============================================================================
+# Project Name :PC Remote
+# Author       :André Portela
+# Email        :andre_portela_@hotmail.com
+# Version      :1.0
+# Module       :main
+# Class        :PCRemote ScreenManager handles the finite state machine which
+#               controls the navigation between screens.
+# ============================================================================
+
+from edje_objects import *
+import os
+import sys
+
+class ScreenManager(object):
+    '''
+    classdocs
+    '''
+    def __init__(self, main, tablet, slide, player, torrent,socket):
+        '''
+        Constructor
+        '''
+        self.main = main
+        self.tablet = tablet
+        self.slide = slide
+        self.player = player
+        self.torrent = torrent
+        self.sock = socket
+        main.signal_callback_add("mouse,up,1", "Tablet",self.run_tablet)
+        main.signal_callback_add("mouse,up,1", "Slideshow",self.run_slide)
+        main.signal_callback_add("mouse,up,1", "Player",self.run_player)
+        main.signal_callback_add("mouse,up,1", "Torrent",self.run_torrent)
+
+    def run_tablet(self, edje, emission, source):
+        self.sock.send_message(source+":#start")
+        print 'entrou no tablet'
+        #main edje object
+        edje.focus_set(False)
+        edje.hide()
+        if self.tablet is None:
+            edje_file = os.path.join(os.path.dirname(sys.argv[0]), "tablet.edj")
+            self.tablet = TabletScreen(edje.canvas_class, edje_file, 'main', 'tablet', self.sock)
+            self.tablet.signal_callback_add("mouse,up,1","tablet_bt-voltar_area",self.tablet_back)
+        self.tablet.part_text_set('pc_name',edje.sock_address)
+        self.tablet.show()
+        self.tablet.focus_set(True)
+
+    def tablet_back(self, edje, emission, source):
+        #tablet edje object
+        edje.focus_set(False)
+        edje.hide()
+        self.sock.send_message("Tablet:#stop")
+        self.main.show()
+        self.main.focus_set(True)
+
+    def run_slide(self, edje, emission, source):
+        self.sock.send_message(source+":#start")
+        print 'entrou no slide'
+        #main edje object
+        edje.focus_set(False)
+        edje.hide()
+        if self.slide is None:
+            edje_file = os.path.join(os.path.dirname(sys.argv[0]), "slide.edj")
+            self.slide = SlideScreen(edje.canvas_class, edje_file, 'main', 'slide', self.sock)
+            self.slide.signal_callback_add("unselected","slide_bt-voltar",self.slide_back)
+        #self.slide.part_text_set('pc_name',edje.sock_address)
+        #this rotates the screen 90 degrees (to fit text in vertical orientation)
+        #self.slide.x11.rotation_set(90)
+        self.slide.show()
+        self.slide.focus_set(True)
+
+    def slide_back(self, edje, emission, source):
+        #slide edje object
+        edje.focus_set(False)
+        edje.hide()
+        self.sock.send_message("Slideshow:#stop")
+        #this rotates the screen from 90 to 0 degrees (to fit text in horizontal orientation again)
+        #self.main.x11.rotation_set(0)
+        self.main.show()
+        self.main.focus_set(True)
+
+    def run_player(self, edje, emission, source):
+        print 'not implemented yet'
+
+    def player_back(self, edje, emission, source):
+        print 'not implemented yet'
+
+    def run_torrent(self, edje, emission, source):
+        print 'not implemented yet'
+
+    def torrent_back(self, edje, emission, source):
+        print 'not implemented yet'
+
diff --git a/pcremote-client/slide.edj b/pcremote-client/slide.edj
new file mode 100755 (executable)
index 0000000..d4e3119
Binary files /dev/null and b/pcremote-client/slide.edj differ
diff --git a/pcremote-client/tablet.edj b/pcremote-client/tablet.edj
new file mode 100755 (executable)
index 0000000..b50a7e4
Binary files /dev/null and b/pcremote-client/tablet.edj differ
diff --git a/pcremote-client/utils/__init__.py b/pcremote-client/utils/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/pcremote-client/utils/labels.py b/pcremote-client/utils/labels.py
new file mode 100755 (executable)
index 0000000..dd12186
--- /dev/null
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 of the License, or
+#  (at your option) any later version.
+
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : Jônatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Version      : 1.0
+#  Description  : Labels
+#  ============================================================================
+
+
+# GENERIC LABELS FOR MULTIMEDIA APPLICATIONS
+
+PLAY        = "#play"
+STOP        = "#stop"
+PAUSE       = "#pause"
+NEXT        = "#next"
+PREVIOUS    = "#previous"
+VOL_UP      = "#vol_up"
+VOL_DOWN    = "#vol_down"
+TLINE_LEFT  = "#tline_left"
+TLINE_RIGHT = "#tline_right"
+RECORD      = "#record"
+#------------------------------------------>
+
+# GENERIC LABELS FOR APPLICATIONS
+
+START      = "#start"
+CLOSE      = "#close"
+FULL       = "#fullscreen"
+UPLOAD     = "#upload"
+DOWNLOAD   = "#download"
+SAVE       = "#save"
+DELETE     = "#delete"
+#-------------------------------->
+
+# GENERAL MOUSE LABELS
+
+CLICK         = "#click"
+DOUBLE_CLICK  = "#double_click"
+TRIPLE_CLICK  = "#triple_click"
+LEFT_CLICK    = "#left_click"
+RIGHT_CLICK   = "#right_click"
+MIDDLE_CLICK  = "#middle_click"
+#-------------------------------->
+
+