metasm 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.hgtags +3 -0
- data/Gemfile +1 -0
- data/INSTALL +61 -0
- data/LICENCE +458 -0
- data/README +29 -21
- data/Rakefile +10 -0
- data/TODO +10 -12
- data/doc/code_organisation.txt +2 -0
- data/doc/core/DynLdr.txt +247 -0
- data/doc/core/ExeFormat.txt +43 -0
- data/doc/core/Expression.txt +220 -0
- data/doc/core/GNUExports.txt +27 -0
- data/doc/core/Ia32.txt +236 -0
- data/doc/core/SerialStruct.txt +108 -0
- data/doc/core/VirtualString.txt +145 -0
- data/doc/core/WindowsExports.txt +61 -0
- data/doc/core/index.txt +1 -0
- data/doc/style.css +6 -3
- data/doc/usage/debugger.txt +327 -0
- data/doc/usage/index.txt +1 -0
- data/doc/use_cases.txt +2 -2
- data/metasm.gemspec +22 -0
- data/{lib/metasm.rb → metasm.rb} +11 -3
- data/{lib/metasm → metasm}/compile_c.rb +13 -7
- data/metasm/cpu/arc.rb +8 -0
- data/metasm/cpu/arc/decode.rb +425 -0
- data/metasm/cpu/arc/main.rb +191 -0
- data/metasm/cpu/arc/opcodes.rb +588 -0
- data/{lib/metasm → metasm/cpu}/arm.rb +7 -5
- data/{lib/metasm → metasm/cpu}/arm/debug.rb +2 -2
- data/{lib/metasm → metasm/cpu}/arm/decode.rb +13 -12
- data/{lib/metasm → metasm/cpu}/arm/encode.rb +23 -8
- data/{lib/metasm → metasm/cpu}/arm/main.rb +0 -3
- data/metasm/cpu/arm/opcodes.rb +324 -0
- data/{lib/metasm → metasm/cpu}/arm/parse.rb +25 -13
- data/{lib/metasm → metasm/cpu}/arm/render.rb +2 -2
- data/metasm/cpu/arm64.rb +15 -0
- data/metasm/cpu/arm64/debug.rb +38 -0
- data/metasm/cpu/arm64/decode.rb +289 -0
- data/metasm/cpu/arm64/encode.rb +41 -0
- data/metasm/cpu/arm64/main.rb +105 -0
- data/metasm/cpu/arm64/opcodes.rb +232 -0
- data/metasm/cpu/arm64/parse.rb +20 -0
- data/metasm/cpu/arm64/render.rb +95 -0
- data/{lib/metasm/ppc.rb → metasm/cpu/bpf.rb} +2 -4
- data/metasm/cpu/bpf/decode.rb +142 -0
- data/metasm/cpu/bpf/main.rb +60 -0
- data/metasm/cpu/bpf/opcodes.rb +81 -0
- data/metasm/cpu/bpf/render.rb +41 -0
- data/metasm/cpu/cy16.rb +9 -0
- data/metasm/cpu/cy16/decode.rb +253 -0
- data/metasm/cpu/cy16/main.rb +63 -0
- data/metasm/cpu/cy16/opcodes.rb +78 -0
- data/metasm/cpu/cy16/render.rb +41 -0
- data/metasm/cpu/dalvik.rb +11 -0
- data/{lib/metasm → metasm/cpu}/dalvik/decode.rb +35 -13
- data/{lib/metasm → metasm/cpu}/dalvik/main.rb +51 -2
- data/{lib/metasm → metasm/cpu}/dalvik/opcodes.rb +19 -11
- data/metasm/cpu/ia32.rb +17 -0
- data/{lib/metasm → metasm/cpu}/ia32/compile_c.rb +5 -7
- data/{lib/metasm → metasm/cpu}/ia32/debug.rb +5 -5
- data/{lib/metasm → metasm/cpu}/ia32/decode.rb +246 -59
- data/{lib/metasm → metasm/cpu}/ia32/decompile.rb +7 -7
- data/{lib/metasm → metasm/cpu}/ia32/encode.rb +19 -13
- data/{lib/metasm → metasm/cpu}/ia32/main.rb +51 -8
- data/metasm/cpu/ia32/opcodes.rb +1424 -0
- data/{lib/metasm → metasm/cpu}/ia32/parse.rb +47 -16
- data/{lib/metasm → metasm/cpu}/ia32/render.rb +31 -4
- data/metasm/cpu/mips.rb +14 -0
- data/{lib/metasm → metasm/cpu}/mips/compile_c.rb +1 -1
- data/metasm/cpu/mips/debug.rb +42 -0
- data/{lib/metasm → metasm/cpu}/mips/decode.rb +46 -16
- data/{lib/metasm → metasm/cpu}/mips/encode.rb +4 -3
- data/{lib/metasm → metasm/cpu}/mips/main.rb +11 -4
- data/{lib/metasm → metasm/cpu}/mips/opcodes.rb +86 -17
- data/{lib/metasm → metasm/cpu}/mips/parse.rb +1 -1
- data/{lib/metasm → metasm/cpu}/mips/render.rb +1 -1
- data/{lib/metasm/dalvik.rb → metasm/cpu/msp430.rb} +1 -1
- data/metasm/cpu/msp430/decode.rb +247 -0
- data/metasm/cpu/msp430/main.rb +62 -0
- data/metasm/cpu/msp430/opcodes.rb +101 -0
- data/{lib/metasm → metasm/cpu}/pic16c/decode.rb +6 -7
- data/{lib/metasm → metasm/cpu}/pic16c/main.rb +0 -0
- data/{lib/metasm → metasm/cpu}/pic16c/opcodes.rb +1 -1
- data/{lib/metasm/mips.rb → metasm/cpu/ppc.rb} +4 -4
- data/{lib/metasm → metasm/cpu}/ppc/decode.rb +18 -12
- data/{lib/metasm → metasm/cpu}/ppc/decompile.rb +3 -3
- data/{lib/metasm → metasm/cpu}/ppc/encode.rb +2 -2
- data/{lib/metasm → metasm/cpu}/ppc/main.rb +17 -12
- data/{lib/metasm → metasm/cpu}/ppc/opcodes.rb +11 -5
- data/metasm/cpu/ppc/parse.rb +55 -0
- data/metasm/cpu/python.rb +8 -0
- data/metasm/cpu/python/decode.rb +136 -0
- data/metasm/cpu/python/main.rb +36 -0
- data/metasm/cpu/python/opcodes.rb +180 -0
- data/{lib/metasm → metasm/cpu}/sh4.rb +1 -1
- data/{lib/metasm → metasm/cpu}/sh4/decode.rb +48 -17
- data/{lib/metasm → metasm/cpu}/sh4/main.rb +13 -4
- data/{lib/metasm → metasm/cpu}/sh4/opcodes.rb +7 -8
- data/metasm/cpu/x86_64.rb +15 -0
- data/{lib/metasm → metasm/cpu}/x86_64/compile_c.rb +28 -17
- data/{lib/metasm → metasm/cpu}/x86_64/debug.rb +4 -4
- data/{lib/metasm → metasm/cpu}/x86_64/decode.rb +57 -15
- data/{lib/metasm → metasm/cpu}/x86_64/encode.rb +55 -26
- data/{lib/metasm → metasm/cpu}/x86_64/main.rb +14 -6
- data/metasm/cpu/x86_64/opcodes.rb +136 -0
- data/{lib/metasm → metasm/cpu}/x86_64/parse.rb +10 -2
- data/metasm/cpu/x86_64/render.rb +35 -0
- data/metasm/cpu/z80.rb +9 -0
- data/metasm/cpu/z80/decode.rb +313 -0
- data/metasm/cpu/z80/main.rb +67 -0
- data/metasm/cpu/z80/opcodes.rb +224 -0
- data/metasm/cpu/z80/render.rb +59 -0
- data/{lib/metasm/os/main.rb → metasm/debug.rb} +160 -401
- data/{lib/metasm → metasm}/decode.rb +35 -4
- data/{lib/metasm → metasm}/decompile.rb +15 -16
- data/{lib/metasm → metasm}/disassemble.rb +201 -45
- data/{lib/metasm → metasm}/disassemble_api.rb +651 -87
- data/{lib/metasm → metasm}/dynldr.rb +220 -133
- data/{lib/metasm → metasm}/encode.rb +10 -1
- data/{lib/metasm → metasm}/exe_format/a_out.rb +9 -6
- data/{lib/metasm → metasm}/exe_format/autoexe.rb +1 -0
- data/{lib/metasm → metasm}/exe_format/bflt.rb +57 -27
- data/{lib/metasm → metasm}/exe_format/coff.rb +11 -3
- data/{lib/metasm → metasm}/exe_format/coff_decode.rb +53 -20
- data/{lib/metasm → metasm}/exe_format/coff_encode.rb +11 -13
- data/{lib/metasm → metasm}/exe_format/dex.rb +13 -5
- data/{lib/metasm → metasm}/exe_format/dol.rb +1 -0
- data/{lib/metasm → metasm}/exe_format/elf.rb +93 -57
- data/{lib/metasm → metasm}/exe_format/elf_decode.rb +143 -34
- data/{lib/metasm → metasm}/exe_format/elf_encode.rb +122 -31
- data/metasm/exe_format/gb.rb +65 -0
- data/metasm/exe_format/javaclass.rb +424 -0
- data/{lib/metasm → metasm}/exe_format/macho.rb +204 -16
- data/{lib/metasm → metasm}/exe_format/main.rb +26 -3
- data/{lib/metasm → metasm}/exe_format/mz.rb +1 -0
- data/{lib/metasm → metasm}/exe_format/nds.rb +7 -4
- data/{lib/metasm → metasm}/exe_format/pe.rb +71 -8
- data/metasm/exe_format/pyc.rb +167 -0
- data/{lib/metasm → metasm}/exe_format/serialstruct.rb +67 -14
- data/{lib/metasm → metasm}/exe_format/shellcode.rb +7 -3
- data/metasm/exe_format/shellcode_rwx.rb +114 -0
- data/metasm/exe_format/swf.rb +205 -0
- data/{lib/metasm → metasm}/exe_format/xcoff.rb +7 -7
- data/metasm/exe_format/zip.rb +335 -0
- data/metasm/gui.rb +13 -0
- data/{lib/metasm → metasm}/gui/cstruct.rb +35 -41
- data/{lib/metasm → metasm}/gui/dasm_coverage.rb +11 -11
- data/{lib/metasm → metasm}/gui/dasm_decomp.rb +7 -20
- data/{lib/metasm → metasm}/gui/dasm_funcgraph.rb +0 -0
- data/metasm/gui/dasm_graph.rb +1695 -0
- data/{lib/metasm → metasm}/gui/dasm_hex.rb +12 -8
- data/{lib/metasm → metasm}/gui/dasm_listing.rb +43 -28
- data/{lib/metasm → metasm}/gui/dasm_main.rb +310 -53
- data/{lib/metasm → metasm}/gui/dasm_opcodes.rb +5 -19
- data/{lib/metasm → metasm}/gui/debug.rb +93 -27
- data/{lib/metasm → metasm}/gui/gtk.rb +162 -40
- data/{lib/metasm → metasm}/gui/qt.rb +12 -2
- data/{lib/metasm → metasm}/gui/win32.rb +179 -42
- data/{lib/metasm → metasm}/gui/x11.rb +59 -59
- data/{lib/metasm → metasm}/main.rb +389 -264
- data/{lib/metasm/os/remote.rb → metasm/os/gdbremote.rb} +146 -54
- data/{lib/metasm → metasm}/os/gnu_exports.rb +1 -1
- data/{lib/metasm → metasm}/os/linux.rb +628 -151
- data/metasm/os/main.rb +330 -0
- data/{lib/metasm → metasm}/os/windows.rb +132 -42
- data/{lib/metasm → metasm}/os/windows_exports.rb +141 -0
- data/{lib/metasm → metasm}/parse.rb +26 -24
- data/{lib/metasm → metasm}/parse_c.rb +221 -116
- data/{lib/metasm → metasm}/preprocessor.rb +55 -40
- data/{lib/metasm → metasm}/render.rb +14 -38
- data/misc/hexdump.rb +2 -1
- data/misc/lint.rb +58 -0
- data/misc/txt2html.rb +9 -7
- data/samples/bindiff.rb +3 -4
- data/samples/dasm-plugins/bindiff.rb +15 -0
- data/samples/dasm-plugins/bookmark.rb +133 -0
- data/samples/dasm-plugins/c_constants.rb +57 -0
- data/samples/dasm-plugins/colortheme_solarized.rb +125 -0
- data/samples/dasm-plugins/cppobj_funcall.rb +60 -0
- data/samples/dasm-plugins/dasm_all.rb +70 -0
- data/samples/dasm-plugins/demangle_cpp.rb +31 -0
- data/samples/dasm-plugins/deobfuscate.rb +251 -0
- data/samples/dasm-plugins/dump_text.rb +35 -0
- data/samples/dasm-plugins/export_graph_svg.rb +86 -0
- data/samples/dasm-plugins/findgadget.rb +75 -0
- data/samples/dasm-plugins/hl_opcode.rb +32 -0
- data/samples/dasm-plugins/hotfix_gtk_dbg.rb +19 -0
- data/samples/dasm-plugins/imm2off.rb +34 -0
- data/samples/dasm-plugins/match_libsigs.rb +93 -0
- data/samples/dasm-plugins/patch_file.rb +95 -0
- data/samples/dasm-plugins/scanfuncstart.rb +36 -0
- data/samples/dasm-plugins/scanxrefs.rb +26 -0
- data/samples/dasm-plugins/selfmodify.rb +197 -0
- data/samples/dasm-plugins/stringsxrefs.rb +28 -0
- data/samples/dasmnavig.rb +1 -1
- data/samples/dbg-apihook.rb +24 -9
- data/samples/dbg-plugins/heapscan.rb +283 -0
- data/samples/dbg-plugins/heapscan/compiled_heapscan_lin.c +155 -0
- data/samples/dbg-plugins/heapscan/compiled_heapscan_win.c +128 -0
- data/samples/dbg-plugins/heapscan/graphheap.rb +616 -0
- data/samples/dbg-plugins/heapscan/heapscan.rb +709 -0
- data/samples/dbg-plugins/heapscan/winheap.h +174 -0
- data/samples/dbg-plugins/heapscan/winheap7.h +307 -0
- data/samples/dbg-plugins/trace_func.rb +214 -0
- data/samples/disassemble-gui.rb +35 -5
- data/samples/disassemble.rb +31 -6
- data/samples/dump_upx.rb +24 -12
- data/samples/dynamic_ruby.rb +12 -3
- data/samples/exeencode.rb +6 -5
- data/samples/factorize-headers-peimports.rb +1 -1
- data/samples/lindebug.rb +175 -381
- data/samples/metasm-shell.rb +1 -2
- data/samples/peldr.rb +2 -2
- data/tests/all.rb +1 -1
- data/tests/arc.rb +26 -0
- data/tests/dynldr.rb +22 -4
- data/tests/expression.rb +55 -0
- data/tests/graph_layout.rb +285 -0
- data/tests/ia32.rb +79 -26
- data/tests/mips.rb +9 -2
- data/tests/x86_64.rb +66 -18
- metadata +330 -218
- data/lib/metasm/arm/opcodes.rb +0 -177
- data/lib/metasm/gui.rb +0 -23
- data/lib/metasm/gui/dasm_graph.rb +0 -1354
- data/lib/metasm/ia32.rb +0 -14
- data/lib/metasm/ia32/opcodes.rb +0 -873
- data/lib/metasm/ppc/parse.rb +0 -52
- data/lib/metasm/x86_64.rb +0 -12
- data/lib/metasm/x86_64/opcodes.rb +0 -118
- data/samples/gdbclient.rb +0 -583
- data/samples/rubstop.rb +0 -399
@@ -323,11 +323,21 @@ Execute Printer Play Sleep Zoom Cancel
|
|
323
323
|
end
|
324
324
|
|
325
325
|
# update @hl_word from a line & offset, return nil if unchanged
|
326
|
-
def update_hl_word(line, offset)
|
326
|
+
def update_hl_word(line, offset, mode=:asm)
|
327
327
|
return if not line
|
328
328
|
word = line[0...offset].to_s[/\w*$/] << line[offset..-1].to_s[/^\w*/]
|
329
329
|
word = nil if word == ''
|
330
|
-
|
330
|
+
if @hl_word != word
|
331
|
+
if word
|
332
|
+
if mode == :asm and defined?(@dasm) and @dasm
|
333
|
+
re = @dasm.gui_hilight_word_regexp(word)
|
334
|
+
else
|
335
|
+
re = Regexp.escape word
|
336
|
+
end
|
337
|
+
@hl_word_re = /^(.*?)(\b(?:#{re})\b)/
|
338
|
+
end
|
339
|
+
@hl_word = word
|
340
|
+
end
|
331
341
|
end
|
332
342
|
|
333
343
|
# invalidate the whole widget area
|
@@ -685,7 +685,7 @@ TrackMouseEvent(
|
|
685
685
|
#define QS_ALLEVENTS (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY)
|
686
686
|
#define QS_ALLINPUT (QS_ALLEVENTS | QS_SENDMESSAGE)
|
687
687
|
|
688
|
-
#define WAIT_TIMEOUT 258L
|
688
|
+
#define WAIT_TIMEOUT 258L
|
689
689
|
|
690
690
|
#define CF_TEXT 1
|
691
691
|
#define CF_BITMAP 2
|
@@ -960,6 +960,33 @@ GetTextExtentPoint32A(
|
|
960
960
|
__in_ecount(c) LPCSTR lpString,
|
961
961
|
__in int c,
|
962
962
|
__out LPPOINT lpsz);
|
963
|
+
|
964
|
+
typedef struct tagRECT {
|
965
|
+
LONG left;
|
966
|
+
LONG top;
|
967
|
+
LONG right;
|
968
|
+
LONG bottom;
|
969
|
+
} RECT, *LPRECT;
|
970
|
+
|
971
|
+
#define TPM_LEFTBUTTON 0x0000L
|
972
|
+
#define TPM_RIGHTBUTTON 0x0002L
|
973
|
+
#define TPM_LEFTALIGN 0x0000L
|
974
|
+
#define TPM_CENTERALIGN 0x0004L
|
975
|
+
#define TPM_RIGHTALIGN 0x0008L
|
976
|
+
#define TPM_TOPALIGN 0x0000L
|
977
|
+
#define TPM_VCENTERALIGN 0x0010L
|
978
|
+
#define TPM_BOTTOMALIGN 0x0020L
|
979
|
+
#define TPM_HORIZONTAL 0x0000L
|
980
|
+
#define TPM_VERTICAL 0x0040L
|
981
|
+
#define TPM_NONOTIFY 0x0080L
|
982
|
+
#define TPM_RETURNCMD 0x0100L
|
983
|
+
#define TPM_RECURSE 0x0001L
|
984
|
+
#define TPM_HORPOSANIMATION 0x0400L
|
985
|
+
#define TPM_HORNEGANIMATION 0x0800L
|
986
|
+
#define TPM_VERPOSANIMATION 0x1000L
|
987
|
+
#define TPM_VERNEGANIMATION 0x2000L
|
988
|
+
#define TPM_NOANIMATION 0x4000L
|
989
|
+
#define TPM_LAYOUTRTL 0x8000L
|
963
990
|
WINUSERAPI
|
964
991
|
BOOL
|
965
992
|
WINAPI
|
@@ -980,6 +1007,17 @@ WINAPI
|
|
980
1007
|
DestroyMenu(
|
981
1008
|
__in HMENU hMenu);
|
982
1009
|
WINUSERAPI
|
1010
|
+
BOOL
|
1011
|
+
WINAPI
|
1012
|
+
TrackPopupMenu(
|
1013
|
+
__in HMENU hMenu,
|
1014
|
+
__in UINT uFlags,
|
1015
|
+
__in int x,
|
1016
|
+
__in int y,
|
1017
|
+
__in int nReserved,
|
1018
|
+
__in HWND hWnd,
|
1019
|
+
__in_opt CONST RECT *prcRect);
|
1020
|
+
WINUSERAPI
|
983
1021
|
DWORD
|
984
1022
|
WINAPI
|
985
1023
|
CheckMenuItem(
|
@@ -999,13 +1037,6 @@ AppendMenuA(
|
|
999
1037
|
#define OPAQUE 2
|
1000
1038
|
int WINAPI SetBkMode(__in HDC hdc, __in int mode);
|
1001
1039
|
|
1002
|
-
typedef struct tagRECT {
|
1003
|
-
LONG left;
|
1004
|
-
LONG top;
|
1005
|
-
LONG right;
|
1006
|
-
LONG bottom;
|
1007
|
-
} RECT, *LPRECT;
|
1008
|
-
|
1009
1040
|
WINUSERAPI
|
1010
1041
|
int
|
1011
1042
|
WINAPI
|
@@ -1086,6 +1117,18 @@ UpdateWindow(
|
|
1086
1117
|
WINUSERAPI
|
1087
1118
|
BOOL
|
1088
1119
|
WINAPI
|
1120
|
+
ClientToScreen(
|
1121
|
+
__in HWND hWnd,
|
1122
|
+
__inout LPPOINT pt);
|
1123
|
+
WINUSERAPI
|
1124
|
+
BOOL
|
1125
|
+
WINAPI
|
1126
|
+
ScreenToClient(
|
1127
|
+
__in HWND hWnd,
|
1128
|
+
__inout LPPOINT pt);
|
1129
|
+
WINUSERAPI
|
1130
|
+
BOOL
|
1131
|
+
WINAPI
|
1089
1132
|
GetClientRect(
|
1090
1133
|
__in HWND hWnd,
|
1091
1134
|
__out LPRECT lpRect);
|
@@ -1390,11 +1433,11 @@ class WinWidget
|
|
1390
1433
|
return if not @parent
|
1391
1434
|
@parent.set_focus(self) if @parent.respond_to? :set_focus
|
1392
1435
|
end
|
1393
|
-
|
1436
|
+
|
1394
1437
|
def focus?
|
1395
1438
|
return true if not @parent
|
1396
1439
|
(@parent.respond_to?(:focus?) ? @parent.focus? : true) and
|
1397
|
-
|
1440
|
+
(@parent.respond_to?(:has_focus?) ? @parent.has_focus?(self) : true)
|
1398
1441
|
end
|
1399
1442
|
|
1400
1443
|
def redraw
|
@@ -1484,6 +1527,7 @@ class ContainerChoiceWidget < WinWidget
|
|
1484
1527
|
|
1485
1528
|
def set_focus(c)
|
1486
1529
|
@curview = c
|
1530
|
+
grab_focus
|
1487
1531
|
redraw
|
1488
1532
|
end
|
1489
1533
|
end
|
@@ -1519,7 +1563,7 @@ class ContainerVBoxWidget < WinWidget
|
|
1519
1563
|
cy = 0
|
1520
1564
|
pv = []
|
1521
1565
|
@views.each_with_index { |v, i|
|
1522
|
-
if y >= cy and y < cy + v.height
|
1566
|
+
if y >= cy+1 and y < cy + v.height - 1
|
1523
1567
|
if @focus_idx != i
|
1524
1568
|
@focus_idx = i
|
1525
1569
|
redraw
|
@@ -1528,8 +1572,7 @@ class ContainerVBoxWidget < WinWidget
|
|
1528
1572
|
return
|
1529
1573
|
end
|
1530
1574
|
cy += v.height
|
1531
|
-
if y >= cy and y < cy+@spacing
|
1532
|
-
vsz = v
|
1575
|
+
if y >= cy-1 and y < cy+@spacing+1
|
1533
1576
|
@resizing = v
|
1534
1577
|
@wantheight[@resizing] ||= v.height
|
1535
1578
|
@tmpwantheight = []
|
@@ -1665,12 +1708,13 @@ class ContainerVBoxWidget < WinWidget
|
|
1665
1708
|
|
1666
1709
|
def set_focus(c)
|
1667
1710
|
@focus_idx = @views.index(c)
|
1711
|
+
grab_focus
|
1668
1712
|
redraw
|
1669
1713
|
end
|
1670
1714
|
end
|
1671
1715
|
|
1672
1716
|
module TextWidget
|
1673
|
-
attr_accessor :caret_x, :caret_y, :hl_word, :font_width, :font_height
|
1717
|
+
attr_accessor :caret_x, :caret_y, :hl_word, :hl_word_re, :font_width, :font_height
|
1674
1718
|
|
1675
1719
|
def initialize_text
|
1676
1720
|
@caret_x = @caret_y = 0 # text cursor position
|
@@ -1679,11 +1723,21 @@ module TextWidget
|
|
1679
1723
|
@hl_word = nil
|
1680
1724
|
end
|
1681
1725
|
|
1682
|
-
def update_hl_word(line, offset)
|
1726
|
+
def update_hl_word(line, offset, mode=:asm)
|
1683
1727
|
return if not line
|
1684
1728
|
word = line[0...offset].to_s[/\w*$/] << line[offset..-1].to_s[/^\w*/]
|
1685
1729
|
word = nil if word == ''
|
1686
|
-
|
1730
|
+
if @hl_word != word
|
1731
|
+
if word
|
1732
|
+
if mode == :asm and defined?(@dasm) and @dasm
|
1733
|
+
re = @dasm.gui_hilight_word_regexp(word)
|
1734
|
+
else
|
1735
|
+
re = Regexp.escape(word)
|
1736
|
+
end
|
1737
|
+
@hl_word_re = /^(.*?)(\b(?:#{re})\b)/
|
1738
|
+
end
|
1739
|
+
@hl_word = word
|
1740
|
+
end
|
1687
1741
|
end
|
1688
1742
|
|
1689
1743
|
def set_caret_from_click(x, y)
|
@@ -1737,7 +1791,15 @@ end
|
|
1737
1791
|
class DrawableWidget < WinWidget
|
1738
1792
|
include TextWidget
|
1739
1793
|
|
1740
|
-
|
1794
|
+
BasicColor = { :white => 'fff', :palegrey => 'ddd', :black => '000', :grey => '444',
|
1795
|
+
:red => 'f44', :darkred => '800', :palered => 'faa',
|
1796
|
+
:green => '4f4', :darkgreen => '080', :palegreen => 'afa',
|
1797
|
+
:blue => '44f', :darkblue => '008', :paleblue => 'aaf',
|
1798
|
+
:yellow => 'ff4', :darkyellow => '440', :paleyellow => 'ffa',
|
1799
|
+
:orange => 'fc8',
|
1800
|
+
}
|
1801
|
+
attr_accessor :buttons, :parent_widget
|
1802
|
+
attr_accessor :default_color_association
|
1741
1803
|
|
1742
1804
|
def initialize(*a, &b)
|
1743
1805
|
@color = {}
|
@@ -1754,12 +1816,7 @@ class DrawableWidget < WinWidget
|
|
1754
1816
|
end
|
1755
1817
|
|
1756
1818
|
def initialize_visible_
|
1757
|
-
{
|
1758
|
-
:red => 'f00', :darkred => '800', :palered => 'fcc',
|
1759
|
-
:green => '0f0', :darkgreen => '080', :palegreen => 'cfc',
|
1760
|
-
:blue => '00f', :darkblue => '008', :paleblue => 'ccf',
|
1761
|
-
:yellow => 'ff0', :darkyellow => '440', :paleyellow => 'ffc',
|
1762
|
-
}.each { |tag, val|
|
1819
|
+
BasicColor.each { |tag, val|
|
1763
1820
|
@color[tag] = color(val)
|
1764
1821
|
}
|
1765
1822
|
@color[:winbg] = Win32Gui.getsyscolor(Win32Gui::COLOR_BTNFACE)
|
@@ -1768,11 +1825,24 @@ class DrawableWidget < WinWidget
|
|
1768
1825
|
initialize_visible if respond_to? :initialize_visible
|
1769
1826
|
end
|
1770
1827
|
|
1771
|
-
def set_color_association(
|
1772
|
-
|
1828
|
+
def set_color_association(hash)
|
1829
|
+
hord = Hash.new { |h, k| h[k] = (hash[k] ? h[hash[k]] + 1 : 0) }
|
1830
|
+
hash.sort_by { |k, v| hord[k] }.each { |k, v| @color[k] = color(v) }
|
1773
1831
|
gui_update
|
1774
1832
|
end
|
1775
1833
|
|
1834
|
+
def new_menu
|
1835
|
+
toplevel.new_menu
|
1836
|
+
end
|
1837
|
+
|
1838
|
+
def addsubmenu(*a, &b)
|
1839
|
+
toplevel.addsubmenu(*a, &b)
|
1840
|
+
end
|
1841
|
+
|
1842
|
+
def popupmenu(m, x, y)
|
1843
|
+
toplevel.popupmenu(m, (x+@x).to_i, (y+@y).to_i)
|
1844
|
+
end
|
1845
|
+
|
1776
1846
|
def paint_(realhdc)
|
1777
1847
|
@hdc = Win32Gui.createcompatibledc(realhdc)
|
1778
1848
|
bmp = Win32Gui.createcompatiblebitmap(realhdc, @width, @height)
|
@@ -1813,7 +1883,7 @@ class DrawableWidget < WinWidget
|
|
1813
1883
|
end
|
1814
1884
|
|
1815
1885
|
def color(col)
|
1816
|
-
@color[col] ||= col.sub(/^(\w)(\w)(\w)$/, '\\3\\3\\2\\2\\1\\1').to_i(16)
|
1886
|
+
@color[col] ||= col.sub(/^(\w\w)(\w\w)(\w\w)$/, '\\3\\2\\1').sub(/^(\w)(\w)(\w)$/, '\\3\\3\\2\\2\\1\\1').to_i(16)
|
1817
1887
|
end
|
1818
1888
|
|
1819
1889
|
def draw_color(col)
|
@@ -1853,6 +1923,23 @@ class DrawableWidget < WinWidget
|
|
1853
1923
|
draw_string(x, y, text)
|
1854
1924
|
end
|
1855
1925
|
|
1926
|
+
# same as draw_string_color + hilight @hl_word_re
|
1927
|
+
def draw_string_hl(col, x, y, str)
|
1928
|
+
if @hl_word
|
1929
|
+
while str =~ @hl_word_re
|
1930
|
+
s1, s2 = $1, $2
|
1931
|
+
draw_string_color(col, x, y, s1)
|
1932
|
+
x += s1.length*@font_width
|
1933
|
+
hl_w = s2.length*@font_width
|
1934
|
+
draw_rectangle_color(:hl_word_bg, x, y, hl_w, @font_height)
|
1935
|
+
draw_string_color(:hl_word, x, y, s2)
|
1936
|
+
x += hl_w
|
1937
|
+
str = str[s1.length+s2.length..-1]
|
1938
|
+
end
|
1939
|
+
end
|
1940
|
+
draw_string_color(col, x, y, str)
|
1941
|
+
end
|
1942
|
+
|
1856
1943
|
def keyboard_state(query=nil)
|
1857
1944
|
case query
|
1858
1945
|
when :control, :ctrl
|
@@ -1952,10 +2039,10 @@ class Window
|
|
1952
2039
|
:style => Win32Gui::CS_DBLCLKS,
|
1953
2040
|
:hcursor => Win32Gui.loadcursora(0, Win32Gui::IDC_ARROW),
|
1954
2041
|
:lpszclassname => cname,
|
1955
|
-
|
2042
|
+
:lpfnwndproc => Win32Gui.callback_alloc_c('__stdcall int wndproc(int, int, int, int)') { |hwnd, msg, wp, lp| windowproc(hwnd, msg, wp, lp) }
|
1956
2043
|
|
1957
2044
|
Win32Gui.registerclassexa(cls)
|
1958
|
-
|
2045
|
+
|
1959
2046
|
@hwnd = Win32Gui.createwindowexa(win32styleex, cname, 'win32gui window', win32style, Win32Gui::CW_USEDEFAULT, Win32Gui::SW_HIDE, Win32Gui::CW_USEDEFAULT, 0, 0, 0, 0, 0)
|
1960
2047
|
|
1961
2048
|
initialize_window(*a, &b)
|
@@ -1997,7 +2084,8 @@ class Window
|
|
1997
2084
|
h.update v => {
|
1998
2085
|
:prior => :pgup, :next => :pgdown,
|
1999
2086
|
:escape => :esc, :return => :enter,
|
2000
|
-
:back => :backspace,
|
2087
|
+
:back => :backspace, :apps => :popupmenu,
|
2088
|
+
:add => ?+, :subtract => ?-, :multiply => ?*, :divide => ?/,
|
2001
2089
|
}.fetch(key, key)
|
2002
2090
|
}
|
2003
2091
|
|
@@ -2053,7 +2141,9 @@ class Window
|
|
2053
2141
|
when Win32Gui::WM_KEYDOWN, Win32Gui::WM_SYSKEYDOWN
|
2054
2142
|
# SYSKEYDOWN for f10 (default = activate the menu bar)
|
2055
2143
|
if key = Keyboard_trad[wparam]
|
2056
|
-
if
|
2144
|
+
if [?+, ?-, ?/, ?*].include?(key)
|
2145
|
+
# keypad keys generate wm_keydown + wm_char, ignore this one
|
2146
|
+
elsif keyboard_state(:control)
|
2057
2147
|
@widget.keypress_ctrl_(key) if @widget
|
2058
2148
|
else
|
2059
2149
|
@widget.keypress_(key) if @widget
|
@@ -2064,15 +2154,15 @@ class Window
|
|
2064
2154
|
if keyboard_state(:control) and not keyboard_state(:alt) # altgr+[ returns CTRL on..
|
2065
2155
|
if ?a.kind_of?(String)
|
2066
2156
|
wparam += (keyboard_state(:shift) ? ?A.ord : ?a.ord) - 1 if wparam < 0x1a
|
2067
|
-
|
2157
|
+
key = wparam.chr
|
2068
2158
|
else
|
2069
2159
|
wparam += (keyboard_state(:shift) ? ?A : ?a) - 1 if wparam < 0x1a
|
2070
|
-
|
2160
|
+
key = wparam
|
2071
2161
|
end
|
2072
|
-
@widget.keypress_ctrl_(
|
2162
|
+
@widget.keypress_ctrl_(key) if @widget
|
2073
2163
|
else
|
2074
|
-
|
2075
|
-
@widget.keypress_(
|
2164
|
+
key = (?a.kind_of?(String) ? wparam.chr : wparam)
|
2165
|
+
@widget.keypress_(key) if @widget
|
2076
2166
|
end
|
2077
2167
|
when Win32Gui::WM_DESTROY
|
2078
2168
|
destroy_window
|
@@ -2214,12 +2304,39 @@ class Window
|
|
2214
2304
|
|
2215
2305
|
# make the window's MenuBar reflect the content of @menu
|
2216
2306
|
def update_menu
|
2307
|
+
unuse_menu(@menu)
|
2217
2308
|
Win32Gui.destroymenu(@menuhwnd) if @menuhwnd != 0
|
2218
2309
|
@menuhwnd = Win32Gui.createmenu()
|
2219
2310
|
@menu.each { |e| create_menu_item(@menuhwnd, e) }
|
2220
2311
|
Win32Gui.setmenu(@hwnd, @menuhwnd)
|
2221
2312
|
end
|
2222
2313
|
|
2314
|
+
def popupmenu(m, x, y)
|
2315
|
+
hm = Win32Gui.createpopupmenu()
|
2316
|
+
m.each { |e| create_menu_item(hm, e) }
|
2317
|
+
pt = Win32Gui.alloc_c_struct('POINT', :x => x, :y => y)
|
2318
|
+
Win32Gui.clienttoscreen(@hwnd, pt)
|
2319
|
+
id = Win32Gui.trackpopupmenu(hm, Win32Gui::TPM_NONOTIFY | Win32Gui::TPM_RETURNCMD, pt.x, pt.y, 0, @hwnd, 0)
|
2320
|
+
if p = @control_action[id]
|
2321
|
+
# TrackPopup returns before WM_COMMAND is delivered, so if we
|
2322
|
+
# want to cleanup @control_action we must call it now & clenup
|
2323
|
+
p.call
|
2324
|
+
end
|
2325
|
+
unuse_menu(m)
|
2326
|
+
Win32Gui.destroymenu(hm)
|
2327
|
+
end
|
2328
|
+
|
2329
|
+
def unuse_menu(m)
|
2330
|
+
m.flatten.grep(Proc).reverse_each { |c|
|
2331
|
+
if @control_action[@controlid-1] == c
|
2332
|
+
@controlid -= 1 # recycle IDs
|
2333
|
+
@control_action.delete @controlid
|
2334
|
+
elsif i = @control_action.index(c)
|
2335
|
+
@control_action.delete i
|
2336
|
+
end
|
2337
|
+
}
|
2338
|
+
end
|
2339
|
+
|
2223
2340
|
def create_menu_item(menu, entry)
|
2224
2341
|
args = entry.dup
|
2225
2342
|
|
@@ -2270,6 +2387,7 @@ class Window
|
|
2270
2387
|
checked = action.call(!checked)
|
2271
2388
|
Win32Gui.checkmenuitem(menu, id, (checked ? Win32Gui::MF_CHECKED : Win32Gui::MF_UNCHECKED))
|
2272
2389
|
}
|
2390
|
+
entry << @control_action[id] # allow deletion in unuse_menu
|
2273
2391
|
end
|
2274
2392
|
@controlid += 1
|
2275
2393
|
end
|
@@ -2329,7 +2447,7 @@ class OpenFile
|
|
2329
2447
|
buf = [0].pack('C')*512
|
2330
2448
|
ofn = Win32Gui.alloc_c_struct 'OPENFILENAMEA',
|
2331
2449
|
:lstructsize => :size,
|
2332
|
-
|
2450
|
+
#:hwndowner => win.hwnd, # 0 for nonmodal
|
2333
2451
|
:lpstrfilter => "All Files\0*.*\0\0",
|
2334
2452
|
:lpstrfile => buf,
|
2335
2453
|
:lpstrtitle => title,
|
@@ -2369,6 +2487,10 @@ class IBoxWidget < DrawableWidget
|
|
2369
2487
|
@oldsel_x = @caret_x_select = 0
|
2370
2488
|
@caret_x = @curline.length
|
2371
2489
|
@caret_x_start = 0
|
2490
|
+
@@history ||= {}
|
2491
|
+
histkey = opts[:history] || label[0, 10]
|
2492
|
+
@history = (@@history[histkey] ||= [])
|
2493
|
+
@history_off = @history.length
|
2372
2494
|
|
2373
2495
|
add_button('Ok', :btnc1, :btnc2) { keypress(:enter) }
|
2374
2496
|
add_button('Cancel', :btnc1, :btnc2) { keypress(:esc) }
|
@@ -2505,7 +2627,19 @@ class IBoxWidget < DrawableWidget
|
|
2505
2627
|
end
|
2506
2628
|
@caret_x = @curline.length
|
2507
2629
|
update_caret
|
2630
|
+
when :up, :down
|
2631
|
+
if @history_off < @history.length or @curline.strip != @history.last
|
2632
|
+
@history[@history_off] = @curline.strip
|
2633
|
+
end
|
2634
|
+
@history_off += (key == :up ? -1 : 1)
|
2635
|
+
@history_off %= @history.length
|
2636
|
+
@curline = @history[@history_off].to_s
|
2637
|
+
@caret_x = @curline.length if @caret_x > @curline.length
|
2638
|
+
redraw
|
2508
2639
|
when :enter
|
2640
|
+
@history << @curline.strip
|
2641
|
+
@history.pop if @history.last == ''
|
2642
|
+
@history.pop if @history.last == @history[-2]
|
2509
2643
|
destroy
|
2510
2644
|
Gui.main_iter
|
2511
2645
|
protect { @action.call(@curline.strip) }
|
@@ -2588,7 +2722,7 @@ class IBoxWidget < DrawableWidget
|
|
2588
2722
|
elsif mouserelease_buttons(x, y)
|
2589
2723
|
end
|
2590
2724
|
end
|
2591
|
-
|
2725
|
+
|
2592
2726
|
def update_caret
|
2593
2727
|
return if @oldcaret_x == @caret_x and @oldsel_x == @caret_x_select
|
2594
2728
|
redraw
|
@@ -2664,7 +2798,7 @@ class LBoxWidget < DrawableWidget
|
|
2664
2798
|
def initial_size
|
2665
2799
|
@colw = @colwmax.map { |w| (w+1) * @font_width }
|
2666
2800
|
allw = @colw.inject(0) { |a, i| a+i }
|
2667
|
-
[[allw, 80*@font_width].min, [@list.length+
|
2801
|
+
[[allw+@font_width, 80*@font_width].min, [@list.length+2, 30].min * @font_height+2]
|
2668
2802
|
end
|
2669
2803
|
|
2670
2804
|
def resized(w, h)
|
@@ -2699,7 +2833,11 @@ class LBoxWidget < DrawableWidget
|
|
2699
2833
|
def paint
|
2700
2834
|
@btnx = []
|
2701
2835
|
@btny = 0
|
2702
|
-
@btnheight
|
2836
|
+
if @btnheight != @font_height * 4/3
|
2837
|
+
# fix vscrollbar height on w7
|
2838
|
+
@btnheight = @font_height * 4/3
|
2839
|
+
resized(width, height)
|
2840
|
+
end
|
2703
2841
|
x = 0
|
2704
2842
|
@colw.each { |w|
|
2705
2843
|
@btnx << x
|
@@ -2817,7 +2955,6 @@ class LBoxWidget < DrawableWidget
|
|
2817
2955
|
vscroll((@linehead-off)*@font_height)
|
2818
2956
|
redraw
|
2819
2957
|
when :down
|
2820
|
-
n = @lineshown-1
|
2821
2958
|
off = [@lineshown, [@lineshown/2, 5].max].min
|
2822
2959
|
vscroll((@linehead+off)*@font_height)
|
2823
2960
|
redraw
|
@@ -2907,7 +3044,7 @@ class LBoxWidget < DrawableWidget
|
|
2907
3044
|
redraw
|
2908
3045
|
end
|
2909
3046
|
end
|
2910
|
-
|
3047
|
+
|
2911
3048
|
def destroy
|
2912
3049
|
@parent.destroy
|
2913
3050
|
end
|
@@ -2943,7 +3080,7 @@ end
|
|
2943
3080
|
Win32Gui.getscrollinfo(@hwnd, Win32Gui::SB_VERT, sif)
|
2944
3081
|
case wparam & 0xffff
|
2945
3082
|
when Win32Gui::SB_THUMBPOSITION; val = sif.ntrackpos
|
2946
|
-
when Win32Gui::SB_THUMBTRACK; val = sif.ntrackpos
|
3083
|
+
when Win32Gui::SB_THUMBTRACK; val = sif.ntrackpos #; nopos = true
|
2947
3084
|
when Win32Gui::SB_LINEDOWN; val = sif.npos + 1
|
2948
3085
|
when Win32Gui::SB_LINEUP; val = sif.npos - 1
|
2949
3086
|
when Win32Gui::SB_PAGEDOWN; val = sif.npos + sif.npage
|