OSDN Git Service

updates
authorshy <shy>
Sun, 29 Jul 2007 13:46:57 +0000 (13:46 +0000)
committershy <shy>
Sun, 29 Jul 2007 13:46:57 +0000 (13:46 +0000)
ChangeLog
lib/ninix/balloon.py
lib/ninix/dll/osuwari.py [new file with mode: 0755]
lib/ninix/ghost.py
lib/ninix/surface.py
lib/ninix/version.py

index f9458a5..bb0f72b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+Sun July 29 2007   Shyouzou Sugitani <shy@users.sourceforge.jp>
+       * osuwari.dll互換SAORIモジュールosuwari.pyを追加.
+
 Sun July 22 2007   Shyouzou Sugitani <shy@users.sourceforge.jp>
        * バージョン3.9.6リリース.
        * OnBallonCloseイベントのサポートを追加.
index 1711474..7e17929 100644 (file)
@@ -111,6 +111,12 @@ class Balloon:
         window.realize()
         return window
 
+    def identify_window(self, win):
+        for balloon_window in self.window:
+            if win == balloon_window.window.window:
+                return True
+        return False
+
     def delete(self, window, event):
         self.sakura.ghost.finalize() ## FIXME
         return False
diff --git a/lib/ninix/dll/osuwari.py b/lib/ninix/dll/osuwari.py
new file mode 100755 (executable)
index 0000000..2424b82
--- /dev/null
@@ -0,0 +1,178 @@
+# -*- coding: ascii -*-
+#
+#  osuwari.py - a Osuwari compatible Saori module for ninix
+#  Copyright (C) 2006 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#
+#  This program is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License (version 2) as
+#  published by the Free Software Foundation.  It 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 General Public License for more details.
+#
+#
+
+# TODO: MOVE, NOCLIP, FIX, etc.
+
+import gobject
+import gtk
+
+from ninix.dll import SAORI
+
+
+class Saori(SAORI):
+
+    def __init__(self):
+        SAORI.__init__(self)
+        self.timeout_id = None
+        self.settings = {}
+        self.__ghost = None
+
+    def need_ghost_backdoor(self, ghost):
+        self.__ghost = ghost
+
+    def check_import(self):
+        return 1
+
+    def setup(self): ## FIXME
+        return 1
+
+    def execute(self, argument):
+        if not argument:
+            return 'SAORI/1.0 400 Bad Request\r\n\r\n'
+        if argument[0] == 'START':
+            if len(argument) < 7:
+                return 'SAORI/1.0 400 Bad Request\r\n\r\n'
+            try:
+                assert argument[2] in ['ACTIVE', 'FIX'] or \
+                       arguent[2].stratswith('@') or \
+                       argument[2].startswith('#')
+                assert argument[3] in ['TL', 'TR', 'BL', 'BR']
+                self.settings['hwnd'] = argument[1]
+                self.settings['target'] = argument[2]
+                self.settings['position'] = argument[3]
+                self.settings['offset_x'] = int(argument[4])
+                self.settings['offset_y'] = int(argument[5])
+                self.settings['timeout'] = int(argument[6])
+                self.settings['xmove'] = 0
+                self.settings['ymove'] = 0
+                self.settings['noclip'] = 0
+                if len(argument) > 7:
+                    if 'XMOVE' in argument[7]:
+                        self.settings['xmove'] = 1
+                    if 'YMOVE' in argument[7]:
+                        self.settings['ymove'] = 1
+                    if 'NOCLIP' in argument[7]:
+                        self.settings['noclip'] = 1
+                self.settings['except'] = ('DESKTOP', 'CENTER')
+                #if len(argument) > 8:
+                #    target, position = argument[8].split()
+                #    assert target in ['DESKTOP', 'WORKAREA']
+                #    assert position in ['TOP', 'LEFT', 'RIGHT', 'BOTTOM']
+                #    self.settings['except'] = (target, position)
+            except:
+                return 'SAORI/1.0 400 Bad Request\r\n\r\n'
+            #self.timeout_id = gobject.timeout_add(self.settings['timeout'], self.do_idle_tasks)
+            self.timeout_id = gobject.timeout_add(100, self.do_idle_tasks)
+            return 'SAORI/1.0 204 No Content\r\n\r\n'
+        elif argument[0] == 'STOP':
+            if self.timeout_id is not None:
+                gobject.source_remove(self.timeout_id)
+                self.timeout_id = None
+                self.settings = {}
+            return 'SAORI/1.0 204 No Content\r\n\r\n'
+        else:
+            return 'SAORI/1.0 400 Bad Request\r\n\r\n'
+
+    def do_idle_tasks(self):
+        if self.timeout_id is None:
+            return False
+        target = self.settings['target']
+        if target == 'ACTIVE':
+            active_id = self.get_active_window()
+            gdk_win = gtk.gdk.window_lookup(active_id)
+            if gdk_win and self.__ghost.identify_window(gdk_win):
+                return True
+            root_screen = gtk.gdk.screen_get_default() # XXX
+            active = root_screen.get_active_window()
+            if active:
+                target_x, target_y, target_w, target_h = self.get_geometry(active)
+            else:
+                return True
+        elif target == 'FIX': ## FIXME
+            target_x = 0
+            target_y = 0
+            target_w = gtk.gdk.screen_width()
+            target_h = gtk.gdk.screen_height()
+        elif target.startswith('@'): ## FIXME
+            #win = self.get_window_by_name(target[1:])
+            #if self.__ghost.identify_window(gtk.gdk.window_lookup(win.id)):
+            #    return True
+            #target_x, target_y, target_w, target_h = self.get_geometry(win)
+            return False
+        elif target.startswith('#'): ## FIXME
+            return False
+        else:
+            return False # should not reach here
+        pos = self.settings['position']
+        scale = self.__ghost.get_surface_scale()
+        offset_x = int(self.settings['offset_x'] * scale / 100)
+        offset_y = int(self.settings['offset_y'] * scale / 100)
+        if self.settings['hwnd'].startswith('s'):
+            try:
+                side = int(self.settings['hwnd'][1:])
+            except:
+                return False
+        else:
+            try:
+                side = int(self.settings['hwnd'])
+            except:
+                return False
+        w, h = self.__ghost.get_surface_size(side)
+        if pos[0] == 'T':
+            y = target_y + offset_y
+        elif pos[0] == 'B':
+            y = target_y + target_h + offset_y - h
+        else:
+            return False # should not reach here
+        if pos[1] == 'L':
+            x = target_x + offset_x
+        elif pos[1] == 'R':
+            x = target_x + target_w + offset_x - w
+        else:
+            return False # should not reach here
+        if not self.settings['noclip']:
+            if x < 0 or y < 0:
+                pass ## FIXME
+        self.__ghost.set_surface_position(side, x, y)
+        self.__ghost.raise_surface(side) ## FIXME
+        return True
+
+    def get_geometry(self, win):
+        relative_x, relative_y, w, h , d = win.get_geometry() # ._data
+        w = w + relative_x * 2
+        h = h + relative_y + relative_x
+        x, y = win.get_root_origin()
+        return x, y, w, h
+        #return geom['x'], geom['y'], geom['width'], geom['height']
+
+    def get_window_by_name(self, name): ## FIXME
+        return None
+
+    def get_active_window(self):
+        root = gtk.gdk.get_default_root_window()
+        atom = gtk.gdk.atom_intern("_NET_SUPPORTED", True)
+        supported_atom = root.property_get(atom)
+        if supported_atom is None or len(supported_atom) < 2:
+            return None
+        else:
+            assert supported_atom[0] == 'ATOM'
+            supported = supported_atom[2]
+        current_desktop = 0
+        if "_NET_CURRENT_DESKTOP" in supported:
+            atom = gtk.gdk.atom_intern("_NET_CURRENT_DESKTOP", True)
+            current_desktop = root.property_get(atom)[2][0]
+        if "_NET_ACTIVE_WINDOW" in supported:
+            atom = gtk.gdk.atom_intern("_NET_ACTIVE_WINDOW", True)
+            active_window = root.property_get(atom)[2][current_desktop]
+        return active_window
index 8e2106a..bf7df76 100644 (file)
@@ -159,6 +159,13 @@ class Ghost:
         else:
             return 0
 
+    def identify_window(self, win):
+        if self.__surface.identify_window(win) or \
+           self.__balloon.identify_window(win):
+            return True
+        else:
+            return False
+
     def set_observer(self, observer):
         if observer not in self.__observer:
             self.__observer.append(observer)
index 55112e7..c3bdad8 100644 (file)
@@ -124,6 +124,12 @@ class Surface:
         window.realize()
         return window
 
+    def identify_window(self, win):
+        for surface_window in self.window:
+            if win == surface_window.window.window:
+                return True
+        return False
+
     def window_stayontop(self, flag):
         for surface_window in self.window:
             gtk_window = surface_window.window
index b7e3603..0339c31 100644 (file)
@@ -10,7 +10,7 @@
 #  PURPOSE.  See the GNU General Public License for more details.
 #
 
-NUMBER = '3.9.6'
+NUMBER = '3.9.7'
 CODENAME = '"I see no more YASAGURE here."'
 
 VERSION = '%s (%s)' % (NUMBER, CODENAME)