Thread View: pl.comp.os.linux.programowanie
4 messages
4 total messages
Started by Borneq
Thu, 26 Nov 2015 10:41
Niskopoziomowy timer
Author: Borneq
Date: Thu, 26 Nov 2015 10:41
Date: Thu, 26 Nov 2015 10:41
306 lines
9884 bytes
9884 bytes
Chciałem użyć biblioteki XCB jako nowszej niż Xlib. Mam przykład z
http://xcb.freedesktop.org/tutorial/fonts/ który wyświetla tylko tekst w
oknie. Teraz chciałem podłączyć timer czy dwa, które w callbacku
zmieniają ten tekst.
Używam timer_create(CLOCK_REALTIME, &sigev, &tid) który łączy sygnały z
timerem.
Jednak nic się nie dzieje.
Kompilacja: w Code::Blocks nie trzeba ustawiać ścieżek, tylko dodać
biblioteki linkera: xcb i rt.
Oto moja próba:
--------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <xcb/xcb.h>
#include <signal.h>
#include <time.h>
#define WIDTH 300
#define HEIGHT 100
static xcb_gcontext_t getFontGC (xcb_connection_t *c,
xcb_screen_t *screen,
xcb_window_t window,
const char *font_name );
static void drawText (xcb_connection_t *c,
xcb_screen_t *screen,
xcb_window_t window,
int16_t x1,
int16_t y1,
const char *label );
static void
testCookie (xcb_void_cookie_t cookie,
xcb_connection_t *connection,
char *errMessage )
{
xcb_generic_error_t *error = xcb_request_check (connection, cookie);
if (error) {
fprintf (stderr, "ERROR: %s : %"PRIu8"\n", errMessage ,
error->error_code);
xcb_disconnect (connection);
exit (-1);
}
}
static void
drawText (xcb_connection_t *connection,
xcb_screen_t *screen,
xcb_window_t window,
int16_t x1,
int16_t y1,
const char *label )
{
/* get graphics context */
xcb_gcontext_t gc = getFontGC (connection, screen, window, "fixed");
/* draw the text */
xcb_void_cookie_t textCookie = xcb_image_text_8_checked (connection,
strlen
(label),
window,
gc,
x1, y1,
label );
testCookie(textCookie, connection, "can't paste text");
/* free the gc */
xcb_void_cookie_t gcCookie = xcb_free_gc (connection, gc);
testCookie(gcCookie, connection, "can't free gc");
}
static xcb_gcontext_t
getFontGC (xcb_connection_t *connection,
xcb_screen_t *screen,
xcb_window_t window,
const char *font_name )
{
/* get font */
xcb_font_t font = xcb_generate_id (connection);
xcb_void_cookie_t fontCookie = xcb_open_font_checked (connection,
font,
strlen
(font_name),
font_name );
testCookie(fontCookie, connection, "can't open font");
/* create graphics context */
xcb_gcontext_t gc = xcb_generate_id (connection);
uint32_t mask = XCB_GC_FOREGROUND |
XCB_GC_BACKGROUND | XCB_GC_FONT;
uint32_t value_list[3] = { screen->black_pixel,
screen->white_pixel,
font };
xcb_void_cookie_t gcCookie = xcb_create_gc_checked (connection,
gc,
window,
mask,
value_list );
testCookie(gcCookie, connection, "can't create gc");
/* close font */
fontCookie = xcb_close_font_checked (connection, font);
testCookie(fontCookie, connection, "can't close font");
return gc;
}
char *text_message = "abcdef";
#define SIGTIMER (SIGRTMAX)
#define SIG SIGUSR1
static timer_t tid1;
static timer_t tid2;
void SignalHandler(int signo, siginfo_t* info, void* context)
{
if (signo == SIGTIMER) {
text_message = "parameter frequency";
}
else if (signo == SIG) {
text_message = "Communication frequency";
}
}
timer_t SetTimer(int signo, long int sec, int mode)
{
static struct sigevent sigev;
static timer_t tid;
static struct itimerspec itval;
static struct itimerspec oitval;
// Create the POSIX timer to generate signo
sigev.sigev_notify = SIGEV_SIGNAL;
sigev.sigev_signo = signo;
sigev.sigev_value.sival_ptr = &tid;
if (timer_create(CLOCK_REALTIME, &sigev, &tid) == 0) {
itval.it_value.tv_sec = sec;
itval.it_value.tv_nsec = 0;
if (mode == 1) {
itval.it_interval.tv_sec = sec;
itval.it_interval.tv_nsec = 0;
}
else {
itval.it_interval.tv_sec = sec;
itval.it_interval.tv_nsec = 0;
}
if (timer_settime(tid, 0, &itval, &oitval) != 0) {
perror("time_settime error!");
}
}
else {
perror("timer_create error!");
return NULL;
}
return tid;
}
int main ()
{
/* get the connection */
int screenNum;
xcb_connection_t *connection = xcb_connect (NULL, &screenNum);
if (!connection) {
fprintf (stderr, "ERROR: can't connect to an X server\n");
return -1;
}
/* get the current screen */
xcb_screen_iterator_t iter = xcb_setup_roots_iterator
(xcb_get_setup (connection));
// we want the screen at index screenNum of the iterator
for (int i = 0; i < screenNum; ++i) {
xcb_screen_next (&iter);
}
xcb_screen_t *screen = iter.data;
if (!screen) {
fprintf (stderr, "ERROR: can't get the current screen\n");
xcb_disconnect (connection);
return -1;
}
/* create the window */
xcb_window_t window = xcb_generate_id (connection);
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t values[2];
values[0] = screen->white_pixel;
values[1] = XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_BUTTON_PRESS |
XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_POINTER_MOTION;
xcb_void_cookie_t windowCookie = xcb_create_window_checked (connection,
screen->root_depth,
window,
screen->root,
20, 200,
WIDTH,
HEIGHT,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
mask,
values);
testCookie(windowCookie, connection, "can't create window");
xcb_void_cookie_t mapCookie = xcb_map_window_checked (connection,
window);
testCookie(mapCookie, connection, "can't map window");
xcb_flush(connection); // make sure window is drawn
/* event loop */
xcb_generic_event_t *event;
/* event loop */
int done = 0;
struct sigaction sigact;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_SIGINFO;
sigact.sa_sigaction = SignalHandler;
// set up sigaction to catch signal
if (sigaction(SIGTIMER, &sigact, NULL) == -1)
{
perror("sigaction failed");
exit( EXIT_FAILURE );
}
int param_delay = 2;
tid1=SetTimer(SIGTIMER, param_delay, 1);
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = SignalHandler;
// set up sigaction to catch signal
if (sigaction(SIG, &sa, NULL) == -1)
{
perror("sa failed");
exit( EXIT_FAILURE );
}
int commn_delay = 1;
tid2=SetTimer(SIG, commn_delay, 1);
while (!done && (event = xcb_wait_for_event(connection))) {
switch (event->response_type & ~0x80) {
case XCB_EXPOSE: /* draw or redraw the window */
drawText (connection,
screen,
window,
10, HEIGHT - 10,
text_message );
xcb_flush(connection);
break;
case XCB_KEY_RELEASE: /* exit on key press */
done = 1;
break;
}
free(event);
}
/* close connection to server */
xcb_disconnect(connection);
return 0;
}
Re: Niskopoziomowy timer
Author: Borneq
Date: Thu, 26 Nov 2015 11:06
Date: Thu, 26 Nov 2015 11:06
8 lines
1192 bytes
1192 bytes
W dniu 2015-11-26 o 11:41, Borneq pisze: > Używam timer_create(CLOCK_REALTIME, &sigev, &tid) który łączy sygnały z > timerem. > Jednak nic się nie dzieje. Nawet konsolowy przykład z man http://man7.org/linux/man-pages/man2/timer_create.2.html nie za dobrze działa - sleep na 1 sekundę i co z tego? handler nie wołany.
Re: Niskopoziomowy timer
Author: Borneq
Date: Thu, 26 Nov 2015 11:10
Date: Thu, 26 Nov 2015 11:10
8 lines
1261 bytes
1261 bytes
W dniu 2015-11-26 o 12:06, Borneq pisze: > Nawet konsolowy przykład z man > http://man7.org/linux/man-pages/man2/timer_create.2.html > nie za dobrze działa - sleep na 1 sekundę i co z tego? handler nie wołany. http://stackoverflow.com/questions/5740954/problem-in-timers-and-signal Już zaczyna łapać tylko teraz nie konsolowy a pętla eventów
Re: Niskopoziomowy timer
Author: Borneq
Date: Thu, 26 Nov 2015 16:38
Date: Thu, 26 Nov 2015 16:38
5 lines
1191 bytes
1191 bytes
W dniu 2015-11-26 o 12:10, Borneq pisze: > http://stackoverflow.com/questions/5740954/problem-in-timers-and-signal > Już zaczyna łapać > tylko teraz nie konsolowy a pętla eventów Udało się : https://gist.github.com/borneq/c629924b60d117ec5c31
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads