Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > pl.comp.os.linux.programowanie > #2037
| From | Borneq <borneq@antyspam.hidden.pl> |
|---|---|
| Newsgroups | pl.comp.os.linux.programowanie |
| Subject | Niskopoziomowy timer |
| Date | 2015-11-26 11:41 +0100 |
| Organization | ATMAN - ATM S.A. |
| Message-ID | <n36nkj$1kn$1@node1.news.atman.pl> (permalink) |
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;
}
Back to pl.comp.os.linux.programowanie | Previous | Next — Next in thread | Find similar
Niskopoziomowy timer Borneq <borneq@antyspam.hidden.pl> - 2015-11-26 11:41 +0100
Re: Niskopoziomowy timer Borneq <borneq@antyspam.hidden.pl> - 2015-11-26 12:06 +0100
Re: Niskopoziomowy timer Borneq <borneq@antyspam.hidden.pl> - 2015-11-26 12:10 +0100
Re: Niskopoziomowy timer Borneq <borneq@antyspam.hidden.pl> - 2015-11-26 17:38 +0100
csiph-web