i am making a program which needs to be run in desktop mode. How can I check in C? And also, is it possible to get screen width and height in C(of the monitor)?
This is a very broad question, but I'll bite. I'm assuming that by "desktop mode" you mean a running X window system. Since you don't seem to have a preferred widget toolkit, I'll show an example which uses Xlib.
You could simply try to open the display and check the return value. If it's up, you can retrieve the screen resolution as well:
#include <stdio.h>
#include <X11/Xlib.h>
int main(int argc, char ** argv)
{
int screen_num;
unsigned int display_width, display_height;
Display *display;
/* First connect to the display server, as specified in the DISPLAY
environment variable. */
display = XOpenDisplay(NULL);
if (!display)
{
fprintf(stderr, "unable to connect to display");
return 1;
}
/* pull useful data out of the display object */
screen_num = DefaultScreen(display);
/* Display size is a member of display structure */
display_width = DisplayWidth(display, screen_num);
display_height = DisplayHeight(display, screen_num);
fprintf(stdout, "resolution is %d x %d\n", display_width, display_height);
return 0;
}
You have to compile with -lX11. All of this and much more can be learned from the Xlib programming tutorial here.
Related
Basically I'm using Linux 2.6.34 on PowerPC (Freescale e500mc). I have a process (a kind of VM that was developed in-house) that uses about 2.25 G of mlocked VM. When I kill it, I notice that it takes upwards of 2 minutes to terminate.
I investigated a little. First, I closed all open file descriptors but that didn't seem to make a difference. Then I added some printk in the kernel and through it I found that all delay comes from the kernel unlocking my VMAs. The delay is uniform across pages, which I verified by repeatedly checking the locked page count in /proc/meminfo. I've checked with programs that allocate that much memory and they all die as soon as I signal them.
What do you think I should check now? Thanks for your replies.
Edit: I had to find a way to share more information about the problem so I wrote this below program:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>
#define MAP_PERM_1 (PROT_WRITE | PROT_READ | PROT_EXEC)
#define MAP_PERM_2 (PROT_WRITE | PROT_READ)
#define MAP_FLAGS (MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE)
#define PG_LEN 4096
#define align_pg_32(addr) (addr & 0xFFFFF000)
#define num_pg_in_range(start, end) ((end - start + 1) >> 12)
inline void __force_pgtbl_alloc(unsigned int start)
{
volatile int *s = (int *) start;
*s = *s;
}
int __map_a_page_at(unsigned int start, int whichperm)
{
int perm = whichperm ? MAP_PERM_1 : MAP_PERM_2;
if(MAP_FAILED == mmap((void *)start, PG_LEN, perm, MAP_FLAGS, 0, 0)){
fprintf(stderr,
"mmap failed at 0x%x: %s.\n",
start, strerror(errno));
return 0;
}
return 1;
}
int __mlock_page(unsigned int addr)
{
if (mlock((void *)addr, (size_t)PG_LEN) < 0){
fprintf(stderr,
"mlock failed on page: 0x%x: %s.\n",
addr, strerror(errno));
return 0;
}
return 1;
}
void sigint_handler(int p)
{
struct timeval start = {0 ,0}, end = {0, 0}, diff = {0, 0};
gettimeofday(&start, NULL);
munlockall();
gettimeofday(&end, NULL);
timersub(&end, &start, &diff);
printf("Munlock'd entire VM in %u secs %u usecs.\n",
diff.tv_sec, diff.tv_usec);
exit(0);
}
int make_vma_map(unsigned int start, unsigned int end)
{
int num_pg = num_pg_in_range(start, end);
if (end < start){
fprintf(stderr,
"Bad range: start: 0x%x end: 0x%x.\n",
start, end);
return 0;
}
for (; num_pg; num_pg --, start += PG_LEN){
if (__map_a_page_at(start, num_pg % 2) && __mlock_page(start))
__force_pgtbl_alloc(start);
else
return 0;
}
return 1;
}
void display_banner()
{
printf("-----------------------------------------\n");
printf("Virtual memory allocator. Ctrl+C to exit.\n");
printf("-----------------------------------------\n");
}
int main()
{
unsigned int vma_start, vma_end, input = 0;
int start_end = 0; // 0: start; 1: end;
display_banner();
// Bind SIGINT handler.
signal(SIGINT, sigint_handler);
while (1){
if (!start_end)
printf("start:\t");
else
printf("end:\t");
scanf("%i", &input);
if (start_end){
vma_end = align_pg_32(input);
make_vma_map(vma_start, vma_end);
}
else{
vma_start = align_pg_32(input);
}
start_end = !start_end;
}
return 0;
}
As you would see, the program accepts ranges of virtual addresses, each range being defined by start and end. Each range is then further subdivided into page-sized VMAs by giving different permissions to adjacent pages. Interrupting (using SIGINT) the program triggers a call to munlockall() and the time for said procedure to complete is duly noted.
Now, when I run it on freescale e500mc with Linux version at 2.6.34 over the range 0x30000000-0x35000000, I get a total munlockall() time of almost 45 seconds. However, if I do the same thing with smaller start-end ranges in random orders (that is, not necessarily increasing addresses) such that the total number of pages (and locked VMAs) is roughly the same, observe total munlockall() time to be no more than 4 seconds.
I tried the same thing on x86_64 with Linux 2.6.34 and my program compiled against the -m32 parameter and it seems the variations, though not so pronounced as with ppc, are still 8 seconds for the first case and under a second for the second case.
I tried the program on Linux 2.6.10 on the one end and on 3.19, on the other and it seems these monumental differences don't exist there. What's more, munlockall() always completes at under a second.
So, it seems that the problem, whatever it is, exists only around the 2.6.34 version of the Linux kernel.
You said the VM was developed in-house. Does this mean you have access to the source? I would start by checking to see if it has anything to stop it from immediately terminating to avoid data loss.
Otherwise, could you potentially try to provide more information? You may also want to check out: https://unix.stackexchange.com/ as they would be better suited to help with any issues the linux kernel may be having.
I am using fltk 1.3.2.
I set the button's label color with
_button->labelcolor(fl_rgb_color(162, 60, 62));
but when I press the button, the color is changed.
I couldn't find the function how set the active label color.
Does anyone know how to do that?
Edit:
I use Fl::background() and Fl::foreground() functions before creating the window. This make the problem.
Edit2:
This example shows the problem.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <iostream>
void HitMe(Fl_Widget* w)
{
std::cout << "Ouch" << std::endl;
}
int main(int argc, char ** argv)
{
Fl::background(0x60, 0x66, 0x60);
Fl_Window *window = new Fl_Window(320,130);
Fl_Button *b = new Fl_Button(10, 10, 130, 30, "A red label");
b->labelcolor(fl_rgb_color(162, 60, 20));
b->callback(HitMe);
window->end();
window->show(argc,argv);
return Fl::run();
}
When I commented out Fl::background() function everything is alright.
What you are seeing is the contrasting colour (see commented out code below). FLTK does this when the button is pressed. It gets the colour of the button, works out the contrasting colour based on the foreground and background colours. Have a look at the help for fl_contrast for more details.
Basically, if there is enough contrast, it will use the foreground colour otherwise it will find a contrasting colour for your background.
What can you do about it?
do nothing - that is how it is
choose a lighter background colour which will satisfy the contrast conditions
make your own button type with its own draw method
class KeepFGButton : public Fl_Button
{
public:
KeepFGButton(int x, int y, int w, int h, const char* s)
: Fl_Button(x, y, w, h, s)
{
}
void draw() {
if (type() == FL_HIDDEN_BUTTON) return;
Fl_Color col = value() ? selection_color() : color();
draw_box(value() ? (down_box() ? down_box() : fl_down(box())) : box(), col);
draw_backdrop();
// Remove the code that changes the contrast
//if (labeltype() == FL_NORMAL_LABEL && value()) {
// Fl_Color c = labelcolor();
// labelcolor(fl_contrast(c, col));
// draw_label();
// labelcolor(c);
//}
//else
draw_label();
if (Fl::focus() == this) draw_focus();
}
};
int main(int argc, char ** argv)
{
Fl::background(0x60, 0x66, 0x60);
Fl_Window *window = new Fl_Window(320, 130);
Fl_Button *b = new KeepFGButton(10, 10, 130, 30, "A red label");
...
Try the following and let me know if, when you run it, the label becomes white. If it doesn't then there is possibly something else that you are doing that is not quite right. If it does, I don't know what the problem is.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <iostream>
void HitMe(Fl_Widget* w)
{
std::cout << "Ouch" << std::endl;
}
int main(int argc, char ** argv) {
Fl_Window *window = new Fl_Window(320,130);
Fl_Button *b = new Fl_Button(10, 10, 130, 30, "A red label");
b->labelcolor(fl_rgb_color(162, 60, 20));
b->callback(HitMe);
window->end();
window->show(argc,argv);
return Fl::run();
}
This is definitely too late to help the author, but in the event that this helps anyone else searching for an answer to this still relevant issue in FLTK, I'm going to offer my solution:
If you dig through the source code for FLTK 1.3.4-2 (current stable as of this post), there are a couple of built-in colormap indices which are referenced when the drawing of shadow boxes or frames are called: FL_DARK3 (for the boxes) and FL_DARK2 (for the scrollbar back color in Fl_Scroll). You can look at this FLTK documentation to see how to reset these colors to anything you wish at runtime. In particular, anticipating that this ugly red default mess will show up whenever there's a sufficiently dark background, it works well for me to just set these to a slightly lighter version of the overlayed box color:
Fl_Color boxColor = 0x88888800;
Fl_Color boxShadowColor = 0xaaaaaa00;
Fl::set_color(FL_DARK3, boxShadowColor);
Fl::set_color(FL_DARK2, boxShadowColor);
Now create your label as above and the display will be free of the red shadow. N.b. it is also possible to override the standard background2() behavior which resets FL_BACKGROUND_COLOR to the one produced by fl_contrast:
Fl::set_color(FL_BACKGROUND2_COLOR, yourBgColor);
The same trick works for other hard to reset colors like FL_INACTIVE_COLOR and FL_SELECTION_COLOR.
Hope this workaround helps.
Was trying to code. C, Linux. User enter some string and date. If it's today, then program should show a window with his string. Then this window should be closed by code, not user. And then it will pop up again after a short period of time. gtk_widget_destroy and gtk_widget_hide don't work.
`(aa:26429): Gtk-CRITICAL **: IA__gtk_widget_hide: assertion 'GTK_IS_WIDGET (widget)' failed`
#include <gtk/gtk.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
/* numbered markers placed below by msw for reference */
char str[50];
int main( int argc, char *argv[] )
{
printf("Enter your string\n>:");
fgets( str, 50, stdin );
char time_buf[10], date[10];
int a=strlen(time_buf);
int i=0;
time_t endwait;
time_t start = time(NULL);
time_t seconds = 30;
endwait=start+seconds;
printf("Enter date\n>:");
fgets(date, 10, stdin);
time_t now;
time(&now);
strftime(time_buf, 21, "%Y-%m-%d", gmtime(&now));
if (strncmp(time_buf,date,9) == 0) {
printf("TODAY!\n");
while (start < endwait) {
GtkWidget *label;
GtkWidget *window;
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_window_set_title( GTK_WINDOW( window ),"ALARM");
label = gtk_label_new( str );
gtk_container_set_border_width(GTK_CONTAINER(window), 50);
gtk_container_add( GTK_CONTAINER( window ), label );
gtk_widget_show_all( window );
g_signal_connect(G_OBJECT(window),"destroy",
G_CALLBACK( gtk_main_quit ),NULL)
gtk_main(); // mark 1 ###
gtk_widget_destroy (label); // mark 2 ###
//gtk_widget_hide(window);
start = time(NULL);
sleep(10);
}
} else {
printf("NOT TODAY");
return 0;
}
}
GTK has an event loop, started with gtk_main. Actually, it is wrapping a glib event loop, to which you can add timeouts using g_timeout_add_full (or simply g_timeout_add). This is the good way to handle your issue (make some GTK signal handler register a Glib timeout which could e.g. call gtk_widget_hide or gtk_exit ...)
The big problem is that after you invoke gtk_main() at mark 1, your program does not get to run again until gtk_main exits. Prior to gtk_main returning, all widgets from the toplevel down will be destroyed. That's why I assume the error happened at mark 2 where you try to destroy a label that's already been destroyed.
It is still not clear to me why you'd want the behavior. Screen-wide popup notification behaves differently than gtk/glib/X11 programs because it is different. If I am running a program and a top-level window comes to the screen I should know what caused it and be able to get rid of it. It is more intuitive for the user if you scrap the popup, put a label below the entry¹ and change its text to "" when you want it to be invisible. And what #BasileStarynkevitch said.
¹What entry? The one that you should have to enter the string in. it would be an odd program that takes input from the console and displays output in a window.
I want to move my GTK_WINDOW across the screen automatically. Currently I have it in a draw/move loop, but that's terribly choppy. I'm very new to GTK programming (and gui programming in general). What am I missing?
You haven't said what sort of path you want the window to follow. If the path is some simple function of time -- that is, if you have a way to compute where you want the window to be at any given time -- you could try the method illustrated in following code. For the quite-simple menu in the example, it works ok on my Linux system and produces fairly smooth motion.
The key to the method is that instead of moving the window a given distance per timer event, it finds out the current time and moves the window to the location it should be at, at that time. Thus, the time derivative of speed of motion should be constant, which avoids ragged or choppy motion even if timer events occur irregularly. (As noted in g-timeout-add() description, irregularity can easily occur.)
In this example, the path is from top left of window to bottom left and back, repeatedly. The constant 'HalfTime' in timerEvent() controls how long it takes to move from corner to corner. The constant 3 in the g_timeout_add() call sets the timer interval to 0.003 seconds, or about 333 moves per second (MPS). (You may want to try more-reasonable rates, such as 20, 30, 40, etc MPS; I used the number 3 because I didn't look up g-timeout-add() before using it, and assumed the delay was hundreths of seconds, for about 33 MPS, rather than milliseconds, for about 333 MPS.) If your window contents are quite complex, fewer MPS will be practical. Also, I tried some slower rates and got more of an impression of choppiness.
/* $Id: app12.c $
Re: animating position of a top-level Gtk window
jiw July 2011 -- Offered without warranty under GPL v3
terms per http://www.gnu.org/licenses/gpl.html */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <gtk/gtk.h>
typedef struct DATA { GTimer *timer; GtkWidget *window; int w, h; }
DataStruct;
gboolean timerEvent(void *dataset) {
enum { HalfTime=8, CycTime=2*HalfTime };
gulong micros;
DataStruct *data =dataset;
double t = fabs(fmod (g_timer_elapsed (data->timer, µs), CycTime));
int x = (t*data->w)/HalfTime, y = (t*data->h)/HalfTime;
gtk_window_move (GTK_WINDOW(data->window),
t<HalfTime? x : 2*data->w-x, t<HalfTime? y : 2*data->h-y);
return TRUE; /* Keep timeout running */
}
int main(int argc, char **argv) {
GtkWidget *vbox, *b;
GdkScreen *gds;
DataStruct data;
data.timer = g_timer_new();
gtk_init (&argc, &argv);
data.window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW(data.window), 200, 150);
g_signal_connect (G_OBJECT(data.window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER(data.window), vbox);
b = gtk_button_new_with_label ("Click to Exit");
gtk_box_pack_start (GTK_BOX(vbox), b, TRUE, TRUE, TRUE);
g_signal_connect (b, "clicked", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all (data.window);
gds = gdk_screen_get_default (); /* Get pointer to screen */
data.w = gdk_screen_get_width (gds); /* Find out screen width */
data.h = gdk_screen_get_height (gds); /* Find out screen height */
printf ("Screen size = %d by %d\n", data.w, data.h); fflush(stdout);
g_timeout_add(3, timerEvent, &data); /* Create .003 sec timer */
gtk_main();
return (0);
}
I need a fast command line app to return the color of the pixel under the mouse cursor.
How can I build this in VC++, I need something similar to this, but ideally not in .NET so it can be run many times per second?
Off the top of my head, the straightforward way:
#include <stdio.h>
#include <Windows.h>
int main(void) {
POINT p;
COLORREF color;
HDC hDC;
BOOL b;
// Get the device context for the screen
hDC = GetDC(NULL);
if (hDC == NULL)
return 3;
// Get the current cursor position
b = GetCursorPos(&p);
if (!b)
return 2;
// Retrieve the color at that position
color = GetPixel(hDC, p.x, p.y);
if (color == CLR_INVALID)
return 1;
// Release the device context again
ReleaseDC(GetDesktopWindow(), hDC);
printf("%i %i %i", GetRValue(color), GetGValue(color), GetBValue(color));
return 0;
}
ETA: Appears to work, at least for me.
ETA2: Added some error checking
ETA3: Commented code, compiled executable and a Visual Studio Solution can be found in my SVN repository.