pidgin/pidgin
Clone
Summary
Browse
Changes
Graph
ChangeLog the external SASL fix
release-2.x.y
v2.12.0
2017-03-09, Gary Kramlich
0241f07ed2ba
ChangeLog the external SASL fix
#include
<assert.h>
#include
<stdio.h>
#include
<GL/gl.h>
#include
<GL/glu.h>
#include
"cc_gtk_gl.h"
#include
"util.h"
static
GdkGLConfig
*
glconfig
=
NULL
;
/**
* Resets the OpenGL viewport stuff on widget reconfiguration (resize,
* reposition)
* @param widget widget that got reconfigured
* @param event the configuration event
* @param data unused
* @return FALSE to propagate other handlers
*/
static
gboolean
configure_event
(
GtkWidget
*
widget
,
GdkEventConfigure
*
event
,
void
*
data
);
/**
* Maps the widget to the screen.
* @param widget widget that got mapped
* @param event the map event
* @param data draw info struct
* @return FALSE to propagate other handlers
*/
static
gboolean
map_event
(
GtkWidget
*
widget
,
GdkEventAny
*
event
,
void
*
data
);
/**
* Unmaps the widget from the screen.
* @param widget widget that got unmapped
* @param event the configuration event
* @param data draw info struct
* @return FALSE to propagate other handlers
*/
static
gboolean
unmap_event
(
GtkWidget
*
widget
,
GdkEventAny
*
event
,
void
*
data
);
/**
* Respond to widget visibility change.
* @param widget widget whose visibility changed
* @param event the visibility event
* @param data draw info struct
* @return FALSE to propagate other handlers
*/
static
gboolean
visibility_notify_event
(
GtkWidget
*
widget
,
GdkEventVisibility
*
event
,
void
*
data
);
/**
* Add a glib timer to periodically draw the widget.
* @param widget widget we're drawing
* @param info draw info struct
*/
static
void
widget_draw_timer_add
(
GtkWidget
*
widget
,
struct
draw_info
*
info
);
/**
* Remove glib timer that was drawing this widget.
* @param widget widget we're drawing
* @param info draw info struct
*/
static
void
widget_draw_timer_remove
(
GtkWidget
*
widget
,
struct
draw_info
*
info
);
/**
* Periodically invalidates gtk gl widget and tells GTK to redraw
* @param widget widget we're drawing
*/
static
gboolean
widget_draw_timer
(
GtkWidget
*
widget
);
/**
* Cleanup widget stuff when it's getting destroyed.
* @param widget widget that got destroyed
* @param data draw info struct
*/
static
void
destroy_event
(
GtkWidget
*
widget
,
struct
draw_info
*
data
);
int
cc_init_gtk_gl
()
{
if
(
glconfig
)
return
0
;
/* configure OpenGL */
glconfig
=
gdk_gl_config_new_by_mode
(
GDK_GL_MODE_RGB
|
GDK_GL_MODE_DEPTH
|
GDK_GL_MODE_DOUBLE
);
if
(
glconfig
==
NULL
)
{
Debug
(
"*** Cannot find the double-buffered visual.
\n
"
);
Debug
(
"*** Trying single-buffered visual.
\n
"
);
/* Try single-buffered visual */
glconfig
=
gdk_gl_config_new_by_mode
(
GDK_GL_MODE_RGB
|
GDK_GL_MODE_DEPTH
);
if
(
glconfig
==
NULL
)
{
Debug
(
"*** No appropriate OpenGL-capable visual "
"found.
\n
"
);
return
1
;
}
}
return
0
;
}
void
cc_new_gl_window
(
gl_init_func
init
,
gl_config_func
config
,
gl_draw_func
draw
,
struct
draw_info
*
data
,
struct
window_box
*
ret
)
{
GtkWidget
*
window
;
GtkWidget
*
vbox
;
GtkWidget
*
drawing_area
;
window
=
gtk_window_new
(
GTK_WINDOW_TOPLEVEL
);
gtk_container_set_reallocate_redraws
(
GTK_CONTAINER
(
window
),
TRUE
);
vbox
=
gtk_vbox_new
(
FALSE
,
0
);
gtk_container_add
(
GTK_CONTAINER
(
window
),
vbox
);
gtk_widget_show
(
vbox
);
if
(
!
data
)
{
data
=
(
struct
draw_info
*
)
malloc
(
sizeof
(
*
data
));
assert
(
data
);
memset
(
data
,
0
,
sizeof
(
*
data
));
data
->
timeout
=
TRUE
;
data
->
delay_ms
=
DEFAULT_FRAME_DELAY
;
}
drawing_area
=
cc_new_gl_area
(
init
,
config
,
draw
,
data
);
gtk_box_pack_start
(
GTK_BOX
(
vbox
),
drawing_area
,
TRUE
,
TRUE
,
0
);
gtk_widget_show
(
drawing_area
);
ret
->
window
=
window
;
ret
->
vbox
=
vbox
;
ret
->
draw_area
=
drawing_area
;
}
GtkWidget
*
cc_new_gl_area
(
gl_init_func
init
,
gl_config_func
config
,
gl_draw_func
draw
,
struct
draw_info
*
data
)
{
GtkWidget
*
drawing_area
;
assert
(
data
);
drawing_area
=
gtk_drawing_area_new
();
assert
(
drawing_area
);
assert
(
gtk_widget_set_gl_capability
(
drawing_area
,
glconfig
,
NULL
,
FALSE
,
GDK_GL_RGBA_TYPE
));
gtk_widget_add_events
(
drawing_area
,
GDK_VISIBILITY_NOTIFY_MASK
);
if
(
init
)
{
g_signal_connect_after
(
G_OBJECT
(
drawing_area
),
"realize"
,
G_CALLBACK
(
init
),
data
->
data
);
}
if
(
config
)
{
g_signal_connect
(
G_OBJECT
(
drawing_area
),
"configure_event"
,
G_CALLBACK
(
config
),
NULL
);
}
else
{
g_signal_connect
(
G_OBJECT
(
drawing_area
),
"configure_event"
,
G_CALLBACK
(
configure_event
),
NULL
);
}
if
(
draw
)
{
g_signal_connect
(
G_OBJECT
(
drawing_area
),
"expose_event"
,
G_CALLBACK
(
draw
),
data
->
data
);
}
g_signal_connect
(
G_OBJECT
(
drawing_area
),
"map_event"
,
G_CALLBACK
(
map_event
),
data
);
g_signal_connect
(
G_OBJECT
(
drawing_area
),
"unmap_event"
,
G_CALLBACK
(
unmap_event
),
data
);
g_signal_connect
(
G_OBJECT
(
drawing_area
),
"visibility_notify_event"
,
G_CALLBACK
(
visibility_notify_event
),
data
);
g_signal_connect
(
G_OBJECT
(
drawing_area
),
"destroy"
,
G_CALLBACK
(
destroy_event
),
data
);
return
drawing_area
;
}
static
gboolean
configure_event
(
GtkWidget
*
widget
,
GdkEventConfigure
*
event
,
void
*
data
)
{
GdkGLContext
*
glcontext
=
gtk_widget_get_gl_context
(
widget
);
GdkGLDrawable
*
gldrawable
=
gtk_widget_get_gl_drawable
(
widget
);
GLfloat
w
=
widget
->
allocation
.
width
;
GLfloat
h
=
widget
->
allocation
.
height
;
GLfloat
aspect
;
// Debug("configuring\n");
/*** OpenGL BEGIN ***/
if
(
!
gdk_gl_drawable_gl_begin
(
gldrawable
,
glcontext
))
return
FALSE
;
glViewport
(
0
,
0
,
w
,
h
);
glMatrixMode
(
GL_PROJECTION
);
glLoadIdentity
();
if
(
w
>
h
)
{
aspect
=
w
/
h
;
glFrustum
(
-
aspect
,
aspect
,
-1.0
,
1.0
,
2.0
,
60.0
);
}
else
{
aspect
=
h
/
w
;
glFrustum
(
-1.0
,
1.0
,
-
aspect
,
aspect
,
2.0
,
60.0
);
}
glMatrixMode
(
GL_MODELVIEW
);
glLoadIdentity
();
gdk_gl_drawable_gl_end
(
gldrawable
);
/*** OpenGL END ***/
return
FALSE
;
}
static
int
map_event
(
GtkWidget
*
widget
,
GdkEventAny
*
event
,
void
*
data
)
{
struct
draw_info
*
info
=
(
struct
draw_info
*
)
data
;
Debug
(
"map
\n
"
);
if
(
info
->
timeout
)
{
widget_draw_timer_add
(
widget
,
info
);
}
return
FALSE
;
}
static
int
unmap_event
(
GtkWidget
*
widget
,
GdkEventAny
*
event
,
void
*
data
)
{
struct
draw_info
*
info
=
(
struct
draw_info
*
)
data
;
Debug
(
"unmap
\n
"
);
if
(
info
->
timeout
)
{
widget_draw_timer_remove
(
widget
,
info
);
}
return
FALSE
;
}
static
int
visibility_notify_event
(
GtkWidget
*
widget
,
GdkEventVisibility
*
event
,
void
*
data
)
{
struct
draw_info
*
info
=
(
struct
draw_info
*
)
data
;
Debug
(
"visibility
\n
"
);
if
(
event
->
state
==
GDK_VISIBILITY_FULLY_OBSCURED
)
{
Debug
(
"obscured
\n
"
);
if
(
info
->
timeout
)
{
widget_draw_timer_remove
(
widget
,
info
);
}
}
else
{
Debug
(
"visible
\n
"
);
if
(
info
->
timeout
)
{
widget_draw_timer_add
(
widget
,
info
);
}
}
return
FALSE
;
}
static
void
widget_draw_timer_add
(
GtkWidget
*
widget
,
struct
draw_info
*
info
)
{
if
(
!
info
->
timer_id
)
{
info
->
timer_id
=
g_timeout_add
(
info
->
delay_ms
,
(
GSourceFunc
)
widget_draw_timer
,
widget
);
}
}
static
void
widget_draw_timer_remove
(
GtkWidget
*
widget
,
struct
draw_info
*
info
)
{
if
(
info
->
timer_id
)
{
g_source_remove
(
info
->
timer_id
);
info
->
timer_id
=
0
;
}
}
static
gboolean
widget_draw_timer
(
GtkWidget
*
widget
)
{
/* invalidate the window */
gdk_window_invalidate_rect
(
widget
->
window
,
&
widget
->
allocation
,
FALSE
);
/* tell gtk to update it _now_ */
gdk_window_process_updates
(
widget
->
window
,
FALSE
);
return
TRUE
;
}
static
void
destroy_event
(
GtkWidget
*
widget
,
struct
draw_info
*
data
)
{
Debug
(
"destroying widget
\n
"
);
if
(
data
)
{
widget_draw_timer_remove
(
widget
,
data
);
free
(
data
);
}
}