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