void GEUIDialog::SaveViewAsKmz( wxString filename, wxString viewname ) { //TODO: - kml, jpg, zip it wxFileName fn(filename); wxFFileOutputStream out(filename); wxZipOutputStream zip(out); double west, east, north, south, lat, lon, alt; bool proj, exa; GEGetPointOnTerrain(GE_SCR_UPCENTER, north, lon, alt, proj, exa); GEGetPointOnTerrain(GE_SCR_LOWCENTER, south, lon, alt, proj, exa); GEGetPointOnTerrain(GE_SCR_LEFTCENTER, lat, west, alt, proj, exa); GEGetPointOnTerrain(GE_SCR_RIGHTCENTER, lat, east, alt, proj, exa); wxString tempimg = wxFileName::CreateTempFileName(_T("gecomapi")); SaveViewAsJPG(tempimg); zip.PutNextEntry(wxString::Format(_T("files/%s.jpg"), fn.GetName())); wxFileInputStream stream(tempimg); zip.Write(stream); zip.PutNextEntry(_T("doc.kml")); wxCharBuffer buffer; buffer = wxConvertWX2MB(wxString::Format(_T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\"><GroundOverlay><name>%s</name><Icon><href>files/%s.jpg</href><drawOrder>0</drawOrder></Icon><LatLonBox><north>%f</north><south>%f</south><east>%f</east><west>%f</west><rotation>%f</rotation></LatLonBox></GroundOverlay></kml>"), encodeXMLEntities(viewname), fn.GetName(), north, south, east, west, 0.0)); zip.Write(buffer.data(), strlen(buffer.data())); wxRemoveFile(tempimg); }
bool wxGetFullHostName(wxChar *buf, int sz) { bool ok = wxGetHostNameInternal(buf, sz); if ( ok ) { if ( !wxStrchr(buf, wxT('.')) ) { struct hostent *host = gethostbyname(wxConvertWX2MB(buf)); if ( !host ) { wxLogSysError(_("Cannot get the official hostname")); ok = false; } else { // the canonical name wxStrncpy(buf, wxConvertMB2WX(host->h_name), sz); } } //else: it's already a FQDN (BSD behaves this way) } return ok; }
wxNativeFont wxLoadFont(const wxString& fontSpec) { // VZ: we should use gdk_fontset_load() instead of gdk_font_load() // here to be able to display Japanese fonts correctly (at least // this is what people report) but unfortunately doing it results // in tons of warnings when using GTK with "normal" European // languages and so we can't always do it and I don't know enough // to determine when should this be done... (FIXME) return gdk_font_load( wxConvertWX2MB(fontSpec) ); }
char *wxGetUserHome( const wxString &user ) #endif { struct passwd *who = (struct passwd *) NULL; if ( !user ) { wxChar *ptr; if ((ptr = wxGetenv(wxT("HOME"))) != NULL) { #if wxUSE_UNICODE wxWCharBuffer buffer( ptr ); return buffer; #else return ptr; #endif } if ((ptr = wxGetenv(wxT("USER"))) != NULL || (ptr = wxGetenv(wxT("LOGNAME"))) != NULL) { who = getpwnam(wxConvertWX2MB(ptr)); } // We now make sure the the user exists! if (who == NULL) { who = getpwuid(getuid()); } } else { who = getpwnam (user.mb_str()); } return wxConvertMB2WX(who ? who->pw_dir : 0); }
long wxExecute(wxChar **argv, int flags, wxProcess *process) { // for the sync execution, we return -1 to indicate failure, but for async // case we return 0 which is never a valid PID // // we define this as a macro, not a variable, to avoid compiler warnings // about "ERROR_RETURN_CODE value may be clobbered by fork()" #define ERROR_RETURN_CODE ((flags & wxEXEC_SYNC) ? -1 : 0) wxCHECK_MSG( *argv, ERROR_RETURN_CODE, wxT("can't exec empty command") ); #if wxUSE_UNICODE int mb_argc = 0; char *mb_argv[WXEXECUTE_NARGS]; while (argv[mb_argc]) { wxWX2MBbuf mb_arg = wxConvertWX2MB(argv[mb_argc]); mb_argv[mb_argc] = strdup(mb_arg); mb_argc++; } mb_argv[mb_argc] = (char *) NULL; // this macro will free memory we used above #define ARGS_CLEANUP \ for ( mb_argc = 0; mb_argv[mb_argc]; mb_argc++ ) \ free(mb_argv[mb_argc]) #else // ANSI // no need for cleanup #define ARGS_CLEANUP wxChar **mb_argv = argv; #endif // Unicode/ANSI // we want this function to work even if there is no wxApp so ensure that // we have a valid traits pointer wxConsoleAppTraits traitsConsole; wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL; if ( !traits ) traits = &traitsConsole; // this struct contains all information which we pass to and from // wxAppTraits methods wxExecuteData execData; execData.flags = flags; execData.process = process; // create pipes if ( !traits->CreateEndProcessPipe(execData) ) { wxLogError( _("Failed to execute '%s'\n"), *argv ); ARGS_CLEANUP; return ERROR_RETURN_CODE; } // pipes for inter process communication wxPipe pipeIn, // stdin pipeOut, // stdout pipeErr; // stderr if ( process && process->IsRedirected() ) { if ( !pipeIn.Create() || !pipeOut.Create() || !pipeErr.Create() ) { wxLogError( _("Failed to execute '%s'\n"), *argv ); ARGS_CLEANUP; return ERROR_RETURN_CODE; } } // fork the process // // NB: do *not* use vfork() here, it completely breaks this code for some // reason under Solaris (and maybe others, although not under Linux) // But on OpenVMS we do not have fork so we have to use vfork and // cross our fingers that it works. #ifdef __VMS pid_t pid = vfork(); #else pid_t pid = fork(); #endif if ( pid == -1 ) // error? { wxLogSysError( _("Fork failed") ); ARGS_CLEANUP; return ERROR_RETURN_CODE; } else if ( pid == 0 ) // we're in child { // These lines close the open file descriptors to to avoid any // input/output which might block the process or irritate the user. If // one wants proper IO for the subprocess, the right thing to do is to // start an xterm executing it. if ( !(flags & wxEXEC_SYNC) ) { // FD_SETSIZE is unsigned under BSD, signed under other platforms // so we need a cast to avoid warnings on all platforms for ( int fd = 0; fd < (int)FD_SETSIZE; fd++ ) { if ( fd == pipeIn[wxPipe::Read] || fd == pipeOut[wxPipe::Write] || fd == pipeErr[wxPipe::Write] || traits->IsWriteFDOfEndProcessPipe(execData, fd) ) { // don't close this one, we still need it continue; } // leave stderr opened too, it won't do any harm if ( fd != STDERR_FILENO ) close(fd); } } #if !defined(__VMS) && !defined(__EMX__) if ( flags & wxEXEC_MAKE_GROUP_LEADER ) { // Set process group to child process' pid. Then killing -pid // of the parent will kill the process and all of its children. setsid(); } #endif // !__VMS // reading side can be safely closed but we should keep the write one // opened traits->DetachWriteFDOfEndProcessPipe(execData); // redirect stdin, stdout and stderr if ( pipeIn.IsOk() ) { if ( dup2(pipeIn[wxPipe::Read], STDIN_FILENO) == -1 || dup2(pipeOut[wxPipe::Write], STDOUT_FILENO) == -1 || dup2(pipeErr[wxPipe::Write], STDERR_FILENO) == -1 ) { wxLogSysError(_("Failed to redirect child process input/output")); } pipeIn.Close(); pipeOut.Close(); pipeErr.Close(); } execvp (*mb_argv, mb_argv); fprintf(stderr, "execvp("); // CS changed ppc to ppc_ as ppc is not available under mac os CW Mach-O for ( char **ppc_ = mb_argv; *ppc_; ppc_++ ) fprintf(stderr, "%s%s", ppc_ == mb_argv ? "" : ", ", *ppc_); fprintf(stderr, ") failed with error %d!\n", errno); // there is no return after successful exec() _exit(-1); // some compilers complain about missing return - of course, they // should know that exit() doesn't return but what else can we do if // they don't? // // and, sure enough, other compilers complain about unreachable code // after exit() call, so we can just always have return here... #if defined(__VMS) || defined(__INTEL_COMPILER) return 0; #endif } else // we're in parent { ARGS_CLEANUP; // save it for WaitForChild() use execData.pid = pid; // prepare for IO redirection #if wxUSE_STREAMS // the input buffer bufOut is connected to stdout, this is why it is // called bufOut and not bufIn wxStreamTempInputBuffer bufOut, bufErr; #endif // wxUSE_STREAMS if ( process && process->IsRedirected() ) { #if wxUSE_STREAMS wxOutputStream *inStream = new wxFileOutputStream(pipeIn.Detach(wxPipe::Write)); wxPipeInputStream *outStream = new wxPipeInputStream(pipeOut.Detach(wxPipe::Read)); wxPipeInputStream *errStream = new wxPipeInputStream(pipeErr.Detach(wxPipe::Read)); process->SetPipeStreams(outStream, inStream, errStream); bufOut.Init(outStream); bufErr.Init(errStream); execData.bufOut = &bufOut; execData.bufErr = &bufErr; #endif // wxUSE_STREAMS } if ( pipeIn.IsOk() ) { pipeIn.Close(); pipeOut.Close(); pipeErr.Close(); } return traits->WaitForChild(execData); } return ERROR_RETURN_CODE; }
long wxExecute(wxChar **argv, int flags, wxProcess *process) { // for the sync execution, we return -1 to indicate failure, but for async // case we return 0 which is never a valid PID // // we define this as a macro, not a variable, to avoid compiler warnings // about "ERROR_RETURN_CODE value may be clobbered by fork()" #define ERROR_RETURN_CODE ((flags & wxEXEC_SYNC) ? -1 : 0) wxCHECK_MSG( *argv, ERROR_RETURN_CODE, wxT("can't exec empty command") ); #if wxUSE_UNICODE int mb_argc = 0; char *mb_argv[WXEXECUTE_NARGS]; while (argv[mb_argc]) { wxWX2MBbuf mb_arg = wxConvertWX2MB(argv[mb_argc]); mb_argv[mb_argc] = strdup(mb_arg); mb_argc++; } mb_argv[mb_argc] = (char *) NULL; // this macro will free memory we used above #define ARGS_CLEANUP \ for ( mb_argc = 0; mb_argv[mb_argc]; mb_argc++ ) \ free(mb_argv[mb_argc]) #else // ANSI // no need for cleanup #define ARGS_CLEANUP wxChar **mb_argv = argv; #endif // Unicode/ANSI #if wxUSE_GUI && !defined(__DARWIN__) // create pipes wxPipe pipeEndProcDetect; if ( !pipeEndProcDetect.Create() ) { wxLogError( _("Failed to execute '%s'\n"), *argv ); ARGS_CLEANUP; return ERROR_RETURN_CODE; } #endif // wxUSE_GUI && !defined(__DARWIN__) // pipes for inter process communication wxPipe pipeIn, // stdin pipeOut, // stdout pipeErr; // stderr if ( process && process->IsRedirected() ) { if ( !pipeIn.Create() || !pipeOut.Create() || !pipeErr.Create() ) { wxLogError( _("Failed to execute '%s'\n"), *argv ); ARGS_CLEANUP; return ERROR_RETURN_CODE; } } // fork the process // // NB: do *not* use vfork() here, it completely breaks this code for some // reason under Solaris (and maybe others, although not under Linux) // But on OpenVMS we do not have fork so we have to use vfork and // cross our fingers that it works. #ifdef __VMS pid_t pid = vfork(); #else pid_t pid = fork(); #endif if ( pid == -1 ) // error? { wxLogSysError( _("Fork failed") ); ARGS_CLEANUP; return ERROR_RETURN_CODE; } else if ( pid == 0 ) // we're in child { // These lines close the open file descriptors to to avoid any // input/output which might block the process or irritate the user. If // one wants proper IO for the subprocess, the right thing to do is to // start an xterm executing it. if ( !(flags & wxEXEC_SYNC) ) { for ( int fd = 0; fd < FD_SETSIZE; fd++ ) { if ( fd == pipeIn[wxPipe::Read] || fd == pipeOut[wxPipe::Write] || fd == pipeErr[wxPipe::Write] #if wxUSE_GUI && !defined(__DARWIN__) || fd == pipeEndProcDetect[wxPipe::Write] #endif // wxUSE_GUI && !defined(__DARWIN__) ) { // don't close this one, we still need it continue; } // leave stderr opened too, it won't do any harm if ( fd != STDERR_FILENO ) close(fd); } } #if !defined(__VMS) && !defined(__EMX__) if ( flags & wxEXEC_MAKE_GROUP_LEADER ) { // Set process group to child process' pid. Then killing -pid // of the parent will kill the process and all of its children. setsid(); } #endif // !__VMS #if wxUSE_GUI && !defined(__DARWIN__) // reading side can be safely closed but we should keep the write one // opened pipeEndProcDetect.Detach(wxPipe::Write); pipeEndProcDetect.Close(); #endif // wxUSE_GUI && !defined(__DARWIN__) // redirect stdin, stdout and stderr if ( pipeIn.IsOk() ) { if ( dup2(pipeIn[wxPipe::Read], STDIN_FILENO) == -1 || dup2(pipeOut[wxPipe::Write], STDOUT_FILENO) == -1 || dup2(pipeErr[wxPipe::Write], STDERR_FILENO) == -1 ) { wxLogSysError(_("Failed to redirect child process input/output")); } pipeIn.Close(); pipeOut.Close(); pipeErr.Close(); } execvp (*mb_argv, mb_argv); fprintf(stderr, "execvp("); for ( char **ppc = mb_argv; *ppc; ppc++ ) fprintf(stderr, "%s%s", ppc == mb_argv ? "" : ", ", *ppc); fprintf(stderr, ") failed with error %d!\n", errno); // there is no return after successful exec() _exit(-1); // some compilers complain about missing return - of course, they // should know that exit() doesn't return but what else can we do if // they don't? // // and, sure enough, other compilers complain about unreachable code // after exit() call, so we can just always have return here... #if defined(__VMS) || defined(__INTEL_COMPILER) return 0; #endif } else // we're in parent { ARGS_CLEANUP; // prepare for IO redirection #if wxUSE_STREAMS // the input buffer bufOut is connected to stdout, this is why it is // called bufOut and not bufIn wxStreamTempInputBuffer bufOut, bufErr; #endif // wxUSE_STREAMS if ( process && process->IsRedirected() ) { #if wxUSE_STREAMS wxOutputStream *inStream = new wxFileOutputStream(pipeIn.Detach(wxPipe::Write)); wxPipeInputStream *outStream = new wxPipeInputStream(pipeOut.Detach(wxPipe::Read)); wxPipeInputStream *errStream = new wxPipeInputStream(pipeErr.Detach(wxPipe::Read)); process->SetPipeStreams(outStream, inStream, errStream); bufOut.Init(outStream); bufErr.Init(errStream); #endif // wxUSE_STREAMS } if ( pipeIn.IsOk() ) { pipeIn.Close(); pipeOut.Close(); pipeErr.Close(); } #if wxUSE_GUI && !defined(__WXMICROWIN__) wxEndProcessData *data = new wxEndProcessData; // wxAddProcessCallback is now (with DARWIN) allowed to call the // callback function directly if the process terminates before // the callback can be added to the run loop. Set up the data. if ( flags & wxEXEC_SYNC ) { // we may have process for capturing the program output, but it's // not used in wxEndProcessData in the case of sync execution data->process = NULL; // sync execution: indicate it by negating the pid data->pid = -pid; } else { // async execution, nothing special to do - caller will be // notified about the process termination if process != NULL, data // will be deleted in GTK_EndProcessDetector data->process = process; data->pid = pid; } #if defined(__DARWIN__) data->tag = wxAddProcessCallbackForPid(data,pid); #else data->tag = wxAddProcessCallback ( data, pipeEndProcDetect.Detach(wxPipe::Read) ); pipeEndProcDetect.Close(); #endif // defined(__DARWIN__) if ( flags & wxEXEC_SYNC ) { wxBusyCursor bc; wxWindowDisabler wd; // data->pid will be set to 0 from GTK_EndProcessDetector when the // process terminates while ( data->pid != 0 ) { #if wxUSE_STREAMS bufOut.Update(); bufErr.Update(); #endif // wxUSE_STREAMS // give GTK+ a chance to call GTK_EndProcessDetector here and // also repaint the GUI wxYield(); } int exitcode = data->exitcode; delete data; return exitcode; } else // async execution { return pid; } #else // !wxUSE_GUI wxASSERT_MSG( flags & wxEXEC_SYNC, wxT("async execution not supported yet") ); int exitcode = 0; if ( waitpid(pid, &exitcode, 0) == -1 || !WIFEXITED(exitcode) ) { wxLogSysError(_("Waiting for subprocess termination failed")); } return exitcode; #endif // wxUSE_GUI } return ERROR_RETURN_CODE; }