Accessing custom XResources colors with X11 - c

I'm just starting my first ever program using the X11 library. To start, I'm just trying to access the colors from the user's color-scheme as defined in xrdb. For example, in my ~/.Xresources I have things like:
*color8: #073642
*color0: #002b36
I've also verified that these colors show up when I run xrdb -query. In my C program so far I have:
#include <X11/Xlib.h>
#include <X11/Xresource.h>
int main (int argc, char *argv[])
{
Display* display = XOpenDisplay (0);
XrmDatabase xrdb = XrmGetDatabase (display);
XrmValue v;
Colormap cmap = DefaultColormap (display, DefaultScreen (display));
XColor screenColor;
XColor exactColor;
if (! XAllocNamedColor (display, cmap "color0", &screenColor, &exactColor))
printf ("ERROR\n");
printf ("%u %u %u\n", screenColor.red, screenColor.green, screenColor.blue);
return 0;
}
But this errors. So what am I missing? Is there a better way to do what I'm trying to do? Thanks!

When you want to access parameters set in an Xresource file loaded by xrdb, you need to
xrdb = XrmGetStringDatabase(XResourceManagerString(display));
instead of XrmGetDatabase(...). Hope that addresses (lately) your question.

Related

XServer first key typed is always in lowercase

I'm writing a method for keyboard handling where I'm passing the key unicodes and firing keystrokes using the XTestFakeKeyEvent Method of X11. Now my issue is that after the opening the display, if the very first Character I send is in Uppercase, it still is typed in lowercase. So provided is the minimal implementation.
Compiled using command: gcc typekeys.c -o typekeys.exe -lX11 -lXtst
#include <stdio.h>
#include <stdbool.h>
#include <X11/extensions/XTest.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
static Display *mainDisplay = NULL;
Display *XGetMainDisplayK(void) {
if (mainDisplay == NULL) {
mainDisplay = XOpenDisplay(NULL);
if (mainDisplay == NULL) {
printf("\nCould not open main display");
}
}
return mainDisplay;
}
void toggleKeySym(unsigned int key){
KeySym sym;
Display *dpy;
dpy = XGetMainDisplayK();
sym=key;
printf("\nKeysym recieved:%u \n",key);
int min, max, numcodes;
XDisplayKeycodes(dpy, &min, &max);
KeySym *keysym;
keysym = XGetKeyboardMapping(dpy, min, max-min+1, &numcodes);
keysym[(max-min-1)*numcodes]=sym;
XChangeKeyboardMapping(dpy, min, numcodes, keysym, (max-min));
XFree(keysym);
XFlush(dpy);
unsigned int code;
printf("Keysym value:%d \n",sym);
code=XKeysymToKeycode(dpy, sym);
printf("Code Generated:%u. \n",code);
XTestFakeKeyEvent(dpy, code, True, CurrentTime);
XTestFakeKeyEvent(dpy, code, False, CurrentTime);
XSync(dpy, false);
XFlush(dpy);
}
void main(){
printf("Start \n");
toggleKeySym(65);
toggleKeySym(65);
printf("Done.\n");
}
The problem is XKeysymToKeycode(dpy, sym);:
If you look at the output of your program, you will see that it outputs something like this:
Code Generated:38.
...
Code Generated:254.
At least on my computer it behaves this way.
(By the way: I can only reproduce the problem the first time after logging off from my computer and logging on again.)
However, your program should write the same value twice because the same key code (254) is pressed.
This means that XKeysymToKeycode(dpy, sym); has returned the wrong value.
The reason is that XKeysymToKeycode() works the following way:
The XOpenDisplay() function calls XGetKeyboardMapping() reading the keyboard information to some "internal" variable (of the type KeySym *); the information in the "internal" variable is then used by XKeysymToKeycode().
The "internal" variable is updated later - maybe during XSync(). However, it seems that the "internal" variable is not updated before XKeysymToKeycode() is called the first time, so XKeysymToKeycode() returns the information still based on the old value of the "internal" variable.
However, you know that you have changed the symbol generated by the key max-1, so you know that code should have the value max-1. Therefore, calling XKeysymToKeycode() is not necessary at all.

Without creating a window, is it possible to detect the current XCB modifier state?

I use the Xkb sticky option, and I would like to write a program that emits some text to stdout when the modifier key state changes, e.g. when Ctrl is "active" regardless of whether the physical Ctrl key is pressed. I want this program to be able to work without creating a visible X window and leaving it open, as that would obstruct my use of other applications.
Is this possible using the Xkb, XkbCommon, Xlib and/or XCB libraries? I tried using XNextEvent as suggested in the Xkb spec, but this function just blocks forever.
My full attempt at an implementation is here, but this is the relevant portion:
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
/* Various X and Xkb data that are often needed together */
typedef struct ExtensionInfo {
Display* display; /* An X display */
int base_event_code; /* Integer code offset for Xkb events */
int base_err_code; /* Integer code offset for Xkb errors */
int xkb_version_major; /* Dual-purpose version indicator; see XkbOpenDisplay(3) */
int xkb_version_minor; /* Dual-purpose version indicator; see XkbOpenDisplay(3) */
int xkb_reason; /* Error reason if XkbOpenDisplay fails, or success reason */
} ExtensionInfo;
int main(int argc, char *argv[]) {
ExtensionInfo *extension_info;
XkbEvent xkb_event;
extension_info->display = XkbOpenDisplay(
/* NULL here is allowed by XkbOpenDisplay but not mentioned explicitly
* in the XkbOpenDisplay man page - it defaults to $DISPLAY */
NULL,
&(extension_info->base_event_code),
&(extension_info->base_err_code),
&(extension_info->xkb_version_major),
&(extension_info->xkb_version_minor),
&(extension_info->xkb_reason)
);
const unsigned long int xkb_details_mask = (
XkbModifierBaseMask |
XkbModifierStateMask |
XkbModifierLatchMask |
XkbModifierLockMask
);
bool xkb_initialized = XkbSelectEventDetails(
extension_info->display,
XkbUseCoreKbd,
XkbStateNotifyMask,
xkb_details_mask,
xkb_details_mask
);
printf("Waiting...\n");
XNextEvent(extension_info->display, &xkb_event.core);
printf("Done.\n");
}
In general yes, it's perfectly possible to call any kind of X11 requests which need a Window handle (eg. for getting or setting the selection) without popping a window on the screen -- by creating an InputOnly window.
But for Xkb* you don't even need that. In the posted snippet, your problem is that you're not calling XkbSelectEvents at all, so no Xkb events will be delivered to your X11 client.
The little example below does get an event whenever the state changes:
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <err.h>
int main(void){
Display *dpy; int xkb_event;
if(!(dpy = XkbOpenDisplay(0, &xkb_event, 0, 0, 0, 0)))
errx(1, "cannot open display '%s'", XDisplayName(0));
XkbSelectEvents(dpy, XkbUseCoreKbd, XkbStateNotifyMask,
XkbStateNotifyMask);
for(;;){
XkbEvent e; XNextEvent(dpy, &e.core);
if(e.type == xkb_event && e.any.xkb_type == XkbStateNotify)
warnx("xkb state changed!");
}
}

How do I can call initgraph more than one time?

Please look at the following code:
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
using namespace std;
void drawrect()
{
int gdriver = IBM8514, gmode;
initgraph(&gdriver, &gmode, "");
rectangle(500, 500, 700, 700);
getch();
cleardevice();
closegraph();
}
int main()
{
int f=1;
while(f)
{
char c;
printf("Press \"e\" to end, and any other character to draw a rectangle");
scanf("%c",&c);
c=='e' ? f=0:f=1;
drawrect();
fflush(stdin);
}
}
at the first time when I run this program, It works correctly and draws a rectangle, but after the first time, the rectangle function doesn't work and the GUI screen is completely blank, While I've cleared and closed previous graphic
So why it doesn't work at second time?
You code has undefined behaviour. The call to initgraph
int gdriver = IBM8514, gmode;
initgraph(&gdriver, &gmode, "");
should pass a pointer to the graphics mode you want to use. This page describes the function and its arguments, and about the mode it says:
*graphmode is an integer that specifies the initial graphics mode (unless *graphdriver equals DETECT; in which case, *graphmode is set
by initgraph to the highest resolution available for the detected
driver). You can give *graphmode a value using a constant of the
graphics_modes enumeration type, which is defined in graphics.h and
listed below.
graphdriver and graphmode must be set to valid values from the
following tables, or you will get unpredictable results. The exception
is graphdriver = DETECT.
But you have not set the mode, and as the second paragraph quoted says, the result is unpredictable. This can be: working how you intended, not working, working strangely, or frying the processor.
So set the graphics mode you want to use with say
int gdriver = IBM8514, gmode = 0;
or whatever mode you need to use. Alternatively you can tell the system to detect for itself, in which case you can use
int gdriver = DETECT, gmode;
Init and close should be called just once and not be called in the drawrect but usually in the main instead ... also having getch in rendering routine makes no sense too...
I will not touch other issues here of your code as I am not coding console stuff for years and BGI even longer but I would start with reordering the code to this:
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
using namespace std;
void drawrect()
{
rectangle(500, 500, 700, 700);
}
int main()
{
int f=1;
int gdriver = IBM8514, gmode;
initgraph(&gdriver, &gmode, "");
while(f)
{
char c;
printf("Press \"e\" to end, and any other character to draw a rectangle");
scanf("%c",&c);
c=='e' ? f=0:f=1;
drawrect();
getch();
fflush(stdin);
}
cleardevice();
closegraph();
}
Also in future address the library by its real name BGI because graphics.h has no meaning as almost all gfx api/libs got a file with that name ...

debugging global variable in eclipse (C/C++)

I wrote this sample C program:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define SIZE 10
typedef struct _sampleStruct{
int f1;
double f2;
int f3[SIZE];
}sampleStruct;
sampleStruct g_s;
int main() {
sampleStruct s;
sampleStruct zeroed = {0};
s.f1 = g_s.f1 = 1;
s.f2 = g_s.f2 = 2.0;
for (int i = 0; i < SIZE; ++i) {
s.f3[i] = g_s.f3[i] = i*10;
}
memset(&s, 0, sizeof(sampleStruct));
printf("s: %d, g_s: %lf, zeroed: %d", s.f1, g_s.f2, zeroed.f3[3]);
return 0;
}
I'm using Eclipse Mars IDE and I want to debug this code.
the s and zeroed variables are shown in the variables tab.
however, the g_s (which is a global variable) is not shown there.
is there a way for me to see its fields and how they're changing etc.?
EDIT: just figured out there's a "add global variables" button but it is grayed, so I can't press it.
ok, so after some more googling about it I found this .
tl;dr - the problem was that I was using the default GDB(DSF) process launcher. apparently this is a known issue (more details in the link above).
what you should do to solve it:
go to Run-->Debug Configurations and check at the bottom of the opened window which debug launcher you are using. if it is the GDB(DSF) then press the "Select other..." link below it. In the opened window mark "Use configuration specific settings" and then choose a different launcher (in my case it is "Legacy Create Process Launcher").
now the "add global variables should not be gray and you can click it and choose the variables you want to watch.
leaving the question just in case someone will encounter the same problem.
I hope that you find this visual description helpful.
Click the Add Global Variables icon (green dot with eye-glasses above it):
Which is located under the Variables tab:
Here is a zoom-out of both:

Live graph for a C application

I have an application which logs periodically on to a host system it could be on a file or just a console. I would like to use this data to plot a statistical graph for me. I am not sure if I can use the live graph for my application.
If this tool is the right one, may I have an example on integrating the external application with the live graph?
this is livegraph link --> http://www.live-graph.org/download.html
I think this can be achieved easiest using Python plus matplotlib. To achieve this there are actually multiple ways: a) integrating the Python Interpreter directly in your C application, b) printing the data to stdout and piping this to a simple python script that does the actual plotting. In the following I will describe both approaches.
We have the following C application (e.g. plot.c). It uses the Python interpreter to interface with matplotlib's plotting functionality. The application is able to plot the data directly (when called like ./plot --plot-data) and to print the data to stdout (when called with any other argument set).
#include <Python.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void initializePlotting() {
Py_Initialize();
// load matplotlib for plotting
PyRun_SimpleString(
"from matplotlib import pyplot as plt\n"
"plt.ion()\n"
"plt.show(block=False)\n"
);
}
void uninitializePlotting() {
PyRun_SimpleString("plt.ioff()\nplt.show()");
Py_Finalize();
}
void plotPoint2d(double x, double y) {
#define CMD_BUF_SIZE 256
static char command[CMD_BUF_SIZE];
snprintf(command, CMD_BUF_SIZE, "plt.plot([%f],[%f],'r.')", x, y);
PyRun_SimpleString(command);
PyRun_SimpleString("plt.gcf().canvas.flush_events()");
}
double myRandom() {
double sum = .0;
int count = 1e4;
int i;
for (i = 0; i < count; i++)
sum = sum + rand()/(double)RAND_MAX;
sum = sum/count;
return sum;
}
int main (int argc, const char** argv) {
bool plot = false;
if (argc == 2 && strcmp(argv[1], "--plot-data") == 0)
plot = true;
if (plot) initializePlotting();
// generate and plot the data
int i = 0;
for (i = 0; i < 100; i++) {
double x = myRandom(), y = myRandom();
if (plot) plotPoint2d(x,y);
else printf("%f %f\n", x, y);
}
if (plot) uninitializePlotting();
return 0;
}
You can build it like this:
$ gcc plot.c -I /usr/include/python2.7 -l python2.7 -o plot
And run it like:
$ ./plot --plot-data
Then it will run for some time plotting red dots onto an axis.
When you choose not to plot the data directly but to print it to the stdout you may do the plotting by an external program (e.g. a Python script named plot.py) that takes input from stdin, i.e. a pipe, and plots the data it gets.
To achieve this call the program like ./plot | python plot.py, with plot.py being similar to:
from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
while True:
# read 2d data point from stdin
data = [float(x) for x in raw_input().split()]
assert len(data) == 2, "can only plot 2d data!"
x,y = data
# plot the data
plt.plot([x],[y],'r.')
plt.gcf().canvas.flush_events()
I have tested both approaches on my debian machine. It requires the packages python2.7 and python-matplotlib to be installed.
EDIT
I have just seen, that you wanted to plot a bar plot or such thing, this of course is also possible using matplotlib, e.g. a histogram:
from matplotlib import pyplot as plt
plt.ion()
plt.show(block=False)
values = list()
while True:
data = [float(x) for x in raw_input().split()]
values.append(data[0])
plt.clf()
plt.hist([values])
plt.gcf().canvas.flush_events()
Well, you only need to write your data in the given format of livegraph and set livegraph up to plot what you want. If wrote small C example which generates random numbers and dumps them together with the time every second. Next, you just attach the livegraph program to the file. That's it.
Playing around with LiveGraph I must say that its use is rather limited. I still would stick to a python script with matplotlib, since you have much more control over how and what is plotted.
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
int main(int argc, char** argv)
{
FILE *f;
gsl_rng *r = NULL;
const gsl_rng_type *T;
int seed = 31456;
double rndnum;
T = gsl_rng_ranlxs2;
r = gsl_rng_alloc(T);
gsl_rng_set(r, seed);
time_t t;
t = time(NULL);
f = fopen("test.lgdat", "a");
fprintf(f, "##;##\n");
fprintf(f,"#LiveGraph test file.\n");
fprintf(f,"Time;Dataset number\n");
for(;;){
rndnum = gsl_ran_gaussian(r, 1);
fprintf(f,"%f;%f\n", (double)t, rndnum);
sleep(1);
fflush(f);
t = time(NULL);
}
gsl_rng_free(r);
return 0;
}
compile with
gcc -Wall main.c `gsl-config --cflags --libs`

Resources