metasm 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|