@@ -2,22 +2,45 @@ module fortplot_system_viewer
22    ! ! System viewer launching for show() functionality
33    ! ! Handles platform-specific viewer launching and graphical session detection
44    use , intrinsic  ::  iso_fortran_env, only: wp = > real64
5+     use , intrinsic  ::  iso_c_binding, only: c_int
56    use  fortplot_logging, only: log_info, log_error
67    implicit none 
78    private 
89
910    public  ::  launch_system_viewer
1011    public  ::  has_graphical_session
12+     public  ::  get_temp_filename
13+     public  ::  cleanup_temp_file
14+ 
15+     interface 
16+         function  c_getpid () bind(C, name= " getpid" 
17+             import ::  c_int
18+             integer (c_int) ::  pid
19+         end  function  c_getpid 
20+     end interface 
1121
1222contains 
1323
1424    function  has_graphical_session () result(has_display)
1525        ! ! Check if a graphical session is available
16-         ! ! Returns .true. if X11, Wayland, or other display is  available
26+         ! ! Returns .true. if X11, Wayland, macOS GUI, or Windows GUI  available
1727        logical  ::  has_display
18-         character (len= 256 ) ::  display_var, wayland_var, session_type
28+         character (len= 256 ) ::  display_var, wayland_var, session_type, ssh_var
29+         character (len= 32 ) ::  os_type
1930
2031        has_display =  .false. 
32+         os_type =  get_os_type()
33+ 
34+         if  (trim (os_type) == ' windows' then 
35+             has_display =  .true. 
36+             return 
37+         end if 
38+ 
39+         if  (trim (os_type) == ' darwin' then 
40+             call  get_environment_variable(' SSH_CONNECTION' 
41+             has_display =  len_trim (ssh_var) == 0 
42+             return 
43+         end if 
2144
2245        call  get_environment_variable(' DISPLAY' 
2346        if  (len_trim (display_var) > 0 ) then 
@@ -89,37 +112,107 @@ end function get_viewer_command
89112    function  get_os_type () result(os_type)
90113        ! ! Detect operating system type
91114        character (len= 32 ) ::  os_type
92-         character (len= 256 ) ::  ostype_var
93-         integer  ::  stat
115+         character (len= 256 ) ::  ostype_var, uname_s
116+         integer  ::  stat, uname_unit, ios
117+ 
118+         call  get_environment_variable(' OS' 
119+         if  (index (ostype_var, ' Windows' 0 ) then 
120+             os_type =  ' windows' 
121+             return 
122+         end if 
123+ 
124+         call  execute_command_line(' uname -s > /tmp/fortplot_uname.txt' = stat)
125+         if  (stat == 0 ) then 
126+             open (newunit= uname_unit, file= ' /tmp/fortplot_uname.txt' = ' old' = ios)
127+             if  (ios == 0 ) then 
128+                 read (uname_unit, ' (A)' = ios) uname_s
129+                 close (uname_unit, status= ' delete' 
130+                 if  (index (uname_s, ' Darwin' 0 ) then 
131+                     os_type =  ' darwin' 
132+                     return 
133+                 else  if  (index (uname_s, ' Linux' 0 ) then 
134+                     os_type =  ' linux' 
135+                     return 
136+                 end if 
137+             end if 
138+         end if 
94139
95140        call  get_environment_variable(' OSTYPE' 
96-         if  (len_trim (ostype_var) > 0 ) then 
97-             if  (index (ostype_var, ' linux' 0 ) then 
98-                 os_type =  ' linux' 
99-                 return 
100-             else  if  (index (ostype_var, ' darwin' 0 ) then 
101-                 os_type =  ' darwin' 
141+         if  (index (ostype_var, ' darwin' 0  .or.  index (ostype_var, ' Darwin' 0 ) then 
142+             os_type =  ' darwin' 
143+         else  if  (index (ostype_var, ' linux' 0  .or.  index (ostype_var, ' Linux' 0 ) then 
144+             os_type =  ' linux' 
145+         else  if  (index (ostype_var, ' win' 0  .or.  index (ostype_var, ' msys' 0 ) then 
146+             os_type =  ' windows' 
147+         else 
148+             os_type =  ' linux' 
149+         end if 
150+     end  function  get_os_type 
151+ 
152+     function  get_temp_dir () result(tempdir)
153+         ! ! Get platform-specific temporary directory
154+         character (len= 256 ) ::  tempdir
155+         character (len= 256 ) ::  temp_env
156+         character (len= 32 ) ::  os_type
157+ 
158+         os_type =  get_os_type()
159+ 
160+         if  (trim (os_type) == ' windows' then 
161+             call  get_environment_variable(' TEMP' 
162+             if  (len_trim (temp_env) > 0 ) then 
163+                 tempdir =  trim (temp_env)
102164                return 
103-             else  if  (index (ostype_var, ' win' 0  .or.  index (ostype_var, ' msys' 0 ) then 
104-                 os_type =  ' windows' 
165+             end if 
166+             call  get_environment_variable(' TMP' 
167+             if  (len_trim (temp_env) > 0 ) then 
168+                 tempdir =  trim (temp_env)
105169                return 
106170            end if 
171+             tempdir =  ' C:\Temp' 
172+         else 
173+             tempdir =  ' /tmp' 
107174        end if 
175+     end  function  get_temp_dir 
176+ 
177+     subroutine  get_temp_filename (extension , filename )
178+         ! ! Generate unique temporary filename with proper platform handling
179+         character (len=* ), intent (in ) ::  extension
180+         character (len=* ), intent (out ) ::  filename
181+         character (len= 256 ) ::  tempdir
182+         character (len= 1 ) ::  sep
183+         character (len= 32 ) ::  os_type
184+         integer (c_int) ::  pid
185+         integer  ::  clk_count, clk_rate, clk_max
108186
109-         call  execute_command_line(' uname' = stat)
110-         if  (stat == 0 ) then 
111-             os_type =  ' linux' 
112-             return 
113-         end if 
187+         tempdir =  get_temp_dir()
188+         os_type =  get_os_type()
189+         pid =  c_getpid()
190+         call  system_clock (clk_count, clk_rate, clk_max)
114191
115-         call  get_environment_variable( ' OS ' , ostype_var) 
116-         if  ( index (ostype_var,  ' Windows ' ) >  0 )  then 
117-             os_type  =   ' windows ' 
118-             return 
192+         if  ( trim (os_type) ==  ' windows ' )  then 
193+             sep  =   ' \ ' 
194+         else 
195+             sep  =   ' / ' 
119196        end if 
120197
121-         os_type =  ' linux' 
122-     end  function  get_os_type 
198+         write (filename, ' (A,A,A,I0,A,I0,A)' trim (tempdir), sep, ' fortplot_show_' 
199+               int (pid), ' _' trim (extension)
200+     end  subroutine  get_temp_filename 
201+ 
202+     subroutine  cleanup_temp_file (filename )
203+         ! ! Remove temporary file (best effort, no error on failure)
204+         character (len=* ), intent (in ) ::  filename
205+         integer  ::  stat
206+         logical  ::  exists
207+ 
208+         inquire (file= trim (filename), exist= exists)
209+         if  (exists) then 
210+             open (newunit= stat, file= trim (filename), status= ' old' = stat)
211+             if  (stat == 0 ) then 
212+                 close (stat, status= ' delete' = stat)
213+             end if 
214+         end if 
215+     end  subroutine  cleanup_temp_file 
123216
124217    function  int_to_str (i ) result(str)
125218        ! ! Convert integer to string
0 commit comments