keypress event keyval traduction table
this hash is used to determine the colors of the Gui elements (background, caret, …) modifications to it are only useful before the widget is first rendered (IE before Metasm::Gui.main)
# File metasm/gui/gtk.rb, line 201 def initialize(*a, &b) @parent_widget = nil @caret_x = @caret_y = 0 # text cursor position @oldcaret_x = @oldcaret_y = 1 @hl_word = nil @layout = Pango::Layout.new Gdk::Pango.context # text rendering @color = {} @default_color_association = {:background => :palegrey} super() # events callbacks signal_connect('expose_event') { @w = window ; @gc = Gdk::GC.new(@w) protect { paint } @w = @gc = nil true } signal_connect('size_allocate') { |w, alloc| protect { resized(alloc.width, alloc.height) } } signal_connect('button_press_event') { |w, ev| @last_kb_ev = ev if keyboard_state(:control) next protect { click_ctrl(ev.x, ev.y) } if ev.event_type == Gdk::Event::Type::BUTTON_PRESS and ev.button == 1 and respond_to? :click_ctrl next end case ev.event_type when Gdk::Event::Type::BUTTON_PRESS grab_focus case ev.button when 1; protect { click(ev.x, ev.y) } if respond_to? :click end when Gdk::Event::Type::BUTTON2_PRESS case ev.button when 1; protect { doubleclick(ev.x, ev.y) } if respond_to? :doubleclick end end } signal_connect('motion_notify_event') { |w, ev| @last_kb_ev = ev if keyboard_state(:control) protect { mousemove_ctrl(ev.x, ev.y) } if respond_to? :mousemove_ctrl else protect { mousemove(ev.x, ev.y) } end } if respond_to? :mousemove signal_connect('button_release_event') { |w, ev| case ev.button when 1; protect { mouserelease(ev.x, ev.y) } if respond_to? :mouserelease when 3; protect { rightclick(ev.x, ev.y) } if respond_to? :rightclick end } signal_connect('scroll_event') { |w, ev| dir = case ev.direction when Gdk::EventScroll::Direction::UP; :up when Gdk::EventScroll::Direction::DOWN; :down else next end @last_kb_ev = ev if keyboard_state(:control) protect { mouse_wheel_ctrl(dir, ev.x, ev.y) } if respond_to? :mouse_wheel_ctrl else protect { mouse_wheel(dir, ev.x, ev.y) } end } if respond_to? :mouse_wheel signal_connect('key_press_event') { |w, ev| @last_kb_ev = ev key = Keyboard_trad[ev.keyval] if keyboard_state(:control) protect { keypress_ctrl(key) or (@parent_widget and @parent_widget.keypress_ctrl(key)) } else protect { keypress(key) or (@parent_widget and @parent_widget.keypress(key)) } end } signal_connect('realize') { BasicColor.each { |tag, val| @color[tag] = color(val) } set_color_association @default_color_association initialize_visible if respond_to? :initialize_visible } initialize_widget(*a, &b) # receive keyboard/mouse signals set_events Gdk::Event::ALL_EVENTS_MASK set_can_focus true set_font 'courier 10' end
# File metasm/gui/gtk.rb, line 508 def clipboard_copy(buf) clipboard = Gtk::Clipboard.get(Gdk::Selection::PRIMARY) clipboard.text = buf end
# File metasm/gui/gtk.rb, line 513 def clipboard_paste clipboard = Gtk::Clipboard.get(Gdk::Selection::PRIMARY) clipboard.wait_for_text end
create a color from a 'rgb' description
# File metasm/gui/gtk.rb, line 309 def color(val) if not @color[val] v = case val.length when 3; val.scan(/./).map { |c| (c*4).to_i(16) } when 6; val.scan(/../).map { |c| (c+c).to_i(16) } end @color[val] = Gdk::Color.new(*v) window.colormap.alloc_color(@color[val], true, true) end @color[val] end
# File metasm/gui/gtk.rb, line 421 def draw_color(col) @gc.set_foreground color(col) end
# File metasm/gui/gtk.rb, line 448 def draw_line(x, y, ex, ey) if x.abs > 0x7000 return if ex.abs > 0x7000 and ((ex < 0) == (x < 0)) ox = x x = ((x > 0) ? 0x7000 : -0x7000) y = ey+(x-ex)*(y-ey)/(ox-ex) end if ex.abs > 0x7000 oex = ex ex = ((ex > 0) ? 0x7000 : -0x7000) ey = y+(ex-x)*(ey-y)/(oex-x) end if y.abs > 0x7000 return if ey.abs > 0x7000 and ((ey < 0) == (y < 0)) oy = y y = ((y > 0) ? 0x7000 : -0x7000) x = ex+(y-ey)*(x-ex)/(oy-ey) end if ey.abs > 0x7000 oey = ey ey = ((ey > 0) ? 0x7000 : -0x7000) ex = x+(ey-y)*(ex-x)/(oey-y) end @w.draw_line(@gc, x, y, ex, ey) end
# File metasm/gui/gtk.rb, line 475 def draw_line_color(col, x, y, ex, ey) draw_color(col) draw_line(x, y, ex, ey) end
# File metasm/gui/gtk.rb, line 425 def draw_rectangle(x, y, w, h) # GTK clips coords around 0x8000 return if x > 0x7000 or y > 0x7000 if x < -0x7000 w += x + 100 x = -100 end if y < -0x7000 h += y + 100 y = -100 end return if w <= 0 or h <= 0 w = 0x7000 if w > 0x7000 h = 0x7000 if h > 0x7000 @w.draw_rectangle(@gc, true, x, y, w, h) end
# File metasm/gui/gtk.rb, line 443 def draw_rectangle_color(col, x, y, w, h) draw_color(col) draw_rectangle(x, y, w, h) end
# File metasm/gui/gtk.rb, line 480 def draw_string(x, y, str) return if x.abs > 0x7000 or y.abs > 0x7000 @layout.text = str @w.draw_layout(@gc, x, y, @layout) end
# File metasm/gui/gtk.rb, line 486 def draw_string_color(col, x, y, str) draw_color(col) draw_string(x, y, str) end
same as #draw_string_color + hilight @hl_word_re
# File metasm/gui/gtk.rb, line 492 def draw_string_hl(col, x, y, str) if @hl_word while str =~ @hl_word_re s1, s2 = $1, $2 draw_string_color(col, x, y, s1) x += s1.length*@font_width hl_w = s2.length*@font_width draw_rectangle_color(:hl_word_bg, x, y, hl_w, @font_height) draw_string_color(:hl_word, x, y, s2) x += hl_w str = str[s1.length+s2.length..-1] end end draw_string_color(col, x, y, str) end
# File metasm/gui/qt.rb, line 276 def grab_focus; set_focus end
# File metasm/gui/gtk.rb, line 417 def gui_update redraw end
# File metasm/gui/gtk.rb, line 403 def height allocation.height end
# File metasm/gui/win32.rb, line 1818 def initialize_visible_ BasicColor.each { |tag, val| @color[tag] = color(val) } @color[:winbg] = Win32Gui.getsyscolor(Win32Gui::COLOR_BTNFACE) set_color_association(@default_color_association) # should be called after Gui.main set_font('courier 10') initialize_visible if respond_to? :initialize_visible end
# File metasm/gui/gtk.rb, line 304 def initialize_widget end
# File metasm/gui/gtk.rb, line 394 def invalidate(x, y, w, h) return if not window window.invalidate Gdk::Rectangle.new(x, y, w, h), false end
# File metasm/gui/gtk.rb, line 390 def invalidate_caret(cx, cy, x=0, y=0) invalidate(x + cx*@font_width, y + cy*@font_height, 2, @font_height) end
# File metasm/gui/qt.rb, line 224 def keyPressEvent(key) val = key.key >= 128 ? Keyboard_trad[key.key] : key.text[0].ord # must use text[0] to differenciate downcase/upcase if key.modifiers.to_i & Qt::ControlModifier.to_i > 0 # AONETHUAAAAAAAAAAAAAAA protect { keypress_ctrl(val) } if respond_to? :keypress_ctrl else protect { keypress(val) } if respond_to? :keypress end end
# File metasm/gui/gtk.rb, line 518 def keyboard_state(query=nil) case query when :control, :ctrl ev = @last_kb_ev and ev.state & Gdk::Window::CONTROL_MASK == Gdk::Window::CONTROL_MASK when :shift ev = @last_kb_ev and ev.state & Gdk::Window::SHIFT_MASK == Gdk::Window::SHIFT_MASK when :alt ev = @last_kb_ev and ev.state & Gdk::Window::MOD1_MASK == Gdk::Window::MOD1_MASK else [:control, :shift, :alt].find_all { |s| keyboard_state(s) } end end
# File metasm/gui/gtk.rb, line 411 def keypress(key) end
# File metasm/gui/win32.rb, line 1868 def keypress_(key) # XXX my gtk api sux if not respond_to? :keypress or not protect { keypress(key) } protect { @parent.keypress(key) } if @parent.respond_to? :keypress end end
# File metasm/gui/gtk.rb, line 414 def keypress_ctrl(key) end
# File metasm/gui/win32.rb, line 1875 def keypress_ctrl_(key) if not respond_to? :keypress_ctrl or not protect { keypress_ctrl(key) } protect { @parent.keypress_ctrl(key) } if @parent.respond_to? :keypress_ctrl end end
# File metasm/gui/qt.rb, line 245 def mouseDoubleClickEvent(ev) protect { doubleclick(ev.x, ev.y) } if respond_to? :doubleclick end
# File metasm/gui/qt.rb, line 255 def mouseMoveEvent(ev) if ev.modifiers.to_i & Qt::ControlModifier.to_i > 0 protect { mousemove_ctrl(ev.x, ev.y) } if respond_to? :mousemove_ctrl else protect { mousemove(ev.x, ev.y) } if respond_to? :mousemove end end
# File metasm/gui/qt.rb, line 233 def mousePressEvent(ev) if ev.modifiers.to_i & Qt::ControlModifier.to_i > 0 protect { click_ctrl(ev.x, ev.y) } if respond_to? :click_ctrl else if ev.button == Qt::LeftButton protect { click(ev.x, ev.y) } elsif ev.button == Qt::RightButton protect { rightclick(ev.x, ev.y) } if respond_to? :rightclick end end end
# File metasm/gui/qt.rb, line 249 def mouseReleaseEvent(ev) if ev.button == Qt::LeftButton protect { mouserelease(ev.x, ev.y) } if respond_to? :mouserelease end end
# File metasm/gui/gtk.rb, line 382 def paint end
# File metasm/gui/qt.rb, line 278 def paintEvent(*a) @painter = Qt::Painter.new(self) protect { paint } @painter.end @painter = nil end
# File metasm/gui/win32.rb, line 1846 def paint_(realhdc) @hdc = Win32Gui.createcompatibledc(realhdc) bmp = Win32Gui.createcompatiblebitmap(realhdc, @width, @height) Win32Gui.selectobject(@hdc, bmp) Win32Gui.selectobject(@hdc, Win32Gui.getstockobject(Win32Gui::DC_BRUSH)) Win32Gui.selectobject(@hdc, Win32Gui.getstockobject(Win32Gui::DC_PEN)) Win32Gui.selectobject(@hdc, Win32Gui.getstockobject(Win32Gui::ANSI_FIXED_FONT)) Win32Gui.setbkmode(@hdc, Win32Gui::TRANSPARENT) draw_rectangle_color(:background, 0, 0, @width, @height) paint Win32Gui.bitblt(realhdc, @x, @y, @width, @height, @hdc, 0, 0, Win32Gui::SRCCOPY) Win32Gui.deleteobject(bmp) Win32Gui.deletedc(@hdc) @hdc = nil end
invalidate the whole widget area
# File metasm/gui/gtk.rb, line 386 def redraw invalidate(0, 0, 1000000, 1000000) end
# File metasm/gui/qt.rb, line 272 def resizeEvent(ev) protect { resized(ev.size.width, ev.size.height) } if respond_to? :resized end
# File metasm/gui/gtk.rb, line 407 def resized(w, h) redraw end
# File metasm/gui/win32.rb, line 1862 def resized_(w, h) @width = w @height = h resized(w, h) if respond_to? :resized end
# File metasm/gui/gtk.rb, line 321 def set_caret_from_click(x, y) @caret_x = (x-1).to_i / @font_width @caret_y = y.to_i / @font_height update_caret end
change the color association arg is a hash function symbol => color symbol check initialize/sig('realize') for initial function/color list if called before the widget is first displayed onscreen, will register a hook to re-call itself later
# File metasm/gui/gtk.rb, line 340 def set_color_association(hash) if not realized? sid = signal_connect('realize') { signal_handler_disconnect(sid) set_color_association(hash) } else hord = Hash.new { |h, k| h[k] = (hash[k] ? h[hash[k]] + 1 : 0) } hash.sort_by { |k, v| hord[k] }.each { |k, v| @color[k] = color(v) } modify_bg Gtk::STATE_NORMAL, @color[:background] gui_update end end
change the font of the widget arg is a Gtk Fontdescription string (eg 'courier 10')
# File metasm/gui/gtk.rb, line 329 def set_font(descr) @layout.font_description = Pango::FontDescription.new(descr) @layout.text = 'x' @font_width, @font_height = @layout.pixel_size gui_update end
update @hl_word from a line & offset, return nil if unchanged
# File metasm/gui/gtk.rb, line 365 def update_hl_word(line, offset, mode=:asm) return if not line word = line[0...offset].to_s[/\w*$/] << line[offset..-1].to_s[/^\w*/] word = nil if word == '' if @hl_word != word if word if mode == :asm and defined?(@dasm) and @dasm re = @dasm.gui_hilight_word_regexp(word) else re = Regexp.escape word end @hl_word_re = /^(.*?)(\b(?:#{re})\b)/ end @hl_word = word end end
# File metasm/gui/qt.rb, line 263 def wheelEvent(ev) dir = ev.delta > 0 ? :up : :down if ev.modifiers.to_i & Qt::ControlModifier.to_i > 0 protect { mouse_wheel_ctrl(dir, ev.x, ev.y) } if respond_to? :mouse_wheel_ctrl else protect { mouse_wheel(dir, ev.x, ev.y) } if respond_to? :mouse_wheel end end
# File metasm/gui/gtk.rb, line 399 def width allocation.width end