86 self.colors = {} # maps names to curses attributes |
87 self.colors = {} # maps names to curses attributes |
87 self.colorpairs = {} # maps tuple (fg,bg) to curses color_pair |
88 self.colorpairs = {} # maps tuple (fg,bg) to curses color_pair |
88 self.colorstack = [] # pushcolor/popcolor puts or gets attributes from this |
89 self.colorstack = [] # pushcolor/popcolor puts or gets attributes from this |
89 self.inputqueue = [] |
90 self.inputqueue = [] |
90 self.mbtnstack = [] |
91 self.mbtnstack = [] |
91 self._mouse_last_pos = (None, None) |
92 self._mouse_last_pos = None # Point |
92 self._mouse_last_bstate = None |
93 self._mouse_last_bstate = None |
93 |
94 |
94 ## initialization, finalization ## |
95 ## initialization, finalization ## |
95 |
96 |
96 def init(self): |
97 def init(self): |
278 try: |
279 try: |
279 _id, x, y, _z, bstate = curses.getmouse() |
280 _id, x, y, _z, bstate = curses.getmouse() |
280 except curses.error: |
281 except curses.error: |
281 return [] |
282 return [] |
282 |
283 |
|
284 pos = Point(x, y) |
283 out = [] |
285 out = [] |
284 |
286 |
285 if bstate & curses.REPORT_MOUSE_POSITION: |
287 if bstate & curses.REPORT_MOUSE_POSITION: |
286 if self._mouse_last_pos != (x, y): |
288 if self._mouse_last_pos != pos: |
287 if self._mouse_last_pos[0] is not None: |
289 if self._mouse_last_pos: |
288 relx = x - (self._mouse_last_pos[0] or 0) |
290 relpos = pos - self._mouse_last_pos |
289 rely = y - (self._mouse_last_pos[1] or 0) |
291 out += [('mousemove', 0, pos, relpos)] |
290 out += [('mousemove', 0, x, y, relx, rely)] |
292 self._mouse_last_pos = pos |
291 self._mouse_last_pos = (x, y) |
|
292 |
293 |
293 # we are interested only in changes, not buttons already pressed before event |
294 # we are interested only in changes, not buttons already pressed before event |
294 if self._mouse_last_bstate is not None: |
295 if self._mouse_last_bstate is not None: |
295 old = self._mouse_last_bstate |
296 old = self._mouse_last_bstate |
296 new = bstate |
297 new = bstate |
298 self._mouse_last_bstate = new |
299 self._mouse_last_bstate = new |
299 else: |
300 else: |
300 self._mouse_last_bstate = bstate |
301 self._mouse_last_bstate = bstate |
301 |
302 |
302 if bstate & curses.BUTTON1_PRESSED: |
303 if bstate & curses.BUTTON1_PRESSED: |
303 out += [('mousedown', 1, x, y)] |
304 out += [('mousedown', 1, pos)] |
304 if bstate & curses.BUTTON2_PRESSED: |
305 if bstate & curses.BUTTON2_PRESSED: |
305 out += [('mousedown', 2, x, y)] |
306 out += [('mousedown', 2, pos)] |
306 if bstate & curses.BUTTON3_PRESSED: |
307 if bstate & curses.BUTTON3_PRESSED: |
307 out += [('mousedown', 3, x, y)] |
308 out += [('mousedown', 3, pos)] |
308 if bstate & curses.BUTTON1_RELEASED: |
309 if bstate & curses.BUTTON1_RELEASED: |
309 out += [('mouseup', 1, x, y)] |
310 out += [('mouseup', 1, pos)] |
310 if bstate & curses.BUTTON2_RELEASED: |
311 if bstate & curses.BUTTON2_RELEASED: |
311 out += [('mouseup', 2, x, y)] |
312 out += [('mouseup', 2, pos)] |
312 if bstate & curses.BUTTON3_RELEASED: |
313 if bstate & curses.BUTTON3_RELEASED: |
313 out += [('mouseup', 3, x, y)] |
314 out += [('mouseup', 3, pos)] |
314 |
315 |
315 # reset last pos when pressed/released |
316 # reset last pos when pressed/released |
316 if len(out) > 0 and out[-1][0] in ('mousedown', 'mouseup'): |
317 if len(out) > 0 and out[-1][0] in ('mousedown', 'mouseup'): |
317 self._mouse_last_pos = (None, None) |
318 self._mouse_last_pos = None |
318 |
319 |
319 return out |
320 return out |
320 |
321 |
321 def _process_utf8_chars(self): |
322 def _process_utf8_chars(self): |
322 #FIXME read exact number of chars as defined by utf-8 |
323 #FIXME read exact number of chars as defined by utf-8 |
393 |
394 |
394 def _process_xterm_mouse(self): |
395 def _process_xterm_mouse(self): |
395 t = self._inputqueue_get_wait() |
396 t = self._inputqueue_get_wait() |
396 x = self._inputqueue_get_wait() - 0x21 |
397 x = self._inputqueue_get_wait() - 0x21 |
397 y = self._inputqueue_get_wait() - 0x21 |
398 y = self._inputqueue_get_wait() - 0x21 |
|
399 pos = Point(x, y) |
398 |
400 |
399 out = [] |
401 out = [] |
400 |
402 |
401 if t in (0x20, 0x21, 0x22): |
403 if t in (0x20, 0x21, 0x22): |
402 # button press |
404 # button press |
403 btn = t - 0x1f |
405 btn = t - 0x1f |
404 if not btn in self.mbtnstack: |
406 if not btn in self.mbtnstack: |
405 self.mbtnstack.append(btn) |
407 self.mbtnstack.append(btn) |
406 self._mouse_last_pos = (None, None) |
408 self._mouse_last_pos = None |
407 out += [('mousedown', btn, x, y)] |
409 out += [('mousedown', btn, pos)] |
408 else: |
410 else: |
409 # mouse move |
411 # mouse move |
410 if self._mouse_last_pos != (x, y): |
412 if self._mouse_last_pos != pos: |
411 if self._mouse_last_pos[0] is not None: |
413 if self._mouse_last_pos: |
412 relx = x - self._mouse_last_pos[0] |
414 relpos = pos - self._mouse_last_pos |
413 rely = y - self._mouse_last_pos[1] |
415 out += [('mousemove', btn, pos, relpos)] |
414 out += [('mousemove', btn, x, y, relx, rely)] |
416 self._mouse_last_pos = pos |
415 self._mouse_last_pos = (x, y) |
|
416 elif t == 0x23: |
417 elif t == 0x23: |
417 # button release |
418 # button release |
418 btn = self.mbtnstack.pop() |
419 btn = self.mbtnstack.pop() |
419 self._mouse_last_pos = (None, None) |
420 self._mouse_last_pos = (None, None) |
420 out += [('mouseup', btn, x, y)] |
421 out += [('mouseup', btn, pos)] |
421 elif t in (0x60, 0x61): |
422 elif t in (0x60, 0x61): |
422 # wheel up, down |
423 # wheel up, down |
423 btn = 4 + t - 0x60 |
424 btn = 4 + t - 0x60 |
424 out += [('mousewheel', btn, x, y)] |
425 out += [('mousewheel', btn, pos)] |
425 else: |
426 else: |
426 raise Exception('Unknown mouse event: %x' % t) |
427 raise Exception('Unknown mouse event: %x' % t) |
427 |
428 |
428 return out |
429 return out |
429 |
430 |