Package elisa :: Package plugins :: Package good :: Package pigment :: Module pigment_context
[hide private]
[frames] | no frames]

Source Code for Module elisa.plugins.good.pigment.pigment_context

  1  # -*- coding: utf-8 -*- 
  2  # Elisa - Home multimedia server 
  3  # Copyright (C) 2006-2008 Fluendo Embedded S.L. (www.fluendo.com). 
  4  # All rights reserved. 
  5  # 
  6  # This file is available under one of two license agreements. 
  7  # 
  8  # This file is licensed under the GPL version 3. 
  9  # See "LICENSE.GPL" in the root of this distribution including a special 
 10  # exception to use Elisa with Fluendo's plugins. 
 11  # 
 12  # The GPL part of Elisa is also available under a commercial licensing 
 13  # agreement from Fluendo. 
 14  # See "LICENSE.Elisa" in the root directory of this distribution package 
 15  # for details on that license. 
 16   
 17   
 18  __maintainer__ = 'Lionel Martin <lionel@fluendo.com>' 
 19  __maintainer2__ = 'Florian Boucault <florian@fluendo.com>' 
 20   
 21   
 22  from elisa.base_components.context import Context 
 23  from elisa.core.utils import signal 
 24   
 25  import pgm 
 26  import os 
 27   
 28  from twisted.internet import reactor 
 29   
30 -class PigmentContext(Context):
31 """ 32 Context based on Pigment. Creates a Pigment viewport and associates a 33 Pigment canvas to it. It takes care of the viewport resizes and 34 subsequent regenerations. 35 36 @ivar master_drawables: dictionary of master drawables used for improved 37 theme management based on Pigment cloning 38 keys: theme icons 39 values: master drawables 40 @type master_drawables: dictionary 41 """ 42 43 default_config = {'screen_ratio' : 'auto', 44 'window_width': '0', 45 'touchscreen': '0', 46 'use_gtk': '0'} 47 config_doc = {'screen_ratio' : 'The ratio of the screen. This is a string' 48 ' containing a relation value, separated' 49 ' by a colon (:). Common values are 16:9,' 50 ' 4:3, 16:10, but it could be any other,' 51 ' too. You can have special values : mm,' 52 ' based on screen size in milimeters,' 53 ' sr, based on window manager resolution,' 54 ' or auto. auto will use mm special value.', 55 'window_width' : 'Here you can set the width in pixels the' 56 ' window should have at startup. The height' 57 ' is computed using screen_ratio.' 58 ' If this value is 0, we decide' 59 ' automatically.', 60 'touchscreen' : 'If set to 1, the mouse behaviour will be' 61 ' adapted for touchscreen equipped hardware.' 62 } 63 64 master_drawables = {} 65
66 - def initialize(self):
67 Context.initialize(self) 68 69 # signal handlers id 70 self._signal_handler_ids = [] 71 72 config_screen_ratio = self.config.get('screen_ratio', 'auto') 73 74 self.touchscreen = self.config.get('touchscreen', '1') == '1' 75 try: 76 # FIXME: that is only working on Linux with ps installed 77 self._compiz_check() 78 except: 79 pass 80 81 # FIXME: this is a workaround a Python import bug; at that point for 82 # some reason pgm is not defined. This should be fixed with Python 83 # 3000 84 import pgm 85 86 # OpenGL viewport creation 87 factory = pgm.ViewportFactory('opengl') 88 viewport = factory.create() 89 90 self.viewport_handle = viewport 91 viewport.title = 'Elisa Media Center' 92 self._window_managet_screen_size_mm = viewport.screen_size_mm 93 94 # Canvas creation 95 self.canvas = pgm.Canvas() 96 97 try: 98 width = int(self.config.get('window_width', '0')) 99 if width != 0: 100 viewport.width = width 101 except Exception, e: 102 self.warning("The configuration value of window_width seems to be" 103 " no number value in pixels: %s" % e) 104 105 # delay the resize of the canvas to avoid crippling the CPU 106 self._resize_delay = 0.200 107 self._resize_delayed = None 108 self.canvas_resized = signal.Signal('canvas_resized', tuple) 109 self.aspect_ratio_changed(None, config_screen_ratio) 110 111 # Bind the canvas to the OpenGL viewport 112 viewport.set_canvas(self.canvas) 113 114 use_gtk = self.config.get('use_gtk', 115 self.default_config.get('use_gtk')) == '1' 116 if use_gtk: 117 import gtk 118 import pgm.gtk 119 self.gtk_window = gtk.Window(gtk.WINDOW_TOPLEVEL) 120 id = self.gtk_window.connect('delete-event', 121 self._gtk_window_delete_event_cb) 122 self._signal_handler_ids.append(id) 123 embed = pgm.gtk.PgmGtk() 124 self.gtk_window.add(embed) 125 embed.set_viewport(viewport) 126 self.gtk_window.resize(*viewport.size) 127 self.gtk_window.set_focus_child(embed) 128 self.gtk_window.show_all() 129 else: 130 # show the window 131 self.gtk_window = None 132 viewport.show() 133 id = viewport.connect('configure-event', self._configure_callback) 134 self._signal_handler_ids.append(id) 135 136 # hide the cursor 137 self.viewport_handle.cursor = pgm.VIEWPORT_NONE 138 139 if not self.touchscreen: 140 # delay the hiding of the mouse cursor 141 self._cursor_delay = 1.000 142 self._cursor_delayed = None 143 # signal triggered when the canvas gets resized 144 id = viewport.connect('motion-notify-event', 145 self._motion_notify_callback) 146 self._signal_handler_ids.append(id)
147
148 - def _gtk_window_delete_event_cb(self, *args):
149 from elisa.core import common 150 common.application.stop()
151
152 - def aspect_ratio_changed(self, old_aspect_ratio, new_aspect_ratio):
153 if old_aspect_ratio is not None: 154 self.debug("aspect ratio changed from %r to %r", old_aspect_ratio, 155 new_aspect_ratio) 156 else: 157 self.info("will set the aspect ratio with parameter %r", new_aspect_ratio) 158 159 screen_ratio = self._get_screen_size_from_ratio(new_aspect_ratio) 160 self.debug("screen ratio is %r", screen_ratio) 161 162 pixel_aspect_ratio = self._get_pixel_aspect_ratio(screen_ratio) 163 self.info("used pixel aspect ratio is %r", pixel_aspect_ratio) 164 165 canvas_height = self.canvas.width / screen_ratio 166 self.debug("new canvas height: %r", canvas_height) 167 self.canvas.height = canvas_height 168 169 # set the window aspect ratio to the screen aspect ratio 170 viewport_height = self.viewport_handle.width / (screen_ratio * pixel_aspect_ratio) 171 self.debug("new viewport height: %r", viewport_height) 172 self.viewport_handle.height = viewport_height 173 174 #w2,l2 = self.viewport_handle.size 175 #self.viewport_handle.screen_size_mm = (int(w), int(h)) 176 self.viewport_size = self.viewport_handle.size 177 self.debug("viewport size: %r", self.viewport_size) 178 179 config_screen_ratio = self.config.get('screen_ratio', 'auto') 180 if config_screen_ratio != new_aspect_ratio: 181 self.config['screen_ratio'] = new_aspect_ratio 182 183 self.canvas_resized.emit(self.canvas.size)
184
185 - def clean(self):
186 viewport = self.viewport_handle 187 188 # disconnecting from all the signals it connected to 189 for id in self._signal_handler_ids: 190 viewport.disconnect(id) 191 192 # unbinding the canvas from the OpenGL viewport 193 viewport.set_canvas(None) 194 195 # releasing its reference to the OpenGL viewport 196 del self.viewport_handle
197
198 - def context_handle__set(self, context_handle):
199 self._context_handle = context_handle 200 if isinstance(context_handle, pgm.Drawable): 201 self.canvas.add(pgm.DRAWABLE_MIDDLE, context_handle)
202
203 - def context_handle__get(self):
204 return self._context_handle
205
206 - def _compiz_check(self):
207 # FIXME: this is a work-a-round against the flickering in compiz 208 ps_aux = os.popen('ps aux') 209 210 compiz = False 211 212 for line in ps_aux: 213 if 'compiz' in line: 214 compiz = True 215 216 if compiz: 217 self.warning("Compiz detected, trying to hide all other windows.") 218 try: 219 import wnck 220 except ImportError: 221 self.warning("Could not import WNCK. Windows hiding disabled.") 222 else: 223 s = wnck.screen_get_default() 224 s.force_update() 225 lst = s.get_windows() 226 cur_workspace = s.get_active_workspace() 227 for window in lst: 228 if window.is_in_viewport(cur_workspace): 229 window.minimize() 230 231 else: 232 self.info('Compiz not found')
233
234 - def _get_screen_size_from_ratio(self, config_screen_ratio):
235 # retrieve the screen aspect ratio 236 if config_screen_ratio == 'sr': 237 self.info("using window manager screen resolution as screen aspect ratio: %r", 238 self.viewport_handle.screen_resolution) 239 w, h = self.viewport_handle.screen_resolution 240 self.viewport_handle.screen_size_mm = (int(w), int(h) ) 241 elif config_screen_ratio.find(':') != -1: 242 self.info("Using configured aspect screen ratio: %r", config_screen_ratio) 243 w, h = config_screen_ratio.split(':') 244 self.viewport_handle.screen_size_mm = (int(w), int(h)) 245 else: 246 self.info("Using the milimeter based screen aspect ratio : %r", 247 self.viewport_handle.screen_size_mm) 248 w, h = self._window_managet_screen_size_mm 249 self.viewport_handle.screen_size_mm = (int(w), int(h)) 250 width = float(w) 251 height = float(h) 252 self.debug("screen size: (%r,%r)", width, height) 253 254 return width / float(height)
255
256 - def _get_pixel_aspect_ratio(self, screen_aspect_ratio):
257 w, h = self.viewport_handle.screen_resolution 258 return ( w / float(h) ) / float(screen_aspect_ratio)
259
260 - def _configure_callback(self, viewport, event):
261 # (re)schedule the resize of the canvas 262 if self._resize_delayed != None and self._resize_delayed.active(): 263 self._resize_delayed.reset(self._resize_delay) 264 else: 265 self._resize_delayed = reactor.callLater(self._resize_delay, 266 self._resize_canvas)
267
268 - def _resize_canvas(self):
269 # only reacts if the size of the viewport changed 270 if self.viewport_size != self.viewport_handle.size: 271 self.debug("regeneration of the drawables") 272 self.viewport_size = self.viewport_handle.size 273 self.canvas_resized.emit(self.canvas.size) 274 275 """ 276 # resize the canvas to follow the aspect ratio of the viewport 277 viewport_ratio = float(self.viewport_handle.width)/float(self.viewport_handle.height) 278 canvas_ratio = float(self.canvas.width)/float(self.canvas.height) 279 280 # only resize the canvas if the aspect ratio of the viewport has changed 281 if viewport_ratio != canvas_ratio: 282 # FIXME: only one of width/height needs to change (multiplied by 283 # viewport_ratio) 284 self.canvas.size = (self.viewport_handle.width/100.0, 285 self.viewport_handle.height/100.0) 286 self.debug("The canvas is getting resized. New size = (%s, %s)" % \ 287 (self.canvas.size[0], self.canvas.size[1])) 288 """
289
290 - def _motion_notify_callback(self, viewport, event):
291 # show the cursor 292 viewport.cursor = pgm.VIEWPORT_INHERIT 293 294 # (re)schedule the hiding of the cursor 295 if self._cursor_delayed != None and self._cursor_delayed.active(): 296 self._cursor_delayed.reset(self._cursor_delay) 297 else: 298 self._cursor_delayed = reactor.callLater(self._cursor_delay, self._hide_cursor)
299
300 - def _hide_cursor(self):
301 self.viewport_handle.cursor = pgm.VIEWPORT_NONE
302
303 - def theme_changed(self, old_theme, new_theme):
304 for icon, master in self.master_drawables.iteritems(): 305 image_path = new_theme.get_media(icon) 306 master.set_from_file(image_path)
307