Writing code in C that must run on Raspbian but with the option of having various displays - from 128*64 to 1280*1024 and perhaps even larger. I want my program to begin by getting the physical dimensions of the display (in pixels) then decide what windows to create in it. The application is kind of kiosk , user interaction may not be a requirement, so the display must be right from the beginning.
Using Raspbian Stretch, Cairo over Gtk, gcc 6.3.0
More critical info is what gtk version you are using. If those are deprecated it is because gdk moved to per screen settings which you can get with functions such as:
gdk_display_get_n_monitors
gdk_get_monitor
gdk_monitor_get_geometry
GdkRectangle->width and/or ->height
These are in application pixels so you may need to scale.
At a guess the IS_SCREEN failure may be due to things not being initialised. Will need more info to know for sure.
Related
I am using CLion in Windows. It has a stdout-like terminal that allows printf output to be shown. In some cases, however, I would like to have a static display that is updated. For example, I might have a matrix, and I want to see the values in the matrix update as the program runs. I do not want to print the matrix out to stdout because it would just scroll off the screen and be unreadable. I need the matrix to stay in one place and just update. In Unix I can do things like this with curses. Obviously I could start writing Windows graphical applications, but that would be complicated and time consuming. Is there any easy way to get an ASCII 2D display of information using CLion for Windows?
In CLion you may set breakpoints at appropriate positions (at the points where you'd like to see the values of the variables) and run the program in 'Debug' mode.
All the variables and their values at that point could be accessed in the variables tab and you may add them to your 'watch list' so that they can stand out from rest of the variables.
CLion has a pretty great debugger. You can even evaluate some statements using those variables.
For example :
I am creating a tick-based simulation in C, currently running on Mac OS X 10.8.4.
At the moment after each tick, I am printing out the entire world representing in ASCII to the terminal, using ANSI escape codes to move the cursor to the correct place.
I would like to transition to a graphical based representation of the world instead of using the terminal window. What would be a good library use? Also, what is the accepted way of performing multiple updates to the screen per second in this library?
I would use SDL since it is cross compatible with most OS and mature.
Also check these examples for 2D animations in order to perform the screen updates you need.
Obviously, this information is available in xorg.conf so I could try to parse this file. But is there a way to achieve this using Xlib calls (+ extensions) only?
Thanks,
PMJ
It must be possible, because I know the program xdpyinfo can do it. At first, I was going to suggest executing that from within your program and parsing the output. That shouldn't be necessary, though, since the source of xdpyinfo is freely available.
It looks like if you have a (Display*) variable (and you will, because pretty much every X11 function call requires one), you can call these wonderful macros to get interesting data, including ServerVendor and VendorRelease. That should cover the "graphic adapter" portion of your quest.
As for the monitor name, according to xdpyinfo.c, this is governed by XF86VidModeGetMonitor() which is part of an X11 extension. This returns a XF86VidModeMonitor structure which will reveal vendor, model, and other juicy data.
Run xdpyinfo-- if that program can query the data, so can your program.
How would I change a pixel on a display, in C?
Assume NOTHING: I am using a linux machine from console to do this. I do not want to use GUI toolkits or frameworks to draw the pixel. I do not want to draw the pixel in a window. I want to draw the pixel directly to the screen.
EDIT: I have a screen. I'm on a laptop running linux from console. I'd prefer a solution not using X as I'd rather learn how X works than how to use X.
If theres more information, ask, but don't assume. I'm not trying to build a GUI, and that was the main purpose of blocking assumptions as I don't want people to assume I'm doing things the long way when in reality I'm just tinkering.
EDIT 2: You may use any X11 related libraries provided that you can explain how they work.
If we really assume nothing, can we even assume that X is running? For that matter, can we even assume that there is a video card? Perhaps Linux is running headless and we're accessing it over a serial console.
If we are allowed to assume a few things, let's assume that Linux has booted with framebuffer support. (It's been a couple years since I worked with Linux framebuffers, I may get some of the details wrong.) There will be a device created, probably /dev/fb or /dev/fb0. Open that file and start writing RGB values at an offset, and the screen will change, pretty much regardless of anything: text console, graphical console, full-fledged desktop envrionment, etc. If you want to see if framebuffer support is working, do dd if=/dev/zero of=/dev/fb on the command line, and the display should go all black.
C doesnt have any graphics capabilities - you'd need to use a third party library for this.
You cannot assume a display in C. There is literally no way to do what you ask.
Edit: Okay, you have a display, but again, there's not a whole lot you can get from there. The point is that there are a TON of competing standards for graphics displays, and while some of them (VGA interfaces, for example) are standardized, a lot of the others (display driver interfaces, for example) are NOT. Much of what X (and other display device drivers, such as Windows or the like) do, is have specific interface code for how to talk to the display drivers; they abstract out the complexity of dealing with the display drivers. The windowing systems, though, have HUGE libraries of complicated and specific code for dealing with the display drivers; the fact that these things are relatively transparent is an indication of just how much work they've put into these things over time.
Very primitive and making a lot of assumptions:
fd = open("/dev/fb0", O_RDWR);
lseek(fd, 640*y+x, SEEK_SET);
write(fd, "\377\377\377\377", 4);
In reality, you would use mmap rather than write, and use the appropriate ioctl to query the screen mode rather than assuming 640xHHH 32bpp. There are also endian issues, etc.
So in real reality, you might use some sort of library code that handles this kind of thing for you.
I suppose you could paint to the terminal program that you are using as your console. All you have to do is figure out which one that is and look it up.
Whoops I assumed a terminal. :P
I think what you are looking for is information on how to write to the frame buffer. The easiest way would be to use SDL and render to the frame buffer, or else use GTK+ with DirectFB, although that goes against your edict on not using toolkits or frameworks.
Consider the following file:
-rw-r--r-- 1 user user 470886479 2009-12-15 08:26 the_known_universe.png
How would you scale the image down to a reasonable resolution, using no more than 4GB of RAM?
For example:
$ convert -scale 7666x3833 the_known_universe.png
What C library would handle it?
Thank you!
I believe libpng has a stream interface. I think this can be used to read parts of the image at a time; depending on the image file you might be able to get the lines in order. You could then shrink each line (e.g. for 50% shrinking, shrink the line horizontally and discard every second line) and write to an output file.
Using libpng in C can take a fair amount of code, but the documentation guides you through it pretty well.
http://www.libpng.org/pub/png/libpng-1.2.5-manual.html#section-3.8
You could try making a 64 bit build of ImageMagick or seeing if there is one. My colleague wrote a blog with a super-simple png decoder (assumes you have zlib or equivalent) so you can kind of see the code you'd need to roll your own.
http://www.atalasoft.com/cs/blogs/stevehawley/archive/2010/02/23/libpng-you-re-doing-it-wrong.aspx
You would need to do the resample as you're reading it in.
I used cximage a few years ago. I think the latest version is at
http://www.xdp.it/cximage.htm
after moving off of CodeProject.
Edit: sorry, it's C++ not C.
You could use an image processing library that is intended to do complex operations on large (and small) images. One example is the IM imaging toolkit. It links well with C (but is implemented at least partly in C++) and has a good binding to Lua. From the Lua binding it should be easy to experiment.
libvips is comfortable with huge images. It's a streaming image processing library, so it can read from the source, process, and write to the destination simultaneously and in parallel. It's typically 3x to 5x faster than imagemagick and needs very little memory.
For example, with the largest PNG I have on my laptop (1.8gb), I can downsize 10x with:
$ vipsheader huge.png
huge.png: 72000x72000 uchar, 3 bands, srgb, pngload
$ ls -l huge.png
-rw-r--r-- 1 john john 1785845477 Feb 19 09:39 huge.png
$ time vips resize huge.png x.png 0.1
real 1m35.279s
user 1m49.178s
sys 0m1.208s
peak RES 230mb
Not fast, but not too shabby either. PNG is rather a slow format, it would be much quicker with TIFF.
libvips is installable by most package managers (eg. homebrew on macOS, apt on Debian), there's a Windows binary, and it's free (LGPL). As well as the command-line, there are bindings for C, C++, Python, Ruby, Lua, node, PHP, and others.
Have you considered exploring pyramid based images? Imagine a pyramid where the image is divided up in multiple layers, each layer with a different resolution. Each layer is split up into tiles.
This way you can display a zoomed out version of the image, and also a zoomed in partial view of the image, without having to re-scale.
See the Wikipedia entry.
One of the original formats was FlashPix, which I wrote a renderer for.
I've also created a new format of a pyramid converter and renderer, which was used for a medical application. An actual scanner would produce 90GB+ scans of a slice of an organ for cancer research.
The algorithm of the converter was actually pretty tricky to get efficient, to produce the pyramid images efficienty. Believe it or not, it was actually Java based, and it performed much better than you'd think. It used multithreading. Benchmarking showed it was unlikely that a C version would do a whole lot better. This was 6ish years ago. The original renderer I did over 10 years ago.
You don't hear anything about pyramid based images anymore these days. But it's really the only efficient way to produce scaled images on demand without having to generate cached scaled versions.
Jpeg2000 may or may not have an optional pyramid feature as well.
I recall that ImageMagick's supporter formats and conversions perhaps, include FlashPix.
Googling for "image pyramid" reveals some interesting results. Bring back some memories ;-)
If you can move it to a 64-bit OS you can open it as a memory mapped file or equivalent and use pretty much any library you want. It won't be fast, and may need the increase of the page/swap file (depending on the OS and what else you want to do with it) but in return you won't be limited to streaming libraries so you'll be able to do more operation before going into resolution reduction or slicing.