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 
41 struct vice_renderer_backend_s;
42 
43 /**
44  * \brief Master data structure for a machine window's primary display.
45  */
46 typedef struct video_canvas_s {
47     /** \brief Nonzero if it is safe to access other members of the
48      *         structure. */
49     unsigned int initialized;
50     /** \brief Nonzero if the structure has been fully realized. */
51     unsigned int created;
52 
53     /** \brief Top-level widget that contains the full contents of the
54      *         machine window. */
55     GtkWidget *grid;
56     /** \brief Child widget to which the emulated screen is drawn.
57      *
58      *  Depending on what renderer backend is in use this will be
59      *  either a GtkDrawingArea or a GtkGLArea. */
60     GtkWidget *drawing_area;
61     /** \brief The renderer backend selected for use this run. */
62     struct vice_renderer_backend_s *renderer_backend;
63     /** \brief Data unique to the renderer backend. This value is
64      *         passed to all renderer methods. and is managed by
65      *         them. */
66     void *renderer_context;
67     /** \brief Special "blank" cursor for cases where the mouse
68      *         pointer should disappear. */
69     GdkCursor *blank_ptr;
70     /** \brief Special "target" cursor for active light pens. */
71     GdkCursor *pen_ptr;
72     /** \brief Number of frames the mouse hasn't moved while still on
73      *         the canvas. */
74     unsigned int still_frames;
75     /** \brief Handle to the timer callback that will make the mouse
76      *         disappear if it's hovered for too long over the screen
77      *         display. */
78     guint still_frame_callback_id;
79     /** \brief Light pen X coordinate, in window coordinates. */
80     int pen_x;
81     /** \brief Light pen Y coordinate, in window coordinates. */
82     int pen_y;
83     /** \brief Light pen button status. */
84     int pen_buttons;
85     /** \brief Leftmost X coordinate of the actual machine's screen,
86      *         in window coordinates. */
87     double screen_origin_x;
88     /** \brief Topmost Y coordinate of the actual machine's screen, in
89      *         window coordinates. */
90     double screen_origin_y;
91     /** \brief Width of the actual machine's screen, in window
92      *         coordinates. */
93     double screen_display_w;
94     /** \brief Height of the actual machine's screen, in window
95      *         coordinates. */
96     double screen_display_h;
97 
98     /** \brief Rendering configuration as seen by the emulator
99      *         core. */
100     struct video_render_config_s *videoconfig;
101     /** \brief Drawing buffer as seen by the emulator core. */
102     struct draw_buffer_s *draw_buffer;
103     /** \brief Display window as seen by the emulator core. */
104     struct viewport_s *viewport;
105     /** \brief Machine screen geometry as seen by the emulator
106      *         core. */
107     struct geometry_s *geometry;
108     /** \brief Color palette for translating display results into
109      *         window colors. */
110     struct palette_s *palette;
111     /** \brief Methods for managing the draw buffer when the core
112      *         rasterizer handles it. */
113     struct video_draw_buffer_callback_s *video_draw_buffer_callback;
114 
115     /** \brief Which window contains this canvas.
116      *  \sa ui_resources_s::canvas The array this value indexes */
117     int window_index;
118 } video_canvas_t;
119 
120 /** \brief Rescale and reposition the screen inside the canvas if the
121  *         screen's size has been programatically changed.
122  *  \param canvas The canvas to adjust.
123  */
124 void video_canvas_adjust_aspect_ratio(struct video_canvas_s *canvas);
125 
126 /** \brief A collection of methods that abstract away the underlying
127  *         display API.
128  *
129  *  GTK3's default software rendering (Cairo) and its accelerated one
130  *  (OpenGL) use very different mechanisms for displaying (possibly
131  *  scaled) pixel content or incrementally updating it. These routines
132  *  let us keep those differences contained. */
133 typedef struct vice_renderer_backend_s {
134     /** \brief Creates a widget suitable for this renderer to target.
135      *
136      *  Also initializes the opaque video_canvas_s::renderer_context
137      *  field if needed, and sets other necessary fields.
138      *
139      *  \param canvas The canvas to create the widget for.
140      *  \return The newly created canvas.
141      */
142     GtkWidget *(*create_widget)(video_canvas_t *canvas);
143     /** \brief Creates or resizes the pixel buffer that this renderer
144      *         backend is using for the screen.
145      *
146      * This is an expensive operation if the width and height have
147      * changed since the last call.
148      *
149      * \param canvas The canvas being resized or initially created.
150      * \param width The new width for the machine's screen.
151      * \param height The new height for the machine's screen.
152      */
153     void (*update_context)(video_canvas_t *canvas,
154                            unsigned int width, unsigned int height);
155     /** \brief Clean up any resources used by this renderer backend,
156      *         in preparation for destruction or recreation.
157      *
158      *  \param canvas The canvas whose renderer_context is to be
159      *                deleted
160      */
161     void (*destroy_context)(video_canvas_t *canvas);
162     /** \brief Render pixels in the specified rectangle.
163      *
164      * This both asks the emulator core to update the renderer context
165      * and asks the UI to display the changed results.
166      *
167      * \param canvas The canvas being rendered to
168      * \param xs     A parameter to forward to video_canvas_render()
169      * \param ys     A parameter to forward to video_canvas_render()
170      * \param xi     X coordinate of the leftmost pixel to update
171      * \param yi     Y coordinate of the topmost pixel to update
172      * \param w      Width of the rectangle to update
173      * \param h      Height of the rectangle to update
174      */
175     void (*refresh_rect)(video_canvas_t *canvas,
176                          unsigned int xs, unsigned int ys,
177                          unsigned int xi, unsigned int yi,
178                          unsigned int w, unsigned int h);
179     /** \brief Initialize the palette for this renderer.
180      *
181      * \param canvas The canvas being initialized
182      */
183     void (*set_palette)(video_canvas_t *canvas);
184 } vice_renderer_backend_t;
185 
186 #endif
187