/**************************************************************************

   Fotoxx      edit photos and manage collections

   Copyright 2007 2008 2009 2010 2011  Michael Cornelison
   Source URL: http://kornelix.squarespace.com/fotoxx
   Contact: kornelix2@googlemail.com
   
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program. If not, see http://www.gnu.org/licenses/.

***************************************************************************/

#include <tiffio.h>
#include "zfuncs.h"

//  Fotoxx definitions

#define fversion "Fotoxx v.12.01.2"                                        //  this fotoxx version
#define flicense "Free software - GNU General Public License v.3"
#define fhomepage "http://kornelix.squarespace.com/fotoxx"
#define ftranslators                                                                \
      "Translators: Jie Luo, Justa, Peter Landgren, Alexander Krasnopolsky, \n"     \
      "   Arthur Kalverboer, André Campos Rodovalho, Doriano Blengino"
#define fcredits "Software used: GTK, libtiff, ufraw, exiftool"
#define fcontact "Bug reports: kornelix2@gmail.com"

//  GTK definitions

#define PXB GdkPixbuf
#define TEXTWIN GTK_TEXT_WINDOW_TEXT                                       //  GDK window of GTK text view
#define NODITHER GDK_RGB_DITHER_NONE
#define ALWAYS GTK_POLICY_ALWAYS
#define NEVER GTK_POLICY_NEVER
#define RGBCOLOR GDK_COLORSPACE_RGB
#define LINEATTRIBUTES GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER
#define BILINEAR GDK_INTERP_BILINEAR
#define HYPER GDK_INTERP_HYPER
#define MWIN GTK_WINDOW(mWin)

//  EXIF/IPTC keys for embedded image data

#define iptc_tags_key "Keywords"                                           //  tags (IPTC)
#define iptc_rating_key "Rating"                                           //  star rating (IPTC)
#define exif_date_key "DateTimeOriginal"                                   //  date/time (EXIF)
#define exif_width_key "ImageWidth"                                        //  width, pixels (EXIF)
#define exif_height_key "ImageHeight"                                      //  height, pixels (EXIF)
#define exif_orientation_key "Orientation"                                 //  orientation (EXIF)
#define iptc_editlog_key "EditStatus"                                      //  edits applied list (IPTC)
#define exif_comment_key "UserComment"                                     //  user comments (EXIF)
#define iptc_caption_key "Caption-Abstract"                                //  image caption (IPTC)
#define exif_focal_length_key "FocalLengthIn35mmFormat"                    //  focal length (EXIF)

//  fotoxx definitions

#define mega (1024 * 1024)
#define ftrash "Desktop/fotoxx-trash"                                      //  special trash folder location
#define def_jpeg_quality "90"                                              //  default jpeg quality (high)
#define pi 3.141592654
#define PXMpix(pxm,px,py) ((uint16 *) pxm->bmp+((py)*(pxm->ww)+(px))*3)    //  return PXM pixel[3] at (px,py) (16-bit)
#define PXMpix8(pxm,px,py) ((uint8 *) pxm->bmp+((py)*(pxm->ww)+(px))*3)    //  return PXM pixel[3] at (px,py) (8-bit)
#define pixbright(pix) (0.25*(pix)[0]+0.65*(pix)[1]+0.10*(pix)[2])         //  pixel brightness, 0-64K
#define pixred(pix) (25 * pix[0] / (pixbright(pix)+1))                     //  pixel redness, 0-100%
#define Nrecentfiles 100                                                   //  most recent image files
#define max_threads 6                                                      //  max. working threads
#define maxedits 100                                                       //  max. edits, undo/redo depth
#define MAXIMAGES 100000                                                   //  max. image files supported

#define maxtagcats 200                                                     //  max tag categories
#define tagcc  50                                                          //  max cc for one tag or category ID
#define tagFcc 1000                                                        //  max tag cc for one image file
#define tagntc 1000                                                        //  max no. tags for one category
#define tagGcc 50000                                                       //  max tag cc for one category
#define tagTcc 50000                                                       //  max tag cc for all defined tags
#define tagMcc 200                                                         //  max tag cc for batch add tags
#define tagScc 200                                                         //  max tag cc for search tags
#define tagRcc 200                                                         //  max tag cc for recent tags
#define tagrecl 2000                                                       //  tag rec. cc (>maxfcc and >tagFcc)
#define tagdelims  ",;"                                                    //  valid tag delimiters (; obsolete)  v.11.02
#define tagdelim1  ','                                                     //  delimiter for new tags             v.11.02
#define tagdelim2  ", "                                                    //  delimiter + blank                  v.11.02

//  camera RAW file extensions (also upper case will work)

#define RAWfiles  \
".3fr .ari .arw .srf .sr2 .bay .crw .cr2 .cap .iiq .eip .dcs .dcr "     \
".drf .k25 .kdc .dng .erf .fff .mef .mos .mrw .nef .nrw .orf .pef "     \
".ptx .pxn .r3d .raf .raw .rw2 .raw .rwl .dng .rwz .srw .x3f "

//  externals from zfuncs module

namespace  zfuncs {
   extern char    zlang[8];                                                //  current language lc_RC
   extern cchar   *F1_help_topic;                                          //  F1 context help topic
   extern char    zicondir[200];                                           //  where application icons live
   extern int     zdialog_busy;                                            //  tracks open zdialog's
   extern int     open_popup_windows;                                      //  tracks popup windows open
}

namespace  image_navi {                                                    //  image_gallery() data
   extern char    *galleryname;                                            //  directory or file list name
   extern int     gallerytype;                                             //  1/2/3 = directory/file-list/metadata
   extern int     nfiles, nimages;                                         //  file counts, total and images
   extern char    **flist;                                                 //  image file list
   extern char    **mdlist;                                                //  metadata list
   extern int     xwinW, xwinH;                                            //  image gallery window size
   extern int     thumbfilesize;                                           //  thumbnail file image size
   extern int     thumbsize;                                               //  curr. thumbnail display size
   extern int     genthumbs;                                               //  counts thumbnails generated
}

#define ccc (maxfcc*2+200)                                                 //  max. command line size
EX char        command[ccc];                                               //  command, parameters, 2 filespecs

EX char        PIDstring[12];                                              //  process PID as string
EX int         Nwt;                                                        //  working threads to use
EX int         wtnx[8];                                                    //  internal thread IDs
EX int         wthreads_busy;                                              //  active thread count

EX GtkWidget      *mWin, *drWin, *mVbox;                                   //  main and drawing window
EX GtkWidget      *mMbar, *mTbar, *STbar;                                  //  menu bar, tool bar, status bar
EX GdkGC          *gdkgc;                                                  //  GDK graphics context
EX GdkColor       black, white, red, green;
EX GdkColor       lgray, dgray;
EX GdkColor       fg_color;                                                //  current foreground color
EX GdkColormap    *colormap;    
EX uint           maxcolor;

EX GdkCursor      *arrowcursor;                                            //  main window cursors
EX GdkCursor      *dragcursor;
EX GdkCursor      *drawcursor;

EX int         Fexiftool;                                                  //  exiftool program available
EX int         Fexifwarned;                                                //  missing exiftool was warned
EX int         Fufraw;                                                     //  ufraw-batch program is available
EX int         Fxdgopen;                                                   //  xdg-open program available
EX int         Fshutdown;                                                  //  app shutdown underway
EX int         Fdebug;                                                     //  debug flag
EX int         Fkillfunc;                                                  //  signal, kill running function
EX int         Ffuncbusy;                                                  //  function is busy/working
EX int         Wrepaint;                                                   //  request window paint
EX int         Wpainted;                                                   //  window was repainted
EX int         Fmodified;                                                  //  image was edited/modified
EX int         Fsaved;                                                     //  image saved since last mod
EX int         Ftagschanged;                                               //  image tags changed and not saved
EX int         Fpreview;                                                   //  use window image for edits
EX int         Fblowup;                                                    //  zoom small images to window size
EX int         Fmenulock;                                                  //  lock for some menu functions
EX int         Fslideshow;                                                 //  slide show mode is active
EX int         Frecent;                                                    //  start with recent files gallery
EX int         Fprev;                                                      //  start with previous file
EX int         Fblank;                                                     //  start with blank window
EX int         KBzmalloclog;                                               //  KB toggle for zmalloc reporting

EX int         Fautosync;                                                  //  auto file sync is requested
EX int         Fmansync;                                                   //  manual file sync is requested
EX int         Fsyncbusy;                                                  //  file sync is busy/working
EX cchar       *fsync_lock;                                                //  synchronize files interlock     v.11.11

EX char        *topmenu;                                                   //  latest top-menu selection
EX cchar       *threadmessage;                                             //  popup message from thread process

EX char        *SS_imagefile;                                              //  command line -slideshow parameter
EX char        *SS_musicfile;                                              //  command line -music parameter

volatile                                                                   //  stop optimizer removing code    v.11.03
EX int         SB_goal, SB_done;                                           //  status bar progress tracking    v.11.06
EX char        SB_text[200];                                               //  optional status bar application text

EX char        *topdirk;                                                   //  user's top-level image directory
EX char        *curr_file, *curr_dirk;                                     //  current image file and directory
EX char        *recentfiles[Nrecentfiles];                                 //  most recent image files opened
EX char        curr_file_type[8];                                          //  jpg / tif / png / other
EX int         curr_file_bpc;                                              //  image file bits/color, 8/16
EX int         curr_file_size;                                             //  image file size on disk
EX int         curr_file_posn;                                             //  position in current file set
EX int         curr_file_count;                                            //  count of images in current set
EX double      curr_image_time;                                            //  time current image opened       v.11.07

EX char        f_load_type[8];                                             //  data returned by f_load()
EX int         f_load_bpc, f_load_size;
EX char        f_save_type[8];                                             //  data returned by f_save()
EX int         f_save_bpc, f_save_size;
EX char        jpeg_quality[8];                                            //  jpeg file save quality

//  files and directories in /home/<user>/.fotoxx/

EX char        topdirk_file[200];                                          //  top directory save file         v.11.11
EX char        tags_defined_file[200];                                     //  tags defined file
EX char        search_index_file[200];                                     //  search index file               v.11.02
EX char        recentfiles_file[200];                                      //  file of recent image files      v.11.09
EX char        collections_dirk[200];                                      //  directory for saved image collections
EX char        saved_areas_dirk[200];                                      //  directory for saved select area files
EX char        saved_curves_dirk[200];                                     //  directory for saved curve data
EX char        annotations_dirk[200];                                      //  directory for annotation files

//  fotoxx PXM pixmaps

typedef struct  {                                                          //  PXM pixmap
   char        wmi[8];
   int         ww, hh, bpc;                                                //  width, height, bits per color
   void        *bmp;                                                       //  uint8*/uint16* (bpc=8/16)
}  PXM;

EX PXM         *Fpxm8;                                                     //  input file pixmap, PXM-8
EX PXM         *Fpxm16;                                                    //  input file pixmap, PXM-16
EX PXM         *E1pxm16;                                                   //  edit pixmap, base image
EX PXM         *E3pxm16;                                                   //  edit pixmap, edited image
EX PXM         *ERpxm16;                                                   //  edit pixmap, undo/redo image
EX PXM         *E8pxm16;                                                   //  scratch image for some functions
EX PXM         *E9pxm16;                                                   //  scratch image for some functions
EX PXM         *Dpxm16;                                                    //  drawing window pixmap, 1x 16-bits
EX PXM         *Dpxm8;                                                     //  drawing window pixmap, Mscale 8-bits

EX int         Fww, Fhh;                                                   //  input image dimensions
EX int         E1ww, E1hh, E3ww, E3hh;                                     //  edit image dimensions
EX int         ERww, ERhh;                                                 //  undo/redo image dimensions
EX int         E9ww, E9hh;                                                 //  scratch image dimensions
EX int         Dww, Dhh;                                                   //  drawing window size

EX mutex       Fpixmap_lock;                                               //  lock for accessing PXM pixmaps

EX int         Frefresh;                                                   //  full image refresh needed
EX double      Fzoom;                                                      //  image zoom scale (0 = fit window)
EX int         zoomx, zoomy;                                               //  req. zoom center of window
EX double      Mscale;                                                     //  scale factor, image to window
EX int         Iww, Ihh;                                                   //  current image size at 1x
EX int         iww, ihh;                                                   //  image area in drawing window at Mscale
EX int         dww, dhh;                                                   //  drawing window image, iww * Mscale
EX int         Iorgx, Iorgy;                                               //  drawing window origin in image
EX int         Dorgx, Dorgy;                                               //  image origin in drawing window

EX int         Mbutton;                                                    //  mouse button, 1/3 = left/right
EX int         LMclick, RMclick;                                           //  mouse left, right click
EX int         Mxclick, Myclick;                                           //  mouse click position
EX int         Mxposn, Myposn;                                             //  mouse move position
EX int         Mxdown, Mydown, Mxdrag, Mydrag;                             //  mouse drag vector
EX int         Mdrag;                                                      //  mouse drag underway
EX int         Mcapture;                                                   //  mouse captured by edit function
EX int         Fmousemain;                                                 //  flag, mouse acts on main window

EX int         KBcapture;                                                  //  KB key captured by edit function
EX int         KBkey;                                                      //  active keyboard key

EX int         KBcontrolkey;                                               //  keyboard key states, 1 = down
EX int         KBshiftkey;
EX int         KB_A_key;

EX int         Ntoplines, Nptoplines;                                      //  lines on top of image in window
EX int         toplinex1[4], topliney1[4], toplinex2[4], topliney2[4];
EX int         ptoplinex1[4], ptopliney1[4], ptoplinex2[4], ptopliney2[4];

EX int         Ftoparc, ptoparc;                                           //  arc (circle/ellipse) on top
EX int         toparcx,toparcy,toparcw,toparch;                            //    of image in window
EX int         ptoparcx,ptoparcy,ptoparcw,ptoparch;

struct toptext_t {                                                         //  list of text straings that are
   int      ID, px, py;                                                    //    painted over image whenever
   cchar    *text;                                                         //      the main window is repainted
   cchar    *font;
};
#define maxtoptext 100                                                     //  max. text strings
EX toptext_t   toptext[100];                                               //  text strings written on main window
EX int         Ntoptext;                                                   //  current count

struct topcircle_t {                                                       //  list of red circles that are
   int      px, py;                                                        //    painted over image whenever
   int      radius;                                                        //      the main window is updated
   int      color;                                                         //  1/2/3 = white/black/red
};
#define maxtopcircles 100                                                  //  max. number of circles
EX topcircle_t    topcircles[100];                                         //  circles written on main window
EX int            Ntopcircles;                                             //  current count

//  select area data

#define sa_initseq 10                                                      //  initial sequence number (0/1/2 reserved)
#define sa_maxseq 9999                                                     //  could go to 16 bits = 64K
EX int         sa_geom1, sa_geom2;
EX uint16      sa_endpx[10000], sa_endpy[10000];                           //  last pixel drawn per seqence no.
EX int         sa_thresh;                                                  //  mouse pixel distance threshold
EX int         sa_mouseradius;                                             //  mouse selection radius
EX int         sa_searchrange;                                             //  search range (* mouse radius)
EX int         sa_mousex, sa_mousey;                                       //  mouse position in image
EX int         sa_matchcolor;                                              //  search using color match Y/N
EX double      sa_colormatch;                                              //  color range to match (0.001 to 1.0)
EX uint16      sa_matchRGB[1000][3];                                       //  match colors, up to 1000
EX int         sa_Nmatch;                                                  //  count of match colors
EX int         sa_firewall;                                                //  selected pixels block propagation Y/N
EX GdkColor    *sa_pixRGB;                                                 //  select area outline color
EX int         sa_radius, sa_radius2;                                      //  current mouse radius, radius **2
EX int         sa_radius3;                                                 //  search range **2
EX int         sa_calced;                                                  //  edge calculation done
EX int         sa_blend;                                                   //  edge blend width
EX int         sa_minx, sa_maxx;                                           //  enclosing rectangle for area
EX int         sa_miny, sa_maxy;
EX char        *sa_stackdirec;                                             //  pixel search stack
EX int         *sa_stackii;    
EX int         sa_maxstack;
EX int         sa_Nstack;
EX int         sa_stat;                                                    //  0/1/2/3 = none/edit/pause/complete
EX int         sa_mode;                                                    //  1-7 = curr. select area edit method
EX int         sa_finOK;                                                   //  finish area - success
EX int         sa_finhole;                                                 //  finish area - area has a hole
EX int         sa_currseq;                                                 //  current select sequence no.
EX int         sa_Ncurrseq;                                                //  current sequence pixel count
EX char        *sa_pixselc;                                                //  maps pixels (re)selected in current cycle
EX uint16      *sa_pixmap;                                                 //  0/1/2+ = outside/edge/inside (edge dist)
EX int         sa_Npixel;                                                  //  total select_area pixel count
EX int         sa_fww, sa_fhh;                                             //  valid image dimensions for select area
EX int         Fshowarea;                                                  //  show select area outline
EX int         Factivearea;                                                //  select area complete and enabled
EX int         areanumber;                                                 //  increasing sequential number

//  spline curve data

typedef void t_spcfunc(int spc);                                           //  callback function, spline curve edit

typedef struct {                                                           //  spline curve data 
   GtkWidget   *drawarea;                                                  //  drawing area for spline curves
   t_spcfunc   *spcfunc;                                                   //  callback function when curve changed
   int         Nspc;                                                       //  number of active curves, 1-10
   int         vert[10];                                                   //  curve is vert. (1) or horz. (0)
   int         nap[10];                                                    //  anchor points per curve
   double      apx[10][50], apy[10][50];                                   //  up to 50 anchor points per curve
   double      yval[10][1000];                                             //  y-values for x = 0 to 1 by 0.001
   int         Nscale;                                                     //  no. of fixed scale lines, 0-10
   double      xscale[2][10];                                              //  2 x-values for end points
   double      yscale[2][10];                                              //  2 y-values for end points    v.11.10
} spldat;

//  edit collections data

EX char        *edit_coll_file;                                            //  current edit collection file
EX char        *edit_coll_name;                                            //  collection name = file name
EX char        *edit_coll_memberfile;                                      //  collection member image file
EX zdialog     *zd_edit_coll;                                              //  edit collections dialog

//  image edit function data

typedef struct {                                                           //  edit function data
   cchar       *funcname;                                                  //  function name, e.g. flatten
   int         Fprev;                                                      //  flag, use preview window
   int         Farea;                                                      //  select area: 0/1/2 = delete/ignore/usable
   int         Fpara;                                                      //  flag, parallel edit OK
   int         Fmod;                                                       //  flag, image modified by this func
   zdialog     *zd;                                                        //  edit dialog
   spldat      *curves;                                                    //  edit curve data
   void *      (*threadfunc)(void *);                                      //  edit thread function
   void        (*mousefunc)();                                             //  edit mouse function
} editfunc;

EX editfunc    *CEF;                                                       //  current active edit function
EX pvlist      *editlog;                                                   //  log of image edits done   v.10.2
EX char        *undo_files;                                                //  undo/redo stack, image files
EX int         Pundo;                                                      //  undo/redo stack position
EX int         Pumax;                                                      //  undo/redo stack depth

#define maxplugins 100
EX int         Nplugins;                                                   //  plugin menu items
EX char        *plugins[100];

//  The following are saved and restored across sessions.
//  They belong to different functions in different source modules.

EX char        *pversion;                                                  //  prior fotoxx version
EX char        *last_session;                                              //  last fotoxx session exit time
EX int         Ffirsttime;                                                 //  first time startup
EX int         newfiles;                                                   //  new files found since last synch
EX int         mwgeom[4];                                                  //  main window position and size
EX cchar       *tbar_style;                                                //  toolbar style: icons/text/both
EX cchar       *startdisplay;                                              //  display: recent/prev/blank/file/dirk
EX char        *startdirk;                                                 //  start directory (startdisplay=dirk)
EX char        *startfile;                                                 //  start image file (startdisplay=file)
EX int         Fwarnoverwrite;                                             //  warn overwrite of original image
EX double      lens_mm, lens_bow;                                          //  pano lens mm and bow
EX double      lens_settings[2];                                           //    "  user settings if no EXIF data
EX cchar       *zoomratio;                                                 //  zoom ratio, "1.xxxxxx"
EX int         trimsize[2];                                                //  trim (crop) width, height
EX char        *trimbuttons[6];                                            //  trim dialog button labels
EX char        *trimratios[6];                                             //  corresponding aspect ratios
EX int         editresize[2];                                              //  edit resize width, height
EX int         batchresize[2];                                             //  batch resize width, height
EX int         emailsize[2];                                               //  email resize width, height
EX char        *annotate_text;                                             //  annotation text
EX char        *annotate_font;                                             //  font and size, e.g. "Sans 20"
EX char        *annotate_color[3];                                         //  text, background, text outline colors
EX int         annotate_trans[3];                                          //  corresp. transparencies
EX int         annotate_outline;                                           //  text outline width, pixels
EX double      annotate_angle;                                             //  angle of text
EX int         Fgrid;                                                      //  both grid lines on / off
EX int         gridon[2];                                                  //  x/y gridlines on / off 
EX int         gridspace[2];                                               //  x/y grid line spacing
EX int         gridcount[2];                                               //  x/y grid line counts (alternative)
EX int         gridoffset[2];                                              //  x/y grid line starting offsets
EX int         rotate_grid[8];                                             //  rotate function grid status
EX int         unbend_grid[8];                                             //  unbend function grid status
EX int         warpC_grid[8];                                              //  warp image (curved) grid status
EX int         warpL_grid[8];                                              //  warp image (linear) grid status
EX int         warpF_grid[8];                                              //  warp image (affine) grid status
#define        SSNF 12                                                     //  no. slide show transition types
EX int         ss_funcs[SSNF];                                             //  user preferred transitions
EX char        *ss_musicfile;                                              //  music file or playlist

//  dialogs with global visibility

EX zdialog     *zdedittags;                                                //  edit tags zdialog
EX zdialog     *zdexifview;                                                //  view EXIF/IPTC data
EX zdialog     *zdexifedit;                                                //  edit EXIF/IPTC data
EX zdialog     *zdeditcctext;                                              //  edit IPTC caption and EXIF user comments
EX zdialog     *zdrename;                                                  //  rename file zdialog
EX zdialog     *zdsela;                                                    //  select area dialog

//  GTK functions

int   main(int argc, char * argv[]);                                       //  main program
int   gtkinitfunc(void *data);                                             //  GTK initz. function
int   gtimefunc(void *arg);                                                //  periodic function
void  update_statusbar();                                                  //  update main window status bar
int   delete_event();                                                      //  window delete event function
void  destroy_event();                                                     //  window destroy event function
void  topmenufunc(GtkWidget *, cchar *menu);                               //  top level menu function
int   mwpaint1();                                                          //  window repaint (expose event)
void  mwpaint2();                                                          //  window repaint (thread callable)
void  mwpaint3(int px, int py, int ww, int hh);                            //  paint window area from image area
void  mouse_event(GtkWidget *, GdkEventButton *, void *);                  //  mouse event function
int   KBpress(GtkWidget *, GdkEventKey *, void *);                         //  KB key press event function
int   KBrelease(GtkWidget *, GdkEventKey *, void *);                       //  KB key release event
void  paint_toplines(int arg);                                             //  paint lines on image
void  paint_toparc(int arg);                                               //  paint arc on image
void  paint_gridlines();                                                   //  paint grid lines on image
void  draw_line(int x1, int y1, int x2, int y2);                           //  draw line, image space
void  erase_line(int x1, int y1, int x2, int y2);                          //  erase line
void  draw_pixel(int px, int py, GdkColor *color);                         //  draw one pixel using color
void  draw_fat_pixel(int px, int py, GdkColor *color);                     //  draw one fat pixel using color
void  add_toptext(int ID, int px, int py, cchar *text, cchar *font);       //  paint text on window (image space)
void  erase_toptext(int ID);                                               //  remove all text strings with ID
void  paint_toptext();                                                     //  paint text strings when window repainted
void  paint_text(int px, int py, cchar *text, cchar *font);                //  paint text on window (window space)
void  add_topcircle(int px, int py, int radius, int color);                //  paint circles on window (image space)
void  erase_topcircles();                                                  //  remove all red circles
void  paint_topcircles();                                                  //  paint red circles when window repainted

typedef  void CBfunc();                                                    //  callback function type
EX CBfunc   *mouseCBfunc;                                                  //  current mouse handler function

void takeMouse(zdialog *zd, CBfunc func, GdkCursor *);                     //  capture mouse for dialog     v.11.03
void freeMouse();                                                          //  free mouse for main window

//  spline curve edit functions

spldat * splcurve_init(GtkWidget *frame, void func(int spc));              //  initialize spline curves
int      splcurve_adjust(void *, GdkEventButton *event, spldat *);         //  curve editing function
int      splcurve_draw(void *, void *, spldat *);                          //  curve drawing function
int      splcurve_generate(spldat *, int spc);                             //  generate data from anchor points
double   splcurve_yval(spldat *, int spc, double xval);                    //  get curve y-value
int      splcurve_load(spldat *sd);                                        //  load curve from a file
int      splcurve_save(spldat *sd);                                        //  save curve to a file

//  file menu functions

void  m_gallery(GtkWidget *, cchar *);                                     //  show image gallery window
void  m_gallery2(int Nth, int button);                                     //  receives clicked files
void  m_clone1(GtkWidget *, cchar *);                                      //  start new fotoxx window (desktop 50/50)
void  m_clone2(GtkWidget *, cchar *);                                      //  start new fotoxx window (overlay prior)
void  m_open(GtkWidget *, cchar *);                                        //  open image file in same window
void  m_open_drag(int x, int y, char *file);                               //  open drag-drop file
void  m_open_newin(GtkWidget *, cchar *);                                  //  open image file in new window
void  m_previous(GtkWidget *, cchar *);                                    //  open previously accessed file
void  m_recent(GtkWidget *, cchar *);                                      //  open recently accessed file
void  add_recent_file(cchar *file);                                        //  add file to recent file list
int   f_open(cchar *file, int flock, int Nth = 0, int fswitch = 0);        //  set new current file
void  m_prev(GtkWidget *, cchar *);                                        //  open previous file in gallery
void  m_next(GtkWidget *, cchar *);                                        //  open next file in gallery
void  m_save(GtkWidget *, cchar *);                                        //  save modified image to same file
void  m_savevers(GtkWidget *, cchar *);                                    //  save modified image to new file version
void  m_saveas(GtkWidget *, cchar *);                                      //  save modified image to another file
void  m_zoom(GtkWidget *, cchar *);                                        //  zoom image +/-
void  m_create(GtkWidget *, cchar *);                                      //  create new blank image file
void  m_trash(GtkWidget *, cchar *);                                       //  move image to trash
void  m_rename(GtkWidget *, cchar *);                                      //  rename file
void  m_batchrename(GtkWidget *, cchar *);                                 //  rename many files, base + sequence
void  m_print(GtkWidget *, cchar *);                                       //  print image file
void  m_quit(GtkWidget *, cchar *);                                        //  exit application

//  tools menu functions

void  m_manage_collections(GtkWidget *, cchar *);                          //  create and edit image collections
void  m_move_collections(GtkWidget *, cchar *);                            //  change top image directory
void  edit_coll_popmenu(GtkWidget *, char *file);                          //  popup menu for editing collections
void  m_batchconvert(GtkWidget *, cchar *);                                //  convert/resize/export multiple image files
void  m_conv_raw(GtkWidget *, cchar *);                                    //  convert RAW files to tiff
void  m_slideshow(GtkWidget *, cchar *);                                   //  enter or leave slideshow mode
void  slideshow_next(cchar *);                                             //  show prev/next image
void  m_syncfiles(GtkWidget *, cchar *);                                   //  rebuild thumbnails and search index
int   syncfiles_func(void *);                                              //  sync files function (in subprocess)
void  m_show_RGB(GtkWidget *, cchar *);                                    //  show RGB values at mouse click
void  m_gridlines(GtkWidget *, cchar *);                                   //  set up grid lines
void  load_grid(int *griddata);                                            //  load grid from saved state
void  save_grid(int *griddata);                                            //  save grid to saved state
void  toggle_grid(int action);                                             //  set grid off/on or toggle (0/1/2)
void  m_burn(GtkWidget *, cchar *);                                        //  burn selected images to CD/DVD
void  m_email(GtkWidget *, cchar *);                                       //  e-mail selected images
void  m_moncheck(GtkWidget *, cchar *);                                    //  check monitor brightness and color
void  m_mongamma(GtkWidget *, cchar *);                                    //  adjust monitor gamma
void  m_histogram(GtkWidget *, cchar *);                                   //  start brightness histogram
void  histogram_paint();                                                   //  update brightness histogram
void  histogram_destroy();                                                 //  remove histogram window
void  m_lang(GtkWidget *, cchar *);                                        //  change language
void  m_translate(GtkWidget *, cchar *);                                   //  edit translation
void  m_menu_launcher(GtkWidget *, cchar *);                               //  make desktop menu entry and launcher
void  m_settings(GtkWidget *, cchar *);                                    //  user settings
void  m_memory_usage(GtkWidget *, cchar *);                                //  report memory consumption by category

//  info menu functions (EXIF, IPTC, etc.)

void  m_edit_cctext(GtkWidget *, cchar *);                                 //  edit caption and user comments dialog
void  m_edit_tags(GtkWidget *, cchar *);                                   //  edit tags dialog
void  m_manage_tags(GtkWidget *, cchar *);                                 //  manage tags dialog
void  load_fileinfo(cchar *file);                                          //  EXIF/IPTC >> tags_date, _stars, _filetags
void  save_fileinfo(cchar *file);                                          //  tags_date, _stars, _filetags >> EXIF/IPTC
void  update_search_index(cchar *file);                                    //  update search index file
void  delete_search_index(cchar *file);                                    //  delete entry from search index file
void  m_batchAddTags(GtkWidget *, cchar *);                                //  add tags to many files at once
void  m_batchDelTag(GtkWidget *, cchar *);                                 //  delete/replace a tag for many files
void  m_info_view_short(GtkWidget *, cchar *);                             //  view selected EXIF/IPTC data
void  m_info_view_long(GtkWidget *, cchar *);                              //  view all EXIF/IPTC data
void  info_view(int length);                                               //  view EXIF/IPTC data in popup window
void  m_info_edit(GtkWidget *, cchar *);                                   //  add or change EXIF/IPTC data
void  m_info_delete(GtkWidget *, cchar *);                                 //  delete EXIF/IPTC data
char ** info_get(cchar *file, cchar **keys, int nkeys);                    //  get EXIF/IPTC data for given key(s)
char ** info_getN(cchar **files, int NF, cchar **keys, int NK);            //   " " data for given keys and files
int   info_put(cchar *file, cchar **keys, cchar **text, int nkeys);        //  put EXIF/IPTC data for given key(s)
int   info_copy(cchar *f1, cchar *f2, cchar **k, cchar **t, int nk);       //  copy EXIF/IPTC data from file to file
void  m_search_images(GtkWidget *, cchar *);                               //  search tags, comments, captions, files
void  m_search_metadata(GtkWidget *, cchar *);                             //  search and report image metadata

//  select area menu functions

void  m_select(GtkWidget *, cchar *);                                      //  select area within image
void  m_select_show(GtkWidget *, cchar *);                                 //  enable area for subsequent edits
void  m_select_hide(GtkWidget *, cchar *);                                 //  show area outline
void  m_select_enable(GtkWidget *, cchar *);                               //  hide area outline
void  m_select_disable(GtkWidget *, cchar *);                              //  disable area
void  m_select_invert(GtkWidget *, cchar *);                               //  invert area 
void  m_select_unselect(GtkWidget *, cchar *);                             //  unselect area 
void  m_select_copy(GtkWidget *, cchar *);                                 //  copy area, save in memory
void  m_select_paste(GtkWidget *, cchar *);                                //  paste saved area into image
void  m_select_open(GtkWidget *, cchar *);                                 //  open an area file, save in memory
void  m_select_save(GtkWidget *, cchar *);                                 //  save area to a file
void  m_select_whole_image(GtkWidget *, cchar *);                          //  select whole image area
void  m_select_edit(GtkWidget *, cchar *);                                 //  select and edit in parallel

//  functions for area selection using the mouse

void  sa_geom_mousefunc();                                                 //  select rectangle or ellipse
void  sa_draw_mousefunc();                                                 //  line drawing functions
int   sa_nearpix(int mx, int my, int rad, int &npx, int &npy);             //  find nearest line-end
void  sa_draw_line(int px1, int py1, int px2, int py2);                    //  draw a connected line
void  sa_draw1pix(int px, int py);                                         //  draw one pixel if not already
void  sa_mouse_mousefunc();                                                //  select by radius and color match
void  sa_nextseq();                                                        //  start next sequence number
void  sa_unselect_pixels();                                                //  remove current selection

//  other select area functions

void  sa_finish();                                                         //  finish - map interior pixels
void  sa_finish_auto();                                                    //  finish - interior pixels already known
void  sa_map_pixels();                                                     //  map edge and interior pixels
void  sa_unfinish();                                                       //  set finished area back to edit mode
void  sa_show(int flag);                                                   //  show or hide area
void  sa_enable();                                                         //  enable area
void  sa_disable();                                                        //  disable area
void  sa_invert();                                                         //  invert area
void  sa_unselect();                                                       //  unselect area
void  sa_edgecalc();                                                       //  calculate edge distances
   
//  image edit functions - transform menu

void  m_rotate(GtkWidget *, cchar *);                                      //  rotate image
void  m_trim(GtkWidget *, cchar *);                                        //  trim image
void  m_autotrim(GtkWidget *, cchar *);                                    //  autotrim image after rotate, warp
void  m_resize(GtkWidget *, cchar *);                                      //  resize image
void  m_annotate(GtkWidget *, cchar *);                                    //  annotate image
void  m_flip(GtkWidget *, cchar *);                                        //  flip horizontally or vertically
void  m_negate(GtkWidget *, cchar *);                                      //  B+W and color negatives
void  m_unbend(GtkWidget *, cchar *);                                      //  fix perspective problems
void  m_keystone(GtkWidget *, cchar *);                                    //  convert tetragon image to rectangle
void  m_warp_area(GtkWidget *, cchar *);                                   //  warp image within an area
void  m_warp_curved(GtkWidget *, cchar *);                                 //  warp image, curved transform
void  m_warp_linear(GtkWidget *, cchar *);                                 //  warp image, linear transform
void  m_warp_affine(GtkWidget *, cchar *);                                 //  warp image, affine transform

//  image edit functions - retouch menu

void  m_tune(GtkWidget *, cchar *);                                        //  brightness / color adjustments
void  m_gamma(GtkWidget *, cchar *);                                       //  gamma adjustments
void  m_xbrange(GtkWidget *, cchar *);                                     //  clip brightness, expand rest
void  m_flatten(GtkWidget *, cchar *);                                     //  flatten brightness distribution
void  m_brightramp(GtkWidget *, cchar *);                                  //  ramp brightness across image
void  m_tonemap(GtkWidget *, cchar *);                                     //  tone mapping
void  m_whitebal(GtkWidget *, cchar *);                                    //  adjust white balance
void  m_match_color(GtkWidget *, cchar *);                                 //  set image2 colors to match image1
void  m_DRGB(GtkWidget *, cchar *);                                        //  brightness / color adjust with OD units
void  m_revise_RGB(GtkWidget *, cchar *);                                  //  revise RGB values
void  m_redeye(GtkWidget *, cchar *);                                      //  red-eye removal
void  m_blur(GtkWidget *, cchar *);                                        //  blur image
void  m_sharpen(GtkWidget *, cchar *);                                     //  sharpen image
void  m_denoise(GtkWidget *, cchar *);                                     //  image noise reduction
void  m_smart_erase(GtkWidget *, const char *);                            //  smart erase object
void  m_dust(GtkWidget *, const char *);                                   //  remove dust
void  m_stuckpix(GtkWidget *, const char *);                               //  fix stuck pixels 
void  m_pixedit(GtkWidget *, cchar *);                                     //  edit pixels

//  image edit functions - art menu

void  m_colordep(GtkWidget *, cchar *);                                    //  set color depth 1-16 bits/color
void  m_draw(GtkWidget *, cchar *);                                        //  make simulated drawing
void  m_outlines(GtkWidget *, cchar *);                                    //  make an outline image
void  m_emboss(GtkWidget *, cchar *);                                      //  make simulated embossing
void  m_tiles(GtkWidget *, cchar *);                                       //  make simulated tiles (pixelate)
void  m_dots(GtkWidget *, cchar *);                                        //  convert image to dot matrix form
void  m_painting(GtkWidget *, cchar *);                                    //  make simulated painting

//  image edit functions - combine menu

void  m_HDR(GtkWidget *, cchar *);                                         //  make HDR composite image
void  m_HDF(GtkWidget *, cchar *);                                         //  make HDF composite image
void  m_STP(GtkWidget *, cchar *);                                         //  stack / paint image
void  m_STN(GtkWidget *, cchar *);                                         //  stack / noise reduction
void  m_pano(GtkWidget *, cchar *);                                        //  make panorama composite image
void  m_vpano(GtkWidget *, cchar *);                                       //  make vertical panorama

//  plugin functions                                                       //  v.11.03

void  m_run_plugin(GtkWidget *, cchar *);                                  //  perform a plugin edit function
void  m_edit_plugins(GtkWidget *, cchar *);                                //  add and remove plugin functions

//  edit support functions

int   edit_setup(editfunc &EF);                                            //  start new edit transaction
void  edit_suspend();                                                      //  suspend edit function (parallel)
void  edit_cancel(editfunc &EF);                                           //  cancel edit
void  edit_done(editfunc &EF);                                             //  commit edit, add undo stack
void  edit_takeover(editfunc &EF);                                         //  set current (parallel) edit func
void  edit_undo();                                                         //  undo edit, back to org. image
void  edit_redo();                                                         //  redo the edit after undo
void  edit_reset();                                                        //  reset to initial status
void  edit_zapredo();                                                      //  clear image redo copy
void  edit_fullsize();                                                     //  convert to full-size pixmaps
void  m_undo(GtkWidget *, cchar *);                                        //  toolbar, undo one edit
void  m_redo(GtkWidget *, cchar *);                                        //  toolbar, redo one edit
void  undo_all();                                                          //  undo all edits of current image
void  save_undo(cchar *funcname);                                          //  undo/redo save function
void  load_undo();                                                         //  undo/redo read function
int   mod_keep();                                                          //  query keep/discard edited image
int   menulock(int lock);                                                  //  lock/unlock menu for some funcs
int   is_syncbusy();                                                       //  check Fsyncbusy, message user to wait

//  thread support functions

typedef void * threadfunc(void *);                                         //  edit thread function
void  start_thread(threadfunc func, void *arg);                            //  start edit thread
void  signal_thread();                                                     //  signal thread, work is pending
void  wait_thread_idle();                                                  //  wait for work complete
void  wrapup_thread(int command);                                          //  wait for exit or command exit
void  thread_idle_loop();                                                  //  thread: wait for work or exit command
void  thread_exit();                                                       //  thread: exit unconditionally
void  start_wthread(threadfunc func, void *arg);                           //  start working thread (per processor core)
void  exit_wthread();                                                      //  exit working thread
void  wait_wthreads();                                                     //  wait for working threads

//  other support functions

void  m_help(GtkWidget *, cchar *);                                        //  various help functions
void  load_params();                                                       //  load parameters from prior session
void  save_params();                                                       //  save parameters for next session
void  brhood_calc(int radius, char method);                                //  compute neighborhood brightness
float get_brhood(int px, int py);                                          //  get pixel neighborhood brightness
void  free_resources(int fkeepundo = 0);                                   //  free all allocated resources
int   vpixel(PXM *pxm, double px, double py, uint16 *vpix);                //  get virtual pixel at (px,py)
int   sigdiff(double d1, double d2, double signf);                         //  test for significant difference

//  file load and save functions

PXM * f_load(cchar *filespec, int bpc);                                    //  load a file into an PXM pixmap
int   f_save(char *outfile, cchar *type, int bpc);                         //  save current image pixmap to a file
PXM * TIFFread(cchar *filespec);                                           //  read TIFF file, native bpc
int   TIFFwrite(PXM *pxm, cchar *filespec);                                //  write TIFF file, bpc from pxm
PXM * PXBread(cchar *filespec);                                            //  read using pixbuf library, bpc = 8
int   PXBwrite(PXM *pxm, cchar *filespec);                                 //  write using pixbuf library, bpc = 8

//  PXM pixmap conversion functions

PXM * PXM_make(int ww, int hh, int bpc);                                   //  initialize PXM pixmap
void  PXM_free(PXM *&pxm);                                                 //  free PXM pixmap
PXM * PXM_copy(PXM *pxm);                                                  //  copy PXM pixmap
PXM * PXM_copy_area(PXM *pxm, int orgx, int orgy, int ww, int hh);         //  copy section of PXM pixmap
PXM * PXM_convbpc(PXM *pxm);                                               //  convert from 8/16 to 16/8 bpc
void  PXM_fixblue(PXM *pxm);                                               //  set blue = 0 pixels to blue = 2
PXM * PXM_rescale(PXM *pxm, int ww, int hh);                               //  rescale PXM pixmap (ww/hh)
void  PXM_update(PXM *p16, PXM *p8, int orgx, int orgy, int ww, int hh);   //  copy section of PXM-16 into PXM-8
PXM * PXM_rotate(PXM *pxm, double angle);                                  //  rotate PXM pixmap

//   image navigation and thumbnail gallery functions
//   for functions returning char *, caller responsible for zfree()

char * image_gallery(cchar *filez, cchar *action, int Nth = 0,             //  display image gallery window, navigate, 
       void ufunc(int Nth, int butt) = 0, GtkWidget *parent = 0);          //    do callback for clicked thumbnails
int image_gallery_position(cchar *file, int Nth);                          //  get relative position of file in gallery
int image_file_type(cchar *file);                                          //  determine if directory or image file type
char * image_thumbfile(char *imagefile);                                   //  get thumbnail filespec, create if missing
GdkPixbuf * image_thumbnail(char *imagefile, int size = 0);                //  get thumbnail pixbuf, create if missing
char ** image_gallery_getfiles(char *startdir, GtkWidget *parent = 0);     //  select files from gallery window

//  translatable strings used in multiple dialogs

#define Babsolute ZTX("absolute")
#define Badd ZTX("Add")
#define Baddall ZTX("Add All")
#define Ball ZTX("All")
#define Bamount ZTX("Amount")
#define Bapply ZTX("Apply")
#define Bblack ZTX("Black")
#define Bblendwidth ZTX("Blend Width")
#define Bblue ZTX("Blue")
#define Bbrightness ZTX("Brightness")
#define Bbrowse ZTX("Browse")
#define Bcancel ZTX("Cancel")
#define Bclear ZTX("Clear")
#define Bcolor ZTX("Color")
#define Bcommit ZTX("Commit")
#define Bcopy ZTX("Copy")
#define Bcurvefile ZTX("Curve File:")
#define Bcut ZTX("Cut")
#define Bdarker ZTX("Darker Areas")
#define Bdelete ZTX("Delete")
#define Bdisable ZTX("Disable")
#define Bdiscard ZTX("Discard special gallery list? \n %s")
#define Bdone ZTX("Done")
#define Bedit ZTX("Edit")
#define Benable ZTX("Enable")
#define Berase ZTX("Erase")
#define Bexiftoolmissing ZTX("package libimage-exiftool-perl is required")
#define Bfetch ZTX("Fetch")
#define Bfinish ZTX("Finish")
#define Bfont ZTX("Font")
#define Bgreen ZTX("Green")
#define Bheight ZTX("Height")
#define Bhistogram ZTX("histogram")
#define Bhide ZTX("Hide")
#define Binsert ZTX("Insert")
#define Binvert ZTX("Invert")
#define Blighter ZTX("Lighter Areas")
#define Blimit ZTX("limit")
#define Bnew ZTX("New")
#define Bnext ZTX("Next")
#define BOK ZTX("OK")
#define Bopen ZTX("Open")
#define Bopenrawfile ZTX("Open RAW File")
#define Bpaste ZTX("Paste")
#define Bpause ZTX("Pause")
#define Bpercent ZTX("Percent")
#define Bpresets ZTX("Presets")
#define Bproceed ZTX("Proceed")
#define Bradius ZTX("Radius")
#define Brange ZTX("range")
#define Bred ZTX("Red")
#define Bredo ZTX("Redo")
#define Breduce ZTX("Reduce")
#define Bremove ZTX("Remove")
#define Breset ZTX("Reset")
#define Bsave ZTX("Save")
#define Bsavetoedit ZTX("Unknown file type, save as tiff/jpeg/png to edit")
#define Bsearch ZTX("Search")
#define Bselect ZTX("Select")
#define Bselectfiles ZTX("Select Files")
#define Bshow ZTX("Show")
#define Bstart ZTX("Start")
#define Bthresh ZTX("Threshold")
#define Btoomanyfiles ZTX("exceed %d files")
#define Bundoall ZTX("Undo All")
#define Bundolast ZTX("Undo Last")
#define Bundo ZTX("Undo")
#define Bunfinish ZTX("Unfinish")
#define Bunselect ZTX("Unselect")
#define Bview ZTX("View")
#define Bwhite ZTX("White")
#define Bwidth ZTX("Width")


