├── .drone.yml
├── .gitmodules
├── .travis.yml
├── Docker
├── ubuntu1604.dockerfile
└── ubuntu1804.dockerfile
├── LICENSE
├── README.md
├── configure_ubuntu_16.sh
├── doc
├── auto-contrast.svg
├── link-views.svg
├── location.svg
└── sample_window.png
├── gdb-imagewatch.pro
├── resources
├── gdb-imagewatch.py
├── giwscripts
│ ├── __init__.py
│ ├── debuggers
│ │ ├── __init__.py
│ │ ├── gdbbridge.py
│ │ └── interfaces.py
│ ├── events.py
│ ├── giwtypes
│ │ ├── __init__.py
│ │ ├── eigen3.py
│ │ ├── interface.py
│ │ └── opencv.py
│ ├── giwwindow.py
│ ├── ides
│ │ ├── __init__.py
│ │ └── qtcreator.py
│ ├── symbols.py
│ ├── sysinfo.py
│ ├── test.py
│ └── typebridge.py
├── icons
│ ├── LICENSE.txt
│ ├── config.json
│ ├── fontello.ttf
│ ├── label_alpha_channel.svg
│ ├── label_blue_channel.svg
│ ├── label_green_channel.svg
│ ├── label_red_channel.svg
│ ├── lower_upper_bound.svg
│ ├── x.svg
│ └── y.svg
├── matlab
│ └── giw_load.m
└── resources.qrc
├── src
├── .clang-format
├── debuggerinterface
│ ├── buffer_request_message.cpp
│ ├── buffer_request_message.h
│ ├── managed_pointer.cpp
│ ├── managed_pointer.h
│ ├── preprocessor_directives.h
│ ├── python_native_interface.cpp
│ └── python_native_interface.h
├── giw_window.cpp
├── giw_window.h
├── io
│ ├── buffer_exporter.cpp
│ └── buffer_exporter.h
├── math
│ ├── assorted.cpp
│ ├── assorted.h
│ ├── linear_algebra.cpp
│ └── linear_algebra.h
├── thirdparty
│ └── Khronos
│ │ └── GL
│ │ ├── gl.h
│ │ ├── glcorearb.h
│ │ └── glext.h
├── ui
│ ├── decorated_line_edit.cpp
│ ├── decorated_line_edit.h
│ ├── gl_canvas.cpp
│ ├── gl_canvas.h
│ ├── gl_text_renderer.cpp
│ ├── gl_text_renderer.h
│ ├── go_to_widget.cpp
│ ├── go_to_widget.h
│ ├── main_window
│ │ ├── auto_contrast.cpp
│ │ ├── initialization.cpp
│ │ ├── main_window.cpp
│ │ ├── main_window.h
│ │ └── ui_events.cpp
│ ├── symbol_completer.cpp
│ ├── symbol_completer.h
│ ├── symbol_search_input.cpp
│ └── symbol_search_input.h
└── visualization
│ ├── components
│ ├── background.cpp
│ ├── background.h
│ ├── buffer.cpp
│ ├── buffer.h
│ ├── buffer_values.cpp
│ ├── buffer_values.h
│ ├── camera.cpp
│ ├── camera.h
│ ├── component.cpp
│ └── component.h
│ ├── events.cpp
│ ├── events.h
│ ├── game_object.cpp
│ ├── game_object.h
│ ├── shader.cpp
│ ├── shader.h
│ ├── shaders
│ ├── background_fs.cpp
│ ├── background_vs.cpp
│ ├── buffer_fs.cpp
│ ├── buffer_vs.cpp
│ ├── giw_shaders.h
│ ├── text_fs.cpp
│ └── text_vs.cpp
│ ├── stage.cpp
│ └── stage.h
├── testbench
├── main.cpp
└── testbench.pro
└── ui
└── main_window.ui
/.drone.yml:
--------------------------------------------------------------------------------
1 | kind: pipeline
2 | name: ubuntu1604
3 |
4 | steps:
5 | - name: submodules
6 | image: docker:git
7 | commands:
8 | - git submodule update --init --recursive --remote
9 |
10 | - name: build
11 | image: brunorosa/gdb-imagewatch_env:ubuntu1604
12 | pull: always
13 | commands:
14 | - mkdir build
15 | - cd build
16 | - qmake ..
17 | - make -j4
18 |
19 | ---
20 |
21 | kind: pipeline
22 | name: ubuntu1804
23 |
24 | steps:
25 | - name: submodules
26 | image: docker:git
27 | commands:
28 | - git submodule update --init --recursive --remote
29 |
30 | - name: build
31 | image: brunorosa/gdb-imagewatch_env:ubuntu1804
32 | pull: always
33 | commands:
34 | - mkdir build
35 | - cd build
36 | - qmake ..
37 | - make -j4
38 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/thirdparty/Eigen"]
2 | path = src/thirdparty/Eigen
3 | url = https://github.com/csantosbh/eigen.git
4 | branch = v3.4
5 | [submodule "resources/giwscripts/thirdparty/pysigset"]
6 | path = resources/giwscripts/thirdparty/pysigset
7 | url = https://github.com/csantosbh/pysigset.git
8 | branch = v0.3
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: cpp
2 |
3 | matrix:
4 | include:
5 | - os: osx
6 |
7 | - os: linux
8 | dist: xenial
9 |
10 | - os: linux
11 | dist: bionic
12 |
13 | addons:
14 | homebrew:
15 | packages:
16 | - qt5
17 | update: true
18 | apt:
19 | packages:
20 | - qt5-default
21 | - libqt5opengl5-dev
22 | - python3-dev
23 | - pkg-config
24 | update: true
25 |
26 | before_install:
27 | # Allow qmake to be called via CLI on MacOS
28 | - if [ $TRAVIS_OS_NAME = osx ]; then brew link qt5 --force; fi
29 |
30 | script:
31 | - mkdir build && cd build
32 | - qmake ..
33 | - make -j4
34 |
--------------------------------------------------------------------------------
/Docker/ubuntu1604.dockerfile:
--------------------------------------------------------------------------------
1 | # prebuilt image of Ubuntu 16.04 with qt5
2 | FROM frostasm/qt:qt5.12-desktop
3 | USER root
4 | # adding python3-dev
5 | RUN apt update -y && apt -f install -y && apt upgrade -y && apt install -y python3-dev
6 |
--------------------------------------------------------------------------------
/Docker/ubuntu1804.dockerfile:
--------------------------------------------------------------------------------
1 | # prebuilt image of Ubuntu 18.04
2 | FROM ubuntu:bionic
3 |
4 | # install dependencies
5 | RUN apt update -y && apt upgrade -y && apt install -y \
6 | python3-dev \
7 | qt5-default \
8 | build-essential \
9 | git \
10 | pkg-config
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-2017 GDB ImageWatch contributors (github.com/csantosbh/gdb-imagewatch/)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/configure_ubuntu_16.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | echo -e "\tThis version of GDB ImageWatch requires Qt 5.6 (or more recent)."
3 | echo -e "\tIf you don't have it, please download it from https://www.qt.io/download"
4 | echo "Starting GDB ImageWatch configuration for Ubuntu 16.04."
5 | git submodule init
6 | git submodule update
7 | set -e
8 | sudo apt-get -y install libpython3-dev python3-dev
9 | mkdir build
10 | cd build
11 | export QT_SELECT=5
12 | qmake ..
13 | make -j$(nproc)
14 | make install
15 | cd ..
16 | echo "source $(pwd)/build/gdb-imagewatch.py" > ~/.gdbinit
17 | echo "Completed configuration of GDB ImageWatch."
18 |
--------------------------------------------------------------------------------
/doc/auto-contrast.svg:
--------------------------------------------------------------------------------
1 |
2 |
67 |
--------------------------------------------------------------------------------
/doc/link-views.svg:
--------------------------------------------------------------------------------
1 |
2 |
67 |
--------------------------------------------------------------------------------
/doc/location.svg:
--------------------------------------------------------------------------------
1 |
2 |
67 |
--------------------------------------------------------------------------------
/doc/sample_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csantosbh/gdb-imagewatch/95853220a5ae55d85cb106eb55e5a5f7b5d5b5b2/doc/sample_window.png
--------------------------------------------------------------------------------
/gdb-imagewatch.pro:
--------------------------------------------------------------------------------
1 | # BUILD_MODE variable can be either release or debug
2 | isEmpty(BUILD_MODE) {
3 | BUILD_MODE = release
4 | }
5 |
6 | message(GDB-ImageWatch build mode: $$BUILD_MODE)
7 |
8 | CONFIG += $$BUILD_MODE
9 |
10 | # Prevent strip from producing spurious error messages
11 | QMAKE_STRIP = echo "strip disabled: "
12 |
13 | QT += \
14 | core \
15 | gui \
16 | opengl \
17 | widgets \
18 | gui
19 |
20 | QMAKE_CXXFLAGS += \
21 | -fPIC \
22 | -fvisibility=hidden \
23 | -pthread
24 |
25 | QMAKE_LFLAGS += \
26 | # If you have an error "cannot find -lGL", uncomment the following line and
27 | # replace the folder by the location of your libGL.so
28 | #-L/path/to/your/opengl/folder \
29 | -Wl,--exclude-libs,ALL
30 |
31 | SOURCES += \
32 | src/giw_window.cpp \
33 | src/debuggerinterface/buffer_request_message.cpp \
34 | src/debuggerinterface/managed_pointer.cpp \
35 | src/debuggerinterface/python_native_interface.cpp \
36 | src/io/buffer_exporter.cpp \
37 | src/math/assorted.cpp \
38 | src/math/linear_algebra.cpp \
39 | src/ui/gl_canvas.cpp \
40 | src/ui/symbol_completer.cpp \
41 | src/ui/symbol_search_input.cpp \
42 | src/ui/main_window/main_window.cpp \
43 | src/ui/main_window/initialization.cpp \
44 | src/ui/main_window/auto_contrast.cpp \
45 | src/ui/main_window/ui_events.cpp \
46 | src/visualization/events.cpp \
47 | src/visualization/game_object.cpp \
48 | src/visualization/shader.cpp \
49 | src/visualization/stage.cpp \
50 | src/visualization/components/background.cpp \
51 | src/visualization/components/buffer.cpp \
52 | src/visualization/components/buffer_values.cpp \
53 | src/visualization/components/camera.cpp\
54 | src/visualization/components/component.cpp\
55 | src/visualization/shaders/background_fs.cpp \
56 | src/visualization/shaders/background_vs.cpp \
57 | src/visualization/shaders/buffer_fs.cpp \
58 | src/visualization/shaders/buffer_vs.cpp \
59 | src/visualization/shaders/text_fs.cpp \
60 | src/visualization/shaders/text_vs.cpp \
61 | src/ui/gl_text_renderer.cpp \
62 | src/ui/go_to_widget.cpp \
63 | src/ui/decorated_line_edit.cpp
64 |
65 | # Qt related headers
66 | HEADERS += \
67 | src/debuggerinterface/preprocessor_directives.h \
68 | src/ui/gl_canvas.h \
69 | src/ui/main_window/main_window.h \
70 | src/ui/symbol_completer.h \
71 | src/ui/symbol_search_input.h \
72 | src/ui/gl_text_renderer.h \
73 | src/ui/go_to_widget.h \
74 | src/ui/decorated_line_edit.h
75 |
76 | # Copy resource files to build folder
77 | copydata.commands = \
78 | $(COPY_DIR) \"$$shell_path($$PWD\\resources\\giwscripts)\" \"$$shell_path($$OUT_PWD)\"; \
79 | $(COPY_DIR) \"$$shell_path($$PWD\\resources\\matlab)\" \"$$shell_path($$OUT_PWD)\"; \
80 | $(COPY_FILE) \"$$shell_path($$PWD\\resources\\gdb-imagewatch.py)\" \"$$shell_path($$OUT_PWD)\"
81 |
82 | first.depends = $(first) copydata
83 | export(first.depends)
84 | export(copydata.commands)
85 | QMAKE_EXTRA_TARGETS += first copydata
86 |
87 | # Instalation instructions
88 | isEmpty(PREFIX) {
89 | PREFIX = /usr/local
90 | }
91 |
92 | VERSION = 1.2
93 | TARGET = giwwindow
94 | TEMPLATE = lib
95 | target.path = $$PREFIX/bin/gdb-imagewatch/
96 |
97 | install_debugger_scripts.path = $$PREFIX/bin/gdb-imagewatch/
98 | install_debugger_scripts.files = \
99 | resources/gdb-imagewatch.py \
100 | resources/giwscripts
101 |
102 | install_fonts.path = $$PREFIX/bin/gdb-imagewatch/fonts/
103 | install_fonts.files = resources/fonts/*
104 |
105 | install_matlab_scripts.path = $$PREFIX/bin/gdb-imagewatch/matlab
106 | install_matlab_scripts.files = resources/matlab/*
107 |
108 | INSTALLS += \
109 | install_fonts \
110 | install_matlab_scripts \
111 | install_debugger_scripts \
112 | target
113 |
114 | # Assorted configuration
115 | INCLUDEPATH += \
116 | $$PWD/src \
117 | $$PWD/src/thirdparty/Khronos/
118 |
119 | CONFIG += \
120 | link_pkgconfig \
121 | warn_on \
122 | c++11 \
123 | no_keywords
124 |
125 | PKGCONFIG += python3
126 |
127 | FORMS += ui/main_window.ui
128 |
129 | RESOURCES += resources/resources.qrc
130 |
131 |
--------------------------------------------------------------------------------
/resources/gdb-imagewatch.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | # -*- coding: utf-8 -*-
4 |
5 | """
6 | GDB-ImageWatch entry point. Can be called with --test for opening the watcher
7 | window with a couple of sample buffers; otherwise, should be invoked by the
8 | debugger (GDB).
9 | """
10 |
11 | import argparse
12 | import os
13 | import sys
14 |
15 |
16 | def get_debugger_bridge():
17 | """
18 | Instantiate the debugger bridge. If we ever decide to support other
19 | debuggers, this will be the place to instantiate its bridge object.
20 | """
21 | from giwscripts.debuggers import gdbbridge
22 | from giwscripts import typebridge
23 |
24 | try:
25 | return gdbbridge.GdbBridge(typebridge.TypeBridge())
26 | except Exception as err:
27 | print(err)
28 |
29 | print('[gdb-imagewatch] Error: Could not instantiate any debugger bridge')
30 | exit(1)
31 |
32 |
33 | def main():
34 | """
35 | Main entry point.
36 | """
37 | # Add script path to Python PATH so submodules can be found
38 | script_path = os.path.dirname(os.path.realpath(__file__))
39 | sys.path.append(script_path)
40 |
41 | # Load dependency modules
42 | from giwscripts import events
43 | from giwscripts import giwwindow
44 | from giwscripts import test
45 | from giwscripts.ides import qtcreator
46 |
47 | parser = argparse.ArgumentParser()
48 | parser.add_argument('--test',
49 | help='Open a test window with sample buffers',
50 | action='store_true')
51 | args = parser.parse_args()
52 |
53 | if args.test:
54 | # Test application
55 | test.giwtest(script_path)
56 | else:
57 | # Setup GDB interface
58 | debugger = get_debugger_bridge()
59 | window = giwwindow.GdbImageWatchWindow(script_path, debugger)
60 | event_handler = events.GdbImageWatchEvents(window, debugger)
61 |
62 | qtcreator.register_symbol_fetch_hook(event_handler.refresh_handler)
63 | debugger.register_event_handlers(event_handler)
64 |
65 |
66 | main()
67 |
--------------------------------------------------------------------------------
/resources/giwscripts/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csantosbh/gdb-imagewatch/95853220a5ae55d85cb106eb55e5a5f7b5d5b5b2/resources/giwscripts/__init__.py
--------------------------------------------------------------------------------
/resources/giwscripts/debuggers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csantosbh/gdb-imagewatch/95853220a5ae55d85cb106eb55e5a5f7b5d5b5b2/resources/giwscripts/debuggers/__init__.py
--------------------------------------------------------------------------------
/resources/giwscripts/debuggers/gdbbridge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Code responsible with directly interacting with GDB
5 | """
6 |
7 | import gdb
8 |
9 | from giwscripts import sysinfo
10 | from giwscripts.debuggers.interfaces import BridgeInterface
11 |
12 |
13 | class GdbBridge(BridgeInterface):
14 | """
15 | GDB Bridge class, exposing the common expected interface for the ImageWatch
16 | to access the required buffer data and interact with the debugger.
17 | """
18 | def __init__(self, type_bridge):
19 | self._type_bridge = type_bridge
20 | self._commands = dict(plot=PlotterCommand(self))
21 |
22 | def queue_request(self, callable_request):
23 | return gdb.post_event(callable_request)
24 |
25 | def get_buffer_metadata(self, variable):
26 | picked_obj = gdb.parse_and_eval(variable)
27 |
28 | buffer_metadata = self._type_bridge.get_buffer_metadata(
29 | variable, picked_obj, self)
30 |
31 | bufsize = sysinfo.get_buffer_size(
32 | buffer_metadata['height'],
33 | buffer_metadata['channels'],
34 | buffer_metadata['type'],
35 | buffer_metadata['row_stride']
36 | )
37 |
38 | # Check if buffer is initialized
39 | if buffer_metadata['pointer'] == 0x0:
40 | raise Exception('Invalid null buffer pointer')
41 | if bufsize == 0:
42 | raise Exception('Invalid buffer of zero bytes')
43 | elif bufsize >= sysinfo.get_memory_usage()['free'] / 10:
44 | raise Exception('Invalid buffer size larger than available memory')
45 |
46 | # Check if buffer is valid. If it isn't, this function will throw an
47 | # exception
48 | gdb.execute('x '+str(int(buffer_metadata['pointer'])))
49 |
50 | inferior = gdb.selected_inferior()
51 | buffer_metadata['variable_name'] = variable
52 | buffer_metadata['pointer'] = inferior.read_memory(
53 | buffer_metadata['pointer'], bufsize)
54 |
55 | return buffer_metadata
56 |
57 | def register_event_handlers(self, event_handler):
58 | gdb.events.stop.connect(event_handler.stop_handler)
59 | gdb.events.exited.connect(event_handler.exit_handler)
60 | self._commands['plot'].set_command_listener(event_handler.plot_handler)
61 |
62 | def get_fields_from_type(self, this_type, observable_symbols):
63 | """
64 | Given a class/struct type "this_type", fetch all members of that
65 | particular type and test them against the observable buffer check.
66 | """
67 | for field_name, field_val in this_type.iteritems():
68 | if field_val.is_base_class:
69 | type_fields = self.get_fields_from_type(field_val.type,
70 | observable_symbols)
71 | observable_symbols.update(type_fields)
72 | elif ((field_name not in observable_symbols) and
73 | (self._type_bridge.is_symbol_observable(field_val, field_name))):
74 | try:
75 | observable_symbols.add(field_name)
76 | except Exception:
77 | print('[gdb-imagewatch] Info: Member %s is not observable'
78 | % field_name)
79 | return observable_symbols
80 |
81 | def get_casted_pointer(self, typename, gdb_object):
82 | typename_obj = gdb.lookup_type(typename)
83 | typename_pointer_obj = typename_obj.pointer()
84 | return gdb_object.cast(typename_pointer_obj)
85 |
86 | def get_available_symbols(self):
87 | frame = gdb.selected_frame()
88 | block = frame.block()
89 | observable_symbols = set()
90 |
91 | while block is not None:
92 | for symbol in block:
93 | if symbol.is_argument or symbol.is_variable:
94 | name = symbol.name
95 |
96 | # Get struct/class fields
97 | if name == 'this':
98 | # The GDB API is a bit convoluted, so I have to do some
99 | # contortion in order to get the class type from the
100 | # this object so I can iterate over its fields
101 | this_type = gdb.parse_and_eval(symbol.name) \
102 | .dereference().type
103 | type_fields = self.get_fields_from_type(
104 | this_type,
105 | observable_symbols)
106 | observable_symbols.update(type_fields)
107 | elif ((name not in observable_symbols) and
108 | (self._type_bridge.is_symbol_observable(symbol, name))):
109 | try:
110 | observable_symbols.add(name)
111 | except Exception:
112 | print('[gdb-imagewatch] Info: Field %s is not'
113 | 'observable' % name)
114 |
115 | block = block.superblock
116 |
117 | return observable_symbols
118 |
119 |
120 | class PlotterCommand(gdb.Command):
121 | """
122 | Implements the 'plot' command for the GDB command line mode
123 | """
124 | def __init__(self, gdb_bridge):
125 | super(PlotterCommand, self).__init__("plot",
126 | gdb.COMMAND_DATA,
127 | gdb.COMPLETE_SYMBOL)
128 | self._gdb_bridge = gdb_bridge
129 | self._command_listener = None
130 |
131 | def set_command_listener(self, callback):
132 | """
133 | Called by the GDB bridge in order to configure which callback must be
134 | called when the user calls the function 'plot' in the debugger console.
135 | """
136 | self._command_listener = callback
137 |
138 | def invoke(self, arg, from_tty):
139 | """
140 | Called by GDB whenever the plot command is invoked.
141 | """
142 | args = gdb.string_to_argv(arg)
143 | var_name = str(args[0])
144 |
145 | if self._command_listener is not None:
146 | self._command_listener(var_name)
147 |
--------------------------------------------------------------------------------
/resources/giwscripts/debuggers/interfaces.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Interfaces to be implemented by code that shall interact with the debugger
5 | """
6 |
7 |
8 | class BridgeInterface():
9 | """
10 | This interface defines the methods to be implemented by a debugger bridge
11 | """
12 | def queue_request(self, callable_request):
13 | """
14 | Given a callable object 'callable_request', request the debugger
15 | backend to execute this object in its main execution thread.
16 | If the debugger backend is thread safe (which is not the case for GDB),
17 | this may simply execute the 'callable_request' object.
18 | """
19 | raise NotImplementedError("Method is not implemented")
20 |
21 | def get_buffer_metadata(self, variable):
22 | """
23 | Given a string defining a variable name, must return the following
24 | information about it:
25 |
26 | [mem, width, height, channels, type, step, pixel_layout]
27 | """
28 | raise NotImplementedError("Method is not implemented")
29 |
30 | def register_event_handlers(self, events):
31 | """
32 | Register (callable) listeners to events defined in the dict 'events':
33 | 'stop': When a breakpoint is hit
34 | """
35 | raise NotImplementedError("Method is not implemented")
36 |
37 | def get_casted_pointer(self, typename, debugger_object):
38 | """
39 | Given the string 'typename' specifying any arbitrary type name of the
40 | program being debugger, and an object referring to a pointer object,
41 | this function shall return the corresponding object from the underlying
42 | debugger API corresponding to the cast of the input pointer to a
43 | pointer of the specified type.
44 | """
45 | raise NotImplementedError("Method is not implemented")
46 |
47 | def get_available_symbols(self):
48 | """
49 | Get all visible symbols in the current context of debugging.
50 | """
51 | raise NotImplementedError("Method is not implemented")
52 |
53 |
54 | class BridgeEventHandlerInterface():
55 | """
56 | This interface defines the events that can be raised by the debugger bridge
57 | """
58 | def stop_handler(self, event):
59 | """
60 | Handler to be called whenever the debugger stops (e.g. when a
61 | breakpoint is hit).
62 | """
63 | raise NotImplementedError("Method is not implemented")
64 |
65 | def exit_handler(self, event):
66 | """
67 | Event raised whenever the inferior has exited.
68 | """
69 | raise NotImplementedError("Method is not implemented")
70 |
71 | def refresh_handler(self, event):
72 | """
73 | Handler to be called by the IDE whenever the user performs some action
74 | during a debug session that may require the list of available variables
75 | to change (such as changing position in the stack).
76 | """
77 | raise NotImplementedError("Method is not implemented")
78 |
79 | def plot_handler(self, variable_name):
80 | """
81 | Handler to be called whenever the user actively calls the 'plot'
82 | command from the debugger console.
83 | """
84 | raise NotImplementedError("Method is not implemented")
85 |
--------------------------------------------------------------------------------
/resources/giwscripts/events.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Implementation of handlers for events raised by the debugger
5 | """
6 |
7 | import time
8 |
9 | from giwscripts.debuggers.interfaces import BridgeEventHandlerInterface
10 |
11 |
12 | class GdbImageWatchEvents(BridgeEventHandlerInterface):
13 | """
14 | Handles events raised by the debugger bridge
15 | """
16 | def __init__(self, window, debugger):
17 | self._window = window
18 | self._debugger = debugger
19 |
20 | def _set_symbol_complete_list(self):
21 | """
22 | Retrieve the list of available symbols and provide it to the GIW window
23 | for autocompleting.
24 | """
25 | observable_symbols = list(self._debugger.get_available_symbols())
26 | if self._window.is_ready():
27 | self._window.set_available_symbols(observable_symbols)
28 |
29 | def refresh_handler(self, event):
30 | self._set_symbol_complete_list()
31 |
32 | def exit_handler(self, event):
33 | self._window.terminate()
34 |
35 | def stop_handler(self, event):
36 | """
37 | The debugger has stopped (e.g. a breakpoint was hit). We must list all
38 | available buffers and pass it to the imagewatch window.
39 | """
40 | # Block until the window is up and running
41 | if not self._window.is_ready():
42 | self._window.initialize_window()
43 | while not self._window.is_ready():
44 | time.sleep(0.1)
45 |
46 | # Update buffers being visualized
47 | observed_buffers = self._window.get_observed_buffers()
48 | for buffer_name in observed_buffers:
49 | self._window.plot_variable(buffer_name)
50 |
51 | # Set list of available symbols
52 | self._set_symbol_complete_list()
53 |
54 | def plot_handler(self, variable_name):
55 | """
56 | Command window to plot variable_name if user requests from debugger log
57 | """
58 | self._window.plot_variable(variable_name)
59 |
--------------------------------------------------------------------------------
/resources/giwscripts/giwtypes/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csantosbh/gdb-imagewatch/95853220a5ae55d85cb106eb55e5a5f7b5d5b5b2/resources/giwscripts/giwtypes/__init__.py
--------------------------------------------------------------------------------
/resources/giwscripts/giwtypes/eigen3.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | This module is concerned with the analysis of each variable found by the
5 | debugger, as well as identifying and describing the buffers that should be
6 | plotted in the ImageWatch window.
7 | """
8 |
9 | import re
10 |
11 | from giwscripts import symbols
12 | from giwscripts.giwtypes import interface
13 |
14 |
15 | class EigenXX(interface.TypeInspectorInterface):
16 | """
17 | Implementation for inspecting Eigen::Matrix and Eigen::Map
18 | """
19 | def get_buffer_metadata(self, obj_name, picked_obj, debugger_bridge):
20 | """
21 | Gets the buffer meta data from types of the Eigen Library
22 | Note that it only implements single channel matrix display,
23 | which should be quite common in Eigen.
24 | """
25 |
26 | type_str = str(picked_obj.type)
27 | is_eigen_map = 'Map' in type_str
28 | # First we need the python object for the actual matrix type. When
29 | # parsing a Map, the type is the first template parameter of the
30 | # wrapper type. Otherwise, it is the type field of the picked_obj
31 | if is_eigen_map:
32 | matrix_type_obj = picked_obj.type.template_argument(0)
33 | else:
34 | matrix_type_obj = picked_obj.type
35 |
36 | current_type = str(matrix_type_obj.template_argument(0))
37 | height = int(matrix_type_obj.template_argument(1))
38 | width = int(matrix_type_obj.template_argument(2))
39 | matrix_flag = int(matrix_type_obj.template_argument(3))
40 | transpose_buffer = ((matrix_flag&0x1) == 0)
41 | dynamic_buffer = False
42 |
43 | if height <= 0:
44 | # Buffer has dynamic width
45 | if is_eigen_map:
46 | height = int(picked_obj['m_rows']['m_value'])
47 | else:
48 | height = int(picked_obj['m_storage']['m_rows'])
49 | dynamic_buffer = True
50 |
51 | if width <= 0:
52 | # Buffer has dynamic height
53 | if is_eigen_map:
54 | width = int(picked_obj['m_cols']['m_value'])
55 | else:
56 | width = int(picked_obj['m_storage']['m_cols'])
57 | dynamic_buffer = True
58 |
59 | if transpose_buffer:
60 | width, height = height, width
61 |
62 | # Assign the GIW type according to underlying type
63 | if current_type == 'short':
64 | type_value = symbols.GIW_TYPES_INT16
65 | elif current_type == 'float':
66 | type_value = symbols.GIW_TYPES_FLOAT32
67 | elif current_type == 'double':
68 | type_value = symbols.GIW_TYPES_FLOAT64
69 | elif current_type == 'int':
70 | type_value = symbols.GIW_TYPES_INT32
71 |
72 | # Differentiate between Map and dynamic/static Matrices
73 | if is_eigen_map:
74 | buffer = debugger_bridge.get_casted_pointer(current_type,
75 | picked_obj['m_data'])
76 | elif dynamic_buffer:
77 | buffer = debugger_bridge.get_casted_pointer(
78 | current_type, picked_obj['m_storage'])
79 | else:
80 | buffer = debugger_bridge.get_casted_pointer(
81 | current_type, picked_obj['m_storage']['m_data']['array'])
82 |
83 | if buffer == 0x0:
84 | raise Exception('Received null buffer!')
85 |
86 | # Set row stride and pixel layout
87 | pixel_layout = 'bgra'
88 | row_stride = width
89 |
90 | return {
91 | 'display_name': obj_name + ' (' + str(matrix_type_obj) + ')',
92 | 'pointer': buffer,
93 | 'width': width,
94 | 'height': height,
95 | 'channels': 1,
96 | 'type': type_value,
97 | 'row_stride': row_stride,
98 | 'pixel_layout': pixel_layout,
99 | 'transpose_buffer': transpose_buffer
100 | }
101 |
102 | def is_symbol_observable(self, symbol, symbol_name):
103 | """
104 | Returns true if the given symbol is of observable type (the type of the
105 | buffer you are working with). Make sure to check for pointers of your
106 | type as well
107 | """
108 | # Check if symbol type is the expected buffer
109 | symbol_type = str(symbol.type)
110 | type_regex = r'(const\s+)?Eigen::(\s+?[*&])?'
111 | return re.match(type_regex, symbol_type) is not None
112 |
--------------------------------------------------------------------------------
/resources/giwscripts/giwtypes/interface.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | This module is concerned with the analysis of each variable found by the
5 | debugger, as well as identifying and describing the buffers that should be
6 | plotted in the ImageWatch window.
7 | """
8 |
9 | import abc
10 |
11 | def debug_buffer_metadata(func):
12 | def wrapper(self, obj_name, picked_obj, debugger_bridge):
13 | try:
14 | metadata = func(self, obj_name, picked_obj, debugger_bridge)
15 |
16 | print('[%s] [%s] was parsed by giwtype [%s]' %
17 | (str(picked_obj.type), obj_name, type(self).__name__))
18 | except Exception as error:
19 | print('[%s] [%s] raised exception when parsed by giwtype [%s]:' %
20 | (str(picked_obj.type), obj_name, type(self).__name__))
21 | print(' %s' % str(error))
22 |
23 | raise error
24 |
25 | return wrapper
26 |
27 | def debug_symbol_observable(func):
28 | def wrapper(self, symbol_obj, symbol_name):
29 | is_observable = func(self, symbol_obj, symbol_name)
30 |
31 | if is_observable:
32 | is_observable_str = 'is observable'
33 | else:
34 | is_observable_str = 'is NOT observable'
35 |
36 | print('[' + str(symbol_obj.type) + '] [' + symbol_name + '] ' +
37 | is_observable_str + ' by [' + type(self).__name__ + ']')
38 |
39 | return is_observable
40 |
41 | return wrapper
42 |
43 | class TypeInspectorInterface():
44 | """
45 | This interface defines methods to be implemented by type inspectors that
46 | extract information required for plotting buffers.
47 | """
48 | @abc.abstractmethod
49 | def get_buffer_metadata(self, obj_name, picked_obj, debugger_bridge):
50 | """
51 | Given the variable name obj_name (str), the debugger object with its
52 | internl fields and type picked_obj and the debugger bridge object
53 | debugger_bridge (which implement the methods in
54 | giwscripts.debuggers.interface.BridgeInterface), this method must
55 | return a dict containing the following fields:
56 |
57 | * display_name
58 | * pointer
59 | * width
60 | * height
61 | * channels
62 | * type
63 | * row_stride
64 | * pixel_layout
65 | * transpose_buffer
66 |
67 | For information about these fields, consult the documentation for
68 | giw_plot_buffer in the file $ROOT/src/giw_window.h. The module
69 | giwtypes.opencv shows an example implementation for the OpenCV Mat
70 | type.
71 | """
72 | pass
73 |
74 | @abc.abstractmethod
75 | def is_symbol_observable(self, symbol_obj, symbol_name):
76 | """
77 | Given the debugger with its internal fields and type symbol_obj, and
78 | its name symbol_name, this method must return True if symbol_obj
79 | corresponds to an observable variable (i.e. if its type corresponds to
80 | the type of the buffers that you want to plot).
81 | """
82 | pass
83 |
--------------------------------------------------------------------------------
/resources/giwscripts/giwtypes/opencv.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | This module is concerned with the analysis of each variable found by the
5 | debugger, as well as identifying and describing the buffers that should be
6 | plotted in the ImageWatch window.
7 | """
8 |
9 | import re
10 |
11 | from giwscripts import symbols
12 | from giwscripts.giwtypes import interface
13 |
14 |
15 | # OpenCV constants
16 | CV_CN_MAX = 512
17 | CV_CN_SHIFT = 3
18 | CV_MAT_CN_MASK = ((CV_CN_MAX - 1) << CV_CN_SHIFT)
19 | CV_DEPTH_MAX = (1 << CV_CN_SHIFT)
20 | CV_MAT_TYPE_MASK = (CV_DEPTH_MAX * CV_CN_MAX - 1)
21 |
22 |
23 | class Mat(interface.TypeInspectorInterface):
24 | """
25 | Implementation for inspecting OpenCV Mat classes
26 | """
27 | def get_buffer_metadata(self, obj_name, picked_obj, debugger_bridge):
28 | buffer = debugger_bridge.get_casted_pointer('char', picked_obj['data'])
29 | if buffer == 0x0:
30 | raise Exception('Received null buffer!')
31 |
32 | width = int(picked_obj['cols'])
33 | height = int(picked_obj['rows'])
34 | flags = int(picked_obj['flags'])
35 |
36 | channels = ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
37 | row_stride = int(int(picked_obj['step']['buf'][0])/channels)
38 |
39 | if channels >= 3:
40 | pixel_layout = 'bgra'
41 | else:
42 | pixel_layout = 'rgba'
43 |
44 | cvtype = ((flags) & CV_MAT_TYPE_MASK)
45 |
46 | type_value = (cvtype & 7)
47 |
48 | if (type_value == symbols.GIW_TYPES_UINT16 or
49 | type_value == symbols.GIW_TYPES_INT16):
50 | row_stride = int(row_stride / 2)
51 | elif (type_value == symbols.GIW_TYPES_INT32 or
52 | type_value == symbols.GIW_TYPES_FLOAT32):
53 | row_stride = int(row_stride / 4)
54 | elif type_value == symbols.GIW_TYPES_FLOAT64:
55 | row_stride = int(row_stride / 8)
56 |
57 | return {
58 | 'display_name': obj_name + ' (' + str(picked_obj.type) + ')',
59 | 'pointer': buffer,
60 | 'width': width,
61 | 'height': height,
62 | 'channels': channels,
63 | 'type': type_value,
64 | 'row_stride': row_stride,
65 | 'pixel_layout': pixel_layout,
66 | 'transpose_buffer' : False
67 | }
68 |
69 | def is_symbol_observable(self, symbol, symbol_name):
70 | """
71 | Returns true if the given symbol is of observable type (the type of the
72 | buffer you are working with). Make sure to check for pointers of your
73 | type as well
74 | """
75 | # Check if symbol type is the expected buffer
76 | symbol_type = str(symbol.type)
77 | type_regex = r'(const\s+)?cv::Mat(\s+?[*&])?'
78 | return re.match(type_regex, symbol_type) is not None
79 |
80 | class CvMat(interface.TypeInspectorInterface):
81 | """
82 | Implementation for inspecting OpenCV CvMat structs
83 | """
84 | def get_buffer_metadata(self, obj_name, picked_obj, debugger_bridge):
85 | buffer = debugger_bridge.get_casted_pointer('char', picked_obj['data'])
86 | if buffer == 0x0:
87 | raise Exception('Received null buffer!')
88 |
89 | width = int(picked_obj['cols'])
90 | height = int(picked_obj['rows'])
91 | flags = int(picked_obj['type'])
92 |
93 | channels = ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
94 | row_stride = int(int(picked_obj['step'])/channels)
95 |
96 | if channels >= 3:
97 | pixel_layout = 'bgra'
98 | else:
99 | pixel_layout = 'rgba'
100 |
101 | cvtype = ((flags) & CV_MAT_TYPE_MASK)
102 |
103 | type_value = (cvtype & 7)
104 |
105 | if (type_value == symbols.GIW_TYPES_UINT16 or
106 | type_value == symbols.GIW_TYPES_INT16):
107 | row_stride = int(row_stride / 2)
108 | elif (type_value == symbols.GIW_TYPES_INT32 or
109 | type_value == symbols.GIW_TYPES_FLOAT32):
110 | row_stride = int(row_stride / 4)
111 | elif type_value == symbols.GIW_TYPES_FLOAT64:
112 | row_stride = int(row_stride / 8)
113 |
114 | return {
115 | 'display_name': obj_name + ' (' + str(picked_obj.type) + ')',
116 | 'pointer': buffer,
117 | 'width': width,
118 | 'height': height,
119 | 'channels': channels,
120 | 'type': type_value,
121 | 'row_stride': row_stride,
122 | 'pixel_layout': pixel_layout,
123 | 'transpose_buffer': False
124 | }
125 |
126 | def is_symbol_observable(self, symbol, symbol_name):
127 | symbol_type = str(symbol.type)
128 | type_regex = r'(const\s+)?CvMat(\s+?[*&])?'
129 | return re.match(type_regex, symbol_type) is not None
130 |
--------------------------------------------------------------------------------
/resources/giwscripts/giwwindow.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Classes related to exposing an interface to the ImageWatch window
5 | """
6 |
7 | import ctypes
8 | import ctypes.util
9 | import signal
10 | import threading
11 |
12 | from giwscripts.thirdparty.pysigset import pysigset
13 |
14 |
15 | FETCH_BUFFER_CBK_TYPE = ctypes.CFUNCTYPE(ctypes.c_int,
16 | ctypes.c_char_p)
17 |
18 |
19 | class GdbImageWatchWindow():
20 | """
21 | Python interface for the imagewatch window, which is implemented as a
22 | shared library.
23 | """
24 | def __init__(self, script_path, bridge):
25 | self._bridge = bridge
26 |
27 | # Request ctypes to load libGL before the native giwwindow does; this
28 | # fixes an issue on Ubuntu machines with nvidia drivers. For more
29 | # information, please refer to
30 | # https://github.com/csantosbh/gdb-imagewatch/issues/28
31 | ctypes.CDLL(ctypes.util.find_library('GL'), ctypes.RTLD_GLOBAL)
32 |
33 | # Load imagewatch library and set up its API
34 | self._lib = ctypes.cdll.LoadLibrary(
35 | script_path + '/libgiwwindow.so')
36 |
37 | # libgiw API
38 | self._lib.giw_initialize.argtypes = []
39 | self._lib.giw_initialize.restype = ctypes.c_void_p
40 |
41 | self._lib.giw_cleanup.argtypes = [ctypes.c_void_p]
42 | self._lib.giw_cleanup.restype = None
43 |
44 | self._lib.giw_terminate.argtypes = []
45 | self._lib.giw_terminate.restype = None
46 |
47 | self._lib.giw_exec.argtypes = [ctypes.c_void_p]
48 | self._lib.giw_exec.restype = None
49 |
50 | self._lib.giw_create_window.argtypes = [FETCH_BUFFER_CBK_TYPE]
51 | self._lib.giw_create_window.restype = ctypes.c_void_p
52 |
53 | self._lib.giw_destroy_window.argtypes = [ctypes.c_void_p]
54 | self._lib.giw_destroy_window.restype = ctypes.c_int
55 |
56 | self._lib.giw_is_window_ready.argtypes = [ctypes.c_void_p]
57 | self._lib.giw_is_window_ready.restype = ctypes.c_bool
58 |
59 | self._lib.giw_get_observed_buffers.argtypes = [ctypes.c_void_p]
60 | self._lib.giw_get_observed_buffers.restype = ctypes.py_object
61 |
62 | self._lib.giw_set_available_symbols.argtypes = [
63 | ctypes.c_void_p,
64 | ctypes.py_object
65 | ]
66 | self._lib.giw_set_available_symbols.restype = None
67 |
68 | self._lib.giw_plot_buffer.argtypes = [
69 | ctypes.c_void_p,
70 | ctypes.py_object
71 | ]
72 | self._lib.giw_plot_buffer.restype = None
73 |
74 | # UI handler
75 | self._window_handler = None
76 |
77 | def plot_variable(self, requested_symbol):
78 | """
79 | Plot a variable whose name is 'requested_symbol'.
80 |
81 | This will result in the creation of a callable object of type
82 | DeferredVariablePlotter, where the actual code for plotting the buffer
83 | will be executed. This object will be given to the debugger bridge so
84 | that it can schedule its execution in a thread safe context.
85 | """
86 | if self._bridge is None:
87 | print('[gdb-imagewatch] Could not plot symbol %s: Not a debugging'
88 | ' session.' % requested_symbol)
89 | return 0
90 |
91 | try:
92 | if not isinstance(requested_symbol, str):
93 | variable = requested_symbol.decode('utf-8')
94 | else:
95 | variable = requested_symbol
96 |
97 | plot_callable = DeferredVariablePlotter(variable,
98 | self._lib,
99 | self._bridge,
100 | self._window_handler)
101 | self._bridge.queue_request(plot_callable)
102 | return 1
103 | except Exception as err:
104 | print('[gdb-imagewatch] Error: Could not plot variable')
105 | print(err)
106 |
107 | return 0
108 |
109 | def is_ready(self):
110 | """
111 | Returns True if the ImageWatch window has been loaded; False otherwise.
112 | """
113 | if self._window_handler is None:
114 | return False
115 |
116 | return self._lib.giw_is_window_ready(self._window_handler)
117 |
118 | def terminate(self):
119 | """
120 | Request GIW to terminate application and close all windows
121 | """
122 | self._lib.giw_terminate()
123 |
124 | def set_available_symbols(self, observable_symbols):
125 | """
126 | Set the autocomplete list of symbols with the list of string
127 | 'observable_symbols'
128 | """
129 | self._lib.giw_set_available_symbols(
130 | self._window_handler,
131 | observable_symbols)
132 |
133 | def get_observed_buffers(self):
134 | """
135 | Get a list with the currently observed symbols in the giw window
136 | """
137 | return self._lib.giw_get_observed_buffers(self._window_handler)
138 |
139 | def _ui_thread(self, plot_callback):
140 | # Initialize GIW lib
141 | app_handler = self._lib.giw_initialize()
142 | self._window_handler = self._lib.giw_create_window(plot_callback)
143 | # Run UI loop
144 | self._lib.giw_exec(app_handler)
145 | # Cleanup GIW lib
146 | self._lib.giw_destroy_window(self._window_handler)
147 | self._lib.giw_cleanup(app_handler)
148 |
149 | def initialize_window(self):
150 | """
151 | Launch the ImageWatch window.
152 | """
153 | ##
154 | # Initialize imagewatch window
155 | with pysigset.suspended_signals(signal.SIGCHLD):
156 | # By default, my new threads will be the ones receiving the
157 | # precious signals from the operating system. These signals should
158 | # go to GDB so it could do its thing, and since it doesnt get them,
159 | # my thread will make gdb hang. The solution is to configure the
160 | # new thread to forward the signal back to the main thread, which
161 | # is done by pysigset.
162 | wnd_thread_instance = threading.Thread(
163 | target=self._ui_thread,
164 | args=(FETCH_BUFFER_CBK_TYPE(self.plot_variable),)
165 | )
166 | wnd_thread_instance.daemon = True
167 | wnd_thread_instance.start()
168 |
169 |
170 | class DeferredVariablePlotter():
171 | """
172 | Instances of this class are callable objects whose __call__ method triggers
173 | a buffer plot command. Useful for deferring the plot command to a safe
174 | thread.
175 | """
176 | def __init__(self, variable, lib, bridge, window_handler):
177 | self._variable = variable
178 | self._lib = lib
179 | self._bridge = bridge
180 | self._window_handler = window_handler
181 |
182 | def __call__(self):
183 | try:
184 | buffer_metadata = self._bridge.get_buffer_metadata(self._variable)
185 |
186 | if buffer_metadata is not None:
187 | self._lib.giw_plot_buffer(
188 | self._window_handler,
189 | buffer_metadata)
190 | except Exception as err:
191 | import traceback
192 | print('[gdb-imagewatch] Error: Could not plot variable')
193 | print(err)
194 | traceback.print_exc()
195 |
--------------------------------------------------------------------------------
/resources/giwscripts/ides/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csantosbh/gdb-imagewatch/95853220a5ae55d85cb106eb55e5a5f7b5d5b5b2/resources/giwscripts/ides/__init__.py
--------------------------------------------------------------------------------
/resources/giwscripts/ides/qtcreator.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | QtCreator integration module.
5 | """
6 |
7 |
8 | def register_symbol_fetch_hook(retrieve_symbols_callback):
9 | """
10 | Hacks into Dumper and changes its fetchVariables method to a wrapper that
11 | calls stop_event_handler. This allows us to retrieve the list of locals
12 | every time the user changes the local stack frame during a debug session
13 | from QtCreator interface.
14 | """
15 | try:
16 | imp = __import__('gdbbridge')
17 |
18 | original_fetch_variables = None
19 |
20 | def fetch_variables_wrapper(self, args):
21 | """
22 | Acts as a proxy to QTCreator 'fetchVariables' method, calling the
23 | event handler 'stop' method everytime 'fetchVariables' is called.
24 | """
25 | ret = original_fetch_variables(self, args)
26 |
27 | retrieve_symbols_callback(None)
28 |
29 | return ret
30 |
31 | original_fetch_variables = imp.Dumper.fetchVariables
32 | imp.Dumper.fetchVariables = fetch_variables_wrapper
33 | return True
34 |
35 | except Exception as err:
36 | print('[gdb-imagewatch] Error: Exception thrown in qtcreator'
37 | ' integration module')
38 | print(err)
39 | return False
40 |
--------------------------------------------------------------------------------
/resources/giwscripts/symbols.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Definition of global constants and symbols.
5 | """
6 |
7 | # Enum values for supported buffer types
8 | GIW_TYPES_UINT8 = 0
9 | GIW_TYPES_UINT16 = 2
10 | GIW_TYPES_INT16 = 3
11 | GIW_TYPES_INT32 = 4
12 | GIW_TYPES_FLOAT32 = 5
13 | GIW_TYPES_FLOAT64 = 6
14 |
--------------------------------------------------------------------------------
/resources/giwscripts/sysinfo.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | System and memory related methods
5 | """
6 |
7 | from giwscripts import symbols
8 |
9 |
10 | def get_memory_usage():
11 | """
12 | Get node total memory and memory usage, in bytes
13 | """
14 | with open('/proc/meminfo', 'r') as mem:
15 | ret = {}
16 | tmp = 0
17 | for i in mem:
18 | sline = i.split()
19 | if str(sline[0]) == 'MemTotal:':
20 | ret['total'] = int(sline[1]) * 1024
21 | elif str(sline[0]) in ('MemFree:', 'Buffers:', 'Cached:'):
22 | tmp += int(sline[1]) * 1024
23 | ret['free'] = tmp
24 | ret['used'] = int(ret['total']) - int(ret['free'])
25 | return ret
26 |
27 |
28 | def get_buffer_size(height, channels, typevalue, rowstride):
29 | """
30 | Compute the buffer size in bytes
31 | """
32 | channel_size = 1
33 | if (typevalue == symbols.GIW_TYPES_UINT16 or
34 | typevalue == symbols.GIW_TYPES_INT16):
35 | channel_size = 2 # 2 bytes per element
36 | elif (typevalue == symbols.GIW_TYPES_INT32 or
37 | typevalue == symbols.GIW_TYPES_FLOAT32):
38 | channel_size = 4 # 4 bytes per element
39 | elif typevalue == symbols.GIW_TYPES_FLOAT64:
40 | channel_size = 8 # 8 bytes per element
41 |
42 | return channel_size * channels * rowstride * height
43 |
--------------------------------------------------------------------------------
/resources/giwscripts/test.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | Module developed for quick testing the ImageWatch shared library
5 | """
6 |
7 | import math
8 | import time
9 | import threading
10 | import queue
11 | import array
12 |
13 | from giwscripts import giwwindow
14 | from giwscripts import symbols
15 | from giwscripts.debuggers.interfaces import BridgeInterface
16 |
17 |
18 | def giwtest(script_path):
19 | """
20 | Entry point for the testing mode.
21 | """
22 |
23 | dummy_debugger = DummyDebugger()
24 |
25 | window = giwwindow.GdbImageWatchWindow(script_path, dummy_debugger)
26 | window.initialize_window()
27 |
28 | try:
29 | # Wait for window to initialize
30 | while not window.is_ready():
31 | time.sleep(0.1)
32 |
33 | window.set_available_symbols(dummy_debugger.get_available_symbols())
34 |
35 | for buffer in dummy_debugger.get_available_symbols():
36 | window.plot_variable(buffer)
37 |
38 | while window.is_ready():
39 | time.sleep(0.5)
40 |
41 | except KeyboardInterrupt:
42 | window.terminate()
43 | exit(0)
44 |
45 | dummy_debugger.kill()
46 |
47 |
48 | def _gen_color(pos, k, f_a, f_b):
49 | """
50 | Generates a color for the pixel at (pos[0], pos[1]) with coefficients k[0]
51 | and k[1], and colouring functions f_a and f_b that map R->[-1, 1].
52 | """
53 | return (f_a(pos[0] * f_b(pos[1]/k[0])/k[1]) + 1) * 255 / 2
54 |
55 |
56 | def _gen_buffers(width, height):
57 | """
58 | Generate sample buffers
59 | """
60 | channels = [3, 1]
61 |
62 | types = [{'array': 'B', 'giw': symbols.GIW_TYPES_UINT8},
63 | {'array': 'f', 'giw': symbols.GIW_TYPES_FLOAT32}]
64 |
65 | tex1 = [0] * width * height * channels[0]
66 | tex2 = [0] * width * height * channels[1]
67 |
68 | c_x = width * 2.0 / 3.0
69 | c_y = height * 0.5
70 | scale = 3.0 / width
71 |
72 | for pos_y in range(0, height):
73 | for pos_x in range(0, width):
74 | # Buffer 1: Coloured set
75 | pixel_pos = [pos_x, pos_y]
76 |
77 | buffer_pos = pos_y * channels[0] * width + channels[0] * pos_x
78 |
79 | tex1[buffer_pos + 0] = _gen_color(
80 | pixel_pos, [20, 80], math.cos, math.cos)
81 | tex1[buffer_pos + 1] = _gen_color(
82 | pixel_pos, [50, 200], math.sin, math.cos)
83 | tex1[buffer_pos + 2] = _gen_color(
84 | pixel_pos, [30, 120], math.cos, math.cos)
85 |
86 | # Buffer 2: Mandelbrot set
87 | pixel_pos = complex((pos_x-c_x), (pos_y-c_y)) * scale
88 | buffer_pos = pos_y * channels[1] * width + channels[1] * pos_x
89 |
90 | mandel_z = complex(0, 0)
91 | for _ in range(0, 20):
92 | mandel_z = mandel_z * mandel_z + pixel_pos
93 |
94 | z_norm_squared = mandel_z.real * mandel_z.real +\
95 | mandel_z.imag * mandel_z.imag
96 | z_threshold = 5.0
97 |
98 | for channel in range(0, channels[1]):
99 | tex2[buffer_pos + channel] = z_threshold - min(z_threshold,
100 | z_norm_squared)
101 |
102 | tex_arr1 = array.array(types[0]['array'], [int(val) for val in tex1])
103 | tex_arr2 = array.array(types[1]['array'], tex2)
104 | mem1 = memoryview(tex_arr1)
105 | mem2 = memoryview(tex_arr2)
106 | rowstride = width
107 |
108 | return {
109 | 'sample_buffer_1': {
110 | 'variable_name': 'sample_buffer_1',
111 | 'display_name': 'uint8* sample_buffer_1',
112 | 'pointer': mem1,
113 | 'width': width,
114 | 'height': height,
115 | 'channels': channels[0],
116 | 'type': types[0]['giw'],
117 | 'row_stride': rowstride,
118 | 'pixel_layout': 'rgba',
119 | 'transpose_buffer': False
120 | },
121 | 'sample_buffer_2': {
122 | 'variable_name': 'sample_buffer_2',
123 | 'display_name': 'float* sample_buffer_2',
124 | 'pointer': mem2,
125 | 'width': width,
126 | 'height': height,
127 | 'channels': channels[1],
128 | 'type': types[1]['giw'],
129 | 'row_stride': rowstride,
130 | 'pixel_layout': 'rgba',
131 | 'transpose_buffer': False
132 | }
133 | }
134 |
135 |
136 | class DummyDebugger(BridgeInterface):
137 | """
138 | Very simple implementation of a debugger bridge for the sake of the test
139 | mode.
140 | """
141 | def __init__(self):
142 | width = 400
143 | height = 200
144 | self._buffers = _gen_buffers(width, height)
145 | self._buffer_names = [name for name in self._buffers]
146 |
147 | self._is_running = True
148 | self._request_queue = queue.Queue()
149 | self._request_consumer_thread = threading.Thread(
150 | target=self._request_consumer,
151 | daemon=True)
152 | self._request_consumer_thread.start()
153 |
154 | def _request_consumer(self):
155 | while self._is_running:
156 | latest_request = self._request_queue.get(block=True, timeout=None)
157 | latest_request()
158 |
159 | def kill(self):
160 | """
161 | Request consumer thread to finish its execution
162 | """
163 | self._is_running = False
164 |
165 | def get_casted_pointer(self, typename, debugger_object):
166 | """
167 | No need to cast anything in this example
168 | """
169 | return debugger_object
170 |
171 | def register_event_handlers(self, events):
172 | """
173 | No need to register events in this example
174 | """
175 | pass
176 |
177 | def get_available_symbols(self):
178 | """
179 | Return the names of the available sample buffers
180 | """
181 | return self._buffer_names
182 |
183 | def get_buffer_metadata(self, var_name):
184 | """
185 | Search in the list of available buffers and return the requested one
186 | """
187 | if var_name in self._buffers:
188 | return self._buffers[var_name]
189 |
190 | return None
191 |
192 | def queue_request(self, callable_request):
193 | self._request_queue.put(callable_request)
194 |
--------------------------------------------------------------------------------
/resources/giwscripts/typebridge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | """
4 | This module is the bridge between all type modules defined in giwtypes and the
5 | debugger. For every symbol found by the debugger, this module queries for a
6 | candidate giwtype and forwards the required calls from the debugger to it.
7 | """
8 |
9 | import importlib
10 | import pkgutil
11 |
12 | from giwscripts import giwtypes
13 | from giwscripts.giwtypes.interface import TypeInspectorInterface
14 |
15 |
16 | class TypeBridge:
17 | """
18 | Class responsible for loading and interfacing with all modules implementing
19 | the TypeInspectorInterface
20 | """
21 | def __init__(self):
22 | self._type_inspectors = []
23 |
24 | # Import all modules within giwtypes
25 | for (_, mod_name, _) in pkgutil.iter_modules(giwtypes.__path__):
26 | importlib.import_module('.giwtypes.' + mod_name, __package__)
27 |
28 | # Save instances of all TypeInspector implementations
29 | for inspector_class in TypeInspectorInterface.__subclasses__():
30 | self._type_inspectors.append(inspector_class())
31 |
32 | def get_buffer_metadata(self, symbol_name, picked_obj, debugger_bridge):
33 | """
34 | Returns the metadata related to a variable, which are required for the
35 | purpose of plotting it in the giwwindow
36 | """
37 | for module in self._type_inspectors:
38 | if module.is_symbol_observable(picked_obj, symbol_name):
39 | return module.get_buffer_metadata(symbol_name,
40 | picked_obj,
41 | debugger_bridge)
42 |
43 | return None
44 |
45 | def is_symbol_observable(self, symbol_obj, symbol_name):
46 | """
47 | Returns true if any available module is able to process this particular
48 | symbol
49 | """
50 | for module in self._type_inspectors:
51 | if module.is_symbol_observable(symbol_obj, symbol_name):
52 | return True
53 |
54 | return False
55 |
--------------------------------------------------------------------------------
/resources/icons/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Font license info
2 |
3 |
4 | ## Typicons
5 |
6 | (c) Stephen Hutchings 2012
7 |
8 | Author: Stephen Hutchings
9 | License: SIL (http://scripts.sil.org/OFL)
10 | Homepage: http://typicons.com/
11 |
12 |
13 | ## Font Awesome
14 |
15 | Copyright (C) 2016 by Dave Gandy
16 |
17 | Author: Dave Gandy
18 | License: SIL ()
19 | Homepage: http://fortawesome.github.com/Font-Awesome/
20 |
21 |
22 | ## Entypo
23 |
24 | Copyright (C) 2012 by Daniel Bruce
25 |
26 | Author: Daniel Bruce
27 | License: SIL (http://scripts.sil.org/OFL)
28 | Homepage: http://www.entypo.com
29 |
30 |
31 | ## MFG Labs
32 |
33 | Copyright (C) 2012 by Daniel Bruce
34 |
35 | Author: MFG Labs
36 | License: SIL (http://scripts.sil.org/OFL)
37 | Homepage: http://www.mfglabs.com/
38 |
39 |
40 |
--------------------------------------------------------------------------------
/resources/icons/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "css_prefix_text": "icon-",
4 | "css_use_suffix": false,
5 | "hinting": true,
6 | "units_per_em": 1000,
7 | "ascent": 850,
8 | "glyphs": [
9 | {
10 | "uid": "8d2bc2d959a55e76466bbef6e84c8373",
11 | "css": "resize-normal",
12 | "code": 59392,
13 | "src": "typicons"
14 | },
15 | {
16 | "uid": "bc71f4c6e53394d5ba46b063040014f1",
17 | "css": "cw",
18 | "code": 59393,
19 | "src": "fontawesome"
20 | },
21 | {
22 | "uid": "f9c3205df26e7778abac86183aefdc99",
23 | "css": "ccw",
24 | "code": 59394,
25 | "src": "fontawesome"
26 | },
27 | {
28 | "uid": "ccddff8e8670dcd130e3cb55fdfc2fd0",
29 | "css": "down-open",
30 | "code": 59395,
31 | "src": "fontawesome"
32 | },
33 | {
34 | "uid": "ca90da02d2c6a3183f2458e4dc416285",
35 | "css": "adjust",
36 | "code": 59396,
37 | "src": "fontawesome"
38 | },
39 | {
40 | "uid": "0ddd3e8201ccc7d41f7b7c9d27eca6c1",
41 | "css": "link",
42 | "code": 59397,
43 | "src": "fontawesome"
44 | },
45 | {
46 | "uid": "e8239f8188c76c925be4bd1bbcc013ac",
47 | "css": "erase",
48 | "code": 59400,
49 | "src": "entypo"
50 | },
51 | {
52 | "uid": "291e2e127efe7a6bc580af6d3ead3771",
53 | "css": "location",
54 | "code": 61489,
55 | "src": "mfglabs"
56 | }
57 | ]
58 | }
--------------------------------------------------------------------------------
/resources/icons/fontello.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csantosbh/gdb-imagewatch/95853220a5ae55d85cb106eb55e5a5f7b5d5b5b2/resources/icons/fontello.ttf
--------------------------------------------------------------------------------
/resources/icons/label_alpha_channel.svg:
--------------------------------------------------------------------------------
1 |
2 |
113 |
--------------------------------------------------------------------------------
/resources/icons/label_blue_channel.svg:
--------------------------------------------------------------------------------
1 |
2 |
79 |
--------------------------------------------------------------------------------
/resources/icons/label_green_channel.svg:
--------------------------------------------------------------------------------
1 |
2 |
73 |
--------------------------------------------------------------------------------
/resources/icons/label_red_channel.svg:
--------------------------------------------------------------------------------
1 |
2 |
73 |
--------------------------------------------------------------------------------
/resources/icons/lower_upper_bound.svg:
--------------------------------------------------------------------------------
1 |
2 |
93 |
--------------------------------------------------------------------------------
/resources/icons/x.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
69 |
--------------------------------------------------------------------------------
/resources/icons/y.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
69 |
--------------------------------------------------------------------------------
/resources/matlab/giw_load.m:
--------------------------------------------------------------------------------
1 | %%
2 | % Loads a binary file saved from gdb-imagewatch.
3 |
4 | function buffer = giw_load(fname)
5 |
6 | fid = fopen(fname, 'r');
7 |
8 | type = fgets(fid);
9 | dimensions = fread(fid, 3, 'int32')';
10 |
11 | buffer = fread(fid, prod(dimensions), type(1:length(type)-1));
12 |
13 | rows = dimensions(1);
14 | cols = dimensions(2);
15 | channels = dimensions(3);
16 |
17 | buffer_t = reshape(reshape(buffer, channels, rows*cols)', [cols,rows,channels]);
18 |
19 | buffer = zeros(dimensions);
20 | for c = 1:channels
21 | buffer(:, :, c) = buffer_t(:, :, c)';
22 | end
23 |
24 | fclose(fid);
25 |
26 |
--------------------------------------------------------------------------------
/resources/resources.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | icons/fontello.ttf
4 | icons/label_red_channel.svg
5 | icons/label_green_channel.svg
6 | icons/label_blue_channel.svg
7 | icons/label_alpha_channel.svg
8 | icons/lower_upper_bound.svg
9 | icons/x.svg
10 | icons/y.svg
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/.clang-format:
--------------------------------------------------------------------------------
1 | BinPackParameters: false
2 | AllowAllParametersOfDeclarationOnNextLine: false
3 | ColumnLimit: 80
4 | IndentWidth: 4
5 | UseTab: Never
6 | AlignConsecutiveAssignments: true
7 | PointerBindsToType: true
8 | Cpp11BracedListStyle: true
9 | AlignAfterOpenBracket: Align
10 | AlignEscapedNewlinesLeft: true
11 | AllowShortBlocksOnASingleLine: false
12 | AllowShortCaseLabelsOnASingleLine: false
13 | AllowShortFunctionsOnASingleLine: false
14 | BinPackArguments: false
15 | AlwaysBreakTemplateDeclarations: true
16 | AllowShortFunctionsOnASingleLine: false
17 | AllowShortCaseLabelsOnASingleLine: false
18 | AllowShortBlocksOnASingleLine: false
19 | AlignOperands: true
20 | BraceWrapping:
21 | AfterFunction: true
22 | AfterNamespace: true
23 | AfterClass: true
24 | AfterStruct: true
25 | AfterUnion: true
26 | BreakBeforeBraces: Custom
27 | MaxEmptyLinesToKeep: 2
28 | SortIncludes: true
29 | SpaceBeforeAssignmentOperators: true
30 | BreakConstructorInitializers: BeforeComma
31 |
--------------------------------------------------------------------------------
/src/debuggerinterface/buffer_request_message.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include "buffer_request_message.h"
27 |
28 |
29 | void copy_py_string(std::string& dst, PyObject* src)
30 | {
31 | if (PyUnicode_Check(src)) {
32 | // Unicode sring
33 | PyObject* src_bytes = PyUnicode_AsEncodedString(src, "ASCII", "strict");
34 | dst = PyBytes_AS_STRING(src_bytes);
35 | Py_DECREF(src_bytes);
36 | } else {
37 | assert(PyBytes_Check(src));
38 | dst = PyBytes_AS_STRING(src);
39 | }
40 | }
41 |
42 |
43 | BufferRequestMessage::BufferRequestMessage(const BufferRequestMessage& buff)
44 | : py_buffer(buff.py_buffer)
45 | , variable_name_str(buff.variable_name_str)
46 | , display_name_str(buff.display_name_str)
47 | , width_i(buff.width_i)
48 | , height_i(buff.height_i)
49 | , channels(buff.channels)
50 | , type(buff.type)
51 | , step(buff.step)
52 | , pixel_layout(buff.pixel_layout)
53 | , transpose_buffer(buff.transpose_buffer)
54 | {
55 | Py_INCREF(py_buffer);
56 | }
57 |
58 |
59 | BufferRequestMessage::BufferRequestMessage(PyObject* pybuffer,
60 | PyObject* variable_name,
61 | PyObject* display_name,
62 | int buffer_width_i,
63 | int buffer_height_i,
64 | int channels,
65 | int type,
66 | int step,
67 | PyObject* pixel_layout,
68 | bool transpose)
69 | : py_buffer(pybuffer)
70 | , width_i(buffer_width_i)
71 | , height_i(buffer_height_i)
72 | , channels(channels)
73 | , type(static_cast(type))
74 | , step(step)
75 | , transpose_buffer(transpose)
76 | {
77 | Py_INCREF(py_buffer);
78 |
79 | copy_py_string(this->variable_name_str, variable_name);
80 | copy_py_string(this->display_name_str, display_name);
81 | copy_py_string(this->pixel_layout, pixel_layout);
82 | }
83 |
84 |
85 | BufferRequestMessage::~BufferRequestMessage()
86 | {
87 | Py_DECREF(py_buffer);
88 | }
89 |
90 |
91 | int BufferRequestMessage::get_visualized_width() const
92 | {
93 | if (!transpose_buffer) {
94 | return width_i;
95 | } else {
96 | return height_i;
97 | }
98 | }
99 |
100 |
101 | int BufferRequestMessage::get_visualized_height() const
102 | {
103 | if (!transpose_buffer) {
104 | return height_i;
105 | } else {
106 | return width_i;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/debuggerinterface/buffer_request_message.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef BUFFER_REQUEST_MESSAGE_H_
27 | #define BUFFER_REQUEST_MESSAGE_H_
28 |
29 | #include
30 |
31 | #include
32 |
33 | #include "visualization/components/buffer.h"
34 |
35 |
36 | void copy_py_string(std::string& dst, PyObject* src);
37 |
38 | struct BufferRequestMessage
39 | {
40 | PyObject* py_buffer;
41 | std::string variable_name_str;
42 | std::string display_name_str;
43 | int width_i;
44 | int height_i;
45 | int channels;
46 | Buffer::BufferType type;
47 | int step;
48 | std::string pixel_layout;
49 | bool transpose_buffer;
50 |
51 | BufferRequestMessage(const BufferRequestMessage& buff);
52 |
53 | BufferRequestMessage(PyObject* pybuffer,
54 | PyObject* variable_name,
55 | PyObject* display_name,
56 | int buffer_width_i,
57 | int buffer_height_i,
58 | int channels,
59 | int type,
60 | int step,
61 | PyObject* pixel_layout,
62 | bool transpose);
63 |
64 | ~BufferRequestMessage();
65 |
66 | BufferRequestMessage() = delete;
67 |
68 | BufferRequestMessage& operator=(const BufferRequestMessage&) = delete;
69 |
70 | /**
71 | * Returns buffer width taking into account its transposition flag
72 | */
73 | int get_visualized_width() const;
74 |
75 | /**
76 | * Returns buffer height taking into account its transposition flag
77 | */
78 | int get_visualized_height() const;
79 | };
80 |
81 | #endif // BUFFER_REQUEST_MESSAGE_H_
82 |
--------------------------------------------------------------------------------
/src/debuggerinterface/managed_pointer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include
27 |
28 | #include "managed_pointer.h"
29 |
30 |
31 | using namespace std;
32 |
33 |
34 | shared_ptr make_shared_py_object(PyObject* obj)
35 | {
36 | Py_INCREF(obj);
37 |
38 | return shared_ptr(
39 | reinterpret_cast(obj),
40 | [](uint8_t* obj) { Py_DECREF(reinterpret_cast(obj)); });
41 | }
42 |
43 |
44 | shared_ptr make_float_buffer_from_double(double* buff, int length)
45 | {
46 | shared_ptr result(
47 | reinterpret_cast(new float[length]),
48 | [](uint8_t* buff) { delete[] reinterpret_cast(buff); });
49 |
50 | // Cast from double to float
51 | float* dst = reinterpret_cast(result.get());
52 | for (int i = 0; i < length; ++i) {
53 | dst[i] = static_cast(buff[i]);
54 | }
55 |
56 | return result;
57 | }
58 |
--------------------------------------------------------------------------------
/src/debuggerinterface/managed_pointer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef MANAGED_POINTER_H_
27 | #define MANAGED_POINTER_H_
28 |
29 | #include
30 |
31 | #include
32 |
33 |
34 | std::shared_ptr make_shared_py_object(PyObject* obj);
35 |
36 | std::shared_ptr make_float_buffer_from_double(double* buff,
37 | int length);
38 |
39 | #endif // MANAGED_POINTER_H_
40 |
--------------------------------------------------------------------------------
/src/debuggerinterface/preprocessor_directives.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef PREPROCESSOR_DIRECTIVES_H_
27 | #define PREPROCESSOR_DIRECTIVES_H_
28 |
29 | #define RAISE_PY_EXCEPTION(exception_type, msg) \
30 | PyGILState_STATE gstate = PyGILState_Ensure(); \
31 | PyErr_SetString(exception_type, msg); \
32 | PyGILState_Release(gstate);
33 |
34 |
35 | #define RAISE_PY_EXCEPTION(exception_type, msg) \
36 | PyGILState_STATE gstate = PyGILState_Ensure(); \
37 | PyErr_SetString(exception_type, msg); \
38 | PyGILState_Release(gstate);
39 |
40 |
41 | #define CHECK_FIELD_PROVIDED(name, current_ctx_name) \
42 | if (py_##name == nullptr) { \
43 | RAISE_PY_EXCEPTION( \
44 | PyExc_KeyError, \
45 | "Missing key in dictionary provided to " current_ctx_name \
46 | ": Was expecting <" #name "> key"); \
47 | return; \
48 | }
49 |
50 |
51 | #define CHECK_FIELD_TYPE(name, type_checker_funct, current_ctx_name) \
52 | if (type_checker_funct(py_##name) == 0) { \
53 | RAISE_PY_EXCEPTION( \
54 | PyExc_TypeError, \
55 | "Key " #name " provided to " current_ctx_name " does not " \
56 | "have the expected type (" #type_checker_funct " failed)"); \
57 | return; \
58 | }
59 |
60 |
61 | #define FALSE 0
62 |
63 | #define TRUE (!FALSE)
64 |
65 | #endif // PREPROCESSOR_DIRECTIVES_H_
66 |
--------------------------------------------------------------------------------
/src/debuggerinterface/python_native_interface.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include "python_native_interface.h"
27 |
28 |
29 | int get_py_int(PyObject* obj)
30 | {
31 | return PyLong_AS_LONG(obj);
32 | }
33 |
34 |
35 | int check_py_string_type(PyObject* obj)
36 | {
37 | return PyUnicode_Check(obj) == 1 ? 1 : PyBytes_Check(obj);
38 | }
39 |
40 |
41 | void* get_c_ptr_from_py_buffer(PyObject* obj)
42 | {
43 | assert(PyMemoryView_Check(obj));
44 | return PyMemoryView_GET_BUFFER(obj)->buf;
45 | }
46 |
--------------------------------------------------------------------------------
/src/debuggerinterface/python_native_interface.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef PYTHON_NATIVE_INTERFACE_H_
27 | #define PYTHON_NATIVE_INTERFACE_H_
28 |
29 | #include
30 |
31 |
32 | int get_py_int(PyObject* obj);
33 |
34 |
35 | int check_py_string_type(PyObject* obj);
36 |
37 |
38 | void* get_c_ptr_from_py_buffer(PyObject* obj);
39 |
40 | #endif // PYTHON_NATIVE_INTERFACE_H_
41 |
--------------------------------------------------------------------------------
/src/giw_window.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch (github.com/csantosbh/gdb-imagewatch/)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to
8 | * deal in the Software without restriction, including without limitation the
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 | * sell copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 | * IN THE SOFTWARE.
23 | */
24 |
25 | #ifndef GIW_WINDOW_H_
26 | #define GIW_WINDOW_H_
27 |
28 | #include
29 |
30 | #ifndef GIW_API
31 | # if __GNUC__ >= 4
32 | # define GIW_API __attribute__((visibility("default")))
33 | # else
34 | # define GIW_API
35 | # endif
36 | #endif
37 |
38 | #ifdef __cplusplus
39 | extern "C" {
40 | #endif
41 |
42 |
43 | typedef void* AppHandler;
44 | typedef void* WindowHandler;
45 |
46 |
47 | /**
48 | * Initialize GIW application
49 | *
50 | * The thread in which this function will be called will become the GUI thread;
51 | * all later functions (with exception of giw_terminate()) must be called
52 | * in the same thread.
53 | *
54 | * @return Application context
55 | */
56 | GIW_API
57 | AppHandler giw_initialize();
58 |
59 | /**
60 | * Cleanup GIW application
61 | *
62 | * This function should be called prior to the application shutdown, in order to
63 | * release some of the resources acquired by the underlying GUI library.
64 | *
65 | * @param handler Application context generated by giw_initialize()
66 | */
67 | GIW_API
68 | void giw_cleanup(AppHandler handler);
69 |
70 | /**
71 | * Request GIW application to be terminated
72 | *
73 | * This function will close all windows, making the method giw_exec() to finish
74 | * executing. This function can be called from any thread.
75 | */
76 | GIW_API
77 | void giw_terminate();
78 |
79 | /**
80 | * Execute GUI loop
81 | *
82 | * This methods blocks the caller until the GIW window is closed. If
83 | * non-blocking behavior is desired, it must be called from a dedicated thread.
84 | * Notice that it must also be called in the same thread as giw_initialize().
85 | *
86 | * @param handler Application context
87 | */
88 | GIW_API
89 | void giw_exec(AppHandler handler);
90 |
91 | /**
92 | * Create and open new window
93 | *
94 | * Must be called after giw_initialize(), in the same thread as it was called.
95 | *
96 | * @param plot_callback Callback function to be called when the user requests
97 | * a symbol name from the giw window
98 | *
99 | * @return Window context
100 | */
101 | GIW_API
102 | WindowHandler giw_create_window(int (*plot_callback)(const char*));
103 |
104 | /**
105 | * Check if the given window is open
106 | *
107 | * @param handler Window handler, generated by giw_create_window()
108 | * @return Returns 1 if the window has been fully initialized, 0 otherwise.
109 | */
110 | GIW_API
111 | int giw_is_window_ready(WindowHandler handler);
112 |
113 | /**
114 | * Clean up GIW window
115 | *
116 | * This function should be called prior to the application shutdown, in order to
117 | * release some of the resources acquired by the underlying GUI library.
118 | *
119 | * @param handler Window handler, generated by giw_create_window()
120 | */
121 | GIW_API
122 | void giw_destroy_window(WindowHandler handler);
123 |
124 | /**
125 | * Get a list of the names of all buffers being visualized
126 | *
127 | * Returns a python list object with the names of all buffers present in the
128 | * visualization list.
129 | *
130 | * @param handler Window handler, generated by giw_create_window()
131 | * @return Python list object containing python str objects with the names of
132 | * all buffers being visualized.
133 | */
134 | GIW_API
135 | PyObject* giw_get_observed_buffers(WindowHandler handler);
136 |
137 | /**
138 | * Set list of symbols available in the current context
139 | *
140 | * Sets a list of names of variables available for plotting in the current
141 | * context. This list will serve as base for the autocomplete mechanism in the
142 | * symbol searcher input.
143 | *
144 | * @param handler Window handler, generated by giw_create_window()
145 | * @param available_set Python list of python str objects containing the names
146 | * of all available symbols in the current context.
147 | */
148 | GIW_API
149 | void giw_set_available_symbols(WindowHandler handler,
150 | PyObject* available_vars);
151 |
152 | /**
153 | * Add a buffer to the plot list
154 | *
155 | * @param handler Handler of the window where the buffer should be plotted
156 | * @param buffer_metadata Python dictionary with the following elements:
157 | * - [pointer ] PyMemoryView object wrapping the target buffer
158 | * - [display_name] Variable name as it shall be displayed
159 | * - [width ] Buffer width, in pixels
160 | * - [height ] Buffer height, in pixels
161 | * - [channels ] Number of channels (1 to 4)
162 | * - [type ] Buffer type (see symbols.py for details)
163 | * - [row_stride ] Row stride, in pixels
164 | * - [pixel_layout] String defining pixel channel layout (e.g. 'rgba')
165 | * */
166 | GIW_API
167 | void giw_plot_buffer(WindowHandler handler, PyObject* bufffer_metadata);
168 |
169 | #ifdef __cplusplus
170 | }
171 | #endif
172 |
173 | #endif
174 |
--------------------------------------------------------------------------------
/src/io/buffer_exporter.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef BUFFER_EXPORTER_H_
27 | #define BUFFER_EXPORTER_H_
28 |
29 | #include "visualization/components/buffer.h"
30 |
31 |
32 | class BufferExporter
33 | {
34 | public:
35 | enum class OutputType { Bitmap, OctaveMatrix };
36 |
37 | static void export_buffer(const Buffer* buffer,
38 | const std::string& path,
39 | OutputType type);
40 | };
41 |
42 | #endif // BUFFER_EXPORTER_H_
43 |
--------------------------------------------------------------------------------
/src/math/assorted.cpp:
--------------------------------------------------------------------------------
1 | #include "assorted.h"
2 |
--------------------------------------------------------------------------------
/src/math/assorted.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef ASSORTED_H_
27 | #define ASSORTED_H_
28 |
29 | #include
30 |
31 | template
32 | int clamp(T value, T lower, T upper)
33 | {
34 | return std::min(std::max(value, lower), upper);
35 | }
36 |
37 | #endif // ASSORTED_H_
38 |
--------------------------------------------------------------------------------
/src/math/linear_algebra.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include
27 |
28 | #include "linear_algebra.h"
29 |
30 |
31 | vec4::vec4()
32 | {
33 | }
34 |
35 |
36 | vec4::vec4(float x, float y, float z, float w)
37 | : vec(x, y, z, w)
38 | {
39 | }
40 |
41 |
42 | void vec4::operator=(const vec4& b)
43 | {
44 | vec = b.vec;
45 | }
46 |
47 |
48 | vec4& vec4::operator+=(const vec4& b)
49 | {
50 | for (int i = 0; i < 4; ++i)
51 | vec[i] += b.vec[i];
52 | return *this;
53 | }
54 |
55 |
56 | vec4 vec4::operator+(const vec4& b) const
57 | {
58 | return vec4(vec[0] + b.vec[0],
59 | vec[1] + b.vec[1],
60 | vec[2] + b.vec[2],
61 | vec[3] + b.vec[3]);
62 | }
63 |
64 |
65 | vec4 vec4::operator-(const vec4& b) const
66 | {
67 | return vec4(vec[0] - b.vec[0],
68 | vec[1] - b.vec[1],
69 | vec[2] - b.vec[2],
70 | vec[3] - b.vec[3]);
71 | }
72 |
73 |
74 | vec4 vec4::operator*(float scalar) const
75 | {
76 | vec4 result(*this);
77 | result.vec *= scalar;
78 |
79 | return result;
80 | }
81 |
82 |
83 | void vec4::print() const
84 | {
85 | std::cout << vec.transpose() << std::endl;
86 | }
87 |
88 |
89 | float* vec4::data()
90 | {
91 | return vec.data();
92 | }
93 |
94 |
95 | float& vec4::x()
96 | {
97 | return vec[0];
98 | }
99 |
100 |
101 | float& vec4::y()
102 | {
103 | return vec[1];
104 | }
105 |
106 |
107 | float& vec4::z()
108 | {
109 | return vec[2];
110 | }
111 |
112 |
113 | float& vec4::w()
114 | {
115 | return vec[3];
116 | }
117 |
118 |
119 | const float& vec4::x() const
120 | {
121 | return vec[0];
122 | }
123 |
124 |
125 | const float& vec4::y() const
126 | {
127 | return vec[1];
128 | }
129 |
130 |
131 | const float& vec4::z() const
132 | {
133 | return vec[2];
134 | }
135 |
136 |
137 | const float& vec4::w() const
138 | {
139 | return vec[3];
140 | }
141 |
142 |
143 | vec4 vec4::zero()
144 | {
145 | return vec4(0, 0, 0, 0);
146 | }
147 |
148 |
149 | vec4 operator-(const vec4& vector)
150 | {
151 | return {-vector.x(), -vector.y(), -vector.z(), -vector.w()};
152 | }
153 |
154 |
155 | void mat4::set_identity()
156 | {
157 | // clang-format off
158 | *this << std::initializer_list{
159 | 1, 0, 0, 0,
160 | 0, 1, 0, 0,
161 | 0, 0, 1, 0,
162 | 0, 0, 0, 1
163 | };
164 | // clang-format on
165 | }
166 |
167 |
168 | void mat4::set_from_st(float scaleX,
169 | float scaleY,
170 | float scaleZ,
171 | float x,
172 | float y,
173 | float z)
174 | {
175 | float* data = this->data();
176 |
177 | data[0] = scaleX, data[5] = scaleY, data[10] = scaleZ;
178 | data[12] = x, data[13] = y, data[14] = z;
179 |
180 | data[1] = data[2] = data[3] = data[4] = 0.0;
181 | data[6] = data[7] = data[8] = data[9] = 0.0;
182 | data[11] = 0.0;
183 | data[15] = 1.0;
184 | }
185 |
186 |
187 | void mat4::set_from_srt(float scaleX,
188 | float scaleY,
189 | float scaleZ,
190 | float rZ,
191 | float x,
192 | float y,
193 | float z)
194 | {
195 | using Eigen::Affine3f;
196 | using Eigen::AngleAxisf;
197 | using Eigen::Vector3f;
198 |
199 | Affine3f t = Affine3f::Identity();
200 | t.translate(Vector3f(x, y, z))
201 | .rotate(AngleAxisf(rZ, Vector3f(0, 0, 1)))
202 | .scale(Vector3f(scaleX, scaleY, scaleZ));
203 | this->mat_ = t.matrix();
204 | }
205 |
206 |
207 | float* mat4::data()
208 | {
209 | return mat_.data();
210 | }
211 |
212 |
213 | void mat4::operator<<(const std::initializer_list& data)
214 | {
215 | memcpy(mat_.data(), data.begin(), sizeof(float) * data.size());
216 | }
217 |
218 |
219 | mat4 mat4::rotation(float angle)
220 | {
221 | using Eigen::Affine3f;
222 | using Eigen::AngleAxisf;
223 | using Eigen::Vector3f;
224 |
225 | mat4 result;
226 | Affine3f t = Affine3f::Identity();
227 | t.rotate(AngleAxisf(angle, Vector3f(0, 0, 1)));
228 |
229 | result.mat_ = t.matrix();
230 | return result;
231 | }
232 |
233 |
234 | mat4 mat4::translation(const vec4& vector)
235 | {
236 | using Eigen::Affine3f;
237 | using Eigen::Vector3f;
238 |
239 | mat4 result;
240 |
241 | Affine3f t = Affine3f::Identity();
242 | t.translate(Vector3f(vector.x(), vector.y(), vector.z()));
243 | result.mat_ = t.matrix();
244 |
245 | return result;
246 | }
247 |
248 |
249 | mat4 mat4::scale(const vec4& factor)
250 | {
251 | using Eigen::Affine3f;
252 | using Eigen::Vector3f;
253 |
254 | mat4 result;
255 |
256 | Affine3f t = Affine3f::Identity();
257 | t.scale(Vector3f(factor.x(), factor.y(), factor.z()));
258 | result.mat_ = t.matrix();
259 |
260 | return result;
261 | }
262 |
263 |
264 | void mat4::set_ortho_projection(float right, float top, float near, float far)
265 | {
266 | float* data = this->data();
267 |
268 | data[0] = 1.0 / right;
269 | data[5] = -1.0 / top;
270 | data[10] = -2.0 / (far - near);
271 | data[14] = -(far + near) / (far - near);
272 |
273 | data[1] = data[2] = data[3] = data[4] = 0.0;
274 | data[6] = data[7] = data[8] = data[9] = 0.0;
275 | data[11] = data[12] = data[13] = 0.0;
276 | data[15] = 1.0;
277 | }
278 |
279 |
280 | void mat4::print() const
281 | {
282 | std::cout << mat_ << std::endl;
283 | }
284 |
285 |
286 | mat4 mat4::inv() const
287 | {
288 | mat4 res;
289 | res.mat_ = this->mat_.inverse();
290 |
291 | return res;
292 | }
293 |
294 |
295 | vec4 mat4::operator*(const vec4& b) const
296 | {
297 | vec4 res;
298 | res.vec = this->mat_ * b.vec;
299 |
300 | return res;
301 | }
302 |
303 |
304 | float&mat4::operator()(int row, int col) {
305 | return mat_(row, col);
306 | }
307 |
308 |
309 | mat4 mat4::operator*(const mat4& b) const
310 | {
311 | mat4 res;
312 |
313 | res.mat_ = this->mat_ * b.mat_;
314 |
315 | return res;
316 | }
317 |
--------------------------------------------------------------------------------
/src/math/linear_algebra.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef LINEAR_ALGEBRA_H_
27 | #define LINEAR_ALGEBRA_H_
28 |
29 | #include
30 | #include
31 |
32 | #include "thirdparty/Eigen/Eigen"
33 |
34 |
35 | class mat4;
36 |
37 |
38 | class vec4
39 | {
40 | friend class mat4;
41 |
42 | public:
43 | vec4();
44 | void operator=(const vec4& b);
45 |
46 | vec4& operator+=(const vec4& b);
47 |
48 | vec4 operator+(const vec4& b) const;
49 |
50 | vec4 operator-(const vec4& b) const;
51 |
52 | vec4 operator*(float scalar) const;
53 |
54 | vec4(float x, float y, float z, float w);
55 |
56 | void print() const;
57 |
58 | float* data();
59 |
60 | float& x();
61 | float& y();
62 | float& z();
63 | float& w();
64 |
65 | const float& x() const;
66 | const float& y() const;
67 | const float& z() const;
68 | const float& w() const;
69 |
70 | static vec4 zero();
71 |
72 | private:
73 | Eigen::Vector4f vec;
74 | };
75 |
76 | vec4 operator-(const vec4& vector);
77 |
78 |
79 | class mat4
80 | {
81 | public:
82 | void set_identity();
83 |
84 | void set_from_srt(float scaleX,
85 | float scaleY,
86 | float scaleZ,
87 | float rZ,
88 | float x,
89 | float y,
90 | float z);
91 |
92 | void set_from_st(float scaleX,
93 | float scaleY,
94 | float scaleZ,
95 | float x,
96 | float y,
97 | float z);
98 |
99 | float* data();
100 |
101 | void operator<<(const std::initializer_list& data);
102 |
103 | void set_ortho_projection(float right, float top, float near, float far);
104 |
105 | void print() const;
106 |
107 | mat4 inv() const;
108 |
109 | mat4 operator*(const mat4& b) const;
110 |
111 | vec4 operator*(const vec4& b) const;
112 |
113 | float& operator()(int row, int col);
114 |
115 | static mat4 rotation(float angle);
116 |
117 | static mat4 translation(const vec4& vector);
118 |
119 | static mat4 scale(const vec4& factor);
120 |
121 | private:
122 | Eigen::Matrix4f mat_;
123 | };
124 |
125 | #endif // LINEAR_ALGEBRA_H_
126 |
--------------------------------------------------------------------------------
/src/thirdparty/Khronos/GL/gl.h:
--------------------------------------------------------------------------------
1 | #ifndef __gl_h_
2 | #define __gl_h_ 1
3 |
4 | #define GL_GLEXT_PROTOTYPES
5 | #include "GL/glcorearb.h"
6 |
7 | #endif
8 |
--------------------------------------------------------------------------------
/src/ui/decorated_line_edit.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "decorated_line_edit.h"
9 |
10 |
11 | DecoratedLineEdit::DecoratedLineEdit(const char* icon_path,
12 | const char* tooltip,
13 | QWidget* parent)
14 | : QLineEdit(parent)
15 | {
16 | QIcon label_icon(icon_path);
17 | QAction* label_widget = new QAction(label_icon, tooltip, this);
18 | addAction(label_widget, QLineEdit::ActionPosition::LeadingPosition);
19 | }
20 |
--------------------------------------------------------------------------------
/src/ui/decorated_line_edit.h:
--------------------------------------------------------------------------------
1 | #ifndef DECORATED_LINE_EDIT_H_
2 | #define DECORATED_LINE_EDIT_H_
3 |
4 | #include
5 | #include
6 |
7 | class DecoratedLineEdit : public QLineEdit
8 | {
9 | Q_OBJECT
10 |
11 | public:
12 | DecoratedLineEdit(const char* icon_path,
13 | const char* tooltip,
14 | QWidget* parent = nullptr);
15 |
16 | private:
17 | };
18 |
19 | #endif // DECORATED_LINE_EDIT_H_
20 |
--------------------------------------------------------------------------------
/src/ui/gl_canvas.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include "gl_canvas.h"
27 |
28 | #include "main_window/main_window.h"
29 | #include "ui/gl_text_renderer.h"
30 | #include "visualization/components/camera.h"
31 | #include "visualization/game_object.h"
32 |
33 |
34 | using namespace std;
35 |
36 |
37 | GLCanvas::GLCanvas(QWidget* parent)
38 | : QOpenGLWidget(parent)
39 | , QOpenGLFunctions()
40 | , mouse_x_(0)
41 | , mouse_y_(0)
42 | , initialized_(false)
43 | , text_renderer_(new GLTextRenderer(this))
44 | {
45 | mouse_down_[0] = mouse_down_[1] = false;
46 | }
47 |
48 |
49 | GLCanvas::~GLCanvas()
50 | {
51 | }
52 |
53 |
54 | void GLCanvas::mouseMoveEvent(QMouseEvent* ev)
55 | {
56 | int last_mouse_x = mouse_x_;
57 | int last_mouse_y = mouse_y_;
58 |
59 | mouse_x_ = ev->localPos().x();
60 | mouse_y_ = ev->localPos().y();
61 |
62 | if (mouse_down_[0]) {
63 | main_window_->mouse_drag_event(mouse_x_ - last_mouse_x,
64 | mouse_y_ - last_mouse_y);
65 | } else {
66 | main_window_->mouse_move_event(mouse_x_ - last_mouse_x,
67 | mouse_y_ - last_mouse_y);
68 | }
69 | }
70 |
71 |
72 | void GLCanvas::mousePressEvent(QMouseEvent* ev)
73 | {
74 | if (ev->button() == Qt::LeftButton)
75 | mouse_down_[0] = true;
76 |
77 | if (ev->button() == Qt::RightButton)
78 | mouse_down_[1] = true;
79 | }
80 |
81 |
82 | void GLCanvas::mouseReleaseEvent(QMouseEvent* ev)
83 | {
84 | if (ev->button() == Qt::LeftButton)
85 | mouse_down_[0] = false;
86 |
87 | if (ev->button() == Qt::RightButton)
88 | mouse_down_[1] = false;
89 | }
90 |
91 |
92 | void GLCanvas::initializeGL()
93 | {
94 | this->makeCurrent();
95 | initializeOpenGLFunctions();
96 |
97 | glEnable(GL_BLEND);
98 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
99 | glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
100 |
101 | ///
102 | // Texture for generating icons
103 | assert(main_window_ != nullptr);
104 | QSizeF icon_size = main_window_->get_icon_size();
105 | int icon_width = icon_size.width();
106 | int icon_height = icon_size.height();
107 | glGenTextures(1, &icon_texture_);
108 | glBindTexture(GL_TEXTURE_2D, icon_texture_);
109 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
110 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
111 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
112 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
113 | glTexImage2D(GL_TEXTURE_2D,
114 | 0,
115 | GL_RGB8,
116 | icon_width,
117 | icon_height,
118 | 0,
119 | GL_RGB,
120 | GL_UNSIGNED_BYTE,
121 | NULL);
122 |
123 | // Generate FBO
124 | glGenFramebuffers(1, &icon_fbo_);
125 | glBindFramebuffer(GL_FRAMEBUFFER, icon_fbo_);
126 |
127 | // Attach 2D texture to this FBO
128 | glFramebufferTexture2D(
129 | GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, icon_texture_, 0);
130 |
131 | // Check if the GPU won't freak out about our FBO
132 | GLenum status;
133 | status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
134 | switch (status) {
135 | case GL_FRAMEBUFFER_COMPLETE:
136 | break;
137 | default:
138 | cerr << "Error: FBO configuration is not supported -- sorry mate!"
139 | << endl;
140 | break;
141 | }
142 |
143 | glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
144 |
145 | // Initialize text renderer
146 | text_renderer_->initialize();
147 |
148 | initialized_ = true;
149 | }
150 |
151 |
152 | void GLCanvas::paintGL()
153 | {
154 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
155 | main_window_->draw();
156 | }
157 |
158 |
159 | void GLCanvas::wheelEvent(QWheelEvent* ev)
160 | {
161 | main_window_->scroll_callback(ev->delta() / 120.0f);
162 | }
163 |
164 |
165 | const GLTextRenderer* GLCanvas::get_text_renderer()
166 | {
167 | return text_renderer_.get();
168 | }
169 |
170 |
171 | void GLCanvas::render_buffer_icon(Stage* stage, int icon_width, int icon_height)
172 | {
173 | glBindFramebuffer(GL_FRAMEBUFFER_EXT, icon_fbo_);
174 |
175 | glViewport(0, 0, icon_width, icon_height);
176 |
177 | GameObject* camera = stage->get_game_object("camera");
178 | Camera* cam = camera->get_component("camera_component");
179 |
180 | // Save original camera pose
181 | Camera original_pose = *cam;
182 |
183 | // Adapt camera to the thumbnail dimentions
184 | cam->window_resized(icon_width, icon_height);
185 | // Flips the projected image along the horizontal axis
186 | cam->projection.set_ortho_projection(
187 | icon_width / 2.0, -icon_height / 2.0, -1.0f, 1.0f);
188 | // Reposition buffer in the center of the canvas
189 | cam->recenter_camera();
190 |
191 | stage->draw();
192 | stage->buffer_icon.resize(3 * icon_width * icon_height);
193 | glPixelStorei(GL_PACK_ALIGNMENT, 1);
194 | glReadPixels(0,
195 | 0,
196 | icon_width,
197 | icon_height,
198 | GL_RGB,
199 | GL_UNSIGNED_BYTE,
200 | stage->buffer_icon.data());
201 |
202 | // Reset stage camera
203 | glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
204 | glViewport(0, 0, width(), height());
205 | *cam = original_pose;
206 | cam->window_resized(width(), height());
207 | }
208 |
209 |
210 | void GLCanvas::resizeGL(int w, int h)
211 | {
212 | glViewport(0, 0, w, h);
213 | main_window_->resize_callback(w, h);
214 | }
215 |
216 |
217 | void GLCanvas::set_main_window(MainWindow* mw)
218 | {
219 | main_window_ = mw;
220 | }
221 |
222 |
223 | void list_gl_extensions()
224 | {
225 | GLint num_exts = 0;
226 | glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts);
227 |
228 | cout << "Supported OpenGL extensions:" << glGetString(GL_EXTENSIONS)
229 | << endl;
230 | }
231 |
--------------------------------------------------------------------------------
/src/ui/gl_canvas.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef GL_CANVAS_H_
27 | #define GL_CANVAS_H_
28 |
29 | #include
30 |
31 | #include
32 | #include
33 | #include
34 |
35 |
36 | class MainWindow;
37 | class Stage;
38 | class GLTextRenderer;
39 |
40 |
41 | class GLCanvas : public QOpenGLWidget, public QOpenGLFunctions
42 | {
43 | Q_OBJECT
44 | public:
45 | explicit GLCanvas(QWidget* parent = 0);
46 |
47 | ~GLCanvas();
48 |
49 | void mouseMoveEvent(QMouseEvent* ev);
50 |
51 | void mousePressEvent(QMouseEvent* ev);
52 |
53 | void mouseReleaseEvent(QMouseEvent* ev);
54 |
55 | void initializeGL();
56 |
57 | void paintGL();
58 |
59 | void resizeGL(int w, int h);
60 |
61 | void wheelEvent(QWheelEvent* ev);
62 |
63 | int mouse_x()
64 | {
65 | return mouse_x_;
66 | }
67 |
68 | int mouse_y()
69 | {
70 | return mouse_y_;
71 | }
72 |
73 | bool is_mouse_down()
74 | {
75 | return mouse_down_[0];
76 | }
77 |
78 | bool is_ready()
79 | {
80 | return initialized_;
81 | }
82 |
83 | const GLTextRenderer* get_text_renderer();
84 |
85 | void set_main_window(MainWindow* mw);
86 |
87 | void render_buffer_icon(Stage* stage, int icon_width, int icon_height);
88 |
89 | private:
90 | bool mouse_down_[2];
91 |
92 | int mouse_x_;
93 | int mouse_y_;
94 |
95 | MainWindow* main_window_;
96 |
97 | GLuint icon_texture_;
98 | GLuint icon_fbo_;
99 |
100 | bool initialized_;
101 |
102 | std::unique_ptr text_renderer_;
103 |
104 | void generate_icon_texture();
105 | };
106 |
107 | #endif // GL_CANVAS_H_
108 |
--------------------------------------------------------------------------------
/src/ui/gl_text_renderer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef GL_TEXT_RENDERER_H_
27 | #define GL_TEXT_RENDERER_H_
28 |
29 | #include "math/linear_algebra.h"
30 | #include "ui/gl_canvas.h"
31 | #include "visualization/shader.h"
32 |
33 |
34 | class GLTextRenderer
35 | {
36 | public:
37 | static constexpr float font_size = 96.0f;
38 |
39 | QFont font;
40 | GLuint text_vbo;
41 | GLuint text_tex;
42 |
43 | int text_texture_offsets[256][2];
44 | int text_texture_advances[256][2];
45 | int text_texture_sizes[256][2];
46 | int text_texture_tls[256][2];
47 |
48 | GLTextRenderer(GLCanvas* gl_canvas);
49 | ~GLTextRenderer();
50 |
51 | bool initialize();
52 |
53 | void generate_glyphs_texture();
54 |
55 | ShaderProgram text_prog;
56 |
57 | float text_texture_width;
58 | float text_texture_height;
59 |
60 | private:
61 | GLCanvas* gl_canvas_;
62 | };
63 |
64 | #endif // GL_TEXT_RENDERER_H_
65 |
--------------------------------------------------------------------------------
/src/ui/go_to_widget.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include
27 |
28 | #include
29 | #include
30 | #include
31 |
32 | #include "go_to_widget.h"
33 |
34 | GoToWidget::GoToWidget(QWidget* parent)
35 | : QWidget(parent)
36 | {
37 | QHBoxLayout* layout = new QHBoxLayout(this);
38 | layout->setMargin(0);
39 | layout->setSpacing(0);
40 |
41 | x_coordinate_ = new DecoratedLineEdit(
42 | ":resources/icons/x.svg", "Horizontal coordinate", this);
43 | x_coordinate_->setValidator(new QIntValidator(x_coordinate_));
44 |
45 | y_coordinate_ = new DecoratedLineEdit(
46 | ":resources/icons/y.svg", "Vertical coordinate", this);
47 | y_coordinate_->setValidator(new QIntValidator(y_coordinate_));
48 |
49 | layout->addWidget(x_coordinate_);
50 | layout->addWidget(y_coordinate_);
51 |
52 | setVisible(false);
53 | }
54 |
55 |
56 | void GoToWidget::keyPressEvent(QKeyEvent* e)
57 | {
58 | switch (e->key()) {
59 | case Qt::Key_Escape:
60 | toggle_visible();
61 | e->accept();
62 |
63 | return;
64 | case Qt::Key_Enter:
65 | case Qt::Key_Return:
66 | toggle_visible();
67 | e->accept();
68 | Q_EMIT(go_to_requested(x_coordinate_->text().toFloat() + 0.5f,
69 | y_coordinate_->text().toFloat() + 0.5f));
70 | return; // Let the completer do default behavior
71 | }
72 | }
73 |
74 |
75 | void GoToWidget::toggle_visible()
76 | {
77 | QWidget* parent_widget = static_cast(parent());
78 |
79 | if (isVisible()) {
80 | hide();
81 |
82 | parent_widget->setFocus();
83 | } else {
84 | show();
85 |
86 | this->move(parent_widget->width() - this->width(),
87 | parent_widget->height() - this->height());
88 |
89 | x_coordinate_->setFocus();
90 | x_coordinate_->selectAll();
91 | }
92 | }
93 |
94 |
95 | void GoToWidget::set_defaults(float default_x, float default_y)
96 | {
97 | x_coordinate_->setText(QString::number(std::round(default_x - 0.5f)));
98 | y_coordinate_->setText(QString::number(std::round(default_y - 0.5f)));
99 | }
100 |
--------------------------------------------------------------------------------
/src/ui/go_to_widget.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef GO_TO_WIDGET_H_
27 | #define GO_TO_WIDGET_H_
28 |
29 | #include
30 | #include
31 |
32 | #include "decorated_line_edit.h"
33 |
34 |
35 | class GoToWidget : public QWidget
36 | {
37 | Q_OBJECT
38 |
39 | public:
40 | explicit GoToWidget(QWidget* parent = nullptr);
41 | void toggle_visible();
42 | void set_defaults(float default_x, float default_y);
43 |
44 | Q_SIGNALS:
45 | void go_to_requested(float x, float y);
46 |
47 | public Q_SLOTS:
48 |
49 | protected:
50 | void keyPressEvent(QKeyEvent* e);
51 |
52 |
53 | private:
54 | DecoratedLineEdit* x_coordinate_;
55 | DecoratedLineEdit* y_coordinate_;
56 | };
57 |
58 | #endif // GO_TO_WIDGET_H_
59 |
--------------------------------------------------------------------------------
/src/ui/main_window/main_window.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef MAIN_WINDOW_H_
27 | #define MAIN_WINDOW_H_
28 |
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 |
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 | #include "debuggerinterface/buffer_request_message.h"
41 | #include "math/linear_algebra.h"
42 | #include "ui/go_to_widget.h"
43 | #include "ui/symbol_completer.h"
44 | #include "visualization/stage.h"
45 |
46 |
47 | namespace Ui
48 | {
49 | class MainWindowUi;
50 | }
51 |
52 |
53 | class MainWindow : public QMainWindow
54 | {
55 | Q_OBJECT
56 |
57 | public:
58 | ///
59 | // Constructor / destructor
60 | explicit MainWindow(QWidget* parent = 0);
61 |
62 | ~MainWindow();
63 |
64 | ///
65 | // Assorted methods - implemented in main_window.cpp
66 | void show();
67 |
68 | void draw();
69 |
70 | GLCanvas* gl_canvas();
71 |
72 | QSizeF get_icon_size();
73 |
74 | // External interface
75 | void set_plot_callback(int (*plot_cbk)(const char*));
76 |
77 | void plot_buffer(const BufferRequestMessage& buffer_metadata);
78 |
79 | std::deque get_observed_symbols();
80 |
81 | bool is_window_ready();
82 |
83 | void set_available_symbols(const std::deque& available_set);
84 |
85 | ///
86 | // Auto contrast pane - implemented in auto_contrast.cpp
87 | void reset_ac_min_labels();
88 |
89 | void reset_ac_max_labels();
90 |
91 | ///
92 | // General UI Events - implemented in ui_events.cpp
93 | void resize_callback(int w, int h);
94 |
95 | void scroll_callback(float delta);
96 |
97 | void mouse_drag_event(int mouse_x, int mouse_y);
98 |
99 | void mouse_move_event(int mouse_x, int mouse_y);
100 |
101 | // Window change events - only called after the event is finished
102 | bool eventFilter(QObject* target, QEvent* event);
103 |
104 | void resizeEvent(QResizeEvent*);
105 |
106 | void moveEvent(QMoveEvent*);
107 |
108 | void closeEvent(QCloseEvent*);
109 |
110 | public Q_SLOTS:
111 | ///
112 | // Assorted methods - slots - implemented in main_window.cpp
113 | void loop();
114 |
115 | void request_render_update();
116 |
117 | ///
118 | // Auto contrast pane - slots - implemented in auto_contrast.cpp
119 | void ac_red_min_update();
120 |
121 | void ac_green_min_update();
122 |
123 | void ac_blue_min_update();
124 |
125 | void ac_alpha_min_update();
126 |
127 | void ac_red_max_update();
128 |
129 | void ac_green_max_update();
130 |
131 | void ac_blue_max_update();
132 |
133 | void ac_alpha_max_update();
134 |
135 | void ac_min_reset();
136 |
137 | void ac_max_reset();
138 |
139 | void ac_toggle();
140 |
141 | ///
142 | // General UI Events - slots - implemented in ui_events.cpp
143 | void recenter_buffer();
144 |
145 | void link_views_toggle();
146 |
147 | void rotate_90_cw();
148 |
149 | void rotate_90_ccw();
150 |
151 | void buffer_selected(QListWidgetItem* item);
152 |
153 | void remove_selected_buffer();
154 |
155 | void symbol_selected();
156 |
157 | void symbol_completed(QString str);
158 |
159 | void export_buffer();
160 |
161 | void show_context_menu(const QPoint& pos);
162 |
163 | void toggle_go_to_dialog();
164 |
165 | void go_to_pixel(float x, float y);
166 |
167 | private Q_SLOTS:
168 | ///
169 | // Assorted methods - private slots - implemented in main_window.cpp
170 | void persist_settings();
171 |
172 | private:
173 | bool is_window_ready_;
174 | bool request_render_update_;
175 | bool completer_updated_;
176 | bool ac_enabled_;
177 | bool link_views_enabled_;
178 |
179 | const int icon_width_base_;
180 | const int icon_height_base_;
181 |
182 | double render_framerate_;
183 |
184 | QTimer settings_persist_timer_;
185 | QTimer update_timer_;
186 |
187 | QString default_export_suffix_;
188 |
189 | Stage* currently_selected_stage_;
190 |
191 | std::map> held_buffers_;
192 | std::map> stages_;
193 |
194 | std::set previous_session_buffers_;
195 | std::set removed_buffer_names_;
196 |
197 | std::deque pending_updates_;
198 |
199 | QStringList available_vars_;
200 |
201 | std::mutex ui_mutex_;
202 |
203 | SymbolCompleter* symbol_completer_;
204 |
205 | Ui::MainWindowUi* ui_;
206 |
207 | QLabel* status_bar_;
208 | GoToWidget* go_to_widget_;
209 |
210 | int (*plot_callback_)(const char*);
211 |
212 | ///
213 | // Assorted methods - private - implemented in main_window.cpp
214 | void update_status_bar();
215 |
216 | qreal get_screen_dpi_scale();
217 |
218 | std::string get_type_label(Buffer::BufferType type, int channels);
219 |
220 | void persist_settings_deferred();
221 |
222 | void set_currently_selected_stage(Stage* stage);
223 |
224 | vec4 get_stage_coordinates(float pos_window_x, float pos_window_y);
225 |
226 | ///
227 | // Auto contrast pane - private - implemented in auto_contrast.cpp
228 | void set_ac_min_value(int idx, float value);
229 |
230 | void set_ac_max_value(int idx, float value);
231 |
232 | ///
233 | // Initialization - private - implemented in initialization.cpp
234 | void initialize_ui_icons();
235 |
236 | void initialize_timers();
237 |
238 | void initialize_shortcuts();
239 |
240 | void initialize_symbol_completer();
241 |
242 | void initialize_auto_contrast_form();
243 |
244 | void initialize_toolbar();
245 |
246 | void initialize_left_pane();
247 |
248 | void initialize_status_bar();
249 |
250 | void initialize_visualization_pane();
251 |
252 | void initialize_settings();
253 |
254 | void initialize_go_to_widget();
255 | };
256 |
257 | #endif // MAIN_WINDOW_H_
258 |
--------------------------------------------------------------------------------
/src/ui/symbol_completer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include "symbol_completer.h"
27 |
28 |
29 | SymbolCompleter::SymbolCompleter(QObject* parent)
30 | : QCompleter(parent)
31 | , list_()
32 | , model_()
33 | {
34 | setModel(&model_);
35 | }
36 |
37 |
38 | void SymbolCompleter::update(const QString& word)
39 | {
40 | QStringList filtered = list_.filter(word, caseSensitivity());
41 | model_.setStringList(filtered);
42 | word_ = word;
43 | complete();
44 | }
45 |
46 |
47 | void SymbolCompleter::update_symbol_list(const QStringList& symbols)
48 | {
49 | list_ = symbols;
50 | }
51 |
52 |
53 | const QString& SymbolCompleter::word() const
54 | {
55 | return word_;
56 | }
57 |
--------------------------------------------------------------------------------
/src/ui/symbol_completer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef SYMBOL_COMPLETER_H_
27 | #define SYMBOL_COMPLETER_H_
28 |
29 | #include
30 | #include
31 | #include
32 |
33 |
34 | class SymbolCompleter : public QCompleter
35 | {
36 | Q_OBJECT
37 |
38 | public:
39 | SymbolCompleter(QObject* parent = nullptr);
40 |
41 | void update(const QString& word);
42 |
43 | void update_symbol_list(const QStringList& symbols);
44 |
45 | const QString& word() const;
46 |
47 | private:
48 | QStringList list_;
49 | QStringListModel model_;
50 | QString word_;
51 | };
52 |
53 |
54 | #endif // SYMBOL_COMPLETER_H_
55 |
--------------------------------------------------------------------------------
/src/ui/symbol_search_input.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Advanced search completer based on:
3 | * http://www.qtcentre.org/threads/23518
4 | */
5 |
6 | #include
7 | #include
8 |
9 | #include "symbol_search_input.h"
10 |
11 |
12 | SymbolSearchInput::SymbolSearchInput(QWidget* parent)
13 | : QLineEdit(parent)
14 | , completer_(nullptr)
15 | {
16 | }
17 |
18 |
19 | SymbolSearchInput::~SymbolSearchInput()
20 | {
21 | }
22 |
23 |
24 | void SymbolSearchInput::set_completer(SymbolCompleter* completer)
25 | {
26 | if (completer_) {
27 | QObject::disconnect(completer_, 0, this, 0);
28 | }
29 |
30 | completer_ = completer;
31 |
32 | if (!completer_) {
33 | return;
34 | }
35 |
36 | completer_->setWidget(this);
37 | connect(completer,
38 | SIGNAL(activated(const QString&)),
39 | this,
40 | SLOT(insert_completion(const QString&)));
41 | }
42 |
43 |
44 | SymbolCompleter* SymbolSearchInput::completer() const
45 | {
46 | return completer_;
47 | }
48 |
49 |
50 | void SymbolSearchInput::insert_completion(const QString& completion)
51 | {
52 | setText(completion);
53 | selectAll();
54 | }
55 |
56 |
57 | void SymbolSearchInput::keyPressEvent(QKeyEvent* e)
58 | {
59 | // The following keys are forwarded by the completer to the widget
60 | switch (e->key()) {
61 | case Qt::Key_Escape:
62 | clearFocus();
63 | e->accept();
64 | return;
65 | case Qt::Key_Tab:
66 | case Qt::Key_Backtab:
67 | case Qt::Key_Enter:
68 | case Qt::Key_Return:
69 | e->ignore();
70 | return; // Let the completer do default behavior
71 | }
72 |
73 | bool is_shortcut =
74 | (e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E;
75 | if (!is_shortcut)
76 | QLineEdit::keyPressEvent(
77 | e); // Don't send the shortcut (CTRL-E) to the text edit.
78 |
79 | if (!completer_)
80 | return;
81 |
82 | bool ctrl_or_shift =
83 | e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
84 |
85 | if (!is_shortcut && !ctrl_or_shift && e->modifiers() != Qt::NoModifier) {
86 | completer_->popup()->hide();
87 | return;
88 | }
89 |
90 | completer_->update(text());
91 | completer_->popup()->setCurrentIndex(
92 | completer_->completionModel()->index(0, 0));
93 | }
94 |
--------------------------------------------------------------------------------
/src/ui/symbol_search_input.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Advanced search completer based on:
3 | * http://www.qtcentre.org/threads/23518
4 | */
5 |
6 | #ifndef SYMBOL_SEARCH_INPUT_H_
7 | #define SYMBOL_SEARCH_INPUT_H_
8 |
9 | #include
10 |
11 | #include "ui/symbol_completer.h"
12 |
13 |
14 | class SymbolSearchInput : public QLineEdit
15 | {
16 | Q_OBJECT
17 |
18 | public:
19 | SymbolSearchInput(QWidget* parent = 0);
20 | ~SymbolSearchInput();
21 |
22 | void set_completer(SymbolCompleter* completer_);
23 |
24 | SymbolCompleter* completer() const;
25 |
26 | protected:
27 | void keyPressEvent(QKeyEvent* e);
28 |
29 | private Q_SLOTS:
30 | void insert_completion(const QString& completion);
31 |
32 | private:
33 | SymbolCompleter* completer_;
34 | };
35 |
36 |
37 | #endif // SYMBOL_SEARCH_INPUT_H_
38 |
--------------------------------------------------------------------------------
/src/visualization/components/background.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include "background.h"
27 |
28 | #include "math/linear_algebra.h"
29 | #include "visualization/game_object.h"
30 | #include "visualization/shader.h"
31 | #include "visualization/shaders/giw_shaders.h"
32 | #include "visualization/stage.h"
33 |
34 |
35 | Background::Background(GameObject* game_object, GLCanvas* gl_canvas)
36 | : Component(game_object, gl_canvas)
37 | , background_prog(gl_canvas)
38 | {
39 | }
40 |
41 |
42 | Background::~Background()
43 | {
44 | gl_canvas_->glDeleteBuffers(1, &background_vbo);
45 | }
46 |
47 |
48 | bool Background::initialize()
49 | {
50 | background_prog.create(shader::background_vert_shader,
51 | shader::background_frag_shader,
52 | ShaderProgram::FormatR,
53 | "rgba",
54 | {});
55 |
56 | // Generate square VBO
57 | // clang-format off
58 | static const GLfloat vertex_buffer_data[] = {
59 | -1, -1,
60 | 1, -1,
61 | 1, 1,
62 | 1, 1,
63 | -1, 1,
64 | -1, -1,
65 | };
66 | // clang-format on
67 | gl_canvas_->glGenBuffers(1, &background_vbo);
68 |
69 | gl_canvas_->glBindBuffer(GL_ARRAY_BUFFER, background_vbo);
70 | gl_canvas_->glBufferData(GL_ARRAY_BUFFER,
71 | sizeof(vertex_buffer_data),
72 | vertex_buffer_data,
73 | GL_STATIC_DRAW);
74 |
75 | return true;
76 | }
77 |
78 |
79 | void Background::draw(const mat4&, const mat4&)
80 | {
81 | background_prog.use();
82 |
83 | gl_canvas_->glEnableVertexAttribArray(0);
84 | gl_canvas_->glBindBuffer(GL_ARRAY_BUFFER, background_vbo);
85 | gl_canvas_->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
86 | gl_canvas_->glDrawArrays(GL_TRIANGLES, 0, 6);
87 | }
88 |
89 |
90 | int Background::render_index() const
91 | {
92 | return -100;
93 | }
94 |
--------------------------------------------------------------------------------
/src/visualization/components/background.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef BACKGROUND_H_
27 | #define BACKGROUND_H_
28 |
29 | #include "component.h"
30 | #include "visualization/shader.h"
31 |
32 |
33 | class Background : public Component
34 | {
35 | public:
36 | Background(GameObject* game_object, GLCanvas* gl_canvas);
37 |
38 | virtual ~Background();
39 |
40 | virtual bool initialize();
41 |
42 | virtual void update()
43 | {
44 | }
45 |
46 | virtual void draw(const mat4& projection, const mat4& view_inv);
47 |
48 | virtual int render_index() const;
49 |
50 | private:
51 | ShaderProgram background_prog;
52 | GLuint background_vbo;
53 | };
54 |
55 | #endif // BACKGROUND_H_
56 |
--------------------------------------------------------------------------------
/src/visualization/components/buffer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef BUFFER_H_
27 | #define BUFFER_H_
28 |
29 | #include
30 | #include
31 |
32 | #include "component.h"
33 | #include "visualization/shader.h"
34 |
35 |
36 | class Buffer : public Component
37 | {
38 | public:
39 | Buffer(GameObject* game_object, GLCanvas* gl_canvas);
40 |
41 | enum class BufferType {
42 | UnsignedByte = 0,
43 | UnsignedShort = 2,
44 | Short = 3,
45 | Int32 = 4,
46 | Float32 = 5,
47 | Float64 = 6
48 | };
49 |
50 | const int max_texture_size = 2048;
51 |
52 | std::vector buff_tex;
53 |
54 | static const float no_ac_params[8];
55 |
56 | float buffer_width_f;
57 | float buffer_height_f;
58 |
59 | int channels;
60 | int step;
61 |
62 | BufferType type;
63 |
64 | uint8_t* buffer;
65 |
66 | bool transpose;
67 |
68 | ~Buffer();
69 |
70 | bool buffer_update();
71 |
72 | void recompute_min_color_values();
73 |
74 | void recompute_max_color_values();
75 |
76 | void reset_contrast_brightness_parameters();
77 |
78 | void compute_contrast_brightness_parameters();
79 |
80 | int sub_texture_id_at_coord(int x, int y);
81 |
82 | void set_pixel_layout(const std::string& pixel_layout);
83 |
84 | const char* get_pixel_layout() const;
85 |
86 | float tile_coord_x(int x);
87 | float tile_coord_y(int y);
88 |
89 | bool initialize();
90 |
91 | void update();
92 |
93 | void draw(const mat4& projection, const mat4& viewInv);
94 |
95 | int num_textures_x;
96 | int num_textures_y;
97 |
98 | float* min_buffer_values();
99 |
100 | float* max_buffer_values();
101 |
102 | const float* auto_buffer_contrast_brightness() const;
103 |
104 | void set_min_buffer_values();
105 | void set_max_buffer_values();
106 |
107 | void get_pixel_info(std::stringstream& output, int x, int y);
108 |
109 | void rotate(float angle);
110 |
111 | private:
112 | void create_shader_program();
113 |
114 | void setup_gl_buffer();
115 |
116 | void update_object_pose();
117 |
118 | char pixel_layout_[4] = {'r', 'g', 'b', 'a'};
119 |
120 | float min_buffer_values_[4];
121 | float max_buffer_values_[4];
122 | float auto_buffer_contrast_brightness_[8] =
123 | {1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0};
124 | float angle_ = 0.f;
125 |
126 | ShaderProgram buff_prog;
127 | GLuint vbo;
128 | };
129 |
130 | #endif // BUFFER_H_
131 |
--------------------------------------------------------------------------------
/src/visualization/components/buffer_values.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef BUFFER_VALUES_H_
27 | #define BUFFER_VALUES_H_
28 |
29 | #include
30 |
31 | #include
32 |
33 | #include "component.h"
34 | #include "ui/gl_text_renderer.h"
35 |
36 | class BufferValues : public Component
37 | {
38 | public:
39 | BufferValues(GameObject* game_object,
40 | GLCanvas* gl_canvas);
41 |
42 | virtual ~BufferValues();
43 |
44 | virtual void update()
45 | {
46 | }
47 |
48 | virtual int render_index() const;
49 |
50 | virtual void draw(const mat4& projection, const mat4& view_inv);
51 |
52 | private:
53 | float text_pixel_scale = 1.0;
54 | static float constexpr padding = 0.125f; // Must be smaller than 0.5
55 |
56 | void generate_glyphs_texture();
57 |
58 | void draw_text(const mat4& projection,
59 | const mat4& view_inv,
60 | const mat4& buffer_pose,
61 | const char* text,
62 | float x,
63 | float y,
64 | float y_offset,
65 | float channels);
66 | };
67 |
68 | #endif // BUFFER_VALUES_H_
69 |
--------------------------------------------------------------------------------
/src/visualization/components/camera.h:
--------------------------------------------------------------------------------
1 | #ifndef CAMERA_H_
2 | #define CAMERA_H_
3 |
4 | #include "component.h"
5 | #include "math/linear_algebra.h"
6 |
7 |
8 | class Camera : public Component
9 | {
10 | public:
11 | Camera(GameObject* game_object, GLCanvas* gl_canvas);
12 |
13 | static constexpr float zoom_factor = 1.1;
14 | mat4 projection;
15 |
16 | vec4 mouse_position = vec4::zero();
17 |
18 | Camera& operator=(const Camera& cam);
19 |
20 | virtual void update();
21 |
22 | virtual void draw(const mat4&, const mat4&)
23 | {
24 | }
25 |
26 | virtual bool post_buffer_update();
27 |
28 | virtual bool post_initialize();
29 |
30 | virtual EventProcessCode key_press_event(int key_code);
31 |
32 | void window_resized(int w, int h);
33 |
34 | void scroll_callback(float delta);
35 |
36 | void recenter_camera();
37 |
38 | void mouse_drag_event(int mouse_x, int mouse_y);
39 |
40 | float compute_zoom();
41 |
42 | void move_to(float x, float y);
43 |
44 | vec4 get_position();
45 |
46 | private:
47 | void update_object_pose();
48 |
49 | void scale_at(const vec4& center_ndc, float delta);
50 |
51 | void set_initial_zoom();
52 |
53 | void handle_key_events();
54 |
55 | float zoom_power_ = 0.0f;
56 | float camera_pos_x_ = 0.0f;
57 | float camera_pos_y_ = 0.0f;
58 |
59 | int canvas_width_;
60 | int canvas_height_;
61 |
62 | mat4 scale_;
63 | };
64 |
65 | #endif // CAMERA_H_
66 |
--------------------------------------------------------------------------------
/src/visualization/components/component.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include "component.h"
27 |
28 |
29 | Component::Component(GameObject* game_object, GLCanvas* gl_canvas)
30 | : game_object_(game_object)
31 | , gl_canvas_(gl_canvas)
32 | {
33 | }
34 |
35 |
36 | Component::~Component()
37 | {
38 | }
39 |
40 |
41 | bool Component::initialize()
42 | {
43 | return true;
44 | }
45 |
46 |
47 | bool Component::buffer_update()
48 | {
49 | return true;
50 | }
51 |
52 |
53 | bool Component::post_buffer_update()
54 | {
55 | return true;
56 | }
57 |
58 |
59 | int Component::render_index() const
60 | {
61 | return 0;
62 | }
63 |
64 |
65 |
66 |
67 |
68 | bool Component::post_initialize()
69 | {
70 | return true;
71 | }
72 |
--------------------------------------------------------------------------------
/src/visualization/components/component.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef COMPONENT_H_
27 | #define COMPONENT_H_
28 |
29 | #include "src/visualization/events.h"
30 |
31 | class GameObject;
32 | class GLCanvas;
33 | class mat4;
34 |
35 |
36 | class Component
37 | {
38 | public:
39 | Component(GameObject* game_object, GLCanvas* gl_canvas);
40 |
41 | virtual bool initialize();
42 |
43 | virtual bool buffer_update();
44 |
45 | virtual bool post_buffer_update();
46 |
47 | virtual int render_index() const;
48 |
49 | // Called after all components are initialized
50 | virtual bool post_initialize();
51 |
52 | virtual void update() = 0;
53 |
54 | virtual void draw(const mat4& projection, const mat4& viewInv) = 0;
55 |
56 | ///
57 | // Events
58 | virtual EventProcessCode key_press_event(int /* key_code */)
59 | {
60 | return EventProcessCode::IGNORED;
61 | }
62 |
63 | virtual void mouse_drag_event(int /* mouse_x */, int /* mouse_y */)
64 | {
65 | }
66 |
67 | virtual void mouse_move_event(int /* mouse_x */, int /* mouse_y */)
68 | {
69 | }
70 |
71 | virtual ~Component();
72 |
73 | protected:
74 | GameObject* game_object_;
75 |
76 | GLCanvas* gl_canvas_;
77 | };
78 |
79 | #endif // COMPONENT_H_
80 |
--------------------------------------------------------------------------------
/src/visualization/events.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 | #include
5 |
6 | #include "events.h"
7 |
8 |
9 | std::set KeyboardState::pressed_keys_;
10 |
11 |
12 | bool KeyboardState::is_modifier_key_pressed(ModifierKey key)
13 | {
14 | switch (key) {
15 | case ModifierKey::Alt:
16 | return (QApplication::keyboardModifiers() & Qt::AltModifier) != 0;
17 | case ModifierKey::Control:
18 | return (QApplication::keyboardModifiers() & Qt::ControlModifier) != 0;
19 | case ModifierKey::Shift:
20 | return (QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0;
21 | default:
22 | assert(!"Invalid modifier key");
23 | return false;
24 | }
25 | }
26 |
27 |
28 | bool KeyboardState::is_key_pressed(Key key)
29 | {
30 | switch (key) {
31 | case Key::Left:
32 | return pressed_keys_.find(Qt::Key_Left) != pressed_keys_.end();
33 | case Key::Right:
34 | return pressed_keys_.find(Qt::Key_Right) != pressed_keys_.end();
35 | case Key::Up:
36 | return pressed_keys_.find(Qt::Key_Up) != pressed_keys_.end();
37 | case Key::Down:
38 | return pressed_keys_.find(Qt::Key_Down) != pressed_keys_.end();
39 | case Key::Plus:
40 | return pressed_keys_.find(Qt::Key_Plus) != pressed_keys_.end();
41 | case Key::Minus:
42 | return pressed_keys_.find(Qt::Key_Minus) != pressed_keys_.end();
43 | default:
44 | assert(!"Invalid key requested");
45 | return false;
46 | }
47 | }
48 |
49 |
50 | void KeyboardState::update_keyboard_state(const QEvent* event)
51 | {
52 | if (event->type() == QEvent::KeyPress) {
53 | pressed_keys_.insert(static_cast(event)->key());
54 | } else if (event->type() == QEvent::KeyRelease) {
55 | pressed_keys_.erase(static_cast(event)->key());
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/visualization/events.h:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef EVENTS_H_
27 | #define EVENTS_H_
28 |
29 | #include
30 |
31 | enum class EventProcessCode { IGNORED, INTERCEPTED };
32 |
33 | class MainWindow;
34 | class QEvent;
35 |
36 | class KeyboardState
37 | {
38 | public:
39 | friend class MainWindow;
40 |
41 | enum class ModifierKey { Control, Alt, Shift };
42 | enum class Key { Left, Right, Up, Down, Plus, Minus };
43 |
44 | static bool is_modifier_key_pressed(ModifierKey key);
45 |
46 | static bool is_key_pressed(Key key);
47 |
48 | private:
49 | static void update_keyboard_state(const QEvent* event);
50 |
51 | static std::set pressed_keys_;
52 | };
53 |
54 | #endif // EVENTS_H_
55 |
--------------------------------------------------------------------------------
/src/visualization/game_object.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2015-2017 GDB ImageWatch contributors
5 | * (github.com/csantosbh/gdb-imagewatch/)
6 | *
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy
8 | * of this software and associated documentation files (the "Software"), to
9 | * deal in the Software without restriction, including without limitation the
10 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 | * sell copies of the Software, and to permit persons to whom the Software is
12 | * furnished to do so, subject to the following conditions:
13 | *
14 | * The above copyright notice and this permission notice shall be included in
15 | * all copies or substantial portions of the Software.
16 | *
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 | * IN THE SOFTWARE.
24 | */
25 |
26 | #include
27 | #include