I'm trying to make my C++ program detect installed fonts on my Win32 machine. I tried fontconfig by taking the library from the GTK+ bundle.
I use the following test code:
#include<fontconfig.h>
FcBool success = FcInit ();
if ( !success ) {
return false;
}
FcConfig *config = FcInitLoadConfigAndFonts ();
if(!config) {
return false;
}
FcChar8 *s, *file;
FcPattern *p = FcPatternCreate();
FcObjectSet *os = FcObjectSetBuild (FC_FAMILY,NULL);
FcFontSet *fs = FcFontList(config, p, os);
LOG("Total fonts: %d\n", fs->nfont);
for (int i=0; fs && i < fs->nfont; i++) {
FcPattern *font = fs->fonts[i];
s = FcNameUnparse(font);
LOG("Font: %s\n", s);
free(s);
if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) {
LOG("Filename: %s\n", file);
}
}
// destroy objects here ...
Unfortunately this test application only prints:
Total fonts: 0
I know there are fonts installed on my machine and I know that Gimp2.0 detects them, so there must be something wrong with my test code. Does anyone have any idea?
Other than linking the fontconfig-1.dll, I did nothing else. I haven't created any config files or anything, because I couldn't read anywhere about having to do that.
I am open to your suggestions, thanks!
Instead of:
FcConfig *config = FcInitLoadConfigAndFonts ();
Try:
FcConfig *config = FcConfigCreate();
FcConfigAppFontAddDir(config, (const FcChar8 *)"C:\\Windows\\Fonts");
(this is the lazy version, you should adapt it to go off GetWindowsDirectory...)
Related
I am working on a basic demo application (kmscube) to do rendering via the DRM and GBM APIs. My application uses the TI variation of libgbm (mesa generic buffer management). TI provides the source, GNU autotools files, and a build environment (Yocto) to compile it. I compiled GBM in their environment and it works perfectly.
I did not want to use Yocto, so I moved the source into my own build system (buildroot) and compiled it. Everything compiles correctly (using the same autotools files), but when it runs, I get a segmentation fault when I call gbm_surface_create. I debugged as far as I could and found that the program steps into the gbm library but fails on return gbm->surface_create(gbm, width, height, format, flags);
What would cause a library to run differently when compiled in different environments. Are there some really important compiler or linker flags that I could be missing?
This is the code from the graphics application (in kmscube.c)
gbm.dev = gbm_create_device(drm.fd);
gbm.surface = gbm_surface_create(gbm.dev,
drm.mode[DISP_ID]->hdisplay, drm.mode[DISP_ID]->vdisplay,
drm_fmt_to_gbm_fmt(drm.format[DISP_ID]),
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
if (!gbm.surface) {
printf("failed to create gbm surface\n");
return -1;
}
return 0;
This is the call stack that creates the device ( in gbm.c)
GBM_EXPORT struct gbm_device *
gbm_create_device(int fd)
{
struct gbm_device *gbm = NULL;
struct stat buf;
if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) {
fprintf(stderr, "gbm_create_device: invalid fd: %d\n", fd);
return NULL;
}
if (device_num == 0)
memset(devices, 0, sizeof devices);
gbm = _gbm_create_device(fd);
if (gbm == NULL)
return NULL;
gbm->dummy = gbm_create_device;
gbm->stat = buf;
gbm->refcount = 1;
if (device_num < ARRAY_SIZE(devices)-1)
devices[device_num++] = gbm;
return gbm;
}
(continued in backend.c)
struct gbm_device *
_gbm_create_device(int fd)
{
const struct gbm_backend *backend = NULL;
struct gbm_device *dev = NULL;
int i;
const char *b;
b = getenv("GBM_BACKEND");
if (b)
backend = load_backend(b);
if (backend)
dev = backend->create_device(fd);
for (i = 0; i < ARRAY_SIZE(backends) && dev == NULL; ++i) {
backend = load_backend(backends[i]);
if (backend == NULL)
continue;
fprintf(stderr, "found valid GBM backend : %s\n", backends[i]);
dev = backend->create_device(fd);
}
return dev;
}
static const void *
load_backend(const char *name)
{
char path[PATH_MAX];
void *module;
const char *entrypoint = "gbm_backend";
if (name[0] != '/')
snprintf(path, sizeof path, MODULEDIR "/%s", name);
else
snprintf(path, sizeof path, "%s", name);
module = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
if (!module) {
fprintf(stderr, "failed to load module: %s\n", dlerror());
return NULL;
}
else {
fprintf(stderr, "loaded module : %s\n", name);
}
return dlsym(module, entrypoint);
}
And here is the code that throws a segmentation fault (in gbm.c)
GBM_EXPORT struct gbm_surface *
gbm_surface_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags)
{
return gbm->surface_create(gbm, width, height, format, flags);
}
I'm using libzip in a c++ application for Linux that will need to be able to zip/unzip directories containing symbolic links. I want to add the link itself without following it. Reading out the link with readlink() and adding it to the zip archive results in a nonsense standard file when unzipped with unzip.
Solution does not need to be portable, it will only be used under Linux. The linux zip command has a --symlinks flags so the zip standard should support it. System calls are not really an option, the number of files is quite large and this makes the application extremely slow.
Is it possible to add symlinks with libzip, and how?
Thanks,
Sander
Based on documentation: no
According to its webpage, libzip is based on zlib. The zip program used in Linux, etc, is info-zip, which does not use zlib, but is self-contained (and contains features not in zlib).
Yes it's possible.
Below a function i use for zipping a list of files in c-code.
The files to zip are stored in a cJSON struct,no uid/gid set and files/directories relative to a directory "base" (as that is my appliction).
The Function returns 0 on success.
int list_zip_it(char * upload_zip_name,char * base, cJSON * filelist)
{
int result=0;
int error_n = 0;
struct zip *archive = zip_open(upload_zip_name, ZIP_TRUNCATE | ZIP_CREATE, &error_n);
if(!archive)
{
printf(stderr,"could not open or create archive\n");
return -1;
}
mode_t mode=0;
cJSON * item;
cJSON_ArrayForEach(item,filelist)
{
char * path=NULL;
path=item->valuestring;
// stat the item
struct stat sb;
if (stat(path, &sb) == 0 ) mode=sb.st_mode;
zip_uint32_t attr=0;
attr=((mode ) << 16L);
char rel_file[1024];
if (strncmp(path,CI_PROJECT_DIR,strlen(base))==0 )
{
snprintf(rel_file,1024,"%s",path+strlen(base)+1);
printf("archive filename: %s\n",rel_file);
}
else
{
fprintf(stderr,"filename outside base-derectory\n");
continue;
}
if (S_ISDIR(mode))
{
int index = (int)zip_add_dir(archive, rel_file);
if (index>0) zip_file_set_external_attributes(archive, index, 0, ZIP_OPSYS_UNIX, attr);
}
else if (S_ISLNK(mode)) // symlink
{
char link[1024];//=calloc(1, 1024);
memset(link, 0, 1024);
ssize_t size_link=readlink(path , link, 1023);
if (size_link > 0)
{
struct zip_source *source = zip_source_buffer(archive , link, ( zip_uint64_t)size_link,0);
if (source)
{
int index = (int)zip_add(archive, rel_file, source);
if (index>0) zip_file_set_external_attributes(archive, index, 0, ZIP_OPSYS_UNIX, attr);
}
else
{
printf(stderr,"failed to create source buffer: %s \n", zip_strerror(archive) );
zip_source_free(source);
}
}
else error("failed to read link: %s \n",path );
}
else if (S_ISREG(mode))
{
struct zip_source *source = zip_source_file(archive, path, 0, 0);
if(source == NULL)
{
error("failed to create source buffer: %s \n", zip_strerror(archive) );
result=1;
break;
}
// todo calculate filename relative to project_dir
int index = (int)zip_add(archive, rel_file, source);
if(index < 0 )
{
int zep,sep;
zip_error_get(archive, &zep, &sep);
if (zep== ZIP_ER_EXISTS )
{
fprintf(stderr,"failed to add file to archive: %s \n", zip_strerror(archive) );
zip_source_free(source);
}
else
{
fprintf(stderr,"failed to add file to archive: %s \n", zip_strerror(archive) );
zip_source_free(source);
result=1;
break;
}
}
else
{
zip_file_set_external_attributes(archive, index, 0, ZIP_OPSYS_UNIX, attr);
}
}
}
zip_close(archive);
return result;
}
First off, I do mostly C#, .Net development so go easy on me if this is a stupid question.
I am implementing an Ericcson open source project to convert an image to another format. The problem is that on conversion an output to a console happens as follows...
1 file(s) copied.
I need to suppress this dialog that pops up. I just want to execute the system command with no output. I think I have isolated the area of the code causing this.
void writeOutputFile(char *dstfile, uint8* img, uint8* alphaimg, int width, int height)
{
char str[300];
if(format!=ETC2PACKAGE_R_NO_MIPMAPS&&format!=ETC2PACKAGE_RG_NO_MIPMAPS)
{
fWritePPM("tmp.ppm",width,height,img,8,false);
//PRINTF("Saved file tmp.ppm \n\n");
}
else if(format==ETC2PACKAGE_RG_NO_MIPMAPS)
{
fWritePPM("tmp.ppm",width,height,img,16,false);
}
if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
fWritePGM("alphaout.pgm",width,height,alphaimg,false,8);
if(format==ETC2PACKAGE_R_NO_MIPMAPS)
fWritePGM("alphaout.pgm",width,height,alphaimg,false,16);
// Delete destination file if it exists
if(fileExist(dstfile))
{
sprintf(str, "del %s\n",dstfile);
system(str);
}
int q = find_pos_of_extension(dstfile);
if(!strcmp(&dstfile[q],".ppm")&&format!=ETC2PACKAGE_R_NO_MIPMAPS)
{
// Already a .ppm file. Just rename.
sprintf(str,"move tmp.ppm %s\n",dstfile);
//PRINTF("Renaming destination file to %s\n",dstfile);
}
else
{
// Converting from .ppm to other file format
//
// Use your favorite command line image converter program,
// for instance Image Magick. Just make sure the syntax can
// be written as below:
//
// C:\imconv source.ppm dest.jpg
//
if(format==ETC2PACKAGE_RGBA_NO_MIPMAPS||format==ETC2PACKAGE_RGBA1_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA_NO_MIPMAPS||format==ETC2PACKAGE_sRGBA1_NO_MIPMAPS)
{
// Somewhere after version 6.7.1-2 of ImageMagick the following command gives the wrong result due to a bug.
// sprintf(str,"composite -compose CopyOpacity alphaout.pgm tmp.ppm %s\n",dstfile);
// Instead we read the file and write a tga.
//PRINTF("Converting destination file from .ppm/.pgm to %s with alpha\n",dstfile);
int rw, rh;
unsigned char *pixelsRGB;
unsigned char *pixelsA;
fReadPPM("tmp.ppm", rw, rh, pixelsRGB, 8);
fReadPGM("alphaout.pgm", rw, rh, pixelsA, 8);
fWriteTGAfromRGBandA(dstfile, rw, rh, pixelsRGB, pixelsA, true);
free(pixelsRGB);
free(pixelsA);
sprintf(str,""); // Nothing to execute.
}
else if(format==ETC2PACKAGE_R_NO_MIPMAPS)
{
sprintf(str,"imconv alphaout.pgm %s\n",dstfile);
//PRINTF("Converting destination file from .pgm to %s\n",dstfile);
}
else
{
sprintf(str,"imconv tmp.ppm %s\n",dstfile);
//PRINTF("Converting destination file from .ppm to %s\n",dstfile);
}
}
// Execute system call
system(str);
free(img);
if(alphaimg!=NULL)
free(alphaimg);
}
I am lost at this point about how to suppress the console that pops up. As we iterate through images via a reference to the dll, many many console windows flash on the screen. Need to stop this from happening.
Help is greatly appreciated.
Try doing:
strcat( str, " > nul" ) // for Windows or
//strcat( str, " > /dev/null" ) // for Unix
system( str )
If it doesn't help then this may help:
#include <string>
#include <ShellAPI.h>
int system_no_output( std::string command )
{
command.insert( 0, "/C " );
SHELLEXECUTEINFOA ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "cmd.exe";
ShExecInfo.lpParameters = command.c_str();
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_HIDE;
ShExecInfo.hInstApp = NULL;
if( ShellExecuteExA( &ShExecInfo ) == FALSE )
return -1;
WaitForSingleObject( ShExecInfo.hProcess, INFINITE );
DWORD rv;
GetExitCodeProcess( ShExecInfo.hProcess, &rv );
CloseHandle( ShExecInfo.hProcess );
return rv;
}
and replace all your system() calls to system_no_output() ones.
To fully suppress the output, redirect both stdout and stderr:
system("command >nul 2>nul");
Take a look here if you're using C#. The class used in C# is ProcessStartInfo.
In the example in the link, look at the OpenWithStartInfo member function which will minimize the console.
As far as doing this in C++, take a look at the spawn family of functions here.
How do I get the total number of files in a directory by using C++ standard library?
If you don't exclude the basically always available C standard library, you can use that one.
Because it's available everywhere anyways, unlike boost, it's a pretty usable option!
An example is given here.
And here:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main (void)
{
DIR *dp;
int i = 0;
struct dirent *ep;
dp = opendir ("./");
if (dp != NULL)
{
while (ep = readdir (dp))
i++;
(void) closedir (dp);
}
else
perror ("Couldn't open the directory");
printf("There's %d files in the current directory.\n", i);
return 0;
}
And sure enough
> $ ls -a | wc -l
138
> $ ./count
There's 138 files in the current directory.
This isn't C++ at all, but it is available on most, if not all, operating systems, and will work in C++ regardless.
UPDATE: I'll correct my previous statement about this being part of the C standard library - it's not. But you can carry this concept to other operating systems, because they all have their ways of dealing with files without having to grab out additional libraries.
EDIT: : Added initialization of i
You can't. The closest you are going to be able to get is to use something like Boost.Filesystem
EDIT: It is possible with C++17 using the STL's filesystem library
As of C++17 it can be done with STL:
auto dirIter = std::filesystem::directory_iterator("directory_path");
int fileCount = std::count_if(
begin(dirIter),
end(dirIter),
[](auto& entry) { return entry.is_regular_file(); }
);
A simple for-loop works, too:
auto dirIter = std::filesystem::directory_iterator("directory_path");
int fileCount = 0;
for (auto& entry : dirIter)
{
if (entry.is_regular_file())
{
++fileCount;
}
}
See https://en.cppreference.com/w/cpp/filesystem/directory_iterator
An old question, but since it appears first on Google search, I thought to add my answer since I had a need for something like that.
int findNumberOfFilesInDirectory(std::string& path)
{
int counter = 0;
WIN32_FIND_DATA ffd;
HANDLE hFind = INVALID_HANDLE_VALUE;
// Start iterating over the files in the path directory.
hFind = ::FindFirstFileA (path.c_str(), &ffd);
if (hFind != INVALID_HANDLE_VALUE)
{
do // Managed to locate and create an handle to that folder.
{
counter++;
} while (::FindNextFile(hFind, &ffd) == TRUE);
::FindClose(hFind);
} else {
printf("Failed to find path: %s", path.c_str());
}
return counter;
}
If they are well named, sorted, and have the same extension, you could simply do count them with standard C++ library.
Assume the file names are like "img_0.jpg..img_10000.jpg..img_n.jpg",
Just check if they are in the folder or not.
int Trainer::fileCounter(string dir, string prefix, string extension)
{
int returnedCount = 0;
int possibleMax = 5000000; //some number you can expect.
for (int istarter = 0; istarter < possibleMax; istarter++){
string fileName = "";
fileName.append(dir);
fileName.append(prefix);
fileName.append(to_string(istarter));
fileName.append(extension);
bool status = FileExistenceCheck(fileName);
returnedCount = istarter;
if (!status)
break;
}
return returnedCount;
}
bool Trainer::FileExistenceCheck(const std::string& name) {
struct stat buffer;
return (stat(name.c_str(), &buffer) == 0);
}
You would need to use a native API or framework.
I'm trying to get a list of all top level desktop windows in an X11 session. Basically, I want to get a list of all windows that are shown in the window managers application-switching UI (commonly opened when the user presses ALT+TAB).
I've never done any X11 programming before, but so far I've managed to enumerate through the entire window list, with code that looks something like this:
void CSoftwareInfoLinux::enumerateWindows(Display *display, Window rootWindow)
{
Window parent;
Window *children;
Window *child;
quint32 nNumChildren;
XTextProperty wmName;
XTextProperty wmCommand;
int status = XGetWMName(display, rootWindow, &wmName);
if (status && wmName.value && wmName.nitems)
{
int i;
char **list;
status = XmbTextPropertyToTextList(display, &wmName, &list, &i);
if (status >= Success && i && *list)
{
qDebug() << "Found window with name:" << (char*) *list;
}
status = XGetCommand(display, rootWindow, &list, &i);
if (status >= Success && i && *list)
{
qDebug() << "... and Command:" << i << (char*) *list;
}
Window tf;
status = XGetTransientForHint(display, rootWindow, &tf);
if (status >= Success && tf)
{
qDebug() << "TF set!";
}
XWMHints *pHints = XGetWMHints(display, rootWindow);
if (pHints)
{
qDebug() << "Flags:" << pHints->flags
<< "Window group:" << pHints->window_group;
}
}
status = XQueryTree(display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);
if (status == 0)
{
// Could not query window tree further, aborting
return;
}
if (nNumChildren == 0)
{
// No more children found. Aborting
return;
}
for (int i = 0; i < nNumChildren; i++)
{
enumerateWindows(display, children[i]);
}
XFree((char*) children);
}
enumerateWindows() is called initially with the root window.
This works, in so far as it prints out information about hundreds of windows - what I need, is to work out which property I can interrogate to determine if a given Window is a top-level Desktop application window (not sure what the official terminology is), or not.
Can anyone shed some light on this? All the reference documentation I've found for X11 programming has been terribly dry and hard to understand. Perhaps someone could point be to a better resource?
I have a solution!
Well, sort of.
If your window manager uses the extended window manager hints (EWMH), you can query the root window using the "_NET_CLIENT_LIST" atom. This returna list of client windows the window manager is managing. For more information, see here.
However, there are some issues with this. For a start, the window manager in use must support the EWMH. KDE and GNOME do, and I'm sure some others do as well. However, I'm sure there are many that don't. Also, I've noticed a few issues with KDE. Basically, some non-KDE applications don't get included in the list. For example, if you run xcalc under KDE it won't show up in this list.
If anyone can provide any improvements on this method, I'd be glad to hear them. For reference, the code I'm using is listed below:
Atom a = XInternAtom(m_pDisplay, "_NET_CLIENT_LIST" , true);
Atom actualType;
int format;
unsigned long numItems, bytesAfter;
unsigned char *data =0;
int status = XGetWindowProperty(m_pDisplay,
rootWindow,
a,
0L,
(~0L),
false,
AnyPropertyType,
&actualType,
&format,
&numItems,
&bytesAfter,
&data);
if (status >= Success && numItems)
{
// success - we have data: Format should always be 32:
Q_ASSERT(format == 32);
// cast to proper format, and iterate through values:
quint32 *array = (quint32*) data;
for (quint32 k = 0; k < numItems; k++)
{
// get window Id:
Window w = (Window) array[k];
qDebug() << "Scanned client window:" << w;
}
XFree(data);
}
To expand on the previous solution, if you want to then get the window names:
// get window Id:
Window w = (Window) array[k];
char* name = '\0';
status = XFetchName(display, w, &name);
if (status >= Success)
{
if (name == NULL)
printf("Found: %ul NULL\n", w);
else
printf("Found: %ul %s\n", w, name);
}
XFree(name);
If you don't have to use Xlib, using GDK's gdk_screen_get_window_stack() and gdk_window_get_window_type() may help you out for your needs.