High numbers when getting pointer motion xlib [duplicate] - c

Hi! I am trying to write a program where I need to report the position of every mouse motion. I have called the XSelectInput() function with a PointerMotionMask mask. Everything seems to work alright but the numbers after printing don't appear after every movement, they appear in blocks and also the numbers in event.xmotion.x and event.xmotion.y are very high, in the hundred thousands.
What is causing these large numbers?
Also is my program getting every number and reporting it immediately or is it being stored in a queue and sent in blocks to the terminal?
Thanks
Here's my event loop:
while(1)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
glClearColor( 1.0, 1.0, 0.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT );
glFlush();
glXSwapBuffers( display, glxwin );
break;
case MotionNotify:
printf("%d, %d", event.xmotion.x, event.xmotion.y);
break;
case ButtonPress: exit(1);
default: break;
}
}

Besides printing a newline at the end, you could also do a '\r' at the end it it will move the cursor to the beginning of the existing line, so it will just print over itself each time. To make this work better, change the digit formatting to be a fixed size, like:
printf("%4d, %4d \r", event.xmotion.x, event.xmotion.y);
fflush(stdout) ;

Related

Keeping aspect ratio in C (ncurses)

I need to make a game using ncurses in C.
The game needs to be 80(char)x24(char).
I need an status bar on the bottom (5 char) so I hardcoded it.
I made this loop to keep things centralized, but I can't figure out how to keep the aspect ratio when the terminal screen is resized.
Is there any way to do it using ncurses?
I need the screen to always stay at least 80x24, perhaps using fullscreen mode always, I don't really need screen resizing.
Here's the loop to keep things in their places (status bar poorly hardcoded, the aspect ratio is a mess)
/* LOOP TO CENTRALIZE FOR ANY RESIZING */
while (1){
getmaxyx(stdscr, yMax, xMax);
clear();
mvprintw(yMax/24, xMax/80, "BEG");
mvprintw(yMax/2, xMax/2, "CENTER %d %d", yMax, xMax);
attron(COLOR_PAIR(1)); /* bottom status bar (5 lines) */
int i, j;
for ( j=(yMax-5) ; j <= yMax ; j++){
for ( i=0 ; i <= xMax ; i++ ){
mvprintw(j, i, " ");
}
}
attroff(COLOR_PAIR(1));
refresh();
}
Unless your program reads input, e.g., calls getch, ncurses will continue using the original screen-size (and look confused). When you call getch after ncurses receives a SIGWINCH, it returns KEY_RESIZE, and at that point ncurses updates its screen-size.

glFlush() do not show anything

My OpenGL glFlush() didn't show anything when I run a glut project in Codeblocks on windows 7.
Here my main function.
#include <windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
float Color1=0.0, Color2=0.0, Color3=0.0;
int r,p,q;
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27: // ESCAPE key
exit (0);
break;
case 'r':
Color1=1.0, Color2=0.0, Color3=0.0;
break;
case 'g':
Color1=0.0, Color2=1.0, Color3=0.0;
break;
case 'b':
Color1=0.0, Color2=0.0, Color3=1.0;
break;
}
glutPostRedisplay();
}
void Init(int w, int h)
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glViewport(0,0, (GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D( (GLdouble)w/-2,(GLdouble)w/2, (GLdouble)h/-2, (GLdouble)h/2);
}
static void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
int i=0;
glColor4f(0,0,0,1);
glPointSize(1);
glBegin(GL_POINTS);
for( i=-320;i<=320;i++)
glVertex2f(i,0);
for( i=-240;i<=240;i++)
glVertex2f(0,i);
glEnd();
glColor4f(Color1,Color2, Color3,1);
glPointSize(1);
glBegin(GL_POINTS);
int x=0, y = r;
int d= 1-r;
while(y>=x)
{
glVertex2f(x+p, y+q);
glVertex2f(y+p, x+q);
glVertex2f(-1*y+p, x+q);
glVertex2f(-1*x+p, y+q);
glVertex2f(-1*x+p, -1*y+q);
glVertex2f(-1*y+p, -1*x+q);
glVertex2f(y+p, -1*x+q);
glVertex2f(x+p, -1*y+q);
if(d<0)
d += 2*x + 3;
else
{
d += 2*(x-y) + 5;
y--;
}
x++;
}
glEnd();
glFlush();
//glutSwapBuffers();
}
int main(int argc, char *argv[])
{
printf("Enter the center point and radius: ");
scanf("%d %d %d",&p,&q,&r);
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutCreateWindow("Circle drawing");
Init(640, 480);
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
But when I change these two lines, it simply works fine.
glFlush(); to glutSwapBuffers(); and
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); to glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
Can anyone tell me what's the problem with my code and why not glFlush() didn't work?
Modern graphics systems (Windows DWM/Aero, MacOS Quartz Extreme, X11 Composite) are built around the concept of composition. Composition always implies double buffering and hence relies on the buffer swap to initiate a composition refresh.
You can disable DWM/Aero on Windows and restrain from using a compositing window manager on X11, and then single buffered OpenGL should work as expected.
But why exactly do you want single buffered drawing? Modern GPUs are actually presuming that double buffering is used to pump their presentation pipeline efficiently. There's zero benefit in being single buffered.
glFlush works as documented:
The glFlush function forces execution of OpenGL functions in finite time.
What this does, is it forces all outstanding OpenGL operations to compleate rendering to the back buffer. This will not magically display the back buffer. To do that you need to swap the font buffer and the back buffer.
So the correct use of glFlush, is in conjunction with glutSwapBuffers. But that is redundant, since glutSwapBuffers will flush all outstanding rendering operations anyway.
It appears that you are using an old OpenGL 1.1 tutorial, where double buffering was an expensive novelty. Currently double buffering is the norm and you need to jump through quite some expensive hoops to get single buffering.
Since OpenGL is currently at version 4.6, I would encourage you to at least start using 4.0.

C - how to read color of a screen pixel (FAST)? (in Windows)

So I am looking for a way to read a color of a screen pixel in C code.
I already found implementation in C for *nix (which uses X11/Xlib library, that as I understood is for *nix systems only) and I tried the code on a linux machine, and it ran pretty fast (it reads 8K of pixels in about 1 second).
Here's the code in C that I've found and forked:
#include <X11/Xlib.h>
void get_pixel_color (Display *d, int x, int y, XColor *color)
{
XImage *image;
image = XGetImage (d, RootWindow (d, DefaultScreen (d)), x, y, 1, 1, AllPlanes, XYPixmap);
color->pixel = XGetPixel (image, 0, 0);
XFree (image);
XQueryColor (d, DefaultColormap(d, DefaultScreen (d)), color);
}
// Your code
XColor c;
get_pixel_color (display, 30, 40, &c);
printf ("%d %d %d\n", c.red, c.green, c.blue);
And I was looking for equivalent solution for Windows as well.
I came across this code (I've put the code about reading screen pixel in a 'for' loop):
FARPROC pGetPixel;
HINSTANCE _hGDI = LoadLibrary("gdi32.dll");
if(_hGDI)
{
pGetPixel = GetProcAddress(_hGDI, "GetPixel");
HDC _hdc = GetDC(NULL);
if(_hdc)
{
int i;
int _red;
int _green;
int _blue;
COLORREF _color;
ReleaseDC(NULL, _hdc);
for (i=0;i<8000;i++)
{
_color = (*pGetPixel) (_hdc, 30 ,40);
_red = GetRValue(_color);
_green = GetGValue(_color);
_blue = GetBValue(_color);
}
ReleaseDC(NULL, _hdc);
printf("Red: %d, Green: %d, Blue: %d", _red, _green, _blue);
}
FreeLibrary(_hGDI);
(using gdi32.dll and windows.h...)
and the 'for' portion of the code (where we read 8K of pixels) runs ALOT slower than the solution in C.
it takes 15 seconds to finish compared to 1 second with X11/Xlib.h library!
So, how can I make it better? or there is any other better and FASTER implementation to read pixel's colors with C code in Windows machine?
Thanks ahead!
I would suggest using loop unwinding. Basically, what this does is execute multiple cycles of your loop in a single iteration:
// Loop the equivalent of `n` cycles, ignoring the least significant bit
for (unsigned int i = 0; i < (n & ~0x01); i += 2)
{
do_some_operation(i);
do_some_operation(i + 1);
}
// Perform the last cycle manually, if one needs to be completed
if (n & 0x01)
{
do_some_operation(n - 1);
}
In this code, the loop ignores the least significant bit of n (which determines the parity of n) so that we are safe to increment i by 2 and perform the equivalent of 2 cycles in just 1 cycle, meaning that this loop is ~2 times faster than a conventional for (unsigned int i = 0; i < n; i++) loop. The final if statement checks the parity of n. If n is odd, the last cycle of the loop is performed.
Of course, this could be reimplemented to increment i by more than 2, but this would become increasingly complex. There is also an alternative to this, Duff's Device. It is basically the same idea, but uses a switch/case block.
After many tests, I've found that just about /anything/ you do to read pixels off the screen in windows using the GDI takes ~16ms (or about 1 frame) whether it is reading a single pixel, or reading even a small area with BitBlt. There doesn't seem to be any clear solution. I will be experimenting with the media libraries to see if I can get anywhere, but the Internet is pretty sure doing anything like this in Windows is just an awful mess, and really terrible things have to be done to do things like VNC or Fraps.

pointer motion. why are numbers so high? why does it print info in blocks not a constant stream?

Hi! I am trying to write a program where I need to report the position of every mouse motion. I have called the XSelectInput() function with a PointerMotionMask mask. Everything seems to work alright but the numbers after printing don't appear after every movement, they appear in blocks and also the numbers in event.xmotion.x and event.xmotion.y are very high, in the hundred thousands.
What is causing these large numbers?
Also is my program getting every number and reporting it immediately or is it being stored in a queue and sent in blocks to the terminal?
Thanks
Here's my event loop:
while(1)
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
glClearColor( 1.0, 1.0, 0.0, 1.0 );
glClear( GL_COLOR_BUFFER_BIT );
glFlush();
glXSwapBuffers( display, glxwin );
break;
case MotionNotify:
printf("%d, %d", event.xmotion.x, event.xmotion.y);
break;
case ButtonPress: exit(1);
default: break;
}
}
Besides printing a newline at the end, you could also do a '\r' at the end it it will move the cursor to the beginning of the existing line, so it will just print over itself each time. To make this work better, change the digit formatting to be a fixed size, like:
printf("%4d, %4d \r", event.xmotion.x, event.xmotion.y);
fflush(stdout) ;

Creating a program loop for the first time in objective-c

I am trying to add some "replay-value" if you will to my temperature scale conversion console program in Objective-C by adding a simple loop.
Now, here is the code for my current main.m file:
#import <Cocoa/Cocoa.h>
#import "class.h"
int main(int argc, char *argv[])
{
int result;
int prompt, prompt2, sourceTempText;
double sourceTemp;
printf("Please choose a source temperature scale:\n[1] Fahrenheit\n[2] Celsius\n[3] Kelvin\n[4] Rankine\n\n");
result = scanf("%i", &prompt);
if (result != 1)
printf("I couldn't understand your input, I need only one number!");
else if (result == EOF)
printf("I apologize, I encountered an error when trying to read your input.");
else if (result == 1)
{
printf("\nNow, please enter the temperature you would like to convert:\n\n");
scanf("%lf", &sourceTemp);
Temperature *converter = [[Temperature alloc] init];
switch (prompt)
{
case 1:
//end-user chooses Fahrenheit
[converter setFahrenheitValue:sourceTemp];
sourceTempText = 1;
break;
case 2:
//end-user chooses Celsius
[converter setCelsiusValue:sourceTemp];
sourceTempText = 2;
break;
case 3:
//end-user chooses Kelvin
[converter setKelvinValue:sourceTemp];
sourceTempText = 3;
break;
case 4:
//end-user chooses Rankine
[converter setRankineValue:sourceTemp];
sourceTempText = 4;
break;
}
printf("\nNow, please choose a target temperature scale:\n[1] Fahrenheit\n[2] Celsius\n[3] Kelvin\n[4] Rankine\n\n");
scanf("%i", &prompt2);
char *scales[4] = { "Fahrenheit", "Celsius", "Kelvin", "Rankine" };
switch (prompt2)
{
case 1:
//end-user chooses Fahrenheit
printf("%lf degrees %s is %lf degrees Fahrenheit\n", sourceTemp, scales[prompt-1], [converter fahrenheitValue]);
break;
case 2:
//end-user chooses Celsius
printf("%lf degrees %s is %lf degrees Celsius\n", sourceTemp, scales[prompt-1], [converter celsiusValue]);
break;
case 3:
//end-user chooses Kelvin
printf("%lf degrees %s is %lf degrees Kelvin\n", sourceTemp, scales[prompt-1], [converter kelvinValue]);
break;
case 4:
//end-user chooses Rankine
printf("%lf degrees %s is %lf degrees Rankine\n", sourceTemp, scales[prompt-1], [converter rankineValue]);
break;
}
}
}
OK, so I would like to prompt the user with a printf statement, asking them if they would like to convert another temperature once they have made their first conversion.
The prompt would ask the end-user to press 0 to exit the program, or 1 to make another conversion.
My first inclination was to declare an integer variable which would be set to 0 or 1 from scanf once the end-user has inputted their choice.
Then, if the new variable == 1, then it would loop back to the beginning, if not, it would exit the program.
Pretty simple, huh?
Just wondering, is there a more efficient way to loop this program or is this a good way, at least with the basic knowledge I have now.
Yes you could just put it in a loop, and ask the exit question right before the end of the loop. Depending on the answer, you could just exit(0). Or you could integrate it in the first question; 1=Fahrenheit, 2=..., 0 = Exit.
The loop could just be while(1) { ... }. Another approach would be to have a variable before the loop:
int done = 0;
and then loop over while ( !done ) { ... }. (read this as "while not done"). In the loop, set done=1 when you're done, and the loop will then terminate.
(for clarity: it will terminate only after completing the whole { ... } block, but you will find that out - if you come to that point you need to read(/ask) about continue and break)
There are a few things to consider: does your loop need to clean up? Here
Temperature *converter = [[Temperature alloc] init];
you allocate some memory. If you just loop again, you will allocate some more memory. And so on: this is called a "memory leak". This goes on until you run out of memory and the program would crash (although it would take a long long time in this case).
So you should really release the converter when you're done with it, by doing
[converter release];
This way you will not leak any memory.
Also this would be a good moment to put parts of your program in a separate function, because it becomes a little bit unclear what exactly is happening when it gets bigger and bigger.

Resources