def imcur(displayname=None): """Read image cursor and return string expected for IRAF's imcur parameter If key pressed is colon, also prompts for additional string input. Raises EOFError if ^D or ^Z is typed and IrafError on other errors. The optional display argument specifies the name of the display to use (default is the display specified in stdimage). """ try: # give kernel a chance to do anything it needs right before imcur gkrnl = gwm.getActiveGraphicsWindow() if gkrnl: gkrnl.pre_imcur() # get device device = _getDevice(displayname) # Read cursor position at keystroke result = device.readCursor() if Verbose>1: sys.__stdout__.write("%s\n" % (result,)) sys.__stdout__.flush() if result == 'EOF': raise EOFError x, y, wcs, key = result.split() if key in [r'\004', r'\032']: # ctrl-D and ctrl-Z are treated as EOF # Should ctrl-C raise a KeyboardInterrupt? raise EOFError elif key == ':': sys.stdout.write(": ") sys.stdout.flush() result = result + ' ' + irafutils.tkreadline()[:-1] return result except IOError, error: raise IrafError(str(error))
def imcur(displayname=None): """Read image cursor and return string expected for IRAF's imcur parameter If key pressed is colon, also prompts for additional string input. Raises EOFError if ^D or ^Z is typed and IrafError on other errors. The optional display argument specifies the name of the display to use (default is the display specified in stdimage). """ try: # give kernel a chance to do anything it needs right before imcur gkrnl = gwm.getActiveGraphicsWindow() if gkrnl: gkrnl.pre_imcur() # get device device = _getDevice(displayname) # Read cursor position at keystroke result = device.readCursor() if Verbose > 1: sys.__stdout__.write(f"{result}\n") sys.__stdout__.flush() if result == 'EOF': raise EOFError() x, y, wcs, key = result.split() if key in [r'\004', r'\032']: # ctrl-D and ctrl-Z are treated as EOF # Should ctrl-C raise a KeyboardInterrupt? raise EOFError() elif key == ':': sys.stdout.write(": ") sys.stdout.flush() result = result + ' ' + irafutils.tkreadline()[:-1] return result except OSError as error: raise IrafError(str(error))
def readString(self, prompt=""): """Prompt and read a string""" self.writeString(prompt) stdin = self.window.getStdin(default=sys.stdin) return irafutils.tkreadline(stdin)[:-1]
def xfer(self): """Handle xfer data requests""" chan, nbytes = self.chanbytes() nchars = nbytes//2 if chan == 3: # Read data from stdin unless xferline already has # some untransmitted data from a previous read line = self.xferline if not line: if self.stdinIsatty: if not self.stdinIsraw: self.setStdio() # tty input, read a single line line = irafutils.tkreadline(self.stdin) else: # Raw input requested # Input character needs to be converted # to its ASCII integer code. #line = raw_input() line = irafukey.getSingleTTYChar() else: # file input, read a big chunk of data # NOTE: Here we are reading ahead in the stdin stream, # which works fine with a single IRAF task. This approach # could conceivably cause problems if some program expects # to continue reading from this stream starting at the # first line not read by the IRAF task. That sounds # very unlikely to be a good design and will not work # as a result of this approach. Sending the data in # large chunks is *much* faster than sending many # small messages (due to the overhead of handshaking # between the CL task and this main process.) That's # why it is done this way. line = self.stdin.read(nchars) self.xferline = line # Send two messages, the first with the number of characters # in the line and the second with the line itself. # For very long lines, may need multiple messages. Task # will keep sending xfer requests until it gets the # newline. if not self.stdinIsraw: if len(line)<=nchars: # short line self.writeString(str(len(line))) self.writeString(line) self.xferline = '' else: # long line self.writeString(str(nchars)) self.writeString(line[:nchars]) self.xferline = line[nchars:] else: self.writeString(str(len(line))) self.writeString(line) self.xferline = '' else: raise IrafProcessError("xfer request for unknown channel %d" % chan)
def xfer(self): """Handle xfer data requests""" chan, nbytes = self.chanbytes() nchars = nbytes // 2 if chan == 3: # Read data from stdin unless xferline already has # some untransmitted data from a previous read line = self.xferline if not line: if self.stdinIsatty: if not self.stdinIsraw: self.setStdio() # tty input, read a single line line = irafutils.tkreadline(self.stdin) else: # Raw input requested # Input character needs to be converted # to its ASCII integer code. # line = raw_input() line = irafukey.getSingleTTYChar() else: # file input, read a big chunk of data # NOTE: Here we are reading ahead in the stdin stream, # which works fine with a single IRAF task. This approach # could conceivably cause problems if some program expects # to continue reading from this stream starting at the # first line not read by the IRAF task. That sounds # very unlikely to be a good design and will not work # as a result of this approach. Sending the data in # large chunks is *much* faster than sending many # small messages (due to the overhead of handshaking # between the CL task and this main process.) That's # why it is done this way. line = self.stdin.read(nchars) self.xferline = line # Send two messages, the first with the number of characters # in the line and the second with the line itself. # For very long lines, may need multiple messages. Task # will keep sending xfer requests until it gets the # newline. if not self.stdinIsraw: if len(line) <= nchars: # short line self.writeString(str(len(line))) self.writeString(line) self.xferline = '' else: # long line self.writeString(str(nchars)) self.writeString(line[:nchars]) self.xferline = line[nchars:] else: self.writeString(str(len(line))) self.writeString(line) self.xferline = '' else: raise IrafProcessError(f"xfer request for unknown channel {chan:d}")