| Index: client/bin/factory_ui
|
| diff --git a/client/bin/factory_ui b/client/bin/factory_ui
|
| index ba0767eb2af038c5597a70223f011437a8e48bb6..44051bb5f1751bc7fc438ebcc11b7814580f9127 100755
|
| --- a/client/bin/factory_ui
|
| +++ b/client/bin/factory_ui
|
| @@ -28,6 +28,7 @@ import gtk
|
| import imp
|
| import os
|
| import pango
|
| +import signal
|
| import subprocess
|
| import sys
|
| import time
|
| @@ -36,6 +37,10 @@ import common
|
| import factory
|
| import factory_ui_lib as ful
|
|
|
| +from gtk import gdk
|
| +from Xlib import X
|
| +from Xlib.display import Display as X_Display
|
| +
|
|
|
| # These definitions are expose these classes directly into this
|
| # namespace, so that the test_list that is sent from the control file
|
| @@ -49,8 +54,6 @@ AutomatedSubTest = factory.AutomatedSubTest
|
| AutomatedRebootSubTest = factory.AutomatedRebootSubTest
|
|
|
|
|
| -_SEP_COLOR = gtk.gdk.color_parse('grey50')
|
| -
|
| _LABEL_EN_SIZE = (170, 35)
|
| _LABEL_ZW_SIZE = (70, 35)
|
| _LABEL_EN_FONT = pango.FontDescription('courier new extra-condensed 16')
|
| @@ -160,7 +163,7 @@ class SubTestLabelBox(gtk.EventBox):
|
|
|
| class UiState():
|
|
|
| - def __init__(self, window, status_map, test_widget_box):
|
| + def __init__(self, status_map, test_widget_box):
|
|
|
| def make_empty_test_label_widget():
|
| label_box = gtk.EventBox()
|
| @@ -180,7 +183,6 @@ class UiState():
|
| False, False)
|
| return vbox
|
|
|
| - self._window = window
|
| self._status_map = status_map
|
| self._test_widget_box = test_widget_box
|
| self._empty_test_widget = make_empty_test_label_widget()
|
| @@ -212,21 +214,7 @@ class UiState():
|
| or self._empty_test_widget)
|
| self._test_widget_box.add(active_widget)
|
| self._active_test_widget = active_widget
|
| - self._window.show_all()
|
| -
|
| -
|
| -def make_hsep(width=1):
|
| - frame = gtk.EventBox()
|
| - frame.set_size_request(-1, width)
|
| - frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR)
|
| - return frame
|
| -
|
| -
|
| -def make_vsep(width=1):
|
| - frame = gtk.EventBox()
|
| - frame.set_size_request(width, -1)
|
| - frame.modify_bg(gtk.STATE_NORMAL, _SEP_COLOR)
|
| - return frame
|
| + self._test_widget_box.show_all()
|
|
|
|
|
| def refresh_status(status_map, ui_state):
|
| @@ -236,25 +224,46 @@ def refresh_status(status_map, ui_state):
|
| return True
|
|
|
|
|
| -def main():
|
| - '''This process is launched by the autotest suite_Factory control
|
| - process. Communication with this process is an exchange of well
|
| - formed python expressions over stdin and stdout. Basically
|
| - sending wraps arguments in a call to repr() and recv calls eval()
|
| - to re-generate the python data.'''
|
| +def grab_shortcut_keys(kbd_shortcut_set, control_pid):
|
| + disp = X_Display()
|
| + root = disp.screen().root
|
| +
|
| + # We want to receive KeyPress events
|
| + root.change_attributes(event_mask = X.KeyPressMask)
|
| +
|
| + keycode_map = {}
|
| + for shortcut in kbd_shortcut_set:
|
| + keysym = gdk.keyval_from_name(shortcut)
|
| + keycode = disp.keysym_to_keycode(keysym)
|
| + keycode_map[keycode] = shortcut
|
| + root.grab_key(keycode, X.ControlMask, 1,
|
| + X.GrabModeAsync, X.GrabModeAsync)
|
|
|
| - def control_recv():
|
| - return eval(sys.stdin.readline().rstrip())
|
| + # This flushes the XGrabKey calls to the server.
|
| + for x in range(0, root.display.pending_events()):
|
| + root.display.next_event()
|
|
|
| - def control_send(x):
|
| - print repr(x)
|
| - sys.stdout.flush()
|
| + def handle_xevent(src, cond, xhandle=root.display,
|
| + keycode_map=keycode_map,
|
| + control_pid=control_pid):
|
| + for i in range(0, xhandle.pending_events()):
|
| + xevent = xhandle.next_event()
|
| + if xevent.type == X.KeyPress:
|
| + keycode = xevent.detail
|
| + factory.log_shared_data('activated_kbd_shortcut',
|
| + keycode_map[keycode])
|
| + os.kill(control_pid, signal.SIGUSR1)
|
| + return True
|
|
|
| - # On startup, get the list of tests to run (in order) and the
|
| - # autotest status file path.
|
| - factory.log('pulling control info')
|
| - test_list = control_recv()
|
| - status_file_path = control_recv()
|
| + gobject.io_add_watch(root.display, gobject.IO_IN, handle_xevent)
|
| +
|
| +
|
| +def main(test_list, status_file_path, control_pid):
|
| + '''This process is launched by the autotest suite_Factory control
|
| + process, which should be identified by the <control pid> cmdline
|
| + argument. When operators press keyboard shortcuts, the shortcut
|
| + value is logged with log_shared_data() and a SIGUSR1 is sent to
|
| + the control program.'''
|
|
|
| status_map = factory.StatusMap(test_list, status_file_path)
|
|
|
| @@ -263,6 +272,11 @@ def main():
|
| window.modify_bg(gtk.STATE_NORMAL, ful.BLACK)
|
|
|
| screen = window.get_screen()
|
| + if (screen is None):
|
| + log('ERROR: communication with the X server is not working, ' +
|
| + 'could not find a working screen. UI exiting.')
|
| + sys.exit(1)
|
| +
|
| screen_size = (screen.get_width(), screen.get_height())
|
| window.set_size_request(*screen_size)
|
|
|
| @@ -280,16 +294,16 @@ def main():
|
| test_widget_box = gtk.Alignment(xalign=0.5, yalign=0.5)
|
| test_widget_box.set_size_request(-1, -1)
|
|
|
| - ui_state = UiState(window, status_map, test_widget_box)
|
| + ui_state = UiState(status_map, test_widget_box)
|
|
|
| lhs_box = gtk.VBox()
|
| lhs_box.pack_end(console_box, False, False)
|
| lhs_box.pack_start(test_widget_box)
|
| - lhs_box.pack_start(make_hsep(3), False, False)
|
| + lhs_box.pack_start(ful.make_hsep(3), False, False)
|
|
|
| base_box = gtk.HBox()
|
| base_box.pack_end(rhs_box, False, False)
|
| - base_box.pack_end(make_vsep(3), False, False)
|
| + base_box.pack_end(ful.make_vsep(3), False, False)
|
| base_box.pack_start(lhs_box)
|
|
|
| window.connect('key-release-event', handle_key_release_event)
|
| @@ -302,18 +316,19 @@ def main():
|
| label_box = TestLabelBox(test)
|
| status_map.set_label_box(test, label_box)
|
| label_trough.pack_start(label_box, False, False)
|
| - label_trough.pack_start(make_hsep(), False, False)
|
| + label_trough.pack_start(ful.make_hsep(), False, False)
|
|
|
| window.add(base_box)
|
| window.show_all()
|
|
|
| + grab_shortcut_keys(status_map.test_db.kbd_shortcut_set, control_pid)
|
| +
|
| ful.hide_cursor(window.window)
|
|
|
| test_widget_allocation = test_widget_box.get_allocation()
|
| test_widget_size = (test_widget_allocation.width,
|
| test_widget_allocation.height)
|
| - factory.log('test_widget_size = %s' % repr(test_widget_size))
|
| - control_send(test_widget_size)
|
| + factory.log_shared_data('test_widget_size', test_widget_size)
|
|
|
| console = Console(console_box.get_allocation())
|
|
|
| @@ -324,4 +339,13 @@ def main():
|
| factory.log('factory_ui gtk.main() finished, exiting.')
|
|
|
| if __name__ == '__main__':
|
| - main()
|
| +
|
| + if len(sys.argv) != 4:
|
| + print ('usage: %s <test list path> <status file path> <control pid>' %
|
| + sys.argv[0])
|
| + test_list_path, status_file_path, control_pid_str = sys.argv[1:]
|
| + control_pid = int(control_pid_str)
|
| +
|
| + execfile(test_list_path)
|
| +
|
| + main(TEST_LIST, status_file_path, control_pid)
|
|
|