Hi Lynette,
Thanks for your advice. I already read dope-users-guide.txt and vscrtest.c and use button event. The application uses ffmpeg to watch video in L4 dope.
Right now, I am writing the pause function but there is a button problem occurred. The sequence is that user presses play button and a new window pop out with video and two buttons (pause, exit) in it. When the video is shown, the pause or exit button event doesn't work until the video finished. Because I use while loop to read the video frame after set up the window, the button event have to wait for the while loop finished.
I have tried using thread to synchronize the event but I failed. Now, I try to find out the way to determine if the button is pressed or not and put the if conditional within while loop. Or maybe I was wrong. Does anyone know how to solve it? Thanks.
Thank you for this more detailed description. Now I see the problem. Generally, as you guessed right, you can request the state of a button by using the 'dope_req' function. For example, to request the state of your pause button, you may do the following:
char buf[8]; dope_req(app_id, buf, sizeof(buf), "pause.state");
The result is either the ascii string "0" (button not pressed) or "1" (button is pressed). However, as you have noticed, DOpE never returns the "1". The reason is that DOpE only lets the user press a button after the application associated an event handler for the button via the 'dope_bind' function. So the button is not press-able (the button does not change its visual state when you click on it anyway). So we have to tell DOpE somehow that we want the button to be press-able. To achive this, you can just call the bind-method of the button widget and leave the bind-argument string empty:
dope_cmd(app_id, "pause.bind("commit", "")");
BTW, this mechanism is also internally used by 'dope_bind', which specifies the information about the callback function as bind argument.
Now we have signaled interest in commit events for the pause button and DOpE will give the proper visual feedback on mouse clicks and it will return a "1" when you request the "state" attribute.
As a reference, I have used the following code for testing:
In the main function:
dope_cmd(app_id, "pause = new Button(-text Pause)"); dope_cmd(app_id, "mg.place(pause, -column 1 -row 101)"); dope_cmd(app_id, "pause.bind("commit", "")");
dope_cmd(app_id, "spin = new Button(-text Spin)"); dope_cmd(app_id, "mg.place(spin, -column 1 -row 100)"); dope_bind(app_id, "spin", "commit", spin_callback, (void *)0);
The callback function for the spin button:
static void spin_callback(dope_event *e, void *arg) { char buf[8]; while (1) { dope_req(app_id, buf, sizeof(buf), "pause.state"); printf("%s\n", buf); } }
You mentioned that you already tried using a separate worker thread for decoding the video. I think this solution would be more elegant than performing long-taking computations from within an event callback function. Generally, a callback function should only trigger a state change of the application and immediately return. It should never perform long-taking operations or even implement a custom event loop ;-) For the clarity of your application, it may be worthwhile for you to try again your worker-thread idea.
Best regards Norman