home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / common / flarefx.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-01  |  32.1 KB  |  1,170 lines

  1. /*
  2.  * This is the FlareFX plug-in for the GIMP 0.99
  3.  * Version 1.05
  4.  *
  5.  * Copyright (C) 1997-1998 Karl-Johan Andersson (t96kja@student.tdb.uu.se)
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published by
  9.  * the Free Software Foundation; either version 2 of the License, or
  10.  * (at your option) any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program; if not, write to the Free Software
  19.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20.  *
  21.  */
  22.  
  23. /* 
  24.  * Please send any comments or suggestions to me,
  25.  * Karl-Johan Andersson (t96kja@student.tdb.uu.se)
  26.  * 
  27.  * TODO:
  28.  * - add "streaks" from lightsource
  29.  * - improve the user interface
  30.  * - speed it up
  31.  * - more flare types, more control (color, size, intensity...)
  32.  *
  33.  * Missing something? - please contact me!
  34.  *
  35.  * May 2000 - tim copperfield [timecop@japan.co.jp]
  36.  * preview window now draws a "mini flarefx" to show approximate
  37.  * positioning after final render.
  38.  *
  39.  * Note, the algorithm does not render into an alpha channel.
  40.  * Therefore, changed RGB* to RGB in the capabilities.
  41.  * Someone who actually knows something about graphics should
  42.  * take a look to see why this doesnt render on alpha channel :)
  43.  *  
  44.  */ 
  45.  
  46. #include "config.h"
  47.  
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51.  
  52. #include <gtk/gtk.h>
  53.  
  54. #include <libgimp/gimp.h>
  55. #include <libgimp/gimpui.h>
  56.  
  57. #include "libgimp/stdplugins-intl.h"
  58.  
  59.  
  60. /* --- Defines --- */
  61. #define ENTRY_WIDTH  75
  62. #define PREVIEW_SIZE 128
  63. #define PREVIEW_MASK (GDK_EXPOSURE_MASK | \
  64.               GDK_BUTTON_PRESS_MASK | \
  65.               GDK_BUTTON1_MOTION_MASK)
  66.  
  67. #define PREVIEW      0x1
  68. #define CURSOR      0x2
  69. #define ALL      0xf
  70.  
  71. #if 0
  72. #define DEBUG1 printf
  73. #else
  74. #define DEBUG1 dummy_printf
  75. static void
  76. dummy_printf (gchar *fmt, ...) {}
  77. #endif
  78.  
  79.  
  80. /* --- Typedefs --- */
  81. typedef struct
  82. {
  83.   gint posx;
  84.   gint posy;
  85. } FlareValues;
  86.  
  87. typedef struct
  88. {
  89.   gint run;
  90. } FlareInterface;
  91.  
  92. typedef struct RGBFLOAT
  93. {
  94.   gfloat r;
  95.   gfloat g;
  96.   gfloat b;
  97. } RGBfloat;
  98.  
  99. typedef struct REFLECT
  100. {
  101.   RGBfloat ccol;
  102.   gfloat size;
  103.   gint   xp;
  104.   gint   yp;
  105.   gint   type;
  106. } Reflect;
  107.  
  108. typedef struct
  109. {
  110.   GimpDrawable *drawable;
  111.   gint       dwidth;
  112.   gint       dheight;
  113.   gint       bpp;
  114.   GtkObject *xadj;
  115.   GtkObject *yadj;
  116.   gint       cursor;
  117.   gint       curx, cury;         /* x,y of cursor in preview */
  118.   gint       oldx, oldy;
  119.   gint       in_call;
  120. } FlareCenter;
  121.  
  122. /* --- Declare local functions --- */
  123. static void query (void);
  124. static void run   (gchar   *name,
  125.            gint     nparams,
  126.            GimpParam  *param,
  127.            gint    *nreturn_vals,
  128.            GimpParam **return_vals);
  129.  
  130. static void FlareFX                    (GimpDrawable *drawable, 
  131.                     gint       preview_mode);
  132. static void fill_preview_with_thumb    (GtkWidget *preview_widget, 
  133.                     gint32     drawable_ID);
  134. static GtkWidget *preview_widget       (GimpDrawable *drawable);
  135.  
  136. static gint flare_dialog               (GimpDrawable *drawable);
  137. static void flare_ok_callback          (GtkWidget *widget,
  138.                     gpointer   data);
  139.  
  140. static GtkWidget * flare_center_create            (GimpDrawable     *drawable);
  141. static void       flare_center_destroy           (GtkWidget     *widget,
  142.                            gpointer       data);
  143. static void       flare_center_draw              (FlareCenter   *center,
  144.                            gint           update);
  145. static void       flare_center_adjustment_update (GtkAdjustment *adjustment,
  146.                            gpointer       data);
  147. static void       flare_center_cursor_update     (FlareCenter   *center);
  148. static gint       flare_center_preview_expose    (GtkWidget     *widget,
  149.                            GdkEvent      *event);
  150. static gint       flare_center_preview_events    (GtkWidget     *widget,
  151.                            GdkEvent      *event);
  152.  
  153. static void mcolor  (guchar *s, gfloat h);
  154. static void mglow   (guchar *s, gfloat h);
  155. static void minner  (guchar *s, gfloat h);
  156. static void mouter  (guchar *s, gfloat h);
  157. static void mhalo   (guchar *s, gfloat h);
  158. static void initref (gint sx, gint sy, gint width, gint height, gint matt);
  159. static void fixpix  (guchar *data, float procent, RGBfloat colpro);
  160. static void mrt1    (guchar *s, gint i, gint col, gint row);
  161. static void mrt2    (guchar *s, gint i, gint col, gint row);
  162. static void mrt3    (guchar *s, gint i, gint col, gint row);
  163. static void mrt4    (guchar *s, gint i, gint col, gint row);
  164.  
  165. /* --- Variables --- */
  166. GimpPlugInInfo PLUG_IN_INFO =
  167. {
  168.   NULL,  /* init_proc  */
  169.   NULL,  /* quit_proc  */
  170.   query, /* query_proc */
  171.   run,   /* run_proc   */
  172. };
  173.  
  174. static FlareValues fvals =
  175. {
  176.   128, 128        /* posx, posy */
  177. };
  178.  
  179. static FlareInterface fint =
  180. {
  181.   FALSE     /* run */
  182. };
  183.  
  184. static  gfloat     scolor, sglow, sinner, souter; /* size     */
  185. static  gfloat     shalo;
  186. static  gint       xs, ys;     
  187. static  gint       numref;
  188. static  RGBfloat   color, glow, inner, outer, halo;
  189. static  Reflect    ref1[19];
  190. static  guchar    *preview_bits;
  191. static  GtkWidget *preview;
  192. static  gdouble    preview_scale_x;
  193. static  gdouble    preview_scale_y;
  194. static  gboolean   show_cursor = 0;
  195.  
  196. /* --- Functions --- */
  197. MAIN ()
  198.  
  199. static void
  200. query (void) 
  201. {
  202.   static GimpParamDef args[] =
  203.   {
  204.     { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
  205.     { GIMP_PDB_IMAGE, "image", "Input image (unused)" },
  206.     { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
  207.     { GIMP_PDB_INT32, "posx", "X-position" },
  208.     { GIMP_PDB_INT32, "posy", "Y-position" }
  209.   };
  210.   static gint nargs = sizeof (args) / sizeof (args[0]);
  211.  
  212.   gimp_install_procedure ("plug_in_flarefx",
  213.               "Add lens flare effects",
  214.               "Adds a lens flare effects.  Makes your image look like it was snapped with a cheap camera with a lot of lens :)",
  215.               "Karl-Johan Andersson", /* Author */
  216.               "Karl-Johan Andersson", /* Copyright */
  217.               "May 2000",
  218.               N_("<Image>/Filters/Light Effects/FlareFX..."),
  219.               "RGB*",
  220.               GIMP_PLUGIN,
  221.               nargs, 0,
  222.               args, NULL);
  223. }
  224.  
  225. static void
  226. run (gchar   *name,
  227.      gint     nparams,
  228.      GimpParam  *param,
  229.      gint    *nreturn_vals,
  230.      GimpParam **return_vals)
  231. {
  232.   static GimpParam values[1];
  233.   GimpDrawable *drawable;
  234.   GimpRunModeType run_mode;
  235.   GimpPDBStatusType status = GIMP_PDB_SUCCESS;
  236.   
  237.   run_mode = param[0].data.d_int32;
  238.  
  239.   *nreturn_vals = 1;
  240.   *return_vals = values;
  241.   
  242.   values[0].type = GIMP_PDB_STATUS;
  243.   values[0].data.d_status = status;
  244.   
  245.   /*  Get the specified drawable  */
  246.   drawable = gimp_drawable_get (param[2].data.d_drawable);
  247.  
  248.   switch (run_mode)
  249.     {
  250.     case GIMP_RUN_INTERACTIVE:
  251.       INIT_I18N_UI();
  252.       /*  Possibly retrieve data  */
  253.       gimp_get_data ("plug_in_flarefx", &fvals);
  254.  
  255.       /*  First acquire information with a dialog  */
  256.       if (! flare_dialog (drawable))
  257.     {
  258.       gimp_drawable_detach (drawable);
  259.       return;
  260.     }
  261.       break;
  262.  
  263.     case GIMP_RUN_NONINTERACTIVE:
  264.       INIT_I18N();
  265.       /*  Make sure all the arguments are there!  */
  266.       if (nparams != 5)
  267.     status = GIMP_PDB_CALLING_ERROR;
  268.       if (status == GIMP_PDB_SUCCESS)
  269.     {
  270.       fvals.posx = (gint) param[3].data.d_int32;
  271.       fvals.posy = (gint) param[4].data.d_int32;
  272.     }
  273.       break;
  274.  
  275.     case GIMP_RUN_WITH_LAST_VALS:
  276.       INIT_I18N();
  277.       /*  Possibly retrieve data  */
  278.       gimp_get_data ("plug_in_flarefx", &fvals);
  279.       break;
  280.  
  281.     default:
  282.       break;
  283.     }
  284.   
  285.   if (status == GIMP_PDB_SUCCESS)
  286.     {
  287.       /*  Make sure that the drawable is gray or RGB color  */
  288.       if (gimp_drawable_is_rgb (drawable->id) ||
  289.       gimp_drawable_is_gray (drawable->id))
  290.     {
  291.       gimp_progress_init (_("Render Flare..."));
  292.       gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
  293.       
  294.       FlareFX (drawable, 0);
  295.       
  296.       if (run_mode != GIMP_RUN_NONINTERACTIVE)
  297.         gimp_displays_flush (); 
  298.  
  299.       /*  Store data  */
  300.       if (run_mode == GIMP_RUN_INTERACTIVE)
  301.         gimp_set_data ("plug_in_flarefx", &fvals, sizeof (FlareValues));
  302.         g_free(preview_bits);
  303.     }
  304.       else
  305.     {
  306.       /* gimp_message ("FlareFX: cannot operate on indexed color images"); */
  307.       status = GIMP_PDB_EXECUTION_ERROR;
  308.     }
  309.     }
  310.  
  311.   values[0].data.d_status = status;
  312.   
  313.   gimp_drawable_detach (drawable);
  314. }
  315.  
  316.  
  317. static gint
  318. flare_dialog (GimpDrawable *drawable)
  319. {
  320.   GtkWidget *dlg;
  321.   GtkWidget *main_vbox;
  322.   GtkWidget *frame;
  323.   FlareCenter *center;
  324.  
  325.   gimp_ui_init ("flarefx", TRUE);
  326.  
  327.   dlg = gimp_dialog_new (_("FlareFX"), "flarefx",
  328.              gimp_standard_help_func, "filters/flarefx.html",
  329.              GTK_WIN_POS_MOUSE,
  330.              FALSE, TRUE, FALSE,
  331.  
  332.              _("OK"), flare_ok_callback,
  333.              NULL, NULL, NULL, TRUE, FALSE,
  334.              _("Cancel"), gtk_widget_destroy,
  335.              NULL, 1, NULL, FALSE, TRUE,
  336.  
  337.              NULL);
  338.  
  339.   gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
  340.               GTK_SIGNAL_FUNC (gtk_main_quit),
  341.               NULL);
  342.  
  343.   /*  parameter settings  */
  344.   main_vbox = gtk_vbox_new (FALSE, 2);
  345.   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
  346.   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), main_vbox, TRUE, TRUE, 0);
  347.   gtk_widget_show (main_vbox);
  348.  
  349.  
  350.   frame = flare_center_create (drawable);
  351.   center = gtk_object_get_user_data (GTK_OBJECT (frame));
  352.   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
  353.   gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
  354.   gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
  355.  
  356.   gtk_widget_show (frame);
  357.   gtk_widget_show (dlg);
  358.  
  359.   gtk_main ();
  360.   gdk_flush ();
  361.  
  362.   return fint.run;
  363. }
  364.  
  365. /* --- Interface functions --- */
  366. static void
  367. flare_ok_callback (GtkWidget *widget,
  368.            gpointer   data)
  369. {
  370.   fint.run = TRUE;
  371.  
  372.   gtk_widget_destroy (GTK_WIDGET (data));
  373. }
  374.  
  375. /* --- Filter functions --- */
  376. static void
  377. FlareFX (GimpDrawable *drawable, 
  378.      gboolean   preview_mode)
  379. {
  380.   GimpPixelRgn srcPR, destPR;
  381.   gint width, height;
  382.   gint bytes;
  383.   guchar *dest, *d;
  384.   guchar *cur_row, *s;
  385.   gint row, col, i;
  386.   gint x1, y1, x2, y2;
  387.   gint matt;
  388.   gfloat hyp;
  389.  
  390.   if (preview_mode) 
  391.     {
  392.       width  = GTK_PREVIEW (preview)->buffer_width;
  393.       height = GTK_PREVIEW (preview)->buffer_height;
  394.       bytes  = GTK_PREVIEW (preview)->bpp;
  395.  
  396.       xs = (gdouble)fvals.posx * preview_scale_x;
  397.       ys = (gdouble)fvals.posy * preview_scale_y;
  398.  
  399.       x1 = y1 = 0;
  400.       x2 = width;
  401.       y2 = height;
  402.     } 
  403.   else 
  404.     {
  405.       gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
  406.       width  = drawable->width;
  407.       height = drawable->height;
  408.       bytes  = drawable->bpp;
  409.  
  410.       xs = fvals.posx; /* set x,y of flare center */
  411.       ys = fvals.posy;
  412.     }
  413.  
  414.   matt = width;
  415.  
  416.   if (preview_mode) 
  417.     {
  418.       cur_row = g_new (guchar, GTK_PREVIEW (preview)->rowstride);
  419.       dest    = g_new (guchar, GTK_PREVIEW (preview)->rowstride);
  420.     }
  421.   else
  422.     {  
  423.       /*  initialize the pixel regions  */
  424.       gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
  425.       gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
  426.  
  427.       cur_row = g_new (guchar, (x2 - x1) * bytes);
  428.       dest    = g_new (guchar, (x2 - x1) * bytes);
  429.     }
  430.  
  431.   scolor = (gfloat)matt * 0.0375;
  432.   sglow  = (gfloat)matt * 0.078125;
  433.   sinner = (gfloat)matt * 0.1796875;
  434.   souter = (gfloat)matt * 0.3359375;
  435.   shalo  = (gfloat)matt * 0.084375;
  436.  
  437.   color.r = 239.0/255.0; color.g = 239.0/255.0; color.b = 239.0/255.0;
  438.   glow.r  = 245.0/255.0; glow.g  = 245.0/255.0; glow.b  = 245.0/255.0;
  439.   inner.r = 255.0/255.0; inner.g = 38.0/255.0;  inner.b = 43.0/255.0;
  440.   outer.r = 69.0/255.0;  outer.g = 59.0/255.0;  outer.b = 64.0/255.0;
  441.   halo.r  = 80.0/255.0;  halo.g  = 15.0/255.0;  halo.b  = 4.0/255.0;
  442.  
  443.   initref (xs, ys, width, height, matt);
  444.  
  445.   /*  Loop through the rows */
  446.   for (row = y1; row < y2; row++) /* y-coord */
  447.     {
  448.       if (preview_mode) 
  449.     memcpy (cur_row, 
  450.         preview_bits + GTK_PREVIEW (preview)->rowstride * row,
  451.         GTK_PREVIEW (preview)->rowstride);
  452.       else 
  453.     gimp_pixel_rgn_get_row (&srcPR, cur_row, x1, row, x2-x1);
  454.  
  455.       d = dest;
  456.       s = cur_row;
  457.       for (col = x1; col < x2; col++) /* x-coord */
  458.     {      
  459.       hyp = hypot (col-xs, row-ys);
  460.       mcolor (s, hyp); /* make color */
  461.       mglow (s, hyp);  /* make glow  */ 
  462.       minner (s, hyp); /* make inner */
  463.       mouter (s, hyp); /* make outer */
  464.       mhalo (s, hyp);  /* make halo  */
  465.       for (i = 0; i < numref; i++) 
  466.         {
  467.           switch (ref1[i].type) 
  468.         {
  469.         case 1: 
  470.           mrt1 (s, i, col, row); 
  471.           break;
  472.         case 2:
  473.           mrt2 (s, i, col, row);
  474.           break;
  475.         case 3:
  476.           mrt3 (s, i, col, row);
  477.           break;
  478.         case 4:
  479.           mrt4 (s, i, col, row);
  480.           break;
  481.         }
  482.         }
  483.       s+=bytes;
  484.     }
  485.       if (preview_mode) 
  486.     {
  487.       memcpy (GTK_PREVIEW (preview)->buffer + GTK_PREVIEW (preview)->rowstride * row, 
  488.           cur_row, 
  489.           GTK_PREVIEW (preview)->rowstride);
  490.     } 
  491.       else 
  492.     {
  493.       /*  store the dest  */
  494.       gimp_pixel_rgn_set_row (&destPR, cur_row, x1, row, (x2 - x1));
  495.     }
  496.       
  497.       if ((row % 5) == 0 && !preview_mode)
  498.     gimp_progress_update ((double) row / (double) (y2 - y1));
  499.     }
  500.  
  501.   if (preview_mode) 
  502.     {
  503.       gtk_widget_queue_draw (preview);
  504.     } 
  505.   else 
  506.     {
  507.       /*  update the textured region  */
  508.       gimp_drawable_flush (drawable);
  509.       gimp_drawable_merge_shadow (drawable->id, TRUE);
  510.       gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
  511.     }
  512.  
  513.   g_free (cur_row);
  514.   g_free (dest);
  515. }
  516.  
  517. static void
  518. mcolor (guchar *s,
  519.     gfloat  h)
  520. {
  521.   static gfloat procent;
  522.   
  523.   procent = scolor - h;
  524.   procent/=scolor;
  525.   if (procent > 0.0)
  526.     {
  527.       procent*=procent;
  528.       fixpix (s, procent, color); 
  529.     }
  530. }
  531.  
  532. static void
  533. mglow (guchar *s,
  534.        gfloat  h)
  535. {
  536.   static gfloat procent;
  537.   
  538.   procent = sglow - h;
  539.   procent/=sglow;
  540.   if (procent > 0.0)
  541.     {
  542.       procent*=procent;
  543.       fixpix (s, procent, glow); 
  544.     }
  545. }
  546.  
  547. static void
  548. minner (guchar *s,
  549.     gfloat  h)
  550. {
  551.   static gfloat procent;
  552.   
  553.   procent = sinner - h;
  554.   procent/=sinner;
  555.   if (procent > 0.0)
  556.     {
  557.       procent*=procent;
  558.       fixpix (s, procent, inner); 
  559.     }
  560. }
  561.  
  562. static void
  563. mouter (guchar *s,
  564.     gfloat  h)
  565. {
  566.   static gfloat procent;
  567.   
  568.   procent = souter - h;
  569.   procent/=souter;
  570.   if (procent > 0.0) 
  571.     fixpix (s, procent, outer); 
  572. }
  573.  
  574. static void
  575. mhalo (guchar *s,
  576.        gfloat  h)
  577. {
  578.   static gfloat procent;
  579.   
  580.   procent = h - shalo;
  581.   procent/=(shalo*0.07);
  582.   procent = fabs (procent);
  583.   if (procent < 1.0)
  584.     fixpix (s, 1.0 - procent, halo); 
  585. }
  586.  
  587. static void
  588. fixpix (guchar   *data,
  589.     float     procent,
  590.     RGBfloat  colpro)
  591. {
  592.   data[0] = data[0] + (255 - data[0]) * procent * colpro.r;
  593.   data[1] = data[1] + (255 - data[1]) * procent * colpro.g;
  594.   data[2] = data[2] + (255 - data[2]) * procent * colpro.b;
  595. }
  596.  
  597. static void
  598. initref (gint sx,
  599.      gint sy,
  600.      gint width,
  601.      gint height,
  602.      gint matt)
  603. {
  604.   gint xh, yh, dx, dy;
  605.   
  606.   xh = width / 2; yh = height / 2;
  607.   dx = xh - sx;   dy = yh - sy;
  608.   numref = 19;
  609.   ref1[0].type=1; ref1[0].size=(gfloat)matt*0.027;
  610.   ref1[0].xp=0.6699*dx+xh; ref1[0].yp=0.6699*dy+yh;
  611.   ref1[0].ccol.r=0.0; ref1[0].ccol.g=14.0/255.0; ref1[0].ccol.b=113.0/255.0;
  612.   ref1[1].type=1; ref1[1].size=(gfloat)matt*0.01;
  613.   ref1[1].xp=0.2692*dx+xh; ref1[1].yp=0.2692*dy+yh;
  614.   ref1[1].ccol.r=90.0/255.0; ref1[1].ccol.g=181.0/255.0; ref1[1].ccol.b=142.0/255.0;
  615.   ref1[2].type=1; ref1[2].size=(gfloat)matt*0.005;
  616.   ref1[2].xp=-0.0112*dx+xh; ref1[2].yp=-0.0112*dy+yh;
  617.   ref1[2].ccol.r=56.0/255.0; ref1[2].ccol.g=140.0/255.0; ref1[2].ccol.b=106.0/255.0;
  618.   ref1[3].type=2; ref1[3].size=(gfloat)matt*0.031;
  619.   ref1[3].xp=0.6490*dx+xh; ref1[3].yp=0.6490*dy+yh;
  620.   ref1[3].ccol.r=9.0/255.0; ref1[3].ccol.g=29.0/255.0; ref1[3].ccol.b=19.0/255.0;
  621.   ref1[4].type=2; ref1[4].size=(gfloat)matt*0.015;
  622.   ref1[4].xp=0.4696*dx+xh; ref1[4].yp=0.4696*dy+yh;
  623.   ref1[4].ccol.r=24.0/255.0; ref1[4].ccol.g=14.0/255.0; ref1[4].ccol.b=0.0;
  624.   ref1[5].type=2; ref1[5].size=(gfloat)matt*0.037;
  625.   ref1[5].xp=0.4087*dx+xh; ref1[5].yp=0.4087*dy+yh;
  626.   ref1[5].ccol.r=24.0/255.0; ref1[5].ccol.g=14.0/255.0; ref1[5].ccol.b=0.0;
  627.   ref1[6].type=2; ref1[6].size=(gfloat)matt*0.022;
  628.   ref1[6].xp=-0.2003*dx+xh; ref1[6].yp=-0.2003*dy+yh;
  629.   ref1[6].ccol.r=42.0/255.0; ref1[6].ccol.g=19.0/255.0; ref1[6].ccol.b=0.0;
  630.   ref1[7].type=2; ref1[7].size=(gfloat)matt*0.025;
  631.   ref1[7].xp=-0.4103*dx+xh; ref1[7].yp=-0.4103*dy+yh;
  632.   ref1[7].ccol.b=17.0/255.0; ref1[7].ccol.g=9.0/255.0; ref1[7].ccol.r=0.0;
  633.   ref1[8].type=2; ref1[8].size=(gfloat)matt*0.058;
  634.   ref1[8].xp=-0.4503*dx+xh; ref1[8].yp=-0.4503*dy+yh;
  635.   ref1[8].ccol.b=10.0/255.0; ref1[8].ccol.g=4.0/255.0; ref1[8].ccol.r=0.0;
  636.   ref1[9].type=2; ref1[9].size=(gfloat)matt*0.017;
  637.   ref1[9].xp=-0.5112*dx+xh; ref1[9].yp=-0.5112*dy+yh;
  638.   ref1[9].ccol.r=5.0/255.0; ref1[9].ccol.g=5.0/255.0; ref1[9].ccol.b=14.0/255.0;
  639.   ref1[10].type=2; ref1[10].size=(gfloat)matt*0.2;
  640.   ref1[10].xp=-1.496*dx+xh; ref1[10].yp=-1.496*dy+yh;
  641.   ref1[10].ccol.r=9.0/255.0; ref1[10].ccol.g=4.0/255.0; ref1[10].ccol.b=0.0;
  642.   ref1[11].type=2; ref1[11].size=(gfloat)matt*0.5;
  643.   ref1[11].xp=-1.496*dx+xh; ref1[11].yp=-1.496*dy+yh;
  644.   ref1[11].ccol.r=9.0/255.0; ref1[11].ccol.g=4.0/255.0; ref1[11].ccol.b=0.0;
  645.   ref1[12].type=3; ref1[12].size=(gfloat)matt*0.075;
  646.   ref1[12].xp=0.4487*dx+xh; ref1[12].yp=0.4487*dy+yh;
  647.   ref1[12].ccol.r=34.0/255.0; ref1[12].ccol.g=19.0/255.0; ref1[12].ccol.b=0.0;
  648.   ref1[13].type=3; ref1[13].size=(gfloat)matt*0.1;
  649.   ref1[13].xp=dx+xh; ref1[13].yp=dy+yh;
  650.   ref1[13].ccol.r=14.0/255.0; ref1[13].ccol.g=26.0/255.0; ref1[13].ccol.b=0.0;
  651.   ref1[14].type=3; ref1[14].size=(gfloat)matt*0.039;
  652.   ref1[14].xp=-1.301*dx+xh; ref1[14].yp=-1.301*dy+yh;
  653.   ref1[14].ccol.r=10.0/255.0; ref1[14].ccol.g=25.0/255.0; ref1[14].ccol.b=13.0/255.0;
  654.   ref1[15].type=4; ref1[15].size=(gfloat)matt*0.19;
  655.   ref1[15].xp=1.309*dx+xh; ref1[15].yp=1.309*dy+yh;
  656.   ref1[15].ccol.r=9.0/255.0; ref1[15].ccol.g=0.0; ref1[15].ccol.b=17.0/255.0;
  657.   ref1[16].type=4; ref1[16].size=(gfloat)matt*0.195;
  658.   ref1[16].xp=1.309*dx+xh; ref1[16].yp=1.309*dy+yh;
  659.   ref1[16].ccol.r=9.0/255.0; ref1[16].ccol.g=16.0/255.0; ref1[16].ccol.b=5.0/255.0;
  660.   ref1[17].type=4; ref1[17].size=(gfloat)matt*0.20;
  661.   ref1[17].xp=1.309*dx+xh; ref1[17].yp=1.309*dy+yh;
  662.   ref1[17].ccol.r=17.0/255.0; ref1[17].ccol.g=4.0/255.0; ref1[17].ccol.b=0.0;
  663.   ref1[18].type=4; ref1[18].size=(gfloat)matt*0.038;
  664.   ref1[18].xp=-1.301*dx+xh; ref1[18].yp=-1.301*dy+yh;
  665.   ref1[18].ccol.r=17.0/255.0; ref1[18].ccol.g=4.0/255.0; ref1[18].ccol.b=0.0;
  666. }
  667.  
  668. static void
  669. mrt1 (guchar *s,
  670.       gint    i,
  671.       gint    col,
  672.       gint    row)
  673. {
  674.   static gfloat procent;
  675.   
  676.   procent = ref1[i].size - hypot (ref1[i].xp - col, ref1[i].yp - row);
  677.   procent/=ref1[i].size;
  678.   if (procent > 0.0)
  679.     {
  680.       procent*=procent;
  681.       fixpix (s, procent, ref1[i].ccol); 
  682.     }  
  683. }
  684.  
  685. static void
  686. mrt2 (guchar *s,
  687.       gint    i,
  688.       gint    col,
  689.       gint    row)
  690. {
  691.   static gfloat procent;
  692.   
  693.   procent = ref1[i].size - hypot (ref1[i].xp - col, ref1[i].yp - row);
  694.   procent/=(ref1[i].size * 0.15);
  695.   if (procent > 0.0)
  696.     {
  697.       if (procent > 1.0) procent = 1.0;
  698.       fixpix (s, procent, ref1[i].ccol); 
  699.     }  
  700. }
  701.  
  702. static void
  703. mrt3 (guchar *s,
  704.       gint    i,
  705.       gint    col,
  706.       gint    row)
  707. {
  708.   static gfloat procent;
  709.   
  710.   procent = ref1[i].size - hypot (ref1[i].xp - col, ref1[i].yp - row);
  711.   procent/=(ref1[i].size * 0.12);
  712.   if (procent > 0.0)
  713.     {
  714.       if (procent > 1.0) procent = 1.0 - (procent * 0.12);
  715.       fixpix (s, procent, ref1[i].ccol); 
  716.     }  
  717. }
  718.  
  719. static void
  720. mrt4 (guchar *s,
  721.       gint    i,
  722.       gint    col,
  723.       gint    row)
  724. {
  725.   static gfloat procent;
  726.   
  727.   procent = hypot (ref1[i].xp - col, ref1[i].yp - row) - ref1[i].size;
  728.   procent/=(ref1[i].size*0.04);
  729.   procent = fabs (procent);
  730.   if (procent < 1.0) 
  731.     fixpix(s, 1.0 - procent, ref1[i].ccol); 
  732. }
  733.  
  734. /*=================================================================
  735.     CenterFrame
  736.  
  737.     A frame that contains one preview and 2 entrys, used for positioning
  738.     of the center of Flare.
  739.     This whole thing is just too ugly, but I don't want to dig into it
  740.      - tim
  741. ==================================================================*/
  742.  
  743. /*
  744.  * Create new CenterFrame, and return it (GtkFrame).
  745.  */
  746.  
  747. static GtkWidget *
  748. flare_center_create (GimpDrawable *drawable)
  749. {
  750.   FlareCenter *center;
  751.   GtkWidget   *frame;
  752.   GtkWidget   *table;
  753.   GtkWidget   *label;
  754.   GtkWidget   *pframe;
  755.   GtkWidget   *spinbutton;
  756.   GtkWidget   *check;
  757.  
  758.   center = g_new (FlareCenter, 1);
  759.   center->drawable = drawable;
  760.   center->dwidth   = gimp_drawable_width(drawable->id );
  761.   center->dheight  = gimp_drawable_height(drawable->id );
  762.   center->bpp       = gimp_drawable_bpp(drawable->id);
  763.   if (gimp_drawable_has_alpha (drawable->id))
  764.     center->bpp--;
  765.   center->cursor   = FALSE;
  766.   center->curx     = 0;
  767.   center->cury     = 0;
  768.   center->oldx     = 0;
  769.   center->oldy     = 0;
  770.   center->in_call  = TRUE;  /* to avoid side effects while initialization */
  771.  
  772.   frame = gtk_frame_new (_("Center of FlareFX"));
  773.   gtk_signal_connect (GTK_OBJECT (frame), "destroy",
  774.               GTK_SIGNAL_FUNC (flare_center_destroy),
  775.               center);
  776.   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
  777.   gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
  778.  
  779.   table = gtk_table_new (3, 4, FALSE);
  780.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  781.   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  782.   gtk_table_set_col_spacing (GTK_TABLE (table), 1, 6);
  783.   gtk_container_set_border_width (GTK_CONTAINER (table), 4);
  784.   gtk_container_add (GTK_CONTAINER (frame), table);
  785.  
  786.   label = gtk_label_new (_("X:"));
  787.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5 );
  788.   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
  789.             GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
  790.   gtk_widget_show (label);
  791.  
  792.   spinbutton =
  793.     gimp_spin_button_new (¢er->xadj,
  794.                           fvals.posx, G_MININT, G_MAXINT,
  795.                           1, 10, 10, 0, 0);
  796.   gtk_object_set_user_data (GTK_OBJECT (center->xadj), center);
  797.   gtk_signal_connect (GTK_OBJECT (center->xadj), "value_changed",
  798.                       GTK_SIGNAL_FUNC (flare_center_adjustment_update),
  799.                       &fvals.posx);
  800.   gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, 0, 1,
  801.                     GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  802.   gtk_widget_show (spinbutton);
  803.  
  804.   label = gtk_label_new (_("Y:"));
  805.   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5 );
  806.   gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
  807.             GTK_SHRINK | GTK_FILL, GTK_FILL, 0, 0);
  808.   gtk_widget_show (label);
  809.  
  810.   spinbutton =
  811.     gimp_spin_button_new (¢er->yadj,
  812.                           fvals.posy, G_MININT, G_MAXINT,
  813.                           1, 10, 10, 0, 0);
  814.   gtk_object_set_user_data (GTK_OBJECT (center->yadj), center);
  815.   gtk_signal_connect (GTK_OBJECT (center->yadj), "value_changed",
  816.                       GTK_SIGNAL_FUNC (flare_center_adjustment_update),
  817.                       &fvals.posy);
  818.   gtk_table_attach (GTK_TABLE (table), spinbutton, 3, 4, 0, 1,
  819.                     GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  820.   gtk_widget_show (spinbutton);
  821.  
  822.   /* frame (shadow_in) that contains preview */
  823.   pframe = gtk_frame_new (NULL);
  824.   gtk_frame_set_shadow_type (GTK_FRAME (pframe), GTK_SHADOW_IN);
  825.   gtk_table_attach (GTK_TABLE (table), pframe, 0, 4, 1, 2, 0, 0, 0, 0);
  826.  
  827.   /* PREVIEW */
  828.   preview = preview_widget (drawable);
  829.   gtk_object_set_user_data (GTK_OBJECT (preview), center);
  830.   gtk_widget_set_events (GTK_WIDGET (preview), PREVIEW_MASK);
  831.   gtk_signal_connect_after (GTK_OBJECT (preview), "expose_event",
  832.                 (GtkSignalFunc) flare_center_preview_expose,
  833.                 center);
  834.   gtk_signal_connect (GTK_OBJECT (preview), "event",
  835.               (GtkSignalFunc) flare_center_preview_events,
  836.               center);
  837.   gtk_container_add (GTK_CONTAINER (pframe ), preview);
  838.   gtk_widget_show (preview);
  839.  
  840.   gtk_widget_show (pframe);
  841.   gtk_widget_show (table);
  842.   gtk_object_set_user_data (GTK_OBJECT (frame), center);
  843.   gtk_widget_show (frame);
  844.  
  845.   /* show / hide cursor */
  846.   check = gtk_check_button_new_with_label (_("Show Cursor"));
  847.   gtk_table_attach (GTK_TABLE (table), check, 0, 4, 2, 3,
  848.             GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  849.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), show_cursor);
  850.   gtk_signal_connect (GTK_OBJECT (check), "toggled",
  851.                       GTK_SIGNAL_FUNC (gimp_toggle_button_update),
  852.                       &show_cursor);
  853.   gtk_signal_connect_object (GTK_OBJECT (check), "toggled",
  854.                  GTK_SIGNAL_FUNC (FlareFX),
  855.                  (gpointer)drawable);
  856.   gtk_widget_show (check);
  857.  
  858.   flare_center_cursor_update (center);
  859.  
  860.   center->cursor = FALSE;    /* Make sure that the cursor has not been drawn */
  861.   center->in_call = FALSE;   /* End of initialization */
  862.  
  863.   FlareFX (drawable, TRUE);
  864.  
  865.   DEBUG1 ("fvals center=%d,%d\n", fvals.posx, fvals.posy);
  866.   DEBUG1 ("center cur=%d,%d\n", center->curx, center->cury);
  867.   
  868.   return frame;
  869. }
  870.  
  871. static void
  872. flare_center_destroy (GtkWidget *widget,
  873.               gpointer   data)
  874. {
  875.   FlareCenter *center = data;
  876.   g_free (center);
  877. }
  878.  
  879. /*
  880.  *  Initialize preview
  881.  *  Draw the contents into the internal buffer of the preview widget
  882.  */
  883.  
  884. static GtkWidget *
  885. preview_widget (GimpDrawable *drawable)
  886. {
  887.   GtkWidget *preview;
  888.   gint       size;
  889.  
  890.   preview = gtk_preview_new (GTK_PREVIEW_COLOR);
  891.   fill_preview_with_thumb (preview, drawable->id);
  892.   size = GTK_PREVIEW (preview)->rowstride * GTK_PREVIEW (preview)->buffer_height;
  893.   preview_bits = g_malloc (size);
  894.   memcpy (preview_bits, GTK_PREVIEW (preview)->buffer, size);
  895.  
  896.   return preview;
  897. }
  898.  
  899. static void
  900. fill_preview_with_thumb (GtkWidget *widget, 
  901.              gint32     drawable_ID)
  902. {
  903.   guchar  *drawable_data;
  904.   gint     bpp;
  905.   gint     x,y;
  906.   gint     width  = PREVIEW_SIZE;
  907.   gint     height = PREVIEW_SIZE;
  908.   guchar  *src;
  909.   gdouble  r, g, b, a;
  910.   gdouble  c0, c1;
  911.   guchar  *p0, *p1;
  912.   guchar  *even, *odd;
  913.  
  914.   bpp = 0; /* Only returned */
  915.   
  916.   drawable_data = 
  917.     gimp_drawable_get_thumbnail_data (drawable_ID, &width, &height, &bpp);
  918.  
  919.   if (width < 1 || height < 1)
  920.     return;
  921.  
  922.   gtk_preview_size (GTK_PREVIEW (widget), width, height);
  923.   preview_scale_x = (gdouble)width  / (gdouble)gimp_drawable_width  (drawable_ID);
  924.   preview_scale_y = (gdouble)height / (gdouble)gimp_drawable_height (drawable_ID);
  925.  
  926.   even = g_malloc (width * 3);
  927.   odd  = g_malloc (width * 3);
  928.   src  = drawable_data;
  929.  
  930.   for (y = 0; y < height; y++)
  931.     {
  932.       p0 = even;
  933.       p1 = odd;
  934.       
  935.       for (x = 0; x < width; x++) 
  936.     {
  937.       if (bpp == 4)
  938.         {
  939.           r = ((gdouble)src[x*4+0]) / 255.0;
  940.           g = ((gdouble)src[x*4+1]) / 255.0;
  941.           b = ((gdouble)src[x*4+2]) / 255.0;
  942.           a = ((gdouble)src[x*4+3]) / 255.0;
  943.         }
  944.       else if (bpp == 3)
  945.         {
  946.           r = ((gdouble)src[x*3+0]) / 255.0;
  947.           g = ((gdouble)src[x*3+1]) / 255.0;
  948.           b = ((gdouble)src[x*3+2]) / 255.0;
  949.           a = 1.0;
  950.         }
  951.     else
  952.       {
  953.         r = ((gdouble)src[x*bpp+0]) / 255.0;
  954.         g = b = r;
  955.         if(bpp == 2)
  956.           a = ((gdouble)src[x*bpp+1]) / 255.0;
  957.         else
  958.           a = 1.0;
  959.       }
  960.     
  961.     if ((x / GIMP_CHECK_SIZE_SM) & 1) 
  962.       {
  963.         c0 = GIMP_CHECK_LIGHT;
  964.         c1 = GIMP_CHECK_DARK;
  965.       } 
  966.     else 
  967.       {
  968.         c0 = GIMP_CHECK_DARK;
  969.         c1 = GIMP_CHECK_LIGHT;
  970.       }
  971.     
  972.     *p0++ = (c0 + (r - c0) * a) * 255.0;
  973.     *p0++ = (c0 + (g - c0) * a) * 255.0;
  974.     *p0++ = (c0 + (b - c0) * a) * 255.0;
  975.     
  976.     *p1++ = (c1 + (r - c1) * a) * 255.0;
  977.     *p1++ = (c1 + (g - c1) * a) * 255.0;
  978.     *p1++ = (c1 + (b - c1) * a) * 255.0;
  979.     
  980.       } /* for */
  981.       
  982.       if ((y / GIMP_CHECK_SIZE_SM) & 1)
  983.     {
  984.       gtk_preview_draw_row (GTK_PREVIEW (widget), (guchar *)odd,  0, y, width);
  985.     }
  986.       else
  987.     {
  988.       gtk_preview_draw_row (GTK_PREVIEW (widget), (guchar *)even, 0, y, width);
  989.     }
  990.       src += width * bpp;
  991.     }
  992.  
  993.   g_free (even);
  994.   g_free (odd);
  995.   g_free (drawable_data);
  996. }
  997.  
  998. /*
  999.  *   Drawing CenterFrame
  1000.  *   if update & PREVIEW, draw preview
  1001.  *   if update & CURSOR,  draw cross cursor
  1002.  */
  1003.  
  1004. static void
  1005. flare_center_draw (FlareCenter *center,
  1006.            gint         update)
  1007. {
  1008.   if (update & PREVIEW)
  1009.     {
  1010.       center->cursor = FALSE;
  1011.       DEBUG1 ("draw-preview\n");
  1012.     }
  1013.  
  1014.   if (update & CURSOR)
  1015.     {
  1016.       DEBUG1 ("draw-cursor %d old=%d,%d cur=%d,%d\n",
  1017.           center->cursor,
  1018.           center->oldx, center->oldy, center->curx, center->cury);
  1019.       gdk_gc_set_function (preview->style->black_gc, GDK_INVERT);
  1020.  
  1021.       if (show_cursor) 
  1022.     {
  1023.       if (center->cursor)
  1024.         {
  1025.           gdk_draw_line (preview->window,
  1026.                  preview->style->black_gc,
  1027.                  center->oldx, 1, 
  1028.                  center->oldx, 
  1029.                  GTK_PREVIEW (preview)->buffer_height - 1);
  1030.           gdk_draw_line (preview->window,
  1031.                  preview->style->black_gc,
  1032.                  1, center->oldy, 
  1033.                  GTK_PREVIEW (preview)->buffer_width - 1, 
  1034.                  center->oldy);
  1035.         }
  1036.  
  1037.       gdk_draw_line (preview->window,
  1038.              preview->style->black_gc,
  1039.              center->curx, 1, 
  1040.              center->curx, 
  1041.              GTK_PREVIEW (preview)->buffer_height - 1);
  1042.       gdk_draw_line (preview->window,
  1043.              preview->style->black_gc,
  1044.              1, center->cury, 
  1045.              GTK_PREVIEW (preview)->buffer_width - 1, 
  1046.              center->cury);
  1047.     }
  1048.  
  1049.       /* current position of cursor is updated */
  1050.       center->oldx = center->curx;
  1051.       center->oldy = center->cury;
  1052.       center->cursor = TRUE;
  1053.  
  1054.       gdk_gc_set_function (preview->style->black_gc, GDK_COPY);
  1055.     }
  1056. }
  1057.  
  1058.  
  1059. /*
  1060.  *  CenterFrame entry callback
  1061.  */
  1062.  
  1063. static void
  1064. flare_center_adjustment_update (GtkAdjustment *adjustment,
  1065.                 gpointer       data)
  1066. {
  1067.   FlareCenter *center;
  1068.  
  1069.   gimp_int_adjustment_update (adjustment, data);
  1070.  
  1071.   center = gtk_object_get_user_data (GTK_OBJECT (adjustment));
  1072.  
  1073.   if (!center->in_call)
  1074.     {
  1075.       flare_center_cursor_update (center);
  1076.       flare_center_draw (center, CURSOR);
  1077.       FlareFX(center->drawable, 1);
  1078.     }
  1079. }
  1080.  
  1081. /*
  1082.  *  Update the cross cursor's coordinates accoding to pvals.[xy]center
  1083.  *  but not redraw it
  1084.  */
  1085.  
  1086. static void
  1087. flare_center_cursor_update (FlareCenter *center)
  1088. {
  1089.   center->curx = 
  1090.     fvals.posx * GTK_PREVIEW (preview)->buffer_width / center->dwidth;
  1091.   center->cury = 
  1092.     fvals.posy * GTK_PREVIEW (preview)->buffer_height / center->dheight;
  1093.  
  1094.   if ( center->curx < 0)             
  1095.     center->curx = 0;
  1096.   else if (center->curx >= GTK_PREVIEW (preview)->buffer_width)   
  1097.     center->curx = GTK_PREVIEW (preview)->buffer_width - 1;
  1098.  
  1099.   if (center->cury < 0)                     
  1100.     center->cury = 0;
  1101.   else if (center->cury >= GTK_PREVIEW (preview)->buffer_height)  
  1102.     center->cury = GTK_PREVIEW (preview)->buffer_height - 1;
  1103. }
  1104.  
  1105. /*
  1106.  *    Handle the expose event on the preview
  1107.  */
  1108. static gint
  1109. flare_center_preview_expose (GtkWidget *widget,
  1110.                  GdkEvent  *event)
  1111. {
  1112.   FlareCenter *center;
  1113.  
  1114.   center = gtk_object_get_user_data (GTK_OBJECT (widget));
  1115.   flare_center_draw (center, ALL);
  1116.   return FALSE;
  1117. }
  1118.  
  1119.  
  1120. /*
  1121.  *    Handle other events on the preview
  1122.  */
  1123.  
  1124. static gint
  1125. flare_center_preview_events (GtkWidget *widget,
  1126.                  GdkEvent  *event)
  1127. {
  1128.   FlareCenter *center;
  1129.   GdkEventButton *bevent;
  1130.   GdkEventMotion *mevent;
  1131.  
  1132.   center = gtk_object_get_user_data (GTK_OBJECT (widget));
  1133.  
  1134.   switch (event->type)
  1135.     {
  1136.     case GDK_EXPOSE:
  1137.       break;
  1138.  
  1139.     case GDK_BUTTON_PRESS:
  1140.       bevent = (GdkEventButton *) event;
  1141.       center->curx = bevent->x;
  1142.       center->cury = bevent->y;
  1143.       goto mouse;
  1144.  
  1145.     case GDK_MOTION_NOTIFY:
  1146.       mevent = (GdkEventMotion *) event;
  1147.       if (!mevent->state) 
  1148.     break;
  1149.       center->curx = mevent->x;
  1150.       center->cury = mevent->y;
  1151.     mouse:
  1152.       flare_center_draw (center, CURSOR);
  1153.       center->in_call = TRUE;
  1154.       gtk_adjustment_set_value (GTK_ADJUSTMENT (center->xadj),
  1155.                                 center->curx * center->dwidth /
  1156.                                 GTK_PREVIEW (preview)->buffer_width);
  1157.       gtk_adjustment_set_value (GTK_ADJUSTMENT (center->yadj),
  1158.                                 center->cury * center->dheight /
  1159.                                 GTK_PREVIEW (preview)->buffer_height);
  1160.       center->in_call = FALSE;
  1161.       FlareFX(center->drawable, 1);
  1162.       break;
  1163.  
  1164.     default:
  1165.       break;
  1166.     }
  1167.  
  1168.   return FALSE;
  1169. }
  1170.