Coverage for pyilper/pilterminal.py: 100%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/python3
2# -*- coding: utf-8 -*-
3# pyILPER 1.2.1 for Linux
4#
5# An emulator for virtual HP-IL devices for the PIL-Box
6# derived from ILPER 1.4.5 for Windows
7# Copyright (c) 2008-2013 Jean-Francois Garnier
8# C++ version (c) 2013 Christoph Gießelink
9# Python Version (c) 2015 Joachim Siebold
10#
11# This program is free software; you can redistribute it and/or
12# modify it under the terms of the GNU General Public License
13# as published by the Free Software Foundation; either version 2
14# of the License, or (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25import queue
26import threading
27import array
28from .pilconfig import PILCONFIG
29from .pilwidgets import cls_tabtermgeneric, T_STRING
30from .pilkeymap import KEYBOARD_TYPE_HP71, keyboardtypes
31from .pildevbase import cls_pildevbase
32from .pilcharconv import CHARSET_HP71, charsets
33#
34# Terminal tab object classes ----------------------------------------------
35#
36# Changelog
37#
38# 03.09.2017 jsi
39# - register pildevice is now method of commobject
40# 14.09.2017 jsi
41# - refactoring, keyboard input is disabled if device not active
42# 17.11.2017 jsi
43# - moved reconfigure method to cls_tabtermgeneric
44# 16.01.2018 jsi
45# - adapted to cls_tabtermgeneric, implemented cascading config menu
46# 28.01.2018 jsi
47# - fixed charset configuration
48# 14.02.2019 jsi
49# - added keyboard type configuration
50# 16.02.2019 jsi
51# - put int not char on termqueue
53class cls_tabterminal(cls_tabtermgeneric):
55 def __init__(self,parent,name):
56 super().__init__(parent,name)
57#
58# init local configuration parameters
59#
60 self.charset=PILCONFIG.get(self.name,"charset",CHARSET_HP71)
61 self.keyboardtype=PILCONFIG.get(self.name,"keyboardtype",KEYBOARD_TYPE_HP71)
62#
63# add terminal config options to cascading menu
64#
65 self.cBut.add_option("Character set","charset",T_STRING,charsets)
66 self.cBut.add_option("Keyboard type","keyboardtype",T_STRING,keyboardtypes)
67#
68# create HP-IL device and let the GUI object know it
69#
70 self.pildevice= cls_pilterminal(self.guiobject)
71 self.guiobject.set_pildevice(self.pildevice)
72 self.guiobject.set_charset(self.charset)
73 self.guiobject.set_keyboardtype(self.keyboardtype)
74 self.cBut.config_changed_signal.connect(self.do_tabconfig_changed)
75#
76# handle changes of the character set
77#
78 def do_tabconfig_changed(self):
79 param= self.cBut.get_changed_option_name()
80#
81# change local config parameters
82#
83 if param=="charset":
84 self.charset= PILCONFIG.get(self.name,"charset")
85 self.guiobject.set_charset(self.charset)
87 if param=="keyboardtype":
88 self.keyboardtype= PILCONFIG.get(self.name,"keyboardtype")
89 self.guiobject.set_keyboardtype(self.keyboardtype)
91 super().do_tabconfig_changed()
92#
93# enable/disable
94#
95 def enable(self):
96 super().enable()
97 self.parent.commthread.register(self.pildevice,self.name)
98 self.pildevice.setactive(PILCONFIG.get(self.name,"active"))
99 self.guiobject.enable_keyboard()
101 def disable(self):
102 super().disable()
103 self.guiobject.disable_keyboard()
104#
105# enable keyboard only if terminal active
106#
107 def toggle_active(self):
108 if self.active:
109 self.guiobject.enable_keyboard()
110 else:
111 self.guiobject.disable_keyboard()
112#
113# HP-IL virtual terminal object class ---------------------------------------
114#
115# Initial release derived from ILPER 1.43 for Windows
116#
117# Changelog
118#
119# 09.02.2015: Improvements and fixes from ILPER 1.50
120# - fixed __fterminal__ handling in do_cmd LAD/SAD
121# - not implemented: auto extended address support switch
122# - not implemeted: set/get AID, ID$
123#
124# 30.05.2015 jsi:
125# - fixed error in handling AP, added getstatus
126# 06.10.2015 jsi:
127# - class statement syntax updates
128# 14.11.2015 jsi:
129# - idy frame srq bit handling
130# 21.11.2015 jsi:
131# - removed SSRQ/CSRQ approach
132# - set SRQ flag if keyboard buffer is not empty
133# 28.11.2015 jsi:
134# - removed delay in __outdta__
135# 29.11.2015 jsi:
136# - introduced device lock
137# 29.01.2016 cg:
138# - fixed Python syntax error in SST frame handler
139# 01.02.2016 jsi:
140# - corrected check SDA/SDI/SST? against 0x02 in do_doe
141# - improved internal documentation
142# 07.02.2016 jsi:
143# - refactored to use new pildevbase class
144# 08.02.2016 jsi:
145# - removed kbdqueue lock, used status_lock instead, rearranged locked code in
146# queueOutput and __outdata__
147# - reset keyboard queue if device clear
148# - rearrange code in __outdata__, keyboard data avialable flag is cleared after
149# the last byte in the buffer was sent.
150# 20.02.2016 jsi:
151# - queueOutput now handles complete escape sequences
152# - ATTN is ignored if the keyboard queue is not empty
153# 06.03.2016 jsi:
154# - use no blocking queue get
155# 09.08.2017 jsi:
156# - register_callback_output and register_callback_clear implemented (from base
157# class
158# 14.09.2017 jsi:
159# - refactoring
160# 27.09.2017 jsi
161# - code to output data to HP-IL rewritten
162#
163class cls_pilterminal(cls_pildevbase):
165 def __init__(self,guiobject):
166 super().__init__()
168 self.__aid__ = 0x3E # accessory id = general interface
169 self.__defaddr__ = 8 # default address alter AAU
170 self.__did__ = "PILTERM" # device id
171 self.__guiobject__= guiobject # terminal gui object
172#
173# initialize HP-IL outdata buffer
174#
175 self.__outbuf__= array.array('i')
176 self.__oc__=0
178#
179# public --------
180#
181# put character or escape sequence to HP-IL outdata queue, called by terminal frontend
182#
183 def putDataToHPIL(self,c):
184 self.__status_lock__.acquire()
185 self.__outbuf__.insert(0, c)
186 self.__oc__+=1
187 self.__status__ = self.__status__ | 0x50 # set ready for data and srq bit
188 self.__status_lock__.release()
189#
190# private (overloaded) --------
191#
192# forward data coming from HP-IL to the terminal frontend widget
193#
194 def __indata__(self,frame):
195 self.__access_lock__.acquire()
196 locked= self.__islocked__
197 self.__access_lock__.release()
198 if not locked:
199 self.__guiobject__.out_terminal(frame & 0xFF)
200#
201# clear device: empty HP-IL outdata buffer and reset terminal
202#
203 def __clear_device__(self):
204 super().__clear_device__() # this clears srq
205 self.__status_lock__.acquire()
206 self.__oc__=0
207 self.__outbuf__= array.array('i')
208 self.__status__= self.__status__ & 0xEF # clear ready for data
209 self.__status_lock__.release()
211#
212# reset device
213#
214 self.__guiobject__.reset_terminal()
215 return
216#
217# send data from HP-IL outdata buffer to the loop
218#
219 def __outdata__(self,frame):
220 self.__status_lock__.acquire()
221 self.__status__= self.__status__ & 0xBF # clear srq bit
222 if self.__oc__== 0:
223 frame= 0x540 # EOT
224 else:
225 frame= self.__outbuf__.pop()
226 self.__oc__-=1
227 if self.__oc__== 0:
228 self.__status__= self.__status__ & 0xEF # clear ready for data bit
229 self.__status_lock__.release()
230 return(frame)