xref: /aosp_15_r20/external/libkmsxx/py/tests/kmsmodeview.py (revision f0687c8a10b3e371dbe09214db6664e37c283cca)
1*f0687c8aSRaman Tenneti#!/usr/bin/python3
2*f0687c8aSRaman Tenneti
3*f0687c8aSRaman Tennetiimport urwid
4*f0687c8aSRaman Tennetiimport pykms
5*f0687c8aSRaman Tenneti
6*f0687c8aSRaman Tennetidef exit_on_q(key):
7*f0687c8aSRaman Tenneti	if key in ('q', 'Q'):
8*f0687c8aSRaman Tenneti		raise urwid.ExitMainLoop()
9*f0687c8aSRaman Tenneti	elif key == 'a':
10*f0687c8aSRaman Tenneti		apply_mode()
11*f0687c8aSRaman Tenneti
12*f0687c8aSRaman Tennetialarm_handle = None
13*f0687c8aSRaman Tenneti
14*f0687c8aSRaman Tennetidef recalc_info(l, d):
15*f0687c8aSRaman Tenneti	global alarm_handle
16*f0687c8aSRaman Tenneti
17*f0687c8aSRaman Tenneti	alarm_handle = None
18*f0687c8aSRaman Tenneti
19*f0687c8aSRaman Tenneti	for w in recalc_list:
20*f0687c8aSRaman Tenneti		w.recalc()
21*f0687c8aSRaman Tenneti
22*f0687c8aSRaman Tennetidef div_or_zero(n, d):
23*f0687c8aSRaman Tenneti	if d == 0:
24*f0687c8aSRaman Tenneti		return 0
25*f0687c8aSRaman Tenneti	else:
26*f0687c8aSRaman Tenneti		return n / d
27*f0687c8aSRaman Tenneti
28*f0687c8aSRaman Tenneticlass MyIntEdit(urwid.IntEdit):
29*f0687c8aSRaman Tenneti	_metaclass_ = urwid.signals.MetaSignals
30*f0687c8aSRaman Tenneti	signals = ['value_change']
31*f0687c8aSRaman Tenneti
32*f0687c8aSRaman Tenneti	def __init__(self, caption, calc=None):
33*f0687c8aSRaman Tenneti		self._myval = 0
34*f0687c8aSRaman Tenneti		self._disable_change = False
35*f0687c8aSRaman Tenneti		self._calc = calc
36*f0687c8aSRaman Tenneti		self._updlist = None
37*f0687c8aSRaman Tenneti
38*f0687c8aSRaman Tenneti		super().__init__(caption, 0)
39*f0687c8aSRaman Tenneti
40*f0687c8aSRaman Tenneti	def set_edit_text(self, text):
41*f0687c8aSRaman Tenneti		global alarm_handle
42*f0687c8aSRaman Tenneti
43*f0687c8aSRaman Tenneti		super().set_edit_text(text)
44*f0687c8aSRaman Tenneti		newtext = super().get_edit_text()
45*f0687c8aSRaman Tenneti		new_val = int(newtext) if newtext != "" else 0
46*f0687c8aSRaman Tenneti		if new_val != self._myval:
47*f0687c8aSRaman Tenneti			self._myval = new_val
48*f0687c8aSRaman Tenneti			if not self._disable_change:
49*f0687c8aSRaman Tenneti				urwid.emit_signal(self, 'value_change', self, self._myval)
50*f0687c8aSRaman Tenneti
51*f0687c8aSRaman Tenneti				if alarm_handle == None:
52*f0687c8aSRaman Tenneti					alarm_handle = loop.set_alarm_in(0, recalc_info)
53*f0687c8aSRaman Tenneti
54*f0687c8aSRaman Tenneti				if self._updlist != None:
55*f0687c8aSRaman Tenneti					for w in self._updlist:
56*f0687c8aSRaman Tenneti						w.recalc()
57*f0687c8aSRaman Tenneti
58*f0687c8aSRaman Tenneti	def recalc(self):
59*f0687c8aSRaman Tenneti		self._disable_change = True
60*f0687c8aSRaman Tenneti		self.set_val(self._calc())
61*f0687c8aSRaman Tenneti		self._disable_change = False
62*f0687c8aSRaman Tenneti
63*f0687c8aSRaman Tenneti	def set_val(self, val):
64*f0687c8aSRaman Tenneti		self.set_edit_text(str(int(val)))
65*f0687c8aSRaman Tenneti
66*f0687c8aSRaman Tenneti	def get_val(self):
67*f0687c8aSRaman Tenneti		return self._myval
68*f0687c8aSRaman Tenneti
69*f0687c8aSRaman Tenneti	def set_updlist(self, list):
70*f0687c8aSRaman Tenneti		self._updlist = list
71*f0687c8aSRaman Tenneti
72*f0687c8aSRaman Tenneti	def keypress(self, size, key):
73*f0687c8aSRaman Tenneti		if key == '+':
74*f0687c8aSRaman Tenneti			self.set_edit_text(str(self.value() + 1))
75*f0687c8aSRaman Tenneti		elif key == '-':
76*f0687c8aSRaman Tenneti			self.set_edit_text(str(self.value() - 1))
77*f0687c8aSRaman Tenneti		else:
78*f0687c8aSRaman Tenneti			return super().keypress(size, key)
79*f0687c8aSRaman Tenneti
80*f0687c8aSRaman Tenneticlass MyIntText(urwid.Text):
81*f0687c8aSRaman Tenneti	def __init__(self, fmt, calc=None):
82*f0687c8aSRaman Tenneti		super().__init__("")
83*f0687c8aSRaman Tenneti		self._fmt = fmt
84*f0687c8aSRaman Tenneti		self._calc = calc
85*f0687c8aSRaman Tenneti
86*f0687c8aSRaman Tenneti	def recalc(self):
87*f0687c8aSRaman Tenneti		val = self._calc()
88*f0687c8aSRaman Tenneti		super().set_text(self._fmt.format(val))
89*f0687c8aSRaman Tenneti
90*f0687c8aSRaman Tennetidef khz_to_ps(khz):
91*f0687c8aSRaman Tenneti	if khz == 0:
92*f0687c8aSRaman Tenneti		return 0
93*f0687c8aSRaman Tenneti	else:
94*f0687c8aSRaman Tenneti		return 1.0 / khz * 1000 * 1000 * 1000
95*f0687c8aSRaman Tenneti
96*f0687c8aSRaman Tennetidef khz_to_us(khz):
97*f0687c8aSRaman Tenneti	if khz == 0:
98*f0687c8aSRaman Tenneti		return 0
99*f0687c8aSRaman Tenneti	else:
100*f0687c8aSRaman Tenneti		return 1.0 / khz * 1000
101*f0687c8aSRaman Tenneti
102*f0687c8aSRaman Tennetipclk_khz_widget = MyIntEdit(u"pclk (kHz) ")
103*f0687c8aSRaman Tennetipclk_ps_widget = MyIntText(fmt="pclk {:.2f} ps", calc = lambda: khz_to_ps(pclk_khz_widget.get_val()))
104*f0687c8aSRaman Tenneti
105*f0687c8aSRaman Tennetipclk_widgets = [pclk_khz_widget, pclk_ps_widget]
106*f0687c8aSRaman Tenneti
107*f0687c8aSRaman Tennetipclk_columns = urwid.LineBox(urwid.Columns(pclk_widgets), title = "Pixel clock")
108*f0687c8aSRaman Tenneti
109*f0687c8aSRaman Tenneti# Horizontal widgets
110*f0687c8aSRaman Tenneti
111*f0687c8aSRaman Tennetihdisp_widget = MyIntEdit(u"hdisp ", calc = lambda: hdisp2_widget.get_val())
112*f0687c8aSRaman Tennetihfp_widget = MyIntEdit(u"hfp   ", calc = lambda: hss_widget.get_val() - hdisp_widget.get_val())
113*f0687c8aSRaman Tennetihsw_widget = MyIntEdit(u"hsw   ", calc = lambda: hse_widget.get_val() - hss_widget.get_val())
114*f0687c8aSRaman Tennetihbp_widget = MyIntEdit(u"hbp   ", calc = lambda: htot_widget.get_val() - hse_widget.get_val())
115*f0687c8aSRaman Tenneti
116*f0687c8aSRaman Tennetihdisp2_widget = MyIntEdit(u"hdisp ", calc = lambda: hdisp_widget.get_val())
117*f0687c8aSRaman Tennetihss_widget = MyIntEdit(u"hss   ",
118*f0687c8aSRaman Tenneti	calc = lambda: hdisp_widget.get_val() + hfp_widget.get_val())
119*f0687c8aSRaman Tennetihse_widget = MyIntEdit(u"hse   ",
120*f0687c8aSRaman Tenneti	calc = lambda: hdisp_widget.get_val() + hfp_widget.get_val() + hsw_widget.get_val())
121*f0687c8aSRaman Tennetihtot_widget = MyIntEdit(u"htot  ",
122*f0687c8aSRaman Tenneti	calc = lambda: hdisp_widget.get_val() + hfp_widget.get_val() + hsw_widget.get_val() + hbp_widget.get_val())
123*f0687c8aSRaman Tenneti
124*f0687c8aSRaman Tennetihwidgets1 = [hdisp_widget, hfp_widget, hsw_widget, hbp_widget]
125*f0687c8aSRaman Tennetihwidgets2 = [hdisp2_widget, hss_widget, hse_widget, htot_widget]
126*f0687c8aSRaman Tenneti
127*f0687c8aSRaman Tennetihoriz_pile1 = urwid.Pile(hwidgets1)
128*f0687c8aSRaman Tennetihoriz_pile2 = urwid.Pile(hwidgets2)
129*f0687c8aSRaman Tenneti
130*f0687c8aSRaman Tennetih_columns = urwid.LineBox(urwid.Columns([(15, horiz_pile1), (15, horiz_pile2)]), title = "Horizontal")
131*f0687c8aSRaman Tenneti
132*f0687c8aSRaman Tenneti# Vertical columns
133*f0687c8aSRaman Tenneti
134*f0687c8aSRaman Tennetivdisp_widget = MyIntEdit(u"vdisp ", calc = lambda: vdisp2_widget.get_val())
135*f0687c8aSRaman Tennetivfp_widget = MyIntEdit(u"vfp   ", calc = lambda: vss_widget.get_val() - vdisp_widget.get_val())
136*f0687c8aSRaman Tennetivsw_widget = MyIntEdit(u"vsw   ", calc = lambda: vse_widget.get_val() - vss_widget.get_val())
137*f0687c8aSRaman Tennetivbp_widget = MyIntEdit(u"vbp   ", calc = lambda: vtot_widget.get_val() - vse_widget.get_val())
138*f0687c8aSRaman Tenneti
139*f0687c8aSRaman Tennetivdisp2_widget = MyIntEdit(u"vdisp ", calc = lambda: vdisp_widget.get_val())
140*f0687c8aSRaman Tennetivss_widget = MyIntEdit(u"vss   ",
141*f0687c8aSRaman Tenneti	calc = lambda: vdisp_widget.get_val() + vfp_widget.get_val())
142*f0687c8aSRaman Tennetivse_widget = MyIntEdit(u"vse   ",
143*f0687c8aSRaman Tenneti	calc = lambda: vdisp_widget.get_val() + vfp_widget.get_val() + vsw_widget.get_val())
144*f0687c8aSRaman Tennetivtot_widget = MyIntEdit(u"vtot  ",
145*f0687c8aSRaman Tenneti	calc = lambda: vdisp_widget.get_val() + vfp_widget.get_val() + vsw_widget.get_val() + vbp_widget.get_val())
146*f0687c8aSRaman Tenneti
147*f0687c8aSRaman Tennetivwidgets1 = [vdisp_widget, vfp_widget, vsw_widget, vbp_widget]
148*f0687c8aSRaman Tennetivwidgets2 = [vdisp2_widget, vss_widget, vse_widget, vtot_widget]
149*f0687c8aSRaman Tenneti
150*f0687c8aSRaman Tennetivert_pile1 = urwid.Pile(vwidgets1)
151*f0687c8aSRaman Tennetivert_pile2 = urwid.Pile(vwidgets2)
152*f0687c8aSRaman Tenneti
153*f0687c8aSRaman Tennetiv_columns = urwid.LineBox(urwid.Columns([(15, vert_pile1), (15, vert_pile2)]), title = "Vertical")
154*f0687c8aSRaman Tenneti
155*f0687c8aSRaman Tenneti# Info widgets
156*f0687c8aSRaman Tenneti
157*f0687c8aSRaman Tennetiline_us_widget = MyIntText(fmt="line {:.2f} us",
158*f0687c8aSRaman Tenneti	calc = lambda: khz_to_us(pclk_khz_widget.get_val()) * htot_widget.get_val())
159*f0687c8aSRaman Tennetiline_khz_widget = MyIntText(fmt="line {:.2f} kHz",
160*f0687c8aSRaman Tenneti	calc = lambda: div_or_zero(pclk_khz_widget.get_val(), htot_widget.get_val()))
161*f0687c8aSRaman Tenneti
162*f0687c8aSRaman Tennetiframe_tot_widget = MyIntText(fmt="tot {} pix",
163*f0687c8aSRaman Tenneti	calc = lambda: htot_widget.get_val() * vtot_widget.get_val())
164*f0687c8aSRaman Tennetiframe_us_widget = MyIntText(fmt="frame {:.2f} ms",
165*f0687c8aSRaman Tenneti	calc = lambda: khz_to_us(pclk_khz_widget.get_val()) * htot_widget.get_val() * vtot_widget.get_val() / 1000)
166*f0687c8aSRaman Tennetiframe_khz_widget = MyIntText(fmt="frame {:.2f} Hz",
167*f0687c8aSRaman Tenneti	calc = lambda: div_or_zero(pclk_khz_widget.get_val() * 1000,  htot_widget.get_val() * vtot_widget.get_val()))
168*f0687c8aSRaman Tenneti
169*f0687c8aSRaman Tennetiinfo_box = urwid.LineBox(urwid.Pile([line_us_widget, line_khz_widget, urwid.Divider(), frame_tot_widget, frame_us_widget, frame_khz_widget]), title = "Info")
170*f0687c8aSRaman Tenneti
171*f0687c8aSRaman Tenneti# Set update lists
172*f0687c8aSRaman Tenneti
173*f0687c8aSRaman Tennetirecalc_list = [ pclk_ps_widget, line_us_widget, line_khz_widget, frame_tot_widget, frame_us_widget, frame_khz_widget ]
174*f0687c8aSRaman Tenneti
175*f0687c8aSRaman Tennetihdisp_widget.set_updlist([hdisp2_widget, hss_widget, hse_widget, htot_widget])
176*f0687c8aSRaman Tennetihfp_widget.set_updlist([hss_widget, hse_widget, htot_widget])
177*f0687c8aSRaman Tennetihsw_widget.set_updlist([hse_widget, htot_widget])
178*f0687c8aSRaman Tennetihbp_widget.set_updlist([htot_widget])
179*f0687c8aSRaman Tennetihdisp2_widget.set_updlist([hdisp_widget, hfp_widget])
180*f0687c8aSRaman Tennetihss_widget.set_updlist([hfp_widget, hsw_widget])
181*f0687c8aSRaman Tennetihse_widget.set_updlist([hsw_widget, hbp_widget])
182*f0687c8aSRaman Tennetihtot_widget.set_updlist([hbp_widget])
183*f0687c8aSRaman Tenneti
184*f0687c8aSRaman Tennetivdisp_widget.set_updlist([vdisp2_widget, vss_widget, vse_widget, vtot_widget])
185*f0687c8aSRaman Tennetivfp_widget.set_updlist([vss_widget, vse_widget, vtot_widget])
186*f0687c8aSRaman Tennetivsw_widget.set_updlist([vse_widget, vtot_widget])
187*f0687c8aSRaman Tennetivbp_widget.set_updlist([vtot_widget])
188*f0687c8aSRaman Tennetivdisp2_widget.set_updlist([vdisp_widget, vfp_widget])
189*f0687c8aSRaman Tennetivss_widget.set_updlist([vfp_widget, vsw_widget])
190*f0687c8aSRaman Tennetivse_widget.set_updlist([vsw_widget, vbp_widget])
191*f0687c8aSRaman Tennetivtot_widget.set_updlist([vbp_widget])
192*f0687c8aSRaman Tenneti
193*f0687c8aSRaman Tenneti# Flags
194*f0687c8aSRaman Tenneti
195*f0687c8aSRaman Tennetifb = None
196*f0687c8aSRaman Tenneti
197*f0687c8aSRaman TennetiDRM_MODE_FLAG_PHSYNC = (1<<0)
198*f0687c8aSRaman TennetiDRM_MODE_FLAG_NHSYNC = (1<<1)
199*f0687c8aSRaman TennetiDRM_MODE_FLAG_PVSYNC = (1<<2)
200*f0687c8aSRaman TennetiDRM_MODE_FLAG_NVSYNC = (1<<3)
201*f0687c8aSRaman TennetiDRM_MODE_FLAG_INTERLACE = (1<<4)
202*f0687c8aSRaman TennetiDRM_MODE_FLAG_DBLCLK = (1<<12)
203*f0687c8aSRaman Tenneti
204*f0687c8aSRaman Tennetidef mode_is_ilace(mode):
205*f0687c8aSRaman Tenneti	return (mode.flags & DRM_MODE_FLAG_INTERLACE) != 0
206*f0687c8aSRaman Tenneti
207*f0687c8aSRaman Tennetidef apply_mode():
208*f0687c8aSRaman Tenneti	global fb
209*f0687c8aSRaman Tenneti
210*f0687c8aSRaman Tenneti	mode = pykms.Videomode()
211*f0687c8aSRaman Tenneti	mode.clock = pclk_khz_widget.get_val()
212*f0687c8aSRaman Tenneti
213*f0687c8aSRaman Tenneti	mode.hdisplay = hdisp2_widget.get_val()
214*f0687c8aSRaman Tenneti	mode.hsync_start = hss_widget.get_val()
215*f0687c8aSRaman Tenneti	mode.hsync_end = hse_widget.get_val()
216*f0687c8aSRaman Tenneti	mode.htotal = htot_widget.get_val()
217*f0687c8aSRaman Tenneti
218*f0687c8aSRaman Tenneti	mode.vdisplay = vdisp2_widget.get_val()
219*f0687c8aSRaman Tenneti	mode.vsync_start = vss_widget.get_val()
220*f0687c8aSRaman Tenneti	mode.vsync_end = vse_widget.get_val()
221*f0687c8aSRaman Tenneti	mode.vtotal = vtot_widget.get_val()
222*f0687c8aSRaman Tenneti
223*f0687c8aSRaman Tenneti	if ilace_box.state:
224*f0687c8aSRaman Tenneti		mode.flags |= DRM_MODE_FLAG_INTERLACE
225*f0687c8aSRaman Tenneti
226*f0687c8aSRaman Tenneti	if dblclk_box.state:
227*f0687c8aSRaman Tenneti		mode.flags |= DRM_MODE_FLAG_DBLCLK
228*f0687c8aSRaman Tenneti
229*f0687c8aSRaman Tenneti	if hsync_pol.state == True:
230*f0687c8aSRaman Tenneti		mode.flags |= DRM_MODE_FLAG_PHSYNC
231*f0687c8aSRaman Tenneti	elif hsync_pol.state == False:
232*f0687c8aSRaman Tenneti		mode.flags |= DRM_MODE_FLAG_NHSYNC
233*f0687c8aSRaman Tenneti
234*f0687c8aSRaman Tenneti	if vsync_pol.state == True:
235*f0687c8aSRaman Tenneti		mode.flags |= DRM_MODE_FLAG_PVSYNC
236*f0687c8aSRaman Tenneti	elif vsync_pol.state == False:
237*f0687c8aSRaman Tenneti		mode.flags |= DRM_MODE_FLAG_NVSYNC
238*f0687c8aSRaman Tenneti
239*f0687c8aSRaman Tenneti	fb = pykms.DumbFramebuffer(card, mode.hdisplay, mode.vdisplay, "XR24");
240*f0687c8aSRaman Tenneti	pykms.draw_test_pattern(fb);
241*f0687c8aSRaman Tenneti
242*f0687c8aSRaman Tenneti	crtc.set_mode(conn, fb, mode)
243*f0687c8aSRaman Tenneti
244*f0687c8aSRaman Tennetidef read_mode(mode):
245*f0687c8aSRaman Tenneti	pclk_khz_widget.set_val(mode.clock)
246*f0687c8aSRaman Tenneti	hdisp2_widget.set_val(mode.hdisplay)
247*f0687c8aSRaman Tenneti	hss_widget.set_val(mode.hsync_start)
248*f0687c8aSRaman Tenneti	hse_widget.set_val(mode.hsync_end)
249*f0687c8aSRaman Tenneti	htot_widget.set_val(mode.htotal)
250*f0687c8aSRaman Tenneti
251*f0687c8aSRaman Tenneti	vdisp2_widget.set_val(mode.vdisplay)
252*f0687c8aSRaman Tenneti	vss_widget.set_val(mode.vsync_start)
253*f0687c8aSRaman Tenneti	vse_widget.set_val(mode.vsync_end)
254*f0687c8aSRaman Tenneti	vtot_widget.set_val(mode.vtotal)
255*f0687c8aSRaman Tenneti
256*f0687c8aSRaman Tenneti	ilace_box.set_state(mode_is_ilace(mode))
257*f0687c8aSRaman Tenneti	dblclk_box.set_state((mode.flags & DRM_MODE_FLAG_DBLCLK) != 0)
258*f0687c8aSRaman Tenneti
259*f0687c8aSRaman Tenneti	sync = 'mixed'
260*f0687c8aSRaman Tenneti	if (mode.flags & DRM_MODE_FLAG_PHSYNC) != 0:
261*f0687c8aSRaman Tenneti		sync = True
262*f0687c8aSRaman Tenneti	elif (mode.flags & DRM_MODE_FLAG_NHSYNC) != 0:
263*f0687c8aSRaman Tenneti		sync = False
264*f0687c8aSRaman Tenneti	hsync_pol.set_state(sync)
265*f0687c8aSRaman Tenneti
266*f0687c8aSRaman Tenneti	sync = 'mixed'
267*f0687c8aSRaman Tenneti	if (mode.flags & DRM_MODE_FLAG_PVSYNC) != 0:
268*f0687c8aSRaman Tenneti		sync = True
269*f0687c8aSRaman Tenneti	elif (mode.flags & DRM_MODE_FLAG_NVSYNC) != 0:
270*f0687c8aSRaman Tenneti		sync = False
271*f0687c8aSRaman Tenneti	vsync_pol.set_state(sync)
272*f0687c8aSRaman Tenneti
273*f0687c8aSRaman Tennetidef apply_press(w):
274*f0687c8aSRaman Tenneti	apply_mode()
275*f0687c8aSRaman Tenneti
276*f0687c8aSRaman Tennetiilace_box = urwid.CheckBox('interlace')
277*f0687c8aSRaman Tennetihsync_pol = urwid.CheckBox('hsync positive', has_mixed=True)
278*f0687c8aSRaman Tennetivsync_pol = urwid.CheckBox('vsync positive', has_mixed=True)
279*f0687c8aSRaman Tennetidblclk_box = urwid.CheckBox('double clock')
280*f0687c8aSRaman Tenneti
281*f0687c8aSRaman Tennetiflags_pile = urwid.LineBox(urwid.Pile([ilace_box, hsync_pol, vsync_pol, dblclk_box]), title = "Flags")
282*f0687c8aSRaman Tenneti
283*f0687c8aSRaman Tennetiapply_button = urwid.LineBox(urwid.Padding(urwid.Button('apply', on_press=apply_press)))
284*f0687c8aSRaman Tenneti
285*f0687c8aSRaman Tenneti# Main
286*f0687c8aSRaman Tenneti
287*f0687c8aSRaman Tennetidef mode_press(w, mode):
288*f0687c8aSRaman Tenneti	read_mode(mode)
289*f0687c8aSRaman Tenneti
290*f0687c8aSRaman Tennetidef mode_to_str(mode):
291*f0687c8aSRaman Tenneti	return "{}@{}{}".format(mode.name, mode.vrefresh, "i" if mode_is_ilace(mode) else "")
292*f0687c8aSRaman Tenneti
293*f0687c8aSRaman Tennetimode_buttons = []
294*f0687c8aSRaman Tenneti
295*f0687c8aSRaman Tenneticard = pykms.Card()
296*f0687c8aSRaman Tenneti
297*f0687c8aSRaman Tennetires = pykms.ResourceManager(card)
298*f0687c8aSRaman Tenneticonn = res.reserve_connector()
299*f0687c8aSRaman Tenneticrtc = res.reserve_crtc(conn)
300*f0687c8aSRaman Tennetiplane = res.reserve_generic_plane(crtc)
301*f0687c8aSRaman Tennetimodes = conn.get_modes()
302*f0687c8aSRaman Tennetii = 0
303*f0687c8aSRaman Tennetifor m in modes:
304*f0687c8aSRaman Tenneti	mode_buttons.append(urwid.Button(mode_to_str(m), on_press=mode_press, user_data=m))
305*f0687c8aSRaman Tenneti	i += 1
306*f0687c8aSRaman Tenneti
307*f0687c8aSRaman Tennetimodes_pile = urwid.LineBox(urwid.Pile(mode_buttons), title = "Video modes")
308*f0687c8aSRaman Tenneti
309*f0687c8aSRaman Tennetimain_pile = urwid.Pile([modes_pile, pclk_columns, urwid.Columns([ h_columns, v_columns ]), info_box, flags_pile, apply_button])
310*f0687c8aSRaman Tenneti
311*f0687c8aSRaman Tennetimain_columns = urwid.Filler(main_pile, valign='top')
312*f0687c8aSRaman Tenneti
313*f0687c8aSRaman Tennetiloop = urwid.MainLoop(main_columns, unhandled_input=exit_on_q, handle_mouse=False)
314*f0687c8aSRaman Tenneti
315*f0687c8aSRaman Tenneti# select the first mode
316*f0687c8aSRaman Tennetimode_press(None, modes[0])
317*f0687c8aSRaman Tenneti
318*f0687c8aSRaman Tennetiloop.run()
319*f0687c8aSRaman Tenneti
320*f0687c8aSRaman Tennetifb = None
321