sdl-display.c 4.41 KB
Newer Older
1 2 3 4 5
/* This file is an image processing operation for GEGL
 *
 * GEGL is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
6
 * version 3 of the License, or (at your option) any later version.
7 8 9 10 11 12 13
 *
 * GEGL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
14
 * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
15 16 17
 *
 * Copyright 2006 Øyvind Kolås <pippin@gimp.org>
 */
18 19 20 21 22

#include "config.h"
#include <glib/gi18n-lib.h>


23
#ifdef GEGL_PROPERTIES
24

25
property_string (window_title, _("Window title"), "window_title")
26
    description (_("Title to be given to output window"))
27
property_string (icon_title, _("Icon title"), "icon_title")
28
    description (_("Icon to be used for output window"))
29 30
#else

31
#define GEGL_OP_SINK
32
#define GEGL_OP_C_SOURCE sdl-display.c
33

34
#include "gegl-op.h"
35 36
#include <SDL.h>

37 38 39 40 41 42
typedef struct {
  SDL_Surface *screen;
  gint         width;
  gint         height;
} SDLState;

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
static void
init_sdl (void)
{
  static int inited = 0;

  if (!inited)
    {
      inited = 1;

      if (SDL_Init (SDL_INIT_VIDEO) < 0)
        {
          fprintf (stderr, "Unable to init SDL: %s\n", SDL_GetError ());
          return;
        }
      atexit (SDL_Quit);
      SDL_EnableUNICODE (1);
    }
}

62 63 64 65 66 67 68 69
static gboolean idle (gpointer data)
{
  SDL_Event event;
  while (SDL_PollEvent  (&event))
    {
      switch (event.type)
        {
          case SDL_QUIT:
70
            exit (0);
71 72 73 74 75 76
        }
    }
  return TRUE;
}

static guint handle = 0;
77 78

static gboolean
79
process (GeglOperation       *operation,
80
         GeglBuffer          *input,
81 82
         const GeglRectangle *result,
         gint                 level)
83
{
84
  GeglProperties   *o = GEGL_PROPERTIES (operation);
85 86
  SDLState     *state = NULL;

87 88 89
  if(!o->user_data)
      o->user_data = g_new0 (SDLState, 1);
  state = o->user_data;
90 91

  init_sdl ();
92

93
  if (!handle)
94
    handle = g_timeout_add (500, idle, NULL);
95

96 97 98
  if (!state->screen ||
       state->width  != result->width ||
       state->height != result->height)
99
    {
100 101
      state->screen = SDL_SetVideoMode (result->width, result->height, 32, SDL_SWSURFACE);
      if (!state->screen)
102
        {
103 104 105
          fprintf (stderr, "Unable to set SDL mode: %s\n",
                   SDL_GetError ());
          return -1;
106
        }
107 108 109

      state->width  = result->width ;
      state->height = result->height;
110 111 112 113
    }

  /*
   * There seems to be a valid faster path to the SDL desired display format
114
   * in B'G'R'A, perhaps babl should have been able to figure this out ito?
115 116
   *
   */
117
  gegl_buffer_get (input,
118
       NULL,
119
       1.0,
120
       babl_format_new (babl_model ("R'G'B'A"),
121
                        babl_type ("u8"),
122 123 124
                        babl_component ("B'"),
                        babl_component ("G'"),
                        babl_component ("R'"),
125
                        babl_component ("A"),
126
                        NULL),
127
       state->screen->pixels, GEGL_AUTO_ROWSTRIDE,
128
       GEGL_ABYSS_NONE);
129

130 131
  SDL_UpdateRect (state->screen, 0, 0, 0, 0);
  SDL_WM_SetCaption (o->window_title, o->icon_title);
132

133 134
  state->width = result->width ;
  state->height = result->height;
135 136 137 138

  return  TRUE;
}

139 140 141
static void
finalize (GObject *object)
{
142
  GeglProperties *o = GEGL_PROPERTIES (object);
143

144
  if (o->user_data)
145
    {
146 147
      g_free (o->user_data);
      o->user_data = NULL;
148 149
    }

150
  G_OBJECT_CLASS (gegl_op_parent_class)->finalize (object);
151 152
}

153
static void
154
gegl_op_class_init (GeglOpClass *klass)
155
{
156
  GObjectClass           *object_class;
157 158
  GeglOperationClass     *operation_class;
  GeglOperationSinkClass *sink_class;
159

160
  object_class    = G_OBJECT_CLASS (klass);
161 162 163
  operation_class = GEGL_OPERATION_CLASS (klass);
  sink_class      = GEGL_OPERATION_SINK_CLASS (klass);

164 165
  object_class->finalize = finalize;

166 167 168
  sink_class->process = process;
  sink_class->needs_full = TRUE;

169
  gegl_operation_class_set_keys (operation_class,
170 171 172 173
    "name",         "gegl:sdl-display",
    "title",        _("SDL Display"),
    "categories",   "display",
    "description",
174
        _("Displays the input buffer in an SDL window (restricted to one"
175 176
          " display op/process, due to SDL implementation issues)."),
        NULL);
177
}
178
#endif