Graphviz 12.0.1~dev.20240716.0800
Loading...
Searching...
No Matches
gltemplate.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <stdbool.h>
12#include <stdlib.h>
13#include <math.h>
14#include "gui.h"
15#include "viewport.h"
16#include "gltemplate.h"
17#include <cgraph/exit.h>
18#include <glcomp/glutils.h>
19#include "glexpose.h"
20#include "glmotion.h"
21
22#include <glcomp/glcompset.h>
23#include "viewportcamera.h"
24#include "gui/menucallbacks.h"
25#include "arcball.h"
26#include "appmouse.h"
27static float begin_x = 0.0;
28static float begin_y = 0.0;
29static float dx = 0.0;
30static float dy = 0.0;
31
32/*mouse mode mapping funvtion from gtk to glcomp*/
34{
35 switch (n) {
36 case 1:
37 return glMouseLeftButton;
38 case 2:
40 case 3:
41 return glMouseRightButton;
42
43 default:
44 return glMouseLeftButton;
45 }
46}
47
48/*
49 initialize the gl , run only once!!
50 params:gtk opgn gl canvas and optional data pointer
51 return value:none
52*/
53static void realize(GtkWidget * widget, gpointer data)
54{
55 (void)data;
56
57 GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
58 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
59
60 /*smyrna does not use any ligthting affects but can be turned on for more effects in the future */
61 float ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
62 float diffuse[] = {0.5f, 0.5f, 0.5f, 1.0f};
63 float position[] = {0.0f, 3.0f, 3.0f, 0.0f};
64
65 float lmodel_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
66 float local_view[] = {0.0f};
67
68 /*** OpenGL BEGIN ***/
69 if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
70 return;
71
72 glClearColor(view->bgColor.R, view->bgColor.G, view->bgColor.B, view->bgColor.A); //background color
73 glClearDepth(1.0);
74 glClear(GL_COLOR_BUFFER_BIT);
75
76
77 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
78 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
79 glLightfv(GL_LIGHT0, GL_POSITION, position);
80 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
81 glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
82
83 glFrontFace(GL_CW);
84 glEnable(GL_BLEND);
85 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
86 gdk_gl_drawable_gl_end(gldrawable);
87 /*** OpenGL END ***/
88}
89
90/*
91 set up GL for window size changes, run this when necesary (when window size or monitor resolution is changed)
92 params:gtk opgn gl canvas , GdkEventConfigure object to retrieve window dimensions and custom data
93 return value:true or false, fails (false) if cannot init gl
94*/
95static gboolean configure_event(GtkWidget * widget,
96 GdkEventConfigure * event, gpointer data)
97{
98 (void)event;
99 (void)data;
100
101 int vPort[4];
102 float aspect;
103 GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
104 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
105 view->w = widget->allocation.width;
106 view->h = widget->allocation.height;
107 if (view->widgets)
109
110
111 /*** OpenGL BEGIN ***/
112 if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
113 return FALSE;
114 glViewport(0, 0, view->w, view->h);
115 /* get current viewport */
116 glGetIntegerv(GL_VIEWPORT, vPort);
117 /* setup various opengl things that we need */
118 glMatrixMode(GL_PROJECTION);
119 glLoadIdentity();
120 if (widget->allocation.width > 1)
121 init_arcBall(view->arcball, (float)view->w, (float)view->h);
122
123 if (view->w > view->h) {
124 aspect = (float) view->w / (float) view->h;
125 glOrtho(-aspect * GL_VIEWPORT_FACTOR, aspect * GL_VIEWPORT_FACTOR,
126 GL_VIEWPORT_FACTOR * -1, GL_VIEWPORT_FACTOR, -1500, 1500);
127 } else {
128 aspect = (float) view->h / (float) view->w;
130 -aspect * GL_VIEWPORT_FACTOR, aspect * GL_VIEWPORT_FACTOR,
131 -1500, 1500);
132 }
133
134 glMatrixMode(GL_MODELVIEW);
135 gdk_gl_drawable_gl_end(gldrawable);
136 /*** OpenGL END ***/
137
138
139 return TRUE;
140}
141
142/*
143 expose function.real drawing takes place here,
144 params:gtk opgn gl canvas , GdkEventExpose object and custom data
145 return value:true or false, fails (false) if cannot init gl
146*/
147gboolean expose_event(GtkWidget * widget, GdkEventExpose * event,
148 gpointer data)
149{
150 (void)event;
151 (void)data;
152
153 GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
154 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
155
156 /*** OpenGL BEGIN ***/
157 if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
158 return FALSE;
159 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
160 glLoadIdentity();
161 glexpose_main(view); //draw all stuff
162 /* Swap buffers */
163 if (gdk_gl_drawable_is_double_buffered(gldrawable))
164 gdk_gl_drawable_swap_buffers(gldrawable);
165 else
166 glFlush();
167 gdk_gl_drawable_gl_end(gldrawable);
168 /*** OpenGL END ***/
169 if (view->initFile) {
170 view->initFile = 0;
171 if (view->activeGraph == 0)
174 }
175 return TRUE;
176}
177
178/*
179 when a mouse button is clicked this function is called
180 params:gtk opgn gl canvas , GdkEventButton object and custom data
181 return value:true or false, fails (false) if cannot init gl
182*/
183static gboolean button_press_event(GtkWidget * widget,
184 GdkEventButton * event, gpointer data)
185{
186 (void)widget;
187 (void)data;
188
189 if (view->g == 0) return FALSE;
190
191 begin_x = (float) event->x;
192 begin_y = (float) event->y;
193 view->widgets->common.functions.mousedown((glCompObj*)view->widgets, (float)event->x, (float)event->y, getGlCompMouseType(event->button));
194 if (event->button == 1) //left click
195 appmouse_left_click_down(view,(int) event->x,(int) event->y);
196
197 if (event->button == 3) //right click
198 appmouse_right_click_down(view,(int) event->x,(int) event->y);
199 if (event->button == 2) //middle click
200 appmouse_middle_click_down(view,(int) event->x,(int) event->y);
201
203
204 return FALSE;
205}
206
207/*
208 when a mouse button is released(always after click) this function is called
209 params:gtk opgn gl canvas , GdkEventButton object and custom data
210 return value:true or false, fails (false) if cannot init gl
211*/
212static gboolean button_release_event(GtkWidget * widget,
213 GdkEventButton * event, gpointer data)
214{
215 (void)widget;
216 (void)data;
217
218 if (view->widgets == 0) return FALSE;
219 view->arcball->isDragging = 0;
220 view->widgets->common.functions.mouseup((glCompObj*)view->widgets, (float)event->x, (float)event->y, getGlCompMouseType(event->button));
221
222
223 if (event->button == 1) //left click release
224 appmouse_left_click_up(view,(int) event->x,(int) event->y);
225 if (event->button == 3) //right click
226 appmouse_right_click_up(view,(int) event->x,(int) event->y);
227 if (event->button == 2) //right click
228 appmouse_middle_click_up(view,(int) event->x,(int) event->y);
229
231 dx = 0.0;
232 dy = 0.0;
233
234 return FALSE;
235}
236static gboolean key_press_event(GtkWidget * widget, GdkEventKey * event, gpointer data)
237{
238 (void)widget;
239 (void)data;
240
241 appmouse_key_press(view,event->keyval);
242 return FALSE;
243}
244static gboolean key_release_event(GtkWidget * widget, GdkEventKey * event, gpointer data)
245{
246 (void)widget;
247 (void)event;
248 (void)data;
249
251 return FALSE;
252}
253
254
255static gboolean
256scroll_event(GtkWidget * widget, GdkEventScroll * event, gpointer data)
257{
258 (void)widget;
259 (void)data;
260
261 gdouble seconds;
262
263 seconds = g_timer_elapsed(view->timer2, NULL);
264 if (seconds > 0.005) {
265 g_timer_stop(view->timer2);
266 if (event->direction == 0)
267 view->mouse.dragX = -30;
268 if (event->direction == 1)
269 view->mouse.dragX = +30;
271 glexpose();
272 g_timer_start(view->timer2);
273
274 }
275 return TRUE;
276}
277
278/*
279 when mouse is moved over glcanvas this function is called
280 params:gtk opgn gl canvas , GdkEventMotion object and custom data
281 return value:always TRUE !!!
282*/
283static gboolean motion_notify_event(GtkWidget * widget,
284 GdkEventMotion * event, gpointer data)
285{
286 (void)data;
287
288 float x = (float) event->x;
289 float y = (float) event->y;
290
291 bool redraw = false;
292 if (view->widgets)
294
295 dx = x - begin_x;
296 dy = y - begin_y;
297 view->mouse.dragX = dx;
298 view->mouse.dragY = dy;
299 appmouse_move(view,(int)event->x,(int)event->y);
300
302 {
303 appmouse_left_drag(view,(int)event->x,(int)event->y);
304 redraw = true;
305
306 }
308 {
309 appmouse_right_drag(view,(int)event->x,(int)event->y);
310 redraw = true;
311 }
313 {
314 appmouse_middle_drag(view,(int)event->x,(int)event->y);
315 redraw = true;
316 }
317 if(view->Topview->sel.selPoly.cnt > 0)
318 redraw = true;
319
320 begin_x = x;
321 begin_y = y;
322
323
324 if (redraw)
325 gdk_window_invalidate_rect(widget->window, &widget->allocation,FALSE);
326 return TRUE;
327}
328
329/*
330 configures various opengl settings
331 params:none
332 return value:GdkGLConfig object
333*/
334GdkGLConfig *configure_gl(void)
335{
336 GdkGLConfig *glconfig;
337 /* Try double-buffered visual */
338 glconfig = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB |
339 GDK_GL_MODE_DEPTH |
340 GDK_GL_MODE_DOUBLE);
341 if (glconfig == NULL) {
342 g_print("\n*** Cannot find the double-buffered visual.\n");
343 g_print("\n*** Trying single-buffered visual.\n");
344
345 /* Try single-buffered visual */
346 glconfig = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB |
347 GDK_GL_MODE_DEPTH);
348 if (glconfig == NULL) {
349 g_print("*** No appropriate OpenGL-capable visual found.\n");
350 graphviz_exit(1);
351 }
352 }
353
354 return glconfig;
355}
356
357/*
358 run this function only once to create and customize gtk based opengl canvas
359 all signal, socket connections are done here for opengl interractions
360 params:gl config object, gtk container widget for opengl canvas
361 return value:none
362*/
363void create_window(GdkGLConfig * glconfig, GtkWidget * vbox)
364{
365 gint major, minor;
366
367 /*
368 * Query OpenGL extension version.
369 */
370
371 gdk_gl_query_version(&major, &minor);
372
373 /* Try double-buffered visual */
374
375 /* Drawing area for drawing OpenGL scene. */
376 view->drawing_area = gtk_drawing_area_new();
377 gtk_widget_set_size_request(view->drawing_area, 300, 300);
378 /* Set OpenGL-capability to the widget. */
379 gtk_widget_set_gl_capability(view->drawing_area,
380 glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
381
382 gtk_widget_add_events(view->drawing_area,
383 GDK_BUTTON_MOTION_MASK |
384 GDK_POINTER_MOTION_MASK |
385 GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS |
386 GDK_BUTTON_RELEASE_MASK |
387 GDK_SCROLL | GDK_VISIBILITY_NOTIFY_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK );
388
389 g_signal_connect_after(G_OBJECT(view->drawing_area), "realize",
390 G_CALLBACK(realize), NULL);
391 g_signal_connect(G_OBJECT(view->drawing_area), "configure_event",
392 G_CALLBACK(configure_event), NULL);
393 g_signal_connect(G_OBJECT(view->drawing_area), "expose_event",
394 G_CALLBACK(expose_event), NULL);
395
396 g_signal_connect(G_OBJECT(view->drawing_area), "button_press_event",
397 G_CALLBACK(button_press_event), NULL);
398
399 g_signal_connect(G_OBJECT(view->drawing_area), "button_release_event",G_CALLBACK(button_release_event), NULL);
400 g_signal_connect(G_OBJECT(view->drawing_area), "key_release_event", G_CALLBACK(key_release_event), NULL);
401 g_signal_connect(G_OBJECT(view->drawing_area), "key_press_event", G_CALLBACK(key_press_event), NULL);
402 g_signal_connect(G_OBJECT(view->drawing_area), "scroll_event",
403 G_CALLBACK(scroll_event), NULL);
404
405 g_signal_connect(G_OBJECT(view->drawing_area), "motion_notify_event",
406 G_CALLBACK(motion_notify_event), NULL);
407
408 gtk_box_pack_start(GTK_BOX(vbox), view->drawing_area, TRUE, TRUE, 0);
409
410 gtk_widget_show(view->drawing_area);
411
412
413
414 gtk_widget_add_events(glade_xml_get_widget(xml, "frmMain"),
415 GDK_BUTTON_MOTION_MASK |
416 GDK_POINTER_MOTION_MASK |
417 GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS |
418 GDK_BUTTON_RELEASE_MASK |
419 GDK_SCROLL | GDK_VISIBILITY_NOTIFY_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK );
420
421
422 g_signal_connect(G_OBJECT(glade_xml_get_widget(xml, "frmMain")), "key_release_event", G_CALLBACK(key_release_event), NULL);
423 g_signal_connect(G_OBJECT(glade_xml_get_widget(xml, "frmMain")), "key_press_event", G_CALLBACK(key_press_event), NULL);
424}
void appmouse_left_click_up(ViewInfo *v, int x, int y)
Definition appmouse.c:112
void appmouse_right_drag(ViewInfo *v, int x, int y)
Definition appmouse.c:135
void appmouse_middle_click_up(ViewInfo *v, int x, int y)
Definition appmouse.c:150
void appmouse_right_click_up(ViewInfo *v, int x, int y)
Definition appmouse.c:130
void appmouse_key_release(ViewInfo *v)
Definition appmouse.c:165
void appmouse_move(ViewInfo *v, int x, int y)
Definition appmouse.c:161
void appmouse_key_press(ViewInfo *v, int key)
Definition appmouse.c:175
void appmouse_middle_drag(ViewInfo *v, int x, int y)
Definition appmouse.c:155
void appmouse_middle_click_down(ViewInfo *v, int x, int y)
Definition appmouse.c:143
void appmouse_left_click_down(ViewInfo *v, int x, int y)
Definition appmouse.c:105
void appmouse_right_click_down(ViewInfo *v, int x, int y)
Definition appmouse.c:123
void appmouse_left_drag(ViewInfo *v, int x, int y)
Definition appmouse.c:116
void init_arcBall(ArcBall_t *a, float NewWidth, float NewHeight)
Definition arcball.c:88
static NORETURN void graphviz_exit(int status)
Definition exit.h:23
glMouseButtonType
Definition glcompdefs.h:89
@ glMouseRightButton
Definition glcompdefs.h:89
@ glMouseMiddleButton
Definition glcompdefs.h:90
@ glMouseLeftButton
Definition glcompdefs.h:89
void glcompsetUpdateBorder(glCompSet *s, int w, int h)
Definition glcompset.c:252
int glexpose_main(ViewInfo *vi)
Definition glexpose.c:153
void glmotion_zoom(void)
Definition glmotion.c:54
static float begin_x
Definition gltemplate.c:27
static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
Definition gltemplate.c:95
static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
Definition gltemplate.c:183
static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data)
Definition gltemplate.c:256
static void realize(GtkWidget *widget, gpointer data)
Definition gltemplate.c:53
static float dy
Definition gltemplate.c:30
static float begin_y
Definition gltemplate.c:28
static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
Definition gltemplate.c:236
static float dx
Definition gltemplate.c:29
static glMouseButtonType getGlCompMouseType(int n)
Definition gltemplate.c:33
static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
Definition gltemplate.c:283
static gboolean key_release_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
Definition gltemplate.c:244
static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
Definition gltemplate.c:212
GdkGLConfig * configure_gl(void)
Definition gltemplate.c:334
void create_window(GdkGLConfig *glconfig, GtkWidget *vbox)
Definition gltemplate.c:363
gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
Definition gltemplate.c:147
node NULL
Definition grammar.y:149
GladeXML * xml
Definition gui.c:22
ViewInfo * view
Definition viewport.c:38
#define GL_VIEWPORT_FACTOR
Definition smyrnadefs.h:39
void glexpose(void)
Definition viewport.c:543
int isDragging
Definition arcball.h:554
ArcBall_t * arcball
Definition smyrnadefs.h:365
topview * Topview
Definition smyrnadefs.h:334
Agraph_t ** g
Definition smyrnadefs.h:313
glCompSet * widgets
Definition smyrnadefs.h:358
char * initFileName
Definition smyrnadefs.h:359
GTimer * timer2
Definition smyrnadefs.h:338
int activeGraph
Definition smyrnadefs.h:317
glCompColor bgColor
Definition smyrnadefs.h:281
GtkWidget * drawing_area
Definition smyrnadefs.h:331
glCompMouse mouse
Definition smyrnadefs.h:321
glCompPoly selPoly
Definition smyrnadefs.h:231
Definition legal.c:50
glcompmouseupfunc_t mouseup
Definition glcompdefs.h:197
glcompmousedownfunc_t mousedown
Definition glcompdefs.h:196
glcompmouseoverfunc_t mouseover
Definition glcompdefs.h:193
glCompCallBacks functions
Definition glcompdefs.h:223
glMouseButtonType t
Definition glcompdefs.h:278
glCompCommon common
Definition glcompdefs.h:298
selection sel
Definition smyrnadefs.h:259
void close_graph(ViewInfo *vi)
Definition viewport.c:74
int add_graph_to_viewport_from_file(char *fileName)
Definition viewport.c:364