| Index: client/site_tests/factory_Synaptics/factory_Synaptics.py
|
| diff --git a/client/site_tests/factory_Synaptics/factory_Synaptics.py b/client/site_tests/factory_Synaptics/factory_Synaptics.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bb5e99ce3f95c4ef39300ba101534c492b7fe2c9
|
| --- /dev/null
|
| +++ b/client/site_tests/factory_Synaptics/factory_Synaptics.py
|
| @@ -0,0 +1,221 @@
|
| +# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +
|
| +from autotest_lib.client.bin import test
|
| +from autotest_lib.client.common_lib import error
|
| +from autotest_lib.client.common_lib import factory_test
|
| +
|
| +import cairo
|
| +import gobject
|
| +import gtk
|
| +import pango
|
| +import time
|
| +import os
|
| +import sys
|
| +import subprocess
|
| +
|
| +
|
| +_SYNCLIENT_SETTINGS_CMDLINE = '/usr/bin/synclient -l'
|
| +_SYNCLIENT_CMDLINE = '/usr/bin/synclient -m 50'
|
| +
|
| +_RGBA_GREEN_OVERLAY = (0, 0.5, 0, 0.6)
|
| +
|
| +_X_SEGMENTS = 5
|
| +_Y_SEGMENTS = 4
|
| +
|
| +_X_TP_OFFSET = 10
|
| +_Y_TP_OFFSET = 10
|
| +_TP_WIDTH = 397
|
| +_TP_HEIGHT = 213
|
| +_TP_SECTOR_WIDTH = (_TP_WIDTH / _X_SEGMENTS) - 1
|
| +_TP_SECTOR_HEIGHT = (_TP_HEIGHT / _Y_SEGMENTS) - 1
|
| +
|
| +_X_SP_OFFSET = 432
|
| +_SP_WIDTH = 19
|
| +
|
| +
|
| +class TouchpadTest:
|
| +
|
| + def __init__(self, tp_image, drawing_area):
|
| + self._tp_image = tp_image
|
| + self._drawing_area = drawing_area
|
| + self._motion_grid = {}
|
| + for x in range(_X_SEGMENTS):
|
| + for y in range(_Y_SEGMENTS):
|
| + self._motion_grid['%d,%d' % (x, y)] = False
|
| + self._scroll_array = {}
|
| + for y in range(_Y_SEGMENTS):
|
| + self._scroll_array[y] = False
|
| + self._l_click = False
|
| + self._r_click = False
|
| +
|
| + def timer_event(self, window):
|
| + if not self._deadline:
|
| + # Ignore timer events with no countdown in progress.
|
| + return True
|
| + if self._deadline <= time.time():
|
| + XXX_log('deadline reached')
|
| + gtk.main_quit()
|
| + window.queue_draw()
|
| + return True
|
| +
|
| + def device_event(self, x, y, z, fingers, left, right):
|
| + x_seg = int(round(x / (1.0 / float(_X_SEGMENTS - 1))))
|
| + y_seg = int(round(y / (1.0 / float(_Y_SEGMENTS - 1))))
|
| + index = '%d,%d' % (x_seg, y_seg)
|
| + assert(index in self._motion_grid)
|
| + assert(y_seg in self._scroll_array)
|
| + if left and not self._l_click:
|
| + self._l_click = True
|
| + factory_test.XXX_log('ok left click')
|
| + elif right and not self._r_click:
|
| + self._r_click = True
|
| + factory_test.XXX_log('ok right click')
|
| + elif fingers == 1 and not self._motion_grid[index]:
|
| + self._motion_grid[index] = True
|
| + elif fingers == 2 and not self._scroll_array[y_seg]:
|
| + self._scroll_array[y_seg] = True
|
| + else:
|
| + return
|
| + self._drawing_area.queue_draw()
|
| + missing_motion_sectors = set(i for i, v in self._motion_grid.items()
|
| + if v is False)
|
| + missing_scroll_segments = set(i for i, v in self._scroll_array.items()
|
| + if v is False)
|
| + if (self._l_click and self._r_click
|
| + and not missing_motion_sectors
|
| + and not missing_scroll_segments):
|
| + gtk.main_quit()
|
| +
|
| + def expose_event(self, widget, event):
|
| + context = widget.window.cairo_create()
|
| +
|
| + context.set_source_surface(self._tp_image, 0, 0)
|
| + context.paint()
|
| +
|
| + for index in self._motion_grid:
|
| + if not self._motion_grid[index]:
|
| + continue
|
| + ind_x, ind_y = map(int, index.split(','))
|
| + x = _X_TP_OFFSET + (ind_x * (_TP_SECTOR_WIDTH + 1))
|
| + y = _Y_TP_OFFSET + (ind_y * (_TP_SECTOR_HEIGHT + 1))
|
| + coords = (x, y, _TP_SECTOR_WIDTH, _TP_SECTOR_HEIGHT)
|
| + context.rectangle(*coords)
|
| + context.set_source_rgba(*_RGBA_GREEN_OVERLAY)
|
| + context.fill()
|
| +
|
| + for y_seg in self._scroll_array:
|
| + if not self._scroll_array[y_seg]:
|
| + continue
|
| + y = _Y_TP_OFFSET + (y_seg * (_TP_SECTOR_HEIGHT + 1))
|
| + coords = (_X_SP_OFFSET, y, _SP_WIDTH, _TP_SECTOR_HEIGHT)
|
| + context.rectangle(*coords)
|
| + context.set_source_rgba(*_RGBA_GREEN_OVERLAY)
|
| + context.fill()
|
| +
|
| + return True
|
| +
|
| + def key_press_event(self, widget, event):
|
| + factory_test.test_switch_on_trigger(event)
|
| + return True
|
| +
|
| + def button_press_event(self, widget, event):
|
| + factory_test.XXX_log('button_press_event %d,%d' % (event.x, event.y))
|
| + return True
|
| +
|
| + def button_release_event(self, widget, event):
|
| + factory_test.XXX_log('button_release_event %d,%d' % (event.x, event.y))
|
| + return True
|
| +
|
| + def motion_event(self, widget, event):
|
| + factory_test.XXX_log('motion_event %d,%d' % (event.x, event.y))
|
| + return True
|
| +
|
| + def register_callbacks(self, window):
|
| + window.connect('key-press-event', self.key_press_event)
|
| + window.add_events(gtk.gdk.KEY_PRESS_MASK)
|
| +
|
| +
|
| +class SynClient:
|
| +
|
| + def __init__(self, test):
|
| + self._test = test
|
| + proc = subprocess.Popen(_SYNCLIENT_SETTINGS_CMDLINE.split(),
|
| + stdout=subprocess.PIPE)
|
| + settings_data = proc.stdout.readlines()
|
| + settings = {}
|
| + for line in settings_data:
|
| + cols = [x for x in line.rstrip().split(' ') if x]
|
| + if len(cols) != 3 or cols[1] != '=':
|
| + continue
|
| + settings[cols[0]] = cols[2]
|
| + self._xmin = float(settings['LeftEdge'])
|
| + self._xmax = float(settings['RightEdge'])
|
| + self._ymin = float(settings['TopEdge'])
|
| + self._ymax = float(settings['BottomEdge'])
|
| + self._proc = subprocess.Popen(_SYNCLIENT_CMDLINE.split(),
|
| + stdout=subprocess.PIPE)
|
| + gobject.io_add_watch(self._proc.stdout, gobject.IO_IN, self.recv)
|
| +
|
| + def recv(self, src, cond):
|
| + data = self._proc.stdout.readline().split()
|
| + if len(data) != 17:
|
| + factory_test.XXX_log('unknown data : %d, %s' % (len(data), data))
|
| + return True
|
| + if data[0] == 'time':
|
| + return True
|
| + data_x, data_y, z, f, w, l, r = data[1:8]
|
| + x = sorted([self._xmin, float(data_x), self._xmax])[1]
|
| + x = (x - self._xmin) / (self._xmax - self._xmin)
|
| + y = sorted([self._ymin, float(data_y), self._ymax])[1]
|
| + y = (y - self._ymin) / (self._ymax - self._ymin)
|
| + self._test.device_event(x, y, int(z), int(f), int(l), int(r))
|
| + return True
|
| +
|
| + def quit(self):
|
| + factory_test.XXX_log('killing SynClient ...')
|
| + self._proc.kill()
|
| + factory_test.XXX_log('dead')
|
| +
|
| +
|
| +class factory_Touchpad(test.test):
|
| + version = 1
|
| + preserve_srcdir = True
|
| +
|
| + def run_once(self, test_widget_size=None, trigger_set=None,
|
| + result_file_path=None):
|
| +
|
| + factory_test.XXX_log('factory_Touchpad')
|
| +
|
| + factory_test.init(trigger_set=trigger_set,
|
| + result_file_path=result_file_path)
|
| +
|
| + os.chdir(self.srcdir)
|
| + tp_image = cairo.ImageSurface.create_from_png('touchpad.png')
|
| + image_size = (tp_image.get_width(), tp_image.get_height())
|
| +
|
| + drawing_area = gtk.DrawingArea()
|
| +
|
| + test = TouchpadTest(tp_image, drawing_area)
|
| +
|
| + drawing_area.set_size_request(*image_size)
|
| + drawing_area.connect('expose_event', test.expose_event)
|
| + drawing_area.connect('button-press-event', test.button_press_event)
|
| + drawing_area.connect('button-release-event', test.button_release_event)
|
| + drawing_area.connect('motion-notify-event', test.motion_event)
|
| + drawing_area.add_events(gtk.gdk.EXPOSURE_MASK |
|
| + gtk.gdk.BUTTON_PRESS_MASK |
|
| + gtk.gdk.BUTTON_RELEASE_MASK |
|
| + gtk.gdk.POINTER_MOTION_MASK)
|
| +
|
| + synclient = SynClient(test)
|
| +
|
| + factory_test.run_test_widget(
|
| + test_widget=drawing_area,
|
| + test_widget_size=test_widget_size,
|
| + window_registration_callback=test.register_callbacks,
|
| + cleanup_callback=synclient.quit)
|
| +
|
| + factory_test.XXX_log('exiting factory_Touchpad')
|
|
|