1 /** 2 * \file videoarch.h 3 * \brief Native GTK3 graphics routines 4 * 5 * \author Ettore Perazzoli 6 * \author Teemu Rantanen <tvr@cs.hut.fi> 7 * \author Andreas Boose <viceteam@t-online.de> 8 * \author Michael C. Martin <mcmartin@gmail.com> 9 */ 10 11 /* 12 * This file is part of VICE, the Versatile Commodore Emulator. 13 * See README for copyright notice. 14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; if not, write to the Free Software 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28 * 02111-1307 USA. 29 * 30 */ 31 #ifndef VICE_VIDEOARCH_H 32 #define VICE_VIDEOARCH_H 33 34 #include "vice.h" 35 36 #include "viewport.h" 37 #include "video.h" 38 39 #include <gtk/gtk.h> 40 #include <pthread.h> 41 42 43 /** \brief Enum for rendering backends for the Gtk3 port 44 * 45 * Currently OpenGL and DirectX map to the same integer value since that's how 46 * our current 'GtkBackend' resource works: 0 = Cario (SW), 1 = HW (OS-dependent). 47 * The Metal and Vulkan enums are added for future renderers, should we add them. 48 */ 49 enum { 50 VICE_RENDER_BACKEND_CAIRO = 0, /**< Cairo (software) rendering */ 51 VICE_RENDER_BACKEND_OPENGL = 1, /**< OpenGL rendering (unix, mac) */ 52 VICE_RENDER_BACKEND_DIRECTX = 1, /**< DirectX rendering (windows) */ 53 VICE_RENDER_BACKEND_METAL = 2, /**< Metal rendering (unsupported) */ 54 VICE_RENDER_BACKEND_VULKAN = 3 /**< Vulkan rendering (unsupported) */ 55 }; 56 57 58 struct vice_renderer_backend_s; 59 60 /** 61 * \brief Master data structure for a machine window's primary display. 62 */ 63 typedef struct video_canvas_s { 64 /** \brief Nonzero if it is safe to access other members of the 65 * structure. */ 66 unsigned int initialized; 67 68 /** \brief Nonzero if the structure has been fully realized. */ 69 unsigned int created; 70 71 /** \brief Used to coordinate vice thread access */ 72 pthread_mutex_t lock; 73 74 /** \brief Top-level widget that contains the full contents of the 75 * machine window. */ 76 GtkWidget *grid; 77 78 /** \brief Widget for mouse input and to size the rendering overlay. 79 */ 80 GtkWidget *event_box; 81 82 /** \brief The renderer backend selected for use this run. */ 83 struct vice_renderer_backend_s *renderer_backend; 84 85 /** \brief Data unique to the renderer backend. This value is 86 * passed to all renderer methods. and is managed by 87 * them. */ 88 void *renderer_context; 89 90 /** \brief Special "blank" cursor for cases where the mouse 91 * pointer should disappear. */ 92 GdkCursor *blank_ptr; 93 94 /** \brief Special "target" cursor for active light pens. */ 95 GdkCursor *pen_ptr; 96 97 /** \brief Handle to the timer callback that will make the mouse 98 * disappear if it's hovered for too long over the screen 99 * display. */ 100 guint still_frame_callback_id; 101 102 /** \brief Light pen X coordinate, in window coordinates. */ 103 int pen_x; 104 105 /** \brief Light pen Y coordinate, in window coordinates. */ 106 int pen_y; 107 108 /** \brief Light pen button status. */ 109 int pen_buttons; 110 111 /** \brief Leftmost X coordinate of the actual machine's screen, 112 * in window coordinates. */ 113 double screen_origin_x; 114 115 /** \brief Topmost Y coordinate of the actual machine's screen, in 116 * window coordinates. */ 117 double screen_origin_y; 118 119 /** \brief Width of the actual machine's screen, in window 120 * coordinates. */ 121 double screen_display_w; 122 123 /** \brief Height of the actual machine's screen, in window 124 * coordinates. */ 125 double screen_display_h; 126 127 /** \brief Rendering configuration as seen by the emulator 128 * core. */ 129 struct video_render_config_s *videoconfig; 130 131 /** \brief Drawing buffer as seen by the emulator core. */ 132 struct draw_buffer_s *draw_buffer; 133 134 /** \brief Display window as seen by the emulator core. */ 135 struct viewport_s *viewport; 136 137 /** \brief Machine screen geometry as seen by the emulator 138 * core. */ 139 struct geometry_s *geometry; 140 141 /** \brief Color palette for translating display results into 142 * window colors. */ 143 struct palette_s *palette; 144 145 /** \brief Methods for managing the draw buffer when the core 146 * rasterizer handles it. */ 147 struct video_draw_buffer_callback_s *video_draw_buffer_callback; 148 149 /** \brief Which window contains this canvas. 150 * \sa ui_resources_s::canvas The array this value indexes */ 151 int window_index; 152 } video_canvas_t; 153 154 /** \brief Rescale and reposition the screen inside the canvas if the 155 * screen's size has been programatically changed. 156 * \param canvas The canvas to adjust. 157 */ 158 void video_canvas_adjust_aspect_ratio(struct video_canvas_s *canvas); 159 160 /** \brief A collection of methods that abstract away the underlying 161 * display API. 162 * 163 * GTK3's default software rendering (Cairo) and its accelerated one 164 * (OpenGL) use very different mechanisms for displaying (possibly 165 * scaled) pixel content or incrementally updating it. These routines 166 * let us keep those differences contained. */ 167 typedef struct vice_renderer_backend_s { 168 /** \brief Add event handlers to the event box and create context. 169 * 170 * \param canvas The canvas to initialise. 171 * \return The newly created widget. 172 */ 173 void (*initialise)(video_canvas_t *canvas); 174 /** \brief Creates or resizes the pixel buffer that this renderer 175 * backend is using for the screen. 176 * 177 * This is an expensive operation if the width and height have 178 * changed since the last call. 179 * 180 * \param canvas The canvas being resized or initially created. 181 * \param width The new width for the machine's screen. 182 * \param height The new height for the machine's screen. 183 */ 184 void (*update_context)(video_canvas_t *canvas, 185 unsigned int width, unsigned int height); 186 /** \brief Clean up any resources used by this renderer backend, 187 * in preparation for destruction or recreation. 188 * 189 * \param canvas The canvas whose renderer_context is to be 190 * deleted 191 */ 192 void (*destroy_context)(video_canvas_t *canvas); 193 /** \brief Render pixels in the specified rectangle. 194 * 195 * This asks the emulator core to update the renderer context. 196 * 197 * \param canvas The canvas being rendered to 198 * \param xs A parameter to forward to video_canvas_render() 199 * \param ys A parameter to forward to video_canvas_render() 200 * \param xi X coordinate of the leftmost pixel to update 201 * \param yi Y coordinate of the topmost pixel to update 202 * \param w Width of the rectangle to update 203 * \param h Height of the rectangle to update 204 */ 205 void (*refresh_rect)(video_canvas_t *canvas, 206 unsigned int xs, unsigned int ys, 207 unsigned int xi, unsigned int yi, 208 unsigned int w, unsigned int h); 209 /** \brief Queue a redraw operation from the UI thread 210 * 211 * \param clock The window GtkFrameClock generating the event 212 * \param widget UI widget to queue a redraw for 213 */ 214 void (*queue_redraw)(GdkFrameClock *clock, video_canvas_t *canvas); 215 /** \brief Initialize the palette for this renderer. 216 * 217 * \param canvas The canvas being initialized 218 */ 219 void (*set_palette)(video_canvas_t *canvas); 220 } vice_renderer_backend_t; 221 222 #endif 223