Handle X11 damage events in a GTK2 application - c

I am writing a GTK2 widget that shows images of all open windows. These images will update in real time.
To do this, I will use the X11 Damage extension. As far as I understand, the first step is to register an interest in damage events for a given window, like this:
damage = XDamageCreate (dpy, xid, XDamageReportNonEmpty);
How can I connect a signal handler to an X11 damage event? I will also need to pass the widget's structure into this callback function.
It is important that the execution of the rest of my GTK program is not halted while waiting for the events.
Update:
On further research, it would seem that I can respond to X11 events using gdk_window_add_filter. It seems to respond to many events, but it does not seem to respond to damage events. How can I make it respond to damage events?
Also, how can I prevent the callback function from causing an infinite loop when it updates the images?

Related

LabVIEW: how to stop a loop inside event structure

I create an event structure for two buttons, start ROI and stop ROI. When the user presses start ROI it goes to this event and do the following:
check if the camera is open and is in idle
enqueue "none" to the queue to initialize the queue
in the loop dequeue every iteration to find if there's invoked message, which is inserted from the callback
if the element is "invoked" then update the region
The problem I am seeing is that when it is in the loop I cannot press the stop ROI or any other buttons. But the ROI keeps updating. I am puzzled why this is happening.
Could you please help me ?
Thanks,
Edit events for that case (the one pictured in your screenshot) and make sure the box titled "Lock front panel" is unchecked. This should solve your issue.
As far as I can tell from the code you have shown, your event structure should not be attempting to handle the stop ROI Value Change event. It doesn't need to, because the only place you need to respond to that event is inside your innermost loop and there you are handling the button click by polling the value of its terminal anyway.
However as #Dave_St explains, this will only work if the loop runs regularly, i.e. if the Dequeue Element function either receives data regularly or has a short timeout, because otherwise it will wait for data indefinitely and the loop iteration will not complete until the dequeue has executed. Having an event handler for the button click can't help here because it can't interrupt the program flow - the event structure only waits for an event to happen and then allows the code in the corresponding frame to execute.
More generally though, and looking at your front panel which suggests you are going to want to deal with further controls and events, the problem is that you are trying to do a time-consuming task inside an event structure. That's not how event structures are designed to be used. You should use a design pattern for your app that separates the UI (responding to user input) from the process (acquiring images from a camera) - perhaps a queued message handler would be suitable. This may seem harder to understand at first but it will make your program much easier to develop, extend, and maintain.
You can find more information, examples and templates in your LabVIEW installation and its online help. I do recommend using one of the templates as your starting point if possible because they already implement a lot of common functionality and can save you a lot of redundant effort.

How do I reconcile Sendmessage, SendInput, Mouse_event blocked by Getasynckeystate?

TL;DR:
I need to use both sendmessage and sendinput in order to get into an old function/event in a program that I can't re-build. While in there, I can't release the virtual mouse click using any of the methods I used to get in there in the first place - they're ignored.
Any other way to trigger the mousedown event - one where I could also release the mouse click might work.
I am writing a program that has to interact with a black-boxed old piece of software written in VB6 long long ago.
My program has to be able to send mouse clicks, specifically mousedown and mouseup events to the old program.
Here's the tricky part...
The mousedown event in the old program uses:
While GetAsyncKeyState(1)
Wend
to wait for the user to release the mouse.
Currently, in order to get the event to trigger, I need to use:
SendMessage(control_handle, WM_LBUTTONDOWN, 0, 0);
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1,&Input,sizeof(INPUT));
This does trigger the event (using just sendmessage does NOT trigger a necessary branch inside the event because that branch is entered with a GetAsyncKeyState(1) test as well), but issuing any combination of the following does NOT release the mouse click:
SendMessage(control_handle, WM_LBUTTONUP, 0, 0)
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1,&Input,sizeof(INPUT));
The code just keeps repeating in the while/wend part, it never gets out. The release code is being sent, but GetAsyncKeyState(1) isn't recognizing it as a mouse release. SUPER weird that GetAsyncKeyState(1) recognizes the function as a mouse down event, but GetAsyncKeyState(1) won't recognize as a mouse up.
What I've tested:
Clicking the real mouse elsewhere on the screen does release the
function.
Removing the sendmessage call, and using just the sendinput function
(and manually positioning the mouse over the object that needs
clicking) DOES work to release the loop.
I can't rely on the user not messing with the mouse while this is
doing its thing, so I'm hesitant to have the code virtually move the
mouse over the button to be clicked.
I've tried the deprecated mouse_event function as well, same exact
behavior.
Timing is critical. There can't be substantial delays between the trigger is issued and when it happens. Think keyboard-response speed.
I wrote a very simple VB6 program to simulate the while/GetAsyncKeyState(1)/wend loop to test this out on, and the behavior is the same - so I can be confident there isn't something weird in the old program that is causing this to happen.
Thank you very much for reading and helping!
In case this ever comes up for anyone else ever.... Using postmessage instead of sendmessage allows the program to continue on. Makes sense, really..

WPF user interface with long processing execution hangs

I am extremely Sorry for this long post. I need some help on c# wpf issues. I have build a complicated UI(somehow) and there is some buttons... like start and stop and others.
When i click the start button a execution process starts with communicating with some protocol layer and others and it is a long process .. and during this process i have to show some notification UI like "Enter a Text", "Select Something" etc... this time i have to show some wpf window object... and after some time i have to automatically destroy the window and go with processing again.
At first i tried to run the execution in the Main window class. But it results that when the execution starts.. user can't click anything and ui doesno't respond rather just hangs. I investigate the problem... and found that UI is busy with processing in the execution on protocol layer so its not responding.
Here is my problem... can u give me some solution that...
i will have 2 button..start and stop
when i click the start button... a large process will start( like nested for loop with a large int which will continue for 50 seconds) in function named Processor.
at time of processing the function Processor will create several window and show them wait for 5-10 seconds and also destroy them. or user click;s on the window
And the whole time the stop button should be clickable so that when i click the stop button .. the process should be stop.
I tried this with backgroundworker, dispatcher... and using separate thread. but no luck. I guess i am missing something. because if i wait for some result showing a window..the window will definitely hang.. and if i separate them with different thread.. it will not communicate with each other. please give me some suggestions
Dispatcher is definitely the solution. You may need to set the Dispatcher Priority. Sharing some relevant code may also reveal some issues.
BackgroundWorker should do what you need. Set WorkerSupportsCancellation and WorkerReportsProgress to true.
I wouldn't suggest popping up multiple windows. Pop up one window to display status. In your loop in DoWork, call BackgroundWorker.ReportProgress. Then in the ProgressChanged event handler, update the status of the window.
To implement Stop:
In your DoWork method you need to check the CancellationPending property on the BackgroundWorker in your loop. When it is true you need to exit that method. On the stop button click, call BackgroundWorker.CancelAsync().

How to clear keyboard buffer from stale messages

My WinForms application has a button. This button has accelerator key (e.g. Alt+L). When button is pressed I handle the Click event and disable UI to prevent further button clicks until processing is finished. However, when accelerator key is pressed using keyboard those keystrokes are queued and get processed as soon as UI is enabled again. I don't want this. My question is how to clear/flush keyboard buffer?
If I use KeyPress or KeyDown to eat those characters I don't know when they have been received. I only want to suppress old/stale messages that arrived when I was still processing first Click event.
Yes, indeed your theory of the problem is consistent with that proposed by both myself and madmik3 in the comment exchange above. The amount of work your application is doing on the UI thread is effectively blocking it from processing other events, including keystrokes by the user. Those are getting queued for later execution whenever your application finishes its time-consuming foreground task. Those are the perils of a modern-day, pre-emptive multitasking OS. Of course, without posting your actual code, the best I or anyone else can do is speculate about what the problem is, given our experience.
The quick check to confirm that this is actually the case is to toss Application.DoEvents into your processing loop. That will allow the OS to handle the keystrokes immediately, which will all fail because the button has been disabled. (Click events, whether initiated by the mouse or keyboard shortcuts, are not raised for a Button control that has its Enabled property set to "False".) This is the closest you'll get to anything like "flushing the buffers". I doubt you're receiving KeyDown or KeyPress events anyway until after whatever long-running task has completed.
If that fixes the problem, the long-term solution is to spawn a new thread and perform whatever processing you need to do there, instead of on your UI thread. This will prevent you from blocking your UI thread, and, assuming the Button control is correctly disabled, cause the keystrokes to get thrown away because the button they "click" is in a non-clickable state. The simplest way to create a new thread is using the BackgroundWorker component. The documentation contains a pretty good example.

Using ProgressBar as a wait bar - how to avoid freezes?

I'm creating a custom charting control and I would like to have the possibility of displaying some sort of wait bar while other commands are running (i.e. chart is being created).
I'm using ProgressBar (System.Windows.Forms.ProgressBar in marquee mode) as a part of this control. I do not need to update the state of the progress bar, I just want it to move over and over until the chart is created.
Right now I'm using it in following scheme:
- Start wait bar (ProgressBar appears and starts running)
- Call charting methods
- When the chart is ready, the wait bar will being hidden.
The problem is: Some charting methods are really computational demanding and the wait bar freezes in such moments. How can I avoid these freezes? Should I use some kind of threading/background worker? And if yes, then what is the simplest way to do it?
Note, that I do not need to change the state of the progress bar while the chart is being prepared. I just need the wait bar to start, run during all computations and stop after that.
EDIT
OK, as suggested, I created a separate thread for these demanding computations to avoid freezes.
But how to wait for a thread to finish and do not freeze the GUI?
I tried, as suggested here, something like that:
Thread t = new Thread( () => { DoSomeLongAndDemandingTask(withParameters); });
t.Start();
t.Join()
// do something that needs to be done after thread finishes
InvokeMeAfterThreadFinished();
But it freezes the GUI. Is there any other way to avoid these freezes?
You've answered your own question - typically the answer is to move the computation onto a background thread. There is a WinForms component called the BackgroundWorker, does a lot of the lifting for you:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
http://dotnetperls.com/backgroundworker
Note that you won't be able to access UI components from the background thread, you need to Control.Invoke onto the UI thread to get access to UI controls. This is heavily talked about (and solutions provided) on the net so Googling will be easy for this.
Alternatively, sometimes a background thread is unworkable (not sure why), so you can use Application.DoEvents() - if memory serves, this processes pending messages on the message queue (including control painting, UI updating). If you only do a little work that causes jittering, this could be a faster and simpler option - though not advised too often.
Using the BackgroundWorker class is the simplest way to perform a background computation.
However, just be careful that the charting methods you are running in the background do not update the UI. All updates to the UI itself must be performed by the UI thread. So a background thread will need to "marshall" such calls to the UI - see Control.Invoke for a starting point on that.

Resources