home *** CD-ROM | disk | FTP | other *** search
/ ftp.sunet.sepub/pictures / 2014.11.ftp.sunet.se-pictures.tar / ftp.sunet.se / pub / pictures / ACiD-artpacks / programs / unix / editors / gimp-plugins-unstable-0_99_23_tar.gz / gimp-plugins-unstable-0_99_23_tar / gimp-plugins-unstable-0.99.23 / CentralReflection / CentralReflection.c next >
C/C++ Source or Header  |  1998-02-20  |  21KB  |  681 lines

  1. /**********************************************************************
  2.  *  CentralReflection Distortion Plug-In (Version 1.04)
  3.  *  Daniel Cotting (cotting@mygale.org)
  4.  **********************************************************************
  5.  *  Official homepages: http://www.mygale.org/~cotting
  6.  *                      http://cotting.citeweb.net
  7.  *                      http://village.cyberbrain.com/cotting
  8.  **********************************************************************    
  9.  */
  10.  
  11. /* The GIMP -- an image manipulation program
  12.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  13.  *
  14.  * This program is free software; you can redistribute it and/or modify
  15.  * it under the terms of the GNU General Public License as published by
  16.  * the Free Software Foundation; either version 2 of the License, or
  17.  * (at your option) any later version.
  18.  *
  19.  * This program is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  * GNU General Public License for more details.
  23.  *
  24.  * You should have received a copy of the GNU General Public License
  25.  * along with this program; if not, write to the Free Software
  26.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27.  */
  28.  
  29. #include <stdlib.h>
  30. #include <math.h>
  31. #include <signal.h>
  32. #include <unistd.h>
  33.  
  34. #include "libgimp/gimp.h"
  35. #include "gtk/gtk.h"
  36. #include "logo.h"
  37.  
  38. #define ENTRY_WIDTH 100
  39.  
  40. /* Declare local functions.
  41.  */
  42. static void query(void);
  43. static void run(char *name, int nparams,
  44.         GParam *param,
  45.         int *nreturn_vals,
  46.         GParam **return_vals);
  47.  
  48. static void drawCentralReflection(GDrawable *drawable);
  49. static gint CentralReflection_dialog(GDrawable *drawable);
  50.  
  51. GPlugInInfo PLUG_IN_INFO =
  52. {
  53.   NULL, /* init_proc */
  54.   NULL, /* quit_proc */
  55.   query, /* query_proc */
  56.   run, /* run_proc */
  57. };
  58.  
  59. typedef struct
  60. {
  61.   gdouble cone_radius;
  62.   gint keep_surr, use_bkgr, set_transparent, use_antialias,flip;
  63. } CentralReflectionValues;
  64.  
  65. static CentralReflectionValues lvals =
  66. {
  67.   /* CentralReflection cone radius value */
  68.   100,
  69.   /* Surroundings options */
  70.   TRUE, FALSE, FALSE, TRUE, TRUE
  71. };
  72.  
  73. typedef struct
  74. {
  75.   gint run;
  76. } CentralReflectionInterface;
  77.  
  78. static CentralReflectionInterface bint =
  79. {
  80.   FALSE  /*  run  */
  81. };
  82.  
  83. GtkWidget * CentralReflection_logo_dialog(void);
  84.  
  85.  
  86. GtkWidget *maindlg;
  87. GtkWidget *logodlg;
  88. GtkTooltips *tips;
  89. GdkColor tips_fg,tips_bg;    
  90.  
  91. MAIN()
  92.  
  93. static void
  94. query(void)
  95. {
  96.   static GParamDef args[] =
  97.   {
  98.     { PARAM_INT32, "run_mode", "Interactive, non-interactive" },
  99.     { PARAM_IMAGE, "image", "Input image (unused)" },
  100.     { PARAM_DRAWABLE, "drawable", "Input drawable" },
  101.     { PARAM_FLOAT, "circle_radius", "Radius of the reflecting circle" },
  102.     { PARAM_INT32, "keep_surroundings", "Keep Central-Reflection surroundings" },
  103.     { PARAM_INT32, "set_background", "Set Central-Reflection surroundings to bkgr value" },
  104.     { PARAM_INT32, "set_transparent", "Set Central-Reflection surroundings transparent (Only on Image w/ Alpha-Layer)" },
  105.     { PARAM_INT32, "use_antialias", "Use antialias for better and smoother results" },
  106.     { PARAM_INT32, "flip", "Flip the image vertically" },
  107.   };
  108.  
  109.   static GParamDef *return_vals = NULL;
  110.   static int nargs = sizeof(args)/ sizeof(args[0]);
  111.   static int nreturn_vals = 0;
  112.  
  113.   gimp_install_procedure("plug_in_CentralReflection",
  114.              "Apply a Central-Reflection effect",
  115.              "",
  116.              "Daniel Cotting (cotting@mygale.org, http://www.mygale.org/~cotting)",
  117.              "Daniel Cotting (cotting@mygale.org, http://www.mygale.org/~cotting)",
  118.              "October, 1997",
  119.              "<Image>/Filters/Glass Effects/Central Reflection",
  120.              "RGB*, GRAY*, INDEXED*",
  121.              PROC_PLUG_IN,
  122.              nargs, nreturn_vals,
  123.              args, return_vals);
  124. }
  125.  
  126. static void
  127. run(char *name,
  128.     int nparams,
  129.     GParam *param,
  130.     int *nreturn_vals,
  131.     GParam **return_vals)
  132. {
  133.   static GParam values[1];
  134.   GDrawable *drawable;
  135.   GRunModeType run_mode;
  136.   GStatusType status = STATUS_SUCCESS;
  137.  
  138.   run_mode = param[0].data.d_int32;
  139.  
  140.   values[0].type = PARAM_STATUS;
  141.   values[0].data.d_status = status;
  142.   
  143.   *nreturn_vals = 1;
  144.   *return_vals = values;
  145.   
  146.   drawable = gimp_drawable_get(param[2].data.d_drawable);
  147.  
  148.   switch(run_mode) {
  149.   case RUN_INTERACTIVE:
  150.     gimp_get_data("plug_in_CentralReflection", &lvals);
  151.     if(!CentralReflection_dialog(drawable)) return;
  152.     break;
  153.  
  154.   case RUN_NONINTERACTIVE:
  155.     if(nparams != 9) status = STATUS_CALLING_ERROR;
  156.     if(status == STATUS_SUCCESS) {
  157.       lvals.cone_radius = param[3].data.d_float;
  158.       lvals.keep_surr = param[4].data.d_int32;
  159.       lvals.use_bkgr = param[5].data.d_int32;
  160.       lvals.set_transparent = param[6].data.d_int32;
  161.       lvals.use_antialias = param[7].data.d_int32;
  162.       lvals.flip = param[8].data.d_int32;
  163.     }
  164.  
  165.     if(status == STATUS_SUCCESS && (lvals.cone_radius <= 0))
  166.       status = STATUS_CALLING_ERROR;
  167.     break;
  168.  
  169.   case RUN_WITH_LAST_VALS:
  170.     gimp_get_data ("plug_in_CentralReflection", &lvals);
  171.     break;
  172.     
  173.   default:
  174.     break;
  175.   }
  176.  
  177.   printf("creflect: waiting... (pid %d)\n", getpid());
  178.   kill(getpid(), SIGSTOP);
  179.  
  180.   gimp_tile_cache_ntiles(2 *(drawable->width / gimp_tile_width() + 1));
  181.   gimp_progress_init("Applying Central-Reflection. Please wait...");
  182.   drawCentralReflection(drawable);
  183.  
  184.   if(run_mode != RUN_NONINTERACTIVE)
  185.     gimp_displays_flush();
  186.   if(run_mode == RUN_INTERACTIVE)
  187.     gimp_set_data("plug_in_CentralReflection", &lvals, sizeof(CentralReflectionValues));
  188.  
  189.   values[0].data.d_status = status;
  190.   
  191.   gimp_drawable_detach(drawable);
  192. }
  193.  
  194.  
  195. static void
  196. set_tooltip (GtkTooltips *tooltips, GtkWidget *widget, const char *desc)
  197. {
  198.   if (desc && desc[0])
  199.     gtk_tooltips_set_tip  (tooltips, widget, (char *) desc, NULL);
  200. }
  201.  
  202. static void
  203. drawCentralReflection(GDrawable *drawable)
  204. {
  205.   GPixelRgn srcPR, destPR;
  206.   gint width, height;
  207.   gint bytes;
  208.   gdouble abstand;
  209.   gdouble radius;
  210.   gdouble verhaltniss, a1,a2,a3,a4,faktor,a_tot;
  211.   gint row;
  212.   gint x1, y1, x2, y2, ix, iy;
  213.   guchar *src, *dest;
  214.   gint i, col, succeeded;
  215.   gfloat regionwidth, regionheight, dx, dy;
  216.   gfloat a, b, x, y;
  217.   glong pixelpos, pos;
  218.   guchar bgr_red, bgr_blue, bgr_green, alphaval;
  219.   GDrawableType drawtype = gimp_drawable_type(drawable->id);
  220.  
  221.   gimp_palette_get_background(&bgr_red, &bgr_green, &bgr_blue);
  222.  
  223.   gimp_drawable_mask_bounds(drawable->id, &x1, &y1, &x2, &y2);
  224.   regionwidth = x2-x1;
  225.   a = regionwidth/2;
  226.   regionheight = y2-y1;
  227.   b = regionheight/2;
  228.  
  229.   radius=lvals.cone_radius;
  230.   
  231.   width = drawable->width;
  232.   height = drawable->height;
  233.   bytes = drawable->bpp;
  234.  
  235.   gimp_pixel_rgn_init(&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
  236.   gimp_pixel_rgn_init(&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
  237.  
  238.   src = g_malloc((x2-x1)*(y2-y1)*bytes);
  239.   dest = g_malloc((x2-x1)*(y2-y1)*bytes);
  240.   gimp_pixel_rgn_get_rect(&srcPR, src, x1, y1, regionwidth, regionheight);
  241.  
  242.   for(col = 0; col < regionwidth; col++) {
  243.     dx = (gfloat)col - a; 
  244.     for(row = 0; row < regionheight; row++) {
  245.       pixelpos = (col+row*regionwidth)*bytes;
  246.       dy = -((gfloat)row - b); 
  247.       abstand=(sqrt(dx*dx+dy*dy));
  248.       succeeded=1;
  249.       verhaltniss=radius/abstand;
  250.       if (lvals.flip) dy = -dy;
  251.       x = dx/(abstand/(radius*verhaltniss))+a;
  252.       y = dy/(abstand/(radius*verhaltniss))+b;
  253.       if (x>regionwidth) succeeded=0;
  254.       if (y>regionheight) succeeded=0;
  255.       if (x<0) succeeded=0;
  256.       if (y<0) succeeded=0;
  257.       if (succeeded){  
  258.       ix=(int)x;
  259.       iy=(int)y;
  260.       if (lvals.use_antialias) {
  261.          if ((ix - x)<0){
  262.                if ((iy - y)<0){} else {iy-=1;}
  263.          } else{
  264.                if ((iy - y)<0){ix-=1;} else {iy-=1;ix-=1;}
  265.          }
  266.              a1=1/((ix-x)*(ix-x)+(iy-y)*(iy-y));   
  267.              a2=1/((ix+1-x)*(ix+1-x)+(iy-y)*(iy-y));   
  268.              a3=1/((ix-x)*(ix-x)+(iy+1-y)*(iy+1-y));   
  269.              a4=1/((ix+1-x)*(ix+1-x)+(iy+1-y)*(iy+1-y));
  270.              a_tot=a1+a2+a3+a4;
  271.              faktor=1/a_tot;
  272.              a1*=faktor;
  273.              a2*=faktor;
  274.              a3*=faktor;
  275.              a4*=faktor;
  276.     
  277.              pos = ((gint)(iy)*regionwidth + (gint)(ix)) * bytes;
  278.  
  279.          for (i = 0; i < bytes; i++) {
  280.            dest[pixelpos+i] = (gint)((gdouble)(src[pos+i])*a1+(gdouble)(src[pos+i+bytes])*a2+(gdouble)(src[pos+i+(gint)(regionwidth*bytes)])*a3+(gdouble)(src[pos+i+(gint)(regionwidth*bytes)+bytes])*a4);
  281.          }
  282.        } else {
  283.          pos = ((gint)(iy)*regionwidth + (gint)(ix)) * bytes;
  284.          for(i = 0; i < bytes; i++) {
  285.             dest[pixelpos+i] = src[pos+i];
  286.          }
  287.       }
  288.     }
  289.     if (succeeded==0){
  290.     if(lvals.keep_surr) {
  291.       for(i = 0; i < bytes; i++) {
  292.         dest[pixelpos+i] = src[pixelpos+i];
  293.       }
  294.     } else {
  295.       if(lvals.set_transparent) alphaval = 0;
  296.       else alphaval = 255;
  297.  
  298.       switch(drawtype) {
  299.       case INDEXEDA_IMAGE:
  300.         dest[pixelpos+1] = alphaval;
  301.       case INDEXED_IMAGE:
  302.         dest[pixelpos+0] = 0;
  303.         break;
  304.  
  305.       case RGBA_IMAGE:
  306.         dest[pixelpos+3] = alphaval;
  307.       case RGB_IMAGE:
  308.         dest[pixelpos+0] = bgr_red;
  309.         dest[pixelpos+1] = bgr_green;
  310.         dest[pixelpos+2] = bgr_blue;
  311.         break;
  312.  
  313.       case GRAYA_IMAGE:
  314.         dest[pixelpos+1] = alphaval;
  315.       case GRAY_IMAGE:
  316.         dest[pixelpos+0] = bgr_red;
  317.         break;
  318.       }
  319.     }
  320.     
  321.       } 
  322.     }
  323.  
  324.       
  325.     if(((gint)(regionwidth-col) % 5) == 0)
  326.       gimp_progress_update((gdouble)col/(gdouble)regionwidth);
  327.   }
  328.  
  329.   gimp_pixel_rgn_set_rect(&destPR, dest, x1, y1, regionwidth, regionheight);
  330.   g_free(src);
  331.   g_free(dest);
  332.  
  333.   gimp_drawable_flush(drawable);
  334.   gimp_drawable_merge_shadow(drawable->id, TRUE);
  335.   gimp_drawable_update(drawable->id, x1, y1,(x2 - x1),(y2 - y1));
  336. }
  337.  
  338. static void
  339. CentralReflection_close_callback(GtkWidget *widget,  gpointer   data)
  340. {
  341.   gtk_main_quit();
  342. }
  343.  
  344. static void
  345. CentralReflection_ok_callback(GtkWidget *widget, gpointer   data)
  346. {
  347.   bint.run = TRUE;
  348.   gtk_widget_destroy(GTK_WIDGET (data));
  349. }
  350.  
  351. static void
  352. CentralReflection_toggle_update(GtkWidget *widget, gpointer   data)
  353. {
  354.   int *toggle_val;
  355.  
  356.   toggle_val = (int *)data;
  357.  
  358.   if(GTK_TOGGLE_BUTTON (widget)->active)
  359.     *toggle_val = TRUE;
  360.   else
  361.     *toggle_val = FALSE;
  362. }
  363.  
  364. static void
  365. toggle_update (GtkWidget *widget,
  366.                gpointer   data)
  367. {
  368.   int *toggle_val;
  369.  
  370.   toggle_val = (int *) data;
  371.  
  372.   if (GTK_TOGGLE_BUTTON (widget)->active)
  373.     *toggle_val = TRUE;
  374.   else
  375.     *toggle_val = FALSE;
  376. }
  377.  
  378. static void
  379. CentralReflection_entry_callback(GtkWidget *widget, gpointer   data)
  380. {
  381.   lvals.cone_radius = atof(gtk_entry_get_text(GTK_ENTRY(widget)));
  382.   if(lvals.cone_radius <= 0) lvals.cone_radius = 10;
  383. }
  384.  
  385. static void
  386. CentralReflection_logo_ok_callback(GtkWidget *widget, gpointer   data)
  387. {
  388.   gtk_widget_set_sensitive (maindlg, TRUE);
  389.   gtk_widget_destroy(logodlg);
  390. }
  391.  
  392.  
  393. static void
  394. CentralReflection_about_callback(GtkWidget *widget, gpointer   data)
  395. {
  396.   gtk_widget_set_sensitive (maindlg, FALSE);
  397.   CentralReflection_logo_dialog();
  398. }
  399.  
  400.  
  401. static gint
  402. CentralReflection_dialog(GDrawable *drawable)
  403. {
  404.   GtkWidget *dlg;
  405.   GtkWidget *label;
  406.   GtkWidget *entry;
  407.   GtkWidget *button;
  408.   GtkWidget *toggle;
  409.   GtkWidget *frame;
  410.   GtkWidget *vbox;
  411.   GtkWidget *hbox;
  412.   gchar buffer[12];
  413.   gchar **argv;
  414.   gint argc;
  415.   GSList *group = NULL;
  416.   GDrawableType drawtype;
  417.  
  418.   drawtype = gimp_drawable_type(drawable->id);
  419.  
  420.   argc = 1;
  421.   argv = g_new(gchar *, 1);
  422.   argv[0] = g_strdup("apply_CentralReflection");
  423.  
  424.   gtk_init(&argc, &argv);
  425.   gtk_rc_parse(gimp_gtkrc());
  426.  
  427.   dlg = maindlg = gtk_dialog_new();
  428.   gtk_window_set_title(GTK_WINDOW(dlg), "Central-Reflection");
  429.   gtk_window_position(GTK_WINDOW(dlg), GTK_WIN_POS_MOUSE);
  430.   gtk_signal_connect(GTK_OBJECT(dlg), "destroy",
  431.                      (GtkSignalFunc)CentralReflection_close_callback,
  432.              NULL);
  433.   frame = gtk_frame_new("Parameter Settings");
  434.   gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
  435.   gtk_container_border_width(GTK_CONTAINER(frame), 10);
  436.   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), frame, TRUE, TRUE, 0);
  437.   vbox = gtk_vbox_new(FALSE, 5);
  438.   gtk_container_border_width(GTK_CONTAINER(vbox), 10);
  439.   gtk_container_add(GTK_CONTAINER(frame), vbox);
  440.   
  441.         /* use black as foreground: */
  442.         tips = gtk_tooltips_new ();
  443.         tips_fg.red   = 0;
  444.         tips_fg.green = 0;
  445.         tips_fg.blue  = 0;
  446.        /* postit yellow (khaki) as background: */
  447.         gdk_color_alloc (gtk_widget_get_colormap (frame), &tips_fg);
  448.         tips_bg.red   = 61669;
  449.         tips_bg.green = 59113;
  450.         tips_bg.blue  = 35979;
  451.         gdk_color_alloc (gtk_widget_get_colormap (frame), &tips_bg);
  452.         gtk_tooltips_set_colors (tips,&tips_bg,&tips_fg);
  453.  
  454.   toggle = gtk_radio_button_new_with_label(group,
  455.                        "Keep original surroundings");
  456.   group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle));
  457.   gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
  458.   gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
  459.                      (GtkSignalFunc) CentralReflection_toggle_update,
  460.              &lvals.keep_surr);
  461.   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), lvals.keep_surr);
  462.   gtk_widget_show(toggle);
  463.   
  464.   set_tooltip(tips,toggle,"In the center, where pixels of outside the image borders would be reflected to, the plug-in can't calculate a reasonable image. If this option is enabled, this area will be filled with the original image.");
  465.  
  466.   toggle =
  467.     gtk_radio_button_new_with_label(group,
  468.                     drawtype == INDEXEDA_IMAGE ||
  469.                     drawtype == INDEXED_IMAGE ?
  470.                     "Set surroundings to index 0" :
  471.                     "Set surroundings to background color");
  472.   group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle));
  473.   gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
  474.   gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
  475.                      (GtkSignalFunc) CentralReflection_toggle_update,
  476.              &lvals.use_bkgr);
  477.   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), lvals.use_bkgr);
  478.   gtk_widget_show(toggle);
  479.   set_tooltip(tips,toggle,"In the center, where pixels of outside the image borders would be reflected to, the plug-in can't calculate a reasonable image. If this option is enabled, this area will be filled with the active background color or the index-0-color, depending on the image type.");
  480.  
  481.   if((drawtype == INDEXEDA_IMAGE) ||
  482.      (drawtype == GRAYA_IMAGE) ||
  483.      (drawtype == RGBA_IMAGE)) {
  484.     toggle = gtk_radio_button_new_with_label(group,
  485.                          "Make surroundings transparent");
  486.     group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle));
  487.     gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
  488.     gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
  489.                (GtkSignalFunc) CentralReflection_toggle_update,
  490.                &lvals.set_transparent);
  491.     gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle),
  492.                 lvals.set_transparent);
  493.     gtk_widget_show(toggle);
  494.     set_tooltip(tips,toggle,"In the center, where pixels of outside the image borders would be reflected to, the plug-in can't calculate a reasonable image. If this option is enabled, this area will be kept transparent.");
  495.  
  496.   }
  497.  
  498.   if((drawtype != INDEXEDA_IMAGE) && (drawtype != INDEXED_IMAGE)){
  499.     toggle = gtk_check_button_new_with_label ("Use antialias (recommended)");
  500.     gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
  501.     gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
  502.                 (GtkSignalFunc) toggle_update,
  503.                 &lvals.use_antialias);
  504.     gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toggle), lvals.use_antialias);
  505.     gtk_widget_show (toggle);
  506.     set_tooltip(tips,toggle,"If this option is enabled, an antialias algorithm will be used to produce a better and smoother output.");
  507.  
  508.   } else{ lvals.use_antialias=FALSE;}    
  509.  
  510.   toggle = gtk_check_button_new_with_label ("Flip image vertically");
  511.   gtk_box_pack_start(GTK_BOX(vbox), toggle, FALSE, FALSE, 0);
  512.   gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
  513.               (GtkSignalFunc) toggle_update,
  514.               &lvals.flip);
  515.   gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toggle), lvals.flip);
  516.   gtk_widget_show (toggle);
  517.   set_tooltip(tips,toggle,"With this option you can flip the image vertically.");
  518.  
  519.  
  520.   hbox = gtk_hbox_new(FALSE, 5);
  521.   gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
  522.  
  523.   label = gtk_label_new("Radius of reflection-circle: ");
  524.   gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, FALSE, 0);
  525.   gtk_widget_show(label);
  526.  
  527.   entry = gtk_entry_new();
  528.   gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
  529.   gtk_widget_set_usize(entry, ENTRY_WIDTH, 0);
  530.   sprintf(buffer, "%.2f", lvals.cone_radius);
  531.   gtk_entry_set_text(GTK_ENTRY(entry), buffer);
  532.   gtk_signal_connect(GTK_OBJECT(entry), "changed",
  533.              (GtkSignalFunc)CentralReflection_entry_callback,
  534.              NULL);
  535.   gtk_widget_show(entry);
  536.   set_tooltip(tips,entry,"This specifies the radius of the circle, at which every pixel is mirrored. Pixels outside the circle will be reflected into its inner part and vice versa.");
  537.   
  538.   
  539.   gtk_widget_show(hbox);
  540.  
  541.   gtk_widget_show(vbox);
  542.   gtk_widget_show(frame);
  543.              
  544.  
  545.   button = gtk_button_new_with_label("OK");
  546.   GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
  547.   gtk_signal_connect(GTK_OBJECT(button), "clicked",
  548.                      (GtkSignalFunc)CentralReflection_ok_callback,
  549.              dlg);
  550.   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area),
  551.              button, TRUE, TRUE, 0);
  552.   gtk_widget_grab_default(button);
  553.   gtk_widget_show(button);
  554.   set_tooltip(tips,button,"Close the dialog box and apply distortion.");
  555.  
  556.   button = gtk_button_new_with_label("Cancel");
  557.   GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
  558.   gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
  559.                             (GtkSignalFunc)gtk_widget_destroy,
  560.                 GTK_OBJECT(dlg));
  561.   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area),
  562.              button, TRUE, TRUE, 0);
  563.   gtk_widget_show(button);
  564.   set_tooltip(tips,button,"Close the dialog box without applying distortion.");
  565.  
  566.       button = gtk_button_new_with_label("About...");
  567.         GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
  568.         gtk_signal_connect(GTK_OBJECT(button), "clicked",
  569.                      (GtkSignalFunc)CentralReflection_about_callback,button);
  570.         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area),
  571.              button, TRUE, TRUE, 0);
  572.         gtk_widget_show(button);
  573.   set_tooltip(tips,button,"Show information about the author and the plug-in.");
  574.  
  575.   
  576.   gtk_widget_show(dlg);
  577.  
  578.   gtk_main();
  579.  
  580.   gtk_object_unref(GTK_OBJECT(tips));
  581.  
  582.   gdk_flush();
  583.  
  584.   return bint.run;
  585. }
  586.  
  587. GtkWidget * 
  588. CentralReflection_logo_dialog()
  589. {
  590.   GtkWidget *xdlg;
  591.   GtkWidget *xlabel;
  592.   GtkWidget *xbutton;
  593.   GtkWidget *xlogo_box;
  594.   GtkWidget *xpreview;
  595.   GtkWidget *xframe,*xframe2;
  596.   GtkWidget *xvbox;
  597.   GtkWidget *xhbox;
  598.   char *text;
  599.   guchar *temp,*temp2;
  600.   guchar *datapointer;
  601.   gint y,x;
  602.   xdlg = logodlg = gtk_dialog_new();
  603.   gtk_window_set_title(GTK_WINDOW(xdlg), "About");
  604.   gtk_window_position(GTK_WINDOW(xdlg), GTK_WIN_POS_MOUSE);
  605.   gtk_signal_connect(GTK_OBJECT(xdlg), "destroy",
  606.                      (GtkSignalFunc)CentralReflection_close_callback,
  607.              NULL);
  608.  
  609.   xbutton = gtk_button_new_with_label("OK");
  610.   GTK_WIDGET_SET_FLAGS(xbutton, GTK_CAN_DEFAULT);
  611.   gtk_signal_connect(GTK_OBJECT(xbutton), "clicked",
  612.                      (GtkSignalFunc)CentralReflection_logo_ok_callback,
  613.              xdlg);
  614.   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(xdlg)->action_area),
  615.              xbutton, TRUE, TRUE, 0);
  616.   gtk_widget_grab_default(xbutton);
  617.   gtk_widget_show(xbutton);
  618.   set_tooltip(tips,xbutton,"Close the information box.");
  619.  
  620.   xframe = gtk_frame_new(NULL);
  621.   gtk_frame_set_shadow_type(GTK_FRAME(xframe), GTK_SHADOW_ETCHED_IN);
  622.   gtk_container_border_width(GTK_CONTAINER(xframe), 10);
  623.   gtk_box_pack_start(GTK_BOX(GTK_DIALOG(xdlg)->vbox), xframe, TRUE, TRUE, 0);
  624.   xvbox = gtk_vbox_new(FALSE, 5);
  625.   gtk_container_border_width(GTK_CONTAINER(xvbox), 10);
  626.   gtk_container_add(GTK_CONTAINER(xframe), xvbox);
  627.  
  628.   /*  The logo frame & drawing area  */
  629.   xhbox = gtk_hbox_new (FALSE, 5);
  630.   gtk_box_pack_start (GTK_BOX (xvbox), xhbox, FALSE, TRUE, 0);
  631.  
  632.   xlogo_box = gtk_vbox_new (FALSE, 0);
  633.   gtk_box_pack_start (GTK_BOX (xhbox), xlogo_box, FALSE, FALSE, 0);
  634.  
  635.   xframe2 = gtk_frame_new (NULL);
  636.   gtk_frame_set_shadow_type (GTK_FRAME (xframe2), GTK_SHADOW_IN);
  637.   gtk_box_pack_start (GTK_BOX (xlogo_box), xframe2, FALSE, FALSE, 0);
  638.  
  639.   xpreview = gtk_preview_new (GTK_PREVIEW_COLOR);
  640.   gtk_preview_size (GTK_PREVIEW (xpreview), logo_width, logo_height);
  641.   temp = g_malloc((logo_width+10)*3);
  642.   datapointer=header_data+logo_width*logo_height-1;
  643.   for (y = 0; y < logo_height; y++){
  644.     temp2=temp;
  645.     for (x = 0; x< logo_width; x++) {
  646.       HEADER_PIXEL(datapointer,temp2); temp2+=3;}
  647.     gtk_preview_draw_row (GTK_PREVIEW (xpreview),
  648.               temp,
  649.               0, y, logo_width); 
  650.   }              
  651.   g_free(temp);
  652.   gtk_container_add (GTK_CONTAINER (xframe2), xpreview);
  653.   gtk_widget_show (xpreview);
  654.   gtk_widget_show (xframe2);
  655.   gtk_widget_show (xlogo_box);
  656.   gtk_widget_show (xhbox);
  657.  
  658.   xhbox = gtk_hbox_new(FALSE, 5);
  659.   gtk_box_pack_start(GTK_BOX(xvbox), xhbox, TRUE, TRUE, 0);
  660.   text = "\nCotting Software Productions\n"
  661.          "Bahnhofstrasse 31\n"
  662.        "CH-3066 Stettlen (Switzerland)\n\n"
  663.      "cotting@mygale.org\n"
  664.      "http://www.mygale.org/~cotting\n\n"
  665.           "Central-Reflection\n Plug-In for the GIMP\n"
  666.           "Version 1.04\n";
  667.   xlabel = gtk_label_new(text);
  668.   gtk_box_pack_start(GTK_BOX(xhbox), xlabel, TRUE, FALSE, 0);
  669.   gtk_widget_show(xlabel);
  670.  
  671.   gtk_widget_show(xhbox);
  672.  
  673.   gtk_widget_show(xvbox);
  674.   gtk_widget_show(xframe);
  675.   gtk_widget_show(xdlg);
  676.  
  677.   gtk_main();
  678.   gdk_flush();
  679.   return xdlg;
  680. }
  681.