atomes 1.3.2
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1/* This file is part of the 'atomes' software
2
3'atomes' is free software: you can redistribute it and/or modify it under the terms
4of the GNU Affero General Public License as published by the Free Software Foundation,
5either version 3 of the License, or (at your option) any later version.
6
7'atomes' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9See the GNU General Public License for more details.
10
11You should have received a copy of the GNU Affero General Public License along with 'atomes'.
12If not, see <https://www.gnu.org/licenses/>
13
14Copyright (C) 2022-2026 by CNRS and University of Strasbourg */
15
22
23/*
24* This file: 'main.c'
25*
26* Contains:
27*
28
29 - The initialization of the atomes program
30 - The functions required to read data from the command line
31
32*
33* List of functions:
34
35 int test_this_ext (int len, gchar * arg);
36 int test_this_arg (gchar * arg);
37 int get_style_from_string (gchar * style_string);
38 int get_rep_from_string (gchar * rep_string);
39 int get_box_axis_from_string (gchar * box_axis_string);
40 int get_color_map_from_string (gchar * col_string);
41 int get_gradient_from_string (gchar * grad_string);
42 int check_for_atomes_file_options (int start, int end, char *argv[]);
43 int parse_command_line (int argc, char *argv[])
44 int main (int argc, char *argv[]);
45
46 ColRGBA * get_color_from_hexa_string (gchar * color_string);
47
48 gboolean destroy_func (gpointer user_data);
49
50 static gboolean handle_open_file (Instance * object, GDBusMethodInvocation * invocation, const gchar * arg_file, gpointer user_data);
51 static gboolean init_dbus_server ();
52 static gboolean check_existing_instance (void);
53
54 static gboolean win32_open_file_idle (gpointer user_data);
55 static gpointer win32_pipe_server_thread (gpointer user_data);
56 static gboolean init_win32_server ();
57 static gboolean check_existing_win32_instance ();
58
59 G_MODULE_EXPORT gboolean splashdraw (GtkWidget * widget, cairo_t * cr, gpointer data);
60
61 void printhelp();
62 void printversion ();
63 void set_atomes_locale ();
64 void read_this_file (int file_type, gchar * this_file);
65 void open_this_data_file (int file_type, gchar * file_name);
66
67 G_MODULE_EXPORT void run_program (GApplication * app, gpointer data);
68
69 GtkWidget * create_splash_window ();
70
71*
72* Notes:
73*
74
75 LLM tools (Le Chat) were used at few occasions to prepare some sections of this file, including:
76 - To write of the function to convert hexadecimal chain to color
77 - To write parts of the d-bus, and Mutex instances management functions
78
79*/
80
81#include <getopt.h>
82#include <ctype.h>
83#include "version.h"
84#include "global.h"
85#include "bind.h"
86#include "callbacks.h"
87#include "preferences.h"
88#include "interface.h"
89#include "project.h"
90#include "workspace.h"
91#include "glview.h"
92#include "movie.h"
93
94#ifdef G_OS_WIN32
95#define APP_EXTENSION ".exe"
96#include <shlobj.h>
97#else
98#include <pwd.h>
99#define APP_EXTENSION
101#endif
102
103extern GtkWidget * create_main_window (GApplication * app);
104
105const gchar * dfi[2];
106struct file_list {
107 gchar * file_name;
109 struct file_list * next;
110};
111
112struct file_list * flist = NULL;
113struct file_list * ftmp = NULL;
114gboolean with_workspace = FALSE;
115
116gchar * bs_styles[] = {"ball&stick", "balls&sticks", "balls&stick", "ball&sticks",
117 "ball_&_stick", "balls_&_sticks", "balls_&_stick", "ball_&_sticks",
118 "ball_and_sticks", "balls_and_sticks", "balls_and_stick", "ball_and_stick",
119 "ballsandsticks", "ballsandstick", "ballanddsticks", "ballandstick",
120 "b&s", "b_and_s", "bs", "b", NULL};
121gchar * wi_styles[] = {"wireframe", "wireframes", "wires", "wire", "wi", "w", NULL};
122gchar * co_styles[] = {"covalent_radius", "covalent", "cov_rad", "cov", "co", "cr", NULL};
123gchar * io_styles[] = {"ionic_radius", "ionic_rad", "ionic", "ion", "ir", NULL};
124gchar * vw_styles[] = {"vdw_radius", "van_der_waals_radius", "van_der_waals", "vdw_radius", "vdw_rad", "vdw", "vr", NULL};
125gchar * cr_styles[] = {"crystal", "crystal_radius", "in_crystal", "in_crystal_radius", "cryst", "crystal_rad", "cr", NULL};
126gchar * sp_styles[] = {"sphere", "spheres", "sph", "sp", "S", NULL};
127gchar * cy_styles[] = {"cylinder", "cylinders", "cyl", "cy", "c", NULL};
128gchar * do_styles[] = {"dot", "dots", "d", NULL};
129gchar * xyz_files[] = {"xyz", NULL};
130gchar * c3d_files[] = {"c3d", "chemd3d", NULL};
131gchar * sml_files[] = {"sml", NULL};
132
139{
140 printf (_("\nUsage: atomes [OPTION]\n"
141 " atomes [FILE]\n"
142 " atomes [OPTION] [FILE]\n"
143 " atomes [FILE1] [FILE2] ...\n"
144 " atomes [OPTION1] [FILE1] [OPTION2] [FILE2] ...\n\n"
145 "3D atomic-scale models analysis, creation/edition and post-processing tool\n\n"
146 "options:\n"
147 " -v, --version version information\n"
148 " -h, --help display this help message\n\n"
149 "files, any number, in any order, in the following formats:\n\n"
150 " atomes workspace file : .awf\n"
151 " atomes project file : .apf\n"
152 " XYZ coordinates file : .xyz\n"
153 " Chem3D coordinates file : .c3d\n"
154 " CPMD trajectory : .trj\n"
155 " VASP trajectory : .xdatcar\n"
156 " PDB coordinates : .pdb, .ent\n"
157 " Crystallographic Information File : .cif\n"
158 " DL-POLY history file : .hist\n"
159 " atomes chemical library file (XML) : .sml\n"
160 " ISAACS project file : .ipf\n\n"
161 " alternatively specify the file format using:\n\n"
162 " -awf [FILE]\n"
163 " -apf [FILE]\n"
164 " -xyz [FILE]\n"
165 " -c3d [FILE]\n"
166 " -trj [FILE]\n"
167 " -xdatcar [FILE]\n"
168 " -pdb [FILE], or, -ent [FILE]\n"
169 " -cif [FILE]\n"
170 " -hist [FILE]\n"
171 " -sml [FILE]\n"
172 " -ipf [FILE]\n\n"
173 "ex:\n\n"
174 " atomes -pdb this.f file.awf -cif that.f *.xyz\n\n"
175 "Image rendering from the command line:\n\n"
176 "Usage: atomes [IMAGE_OPTIONS]\n"
177 " -p, --png, --render-png render image in PNG format\n"
178 " -j, --jpg, --render-jpg render image in JPEG format\n"
179 " -o, --output=[FILE] image file name\n"
180 " -W, --width=[XSIZE] image width\n"
181 " -H, --height=[YSIZE] image height\n"
182 " -s, --style=[STYLE] rendering style\n"
183 " -r, --rep=[REP] representation type\n"
184 " -b, --box=[STYLE] box style\n"
185 " -a, --axis=[STYLE] axis style\n"
186 " -e, --acolor=[MAP] atoms and bonds color map\n"
187 " -t, --pcolor=[MAP] ployhedra color map\n"
188 " -C, --box_color=[COLOR] box color\n"
189 " -G, --back_grad=[GRAD] background gradient type\n"
190 " -B, --back_color=[COLOR] background color\n"
191 " -D, --back_dir=[DIR] background gradient direction\n"
192 " -P, --back_pos=[POS] colors mixed position\n"
193 " -U, --grad_col_a=[COL] gradient initial color\n"
194 " -V, --grad_col_b=[COL] gradient final color\n\n"
195 "ex:\n\n"
196 " atomes --render-png --width=1920 -H 1024 --output=project.png project.apf -s ball_and_stick\n"
197 " atomes --jpg --style=vdw -r ortho -e pc -t pc file.xyz\n\n"
198 "Atomic coordinates conversion from the command line:\n\n"
199 "Usage: atomes [CONVERSION_OPTIONS]\n"
200 " -c, --convert=[FORMAT] conversion format\n\n"
201 "ex:\n\n"
202 " atomes --convert=xyz project.apf\n"
203 " atomes -c sml file.pdb\n\n"));
204 printf ("%s", _("\nReport a bug to <"));
205 printf ("%s>\n\n", PACKAGE_BUGREPORT);
206}
207
214{
215 printf ("%s", _("\n3D atomic scale model analysis, creation/edition and post-processing tool\n"));
216 printf ("\n%s version : %s\n", PACKAGE, VERSION);
217 printf ("\nGTK+ version : %1d.%1d.%1d\n",
218 GTK_MAJOR_VERSION,
219 GTK_MINOR_VERSION,
220 GTK_MICRO_VERSION);
221 printf ("Libavutil version : %2d.%2d.%3d\n",
222 LIBAVUTIL_VERSION_MAJOR,
223 LIBAVUTIL_VERSION_MINOR,
224 LIBAVUTIL_VERSION_MICRO);
225 printf ("Libavformat version : %2d.%2d.%3d\n",
226 LIBAVFORMAT_VERSION_MAJOR,
227 LIBAVFORMAT_VERSION_MINOR,
228 LIBAVFORMAT_VERSION_MICRO);
229 printf ("Libavcodec version : %2d.%2d.%3d\n",
230 LIBAVCODEC_VERSION_MAJOR,
231 LIBAVCODEC_VERSION_MINOR,
232 LIBAVCODEC_VERSION_MICRO);
233 printf ("Libswscale version : %2d.%2d.%3d\n",
234 LIBSWSCALE_VERSION_MAJOR,
235 LIBSWSCALE_VERSION_MINOR,
236 LIBSWSCALE_VERSION_MICRO);
237#ifdef OPENMP
238 float v = 0.0;
239 char * v_string;
240 switch (_OPENMP)
241 {
242 case 200505:
243 v = 2.5;
244 v_string = "2005-05";
245 break;
246 case 200805:
247 v = 3.0;
248 v_string = "2008-05";
249 break;
250 case 201107:
251 v = 3.1;
252 v_string = "2011-07";
253 break;
254 case 201307:
255 v = 4.0;
256 v_string = "2013-07";
257 break;
258 case 201511:
259 v = 4.5;
260 v_string = "2015-11";
261 break;
262 case 201811:
263 v = 5.0;
264 v_string = "2018-11";
265 break;
266 case 202011:
267 v = 5.1;
268 v_string = "2020-11";
269 break;
270 case 202111:
271 v = 5.2;
272 v_string = "2021-11";
273 break;
274 default:
275 v_string = "unknown";
276 break;
277 }
278 printf ("OpenMP version : %1.1f (%s)\n", v, v_string);
279#endif
280 printf ("FC Compiler : %s\n", FC);
281 printf ("FC Compiler flags : %s\n", FCFLAGS);
282 printf ("C Compiler : %s\n", CC);
283 printf ("C Compiler flags : %s\n", CFLAGS);
284
285 printf ("%s", _("\nReport a bug to <"));
286 printf ("%s>\n\n", PACKAGE_BUGREPORT);
287}
288
297int test_this_ext (int len, gchar * arg)
298{
299 int i;
300 gchar * aext = g_strdup_printf ("%c%c%c%c", arg[len-4], arg[len-3], arg[len-2], arg[len-1]);
301 char * eext[17]={".awf", ".apf", ".xyz", "NULL", ".c3d", ".trj", "NULL", ".car", "NULL", ".pdb", ".ent", ".cif", "NULL", "NULL", ".hist", ".sml", ".ipf"};
302 for (i=0; i<17; i++) if (g_strcmp0 (aext, eext[i]) == 0)
303 {
304 g_free (aext);
305 return -(i+1);
306 }
307 g_free (aext);
308 return 0;
309}
310
318int test_this_arg (gchar * arg)
319{
320 char * fext[17]={"-awf", "-apf", " -xyz", "NULL", "-c3d", "-trj", "NULL", "-xdatcar", "NULL", "-pdb", "-ent", "-cif", "NULL", "NULL", "-hist", "-sml", "-ipf"};
321 int i, j;
322 i = strlen(arg);
323 gchar * str = g_ascii_strdown (arg, i);
324 for (j=0; j<17; j++)
325 {
326 if (g_strcmp0 (str, fext[j]) == 0)
327 {
328 g_free (str);
329 return j+1;
330 }
331 }
332 j = test_this_ext (i, str);
333 g_free (str);
334 return (j) ? j : 0;
335}
336
345gboolean is_string_in_string_list (gchar * string, gchar ** list)
346{
347 if (string != NULL)
348 {
349 while (* list != NULL)
350 {
351 if (g_strcmp0(* list, string) == 0)
352 {
353 return TRUE;
354 }
355 list ++;
356 }
357 }
358 return FALSE;
359}
360
368int get_style_from_string (gchar * style_string)
369{
370 if (is_string_in_string_list(style_string, bs_styles)) return BALL_AND_STICK;
371 if (is_string_in_string_list(style_string, wi_styles)) return WIREFRAME;
372 if (is_string_in_string_list(style_string, co_styles)) return OGL_STYLES;
373 if (is_string_in_string_list(style_string, io_styles)) return OGL_STYLES+1;
374 if (is_string_in_string_list(style_string, vw_styles)) return OGL_STYLES+2;
375 if (is_string_in_string_list(style_string, cr_styles)) return OGL_STYLES+3;
376 if (is_string_in_string_list(style_string, sp_styles)) return SPHERES;
377 if (is_string_in_string_list(style_string, cy_styles)) return CYLINDERS;
378 if (is_string_in_string_list(style_string, do_styles)) return PUNT;
379 return NONE;
380}
381
389int get_rep_from_string (gchar * rep_string)
390{
391 gchar * ortho_keys[] = {"orthographic", "ortho", "o", "0", NULL};
392 gchar * persp_keys[] = {"perspective", "persp", "p", "1", NULL};
393 if (is_string_in_string_list(rep_string, ortho_keys)) return ORTHOGRAPHIC;
394 if (is_string_in_string_list(rep_string, persp_keys)) return PERSPECTIVE;
395 return NONE;
396}
397
405int get_box_axis_from_string (gchar * box_axis_string)
406{
407 if (is_string_in_string_list(box_axis_string, wi_styles)) return WIREFRAME;
408 if (is_string_in_string_list(box_axis_string, cy_styles)) return CYLINDERS;
409 return NONE;
410}
411
419int get_file_format_from_string (gchar * file_format_string)
420{
421 if (is_string_in_string_list(file_format_string, xyz_files)) return 0;
422 if (is_string_in_string_list(file_format_string, c3d_files)) return 1;
423 if (is_string_in_string_list(file_format_string, sml_files)) return 2;
424 return NONE;
425}
426
434int get_color_map_from_string (gchar * col_string)
435{
436 gchar * sp_keys[] = {"species", "spec", "sp", "0", NULL};
437 gchar * pt_keys[] = {"total_coordinations", "total_coordination", "total_coord", "total", "tc", "t", "1", NULL};
438 gchar * pc_keys[] = {"partial_coordinations", "partial_coordination", "partial_coord", "partial", "pc", "p", "2", NULL};
439 gchar * fg_keys[] = {"fragments", "fragment", "frag", "fg", "f", "3", NULL};
440 gchar * mo_keys[] = {"molecules", "molecule", "mol", "mo", "m", "4", NULL};
441 if (is_string_in_string_list(col_string, sp_keys)) return 0;
442 if (is_string_in_string_list(col_string, pt_keys)) return 1;
443 if (is_string_in_string_list(col_string, pc_keys)) return 2;
444 if (is_string_in_string_list(col_string, fg_keys)) return 3;
445 if (is_string_in_string_list(col_string, mo_keys)) return 4;
446 return NONE;
447}
448
456ColRGBA * get_color_from_hexa_string (gchar * color_string)
457{
458 ColRGBA * col = NULL;
459 const char * color = color_string;
460 // Ignorer le '#' si présent au début
461 if (color[0] == '#') color ++;
462
463 size_t len = strlen(color);
464 if (len != 3 && len != 4 && len != 6 && len != 8)
465 {
466 // longueur de chaîne incompatible
467 return NULL;
468 }
469 // Format long ?
470 int is_long = (len == 6 || len == 8) ? TRUE : FALSE;
471 float ratio = (is_long) ? 255.0 : 15.0;
472 int incr = (is_long) ? 2 : 1;
473 col = g_malloc0(sizeof*col);
474 col -> alpha = 1.0;
475 char buf[3] = {0}; // pour les caractères à examiner
476 // Format court (#RGB ou #RGBA)
477 buf[incr] = '\0';
478 buf[0] = color[0];
479 if (is_long) buf[1] = color[1];
480 col->red = strtol(buf, NULL, 16) / ratio;
481 buf[0] = color[incr];
482 if (is_long) buf[1] = color[incr+1];
483 col->green = strtol(buf, NULL, 16) / ratio;
484 buf[0] = color[2*incr];
485 if (is_long) buf[1] = color[2*incr+1];
486 col->blue = strtol(buf, NULL, 16) / ratio;
487 if (len == 4 || len == 8)
488 {
489 buf[0] = color[3*incr];
490 if (is_long) buf[1] = color[3*incr+1];
491 col->alpha = strtol(buf, NULL, 16) / ratio;
492 }
493
494 // Safety net
495 if (col -> red < 0.0 || col -> red > 1.0 ||
496 col -> green < 0.0 || col -> green > 1.0 ||
497 col -> blue < 0.0 || col -> blue > 1.0 ||
498 col -> alpha < 0.0 || col -> alpha > 1.0)
499 {
500 g_free(col);
501 return NULL;
502 }
503 return col;
504}
505
513int get_gradient_from_string (gchar * grad_string)
514{
515 gchar * no_keys[] = {"none", "no", "n", "0", NULL};
516 gchar * li_keys[] = {"linear", "lin", "li", "l", "1", NULL};
517 gchar * ci_keys[] = {"circular", "circ", "ci", "c", "2", NULL};
518 if (is_string_in_string_list(grad_string, no_keys)) return 0;
519 if (is_string_in_string_list(grad_string, li_keys)) return 1;
520 if (is_string_in_string_list(grad_string, ci_keys)) return 2;
521 return NONE;
522}
523
534int check_for_atomes_file_options (int start, int end, char *argv[])
535{
536 int i, j, k;
537 i=0;
538 for (j=start; j<end; j++)
539 {
540 k = test_this_arg (argv[j]);
541 if (k > 0 && j < end-1)
542 {
543 if (! (k == 1 && with_workspace))
544 {
545 if (! flist)
546 {
547 flist = g_malloc0(sizeof*flist);
548 ftmp = flist;
549 }
550 else
551 {
552 ftmp -> next = g_malloc0(sizeof*ftmp -> next);
553 ftmp = ftmp -> next;
554 }
555 ftmp -> file_name = g_strdup_printf ("%s", argv[j+1]);
556 ftmp -> file_type = k;
557 argv[j] = argv[j+1] = g_strdup_printf (" ");
558 j ++;
559 i ++;
560 if (k == 1) with_workspace = TRUE;
561 }
562 }
563 }
564 return i;
565}
566
573{
574 setlocale (LC_ALL, ""); /* Charge la locale système définie par l'utilisateur */
575 setlocale (LC_NUMERIC, "C"); /* Conserve le point comme séparateur décimal */
576 bindtextdomain (PACKAGE, PACKAGE_LOCALE);
577 textdomain (PACKAGE);
578 bind_textdomain_codeset (PACKAGE, "UTF-8"); // Forcer UTF-8 pour gettext
579}
580
589int parse_command_line (int argc, char *argv[])
590{
591 struct option atomes_options[] = {{"help", no_argument, 0, 'h'},
592 {"version", no_argument, 0, 'v'},
593 {"libreoffice", no_argument, 0, 'l'},
594 {"render-png", no_argument, 0, 'p'},
595 {"png", no_argument, 0, 'p'},
596 {"render-jpg", no_argument, 0, 'j'},
597 {"jpg", no_argument, 0, 'j'},
598 {"width", required_argument, 0, 'W'},
599 {"height", required_argument, 0, 'H'},
600 {"output", required_argument, 0, 'o'},
601 {"style", required_argument, 0, 's'},
602 {"atoms", required_argument, 0, 'e'},
603 {"poly", required_argument, 0, 't'},
604 {"axis", required_argument, 0, 'a'},
605 {"box", required_argument, 0, 'b'},
606 {"box_color", required_argument, 0, 'C'},
607 {"back_color", required_argument, 0, 'B'},
608 {"back_grad", required_argument, 0, 'G'},
609 {"back_dir", required_argument, 0, 'D'},
610 {"back_pos", required_argument, 0, 'P'},
611 {"grad_col_a", required_argument, 0, 'U'},
612 {"grad_col_b", required_argument, 0, 'V'},
613 {"rep", required_argument, 0, 'r'},
614 {"convert", required_argument, 0, 'c'},
615 // {"debug", no_argument, 0, 'd'},
616 {0, 0, 0, 0}};
617 int opt;
618 int index = -1;
619 int i, j;
620 double v;
621 gchar * image_x = NULL;
622 gchar * image_y = NULL;
623 int img_opt = 0;
624
625 for (i=0; i<2; i++) render_image_grad_color[i] = NULL;
626 /* We want to parse the command line using GNU getopt, but then
627 some options that are atomes specific and not GNU getopt compatible
628 might disappear, to prevent that it is mandatory to prepare
629 the information to be given to GNU getopt */
630 int files_to_read = check_for_atomes_file_options (1, argc, argv);
631
632 /* Letter follow by : means that the command requires an argument
633 No letter if the option is only in long format, ex : --width
634 If the long name is empty the command is only in short format */
635 while ((opt = getopt_long(argc, argv, "hvlpjdW:H:o:s:a:b:c:r:e:t:B:C:G:D:P:U:V:", atomes_options, & index)) != -1)
636 {
637 switch (opt)
638 {
639 case 'h':
641 print_help();
642 return FALSE;
643 break;
644 case 'v':
647 return FALSE;
648 break;
649 case 'e':
650 render_image_acolor = get_color_map_from_string (g_ascii_strdown(optarg,strlen(optarg)));
651 trigger_fragment_analysis = (render_image_acolor > 2) ? TRUE : FALSE;
652 trigger_molecule_analysis = (render_image_acolor > 3) ? TRUE : FALSE;
653 img_opt ++;
654 img_opt += (index == -1) ? 1 : 0;
655 break;
656 case 't':
657 render_image_pcolor = get_color_map_from_string (g_ascii_strdown(optarg,strlen(optarg)));
658 trigger_fragment_analysis = (render_image_pcolor > 2) ? TRUE : FALSE;
659 trigger_molecule_analysis = (render_image_pcolor > 3) ? TRUE : FALSE;
660 img_opt ++;
661 img_opt += (index == -1) ? 1 : 0;
662 break;
663 case 'l':
666 break;
667 case 'p':
668 atomes_render_image = TRUE;
670 img_opt ++;
671 break;
672 case 'j':
673 atomes_render_image = TRUE;
675 img_opt ++;
676 break;
677 case 'o':
678 render_image_output = g_strdup_printf ("%s", optarg);
679 img_opt ++;
680 img_opt += (index == -1) ? 1 : 0;
681 break;
682 case 'W':
683 image_x = g_strdup_printf ("%s", optarg);
684 img_opt ++;
685 img_opt += (index == -1) ? 1 : 0;
686 break;
687 case 'H':
688 image_y = g_strdup_printf ("%s", optarg);
689 img_opt ++;
690 img_opt += (index == -1) ? 1 : 0;
691 break;
692 case 's':
693 render_image_style = get_style_from_string (g_ascii_strdown(optarg,strlen(optarg)));
694 img_opt ++;
695 img_opt += (index == -1) ? 1 : 0;
696 break;
697 case 'a':
698 render_image_axis = get_box_axis_from_string (g_ascii_strdown(optarg,strlen(optarg)));
699 img_opt ++;
700 img_opt += (index == -1) ? 1 : 0;
701 break;
702 case 'b':
703 render_image_box = get_box_axis_from_string (g_ascii_strdown(optarg,strlen(optarg)));
704 img_opt ++;
705 img_opt += (index == -1) ? 1 : 0;
706 break;
707 case 'r':
708 render_image_rep = get_rep_from_string (g_ascii_strdown(optarg,strlen(optarg)));
709 img_opt ++;
710 img_opt += (index == -1) ? 1 : 0;
711 break;
712 case 'C':
714 img_opt ++;
715 img_opt += (index == -1) ? 1 : 0;
716 break;
717 case 'B':
719 img_opt ++;
720 img_opt += (index == -1) ? 1 : 0;
721 break;
722 case 'G':
723 render_image_back_grad = get_gradient_from_string (g_ascii_strdown(optarg,strlen(optarg)));
724 img_opt ++;
725 img_opt += (index == -1) ? 1 : 0;
726 break;
727 case 'D':
728 if (isdigit(optarg[0]))
729 {
730 render_image_back_dir = ((optarg[0] - '0') < 9) ? optarg[0] - '0' : NONE;
731 }
732 img_opt ++;
733 img_opt += (index == -1) ? 1 : 0;
734 break;
735 case 'P':
736 v = string_to_double(optarg);
737 render_image_back_pos = (v >= 0.0 && v <= 1.0) ? v : NONE;
738 img_opt ++;
739 img_opt += (index == -1) ? 1 : 0;
740 break;
741 case 'U':
743 img_opt ++;
744 img_opt += (index == -1) ? 1 : 0;
745 break;
746 case 'V':
748 img_opt ++;
749 img_opt += (index == -1) ? 1 : 0;
750 break;
751 case 'c':
752 atomes_convert_file = get_file_format_from_string (g_ascii_strdown(optarg,strlen(optarg)));
753 break;
754 }
755 index = -1;
756 }
759 {
760 if (! render_image_output) render_image_output = g_strdup_printf ("%s", (render_image_format) ? "image.jpg" : "image.png");
761 if (argc == img_opt + 2 + ((atomes_convert_file != NONE) ? 2 : 0))
762 {
763 if (image_x || image_y)
764 {
766 int pix;
767 if (image_x)
768 {
769 pix = (int) string_to_double(image_x);
770 if (pix > 0) render_image_pixels[0] = pix;
771 }
772 if (image_y)
773 {
774 pix = (int) string_to_double(image_y);
775 if (pix > 0) render_image_pixels[1] = pix;
776 }
777 }
778 }
779 else
780 {
781 return FALSE;
782 }
783 }
784
785 for (i=optind; i<argc; i++)
786 {
787 j = test_this_arg (argv[i]);
788 if (! (j == -1 && with_workspace))
789 {
790 if (j < 0)
791 {
792 if (! flist)
793 {
794 flist = g_malloc0(sizeof*flist);
795 ftmp = flist;
796 }
797 else
798 {
799 ftmp -> next = g_malloc0(sizeof*ftmp -> next);
800 ftmp = ftmp -> next;
801 }
802 ftmp -> file_name = g_strdup_printf ("%s", argv[i]);
803 ftmp -> file_type = -j;
804 files_to_read ++;
805 if (atomes_from_libreoffice) projfile = g_strdup_printf ("%s", argv[i]);
806 if (j == -1) with_workspace = TRUE;
807 }
808 }
809 }
810
811 return ((atomes_render_image || atomes_convert_file != NONE) && files_to_read == 1) ? TRUE : (atomes_render_image || atomes_convert_file != NONE) ? FALSE : TRUE;
812}
813
821gboolean destroy_func (gpointer user_data)
822{
823 GtkWidget * splashi = (GtkWidget*) user_data;
824 destroy_this_widget (splashi);
825 return FALSE;
826}
827
828#ifdef GTK3
838G_MODULE_EXPORT gboolean splashdraw (GtkWidget * widget, cairo_t * cr, gpointer data)
839{
840 cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
841 cairo_paint (cr);
842 return FALSE;
843}
844#endif
845
852{
853 GtkWidget * splash_window = new_gtk_window ();
854 gtk_window_set_decorated (GTK_WINDOW (splash_window), FALSE);
855 GtkWidget * image;
856#ifdef GTK4
857 image = gtk_picture_new_for_filename (PACKAGE_LOGO);
858 gchar * backcol = g_strdup_printf ("window#splash {\n"
859 " background: none;"
860 " background-color: rgba(255, 255, 255, 0);}");
861 provide_gtk_css (backcol);
862 gtk_widget_set_name (splash_window, "splash");
863 g_free (backcol);
864#else
865 gtk_window_set_type_hint (GTK_WINDOW (splash_window), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
866 gtk_window_set_position (GTK_WINDOW (splash_window), GTK_WIN_POS_CENTER_ALWAYS);
867 gtk_widget_set_app_paintable (splash_window, TRUE);
868 GdkScreen * screen = gtk_widget_get_screen (splash_window);
869 GdkVisual * visual = gdk_screen_get_rgba_visual (screen);
870 gtk_widget_set_visual (splash_window, visual);
871 // Next line might be optional for total transparency
872 g_signal_connect(G_OBJECT(splash_window), "draw", G_CALLBACK(splashdraw), NULL);
873 image = gtk_image_new_from_file (PACKAGE_LOGO);
874#endif
875 add_container_child (CONTAINER_WIN, splash_window, image);
876 gtk_window_set_transient_for ((GtkWindow *)splash_window, (GtkWindow *)atomes_main_window);
877 show_the_widgets (splash_window);
878 return splash_window;
879}
880
889void read_this_file (int file_type, gchar * this_file)
890{
891 FILE * fp = fopen (this_file, dfi[0]);
892 if (file_type == 1)
893 {
894 int i = open_save_workspace (fp, 0);
895 if (i != 0)
896 {
897 gchar * err = g_strdup_printf (_("Error while reading workspace file\n%s\n"), this_file);
899 g_free (err);
900 }
901 }
902 else
903 {
904 init_project (FALSE);
905 reading_project = TRUE;
906 open_save (fp, 0, 0, activep, activep, this_file);
907 reading_project = FALSE;
908 }
909 fclose (fp);
910}
911
920void open_this_data_file (int file_type, gchar * file_name)
921{
922 gchar * end;
923 gchar * str;
924 gchar * filedir;
925 int i;
926#ifdef G_OS_WIN32
927 WIN32_FIND_DATA ffd;
928 HANDLE hFind;
929#else
930 DIR * d;
931 struct dirent * dir;
932#endif
933 switch (file_type)
934 {
935 case 1:
936 read_this_file (1, file_name);
937 break;
938 case 2:
939 end = g_strdup_printf ("%c", file_name[strlen(file_name)-1]);
940 if (g_strcmp0 (file_name, "*") == 0 || g_strcmp0 (end, "*") == 0)
941 {
942 if (g_strcmp0 (file_name, "*") == 0)
943 {
944 filedir = g_strdup_printf ("./");
945 }
946 else
947 {
948 filedir = g_strdup_printf ("%c", file_name[0]);
949 for (i=1; i<strlen(file_name)-1; i++) filedir = g_strdup_printf ("%s%c", filedir, file_name[i]);
950 }
951#ifdef G_OS_WIN32
952 hFind = FindFirstFile (filedir, & ffd);
953 if (hFind != INVALID_HANDLE_VALUE)
954 {
955 if (ffd.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)
956 {
957 str = g_strdup_printf ("%s\\%s", filedir, (gchar *)ffd.cFileName);
958 read_this_file (2, str);
959 g_free (str);
960 }
961 while (FindNextFile(hFind, &ffd) != 0)
962 {
963 if (ffd.dwFileAttributes & ! FILE_ATTRIBUTE_DIRECTORY)
964 {
965 str = g_strdup_printf ("%s\\%s", filedir, (gchar *)ffd.cFileName);
966 read_this_file (2, str);
967 g_free (str);
968 }
969 }
970 }
971 FindClose(hFind);
972#else
973 d = opendir (filedir);
974 if (d)
975 {
976 while ((dir = readdir(d)) != NULL)
977 {
978 if (dir -> d_type == DT_REG)
979 {
980 str = g_strdup_printf ("%s/%s", filedir, dir -> d_name);
981 read_this_file (2, str);
982 g_free (str);
983 }
984 }
985 closedir(d);
986 }
987#endif
988 g_free (filedir);
989 }
990 else
991 {
992 read_this_file (2, file_name);
993 }
994 break;
995 case 17:
996 init_project (TRUE);
997 open_this_isaacs_xml_file (g_strdup_printf ("%s", file_name), activep, FALSE);
998 break;
999 default:
1000 end = g_strdup_printf ("%c", file_name[strlen(file_name)-1]);
1001 if (g_strcmp0 (file_name, "*") == 0 || g_strcmp0 (end, "*") == 0)
1002 {
1003 if (g_strcmp0 (file_name, "*") == 0)
1004 {
1005 filedir = g_strdup_printf ("./");
1006 }
1007 else
1008 {
1009 filedir = g_strdup_printf ("%c", file_name[0]);
1010 for (i=1; i<strlen(file_name)-1; i++) filedir = g_strdup_printf ("%s%c", filedir, file_name[i]);
1011 }
1012#ifdef G_OS_WIN32
1013 hFind = FindFirstFile (filedir, & ffd);
1014 if (hFind != INVALID_HANDLE_VALUE)
1015 {
1016 if (ffd.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)
1017 {
1018 init_project (TRUE);
1019 active_project -> coordfile = g_strdup_printf ("%s\\%s", filedir, (gchar *)ffd.cFileName);
1020 open_this_coordinate_file (file_type-3, NULL, TRUE);
1021 }
1022 while (FindNextFile(hFind, &ffd) != 0)
1023 {
1024 if (ffd.dwFileAttributes & ! FILE_ATTRIBUTE_DIRECTORY)
1025 {
1026 init_project (TRUE);
1027 active_project -> coordfile = g_strdup_printf ("%s\\%s", filedir, (gchar *)ffd.cFileName);
1028 open_this_coordinate_file (file_type-3, NULL, TRUE);
1029 }
1030 }
1031 }
1032 FindClose(hFind);
1033#else
1034 d = opendir (filedir);
1035 if (d)
1036 {
1037 while ((dir = readdir(d)) != NULL)
1038 {
1039 if (dir -> d_type == DT_REG)
1040 {
1041 init_project (TRUE);
1042 active_project -> coordfile = g_strdup_printf ("%s/%s", filedir, dir -> d_name);
1043 open_this_coordinate_file (file_type-3, NULL, TRUE);
1044 }
1045 }
1046 closedir(d);
1047 }
1048#endif
1049 g_free (filedir);
1050 }
1051 else
1052 {
1053 init_project (TRUE);
1054 active_project -> coordfile = g_strdup_printf ("%s", file_name);
1055 open_this_coordinate_file (file_type-3, NULL, TRUE);
1056 }
1057 break;
1058 }
1059}
1060
1061#ifndef G_OS_WIN32
1072static gboolean handle_open_file (Instance * object, GDBusMethodInvocation * invocation, const gchar * arg_file, gpointer user_data)
1073{
1074 if (arg_file && strlen (arg_file) > 0)
1075 {
1076 int len = strlen (arg_file);
1077 int file_type = -test_this_ext (len, (gchar *) arg_file);
1078 if (file_type > 0)
1079 {
1080 open_this_data_file (file_type, (gchar *) arg_file);
1081 }
1082 }
1083 instance_complete_open_file (object, invocation);
1084 // Bring the main window on sight
1085
1087 {
1088 if (GTK_IS_WIDGET(atomes_main_window))
1089 {
1090 gtk_window_present (GTK_WINDOW(atomes_main_window));
1091 }
1092 }
1093 return TRUE;
1094}
1095
1101static gboolean init_dbus_server ()
1102{
1103 GError * error = NULL;
1104 GDBusConnection * connection; // D-Bus connection
1105 GDBusInterfaceSkeleton * skeleton; // D-Bus skeleton
1106
1107 // Connexion au bus de session
1108 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, & error);
1109 if (error)
1110 {
1111 g_printerr ("D-Bus connection error : %s\n", error -> message);
1112 g_error_free (error);
1113 return FALSE;
1114 }
1115
1116 // Créer le skeleton généré par gdbus-codegen
1117 Instance * interface = instance_skeleton_new ();
1118 skeleton = G_DBUS_INTERFACE_SKELETON (interface);
1119
1120 // Connecter le gestionnaire de méthode OpenFile
1121 g_signal_connect (interface, "handle-open-file", G_CALLBACK (handle_open_file), NULL);
1122
1123 // Exporter le skeleton via son API propre (utilise sa vtable interne)
1124 if (! g_dbus_interface_skeleton_export (skeleton, connection, "/fr/ipcms/atomes/Instance", & error))
1125 {
1126 g_printerr ("D-Bus interface export error : %s\n", error -> message);
1127 g_error_free (error);
1128 return FALSE;
1129 }
1130
1131 // Réserver le nom bien connu sur le bus (appel synchrone pour garantir
1132 // que le nom est disponible avant le démarrage de la boucle principale)
1133 GVariant * name_result = g_dbus_connection_call_sync (connection,
1134 "org.freedesktop.DBus",
1135 "/org/freedesktop/DBus",
1136 "org.freedesktop.DBus",
1137 "RequestName",
1138 g_variant_new ("(su)", "fr.ipcms.atomes.Instance", 4u), /* 4 = DO_NOT_QUEUE */
1139 G_VARIANT_TYPE ("(u)"),
1140 G_DBUS_CALL_FLAGS_NONE,
1141 -1, NULL, & error);
1142
1143 if (error)
1144 {
1145 g_printerr ("D-Bus name reservation error : %s\n", error -> message);
1146 g_error_free (error);
1147 /* non fatal */
1148 }
1149 else if (name_result)
1150 {
1151 guint reply;
1152 g_variant_get (name_result, "(u)", & reply);
1153 g_variant_unref (name_result);
1154 if (reply != 1u) /* 1 = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER */
1155 {
1156 g_printerr ("Impossible d'obtenir le nom D-Bus (code: %u)\n", reply);
1157 }
1158 }
1159
1160 return TRUE;
1161}
1162
1170static gboolean check_existing_instance ()
1171{
1172 gboolean sent = FALSE;
1173 if (! flist) return sent;
1174
1175 GError * error = NULL;
1176 GDBusConnection * connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, & error);
1177 if (error)
1178 {
1179 g_printerr ("D-Bus connection error : %s\n", error -> message);
1180 g_error_free (error);
1181 return sent;
1182 }
1183
1184 if (! flist) return sent;
1185
1186 struct file_list * tmp = flist;
1187 while (tmp)
1188 {
1189 error = NULL;
1190 GVariant * result = g_dbus_connection_call_sync (connection,
1191 "fr.ipcms.atomes.Instance",
1192 "/fr/ipcms/atomes/Instance",
1193 "fr.ipcms.atomes.Instance",
1194 "OpenFile",
1195 g_variant_new ("(s)", tmp -> file_name),
1196 NULL,
1197 G_DBUS_CALL_FLAGS_NONE,
1198 -1,
1199 NULL,
1200 & error);
1201 if (error)
1202 {
1203 /* Aucune instance ou erreur réseau : on arrête et on démarre normalement */
1204 g_printerr ("D-Bus OpenFile error: %s\n", error -> message);
1205 g_error_free (error);
1206 break;
1207 }
1208 if (result)
1209 {
1210 g_variant_unref (result);
1211 sent = TRUE;
1212 }
1213 tmp = tmp -> next;
1214 }
1215
1216 g_object_unref (connection);
1217 return sent;
1218}
1219#else
1220
1221#define ATOMES_MUTEX_NAME "fr.ipcms.atomes.mutex"
1222#define ATOMES_PIPE_NAME "\\\\.\\pipe\\fr.ipcms.atomes.pipe"
1223#define ATOMES_PIPE_BUFSIZE 4096
1224
1225HANDLE win32_mutex = NULL;
1226
1232typedef struct OpenFileData OpenFileData;
1233struct OpenFileData
1234{
1235 int file_type;
1236 gchar * file_name;
1237};
1238
1250static gboolean win32_open_file_idle (gpointer user_data)
1251{
1252 OpenFileData * ofd = (OpenFileData *) user_data;
1253 open_this_data_file (ofd -> file_type, ofd -> file_name);
1255 {
1256 gtk_window_present (GTK_WINDOW (atomes_main_window));
1257 }
1258 g_free (ofd -> file_name);
1259 g_free (ofd);
1260 return FALSE;
1261}
1262
1274static gpointer win32_pipe_server_thread (gpointer user_data)
1275{
1276 while (TRUE)
1277 {
1278 HANDLE pipe = CreateNamedPipe (ATOMES_PIPE_NAME,
1279 PIPE_ACCESS_INBOUND,
1280 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1281 PIPE_UNLIMITED_INSTANCES,
1282 ATOMES_PIPE_BUFSIZE,
1283 ATOMES_PIPE_BUFSIZE,
1284 0, NULL);
1285 if (pipe == INVALID_HANDLE_VALUE)
1286 {
1287 g_printerr ("CreateNamedPipe failed: %lu\n", GetLastError ());
1288 break;
1289 }
1290
1291 BOOL connected = ConnectNamedPipe(pipe, NULL);
1292 if (! connected && GetLastError() != ERROR_PIPE_CONNECTED)
1293 {
1294 g_printerr ("ConnectNamedPipe failed: %lu", GetLastError());
1295 CloseHandle(pipe);
1296 break;
1297 }
1298 else if (connected || GetLastError () == ERROR_PIPE_CONNECTED)
1299 {
1300 char buf[ATOMES_PIPE_BUFSIZE];
1301 DWORD bytes_read = 0;
1302 BOOL ok = ReadFile (pipe, buf, sizeof (buf) - 1, & bytes_read, NULL);
1303 if (ok && bytes_read > 0)
1304 {
1305 buf[bytes_read] = '\0';
1306 int len = (int) strlen (buf);
1307 int file_type = -test_this_ext (len, buf);
1308 if (file_type > 0)
1309 {
1310 OpenFileData * ofd = g_malloc0 (sizeof * ofd);
1311 ofd -> file_type = file_type;
1312 ofd -> file_name = g_strdup (buf);
1313 g_idle_add (win32_open_file_idle, ofd);
1314 }
1315 }
1316 else
1317 {
1318 g_printerr ("ReadFile failed: %lu", GetLastError());
1319 }
1320 }
1321 DisconnectNamedPipe(pipe);
1322 CloseHandle (pipe);
1323 }
1324 return NULL;
1325}
1326
1335static gboolean init_win32_server ()
1336{
1337 win32_mutex = CreateMutex (NULL, TRUE, ATOMES_MUTEX_NAME);
1338 if (win32_mutex == NULL)
1339 {
1340 g_printerr ("CreateMutex failed: %lu\n", GetLastError ());
1341 return FALSE;
1342 }
1343
1344 if (GetLastError () == ERROR_ALREADY_EXISTS)
1345 {
1346 CloseHandle (win32_mutex);
1347 win32_mutex = NULL;
1348 return TRUE;
1349 }
1350
1351 HANDLE thread = g_thread_new ("atomes-pipe-server", win32_pipe_server_thread, NULL);
1352 if (thread == NULL)
1353 {
1354 CloseHandle (win32_mutex);
1355 win32_mutex = NULL;
1356 return FALSE;
1357 }
1358
1359 return TRUE;
1360}
1361
1373static gboolean check_existing_win32_instance ()
1374{
1375 if (! flist) return FALSE;
1376
1377 HANDLE mutex = OpenMutex (MUTEX_ALL_ACCESS, FALSE, ATOMES_MUTEX_NAME);
1378 if (mutex == NULL) return FALSE;
1379
1380 gboolean sent = FALSE;
1381 struct file_list * tmp = flist;
1382 while (tmp)
1383 {
1384 HANDLE pipe = CreateFile (ATOMES_PIPE_NAME,
1385 GENERIC_WRITE,
1386 0,
1387 NULL,
1388 OPEN_EXISTING,
1389 0,
1390 NULL);
1391
1392 if (pipe == INVALID_HANDLE_VALUE)
1393 {
1394 g_printerr ("CreateFile PIPE FAILED: %lu\n", GetLastError());
1395 }
1396
1397 DWORD len = (DWORD) strlen (tmp -> file_name);
1398 DWORD written = 0;
1399
1400 BOOL ok = WriteFile (pipe, tmp -> file_name, len, & written, NULL);
1401
1402 if (! ok)
1403 {
1404 g_printerr ("WriteFile FAILED: %lu\n", GetLastError());
1405 }
1406 else
1407 {
1408 g_printerr ("WriteFile OK: %lu/%lu bytes\n", written, len);
1409 if (written == len) sent = TRUE;
1410 }
1411
1412 CloseHandle (pipe);
1413 tmp = tmp->next;
1414 }
1415
1416 CloseHandle (mutex);
1417 mutex = NULL;
1418
1419 return sent;
1420}
1421#endif /* G_OS_WIN32 */
1422
1431G_MODULE_EXPORT void run_program (GApplication * app, gpointer data)
1432{
1433 /* GTK re-initializes the locale during startup (gtk_init calls setlocale(LC_ALL, "")),
1434 which overrides the LC_NUMERIC = "C" set in main(). We must enforce it again here
1435 to ensure floating-point parsing/formatting always uses the English (dot) convention. */
1436 setlocale (LC_NUMERIC, "C");
1437 GtkSettings * default_settings = gtk_settings_get_default ();
1438/*
1439#ifndef G_OS_WIN32
1440 g_object_set (default_settings, "gtk-application-prefer-dark-theme", TRUE, NULL);
1441#endif
1442*/
1443#ifdef GTK3
1444 g_object_set (default_settings, "gtk-button-images", TRUE, NULL);
1445#endif
1446#ifdef G_OS_WIN32
1447#ifdef GTK3
1448 g_object_set (default_settings, "gtk-key-theme-name", "win32", NULL);
1449#endif
1450 dfi[0]="rb";
1451 dfi[1]="wb";
1452#else
1453 dfi[0]="r";
1454 dfi[1]="w";
1455#endif
1456
1457#ifdef MAC_INTEGRATION
1458 GtkosxApplication * ProgOSX;
1459 ProgOSX = g_object_new (GTKOSX_TYPE_APPLICATION, NULL);
1460 gtkosx_application_set_use_quartz_accelerators (ProgOSX, FALSE);
1461 gtkosx_application_ready (ProgOSX);
1462#endif
1463#ifdef DEBUG
1464 print_version ();
1465#endif // DEBUG
1466
1468 {
1470 GtkWidget * isplash = create_splash_window ();
1471 if (isplash == NULL)
1472 {
1473 g_warning (_("Impossible to load the splash screen\n"));
1474 }
1475 else
1476 {
1477 g_timeout_add_seconds (1, destroy_func, isplash);
1478 }
1479 }
1480 if (flist)
1481 {
1482 ftmp = flist;
1483 silent_input = TRUE;
1484 if (with_workspace)
1485 {
1486 while (ftmp)
1487 {
1488 if (ftmp -> file_type == 1)
1489 {
1490 // Open the workspace file first
1492 }
1493 ftmp = ftmp -> next;
1494 }
1495 }
1496 ftmp = flist;
1497 while (ftmp)
1498 {
1499 if (ftmp -> file_type != 1)
1500 {
1501 // Add project(s) to workspace
1503 }
1504 ftmp = ftmp -> next;
1505 }
1506 g_free (flist);
1507 flist = NULL;
1508 silent_input = FALSE;
1509 }
1510#ifdef MAC_INTEGRATION
1511 g_object_unref (ProgOSX);
1512#endif
1513}
1514
1521{
1522 GError * error = NULL;
1523 gchar * proc_dir = NULL;
1524 gchar * proc_path = NULL;
1525 const char * proc_name;
1526#ifdef G_OS_WIN32
1527 proc_dir = g_build_filename (PACKAGE_PREFIX, "bin", NULL);
1528 proc_name = "atomes_startup_testing.exe";
1529 proc_path = g_build_filename (proc_dir, proc_name, NULL);
1530#else
1531 proc_dir = g_build_filename (PACKAGE_LIBEXEC, NULL);
1532 proc_name = "atomes_startup_testing";
1533 proc_path = g_build_filename (PACKAGE_LIBEXEC, proc_name, NULL);
1534#endif
1535#ifdef DEBUG
1536 g_print ("proc_dir= %s\n", proc_dir);
1537 g_print ("proc_name= %s\n", proc_name);
1538 g_print ("proc_path= %s\n", proc_path);
1539#endif
1540
1541#ifdef CODEBLOCKS
1542 GSubprocess * proc = g_subprocess_new (G_SUBPROCESS_FLAGS_NONE, & error, proc_path, NULL);
1543#else
1544#ifndef OSX
1545 GSubprocessLauncher * proc_launch = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
1546 g_subprocess_launcher_set_cwd (proc_launch, proc_dir);
1547 GSubprocess * proc = g_subprocess_launcher_spawn (proc_launch, & error, proc_path, NULL);
1548#else
1549 GSubprocess * proc = g_subprocess_new (G_SUBPROCESS_FLAGS_NONE, & error, proc_path, NULL);
1550#endif
1551#endif
1552
1553 if (error)
1554 {
1555 g_printerr ("error: %s\n", error -> message);
1556 g_clear_error (& error);
1557 }
1558 g_subprocess_wait (proc, NULL, & error);
1559 int res = g_subprocess_get_exit_status (proc);
1560#ifdef DEBUG
1561 g_debug ("Exit status of atomes_startup_testing = %d", res);
1562#endif
1563 g_object_unref (proc);
1564#ifndef CODEBLOCKS
1565#ifndef OSX
1566 g_object_unref (proc_launch);
1567#endif
1568#endif
1569 g_free (proc_path);
1570 g_free (proc_dir);
1571 gchar * ogl_info = NULL;
1572 switch (res)
1573 {
1574 case 1:
1575 ogl_info = g_strdup_printf (_("Fatal error on OpenGL initialization: trying to adjust environment !"));
1576 break;
1577 case -2:
1578 ogl_info = g_strdup_printf (_("Impossible to initialize the OpenGL 3D rendering !"));
1579 break;
1580 case -1:
1581 ogl_info = g_strdup_printf (_("GDK visual must be modified to initialize the OpenGL context !"));
1582 break;
1583 default:
1584 break;
1585 }
1586 if (ogl_info)
1587 {
1588 g_print ("%s\n", ogl_info);
1589 g_free (ogl_info);
1590 ogl_info = NULL;
1591 }
1592 return res;
1593}
1594
1603int main (int argc, char *argv[])
1604{
1605 gboolean RUNC = FALSE;
1606
1607 // Allocating application data structure, custom required for instance(s) managment
1608 atomes_app = g_malloc0 (sizeof *atomes_app);
1609
1610#ifdef G_OS_WIN32
1611 PACKAGE_PREFIX = g_win32_get_package_installation_directory_of_module (NULL);
1612 PACKAGE_LOCALE = g_build_filename (PACKAGE_PREFIX, "locale", NULL);
1613 // g_win32_get_package_installation_directory (NULL, NULL);
1614#endif
1615 PACKAGE_LIB_DIR = g_build_filename (PACKAGE_PREFIX, "library", NULL);
1616 PACKAGE_IMP = g_build_filename (PACKAGE_PREFIX, "pixmaps/import.png", NULL);
1617 PACKAGE_IMP = g_build_filename (PACKAGE_PREFIX, "pixmaps/import.png", NULL);
1618 PACKAGE_CON = g_build_filename (PACKAGE_PREFIX, "pixmaps/convert.png", NULL);
1619 PACKAGE_IMG = g_build_filename (PACKAGE_PREFIX, "pixmaps/image.png", NULL);
1620 PACKAGE_PDF = g_build_filename (PACKAGE_PREFIX, "pixmaps/pdf.png", NULL);
1621 PACKAGE_SVG = g_build_filename (PACKAGE_PREFIX, "pixmaps/svg.png", NULL);
1622 PACKAGE_EPS = g_build_filename (PACKAGE_PREFIX, "pixmaps/eps.png", NULL);
1623 PACKAGE_PNG = g_build_filename (PACKAGE_PREFIX, "pixmaps/png.png", NULL);
1624 PACKAGE_JPG = g_build_filename (PACKAGE_PREFIX, "pixmaps/jpg.png", NULL);
1625 PACKAGE_BMP = g_build_filename (PACKAGE_PREFIX, "pixmaps/bmp.png", NULL);
1626 PACKAGE_TIFF = g_build_filename (PACKAGE_PREFIX, "pixmaps/tiff.png", NULL);
1627 PACKAGE_VOID = g_build_filename (PACKAGE_PREFIX, "pixmaps/void.png", NULL);
1628 PACKAGE_TD = g_build_filename (PACKAGE_PREFIX, "pixmaps/td.png", NULL);
1629 PACKAGE_MOL = g_build_filename (PACKAGE_PREFIX, "pixmaps/molecule.png", NULL);
1630 PACKAGE_OGL = g_build_filename (PACKAGE_PREFIX, "pixmaps/opengl.png", NULL);
1631 PACKAGE_OGLM = g_build_filename (PACKAGE_PREFIX, "pixmaps/mol.png", NULL);
1632 PACKAGE_OGLC = g_build_filename (PACKAGE_PREFIX, "pixmaps/mol.png", NULL);
1633 PACKAGE_PRO = g_build_filename (PACKAGE_PREFIX, "pixmaps/prop.png", NULL);
1634 PACKAGE_SET = g_build_filename (PACKAGE_PREFIX, "pixmaps/settings.png", NULL);
1635 PACKAGE_LOGO = g_build_filename (PACKAGE_PREFIX, "pixmaps/logo.png", NULL);
1636 PACKAGE_LAGPL = g_build_filename (PACKAGE_PREFIX, "pixmaps/logo-agpl.png", NULL);
1637 PACKAGE_LABOUT = g_build_filename (PACKAGE_PREFIX, "pixmaps/logo-about.png", NULL);
1638 PACKAGE_DOTA = g_build_filename (PACKAGE_PREFIX, "pixmaps/dots/dots-a.png", NULL);
1639 PACKAGE_DOTB = g_build_filename (PACKAGE_PREFIX, "pixmaps/dots/dots-b.png", NULL);
1640 PACKAGE_DOTC = g_build_filename (PACKAGE_PREFIX, "pixmaps/dots/dots-c.png", NULL);
1641 PACKAGE_DOTD = g_build_filename (PACKAGE_PREFIX, "pixmaps/dots/dots-d.png", NULL);
1642 PACKAGE_DOTE = g_build_filename (PACKAGE_PREFIX, "pixmaps/dots/dots-e.png", NULL);
1643 PACKAGE_DOTF = g_build_filename (PACKAGE_PREFIX, "pixmaps/dots/dots-f.png", NULL);
1644 PACKAGE_DOTG = g_build_filename (PACKAGE_PREFIX, "pixmaps/dots/dots-g.png", NULL);
1645 PACKAGE_DOTH = g_build_filename (PACKAGE_PREFIX, "pixmaps/dots/dots-h.png", NULL);
1646 PACKAGE_DFBD = g_build_filename (PACKAGE_PREFIX, "pixmaps/field/bd.png", NULL);
1647 PACKAGE_DFAN = g_build_filename (PACKAGE_PREFIX, "pixmaps/field/an.png", NULL);
1648 PACKAGE_DFDI = g_build_filename (PACKAGE_PREFIX, "pixmaps/field/di.png", NULL);
1649 PACKAGE_DFTD = g_build_filename (PACKAGE_PREFIX, "pixmaps/field/td.png", NULL);
1650 PACKAGE_DFIN = g_build_filename (PACKAGE_PREFIX, "pixmaps/field/in.png", NULL);
1651 PACKAGE_SGCP = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Cubic-P.png", NULL);
1652 PACKAGE_SGCI = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Cubic-I.png", NULL);
1653 PACKAGE_SGCF = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Cubic-F.png", NULL);
1654 PACKAGE_SGHP = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Hexagonal.png", NULL);
1655 PACKAGE_SGTR = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Trigonal-R.png", NULL);
1656 PACKAGE_SGTI = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Tetragonal-I.png", NULL);
1657 PACKAGE_SGTP = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Tetragonal-P.png", NULL);
1658 PACKAGE_SGOP = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Orthorhombic-P.png", NULL);
1659 PACKAGE_SGOI = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Orthorhombic-I.png", NULL);
1660 PACKAGE_SGOC = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Orthorhombic-C.png", NULL);
1661 PACKAGE_SGOF = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Orthorhombic-F.png", NULL);
1662 PACKAGE_SGMP = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Monoclinic-P.png", NULL);
1663 PACKAGE_SGMI = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Monoclinic-I.png", NULL);
1664 PACKAGE_SGTC = g_build_filename (PACKAGE_PREFIX, "pixmaps/bravais/Triclinic.png", NULL);
1665
1666 switch (argc)
1667 {
1668 case 1:
1669 RUNC = TRUE;
1670 break;
1671 default:
1672 RUNC = parse_command_line (argc, argv);
1673 break;
1674 }
1675
1676 if (RUNC)
1677 {
1678#ifdef G_OS_WIN32
1679#ifndef DEBUG
1680 FreeConsole ();
1681#endif
1682#endif
1684 if (atomes_visual == 1)
1685 {
1686 // OpenGL initialization error, try adapting environment
1687 g_setenv ("GSK_RENDERER", "gl", TRUE);
1688 g_setenv ("GDK_DEBUG", "gl-prefer-gl", TRUE);
1690 if (atomes_visual == 1)
1691 {
1692 // OpenGL initialization error, again try adapting environment
1693 g_setenv ("GDK_RENDERER", "ngl", TRUE);
1695 }
1696 }
1697 if (atomes_visual > 0 || atomes_visual == -2)
1698 {
1699 // No way to initialize an OpenGL context: must quit
1700 return 1;
1701 }
1702#ifdef OSX
1703 g_setenv ("GSK_RENDERER", "gl", TRUE);
1704#endif
1705 atomes_visual = ! (abs(atomes_visual));
1706
1707#ifdef G_OS_WIN32
1708 PWSTR localPath = NULL;
1709 HRESULT hr = SHGetKnownFolderPath (& FOLDERID_LocalAppData, 0, NULL, & localPath);
1710 if (FAILED(hr))
1711 {
1712 fprintf (stderr, _("Error impossible to obtain the AppData\\Roaming (code 0x%08lx)\n%s"), hr);
1713 ATOMES_CONFIG_DIR = NULL;
1714 ATOMES_CONFIG = NULL;
1715 }
1716 else
1717 {
1718 char appdata[MAX_PATH];
1719 wcstombs (appdata, localPath, MAX_PATH);
1720 CoTaskMemFree (localPath); // libérer mémoire retournée par SHGetKnownFolderPath
1721 // Build the folder path for atomes
1722 ATOMES_CONFIG_DIR = g_strdup_printf ("%s\\atomes", appdata);
1723 ATOMES_CONFIG = g_strdup_printf ("%s\\atomes.pml", ATOMES_CONFIG_DIR);
1724 }
1725#else
1726 struct passwd * pw = getpwuid(getuid());
1727 ATOMES_CONFIG_DIR = g_strdup_printf ("%s/.config/atomes", pw -> pw_dir);
1728 ATOMES_CONFIG = g_strdup_printf ("%s/atomes.pml", ATOMES_CONFIG_DIR);
1729#endif
1730
1733
1734 // Now user preferences are known
1736 {
1737 if (default_instance)
1738 {
1739 // Check if there is already an existing atomes instance running
1740 // If yes then transmit the file(s) to open to this instance
1741#ifdef G_OS_WIN32
1742 /* Check for an existing atomes instance via Win32 Named Mutex/Pipe */
1743 if (argc > 1 && check_existing_win32_instance ())
1744 {
1745 return 0;
1746 }
1747 if (! init_win32_server ())
1748 {
1749 g_print ("Init Win32 pipe server failed\n");
1750 return 1;
1751 }
1752#else
1753 if (argc > 1 && check_existing_instance ())
1754 {
1755 // Another instance was found, quit.
1756 return 0;
1757 }
1758
1759 if (! init_dbus_server ())
1760 {
1761 g_print ("Init D-BUS failed\n");
1762 return 1;
1763 }
1764#endif // G_OS_WIN32
1765 }
1766 }
1767
1768#if GLIB_MINOR_VERSION < 74
1769 atomes_app = gtk_application_new (g_strdup_printf ("fr.ipcms.atomes.prog-%d", (int)clock()), G_APPLICATION_FLAGS_NONE);
1770#else
1771 atomes_app = gtk_application_new (g_strdup_printf ("fr.ipcms.atomes.prog-%d", (int)clock()), G_APPLICATION_DEFAULT_FLAGS);
1772#endif
1773 GError * error = NULL;
1774 g_application_register (G_APPLICATION(atomes_app), NULL, & error);
1775 g_signal_connect (G_OBJECT(atomes_app), "activate", G_CALLBACK(run_program), NULL);
1776
1777 int status = g_application_run (G_APPLICATION (atomes_app), 0, NULL);
1778 g_object_unref (atomes_app);
1779#ifdef G_OS_WIN32
1780 if (win32_mutex)
1781 {
1782 ReleaseMutex (win32_mutex);
1783 CloseHandle (win32_mutex);
1784 }
1785#endif
1786 return status;
1787 }
1788 return 0;
1789}
Binding to the Fortran90 subroutines.
int open_save_workspace(FILE *fp, int act)
open or save the active workspace
Definition callbacks.c:378
void open_this_coordinate_file(int format, gchar *proj_name, gboolean main_reader)
open coordinate file format, if successful add to workspace
Definition callbacks.c:1536
int open_save(FILE *fp, int act, int wid, int pid, int aid, gchar *pfile)
open or save project file
Definition callbacks.c:257
const gchar * dfi[2]
Definition main.c:105
void open_this_isaacs_xml_file(gchar *profile, int ptoc, gboolean visible)
open an ISAACS XML file
Definition callbacks.c:831
Callback declarations for main window.
#define VERSION
Definition config.h:67
#define PACKAGE_BUGREPORT
Definition config.h:49
#define PACKAGE
Definition config.h:46
ColRGBA col
Definition d_measures.c:77
FILE * fp
Instance * instance_skeleton_new(void)
void instance_complete_open_file(Instance *object G_GNUC_UNUSED, GDBusMethodInvocation *invocation)
struct _Instance Instance
int atomes_convert_file
Definition global.c:197
gchar * PACKAGE_BMP
Definition global.c:98
gchar * PACKAGE_SET
Definition global.c:107
gchar * ATOMES_CONFIG
Definition global.c:139
gchar * PACKAGE_SGTP
Definition global.c:130
gchar * PACKAGE_SGMI
Definition global.c:136
gchar * PACKAGE_SGTI
Definition global.c:129
gchar * PACKAGE_DOTG
Definition global.c:117
gchar * PACKAGE_TIFF
Definition global.c:99
gchar * PACKAGE_LAGPL
Definition global.c:109
gchar * PACKAGE_LOGO
Definition global.c:108
gchar * PACKAGE_DOTC
Definition global.c:113
gchar * PACKAGE_LIB_DIR
Definition global.c:89
GtkWidget * atomes_main_window
Definition global.c:208
gchar * PACKAGE_IMG
Definition global.c:92
gchar * PACKAGE_DFIN
Definition global.c:123
int activep
Definition global.c:162
gchar * PACKAGE_IMP
Definition global.c:90
gchar * PACKAGE_DOTE
Definition global.c:115
gchar * PACKAGE_DOTH
Definition global.c:118
gchar * PACKAGE_SGMP
Definition global.c:135
gchar * PACKAGE_DFAN
Definition global.c:120
gchar * PACKAGE_SGTR
Definition global.c:128
gchar * PACKAGE_DFDI
Definition global.c:121
gchar * PACKAGE_DFTD
Definition global.c:122
gboolean silent_input
Definition global.c:192
gchar * PACKAGE_SGCF
Definition global.c:126
gchar * PACKAGE_DFBD
Definition global.c:119
gchar * PACKAGE_CON
Definition global.c:91
gchar * PACKAGE_SGHP
Definition global.c:127
gchar * PACKAGE_OGL
Definition global.c:103
gchar * PACKAGE_DOTF
Definition global.c:116
gchar * PACKAGE_EPS
Definition global.c:95
gchar * PACKAGE_DOTA
Definition global.c:111
gchar * PACKAGE_OGLM
Definition global.c:104
gchar * PACKAGE_SGOC
Definition global.c:133
gchar * projfile
Definition global.c:144
gchar * PACKAGE_SGOF
Definition global.c:134
gboolean atomes_render_image
Definition global.c:196
gchar * PACKAGE_SGOP
Definition global.c:131
gchar * PACKAGE_OGLC
Definition global.c:105
int * allocint(int val)
allocate an int * pointer
Definition global.c:302
gchar * PACKAGE_TD
Definition global.c:101
gchar * PACKAGE_SVG
Definition global.c:94
gchar * PACKAGE_SGTC
Definition global.c:137
gchar * PACKAGE_SGCP
Definition global.c:124
gchar * PACKAGE_PRO
Definition global.c:106
gchar * PACKAGE_LABOUT
Definition global.c:110
gchar * ATOMES_CONFIG_DIR
Definition global.c:138
int atomes_visual
Definition global.c:168
gchar * PACKAGE_MOL
Definition global.c:102
gchar * PACKAGE_VOID
Definition global.c:100
gchar * PACKAGE_DOTB
Definition global.c:112
GtkApplication * atomes_app
Definition global.c:207
gchar * PACKAGE_PDF
Definition global.c:93
double string_to_double(gpointer string)
convert string to double
Definition global.c:612
gchar * PACKAGE_SGOI
Definition global.c:132
gchar * PACKAGE_JPG
Definition global.c:97
gchar * PACKAGE_SGCI
Definition global.c:125
gchar * PACKAGE_DOTD
Definition global.c:114
gboolean atomes_from_libreoffice
Definition global.c:195
gchar * PACKAGE_PNG
Definition global.c:96
Global variable declarations Global convenience function declarations Global data structure defin...
#define NONE
Definition global.h:285
@ CONTAINER_WIN
Definition global.h:267
GtkWidget * new_gtk_window()
create a new GtkWindow
Definition gtk-misc.c:389
GtkWidget * destroy_this_widget(GtkWidget *widg)
destroy a GtkWidget
Definition gtk-misc.c:2213
void provide_gtk_css(gchar *css)
create a css provider based on the css data
Definition gtk-misc.c:2185
void add_container_child(int type, GtkWidget *widg, GtkWidget *child)
Add a GtkWidget into another GtkWidget.
Definition gtk-misc.c:267
project * active_project
Definition project.c:47
void show_the_widgets(GtkWidget *widg)
show GtkWidget
Definition gtk-misc.c:202
Variable declarations related to the OpenGL window Function declarations related to the OpenGL wind...
@ PERSPECTIVE
Definition glview.h:161
@ ORTHOGRAPHIC
Definition glview.h:160
@ SPHERES
Definition glview.h:184
@ BALL_AND_STICK
Definition glview.h:181
@ CYLINDERS
Definition glview.h:185
@ WIREFRAME
Definition glview.h:182
@ PUNT
Definition glview.h:186
#define OGL_STYLES
Definition glwin.h:107
ColRGBA * render_image_grad_color[2]
Definition image.c:86
ColRGBA * render_image_box_color
Definition image.c:87
ColRGBA * render_image_back_color
Definition image.c:82
int render_image_rep
Definition image.c:77
int * render_image_pixels
Definition image.c:88
int render_image_pcolor
Definition image.c:79
int render_image_back_grad
Definition image.c:83
gboolean trigger_fragment_analysis
Definition image.c:80
int render_image_acolor
Definition image.c:78
float render_image_back_pos
Definition image.c:85
int render_image_axis
Definition image.c:75
int render_image_back_dir
Definition image.c:84
int render_image_format
Definition image.c:73
int render_image_box
Definition image.c:76
gchar * render_image_output
Definition image.c:89
gboolean trigger_molecule_analysis
Definition image.c:81
int render_image_style
Definition image.c:74
void init_project(gboolean alloc_box)
initialize a new project
Definition init_p.c:273
void show_error(char *error, int val, GtkWidget *win)
show error message
Definition interface.c:299
Messaging function declarations.
int get_color_map_from_string(gchar *col_string)
retrieve color map from command line string
Definition main.c:434
int get_rep_from_string(gchar *rep_string)
retrieve representation style from command line string
Definition main.c:389
int main(int argc, char *argv[])
initialization of the atomes program
Definition main.c:1603
int check_opengl_rendering()
check the initialization parameters for an OpenGL context
Definition main.c:1520
int test_this_arg(gchar *arg)
test an argument from the command line
Definition main.c:318
struct file_list * flist
Definition main.c:112
int get_box_axis_from_string(gchar *box_axis_string)
retrieve box or axis style from command line string
Definition main.c:405
int get_file_format_from_string(gchar *file_format_string)
retrieve file format for convertion from command line string
Definition main.c:419
gchar * xyz_files[]
Definition main.c:129
struct file_list * ftmp
Definition main.c:113
GtkWidget * create_splash_window()
create splash screen window
Definition main.c:851
gchar * wi_styles[]
Definition main.c:121
gchar * sp_styles[]
Definition main.c:126
gchar * bs_styles[]
Definition main.c:116
void print_version()
print version information
Definition main.c:213
ColRGBA * get_color_from_hexa_string(gchar *color_string)
convert Hexadecimal string to ColRGBA
Definition main.c:456
void set_atomes_locale()
set locale
Definition main.c:572
gboolean is_string_in_string_list(gchar *string, gchar **list)
check if a string is in a list of strings
Definition main.c:345
gchar * sml_files[]
Definition main.c:131
int get_gradient_from_string(gchar *grad_string)
retrieve background gradient from command line string
Definition main.c:513
gchar * vw_styles[]
Definition main.c:124
void print_help()
print basic help
Definition main.c:138
GtkWidget * create_main_window(GApplication *app)
create the main application window
Definition gui.c:1087
gboolean destroy_func(gpointer user_data)
destroy splash screen
Definition main.c:821
gchar * cr_styles[]
Definition main.c:125
int parse_command_line(int argc, char *argv[])
test command line arguments
Definition main.c:589
gchar * cy_styles[]
Definition main.c:127
gchar * c3d_files[]
Definition main.c:130
int test_this_ext(int len, gchar *arg)
test extension of an argument from the command line
Definition main.c:297
G_MODULE_EXPORT void run_program(GApplication *app, gpointer data)
run the program
Definition main.c:1431
void open_this_data_file(int file_type, gchar *file_name)
open data file from the command line
Definition main.c:920
gchar * do_styles[]
Definition main.c:128
gchar * co_styles[]
Definition main.c:122
int check_for_atomes_file_options(int start, int end, char *argv[])
retrieve the list of files to read from the command line leave out all other options
Definition main.c:534
void read_this_file(int file_type, gchar *this_file)
read file from the command line
Definition main.c:889
int get_style_from_string(gchar *style_string)
retrieve style from command line string
Definition main.c:368
gboolean with_workspace
Definition main.c:114
gchar * io_styles[]
Definition main.c:123
Data structure declarations for movie encoding Function declarations for movie encoding.
void set_atomes_preferences()
set software default parameters
int default_instance
Preference variable declarations.
Function declarations for reading atomes project file Function declarations for saving atomes proje...
gboolean reading_project
Definition read_curve.c:43
struct file_list * next
Definition main.c:109
gchar * file_name
Definition main.c:107
int file_type
Definition main.c:108
Definition glwin.h:364
int status
Definition w_advance.c:173
GtkWidget * res[2]
Definition w_encode.c:342
GdkPixbuf * pix
Definition workspace.c:69
Function declarations for workspace managment.