I would like to know a way to open the default browser on OS X from a C++ application and then open a requested URL.
EDIT: I solved it like this:
system("open http://www.apple.com");
In case you prefer using the native OS X APIs instead of system("open ...")
You can use this code:
#include <string>
#include <CoreFoundation/CFBundle.h>
#include <ApplicationServices/ApplicationServices.h>
using namespace std;
void openURL(const string &url_str) {
CFURLRef url = CFURLCreateWithBytes (
NULL, // allocator
(UInt8*)url_str.c_str(), // URLBytes
url_str.length(), // length
kCFStringEncodingASCII, // encoding
NULL // baseURL
);
LSOpenCFURLRef(url,0);
CFRelease(url);
}
int main() {
string str("http://www.example.com");
openURL(str);
}
Which you have to compile with the proper OS X frameworks:
g++ file.cpp -framework CoreFoundation -framework ApplicationServices
Look at the docs for Launch Services.
Related
I need to get the keyboard layout being used on Mac OS X. I've found old restonces to this but they all are something like this:
How to change the Mac OS X Keyboard Layout programmatically?
which doesn't work any more. Any help would be much appreciated.
In case someone is interested, I was finally able to get the keyboard layout with the following code:
#include <Carbon/Carbon.h>
int main() {
char layout[128];
memset(layout, '\0', sizeof(layout));
TISInputSourceRef source = TISCopyCurrentKeyboardInputSource();
// get input source id - kTISPropertyInputSourceID
// get layout name - kTISPropertyLocalizedName
CFStringRef layoutID = TISGetInputSourceProperty(source, kTISPropertyInputSourceID);
CFStringGetCString(layoutID, layout, sizeof(layout), kCFStringEncodingUTF8);
printf("%s\n", layout);
return 0;
}
Compiled with:
gcc -o test2 test2.c -framework Carbon
I would try this:
#import <Carbon/Carbon.h>
TISInputSourceRef source = TISCopyCurrentKeyboardInputSource();
NSString *s = (__bridge NSString *)(TISGetInputSourceProperty(source, kTISPropertyInputSourceID));
I've been writing a program that needs a wine version of 2.6 or later. I'd like to get it as a boolean, so I've been trying to use the code below:
#include <string>
#include <iostream>
#include "WineCheck.h"
#include <cstdlib>
using namespace std;
bool checkForWine()
{
// Create variables for checking wine state
bool wineIsThere = false;
bool wineIsVersion = false;
// Check dpkg if wine is there
if (string(system("dpkg -l | cut -c 4-9 | grep \\ wine\\ ")) == " wine ")
{
wineIsThere = true;
// Check version
if (double(system("wine --version | cut -c 6-8")) >= 2.6)
wineIsVersion = true;
}
// Return
if (wineIsThere && wineIsVersion)
return true;
else
return false;
}
First, it's my opinion you shouldn't bother with this. Wine 2.6 should just be included as a dependency in your configuration script, and/or your package file. Targeting a specific package management system in your program source code is not a good idea if you want to maintain portability to other GNU/Linux distributions that don't use that packager.
To answer your question though. There are two ways I found you can do this. You can check /var/lib/dpkg/status. Read through the file line by line until you get to this section. If you don't find the section, or the Status: ... line doesn't say installed then wine is not installed. The Version: ... line will tell you what version is installed. I verified this method works by installing and uninstalling Wine on Debian Wheezy. You didn't say what distro you're working with, but it's obvious you're using the Debian Packaging system, so this should work on Ubuntu and other Debian based distributions as well.
$cat /var/lib/dpkg/status
...
Package: wine
Status: install ok installed
Priority: optional
Section: otherosf
Installed-Size: 80
Maintainer: Debian Wine Party <pkg-wine-party#lists.alioth.debian.org>
Architecture: amd64
Version: 1.4.1-4
...
The other option is use libdpkg. I found an example that lists all installed packages.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/pkg-array.h>
#include "filesdb.h"
const char thisname[] = "example1";
int
main(int argc, const char *const *argv)
{
struct pkg_array array;
struct pkginfo *pkg;
int i;
enum modstatdb_rw msdb_status;
standard_startup();
filesdbinit();
msdb_status = modstatdb_open(msdbrw_readonly);
pkg_infodb_init(msdb_status);
pkg_array_init_from_db(&array);
pkg_array_sort(&array, pkg_sorter_by_name);
for (i = 0; i < array.n_pkgs; i++) {
pkg = array.pkgs[i];
if (pkg->status == stat_notinstalled)
continue;
printf("Package --> %s\n", pkg->set->name);
}
pkg_array_destroy(&array);
modstatdb_shutdown();
standard_shutdown();
}
I foud out there is a new Boost.Process 0.5 but I cant see how to execute across Windows Linux and Mac ping or echo.
I got it working at leaast on Windows with simple:
#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/process.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/error_code.hpp>
namespace bp = boost::process;
namespace bpi = boost::process::initializers;
namespace bio = boost::iostreams;
int main()
{
bp::pipe p = bp::create_pipe();
{
bio::file_descriptor_sink sink(p.sink, bio::close_handle);
boost::filesystem::path p("C:/Windows/System32/cmd.exe");
boost::system::error_code ec;
bp::execute(
bpi::run_exe(p),
bpi::set_cmd_line(L"cmd /c echo --echo-stderr hello"),
bpi::bind_stdout(sink),
bpi::set_on_error(ec)
);
}
bio::file_descriptor_source source(p.source, bio::close_handle);
bio::stream<bio::file_descriptor_source> is(source);
std::string s;
is >> s;
std::cout << s << std::endl;
std::cin.get();
return 0;
}
On windows this works correctly but how to make it crossplatform to work also on Mac and Linux? (I am stupid and do not know how to write one path that would work for any Unix terminal (or at least for Linux Bash and mac default one)) So How to run commandline/terminal utils with Boost.Process 0.5 on Windows and Unix like OSs (better not writing path to terminal each time but just writting app like echo or ping and its arguments)?
...Found related code inside prevoius version:
std::string exe;
std::vector<std::string> args;
#if defined(BOOST_POSIX_API)
exe = "/bin/sh";
args.push_back("sh");
args.push_back("-c");
args.push_back(command);
#elif defined(BOOST_WINDOWS_API)
char sysdir[MAX_PATH];
UINT size = ::GetSystemDirectoryA(sysdir, sizeof(sysdir));
if (!size)
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_shell: GetWindowsDirectory failed"));
BOOST_ASSERT(size < MAX_PATH);
exe = std::string(sysdir) + (sysdir[size - 1] != '\\' ? "\\cmd.exe" : "cmd.exe");
args.push_back("cmd");
args.push_back("/c");
args.push_back(command);
#endif
Under boost.process 0.5 the shell_path() API was introduced so might the following will hook you up
#if defined(BOOST_POSIX_API)
#define SHELL_COMMAND_PREFIX "-c"
#elif defined(BOOST_WINDOWS_API)
#define SHELL_COMMAND_PREFIX "/c"
#endif
filesystem::path shellPath = process::shell_path();
std::string cl = shell_path().string() + " " SHELL_COMMAND_PREFIX " ";
cl += "ping 127.0.0.1";
execute(
set_cmd_line(cl),
throw_on_error()
);
If you really want to hide the #ifdef, I'd go on and edit the boost sources to return also the relevant command prefix (adding new API) , open source after all isn't it ? :).
You could find the relevant sources to edit at boost/process/windows/shell_path.hpp and boost/process/posix/shell_path.hpp
I want to reposition a application window on the desktop using a c++ program .
How should i go about doing that , i need solution for both situations .
When i have the source of the application which want to move .
Move windows of other application by Writing an external program.
External Bash script:
xdotool search --onlyvisible --class dolphin windowmove 13 37
# ^ ^ ^
# window class X & Y coordinates
For more information about this, use xdotool search, xdotool windowmove and man xdotool.
C++ example:
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string cls="dolphin";
int x=13, y=37;
stringstream s;
s<<"xdotool search --onlyvisible --class "<<cls<<" windowmove "<<x<<" "<<y;
system(s.str().c_str());
return 0;
}
And bare minimum example:
#include <stdlib.h>
int main()
{
system("xdotool search --onlyvisible --class dolphin windowmove 13 37");
return 0;
}
I am using libconfig to read/wirte config files in my C++ game.
Right now I just have this one config file called video.cfg:
#Video config file
video:
{
fps:
{
limited = true;
value = 20;
};
};
This config file handles the video settings of the game.
I am trying to write a very basic console program that modifies this values based on user input. However I have no idea how to do this. I can't find anything in libconfig manual and nothing on Google.
So how do you edit values in Libconfig?
#include <libconfig.h>
int main() {
config_t cfg;
config_setting_t *vid_fps_lim = 0;
config_setting_t *vid_fps_val = 0;
config_init(&cfg);
if (config_read_file(&cfg, "myconfig") == CONFIG_TRUE) {
/* lookup the settings we want */
vid_fps_lim = config_lookup(&cfg, "video.fps.limited");
vid_fps_val = config_lookup(&cfg, "video.fps.value");
/* print the current settings */
printf("video.fps.limited = %i\n", config_setting_get_bool(vid_fps_lim));
printf("video.fps.value = %i\n", config_setting_get_int(vid_fps_val));
/* modify the settings */
config_setting_set_bool(vid_fps_lim, 1);
config_setting_set_int(vid_fps_val, 60);
/* write the modified config back */
config_write_file(&cfg, "myconfig");
}
config_destroy(&cfg);
return 0;
}
I named the file "lcex.c" and the config file "myconfig" It builds and runs on my Debian Linux machine using the following...
gcc `pkg-config --cflags libconfig` lcex.c -o lcex `pkg-config --libs libconfig`
./lcex
Open your config file after running the app and you should see that the values have been updated.
Disclaimer...error handling left out to make it easier to read. I didn't build with -Wall, etc. As with any API, read the docs and handle potential errors.
I came across this question while searching for a way to have libconfig write output to a string instead of a file. I see that there's no acceptable answer here, so I thought I would provide one for posterity, even though the question is over 3 years old.
#include <stdint.h>
#include <string>
#include "libconfig.h++"
int32_t
main (void) {
libconfig::Config config;
std::string file = "test.conf";
try {
config.readFile(file.c_str());
libconfig::Setting &limited = config.lookup("video.fps.limited");
libconfig::Setting &value = config.lookup("video.fps.value");
limited = false;
value = 60;
config.writeFile(file.c_str());
}
catch (...) {
// Do something reasonable with exceptions here. Do not catch (...)
}
return 0;
}
Hope that helps someone!