1 /* Libvisual - The audio visualisation framework.
2  *
3  * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
4  *
5  * Authors: Dennis Smit <ds@nerds-incorporated.org>
6  *
7  * $Id:
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as
11  * published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 
29 #include "lvconfig.h"
30 #include "lv_log.h"
31 #include "lv_list.h"
32 #include "lv_transform.h"
33 #include "lv_mem.h"
34 
35 extern VisList *__lv_plugins_transform;
36 
37 static int transform_dtor (VisObject *object);
38 
39 static VisTransformPlugin *get_transform_plugin (VisTransform *transform);
40 
41 
transform_dtor(VisObject * object)42 static int transform_dtor (VisObject *object)
43 {
44 	VisTransform *transform = VISUAL_TRANSFORM (object);
45 
46 	if (transform->plugin != NULL)
47 		visual_plugin_unload (transform->plugin);
48 
49 	transform->plugin = NULL;
50 
51 	return VISUAL_OK;
52 }
53 
get_transform_plugin(VisTransform * transform)54 static VisTransformPlugin *get_transform_plugin (VisTransform *transform)
55 {
56 	VisTransformPlugin *transplugin;
57 
58 	visual_log_return_val_if_fail (transform != NULL, NULL);
59 	visual_log_return_val_if_fail (transform->plugin != NULL, NULL);
60 
61 	transplugin = VISUAL_PLUGIN_TRANSFORM (transform->plugin->info->plugin);
62 
63 	return transplugin;
64 }
65 
66 /**
67  * @defgroup VisTransform VisTransform
68  * @{
69  */
70 
71 /**
72  * Gives the encapsulated VisPluginData from a VisTransform.
73  *
74  * @param transform Pointer of a VisTransform of which the VisPluginData needs to be returned.
75  *
76  * @return VisPluginData that is encapsulated in the VisTransform, possibly NULL.
77  */
visual_transform_get_plugin(VisTransform * transform)78 VisPluginData *visual_transform_get_plugin (VisTransform *transform)
79 {
80 	return transform->plugin;
81 }
82 
83 /**
84  * Gives a list of VisTransforms in the current plugin registry.
85  *
86  * @return An VisList containing the VisTransforms in the plugin registry.
87  */
visual_transform_get_list()88 VisList *visual_transform_get_list ()
89 {
90 	return __lv_plugins_transform;
91 }
92 
93 /**
94  * Gives the next transform plugin based on the name of a plugin.
95  *
96  * @see visual_transform_get_prev_by_name
97  *
98  * @param name The name of the current plugin, or NULL to get the first.
99  *
100  * @return The name of the next plugin within the list.
101  */
visual_transform_get_next_by_name(const char * name)102 const char *visual_transform_get_next_by_name (const char *name)
103 {
104 	return visual_plugin_get_next_by_name (visual_transform_get_list (), name);
105 }
106 
107 /**
108  * Gives the previous transform plugin based on the name of a plugin.
109  *
110  * @see visual_transform_get_next_by_name
111  *
112  * @param name The name of the current plugin. or NULL to get the last.
113  *
114  * @return The name of the previous plugin within the list.
115  */
visual_transform_get_prev_by_name(const char * name)116 const char *visual_transform_get_prev_by_name (const char *name)
117 {
118 	return visual_plugin_get_prev_by_name (visual_transform_get_list (), name);
119 }
120 
121 /**
122  * Checks if the transform plugin is in the registry, based on it's name.
123  *
124  * @param name The name of the plugin that needs to be checked.
125  *
126  * @return TRUE if found, else FALSE.
127  */
visual_transform_valid_by_name(const char * name)128 int visual_transform_valid_by_name (const char *name)
129 {
130 	if (visual_plugin_find (visual_transform_get_list (), name) == NULL)
131 		return FALSE;
132 	else
133 		return TRUE;
134 }
135 
136 /**
137  * Creates a new transform from name, the plugin will be loaded but won't be realized.
138  *
139  * @param transformname
140  * 	The name of the plugin to load, or NULL to simply allocate a new
141  * 	transform.
142  *
143  * @return A newly allocated VisTransform, optionally containing a loaded plugin. Or NULL on failure.
144  */
visual_transform_new(const char * transformname)145 VisTransform *visual_transform_new (const char *transformname)
146 {
147 	VisTransform *transform;
148 	VisPluginRef *ref;
149 
150 	if (__lv_plugins_transform == NULL && transformname != NULL) {
151 		visual_log (VISUAL_LOG_CRITICAL, "the plugin list is NULL");
152 		return NULL;
153 	}
154 
155 	transform = visual_mem_new0 (VisTransform, 1);
156 
157 	/* Do the VisObject initialization */
158 	visual_object_initialize (VISUAL_OBJECT (transform), TRUE, transform_dtor);
159 
160 	if (transformname == NULL)
161 		return transform;
162 
163 	ref = visual_plugin_find (__lv_plugins_transform, transformname);
164 
165 	transform->plugin = visual_plugin_load (ref);
166 
167 	return transform;
168 }
169 
170 /**
171  * Realize the VisTransform. This also calls the plugin init function.
172  *
173  * @param transform Pointer to a VisTransform that needs to be realized.
174  *
175  * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_PLUGIN_NULL or
176  *	error values returned by visual_plugin_realize () on failure.
177  *
178  */
visual_transform_realize(VisTransform * transform)179 int visual_transform_realize (VisTransform *transform)
180 {
181 	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
182 	visual_log_return_val_if_fail (transform->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
183 
184 	return visual_plugin_realize (transform->plugin);
185 }
186 
187 /**
188  * This function negotiates the VisTransform with it's target video that is set by visual_transform_set_video.
189  * When needed it also sets up size fitting environment and depth transformation environment.
190  *
191  * @param transform Pointer to a VisTransform that needs negotiation.
192  *
193  * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_PLUGIN_NULL, -VISUAL_ERROR_PLUGIN_REF_NULL
194  * 	or -VISUAL_ERROR_TRANSFORM_NEGOTIATE on failure.
195  */
visual_transform_video_negotiate(VisTransform * transform)196 int visual_transform_video_negotiate (VisTransform *transform)
197 {
198 	int depthflag;
199 
200 	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
201 	visual_log_return_val_if_fail (transform->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
202 	visual_log_return_val_if_fail (transform->plugin->ref != NULL, -VISUAL_ERROR_PLUGIN_REF_NULL);
203 
204 	depthflag = visual_transform_get_supported_depth (transform);
205 
206 	if (visual_video_depth_is_supported (depthflag, transform->video->depth) == FALSE)
207 		return -VISUAL_ERROR_TRANSFORM_NEGOTIATE;
208 
209 	visual_event_queue_add_resize (&transform->plugin->eventqueue, transform->video,
210 			transform->video->width, transform->video->height);
211 
212 	visual_plugin_events_pump (transform->plugin);
213 
214 	return -VISUAL_OK;
215 }
216 
217 /**
218  * Gives the by the plugin natively supported depths
219  *
220  * @param transform Pointer to a VisTransform of which the supported depth of it's
221  * 	  encapsulated plugin is requested.
222  *
223  * @return an OR value of the VISUAL_VIDEO_DEPTH_* values which can be checked against using AND on succes,
224  * 	-VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_PLUGIN_NULL or -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL on failure.
225  */
visual_transform_get_supported_depth(VisTransform * transform)226 int visual_transform_get_supported_depth (VisTransform *transform)
227 {
228 	VisTransformPlugin *transplugin;
229 
230 	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
231 	visual_log_return_val_if_fail (transform->plugin != NULL, -VISUAL_ERROR_PLUGIN_NULL);
232 
233 	transplugin = get_transform_plugin (transform);
234 
235 	if (transplugin == NULL)
236 		return -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL;
237 
238 	return transplugin->depth;
239 }
240 
241 /**
242  * Used to connect the target display it's VisVideo structure to the VisTransform.
243  *
244  * Using the visual_video methods the screenbuffer, it's depth and dimension and optionally it's pitch
245  * can be set so the transform plugins know about their graphical environment and have a place to draw.
246  *
247  * After this function it's most likely that visual_transform_video_negotiate needs to be called.
248  *
249  * @see visual_video_new
250  * @see visual_transform_video_negotiate
251  *
252  * @param transform Pointer to a VisTransform to which the VisVideo needs to be set.
253  * @param video Pointer to a VisVideo which contains information about the target display and the pointer
254  * 	  to it's screenbuffer.
255  *
256  * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL on failure.
257  */
visual_transform_set_video(VisTransform * transform,VisVideo * video)258 int visual_transform_set_video (VisTransform *transform, VisVideo *video)
259 {
260 	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
261 
262 	transform->video = video;
263 
264 	if (video != NULL)
265 		transform->pal = video->pal;
266 	else
267 		transform->pal = NULL;
268 
269 	return VISUAL_OK;
270 }
271 
272 /**
273  * Used to override the palette that is extracted from the VisVideo that is given using
274  * visual_transform_set_video. Always call this function after visual_transform_set_video is called.
275  *
276  * @see visual_transform_set_video
277  *
278  * @param transform Pointer to a VisTransform to which the VisVideo needs to be set.
279  * @param palette Pointer to the VisPalette which is used to override the palette in the VisTransform.
280  *
281  * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL on failure.
282  */
visual_transform_set_palette(VisTransform * transform,VisPalette * palette)283 int visual_transform_set_palette (VisTransform *transform, VisPalette *palette)
284 {
285 	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
286 
287 	transform->pal = palette;
288 
289 	return VISUAL_OK;
290 }
291 
292 
293 /**
294  * This is called to run a VisTransform.
295  *
296  * @see visual_transform_run_video
297  * @see visual_transform_run_palette
298  *
299  * @param transform Pointer to a VisTransform that needs to be runned.
300  * @param audio Pointer to a VisAudio that contains all the audio data.
301  *
302  * return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL or error values returned by
303  *	either visual_transform_run_video or visual_transform_run_palette on failure.
304  */
visual_transform_run(VisTransform * transform,VisAudio * audio)305 int visual_transform_run (VisTransform *transform, VisAudio *audio)
306 {
307 	int ret;
308 	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
309 
310 	if (transform->video != NULL) {
311 		if ((ret = visual_transform_run_video (transform, audio)) != VISUAL_OK)
312 			return ret;
313 	}
314 
315 	if (transform->pal != NULL) {
316 		if ((ret = visual_transform_run_palette (transform, audio)) != VISUAL_OK)
317 			return ret;
318 	}
319 
320 	return VISUAL_OK;
321 }
322 
323 /**
324  * This is called to run the video part of a VisTransform.
325  *
326  * @see visual_transform_run
327  *
328  * @param transform Pointer to a VisTransform that needs to be runned.
329  * @param audio Pointer to a VisAudio that contains all the audio data.
330  *
331  * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_TRANSFORM_VIDEO_NULL
332  *	or -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL on failure.
333  */
visual_transform_run_video(VisTransform * transform,VisAudio * audio)334 int visual_transform_run_video (VisTransform *transform, VisAudio *audio)
335 {
336 	VisTransformPlugin *transplugin;
337 	VisPluginData *plugin;
338 
339 	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
340 	visual_log_return_val_if_fail (transform->video != NULL, -VISUAL_ERROR_TRANSFORM_VIDEO_NULL);
341 
342 	transplugin = get_transform_plugin (transform);
343 	plugin = visual_transform_get_plugin (transform);
344 
345 	if (transplugin == NULL) {
346 		visual_log (VISUAL_LOG_CRITICAL,
347 			"The given transform does not reference any transform plugin");
348 
349 		return -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL;
350 	}
351 
352 	visual_plugin_events_pump (plugin);
353 
354 	transplugin->video (plugin, transform->video, audio);
355 
356 	return VISUAL_OK;
357 }
358 
359 /**
360  * This is called to run the palette part of a VisTransform.
361  *
362  * @see visual_transform_run
363  *
364  * @param transform Pointer to a VisTransform that needs to be runned.
365  * @param audio Pointer to a VisAudio that contains all the audio data.
366  *
367  * @return VISUAL_OK on succes, -VISUAL_ERROR_TRANSFORM_NULL, -VISUAL_ERROR_TRANSFORM_PALETTE_NULL
368  *	or -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL on failure.
369  */
visual_transform_run_palette(VisTransform * transform,VisAudio * audio)370 int visual_transform_run_palette (VisTransform *transform, VisAudio *audio)
371 {
372 	VisTransformPlugin *transplugin;
373 	VisPluginData *plugin;
374 
375 	visual_log_return_val_if_fail (transform != NULL, -VISUAL_ERROR_TRANSFORM_NULL);
376 	visual_log_return_val_if_fail (transform->pal != NULL, -VISUAL_ERROR_TRANSFORM_PALETTE_NULL);
377 
378 	transplugin = get_transform_plugin (transform);
379 	plugin = visual_transform_get_plugin (transform);
380 
381 	if (transplugin == NULL) {
382 		visual_log (VISUAL_LOG_CRITICAL,
383 			"The given transform does not reference any transform plugin");
384 
385 		return -VISUAL_ERROR_TRANSFORM_PLUGIN_NULL;
386 	}
387 
388 	visual_plugin_events_pump (plugin);
389 
390 	transplugin->palette (plugin, transform->pal, audio);
391 
392 	return VISUAL_OK;
393 }
394 
395 /**
396  * @}
397  */
398 
399