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