fixed SHM deadlock, need to fix more troubles

This commit is contained in:
2026-07-21 09:50:39 +03:00
parent a3134d31a8
commit 87bf7678b1
14 changed files with 928 additions and 613 deletions

View File

@@ -49,7 +49,7 @@ set(CMAKE_COLOR_MAKEFILE ON)
# cmake -DDEBUG=yes -> debugging # cmake -DDEBUG=yes -> debugging
if(DEBUG) if(DEBUG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Og -g3 -ggdb -Werror") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -ggdb -Werror")
add_definitions(-DEBUG) add_definitions(-DEBUG)
set(CMAKE_BUILD_TYPE DEBUG) set(CMAKE_BUILD_TYPE DEBUG)
set(CMAKE_VERBOSE_MAKEFILE "ON") set(CMAKE_VERBOSE_MAKEFILE "ON")

View File

@@ -31,10 +31,10 @@ extern cc_Wheel wheel;
// flags for image processing // flags for image processing
typedef enum{ typedef enum{
IM_ERROR,
IM_SLEEP, IM_SLEEP,
IM_STARTED, IM_STARTED,
IM_READY, IM_READY,
IM_ERROR
} imstate_t; } imstate_t;
// devices // devices
@@ -63,10 +63,7 @@ static double exptime = 0., starttime = 0.;
// return constant string with error code description // return constant string with error code description
static const char *errcode(int ecode){ static const char *errcode(int ecode){
switch(ecode){ switch(ecode){
#ifndef STR #define ECASE(code) case code: return # code
#define STR(par) # par
#endif
#define ECASE(code) case code: return STR(code)
ECASE(S_OK); ECASE(S_OK);
ECASE(S_FALSE); ECASE(S_FALSE);
ECASE(E_UNEXPECTED); ECASE(E_UNEXPECTED);
@@ -131,6 +128,7 @@ static void camclose(){
free(toupcam.data); free(toupcam.data);
toupcam.data = NULL; toupcam.data = NULL;
} }
toupcam.state = IM_ERROR;
} }
/** /**
@@ -241,7 +239,20 @@ static int campoll(cc_capture_status *st, float *remain){
static void EventCallback(unsigned nEvent, void _U_ *pCallbackCtx){ static void EventCallback(unsigned nEvent, void _U_ *pCallbackCtx){
DBG("CALLBACK with evt %d", nEvent); DBG("CALLBACK with evt %d", nEvent);
if(!toupcam.hcam || !toupcam.data){ DBG("NO data!"); return; } if(!toupcam.hcam || !toupcam.data){ DBG("NO data!"); return; }
if(nEvent != TOUPCAM_EVENT_IMAGE){ DBG("Not image event"); return; } switch(nEvent){
case TOUPCAM_EVENT_DISCONNECTED:
WARNX(_("Camera disconnected"));
camclose();
return;
case TOUPCAM_EVENT_ERROR:
WARNX(_("Error occured"));
camcancel();
case TOUPCAM_EVENT_IMAGE:
break;
default:
DBG("Not an image event");
return;
}
ToupcamFrameInfoV4 info = {0}; ToupcamFrameInfoV4 info = {0};
//DBG("LOCK"); //DBG("LOCK");
pthread_mutex_lock(&toupcam.mutex); pthread_mutex_lock(&toupcam.mutex);

View File

@@ -49,36 +49,56 @@ static sem_t *sem = SEM_FAILED;
// client-side SHM lock // client-side SHM lock
int cc_lock_shm(int isserver){ int cc_lock_shm(int isserver){
if(sem == SEM_FAILED){ if(sem == SEM_FAILED){
LOGERR("cc_lock_shm(): can't lock NULL");
DBG("Can't lock NULL"); DBG("Can't lock NULL");
return FALSE; return FALSE;
} }
struct timespec ts = {.tv_sec = 0, .tv_nsec = 10000000}; struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts); // sem_timedwait waits for absolute time!
ts.tv_nsec += 100000000; // 100 ms
if(ts.tv_nsec > 999999999){
ts.tv_nsec -= 1000000000;
++ts.tv_sec;
}
#ifdef EBUG
double tstart = sl_dtime();
#endif
DBG("Try to lock"); DBG("Try to lock");
if(isserver){ int locked = TRUE;
int locked = TRUE; while(locked){
while(sem_timedwait(sem, &ts) && locked){ if(0 == sem_timedwait(sem, &ts)){
switch(errno){ locked = FALSE;
case EINTR: break;
DBG("Interrupt -> try to lock again"); }
break; DBG("Errno=%d (%s)", errno, strerror(errno));
default: // timeout or other error -> force locking if(errno == EINTR){
DBG("Error locking -> force unlock"); DBG("Interrupt -> try to lock again");
locked = FALSE; }else{
if(errno == ENOENT || errno == EINVAL){
DBG("No semaphore -> can't lock");
LOGERR("cc_lock_shm(): no semaphore -> can't lock");
return FALSE;
} }
} DBG("Error locking -> %s", (isserver) ? "force unlock" : "exit");
if(locked){ break;
double t0 = sl_dtime();
while(sem_trywait(sem) && sl_dtime() - t0 < 0.1) sem_post(sem); // force locking
if(sl_dtime() - t0 >= 0.1) return FALSE; // can't lock - timeout
}
}else{
if(sem_timedwait(sem, &ts)){
DBG("Image semaphore is locked too long by other side");
return FALSE; // can't lock
} }
} }
DBG("Semaphore locked"); DBG("locked=%d; time=%g", locked, sl_dtime() - tstart);
return TRUE; if(!locked){
DBG("Semaphore locked");
return TRUE;
}
if(isserver){
double t0 = sl_dtime();
LOGERR("cc_lock_shm(): still locked -> force unlock");
while(sem_trywait(sem) && sl_dtime() - t0 < 0.1) sem_post(sem); // force locking
if(sl_dtime() - t0 >= 0.1){
LOGERR("cc_lock_shm(): failed to unlock");
}
}else{
DBG("Image semaphore is locked too long by other side");
}
return FALSE; // can't lock
} }
void cc_unlock_shm(){ void cc_unlock_shm(){
@@ -89,10 +109,11 @@ void cc_unlock_shm(){
if(sem_post(sem)){ if(sem_post(sem)){
switch(errno){ switch(errno){
case EOVERFLOW: // already unlocked case EOVERFLOW: // already unlocked
DBG("Already unlocked");
break; break;
default: // not a valid? or other? default: // not a valid? or other?
WARN(_("Can't unlock image semaphore"));
LOGERR("Can't unlock image semaphore"); LOGERR("Can't unlock image semaphore");
ERR(_("Can't unlock image semaphore (is server alive?)"));
return; return;
} }
} }
@@ -109,16 +130,21 @@ void cc_init_sem(int isserver){
sem = sem_open(SEM_NAME, 0); sem = sem_open(SEM_NAME, 0);
} }
if(sem == SEM_FAILED){ if(sem == SEM_FAILED){
LOGERR("sem_open failed: %s", strerror(errno)); WARNX("sem_open() failed: %s", strerror(errno));
LOGERR("sem_open() failed: %s", strerror(errno));
} }
} }
void cc_remove_sem(){ void cc_remove_sem(){
if(sem == SEM_FAILED) return; if(sem != SEM_FAILED){
sem_close(sem); sem_post(sem); // try to unlock if it was locked
sem_close(sem);
}
DBG("semaphore closed\n"); DBG("semaphore closed\n");
if(-1 == sem_unlink(SEM_NAME)) if(-1 == sem_unlink(SEM_NAME)){
LOGERR("Can't delete semaphore"); LOGERR("Can't delete semaphore");
WARNX(_("Can't delete semaphore"));
}
} }
/** /**
@@ -175,6 +201,10 @@ int cc_open_socket(int isserver, char *path, int isnet){
WARN("socket()"); WARN("socket()");
continue; continue;
} }
int bufsz = 33554432; // 32MB for buffer size
setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufsz, sizeof(int));
bufsz = 33554432;
setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufsz, sizeof(int));
if(isserver){ if(isserver){
int reuseaddr = 1; int reuseaddr = 1;
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1){ if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(int)) == -1){
@@ -219,6 +249,10 @@ int cc_senddata(int fd, void *data, size_t l){
while(total < l){ while(total < l){
ssize_t sent = send(fd, (char*)data + total, l - total, MSG_NOSIGNAL); ssize_t sent = send(fd, (char*)data + total, l - total, MSG_NOSIGNAL);
if(sent <= 0){ if(sent <= 0){
if(errno == EAGAIN){
usleep(1000);
continue;
}
WARN("send()"); WARN("send()");
LOGWARN("send()"); LOGWARN("send()");
break; // error break; // error
@@ -339,12 +373,8 @@ cc_IMG *cc_getshm(key_t key, size_t imsize){
int shmid = -1; int shmid = -1;
int flags = (imsize) ? IPC_CREAT | 0666 : 0; int flags = (imsize) ? IPC_CREAT | 0666 : 0;
shmid = shmget(key, 0, flags); shmid = shmget(key, 0, flags);
if(shmid < 0 && imsize == 0){ // no SHM segment for client struct shmid_ds buf;
WARN(_("Can't get shared memory segment %d"), key);
return NULL;
}
if(imsize){ // check if segment exists and its size equal to needs if(imsize){ // check if segment exists and its size equal to needs
struct shmid_ds buf;
if(shmctl(shmid, IPC_STAT, &buf) > -1 && shmsize != buf.shm_segsz){ // remove already existing segment if(shmctl(shmid, IPC_STAT, &buf) > -1 && shmsize != buf.shm_segsz){ // remove already existing segment
DBG("Need to remove already existing segment"); DBG("Need to remove already existing segment");
shmctl(shmid, IPC_RMID, NULL); shmctl(shmid, IPC_RMID, NULL);
@@ -355,11 +385,18 @@ cc_IMG *cc_getshm(key_t key, size_t imsize){
return NULL; return NULL;
} }
}else{ }else{
#ifdef EBUG if(shmid < 0){ // no SHM segment for client
struct shmid_ds buf; WARN(_("Can't get shared memory segment %d"), key);
if(shmctl(shmid, IPC_STAT, &buf)) WARNX(_("Can't get SHM data")); return NULL;
else DBG("SHM size = %zd", buf.shm_segsz); }
#endif if(shmctl(shmid, IPC_STAT, &buf)){
WARNX(_("Can't get SHM data"));
return NULL;
}else DBG("SHM size = %zd", buf.shm_segsz);
if(buf.shm_perm.mode & SHM_DEST){
WARNX(_("SHM buffer marked for deletion"));
return NULL;
}
} }
flags = (imsize) ? 0 : SHM_RDONLY; // client opens memory in readonly mode flags = (imsize) ? 0 : SHM_RDONLY; // client opens memory in readonly mode
cc_IMG *ptr = shmat(shmid, NULL, 0); cc_IMG *ptr = shmat(shmid, NULL, 0);
@@ -368,7 +405,7 @@ cc_IMG *cc_getshm(key_t key, size_t imsize){
return NULL; return NULL;
} }
if(!imsize){ if(!imsize){
if(ptr->MAGICK != CC_SHM_MAGIC){ if(ptr->MAGICK != CC_SHM_MAGIC || buf.shm_segsz < ptr->bytelen + sizeof(cc_IMG)){
WARNX(_("Shared memory %d isn't belongs to image server"), key); WARNX(_("Shared memory %d isn't belongs to image server"), key);
shmdt(ptr); shmdt(ptr);
return NULL; return NULL;
@@ -953,3 +990,106 @@ cc_hresult cc_plugin_customcmd(const char *str, cc_parhandler_t *handlers, cc_ch
#undef ADDL #undef ADDL
return result; return result;
} }
/**
* @brief cc_newimage - create new empty image
* @param bitpix - 8 or 16
* @param w - width
* @param h - height
* @return pointer to allocated image or NULL if failed
*/
cc_IMG *cc_newimage(uint8_t bitpix, int w, int h){
FNAME();
if(w < 1 || h < 1){
DBG("Error: w=%d, h=%d", w, h);
return NULL;
}
cc_IMG *newima = calloc(1, sizeof(cc_IMG));
if(!newima){
WARN("calloc()");
return FALSE;
}
int N = bitpix / 8;
if(N < 1 || N > 2){
DBG("Error: %d bytes per pixel", N);
free(newima);
return NULL;
}
size_t ds = N * w * h;
newima->data = calloc(1, ds);
if(!newima->data){
WARN("calloc()");
free(newima);
return NULL;
}
newima->datasize = newima->bytelen = ds;
newima->w = w;
newima->h = h;
newima->MAGICK = CC_SHM_MAGIC;
pthread_mutex_init(&newima->mutex, NULL);
DBG("Created new image %dx%d", w, h);
return newima;
}
void cc_freeimage(cc_IMG **i){
if(!i || !*i) return;
cc_IMG *ptr = *i;
free(ptr->data);
free(ptr);
*i = NULL;
}
/**
* @brief cc_copyimage - copy `src` to `dest`
* @param dest - destination (dest->data would be reallocated if not enough)
* @param src - source image
* @param isshm - ==TRUE if `src` is in shared memory
* @return FALSE if failed
*/
int cc_copyimage(cc_IMG *dest, cc_IMG *src, int isshm){
FNAME();
if(!src || !dest || !src->data) return FALSE;
if(src->MAGICK != CC_SHM_MAGIC){
WARNX(_("Wrong image: bad magick (0x%X instead of 0x%X)"), src->MAGICK, CC_SHM_MAGIC);
return FALSE;
}
if(src->bytelen < 1){
WARNX(_("Wrong image size"));
return FALSE;
}
DBG("Lock");
pthread_mutex_lock(&dest->mutex);
if(!dest->data || dest->datasize < src->bytelen){
size_t newsz = 1024 * (1 + src->bytelen / 1024);
DBG("resize from %zd to %zd bytes", dest->datasize, newsz);
void *nxt = realloc(dest->data, newsz);
if(!nxt){
LOGERR("realloc() failed");
WARN("realloc()");
pthread_mutex_unlock(&dest->mutex);
return FALSE;
}
dest->data = nxt;
dest->datasize = newsz;
DBG("Success");
}
DBG("Copy fields");
#define COPY(field) dest->field = src->field;
COPY(timestamp);
COPY(bitpix);
COPY(w);
COPY(h);
COPY(bytelen);
COPY(imnumber);
#undef COPY
DBG("Copy %zd bytes of data", src->bytelen);
void *srcdata = src->data;
if(isshm){
srcdata = (void*)((uint8_t*)src + sizeof(cc_IMG));
DBG("Copy from SHM by offset; srcptr: %p; datastart: %p, offset: %zd", src, srcdata, sizeof(cc_IMG));
}
memcpy(dest->data, srcdata, src->bytelen);
DBG("All OK");
pthread_mutex_unlock(&dest->mutex);
return TRUE;
}

View File

@@ -34,20 +34,22 @@
#define SEM_NAME "ccdcapture" #define SEM_NAME "ccdcapture"
// base image parameters - sent by socket and stored in shared memory // base image parameters - sent by socket and stored in shared memory
typedef struct __attribute__((packed)){ typedef struct{ // __attribute__((packed))
uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm
pthread_mutex_t mutex; // mutex for working with image data
double timestamp; // timestamp of image taken double timestamp; // timestamp of image taken
uint8_t bitpix; // bits per pixel (8 or 16)
int w, h; // image size int w, h; // image size
int gotstat; // stat counted int gotstat; // stat counted
size_t bytelen; // size of image in bytes
size_t datasize; // size of `data` buffer
size_t imnumber; // counter of images captured from server's start
uint8_t bitpix; // bits per pixel (8 or 16)
uint16_t max, min; // min/max values uint16_t max, min; // min/max values
float avr, std; // statistics float avr, std; // statistics
size_t bytelen; // size of image in bytes
size_t imnumber; // counter of images captured from server's start
void *data; // pointer to data (next byte after this struct) - only for server
/* `data` is uint8_t or uint16_t depending on `bitpix` */
char fitsheader[FITS_HEADER_STRINGS_MAX][FLEN_CARD]; // FITS-header for given image
size_t headerstrings; // amount of records in header size_t headerstrings; // amount of records in header
/* `data` is uint8_t or uint16_t depending on `bitpix` */
void *data; // pointer to data (next byte after this struct) - only for server
char fitsheader[FITS_HEADER_STRINGS_MAX][FLEN_CARD]; // FITS-header for given image
} cc_IMG; } cc_IMG;
typedef struct{ typedef struct{
@@ -323,6 +325,10 @@ void cc_charbufaddline(cc_charbuff *b, const char *s);
cc_strbuff *cc_strbufnew(size_t size, size_t stringsize); cc_strbuff *cc_strbufnew(size_t size, size_t stringsize);
void cc_strbufdel(cc_strbuff **buf); void cc_strbufdel(cc_strbuff **buf);
cc_IMG *cc_newimage(uint8_t bitpix, int w, int h);
int cc_copyimage(cc_IMG *dest, cc_IMG *src, int isshm);
void cc_freeimage(cc_IMG **i);
const char *cc_hresult2str(cc_hresult r); const char *cc_hresult2str(cc_hresult r);
cc_hresult cc_str2hresult(const char *str); cc_hresult cc_str2hresult(const char *str);
int cc_setNtries(int n); int cc_setNtries(int n);

View File

@@ -196,6 +196,7 @@ do{ int status = 0, kt = 0; \
// return FALSE if failed // return FALSE if failed
int saveFITS(cc_IMG *img, char **outp){ int saveFITS(cc_IMG *img, char **outp){
int ret = FALSE; int ret = FALSE;
if(!img || !img->data || !outp) return FALSE;
char fnam[PATH_MAX+1]; char fnam[PATH_MAX+1];
if(!GP->outfile && !GP->outfileprefix){ if(!GP->outfile && !GP->outfileprefix){
LOGWARN("Image not saved: neither filename nor filename prefix pointed"); LOGWARN("Image not saved: neither filename nor filename prefix pointed");
@@ -221,6 +222,7 @@ int saveFITS(cc_IMG *img, char **outp){
LOGERR("Can't save image with prefix %s", GP->outfileprefix); LOGERR("Can't save image with prefix %s", GP->outfileprefix);
} }
} }
pthread_mutex_lock(&img->mutex);
int width = img->w, height = img->h; int width = img->w, height = img->h;
long naxes[2] = {width, height}; long naxes[2] = {width, height};
struct tm *tm_time; struct tm *tm_time;
@@ -275,6 +277,7 @@ fits_write_history(fp, bufhdr->buf, &s);
if(fitserror) goto cloerr; if(fitserror) goto cloerr;
TRYFITS(fits_close_file, fp); TRYFITS(fits_close_file, fp);
cloerr: cloerr:
pthread_mutex_unlock(&img->mutex);
if(fitserror == 0){ if(fitserror == 0){
LOGMSG("Save file '%s'", fnam); LOGMSG("Save file '%s'", fnam);
verbose(VERBOSE_PRIMARY, _("File saved as '%s'"), fnam); verbose(VERBOSE_PRIMARY, _("File saved as '%s'"), fnam);
@@ -839,17 +842,16 @@ static volatile int exitgrab = FALSE;
static volatile size_t lastgrabno = 0; static volatile size_t lastgrabno = 0;
static void *grabnext(void *arg){ static void *grabnext(void *arg){
FNAME(); FNAME();
cc_IMG *ima = (cc_IMG*) arg; if(!arg) return NULL;
cc_IMG *ima = (cc_IMG*)arg;
do{ do{
if(exitgrab) return NULL; if(exitgrab) return NULL;
TIMESTAMP("Start next exp"); TIMESTAMP("Start next exp");
TIMEINIT(); TIMEINIT();
if(!ima || !camera) return NULL; if(!camera) return NULL;
if(!camera->startexposition) ERRX(_("Camera plugin have no function `start exposition`")); if(!camera->startexposition) ERRX(_("Camera plugin have no function `start exposition`"));
if(!camera->startexposition()){ if(!camera->startexposition()){
WARNX(_("Can't start exposition")); ERRX(_("Can't start exposition"));
usleep(10000);
continue;
} }
cc_capture_status cs = CAPTURE_ABORTED; cc_capture_status cs = CAPTURE_ABORTED;
TIMESTAMP("Poll"); TIMESTAMP("Poll");
@@ -866,6 +868,7 @@ static void *grabnext(void *arg){
//calculate_stat(ima); //calculate_stat(ima);
TIMESTAMP("OK"); TIMESTAMP("OK");
}while(1); }while(1);
return NULL;
} }
@@ -875,7 +878,7 @@ static void *grabnext(void *arg){
* @param img - pointer to cc_IMG* (if cc_IMG* is NULL, will be allocated here) * @param img - pointer to cc_IMG* (if cc_IMG* is NULL, will be allocated here)
* @return TRUE if new image available * @return TRUE if new image available
*/ */
int ccdcaptured(cc_IMG **imgptr){ int ccdcaptured(cc_IMG *imgptr){
if(!imgptr) return FALSE; if(!imgptr) return FALSE;
//TIMESTAMP("ccdcaptured() start"); //TIMESTAMP("ccdcaptured() start");
static pthread_t grabthread = 0; static pthread_t grabthread = 0;
@@ -891,32 +894,21 @@ int ccdcaptured(cc_IMG **imgptr){
DBG("OK"); DBG("OK");
return FALSE; return FALSE;
} }
cc_frameformat fmt = camera->geometry; //cc_frameformat fmt = camera->geometry;
int raw_width = fmt.w / GP->hbin, raw_height = fmt.h / GP->vbin; //int raw_width = fmt.w / GP->hbin, raw_height = fmt.h / GP->vbin;
cc_IMG *ima = NULL;
if(*imgptr && ((*imgptr)->w != raw_width || (*imgptr)->h != raw_height)) FREE(*imgptr);
if(!*imgptr){
uint16_t *img = MALLOC(uint16_t, raw_width * raw_height);
DBG("\n\nAllocated image 2x%dx%d=%d", raw_width, raw_height, 2 * raw_width * raw_height);
ima = MALLOC(cc_IMG, 1);
ima->data = img;
ima->w = raw_width;
ima->h = raw_height;
*imgptr = ima;
}else ima = *imgptr;
if(!grabthread){ // start new grab if(!grabthread){ // start new grab
TIMESTAMP("Start new grab"); TIMESTAMP("Start new grab");
TIMEINIT(); TIMEINIT();
if(pthread_create(&grabthread, NULL, &grabnext, (void*)ima)){ if(pthread_create(&grabthread, NULL, &grabnext, (void*)imgptr)){
WARN(_("Can't create grabbing thread")); WARN(_("Can't create grabbing thread"));
grabthread = 0; grabthread = 0;
} }
}else{ // grab in process }else{ // grab in process
if(ima->imnumber != lastgrabno){ // done if(imgptr->imnumber != lastgrabno){ // done
/*ssize_t delta = ima->imnumber - lastgrabno; /*ssize_t delta = ima->imnumber - lastgrabno;
if(delta > 0 && delta != 1) WARNX("ccdcaptured(): missed %zd images", delta-1);*/ if(delta > 0 && delta != 1) WARNX("ccdcaptured(): missed %zd images", delta-1);*/
lastgrabno = ima->imnumber; lastgrabno = imgptr->imnumber;
TIMESTAMP("Got exp #%zd", lastgrabno); TIMESTAMP("Got exp #%zd", lastgrabno);
framerate(); framerate();
return TRUE; return TRUE;
@@ -963,9 +955,6 @@ int start_socket(int isserver){
} }
DBG("Close socket"); DBG("Close socket");
close(sock); close(sock);
if(isserver){ if(isserver) close(imsock);
close(imsock);
signals(0);
}
return 0; return 0;
} }

View File

@@ -40,7 +40,7 @@ void closewheel();
void closecam(); void closecam();
#ifdef IMAGEVIEW #ifdef IMAGEVIEW
void framerate(); void framerate();
int ccdcaptured(cc_IMG **img); int ccdcaptured(cc_IMG *img);
#endif #endif
int start_socket(int isserver); int start_socket(int isserver);

374
client.c
View File

@@ -51,9 +51,7 @@ static int xc0,yc0,xc1,yc1; // current format
static volatile atomic_int grabno = 0; static volatile atomic_int grabno = 0;
static int oldgrabno = 0; static int oldgrabno = 0;
// IPC key for shared memory // IPC key for shared memory
static cc_IMG ima = {0}, *shmima = NULL; // ima - local storage, shmima - shm (if available) static cc_IMG *locima = NULL, *shmima = NULL; // ima - local storage, shmima - shm (if available)
static size_t imbufsz = 0; // image buffer for allocated `ima`
static uint8_t *imbuf = NULL; // we can't use shmima->data as it belongs to server, so we use `imbuf` and set ima.data = imbuf
static volatile atomic_int current_image_number = -1; // for net-parser - last number of exposed image static volatile atomic_int current_image_number = -1; // for net-parser - last number of exposed image
#if 0 #if 0
@@ -82,7 +80,7 @@ static char *readmsg(int fd){
#endif #endif
#define CMP_ANS(cmd, ans) strncmp(cmd, ans, sizeof(cmd)-1) #define CMP_ANS(cmd, ans) strncmp(cmd, ans, sizeof(cmd)-1)
// parser of CCD server messages; return TRUE to exit from polling cycle of `getans` (if receive 'FAIL', 'OK' or 'BUSY') // parser of CCD server messages; return parsing result
static cc_hresult parseans(char *ans){ static cc_hresult parseans(char *ans){
if(!ans) return CC_RESULT_BADKEY; if(!ans) return CC_RESULT_BADKEY;
//TIMESTAMP("parseans() begin"); //TIMESTAMP("parseans() begin");
@@ -97,18 +95,17 @@ static cc_hresult parseans(char *ans){
} }
char *val = cc_get_keyval(&ans); // now `ans` is a key and `val` its value char *val = cc_get_keyval(&ans); // now `ans` is a key and `val` its value
if(0 == CMP_ANS(CC_CMD_EXPSTATE, ans)){ if(0 == CMP_ANS(CC_CMD_EXPSTATE, ans)){
int st = atoi(val); int st = atoi(val), oldst = atomic_load(&expstate);
atomic_store(&expstate, st); if(oldst != CAMERA_FRAMERDY){
DBG("Current state: %d", atomic_load(&expstate)); atomic_store(&expstate, st);
return CC_RESULT_SILENCE; DBG("Current state: %d", atomic_load(&expstate));
}
}else if(0 == CMP_ANS(CC_CMD_FRAMEMAX, ans)){ }else if(0 == CMP_ANS(CC_CMD_FRAMEMAX, ans)){
sscanf(val, "%d,%d,%d,%d", &xm0, &ym0, &xm1, &ym1); sscanf(val, "%d,%d,%d,%d", &xm0, &ym0, &xm1, &ym1);
DBG("Got maxformat: %d,%d,%d,%d", xm0, ym0, xm1, ym1); DBG("Got maxformat: %d,%d,%d,%d", xm0, ym0, xm1, ym1);
return CC_RESULT_SILENCE;
}else if(0 == CMP_ANS(CC_CMD_FRAMEFORMAT, ans)){ }else if(0 == CMP_ANS(CC_CMD_FRAMEFORMAT, ans)){
sscanf(val, "%d,%d,%d,%d", &xc0, &yc0, &xc1, &yc1); sscanf(val, "%d,%d,%d,%d", &xc0, &yc0, &xc1, &yc1);
DBG("Got current format: %d,%d,%d,%d", xc0, yc0, xc1, yc1); DBG("Got current format: %d,%d,%d,%d", xc0, yc0, xc1, yc1);
return CC_RESULT_SILENCE;
}else if(0 == CMP_ANS(CC_CMD_IMNUMBER, ans)){ }else if(0 == CMP_ANS(CC_CMD_IMNUMBER, ans)){
atomic_store(&current_image_number, atoi(val)); atomic_store(&current_image_number, atoi(val));
} }
@@ -120,46 +117,62 @@ static cc_hresult parseans(char *ans){
// if msg != NULL - wait for it in answer // if msg != NULL - wait for it in answer
static int getans(int sock, const char *msg){ static int getans(int sock, const char *msg){
double t0 = sl_dtime(); double t0 = sl_dtime();
char buf[BUFSIZ+1]; static sl_ringbuffer_t *RB = NULL;
int idx = 0; if(!RB){
char *ans = NULL; RB = sl_RB_new(BUFSIZ);
if(!RB){
WARNX(_("Can't allocate buffer"));
return FALSE;
}
}
TIMESTAMP("GetAns(%s)", msg); TIMESTAMP("GetAns(%s)", msg);
double tmout = answer_timeout + 5.; // make first timeout larger for slow networks double tmout = answer_timeout + 5.; // make first timeout larger for slow networks
// TODO: increase first timeout up to 15-30s (add key?) // TODO: increase first timeout up to 15-30s (add key?)
cc_hresult res = CC_RESULT_FAIL; cc_hresult res = CC_RESULT_FAIL;
char buf[256];
while(sl_dtime() - t0 < tmout){ while(sl_dtime() - t0 < tmout){
ans = NULL;
if(1 == sl_canread(sock)){ if(1 == sl_canread(sock)){
ssize_t got = read(sock, buf+idx, BUFSIZ-idx); ssize_t got = read(sock, buf, 255);
if(got > 0){ if(got > 0){
idx += got; DBG("Got %zd bytes (%s)", got, buf);
buf[idx] = 0; if(got != (ssize_t)sl_RB_write(RB, (uint8_t*)buf, got)){
char *nl = strchr(buf, '\n'); WARNX("Ringbuffer overflow??");
if(nl){ sl_RB_clearbuf(RB);
*nl = 0; return FALSE;
ans = buf;
DBG("got '%s'", ans);
} }
}else if(got < 0){
DBG("ERR: got=%zd", got);
if(errno == EAGAIN){
usleep(1000);
continue;
}
WARNX(_("Server disconnected?"));
LOGWARN("Server disconnected?");
return FALSE;
} }
} }
if(!ans) continue; if(sl_RB_hasbyte(RB, '\n') < 0) continue;
DBG("Got newline in RB");
if(sl_RB_readline(RB, buf, 255) < 1){
WARNX(_("Got empty string"));
continue;
}
// got answer -> make timeout less // got answer -> make timeout less
tmout = answer_timeout; tmout = answer_timeout;
t0 = sl_dtime(); t0 = sl_dtime();
TIMESTAMP("Got from server: %s", ans); TIMESTAMP("Got from server: %s", buf);
verbose(VERBOSE_PRIMARY, "\t%s", ans); verbose(VERBOSE_PRIMARY, "\t%s", buf);
DBG("1 msg-> %s, ans -> %s", msg, ans); DBG("1 msg-> %s, ans -> %s", msg, buf);
res = parseans(ans); res = parseans(buf);
DBG("2 msg-> %s, ans -> %s; result: %d", msg, ans, res); DBG("2 msg-> %s, ans -> %s; result: %d", msg, buf, res);
if(msg){ if(msg){
if(res != CC_RESULT_SILENCE || strncmp(ans, msg, strlen(msg))) continue; if(res != CC_RESULT_SILENCE || strncmp(buf, msg, strlen(msg))) continue;
else res = CC_RESULT_OK; else res = CC_RESULT_OK;
} }
DBG("Got answer -> break"); DBG("Got answer -> break");
break; break;
} }
TIMESTAMP("GetAns(%s), ans: '%s', result: %d", msg, ans, res); TIMESTAMP("GetAns(%s), result: %d", msg, res);
if(!ans) DBG("Got no answer from server; result=%d", res);
if(res == CC_RESULT_OK) return TRUE; if(res == CC_RESULT_OK) return TRUE;
return FALSE; return FALSE;
} }
@@ -269,7 +282,6 @@ static int readNbytes(int fd, size_t N, uint8_t *buf){
size_t got = 0, need = N; size_t got = 0, need = N;
double t0 = sl_dtime(); double t0 = sl_dtime();
while(sl_dtime() - t0 < CC_CLIENT_TIMEOUT /*&& sl_canread(fd)*/ && need){ while(sl_dtime() - t0 < CC_CLIENT_TIMEOUT /*&& sl_canread(fd)*/ && need){
t0 = sl_dtime();
ssize_t rd = read(fd, buf + got, need); ssize_t rd = read(fd, buf + got, need);
if(rd <= 0){ if(rd <= 0){
if(errno == EAGAIN || errno == EWOULDBLOCK) continue; if(errno == EAGAIN || errno == EWOULDBLOCK) continue;
@@ -277,11 +289,119 @@ static int readNbytes(int fd, size_t N, uint8_t *buf){
signals(1); signals(1);
} }
got += rd; need -= rd; got += rd; need -= rd;
t0 = sl_dtime();
} }
if(need) return FALSE; // didn't got whole packet if(need) return FALSE; // didn't got whole packet
return TRUE; return TRUE;
} }
static int refresh_shm(){
if(!shmima){
shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
if(shmima){
cc_init_sem(FALSE);
DBG("Got access to shared memory");
return TRUE;
}
return FALSE;
}
int shmid = shmget(GP->shmkey, 0, 0);
if(shmid < 0){
// Segment was deleted
shmdt(shmima);
shmima = NULL;
// refresh connection
return refresh_shm();
}
struct shmid_ds buf;
if(shmctl(shmid, IPC_STAT, &buf) == 0){
if(buf.shm_perm.mode & SHM_DEST){ // marked for deletion
shmdt(shmima);
shmima = NULL;
return refresh_shm();
}
// valid segment
return TRUE;
}
return FALSE;
}
static int lockshm(){
int locked = FALSE;
double t0 = sl_dtime();
while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){
if(cc_lock_shm(FALSE)){
DBG("Locked");
locked = TRUE;
break;
}
usleep(100);
}
if(!locked) WARNX(_("Can't lock shared memory"));
return locked;
}
static int getshmimage(int *shmlocked){
if(!shmlocked || !shmima) return FALSE;
if(!refresh_shm()) return FALSE;
if(!*shmlocked && !(*shmlocked = lockshm())) return FALSE;
DBG("Server's imno: %zd, bytelen: %zd", shmima->imnumber, shmima->bytelen);
int ret = cc_copyimage(locima, shmima, TRUE);
TIMESTAMP("Got by shared memory");
return ret;
}
static int getsocksizes(int *imsock){
if(!imsock || *imsock > -1) return FALSE;
DBG("Open socket @ %s", GP->imageport);
*imsock = cc_open_socket(FALSE, GP->imageport, TRUE);
if(*imsock < 0){
WARNX(_("Can't open image transport socket"));
return FALSE;
}
// get image size
cc_IMG ima;
if(!readNbytes(*imsock, sizeof(cc_IMG), (uint8_t*)&ima)){
WARNX(_("Can't read image header over socket"));
return FALSE;
}
if(ima.MAGICK != CC_SHM_MAGIC || ima.bytelen < 1) return FALSE;
// now copy fields
#define COPY(field) locima->field = ima.field;
COPY(timestamp);
COPY(bitpix);
COPY(w);
COPY(h);
COPY(bytelen);
COPY(imnumber);
#undef COPY
return TRUE;
}
static int getsockimage(int *imsock){
if(!imsock || *imsock < 0) return FALSE;
pthread_mutex_lock(&locima->mutex);
if(locima->datasize < locima->bytelen){
size_t newsz = 1024 * (1 + locima->bytelen / 1024);
void *nxt = realloc(locima->data, newsz);
if(!nxt){
LOGERR("realloc() failed");
WARN("realloc()");
pthread_mutex_unlock(&locima->mutex);
return FALSE;
}
locima->data = nxt;
}
int ok = readNbytes(*imsock, locima->bytelen, locima->data);
pthread_mutex_unlock(&locima->mutex);
if(!ok){
WARNX(_("Can't read image data"));
return FALSE;
}
TIMESTAMP("Got by socket");
return TRUE;
}
/** /**
* @brief getimage - read image from shared memory or socket * @brief getimage - read image from shared memory or socket
* @param askheader == TRUE for storing FITS-header * @param askheader == TRUE for storing FITS-header
@@ -291,132 +411,85 @@ static int getimage(int askheader){
FNAME(); FNAME();
int imsock = -1, shmlocked = FALSE, ret = FALSE; int imsock = -1, shmlocked = FALSE, ret = FALSE;
static double oldtimestamp = -1.; static double oldtimestamp = -1.;
TIMESTAMP("Get image sizes"); TIMESTAMP("Get image sizes (or full image over SHM)");
if(shmima){ // read image from shared memory if(!locima){
DBG("Try to read from SHM"); locima = cc_newimage(16, 1024, 1024);
double t0 = sl_dtime(); if(!locima){
while(sl_dtime() - t0 < MUTEX_LOCK_TMOUT){ WARN("calloc()"); return FALSE;
if(cc_lock_shm(FALSE)){
DBG("Locked");
shmlocked = TRUE;
break;
}
usleep(100);
}
if(!shmlocked){
WARNX(_("Can't lock shared memory"));
return FALSE;
}
memcpy(&ima, shmima, sizeof(cc_IMG));
}else{ // get image by socket
if(imsock < 0){
DBG("Open socket @ %s", GP->imageport);
imsock = cc_open_socket(FALSE, GP->imageport, TRUE);
}
if(imsock < 0) ERRX(_("getimage(): can't open image transport socket"));
// get image size
if(!readNbytes(imsock, sizeof(cc_IMG), (uint8_t*)&ima)){
WARNX(_("Can't read image header"));
goto eofg;
} }
} }
if(ima.MAGICK != CC_SHM_MAGIC){ ret = getshmimage(&shmlocked);
WARNX(_("Wrong image: bad magick")); if(!ret){ // can't get by shm -> try over NET
goto eofg; DBG("Try to get image over network");
} if(!getsocksizes(&imsock)) goto eofg;
if(ima.bytelen < 1){ TIMESTAMP("Start of data read");
WARNX(_("Wrong image size")); ret = getsockimage(&imsock);
goto eofg; if(!ret){
}
DBG("bytelen=%zd, w=%d, h=%d; bitpix=%d", ima.bytelen, ima.w, ima.h, ima.bitpix);
// realloc memory if needed
if(imbufsz < ima.bytelen){
size_t newsz = 1024 * (1 + ima.bytelen / 1024);
DBG("Reallocate memory from %zd to %zd", imbufsz, newsz);
uint8_t *b = imbuf;
imbuf = realloc(imbuf, imbufsz);
if(imbuf){
imbufsz = newsz;
DBG("Size after realloc: %zd", imbufsz);
}else{
WARNX(_("Can't reallocate memory for image buffer"));
imbuf = b;
goto eofg;
}
}
ima.data = imbuf; // renew this value each time after getting `ima` from server
TIMESTAMP("Start of data read");
if(shmima){
uint8_t *datastart = ((uint8_t*)shmima) + sizeof(cc_IMG);
DBG("first image byte: %d; bytelen: %zd", *datastart, ima.bytelen);
memcpy(imbuf, datastart, ima.bytelen);
TIMESTAMP("Got by shared memory");
if(!askheader){
cc_unlock_shm();
shmlocked = FALSE;
}
ret = TRUE;
}else{
if(!readNbytes(imsock, ima.bytelen, imbuf)){
WARNX(_("Can't read image data")); WARNX(_("Can't read image data"));
goto eofg; goto eofg;
} }
ret = TRUE;
TIMESTAMP("Got by socket");
} }
DBG("timestamps new-old=%g; imno: %zd", ima.timestamp - oldtimestamp, ima.imnumber); DBG("timestamps new-old=%g; imno: %zd", locima->timestamp - oldtimestamp, locima->imnumber);
if(ima.timestamp != oldtimestamp){ // test if image is really new if(locima->timestamp != oldtimestamp){ // test if image is really new
oldtimestamp = ima.timestamp; oldtimestamp = locima->timestamp;
atomic_store(&grabno, ima.imnumber); atomic_store(&grabno, locima->imnumber);
TIMESTAMP("Got image #%zd", ima.imnumber); TIMESTAMP("Got image #%zd", locima->imnumber);
if(askheader){ // read FITS-header for later saving if(askheader){ // read FITS-header for later saving
if(shmima){ if(shmima){
size_t rsz = FLEN_CARD * ima.headerstrings; if(locima->headerstrings > FITS_HEADER_STRINGS_MAX){
memcpy(ima.fitsheader, shmima->fitsheader, rsz); WARNX(_("Too many FITS headers, truncating"));
locima->headerstrings = FITS_HEADER_STRINGS_MAX;
}
size_t rsz = FLEN_CARD * locima->headerstrings;
memcpy(locima->fitsheader, shmima->fitsheader, rsz);
cc_unlock_shm();
shmlocked = FALSE;
}else{ }else{
uint8_t card[FLEN_CARD]; uint8_t card[FLEN_CARD];
for(size_t i = 0; i < ima.headerstrings; ++i){ for(size_t i = 0; i < locima->headerstrings; ++i){
if(!readNbytes(imsock, FLEN_CARD, card)){ if(!readNbytes(imsock, FLEN_CARD, card)){
WARNX(_("Can't read full header, got %zd records from %zd"), i, ima.headerstrings); WARNX(_("Can't read full header, got %zd records from %zd"), i, locima->headerstrings);
break; break;
} }
memcpy(&ima.fitsheader[i], card, FLEN_CARD); memcpy(&locima->fitsheader[i], card, FLEN_CARD);
} }
close(imsock);
imsock = -1;
} }
if(GP->addhdr){ // add records from client-side files if(GP->addhdr){ // add records from client-side files
char **nxtfile = GP->addhdr; char **nxtfile = GP->addhdr;
while(*nxtfile){ while(*nxtfile){
cc_kwfromfile(&ima, *(nxtfile++)); cc_kwfromfile(locima, *(nxtfile++));
} }
} }
}else ima.headerstrings = 0; }else locima->headerstrings = 0;
}else WARNX("Still got old image"); }else WARNX(_("Still got old image"));
eofg: eofg:
if(imsock != -1) close(imsock); // reopen in next time in case of error if(imsock > -1) close(imsock); // reopen in next time in case of error
if(shmlocked) cc_unlock_shm(); if(shmlocked) cc_unlock_shm();
return ret; return ret;
} }
// get number of current image; return number or -1 if got error/timeout // get number of current image
static int curImNo(int sock){ static int curImNo(int sock){
int N = -1;
if(shmima){ if(shmima){
if(!cc_lock_shm(FALSE)) return -1; if(lockshm()){
int CurNo = shmima->imnumber; N = shmima->imnumber;
cc_unlock_shm(); cc_unlock_shm();
return CurNo; atomic_store(&current_image_number, N);
}
} }
// no shared memory: try to get number over TCP if(N < 0){ // no shared memory: try to get number over TCP
SENDCMDW(CC_CMD_IMNUMBER); SENDCMDW(CC_CMD_IMNUMBER);
return atomic_load(&current_image_number); N = atomic_load(&current_image_number);
}
return N;
} }
void client(int sock){ void client(int sock){
if(sock < 0) ERRX(_("Can't run without command socket")); if(sock < 0) ERRX(_("Can't run without command socket"));
if(!GP->forceimsock && !shmima){ // init shm buffer if user don't ask to force workign through image socket if(!GP->forceimsock) refresh_shm(); // init shm buffer if user don't ask to force workign through image socket
shmima = cc_getshm(GP->shmkey, 0); // try to init client shm
if(shmima) cc_init_sem(FALSE);
DBG("Got access to shared memory: %s", shmima ? "OK" : "FAIL");
}
if(GP->restart){ if(GP->restart){
SENDCMDW(CC_CMD_RESTART); SENDCMDW(CC_CMD_RESTART);
return; return;
@@ -426,6 +499,7 @@ void client(int sock){
TIMESTAMP("Got headers"); TIMESTAMP("Got headers");
double t0 = sl_dtime(), tw, tstart; double t0 = sl_dtime(), tw, tstart;
int Nremain = 0, nframe = 1; int Nremain = 0, nframe = 1;
atomic_store(&expstate, CAMERA_IDLE); // could be changed earlier
// if client gives filename/prefix or Nframes, make exposition // if client gives filename/prefix or Nframes, make exposition
if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){ if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){
Nremain = GP->nframes; Nremain = GP->nframes;
@@ -434,7 +508,6 @@ void client(int sock){
} else return; // just send headers and exit } else return; // just send headers and exit
double timeout = CC_CLIENT_TIMEOUT; double timeout = CC_CLIENT_TIMEOUT;
verbose(VERBOSE_PRIMARY, _("Exposing frame 1...")); verbose(VERBOSE_PRIMARY, _("Exposing frame 1..."));
atomic_store(&expstate, CAMERA_CAPTURE); // could be changed earlier
DBG("Current state: %d", atomic_load(&expstate)); DBG("Current state: %d", atomic_load(&expstate));
verbose(VERBOSE_PRIMARY, _("Wait for exposition end")); verbose(VERBOSE_PRIMARY, _("Wait for exposition end"));
t0 = sl_dtime(); t0 = sl_dtime();
@@ -443,6 +516,7 @@ void client(int sock){
while(sl_dtime() - t0 < timeout){ while(sl_dtime() - t0 < timeout){
if(sl_dtime() - tw > CC_WAIT_TIMEOUT){ if(sl_dtime() - tw > CC_WAIT_TIMEOUT){
SENDCMDW(CC_CMD_TREMAIN); // get remained time SENDCMDW(CC_CMD_TREMAIN); // get remained time
SENDCMDW(CC_CMD_EXPSTATE);
tw = sl_dtime(); tw = sl_dtime();
usleep(100000); usleep(100000);
} }
@@ -450,9 +524,6 @@ void client(int sock){
t0 = sl_dtime(); // refresh timeout until exp not ends t0 = sl_dtime(); // refresh timeout until exp not ends
usleep(1000); usleep(1000);
continue; continue;
}else{
SENDCMDW(CC_CMD_EXPSTATE);
usleep(1000);
} }
int curst = atomic_load(&expstate); int curst = atomic_load(&expstate);
DBG("Current state: %d", curst); DBG("Current state: %d", curst);
@@ -465,23 +536,23 @@ void client(int sock){
} }
continue; continue;
} }
if(curst == CAMERA_FRAMERDY){ int cur = curImNo(sock);
if(curst == CAMERA_FRAMERDY || cur != lastImNo){
atomic_store(&expstate, CAMERA_IDLE); atomic_store(&expstate, CAMERA_IDLE);
int cur = curImNo(sock); DBG("Current imno: %d", cur);
DBG("Current state: %d, imno: %d", atomic_load(&expstate), cur);
if(Nremain > 1){ // start next capture if(Nremain > 1){ // start next capture
verbose(VERBOSE_PRIMARY, _("Exposing frame %d..."), nframe); verbose(VERBOSE_PRIMARY, _("Exposing frame %d..."), nframe);
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE);
tstart = sl_dtime(); tstart = sl_dtime();
} }
int failed = TRUE; int failed = TRUE;
if(lastImNo < cur){ if(lastImNo != cur){
lastImNo = cur; lastImNo = cur;
verbose(VERBOSE_SECONDARY, _("Frame ready, try to grab")); verbose(VERBOSE_SECONDARY, _("Frame ready, try to grab"));
if(!getimage(TRUE)){ if(!getimage(TRUE)){
WARNX(_("Can't get next image")); WARNX(_("Can't get next image"));
}else{ }else{
if(saveFITS(&ima, &lastfilename)){ if(saveFITS(locima, &lastfilename)){
--Nremain; --Nremain;
++nframe; ++nframe;
failed = FALSE; failed = FALSE;
@@ -534,9 +605,8 @@ static void *grabnext(void _U_ *arg){
int lastImNo = curImNo(sock); int lastImNo = curImNo(sock);
while(1){ while(1){
if(!getWin()) exit(1); if(!getWin()) exit(1);
TIMESTAMP("End of cycle, start new"); TIMESTAMP("Start of capturing cycle");
atomic_store(&expstate, CAMERA_CAPTURE); atomic_store(&expstate, CAMERA_IDLE);
DBG("Current state: %d", atomic_load(&expstate));
TIMEINIT(); TIMEINIT();
SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // start capture SENDMSGW(CC_CMD_EXPSTATE, "=%d", CAMERA_CAPTURE); // start capture
double timeout = GP->exptime + CC_CLIENT_TIMEOUT, t0 = sl_dtime(); double timeout = GP->exptime + CC_CLIENT_TIMEOUT, t0 = sl_dtime();
@@ -547,24 +617,29 @@ static void *grabnext(void _U_ *arg){
} }
TIMESTAMP("Wait for exposition ends (%g s), sleep for %dus", timeout, sleept); TIMESTAMP("Wait for exposition ends (%g s), sleep for %dus", timeout, sleept);
int curst = CAMERA_CAPTURE; int curst = CAMERA_CAPTURE;
int cur = lastImNo;
SENDCMDW(CC_CMD_EXPSTATE);
while(sl_dtime() - t0 < timeout){ while(sl_dtime() - t0 < timeout){
DBG("start sleep for %dus", sleept); DBG("start sleep for %dus", sleept);
usleep(sleept); usleep(sleept);
SENDCMDW(CC_CMD_EXPSTATE); cur = curImNo(sock);
curst = atomic_load(&expstate); curst = atomic_load(&expstate);
if(curst != CAMERA_CAPTURE) break; if(curst != CAMERA_CAPTURE || cur != lastImNo) break;
if(sl_dtime() - t0 > GP->exptime && sleept != CC_IMWAIT_SLEEP){ if(sl_dtime() - t0 > GP->exptime && sleept != CC_IMWAIT_SLEEP){
DBG("Set sleeping time to %dus", sleept);
sleept = CC_IMWAIT_SLEEP; sleept = CC_IMWAIT_SLEEP;
DBG("Set sleeping time to %dus", sleept);
SENDCMDW(CC_CMD_EXPSTATE);
} }
} }
int cur = curImNo(sock); SENDCMDW(CC_CMD_EXPSTATE);
if(sl_dtime() - t0 >= timeout || curst != CAMERA_FRAMERDY || cur <= lastImNo){ curst = atomic_load(&expstate);
if(curst == CAMERA_ERROR) ERRX(_("Camera in error state"));
if(sl_dtime() - t0 >= timeout && cur != lastImNo){
WARNX(_("Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d (timeout: %g)"), curst, sl_dtime() - t0, lastImNo, cur, timeout); WARNX(_("Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d (timeout: %g)"), curst, sl_dtime() - t0, lastImNo, cur, timeout);
continue; continue;
} }
lastImNo = cur; lastImNo = cur;
TIMESTAMP("Frame ready (%d from server's start)", cur); TIMESTAMP("Frame ready (%d from start)", cur);
getimage(FALSE); getimage(FALSE);
} }
return NULL; return NULL;
@@ -585,7 +660,7 @@ static void *waitimage(void _U_ *arg){
t0 = tcur; t0 = tcur;
} }
int cur = curImNo(sock); int cur = curImNo(sock);
if(cur <= lastImNo){ if(cur == lastImNo){
usleep(CC_IMWAIT_SLEEP); usleep(CC_IMWAIT_SLEEP);
continue; continue;
} }
@@ -600,7 +675,7 @@ static void *waitimage(void _U_ *arg){
} }
// try to capture images for viewer // try to capture images for viewer
int sockcaptured(cc_IMG **imgptr){ int sockcaptured(cc_IMG *imgptr){
//TIMESTAMP("sockcaptured() start"); //TIMESTAMP("sockcaptured() start");
if(!imgptr) return FALSE; if(!imgptr) return FALSE;
static pthread_t grabthread = 0; static pthread_t grabthread = 0;
@@ -634,13 +709,12 @@ int sockcaptured(cc_IMG **imgptr){
}else{ // grab in process }else{ // grab in process
int curno = atomic_load(&grabno); int curno = atomic_load(&grabno);
if(curno != oldgrabno){ // image is ready if(curno != oldgrabno){ // image is ready
TIMESTAMP("Image #%d ready", curno); TIMESTAMP("Image #%d ready (old was %d)", curno, oldgrabno);
if(*imgptr && (*imgptr != &ima)) free(*imgptr);
*imgptr = &ima;
oldgrabno = curno; oldgrabno = curno;
framerate(); framerate();
//TIMESTAMP("sockcaptured() end, return TRUE"); //TIMESTAMP("sockcaptured() end, return TRUE");
return TRUE; int ret = cc_copyimage(imgptr, locima, FALSE);
return ret;
} }
} }
//TIMESTAMP("sockcaptured() end, return FALSE"); //TIMESTAMP("sockcaptured() end, return FALSE");

View File

@@ -24,5 +24,5 @@
void client(int fd); void client(int fd);
#ifdef IMAGEVIEW #ifdef IMAGEVIEW
void init_grab_sock(int sock); void init_grab_sock(int sock);
int sockcaptured(cc_IMG **img); int sockcaptured(cc_IMG *img);
#endif #endif

View File

@@ -288,13 +288,15 @@ static void createGLwin(char *title, int w, int h, rawimage *rawdata){
if(!initialized) imageview_init(); if(!initialized) imageview_init();
if(win) killwindow(); if(win) killwindow();
win = MALLOC(windowData, 1); win = MALLOC(windowData, 1);
int wh = w * h;
win->rawdata = MALLOC(uint8_t, wh);
rawimage *raw; rawimage *raw;
if(rawdata){ if(rawdata){
raw = rawdata; raw = rawdata;
}else{ }else{
raw = MALLOC(rawimage, 1); raw = MALLOC(rawimage, 1);
if(raw){ if(raw){
raw->rawdata = MALLOC(GLubyte, w*h*3); raw->rawdata = MALLOC(GLubyte, wh*3);
raw->w = w; raw->w = w;
raw->h = h; raw->h = h;
raw->changed = 1; raw->changed = 1;
@@ -445,15 +447,12 @@ result: 0.0014689s
/** /**
* @brief equalize - hystogram equalization * @brief equalize - hystogram equalization
* @param ori (io) - input/output data * @param img (i) - input image
* @param w,h - image width and height
* @return data allocated here
*/ */
static uint8_t *equalize(cc_IMG *img, int w, int h){ static void equalize(cc_IMG *img){
uint8_t *retn = MALLOC(uint8_t, w*h);
double orig_hysto[0x10000] = {0.}; // original hystogram double orig_hysto[0x10000] = {0.}; // original hystogram
uint8_t eq_levls[0x10000] = {0}; // levels to convert: newpix = eq_levls[oldpix] uint8_t eq_levls[0x10000] = {0}; // levels to convert: newpix = eq_levls[oldpix]
int s = w*h; int s = img->h * img->w;
//double t0 = dtime(); //double t0 = dtime();
/* -- takes too long because of sync /* -- takes too long because of sync
#pragma omp parallel #pragma omp parallel
@@ -492,6 +491,7 @@ static uint8_t *equalize(cc_IMG *img, int w, int h){
} }
//WARNX("equal: %gs", dtime()-t0); //WARNX("equal: %gs", dtime()-t0);
//OMP_FOR() -- takes the same time! //OMP_FOR() -- takes the same time!
uint8_t *retn = win->rawdata;
if(bytes == 1){ if(bytes == 1){
uint8_t *data = (uint8_t*) img->data; uint8_t *data = (uint8_t*) img->data;
for(int i = 0; i < s; ++i){ for(int i = 0; i < s; ++i){
@@ -504,7 +504,6 @@ static uint8_t *equalize(cc_IMG *img, int w, int h){
} }
} }
//WARNX("result: %gs", dtime()-t0); //WARNX("result: %gs", dtime()-t0);
return retn;
} }
/* /*
no omp @ histo: no omp @ histo:
@@ -518,10 +517,9 @@ cuts: 0.00188208s
*/ */
// count image cuts as [median-sigma median+5sigma] // count image cuts as [median-sigma median+5sigma]
static uint8_t *mkcuts(cc_IMG *img, int w, int h){ static void mkcuts(cc_IMG *img){
uint8_t *retn = MALLOC(uint8_t, w*h);
int orig_hysto[0x10000] = {0.}; // original hystogram int orig_hysto[0x10000] = {0.}; // original hystogram
int s = w*h; int s = img->h * img->w;
double sum = 0., sum2 = 0.; double sum = 0., sum2 = 0.;
int bytes = cc_getNbytes(img); int bytes = cc_getNbytes(img);
TIMESTAMP("Make histogram"); TIMESTAMP("Make histogram");
@@ -584,9 +582,11 @@ static uint8_t *mkcuts(cc_IMG *img, int w, int h){
//WARNX("stat: %gs", dtime()-t0); //WARNX("stat: %gs", dtime()-t0);
// DEBUG: 2ms without OMP; 0.7ms with // DEBUG: 2ms without OMP; 0.7ms with
TIMESTAMP("apply cuts"); TIMESTAMP("apply cuts");
uint8_t *retn = win->rawdata;
if(bytes == 1){ if(bytes == 1){
DBG("8 bit data");
uint8_t *data = (uint8_t*) img->data; uint8_t *data = (uint8_t*) img->data;
OMP_FOR() //OMP_FOR()
for(int i = 0; i < s; ++i){ for(int i = 0; i < s; ++i){
uint16_t old = data[i]; uint16_t old = data[i];
if(old > high){ retn[i] = 255; continue; } if(old > high){ retn[i] = 255; continue; }
@@ -594,8 +594,9 @@ static uint8_t *mkcuts(cc_IMG *img, int w, int h){
retn[i] = (uint8_t)(A*(old - low)); retn[i] = (uint8_t)(A*(old - low));
} }
}else{ }else{
DBG("16 bit data");
uint16_t *data = (uint16_t*) img->data; uint16_t *data = (uint16_t*) img->data;
OMP_FOR() //OMP_FOR()
for(int i = 0; i < s; ++i){ for(int i = 0; i < s; ++i){
uint16_t old = data[i]; uint16_t old = data[i];
if(old > high){ retn[i] = 255; continue; } if(old > high){ retn[i] = 255; continue; }
@@ -603,8 +604,8 @@ static uint8_t *mkcuts(cc_IMG *img, int w, int h){
retn[i] = (uint8_t)(A*(old - low)); retn[i] = (uint8_t)(A*(old - low));
} }
} }
DBG("Done");
//WARNX("cuts: %gs", dtime()-t0); //WARNX("cuts: %gs", dtime()-t0);
return retn;
} }
static void change_displayed_image(cc_IMG *img){ static void change_displayed_image(cc_IMG *img){
@@ -614,29 +615,43 @@ static void change_displayed_image(cc_IMG *img){
TIMESTAMP("Got image #%zd", img->imnumber); TIMESTAMP("Got image #%zd", img->imnumber);
if(delta > 0 && delta != 1) WARNX(_("Missed %zd images"), delta-1); if(delta > 0 && delta != 1) WARNX(_("Missed %zd images"), delta-1);
lastN = img->imnumber; lastN = img->imnumber;
//pthread_mutex_lock(&win->mutex); pthread_mutex_lock(&win->mutex);
rawimage *im = win->image;
DBG("imh=%d, imw=%d, ch=%u, cw=%u", im->h, im->w, img->h, img->w);
int w = img->w, h = img->h, s = w*h; int w = img->w, h = img->h, s = w*h;
if(!im || (im->h != h) || (im->w != w)){ // realloc image to new size if(!win->image || ! win->rawdata || (win->image->h != h) || (win->image->w != w)){ // realloc image & raw image to new size
pthread_mutex_lock(&win->mutex); //pthread_mutex_lock(&win->mutex);
DBG("\n\nRealloc rawdata"); DBG("\n\nRealloc rawdata");
if(!im) im = MALLOC(rawimage, 1); uint8_t *raw = win->image->rawdata;
if(im->h*im->w < s) im->rawdata = realloc(im->rawdata, s*3); win->image->rawdata = realloc(win->image->rawdata, s*3);
im->h = h; im->w = w; if(!win->image->rawdata){
win->image = im; WARN("realloc()");
LOGERR("Realloc() error");
win->image->rawdata = raw;
return;
}
win->image->h = h; win->image->w = w;
raw = win->rawdata;
win->rawdata = realloc(win->rawdata, s);
if(!win->rawdata){
WARN("realloc()");
LOGERR("Realloc() error");
win->rawdata = raw;
return;
}
DBG("win->image changed"); DBG("win->image changed");
pthread_mutex_unlock(&win->mutex); //pthread_mutex_unlock(&win->mutex);
} }
rawimage *im = win->image;
uint8_t *raw = win->rawdata;
DBG("imh=%d, imw=%d, ch=%u, cw=%u", im->h, im->w, img->h, img->w);
TIMESTAMP("level correction"); TIMESTAMP("level correction");
uint8_t *newima;
if(imequalize){ if(imequalize){
DBG("equalize"); DBG("equalize");
newima = equalize(img, w, h); equalize(img);
}else{ }else{
DBG("cuts"); DBG("cuts");
newima = mkcuts(img, w, h); mkcuts(img);
} }
//pthread_mutex_lock(&win->mutex);
GLubyte *dst = im->rawdata; GLubyte *dst = im->rawdata;
TIMESTAMP("colorfun"); TIMESTAMP("colorfun");
//double t0 = dtime(); //double t0 = dtime();
@@ -645,17 +660,16 @@ static void change_displayed_image(cc_IMG *img){
OMP_FOR() OMP_FOR()
for(int i = 0; i < s; ++i){ for(int i = 0; i < s; ++i){
GLubyte *t = &dst[i*3]; GLubyte *t = &dst[i*3];
t[0] = t[1] = t[2] = colorfun(newima[i]); t[0] = t[1] = t[2] = colorfun(raw[i]);
} }
}else{ }else{
// without OMP: 3.6ms; with OMP: 1.7ms // without OMP: 3.6ms; with OMP: 1.7ms
OMP_FOR() OMP_FOR()
for(int i = 0; i < s; ++i){ for(int i = 0; i < s; ++i){
gray2rgb(colorfun(newima[i] / 256.), &dst[i*3]); gray2rgb(colorfun(raw[i] / 256.), &dst[i*3]);
} }
} }
//WARNX("Conversion time: %g", dtime()-t0); //WARNX("Conversion time: %g", dtime()-t0);
FREE(newima);
/* /*
// mirror image around Y // mirror image around Y
int w3 = w*3, h1 = h-1, wsz = w3*sizeof(GLubyte); int w3 = w*3, h1 = h-1, wsz = w3*sizeof(GLubyte);
@@ -672,7 +686,7 @@ static void change_displayed_image(cc_IMG *img){
}*/ }*/
DBG("Unlock"); DBG("Unlock");
win->image->changed = 1; win->image->changed = 1;
//pthread_mutex_unlock(&win->mutex); pthread_mutex_unlock(&win->mutex);
} }
void closeGL(){ // killed by external signal or ctrl+c void closeGL(){ // killed by external signal or ctrl+c
@@ -704,7 +718,11 @@ int viewer(imagefunc newimage){
WARNX(_("Can't open OpenGL window, image preview will be inaccessible")); WARNX(_("Can't open OpenGL window, image preview will be inaccessible"));
return 1; return 1;
} }
cc_IMG *img = NULL; static cc_IMG *locimage = NULL;
if(!locimage){
locimage = cc_newimage(16, 1024, 1024);
if(!locimage) return 1;
}
//double t0 = dtime(); //double t0 = dtime();
while(1){ while(1){
if(!win || win->killthread){ // got kill from ctrl+q if(!win || win->killthread){ // got kill from ctrl+q
@@ -717,10 +735,10 @@ int viewer(imagefunc newimage){
} }
if((win->winevt & WINEVT_GETIMAGE) || !(win->winevt & WINEVT_PAUSE)){ if((win->winevt & WINEVT_GETIMAGE) || !(win->winevt & WINEVT_PAUSE)){
//DBG("CHK new image, t=%g", dtime()-t0); //DBG("CHK new image, t=%g", dtime()-t0);
if(newimage(&img)){ if(newimage(locimage)){
TIMESTAMP("got image -> change"); TIMESTAMP("got image -> change");
win->winevt &= ~WINEVT_GETIMAGE; win->winevt &= ~WINEVT_GETIMAGE;
change_displayed_image(img); // change image if refreshed change_displayed_image(locimage); // change image if refreshed
TIMESTAMP("changed"); TIMESTAMP("changed");
} }
//DBG("Next cycle, t=%g", dtime()-t0); //DBG("Next cycle, t=%g", dtime()-t0);
@@ -737,19 +755,19 @@ int viewer(imagefunc newimage){
GP->outfileprefix = strdup("ccd_capture-screenshot"); GP->outfileprefix = strdup("ccd_capture-screenshot");
verbose(VERBOSE_PRIMARY, _("Set output prefix to %s"), GP->outfileprefix); verbose(VERBOSE_PRIMARY, _("Set output prefix to %s"), GP->outfileprefix);
} }
saveFITS(img, NULL); saveFITS(locimage, NULL);
win->winevt &= ~WINEVT_SAVEIMAGE; win->winevt &= ~WINEVT_SAVEIMAGE;
} }
if(win->winevt & WINEVT_ROLLCOLORFUN){ if(win->winevt & WINEVT_ROLLCOLORFUN){
roll_colorfun(); roll_colorfun();
win->winevt &= ~WINEVT_ROLLCOLORFUN; win->winevt &= ~WINEVT_ROLLCOLORFUN;
change_displayed_image(img); change_displayed_image(locimage);
} }
if(win->winevt & WINEVT_EQUALIZE){ if(win->winevt & WINEVT_EQUALIZE){
win->winevt &= ~WINEVT_EQUALIZE; win->winevt &= ~WINEVT_EQUALIZE;
imequalize = !imequalize; imequalize = !imequalize;
verbose(VERBOSE_PRIMARY, _("Equalization of histogram: %s"), imequalize ? N_("on") : N_("off")); verbose(VERBOSE_PRIMARY, _("Equalization of histogram: %s"), imequalize ? N_("on") : N_("off"));
change_displayed_image(img); change_displayed_image(locimage);
} }
} }
} }

View File

@@ -54,7 +54,8 @@ typedef struct{
int ID; // identificator of OpenGL window int ID; // identificator of OpenGL window
char *title; // title of window char *title; // title of window
GLuint Tex; // texture for image inside window GLuint Tex; // texture for image inside window
rawimage *image; // raw image data rawimage *image; // colour image data
uint8_t *rawdata; // raw data after processing
int w; int h; // window size int w; int h; // window size
float x; float y; // image offset coordinates float x; float y; // image offset coordinates
float x0; float y0; // center of window for coords conversion float x0; float y0; // center of window for coords conversion
@@ -82,6 +83,6 @@ void conv_mouse_to_image_coords(int x, int y, float *X, float *Y, windowData *wi
void conv_image_to_mouse_coords(float X, float Y, int *x, int *y, windowData *window); void conv_image_to_mouse_coords(float X, float Y, int *x, int *y, windowData *window);
windowData* getWin(); windowData* getWin();
typedef int (*imagefunc)(cc_IMG**); typedef int (*imagefunc)(cc_IMG*);
int viewer(imagefunc); int viewer(imagefunc);

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-14 14:47+0300\n" "POT-Creation-Date: 2026-07-21 09:39+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -28,46 +28,46 @@ msgstr ""
msgid "Get signal %d - exit" msgid "Get signal %d - exit"
msgstr "" msgstr ""
#: main.c:91 #: main.c:88
msgid "Can't use outfile name and prefix together" msgid "Can't use outfile name and prefix together"
msgstr "" msgstr ""
#: main.c:94 ccdfunc.c:213 #: main.c:91 ccdfunc.c:214
#, c-format #, c-format
msgid "File %s exists!" msgid "File %s exists!"
msgstr "" msgstr ""
#: main.c:97 #: main.c:94
#, c-format #, c-format
msgid "Can't set answer timeout to %g" msgid "Can't set answer timeout to %g"
msgstr "" msgstr ""
#: main.c:101 #: main.c:98
msgid "" msgid ""
"Options `port` and `path` can't be used together! Point `port` for TCP " "Options `port` and `path` can't be used together! Point `port` for TCP "
"socket or `path` for UNIX." "socket or `path` for UNIX."
msgstr "" msgstr ""
#: main.c:106 #: main.c:103
#, c-format #, c-format
msgid "Wrong port value: %d" msgid "Wrong port value: %d"
msgstr "" msgstr ""
#: main.c:119 #: main.c:116
#, c-format #, c-format
msgid "Set image port to %s\n" msgid "Set image port to %s\n"
msgstr "" msgstr ""
#: main.c:122 #: main.c:119
msgid "Can't be client and standalone in same time!" msgid "Can't be client and standalone in same time!"
msgstr "" msgstr ""
#: main.c:127 #: main.c:124
#, c-format #, c-format
msgid "Log file %s @ level %d\n" msgid "Log file %s @ level %d\n"
msgstr "" msgstr ""
#: main.c:129 #: main.c:126
msgid "Can't create log file" msgid "Can't create log file"
msgstr "" msgstr ""
@@ -331,546 +331,566 @@ msgstr ""
msgid "%d unused parameters:\n" msgid "%d unused parameters:\n"
msgstr "" msgstr ""
#: ccdfunc.c:202 #: ccdfunc.c:203
msgid "Image not saved: neither filename nor filename prefix pointed" msgid "Image not saved: neither filename nor filename prefix pointed"
msgstr "" msgstr ""
#: ccdfunc.c:220 #: ccdfunc.c:221
#, c-format #, c-format
msgid "Can't save file with prefix %s" msgid "Can't save file with prefix %s"
msgstr "" msgstr ""
#: ccdfunc.c:280 #: ccdfunc.c:283
#, c-format #, c-format
msgid "File saved as '%s'" msgid "File saved as '%s'"
msgstr "" msgstr ""
#: ccdfunc.c:289 #: ccdfunc.c:292
msgid "Error saving file" msgid "Error saving file"
msgstr "" msgstr ""
#: ccdfunc.c:344 #: ccdfunc.c:347
#, c-format #, c-format
msgid "Image stat:\n" msgid "Image stat:\n"
msgstr "" msgstr ""
#: ccdfunc.c:353 #: ccdfunc.c:356
msgid "Focuser device not pointed" msgid "Focuser device not pointed"
msgstr "" msgstr ""
#: ccdfunc.c:360 #: ccdfunc.c:363
msgid "No focusers found" msgid "No focusers found"
msgstr "" msgstr ""
#: ccdfunc.c:384 #: ccdfunc.c:387
#, c-format #, c-format
msgid "Found focuser #%d: %s\n" msgid "Found focuser #%d: %s\n"
msgstr "" msgstr ""
#: ccdfunc.c:390 #: ccdfunc.c:393
#, c-format #, c-format
msgid "Found %d focusers, you point number %d" msgid "Found %d focusers, you point number %d"
msgstr "" msgstr ""
#: ccdfunc.c:394 #: ccdfunc.c:397
msgid "Can't set active focuser number" msgid "Can't set active focuser number"
msgstr "" msgstr ""
#: ccdfunc.c:408 #: ccdfunc.c:411
msgid "Can't get focuser limit positions" msgid "Can't get focuser limit positions"
msgstr "" msgstr ""
#: ccdfunc.c:415 #: ccdfunc.c:418
msgid "Can't get current focuser position" msgid "Can't get current focuser position"
msgstr "" msgstr ""
#: ccdfunc.c:429 #: ccdfunc.c:432
#, c-format #, c-format
msgid "Can't set position %g: out of limits [%g, %g]" msgid "Can't set position %g: out of limits [%g, %g]"
msgstr "" msgstr ""
#: ccdfunc.c:433 #: ccdfunc.c:436
msgid "Can't home focuser" msgid "Can't home focuser"
msgstr "" msgstr ""
#: ccdfunc.c:435 #: ccdfunc.c:438
#, c-format #, c-format
msgid "Can't set position %g" msgid "Can't set position %g"
msgstr "" msgstr ""
#: ccdfunc.c:443 #: ccdfunc.c:446
msgid "Wheel device not pointed" msgid "Wheel device not pointed"
msgstr "" msgstr ""
#: ccdfunc.c:450 #: ccdfunc.c:453
msgid "No wheels found" msgid "No wheels found"
msgstr "" msgstr ""
#: ccdfunc.c:474 #: ccdfunc.c:477
#, c-format #, c-format
msgid "Found wheel #%d: %s\n" msgid "Found wheel #%d: %s\n"
msgstr "" msgstr ""
#: ccdfunc.c:480 #: ccdfunc.c:483
#, c-format #, c-format
msgid "Found %d wheels, you point number %d" msgid "Found %d wheels, you point number %d"
msgstr "" msgstr ""
#: ccdfunc.c:484 #: ccdfunc.c:487
msgid "Can't set active wheel number" msgid "Can't set active wheel number"
msgstr "" msgstr ""
#: ccdfunc.c:489 #: ccdfunc.c:492
#, c-format #, c-format
msgid "Wheel model: %s" msgid "Wheel model: %s"
msgstr "" msgstr ""
#: ccdfunc.c:498 #: ccdfunc.c:501
msgid "Can't get current wheel position" msgid "Can't get current wheel position"
msgstr "" msgstr ""
#: ccdfunc.c:500 #: ccdfunc.c:503
msgid "Can't get max wheel position" msgid "Can't get max wheel position"
msgstr "" msgstr ""
#: ccdfunc.c:507 #: ccdfunc.c:510
#, c-format #, c-format
msgid "Wheel position should be from 0 to %d" msgid "Wheel position should be from 0 to %d"
msgstr "" msgstr ""
#: ccdfunc.c:511 #: ccdfunc.c:514
#, c-format #, c-format
msgid "Can't set wheel position %d" msgid "Can't set wheel position %d"
msgstr "" msgstr ""
#: ccdfunc.c:526 #: ccdfunc.c:529
msgid "Camera plugin have no capture polling funtion." msgid "Camera plugin have no capture polling funtion."
msgstr "" msgstr ""
#: ccdfunc.c:532 #: ccdfunc.c:535
#, c-format #, c-format
msgid "%.1f seconds till exposition ends" msgid "%.1f seconds till exposition ends"
msgstr "" msgstr ""
#: ccdfunc.c:547 #: ccdfunc.c:550
msgid "Camera device not pointed" msgid "Camera device not pointed"
msgstr "" msgstr ""
#: ccdfunc.c:554 ccdfunc.c:555 #: ccdfunc.c:557 ccdfunc.c:558
msgid "No cameras found" msgid "No cameras found"
msgstr "" msgstr ""
#: ccdfunc.c:575 #: ccdfunc.c:578
msgid "Camera plugin have no model name getter" msgid "Camera plugin have no model name getter"
msgstr "" msgstr ""
#: ccdfunc.c:580 #: ccdfunc.c:583
#, c-format #, c-format
msgid "Found camera #%d: %s\n" msgid "Found camera #%d: %s\n"
msgstr "" msgstr ""
#: ccdfunc.c:586 #: ccdfunc.c:589
#, c-format #, c-format
msgid "Found %d cameras, you point number %d" msgid "Found %d cameras, you point number %d"
msgstr "" msgstr ""
#: ccdfunc.c:590 #: ccdfunc.c:593
msgid "Can't set active camera number" msgid "Can't set active camera number"
msgstr "" msgstr ""
#: ccdfunc.c:596 #: ccdfunc.c:599
msgid "Camera plugin have no custom commands" msgid "Camera plugin have no custom commands"
msgstr "" msgstr ""
#: ccdfunc.c:605 ccdfunc.c:608 #: ccdfunc.c:608 ccdfunc.c:611
#, c-format #, c-format
msgid "Command '%s'" msgid "Command '%s'"
msgstr "" msgstr ""
#: ccdfunc.c:610 #: ccdfunc.c:613
#, c-format #, c-format
msgid " returns \"%s\"" msgid " returns \"%s\""
msgstr "" msgstr ""
#: ccdfunc.c:621 #: ccdfunc.c:624
msgid "Camera plugin have no fun speed setter" msgid "Camera plugin have no fun speed setter"
msgstr "" msgstr ""
#: ccdfunc.c:624 #: ccdfunc.c:627
msgid "Can't set fan speed" msgid "Can't set fan speed"
msgstr "" msgstr ""
#: ccdfunc.c:625 #: ccdfunc.c:628
#, c-format #, c-format
msgid "Set fan speed to %d" msgid "Set fan speed to %d"
msgstr "" msgstr ""
#: ccdfunc.c:630 #: ccdfunc.c:633
#, c-format #, c-format
msgid "Camera model: %s" msgid "Camera model: %s"
msgstr "" msgstr ""
#: ccdfunc.c:631 #: ccdfunc.c:634
#, c-format #, c-format
msgid "Pixel size: %g x %g" msgid "Pixel size: %g x %g"
msgstr "" msgstr ""
#: ccdfunc.c:637 #: ccdfunc.c:640
#, c-format #, c-format
msgid "Full array: %s" msgid "Full array: %s"
msgstr "" msgstr ""
#: ccdfunc.c:640 #: ccdfunc.c:643
#, c-format #, c-format
msgid "Field of view: %s" msgid "Field of view: %s"
msgstr "" msgstr ""
#: ccdfunc.c:643 #: ccdfunc.c:646
#, c-format #, c-format
msgid "Current format: %s" msgid "Current format: %s"
msgstr "" msgstr ""
#: ccdfunc.c:646 #: ccdfunc.c:649
#, c-format #, c-format
msgid "Maximal geometry (WxH): %dx%d" msgid "Maximal geometry (WxH): %dx%d"
msgstr "" msgstr ""
#: ccdfunc.c:647 #: ccdfunc.c:650
#, c-format #, c-format
msgid "Minimal offset: %dx%d" msgid "Minimal offset: %dx%d"
msgstr "" msgstr ""
#: ccdfunc.c:648 #: ccdfunc.c:651
#, c-format #, c-format
msgid "Geometry steps: offset - %dx%d, size - %dx%d" msgid "Geometry steps: offset - %dx%d, size - %dx%d"
msgstr "" msgstr ""
#: ccdfunc.c:652 #: ccdfunc.c:655
#, c-format #, c-format
msgid "Current binning: %d x %d" msgid "Current binning: %d x %d"
msgstr "" msgstr ""
#: ccdfunc.c:655 #: ccdfunc.c:658
#, c-format #, c-format
msgid "Current settings: %d bits per pixel" msgid "Current settings: %d bits per pixel"
msgstr "" msgstr ""
#: ccdfunc.c:658 #: ccdfunc.c:661
#, c-format #, c-format
msgid "Current brightness: %g" msgid "Current brightness: %g"
msgstr "" msgstr ""
#: ccdfunc.c:660 #: ccdfunc.c:663
#, c-format #, c-format
msgid "Current gain: %g" msgid "Current gain: %g"
msgstr "" msgstr ""
#: ccdfunc.c:662 #: ccdfunc.c:665
#, c-format #, c-format
msgid "Maximal gain: %g" msgid "Maximal gain: %g"
msgstr "" msgstr ""
#: ccdfunc.c:664 #: ccdfunc.c:667
msgid "Camera plugin have no temperature setter" msgid "Camera plugin have no temperature setter"
msgstr "" msgstr ""
#: ccdfunc.c:665 #: ccdfunc.c:668
#, c-format #, c-format
msgid "Can't set T to %g degC" msgid "Can't set T to %g degC"
msgstr "" msgstr ""
#: ccdfunc.c:673 #: ccdfunc.c:676
#, c-format #, c-format
msgid "Shutter command: %s\n" msgid "Shutter command: %s\n"
msgstr "" msgstr ""
#: ccdfunc.c:675 #: ccdfunc.c:678
#, c-format #, c-format
msgid "Can't run shutter command %s (unsupported?)" msgid "Can't run shutter command %s (unsupported?)"
msgstr "" msgstr ""
#: ccdfunc.c:678 #: ccdfunc.c:681
#, c-format #, c-format
msgid "Try to configure I/O port as %d" msgid "Try to configure I/O port as %d"
msgstr "" msgstr ""
#: ccdfunc.c:680 #: ccdfunc.c:683
msgid "Can't configure (unsupported?)" msgid "Can't configure (unsupported?)"
msgstr "" msgstr ""
#: ccdfunc.c:686 #: ccdfunc.c:689
msgid "Can't get IOport state (unsupported?)" msgid "Can't get IOport state (unsupported?)"
msgstr "" msgstr ""
#: ccdfunc.c:689 #: ccdfunc.c:692
#, c-format #, c-format
msgid "Try to write %d to I/O port" msgid "Try to write %d to I/O port"
msgstr "" msgstr ""
#: ccdfunc.c:691 #: ccdfunc.c:694
msgid "Can't set IOport" msgid "Can't set IOport"
msgstr "" msgstr ""
#: ccdfunc.c:698 #: ccdfunc.c:701
#, c-format #, c-format
msgid "Set gain to %g" msgid "Set gain to %g"
msgstr "" msgstr ""
#: ccdfunc.c:699 #: ccdfunc.c:702
#, c-format #, c-format
msgid "Can't set gain to %g" msgid "Can't set gain to %g"
msgstr "" msgstr ""
#: ccdfunc.c:704 #: ccdfunc.c:707
#, c-format #, c-format
msgid "Set brightness to %g" msgid "Set brightness to %g"
msgstr "" msgstr ""
#: ccdfunc.c:705 #: ccdfunc.c:708
#, c-format #, c-format
msgid "Can't set brightness to %g" msgid "Can't set brightness to %g"
msgstr "" msgstr ""
#: ccdfunc.c:711 server.c:330 #: ccdfunc.c:714 server.c:353
#, c-format #, c-format
msgid "Can't set binning %dx%d" msgid "Can't set binning %dx%d"
msgstr "" msgstr ""
#: ccdfunc.c:723 server.c:331 #: ccdfunc.c:726 server.c:354
msgid "Can't set given geometry" msgid "Can't set given geometry"
msgstr "" msgstr ""
#: ccdfunc.c:727 #: ccdfunc.c:730
#, c-format #, c-format
msgid "Can't set %d flushes" msgid "Can't set %d flushes"
msgstr "" msgstr ""
#: ccdfunc.c:730 #: ccdfunc.c:733
msgid "Camera plugin have no exposition setter" msgid "Camera plugin have no exposition setter"
msgstr "" msgstr ""
#: ccdfunc.c:732 #: ccdfunc.c:735
#, c-format #, c-format
msgid "Can't set exposure time to %f seconds" msgid "Can't set exposure time to %f seconds"
msgstr "" msgstr ""
#: ccdfunc.c:735 #: ccdfunc.c:738
msgid "Can't change frame type" msgid "Can't change frame type"
msgstr "" msgstr ""
#: ccdfunc.c:738 #: ccdfunc.c:741
msgid "Can't set bit depth" msgid "Can't set bit depth"
msgstr "" msgstr ""
#: ccdfunc.c:740 #: ccdfunc.c:743
msgid "Can't set readout speed" msgid "Can't set readout speed"
msgstr "" msgstr ""
#: ccdfunc.c:741 #: ccdfunc.c:744
#, c-format #, c-format
msgid "Readout mode: %s" msgid "Readout mode: %s"
msgstr "" msgstr ""
#: ccdfunc.c:742 #: ccdfunc.c:745
msgid "Only show statistics" msgid "Only show statistics"
msgstr "" msgstr ""
#: ccdfunc.c:745 #: ccdfunc.c:748
msgid "Can't get current binning" msgid "Can't get current binning"
msgstr "" msgstr ""
#: ccdfunc.c:770 #: ccdfunc.c:773
#, c-format #, c-format
msgid "Capture frame %d" msgid "Capture frame %d"
msgstr "" msgstr ""
#: ccdfunc.c:771 ccdfunc.c:848 server.c:195 #: ccdfunc.c:774 ccdfunc.c:852 server.c:203
msgid "Camera plugin have no function `start exposition`" msgid "Camera plugin have no function `start exposition`"
msgstr "" msgstr ""
#: ccdfunc.c:773 ccdfunc.c:850 server.c:201 #: ccdfunc.c:776 ccdfunc.c:854 server.c:208
msgid "Can't start exposition" msgid "Can't start exposition"
msgstr "" msgstr ""
#: ccdfunc.c:778 #: ccdfunc.c:781
msgid "Can't capture image" msgid "Can't capture image"
msgstr "" msgstr ""
#: ccdfunc.c:781 #: ccdfunc.c:784
msgid "Read grabbed image" msgid "Read grabbed image"
msgstr "" msgstr ""
#: ccdfunc.c:783 ccdfunc.c:863 server.c:218 #: ccdfunc.c:786 ccdfunc.c:865 server.c:239
msgid "Camera plugin have no function `capture`" msgid "Camera plugin have no function `capture`"
msgstr "" msgstr ""
#: ccdfunc.c:785 ccdfunc.c:864 #: ccdfunc.c:788 ccdfunc.c:866
msgid "Can't grab image" msgid "Can't grab image"
msgstr "" msgstr ""
#: ccdfunc.c:799 client.c:499 #: ccdfunc.c:802 client.c:573
#, c-format #, c-format
msgid "%d seconds till pause ends\n" msgid "%d seconds till pause ends\n"
msgstr "" msgstr ""
#. for(int i = 0; i < NFRM; ++i) printf("last[%d]=%g\n", i, lastn[i]); #. for(int i = 0; i < NFRM; ++i) printf("last[%d]=%g\n", i, lastn[i]);
#: ccdfunc.c:834 #: ccdfunc.c:837
#, c-format #, c-format
msgid "Framerate=%.2f (%g seconds for exp); mean framerate=%.2f" msgid "Framerate=%.2f (%g seconds for exp); mean framerate=%.2f"
msgstr "" msgstr ""
#: ccdfunc.c:861 #: ccdfunc.c:863
msgid "Some error when capture" msgid "Some error when capture"
msgstr "" msgstr ""
#: ccdfunc.c:912 #: ccdfunc.c:904
msgid "Can't create grabbing thread" msgid "Can't create grabbing thread"
msgstr "" msgstr ""
#: ccdfunc.c:943 #: ccdfunc.c:935
msgid "Point network port or UNIX-socket path" msgid "Point network port or UNIX-socket path"
msgstr "" msgstr ""
#: ccdfunc.c:947 #: ccdfunc.c:939
msgid "start_socket(): can't open socket" msgid "start_socket(): can't open socket"
msgstr "" msgstr ""
#: ccdfunc.c:956 #: ccdfunc.c:948
msgid "Need exposition time!" msgid "Need exposition time!"
msgstr "" msgstr ""
#: server.c:126 #: server.c:129
msgid "Can't unlock socket mutex" msgid "Can't unlock socket mutex"
msgstr "" msgstr ""
#: server.c:163 #: server.c:167
msgid "Can't allocate memory for image" msgid "Can't allocate memory for image"
msgstr "" msgstr ""
#: server.c:247 #: server.c:216
msgid "Camera disconnected"
msgstr ""
#: server.c:222
msgid "Something's wrong with camera"
msgstr ""
#: server.c:270
msgid "No camera device" msgid "No camera device"
msgstr "" msgstr ""
#: server.c:1060 #: server.c:1092
msgid "server(): need at least command socket fd" msgid "server(): need at least command socket fd"
msgstr "" msgstr ""
#: server.c:1061 #: server.c:1093
msgid "Server run without image transport socket" msgid "Server run without image transport socket"
msgstr "" msgstr ""
#: server.c:1082 #: server.c:1115
msgid "No devices found" msgid "No devices found"
msgstr "" msgstr ""
#: server.c:1127 #: server.c:1160
msgid "Client wants an image, but there's no data" msgid "Client wants an image, but there's no data"
msgstr "" msgstr ""
#: server.c:1156 #: server.c:1189
msgid "Limit of connections reached" msgid "Limit of connections reached"
msgstr "" msgstr ""
#: server.c:1225 #: server.c:1258
#, c-format #, c-format
msgid "Can't create %s" msgid "Can't create %s"
msgstr "" msgstr ""
#: server.c:1261 #: server.c:1294
msgid "Can't lock mutex" msgid "Can't lock mutex"
msgstr "" msgstr ""
#. send message and wait any answer #. send message and wait any answer
#. send message and wait answer starting with 'cmd' #. send message and wait answer starting with 'cmd'
#. send command and wait for answer on it #. send command and wait for answer on it
#: client.c:42 client.c:44 client.c:46 client.c:276 #: client.c:42 client.c:44 client.c:46 client.c:288
msgid "Server disconnected" msgid "Server disconnected"
msgstr "" msgstr ""
#: client.c:173 #: client.c:124
msgid "Can't allocate buffer"
msgstr ""
#: client.c:149
msgid "Server disconnected?"
msgstr ""
#: client.c:157
msgid "Got empty string"
msgstr ""
#: client.c:186
msgid "Send custom plugin commands\n" msgid "Send custom plugin commands\n"
msgstr "" msgstr ""
#: client.c:307 #: client.c:340
msgid "Can't lock shared memory" msgid "Can't lock shared memory"
msgstr "" msgstr ""
#: client.c:316 #: client.c:359
msgid "getimage(): can't open image transport socket" msgid "Can't open image transport socket"
msgstr "" msgstr ""
#: client.c:319 #: client.c:365
msgid "Can't read image header" msgid "Can't read image header over socket"
msgstr "" msgstr ""
#: client.c:324 #: client.c:398 client.c:428
msgid "Wrong image: bad magick"
msgstr ""
#: client.c:328
msgid "Wrong image size"
msgstr ""
#: client.c:342
msgid "Can't reallocate memory for image buffer"
msgstr ""
#: client.c:361
msgid "Can't read image data" msgid "Can't read image data"
msgstr "" msgstr ""
#: client.c:380 #: client.c:440
msgid "Too many FITS headers, truncating"
msgstr ""
#: client.c:451
#, c-format #, c-format
msgid "Can't read full header, got %zd records from %zd" msgid "Can't read full header, got %zd records from %zd"
msgstr "" msgstr ""
#: client.c:414 client.c:517 #: client.c:466
msgid "Still got old image"
msgstr ""
#: client.c:491 client.c:591
msgid "Can't run without command socket" msgid "Can't run without command socket"
msgstr "" msgstr ""
#: client.c:436 #: client.c:510
msgid "Exposing frame 1..." msgid "Exposing frame 1..."
msgstr "" msgstr ""
#: client.c:439 #: client.c:512
msgid "Wait for exposition end" msgid "Wait for exposition end"
msgstr "" msgstr ""
#: client.c:457 #: client.c:531
msgid "Can't make exposition" msgid "Can't make exposition"
msgstr "" msgstr ""
#. start next capture #. start next capture
#. last image -> should re-expose #. last image -> should re-expose
#: client.c:459 client.c:470 client.c:489 #: client.c:533 client.c:544 client.c:563
#, c-format #, c-format
msgid "Exposing frame %d..." msgid "Exposing frame %d..."
msgstr "" msgstr ""
#: client.c:477 #: client.c:551
msgid "Frame ready, try to grab" msgid "Frame ready, try to grab"
msgstr "" msgstr ""
#: client.c:479 #: client.c:553
msgid "Can't get next image" msgid "Can't get next image"
msgstr "" msgstr ""
#: client.c:487 #: client.c:561
msgid "Got already saved image, wait next" msgid "Got already saved image, wait next"
msgstr "" msgstr ""
#: client.c:511 #: client.c:585
msgid "Server timeout" msgid "Server timeout"
msgstr "" msgstr ""
#: client.c:560 #: client.c:636
msgid "Camera in error state"
msgstr ""
#: client.c:638
#, c-format #, c-format
msgid "" msgid ""
"Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d " "Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d "
"(timeout: %g)" "(timeout: %g)"
msgstr "" msgstr ""
#: client.c:620 client.c:627 #: client.c:698 client.c:705
msgid "Can't create capturing thread" msgid "Can't create capturing thread"
msgstr "" msgstr ""
@@ -878,47 +898,47 @@ msgstr ""
msgid "Already initialized!" msgid "Already initialized!"
msgstr "" msgstr ""
#: imageview.c:312 #: imageview.c:314
msgid "Can't init mutex!" msgid "Can't init mutex!"
msgstr "" msgstr ""
#: imageview.c:425 #: imageview.c:427
#, c-format #, c-format
msgid "Histogram conversion: %s" msgid "Histogram conversion: %s"
msgstr "" msgstr ""
#: imageview.c:615 #: imageview.c:616
#, c-format #, c-format
msgid "Missed %zd images" msgid "Missed %zd images"
msgstr "" msgstr ""
#: imageview.c:697 #: imageview.c:711
msgid "No image changing function defined" msgid "No image changing function defined"
msgstr "" msgstr ""
#: imageview.c:704 #: imageview.c:718
msgid "Can't open OpenGL window, image preview will be inaccessible" msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr "" msgstr ""
#. save image #. save image
#: imageview.c:734 #: imageview.c:752
msgid "Make screenshot" msgid "Make screenshot"
msgstr "" msgstr ""
#: imageview.c:738 #: imageview.c:756
#, c-format #, c-format
msgid "Set output prefix to %s" msgid "Set output prefix to %s"
msgstr "" msgstr ""
#: imageview.c:751 #: imageview.c:769
#, c-format #, c-format
msgid "Equalization of histogram: %s" msgid "Equalization of histogram: %s"
msgstr "" msgstr ""
#: imageview.c:751 #: imageview.c:769
msgid "on" msgid "on"
msgstr "" msgstr ""
#: imageview.c:751 #: imageview.c:769
msgid "off" msgid "off"
msgstr "" msgstr ""

View File

@@ -7,7 +7,7 @@
msgid "" msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n" msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-14 14:45+0300\n" "POT-Creation-Date: 2026-07-21 09:39+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,17 +16,17 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Content-Type: text/plain; charset=koi8-r\n" "Content-Type: text/plain; charset=koi8-r\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: ccdfunc.c:610 #: ccdfunc.c:613
#, c-format #, c-format
msgid " returns \"%s\"" msgid " returns \"%s\""
msgstr "" msgstr ""
#: ccdfunc.c:532 #: ccdfunc.c:535
#, c-format #, c-format
msgid "%.1f seconds till exposition ends" msgid "%.1f seconds till exposition ends"
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ" msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
#: ccdfunc.c:799 client.c:499 #: ccdfunc.c:802 client.c:573
#, c-format #, c-format
msgid "%d seconds till pause ends\n" msgid "%d seconds till pause ends\n"
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n" msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
@@ -48,320 +48,335 @@ msgstr "
msgid "CMOS gain level" msgid "CMOS gain level"
msgstr "ÕÒÏ×ÅÎØ Gain CMOS" msgstr "ÕÒÏ×ÅÎØ Gain CMOS"
#: ccdfunc.c:547 #: ccdfunc.c:550
msgid "Camera device not pointed" msgid "Camera device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÐÏÄËÌÀÞÅÎÏ" msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÐÏÄËÌÀÞÅÎÏ"
#: ccdfunc.c:630 #: server.c:216
#, fuzzy
msgid "Camera disconnected"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
#: client.c:636
msgid "Camera in error state"
msgstr ""
#: ccdfunc.c:633
#, c-format #, c-format
msgid "Camera model: %s" msgid "Camera model: %s"
msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s" msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s"
#: ccdfunc.c:526 #: ccdfunc.c:529
#, fuzzy #, fuzzy
msgid "Camera plugin have no capture polling funtion." msgid "Camera plugin have no capture polling funtion."
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:596 #: ccdfunc.c:599
msgid "Camera plugin have no custom commands" msgid "Camera plugin have no custom commands"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:730 #: ccdfunc.c:733
#, fuzzy #, fuzzy
msgid "Camera plugin have no exposition setter" msgid "Camera plugin have no exposition setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:621 #: ccdfunc.c:624
#, fuzzy #, fuzzy
msgid "Camera plugin have no fun speed setter" msgid "Camera plugin have no fun speed setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:783 ccdfunc.c:863 server.c:218 #: ccdfunc.c:786 ccdfunc.c:865 server.c:239
#, fuzzy #, fuzzy
msgid "Camera plugin have no function `capture`" msgid "Camera plugin have no function `capture`"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:771 ccdfunc.c:848 server.c:195 #: ccdfunc.c:774 ccdfunc.c:852 server.c:203
#, fuzzy #, fuzzy
msgid "Camera plugin have no function `start exposition`" msgid "Camera plugin have no function `start exposition`"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:575 #: ccdfunc.c:578
#, fuzzy #, fuzzy
msgid "Camera plugin have no model name getter" msgid "Camera plugin have no model name getter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: ccdfunc.c:664 #: ccdfunc.c:667
#, fuzzy #, fuzzy
msgid "Camera plugin have no temperature setter" msgid "Camera plugin have no temperature setter"
msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ" msgstr "õ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ ÎÅÔ ÏÓÏÂÙÈ ËÏÍÁÎÄ"
#: server.c:163 #: client.c:124
#, fuzzy
msgid "Can't allocate buffer"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: server.c:167
#, fuzzy #, fuzzy
msgid "Can't allocate memory for image" msgid "Can't allocate memory for image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: main.c:122 #: main.c:119
msgid "Can't be client and standalone in same time!" msgid "Can't be client and standalone in same time!"
msgstr "" msgstr ""
#: ccdfunc.c:778 #: ccdfunc.c:781
msgid "Can't capture image" msgid "Can't capture image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:735 #: ccdfunc.c:738
msgid "Can't change frame type" msgid "Can't change frame type"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÔÉÐ ËÁÄÒÁ" msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÔÉÐ ËÁÄÒÁ"
#: ccdfunc.c:680 #: ccdfunc.c:683
msgid "Can't configure (unsupported?)" msgid "Can't configure (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)" msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: server.c:1225 #: server.c:1258
#, fuzzy, c-format #, fuzzy, c-format
msgid "Can't create %s" msgid "Can't create %s"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: client.c:620 client.c:627 #: client.c:698 client.c:705
#, fuzzy #, fuzzy
msgid "Can't create capturing thread" msgid "Can't create capturing thread"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:912 #: ccdfunc.c:904
#, fuzzy #, fuzzy
msgid "Can't create grabbing thread" msgid "Can't create grabbing thread"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: main.c:129 #: main.c:126
#, fuzzy #, fuzzy
msgid "Can't create log file" msgid "Can't create log file"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:686 #: ccdfunc.c:689
msgid "Can't get IOport state (unsupported?)" msgid "Can't get IOport state (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÁ I/O (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)" msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÁ I/O (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:745 #: ccdfunc.c:748
msgid "Can't get current binning" msgid "Can't get current binning"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ ÂÉÎÎÉÎÇÁ" msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ ÂÉÎÎÉÎÇÁ"
#: ccdfunc.c:415 #: ccdfunc.c:418
msgid "Can't get current focuser position" msgid "Can't get current focuser position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ" msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:498 #: ccdfunc.c:501
#, fuzzy #, fuzzy
msgid "Can't get current wheel position" msgid "Can't get current wheel position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ" msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:408 #: ccdfunc.c:411
msgid "Can't get focuser limit positions" msgid "Can't get focuser limit positions"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ" msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:500 #: ccdfunc.c:503
msgid "Can't get max wheel position" msgid "Can't get max wheel position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ËÏÌÅÓÁ" msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ËÏÌÅÓÁ"
#: client.c:479 #: client.c:553
#, fuzzy #, fuzzy
msgid "Can't get next image" msgid "Can't get next image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:785 ccdfunc.c:864 #: ccdfunc.c:788 ccdfunc.c:866
msgid "Can't grab image" msgid "Can't grab image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:433 #: ccdfunc.c:436
msgid "Can't home focuser" msgid "Can't home focuser"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÆÏËÕÓÅÒ × ÎÕÌØ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÆÏËÕÓÅÒ × ÎÕÌØ"
#: imageview.c:312 #: imageview.c:314
msgid "Can't init mutex!" msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!" msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: server.c:1261 #: server.c:1294
#, fuzzy #, fuzzy
msgid "Can't lock mutex" msgid "Can't lock mutex"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!" msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: client.c:307 #: client.c:340
#, fuzzy #, fuzzy
msgid "Can't lock shared memory" msgid "Can't lock shared memory"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: client.c:457 #: client.c:531
msgid "Can't make exposition" msgid "Can't make exposition"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ" msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
#: imageview.c:704 #: imageview.c:718
msgid "Can't open OpenGL window, image preview will be inaccessible" msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÏËÎÏ OpenGL, ÏÔÏÂÒÁÖÅÎÉÅ ÂÕÄÅÔ ÎÅÄÏÓÔÕÐÎÏ" msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÏËÎÏ OpenGL, ÏÔÏÂÒÁÖÅÎÉÅ ÂÕÄÅÔ ÎÅÄÏÓÔÕÐÎÏ"
#: client.c:380 #: client.c:359
#, fuzzy
msgid "Can't open image transport socket"
msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: client.c:451
#, c-format #, c-format
msgid "Can't read full header, got %zd records from %zd" msgid "Can't read full header, got %zd records from %zd"
msgstr "" msgstr ""
#: client.c:361 #: client.c:398 client.c:428
#, fuzzy #, fuzzy
msgid "Can't read image data" msgid "Can't read image data"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: client.c:319 #: client.c:365
#, fuzzy #, fuzzy
msgid "Can't read image header" msgid "Can't read image header over socket"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ" msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: client.c:342 #: ccdfunc.c:678
msgid "Can't reallocate memory for image buffer"
msgstr ""
#: ccdfunc.c:675
#, c-format #, c-format
msgid "Can't run shutter command %s (unsupported?)" msgid "Can't run shutter command %s (unsupported?)"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)" msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: client.c:414 client.c:517 #: client.c:491 client.c:591
#, fuzzy #, fuzzy
msgid "Can't run without command socket" msgid "Can't run without command socket"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)" msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#: ccdfunc.c:220 #: ccdfunc.c:221
#, c-format #, c-format
msgid "Can't save file with prefix %s" msgid "Can't save file with prefix %s"
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s" msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s"
#: ccdfunc.c:727 #: ccdfunc.c:730
#, c-format #, c-format
msgid "Can't set %d flushes" msgid "Can't set %d flushes"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ %d ÓÂÒÏÓÏ×" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ %d ÓÂÒÏÓÏ×"
#: ccdfunc.c:691 #: ccdfunc.c:694
msgid "Can't set IOport" msgid "Can't set IOport"
msgstr "îÅ ÍÏÇÕ ÐÏÍÅÎÑÔØ ÚÎÁÞÅÎÉÑ ÐÏÒÔÁ I/O" msgstr "îÅ ÍÏÇÕ ÐÏÍÅÎÑÔØ ÚÎÁÞÅÎÉÑ ÐÏÒÔÁ I/O"
#: ccdfunc.c:665 #: ccdfunc.c:668
#, c-format #, c-format
msgid "Can't set T to %g degC" msgid "Can't set T to %g degC"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ × %g ÇÒÁÄã" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ × %g ÇÒÁÄã"
#: ccdfunc.c:590 #: ccdfunc.c:593
msgid "Can't set active camera number" msgid "Can't set active camera number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÊ ËÁÍÅÒÙ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÊ ËÁÍÅÒÙ"
#: ccdfunc.c:394 #: ccdfunc.c:397
msgid "Can't set active focuser number" msgid "Can't set active focuser number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ÆÏËÕÓÅÒÁ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:484 #: ccdfunc.c:487
msgid "Can't set active wheel number" msgid "Can't set active wheel number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
#: main.c:97 #: main.c:94
#, fuzzy, c-format #, fuzzy, c-format
msgid "Can't set answer timeout to %g" msgid "Can't set answer timeout to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:711 server.c:330 #: ccdfunc.c:714 server.c:353
#, c-format #, c-format
msgid "Can't set binning %dx%d" msgid "Can't set binning %dx%d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
#: ccdfunc.c:738 #: ccdfunc.c:741
msgid "Can't set bit depth" msgid "Can't set bit depth"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÒÑÄÎÏÓÔØ áãð" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÒÑÄÎÏÓÔØ áãð"
#: ccdfunc.c:705 #: ccdfunc.c:708
#, c-format #, c-format
msgid "Can't set brightness to %g" msgid "Can't set brightness to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:732 #: ccdfunc.c:735
#, c-format #, c-format
msgid "Can't set exposure time to %f seconds" msgid "Can't set exposure time to %f seconds"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÜËÓÐÏÚÉÃÉÀ × %f ÓÅËÕÎÄ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÜËÓÐÏÚÉÃÉÀ × %f ÓÅËÕÎÄ"
#: ccdfunc.c:624 #: ccdfunc.c:627
msgid "Can't set fan speed" msgid "Can't set fan speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ×" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ×"
#: ccdfunc.c:699 #: ccdfunc.c:702
#, c-format #, c-format
msgid "Can't set gain to %g" msgid "Can't set gain to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:723 server.c:331 #: ccdfunc.c:726 server.c:354
msgid "Can't set given geometry" msgid "Can't set given geometry"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
#: ccdfunc.c:435 #: ccdfunc.c:438
#, c-format #, c-format
msgid "Can't set position %g" msgid "Can't set position %g"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÐÏÚÉÃÉÀ ÎÁ %g" msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÐÏÚÉÃÉÀ ÎÁ %g"
#: ccdfunc.c:429 #: ccdfunc.c:432
#, c-format #, c-format
msgid "Can't set position %g: out of limits [%g, %g]" msgid "Can't set position %g: out of limits [%g, %g]"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ %g: ×ÎÅ ÐÒÅÄÅÌÏ× [%g, %g]" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ %g: ×ÎÅ ÐÒÅÄÅÌÏ× [%g, %g]"
#: ccdfunc.c:740 #: ccdfunc.c:743
msgid "Can't set readout speed" msgid "Can't set readout speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÓÞÉÔÙ×ÁÎÉÑ" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÓÞÉÔÙ×ÁÎÉÑ"
#: ccdfunc.c:511 #: ccdfunc.c:514
#, c-format #, c-format
msgid "Can't set wheel position %d" msgid "Can't set wheel position %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
#: ccdfunc.c:773 ccdfunc.c:850 server.c:201 #: ccdfunc.c:776 ccdfunc.c:854 server.c:208
msgid "Can't start exposition" msgid "Can't start exposition"
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ" msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
#: server.c:126 #: server.c:129
#, fuzzy #, fuzzy
msgid "Can't unlock socket mutex" msgid "Can't unlock socket mutex"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!" msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: main.c:91 #: main.c:88
#, fuzzy #, fuzzy
msgid "Can't use outfile name and prefix together" msgid "Can't use outfile name and prefix together"
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s" msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s"
#: ccdfunc.c:770 #: ccdfunc.c:773
#, c-format #, c-format
msgid "Capture frame %d" msgid "Capture frame %d"
msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d" msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d"
#: server.c:1127 #: server.c:1160
msgid "Client wants an image, but there's no data" msgid "Client wants an image, but there's no data"
msgstr "" msgstr ""
#: ccdfunc.c:605 ccdfunc.c:608 #: ccdfunc.c:608 ccdfunc.c:611
#, c-format #, c-format
msgid "Command '%s'" msgid "Command '%s'"
msgstr "" msgstr ""
#: ccdfunc.c:652 #: ccdfunc.c:655
#, fuzzy, c-format #, fuzzy, c-format
msgid "Current binning: %d x %d" msgid "Current binning: %d x %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
#: ccdfunc.c:658 #: ccdfunc.c:661
#, fuzzy, c-format #, fuzzy, c-format
msgid "Current brightness: %g" msgid "Current brightness: %g"
msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g" msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:643 #: ccdfunc.c:646
#, c-format #, c-format
msgid "Current format: %s" msgid "Current format: %s"
msgstr "ôÅËÕÝÉÊ ÆÏÒÍÁÔ: %s" msgstr "ôÅËÕÝÉÊ ÆÏÒÍÁÔ: %s"
#: ccdfunc.c:660 #: ccdfunc.c:663
#, fuzzy, c-format #, fuzzy, c-format
msgid "Current gain: %g" msgid "Current gain: %g"
msgstr "ôÅËÕÝÉÊ ÆÏÒÍÁÔ: %s" msgstr "ôÅËÕÝÉÊ ÆÏÒÍÁÔ: %s"
#: ccdfunc.c:655 #: ccdfunc.c:658
#, c-format #, c-format
msgid "Current settings: %d bits per pixel" msgid "Current settings: %d bits per pixel"
msgstr "" msgstr ""
@@ -370,91 +385,91 @@ msgstr ""
msgid "Display image in OpenGL window" msgid "Display image in OpenGL window"
msgstr "ÏÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL" msgstr "ÏÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL"
#: imageview.c:751 #: imageview.c:769
#, c-format #, c-format
msgid "Equalization of histogram: %s" msgid "Equalization of histogram: %s"
msgstr "üË×ÁÌÉÚÁÃÉÑ ÇÉÓÔÏÇÒÁÍÍÙ: %s" msgstr "üË×ÁÌÉÚÁÃÉÑ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: ccdfunc.c:289 #: ccdfunc.c:292
msgid "Error saving file" msgid "Error saving file"
msgstr "ïÛÉÂËÁ ÓÏÈÒÁÎÅÎÉÑ ÆÁÊÌÁ" msgstr "ïÛÉÂËÁ ÓÏÈÒÁÎÅÎÉÑ ÆÁÊÌÁ"
#. start next capture #. start next capture
#. last image -> should re-expose #. last image -> should re-expose
#: client.c:459 client.c:470 client.c:489 #: client.c:533 client.c:544 client.c:563
#, c-format #, c-format
msgid "Exposing frame %d..." msgid "Exposing frame %d..."
msgstr "" msgstr ""
#: client.c:436 #: client.c:510
msgid "Exposing frame 1..." msgid "Exposing frame 1..."
msgstr "" msgstr ""
#: ccdfunc.c:640 #: ccdfunc.c:643
#, c-format #, c-format
msgid "Field of view: %s" msgid "Field of view: %s"
msgstr "ðÏÌÅ ÚÒÅÎÉÑ: %s" msgstr "ðÏÌÅ ÚÒÅÎÉÑ: %s"
#: main.c:94 ccdfunc.c:213 #: main.c:91 ccdfunc.c:214
#, c-format #, c-format
msgid "File %s exists!" msgid "File %s exists!"
msgstr "" msgstr ""
#: ccdfunc.c:280 #: ccdfunc.c:283
#, c-format #, c-format
msgid "File saved as '%s'" msgid "File saved as '%s'"
msgstr "æÁÊÌ ÓÏÈÒÁÎÅÎ ËÁË '%s'" msgstr "æÁÊÌ ÓÏÈÒÁÎÅÎ ËÁË '%s'"
#: ccdfunc.c:353 #: ccdfunc.c:356
msgid "Focuser device not pointed" msgid "Focuser device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÆÏËÕÓÅÒÁ ÎÅ ÕËÁÚÁÎÏ" msgstr "õÓÔÒÏÊÓÔ×Ï ÆÏËÕÓÅÒÁ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:586 #: ccdfunc.c:589
#, c-format #, c-format
msgid "Found %d cameras, you point number %d" msgid "Found %d cameras, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÁÍÅÒ, ×Ù ÕËÁÚÁÌÉ %d" msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÁÍÅÒ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:390 #: ccdfunc.c:393
#, c-format #, c-format
msgid "Found %d focusers, you point number %d" msgid "Found %d focusers, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ÆÏËÕÓÅÒÏ×, ×Ù ÕËÁÚÁÌÉ %d" msgstr "ïÂÎÁÒÕÖÅÎÏ %d ÆÏËÕÓÅÒÏ×, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:480 #: ccdfunc.c:483
#, c-format #, c-format
msgid "Found %d wheels, you point number %d" msgid "Found %d wheels, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÏÌÅÓ, ×Ù ÕËÁÚÁÌÉ %d" msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÏÌÅÓ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:580 #: ccdfunc.c:583
#, c-format #, c-format
msgid "Found camera #%d: %s\n" msgid "Found camera #%d: %s\n"
msgstr "" msgstr ""
#: ccdfunc.c:384 #: ccdfunc.c:387
#, c-format #, c-format
msgid "Found focuser #%d: %s\n" msgid "Found focuser #%d: %s\n"
msgstr "" msgstr ""
#: ccdfunc.c:474 #: ccdfunc.c:477
#, c-format #, c-format
msgid "Found wheel #%d: %s\n" msgid "Found wheel #%d: %s\n"
msgstr "" msgstr ""
#: client.c:477 #: client.c:551
msgid "Frame ready, try to grab" msgid "Frame ready, try to grab"
msgstr "" msgstr ""
#. for(int i = 0; i < NFRM; ++i) printf("last[%d]=%g\n", i, lastn[i]); #. for(int i = 0; i < NFRM; ++i) printf("last[%d]=%g\n", i, lastn[i]);
#: ccdfunc.c:834 #: ccdfunc.c:837
#, c-format #, c-format
msgid "Framerate=%.2f (%g seconds for exp); mean framerate=%.2f" msgid "Framerate=%.2f (%g seconds for exp); mean framerate=%.2f"
msgstr "" msgstr ""
#: ccdfunc.c:637 #: ccdfunc.c:640
#, c-format #, c-format
msgid "Full array: %s" msgid "Full array: %s"
msgstr "ðÏÌÎÙÊ ÆÏÒÍÁÔ: %s" msgstr "ðÏÌÎÙÊ ÆÏÒÍÁÔ: %s"
#: ccdfunc.c:648 #: ccdfunc.c:651
#, c-format #, c-format
msgid "Geometry steps: offset - %dx%d, size - %dx%d" msgid "Geometry steps: offset - %dx%d, size - %dx%d"
msgstr "" msgstr ""
@@ -465,11 +480,15 @@ msgstr ""
msgid "Get signal %d - exit" msgid "Get signal %d - exit"
msgstr "" msgstr ""
#: client.c:487 #: client.c:561
msgid "Got already saved image, wait next" msgid "Got already saved image, wait next"
msgstr "" msgstr ""
#: imageview.c:425 #: client.c:157
msgid "Got empty string"
msgstr ""
#: imageview.c:427
#, c-format #, c-format
msgid "Histogram conversion: %s" msgid "Histogram conversion: %s"
msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s" msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
@@ -478,32 +497,32 @@ msgstr "
msgid "INET image socket port" msgid "INET image socket port"
msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ ÐÅÒÅÄÁÞÉ ÉÚÏÂÒÁÖÅÎÉÑ" msgstr "ÐÏÒÔ ÌÏËÁÌØÎÏÇÏ ÓÅÔÅ×ÏÇÏ ÓÏËÅÔÁ ÐÅÒÅÄÁÞÉ ÉÚÏÂÒÁÖÅÎÉÑ"
#: ccdfunc.c:202 #: ccdfunc.c:203
msgid "Image not saved: neither filename nor filename prefix pointed" msgid "Image not saved: neither filename nor filename prefix pointed"
msgstr "" msgstr ""
#: ccdfunc.c:344 #: ccdfunc.c:347
#, c-format #, c-format
msgid "Image stat:\n" msgid "Image stat:\n"
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n" msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n"
#: client.c:560 #: client.c:638
#, c-format #, c-format
msgid "Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d " msgid "Image wasn't received, state: %d, waiting: %g, lastNo: %d, curNo: %d "
"(timeout: %g)" "(timeout: %g)"
msgstr "" msgstr ""
#: server.c:1156 #: server.c:1189
msgid "Limit of connections reached" msgid "Limit of connections reached"
msgstr "" msgstr ""
#: main.c:127 #: main.c:124
#, c-format #, c-format
msgid "Log file %s @ level %d\n" msgid "Log file %s @ level %d\n"
msgstr "" msgstr ""
#. save image #. save image
#: imageview.c:734 #: imageview.c:752
msgid "Make screenshot" msgid "Make screenshot"
msgstr "" msgstr ""
@@ -512,22 +531,22 @@ msgstr ""
msgid "Master killed with sig=%d" msgid "Master killed with sig=%d"
msgstr "" msgstr ""
#: ccdfunc.c:662 #: ccdfunc.c:665
#, c-format #, c-format
msgid "Maximal gain: %g" msgid "Maximal gain: %g"
msgstr "" msgstr ""
#: ccdfunc.c:646 #: ccdfunc.c:649
#, c-format #, c-format
msgid "Maximal geometry (WxH): %dx%d" msgid "Maximal geometry (WxH): %dx%d"
msgstr "" msgstr ""
#: ccdfunc.c:647 #: ccdfunc.c:650
#, c-format #, c-format
msgid "Minimal offset: %dx%d" msgid "Minimal offset: %dx%d"
msgstr "" msgstr ""
#: imageview.c:615 #: imageview.c:616
#, c-format #, c-format
msgid "Missed %zd images" msgid "Missed %zd images"
msgstr "" msgstr ""
@@ -536,63 +555,63 @@ msgstr ""
msgid "N flushes before exposing (default: 1)" msgid "N flushes before exposing (default: 1)"
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)" msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
#: ccdfunc.c:956 #: ccdfunc.c:948
msgid "Need exposition time!" msgid "Need exposition time!"
msgstr "" msgstr ""
#: server.c:247 #: server.c:270
msgid "No camera device" msgid "No camera device"
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ" msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
#: ccdfunc.c:554 ccdfunc.c:555 #: ccdfunc.c:557 ccdfunc.c:558
msgid "No cameras found" msgid "No cameras found"
msgstr "ëÁÍÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎÏ" msgstr "ëÁÍÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: server.c:1082 #: server.c:1115
#, fuzzy #, fuzzy
msgid "No devices found" msgid "No devices found"
msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ" msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:360 #: ccdfunc.c:363
msgid "No focusers found" msgid "No focusers found"
msgstr "æÏËÕÓÅÒÏ× ÎÅ ÏÂÎÁÒÕÖÅÎÏ" msgstr "æÏËÕÓÅÒÏ× ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: imageview.c:697 #: imageview.c:711
msgid "No image changing function defined" msgid "No image changing function defined"
msgstr "" msgstr ""
#: ccdfunc.c:450 #: ccdfunc.c:453
msgid "No wheels found" msgid "No wheels found"
msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ" msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:742 #: ccdfunc.c:745
msgid "Only show statistics" msgid "Only show statistics"
msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ" msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ"
#: main.c:101 #: main.c:98
msgid "Options `port` and `path` can't be used together! Point `port` for " msgid "Options `port` and `path` can't be used together! Point `port` for "
"TCP socket or `path` for UNIX." "TCP socket or `path` for UNIX."
msgstr "" msgstr ""
#: ccdfunc.c:631 #: ccdfunc.c:634
#, c-format #, c-format
msgid "Pixel size: %g x %g" msgid "Pixel size: %g x %g"
msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g" msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g"
#: ccdfunc.c:943 #: ccdfunc.c:935
msgid "Point network port or UNIX-socket path" msgid "Point network port or UNIX-socket path"
msgstr "" msgstr ""
#: ccdfunc.c:781 #: ccdfunc.c:784
msgid "Read grabbed image" msgid "Read grabbed image"
msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ" msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ"
#: ccdfunc.c:741 #: ccdfunc.c:744
#, c-format #, c-format
msgid "Readout mode: %s" msgid "Readout mode: %s"
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s" msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
#: client.c:173 #: client.c:186
#, fuzzy #, fuzzy
msgid "Send custom plugin commands\n" msgid "Send custom plugin commands\n"
msgstr "ÏÓÏÂÙÅ ËÏÍÁÎÄÙ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ" msgstr "ÏÓÏÂÙÅ ËÏÍÁÎÄÙ ÐÌÁÇÉÎÁ ËÁÍÅÒÙ"
@@ -600,59 +619,76 @@ msgstr "
#. send message and wait any answer #. send message and wait any answer
#. send message and wait answer starting with 'cmd' #. send message and wait answer starting with 'cmd'
#. send command and wait for answer on it #. send command and wait for answer on it
#: client.c:42 client.c:44 client.c:46 client.c:276 #: client.c:42 client.c:44 client.c:46 client.c:288
#, fuzzy #, fuzzy
msgid "Server disconnected" msgid "Server disconnected"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ" msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
#: server.c:1061 #: client.c:149
#, fuzzy
msgid "Server disconnected?"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
#: server.c:1093
msgid "Server run without image transport socket" msgid "Server run without image transport socket"
msgstr "" msgstr ""
#: client.c:511 #: client.c:585
msgid "Server timeout" msgid "Server timeout"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ" msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
#: ccdfunc.c:704 #: ccdfunc.c:707
#, c-format #, c-format
msgid "Set brightness to %g" msgid "Set brightness to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g" msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:625 #: ccdfunc.c:628
#, c-format #, c-format
msgid "Set fan speed to %d" msgid "Set fan speed to %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d"
#: ccdfunc.c:698 #: ccdfunc.c:701
#, c-format #, c-format
msgid "Set gain to %g" msgid "Set gain to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ Gain × %g" msgstr "õÓÔÁÎÏ×ÉÔØ Gain × %g"
#: main.c:119 #: main.c:116
#, fuzzy, c-format #, fuzzy, c-format
msgid "Set image port to %s\n" msgid "Set image port to %s\n"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d" msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d"
#: imageview.c:738 #: imageview.c:756
#, c-format #, c-format
msgid "Set output prefix to %s" msgid "Set output prefix to %s"
msgstr "" msgstr ""
#: ccdfunc.c:673 #: ccdfunc.c:676
#, c-format #, c-format
msgid "Shutter command: %s\n" msgid "Shutter command: %s\n"
msgstr "ëÏÍÁÎÄÁ ÚÁÔ×ÏÒÁ: %s\n" msgstr "ëÏÍÁÎÄÁ ÚÁÔ×ÏÒÁ: %s\n"
#: ccdfunc.c:861 #: ccdfunc.c:863
msgid "Some error when capture" msgid "Some error when capture"
msgstr "ïÛÉÂËÁ ÐÒÉ ÚÁÈ×ÁÔÅ" msgstr "ïÛÉÂËÁ ÐÒÉ ÚÁÈ×ÁÔÅ"
#: ccdfunc.c:678 #: server.c:222
msgid "Something's wrong with camera"
msgstr ""
#: client.c:466
msgid "Still got old image"
msgstr ""
#: client.c:440
msgid "Too many FITS headers, truncating"
msgstr ""
#: ccdfunc.c:681
#, c-format #, c-format
msgid "Try to configure I/O port as %d" msgid "Try to configure I/O port as %d"
msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d" msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d"
#: ccdfunc.c:689 #: ccdfunc.c:692
#, c-format #, c-format
msgid "Try to write %d to I/O port" msgid "Try to write %d to I/O port"
msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O" msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O"
@@ -661,34 +697,26 @@ msgstr "
msgid "UNIX socket name (command socket)" msgid "UNIX socket name (command socket)"
msgstr "ÉÍÑ UNIX-ÓÏËÅÔÁ" msgstr "ÉÍÑ UNIX-ÓÏËÅÔÁ"
#: client.c:439 #: client.c:512
#, fuzzy #, fuzzy
msgid "Wait for exposition end" msgid "Wait for exposition end"
msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ" msgstr "ÖÄÁÔØ, ÐÏËÁ ÎÅ ËÏÎÞÉÔÓÑ ÜËÓÐÏÚÉÃÉÑ"
#: ccdfunc.c:443 #: ccdfunc.c:446
msgid "Wheel device not pointed" msgid "Wheel device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÔÕÒÅÌÉ ÎÅ ÕËÁÚÁÎÏ" msgstr "õÓÔÒÏÊÓÔ×Ï ÔÕÒÅÌÉ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:489 #: ccdfunc.c:492
#, fuzzy, c-format #, fuzzy, c-format
msgid "Wheel model: %s" msgid "Wheel model: %s"
msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s" msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s"
#: ccdfunc.c:507 #: ccdfunc.c:510
#, c-format #, c-format
msgid "Wheel position should be from 0 to %d" msgid "Wheel position should be from 0 to %d"
msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d" msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d"
#: client.c:328 #: main.c:103
msgid "Wrong image size"
msgstr ""
#: client.c:324
msgid "Wrong image: bad magick"
msgstr ""
#: main.c:106
#, c-format #, c-format
msgid "Wrong port value: %d" msgid "Wrong port value: %d"
msgstr "" msgstr ""
@@ -775,10 +803,6 @@ msgstr ""
msgid "get value of I/O port pins" msgid "get value of I/O port pins"
msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O" msgstr "ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÏÒÔÁ I/O"
#: client.c:316
msgid "getimage(): can't open image transport socket"
msgstr ""
#: cmdlnopts.c:92 #: cmdlnopts.c:92
msgid "horizontal binning to N pixels" msgid "horizontal binning to N pixels"
msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ" msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
@@ -844,11 +868,11 @@ msgstr "
msgid "observing program name" msgid "observing program name"
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ" msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ"
#: imageview.c:751 #: imageview.c:769
msgid "off" msgid "off"
msgstr "×ÙËÌ" msgstr "×ÙËÌ"
#: imageview.c:751 #: imageview.c:769
msgid "on" msgid "on"
msgstr "×ËÌ" msgstr "×ËÌ"
@@ -892,7 +916,7 @@ msgstr "
msgid "run in 8-bit mode" msgid "run in 8-bit mode"
msgstr "8-ÂÉÔÎÙÊ ÒÅÖÉÍ" msgstr "8-ÂÉÔÎÙÊ ÒÅÖÉÍ"
#: server.c:1060 #: server.c:1092
msgid "server(): need at least command socket fd" msgid "server(): need at least command socket fd"
msgstr "" msgstr ""
@@ -928,7 +952,7 @@ msgstr "
msgid "start (!=0) or stop(==0) infinity capturing loop" msgid "start (!=0) or stop(==0) infinity capturing loop"
msgstr "ÎÁÞÁÔØ (!=0) ÉÌÉ ÚÁËÏÎÞÉÔØ (==0) ÂÅÓËÏÎÅÞÎÙÊ ÃÉËÌ ÚÁÈ×ÁÔÁ ÉÚÏÂÒÁÖÅÎÉÊ" msgstr "ÎÁÞÁÔØ (!=0) ÉÌÉ ÚÁËÏÎÞÉÔØ (==0) ÂÅÓËÏÎÅÞÎÙÊ ÃÉËÌ ÚÁÈ×ÁÔÁ ÉÚÏÂÒÁÖÅÎÉÊ"
#: ccdfunc.c:947 #: ccdfunc.c:939
msgid "start_socket(): can't open socket" msgid "start_socket(): can't open socket"
msgstr "" msgstr ""

11
main.c
View File

@@ -58,16 +58,13 @@ void signals(int signo){
if(!GP->client){ if(!GP->client){
DBG("Cancel capturing and close all"); DBG("Cancel capturing and close all");
stop_server(); stop_server();
camstop(); }else exit(signo);
closewheel();
focclose();
}
#ifdef IMAGEVIEW #ifdef IMAGEVIEW
DBG("KILL GL"); DBG("KILL GL");
closeGL(); closeGL();
#endif #endif
DBG("exit(%d)", signo); //DBG("exit(%d)", signo);
exit(signo); //exit(signo);
} }
int main(int argc, char **argv){ int main(int argc, char **argv){
@@ -148,7 +145,7 @@ int main(int argc, char **argv){
return start_socket(isserver); return start_socket(isserver);
} }
#ifdef IMAGEVIEW #ifdef IMAGEVIEW
if(GP->showimage){ // activate image vindow in capture or simple viewer mode if(GP->showimage){ // activate image window in capture or simple viewer mode
imagefunc imfn = NULL; imagefunc imfn = NULL;
if(GP->cameradev || GP->commondev){if(camerainit) imfn = ccdcaptured;} // capture mode if(GP->cameradev || GP->commondev){if(camerainit) imfn = ccdcaptured;} // capture mode
else imfn = NULL; // TODO - simple file viewer else imfn = NULL; // TODO - simple file viewer

View File

@@ -43,6 +43,9 @@ static _Atomic cc_camera_state camstate = CAMERA_IDLE;
static atomic_int camflags = 0, camfanspd = 0, confio = 0, nflushes, infty = 0; static atomic_int camflags = 0, camfanspd = 0, confio = 0, nflushes, infty = 0;
static cc_frameformat frmformatmax = {0}, curformat = {0}; // maximal format static cc_frameformat frmformatmax = {0}, curformat = {0}; // maximal format
// image in shared memory
static cc_IMG *ima = NULL;
static float focmaxpos = 0., focminpos = 0.; // focuser extremal positions static float focmaxpos = 0., focminpos = 0.; // focuser extremal positions
static int wmaxpos = 0.; // wheel max pos static int wmaxpos = 0.; // wheel max pos
static float tremain = 0.; // time when capture done static float tremain = 0.; // time when capture done
@@ -114,10 +117,10 @@ static pthread_mutex_t locmutex = PTHREAD_MUTEX_INITIALIZER; // mutex for wheel/
// return TRUE if `locmutex` can be locked // return TRUE if `locmutex` can be locked
static int lock(){ static int lock(){
if(pthread_mutex_trylock(&locmutex)){ if(pthread_mutex_trylock(&locmutex)){
//DBG("\n\nAlready locked"); DBG("\n\nAlready locked &locmutex");
return FALSE; return FALSE;
} }
//DBG("LOCK()"); //DBG("\n\nLOCK(&locmutex)");
return TRUE; return TRUE;
} }
static void unlock(){ static void unlock(){
@@ -125,11 +128,9 @@ static void unlock(){
LOGERR("Can't unlock socket mutex"); LOGERR("Can't unlock socket mutex");
ERR(_("Can't unlock socket mutex")); ERR(_("Can't unlock socket mutex"));
} }
//DBG("UNLOCK()"); //DBG("\n\nUNLOCK(&locmutex)");
} }
static cc_IMG *ima = NULL;
// cleanup semaphore, stop server processes // cleanup semaphore, stop server processes
void stop_server(){ void stop_server(){
isrunning = 0; isrunning = 0;
@@ -139,6 +140,7 @@ void stop_server(){
if(isrunning == -1) break; if(isrunning == -1) break;
usleep(1000); usleep(1000);
} }
DBG("OK, remove semaphore...");
// destroy semaphore // destroy semaphore
cc_remove_sem(); cc_remove_sem();
} }
@@ -150,8 +152,9 @@ static void fixima(){
int locked = FALSE; int locked = FALSE;
TIMESTAMP("Lock socket"); TIMESTAMP("Lock socket");
// lock socket operations // lock socket operations
while(!(locked = lock()) && sl_dtime() - t0 < 0.5) usleep(1000); while(!(locked = lock()) && sl_dtime() - t0 < 0.5) usleep(100000);
if(!locked){ if(!locked){
LOGDBG("fixima(): force unlock");
DBG("Still locked from outside -> unlock/lock"); DBG("Still locked from outside -> unlock/lock");
while(!lock()) unlock(); // force unlocking if can't do this gracefully while(!lock()) unlock(); // force unlocking if can't do this gracefully
}else DBG("LOCK takes %gs", sl_dtime()-t0); }else DBG("LOCK takes %gs", sl_dtime()-t0);
@@ -159,13 +162,16 @@ static void fixima(){
TIMESTAMP("Check SHM image"); TIMESTAMP("Check SHM image");
// allocate memory for largest possible image // allocate memory for largest possible image
if(!ima){ if(!ima){
ima = cc_getshm(GP->shmkey, camera->array.h * camera->array.w * 2); size_t len = camera->array.h * camera->array.w * 2;
ima = cc_getshm(GP->shmkey, len);
if(!ima) ERR(_("Can't allocate memory for image")); if(!ima) ERR(_("Can't allocate memory for image"));
ima->datasize = ima->bytelen;
// init shared semaphore // init shared semaphore
cc_init_sem(TRUE); cc_init_sem(TRUE);
} }
TIMESTAMP("Lock SHM image"); TIMESTAMP("Lock SHM image");
cc_lock_shm(TRUE); cc_lock_shm(TRUE);
LOGDBG("fixima(): SHM locked");
shmkey = GP->shmkey; shmkey = GP->shmkey;
//if(raw_width == ima->w && raw_height == ima->h) return; // all OK //if(raw_width == ima->w && raw_height == ima->h) return; // all OK
DBG("curformat: %dx%d", curformat.w, curformat.h); DBG("curformat: %dx%d", curformat.w, curformat.h);
@@ -179,12 +185,14 @@ static void fixima(){
ima->bytelen = raw_height * raw_width * cc_getNbytes(ima); ima->bytelen = raw_height * raw_width * cc_getNbytes(ima);
DBG("new image: %dx%d", raw_width, raw_height); DBG("new image: %dx%d", raw_width, raw_height);
cc_unlock_shm(); cc_unlock_shm();
LOGDBG("fixima(): SHM UNlocked");
unlock(); unlock();
TIMESTAMP("All OK"); TIMESTAMP("All OK");
} }
// functions for processCAM finite state machine // functions for processCAM finite state machine
static inline void cameraidlestate(){ // idle - wait for capture commands static inline void cameraidlestate(){ // idle - wait for capture commands
static double Tcheck = 0.;
if(camflags & FLAG_STARTCAPTURE){ // start capturing if(camflags & FLAG_STARTCAPTURE){ // start capturing
TIMESTAMP("Start exposition"); TIMESTAMP("Start exposition");
camflags &= ~(FLAG_STARTCAPTURE | FLAG_CANCEL); camflags &= ~(FLAG_STARTCAPTURE | FLAG_CANCEL);
@@ -194,15 +202,28 @@ static inline void cameraidlestate(){ // idle - wait for capture commands
LOGERR("Camera plugin have no function `start exposition`"); LOGERR("Camera plugin have no function `start exposition`");
WARNX(_("Camera plugin have no function `start exposition`")); WARNX(_("Camera plugin have no function `start exposition`"));
camstate = CAMERA_ERROR; camstate = CAMERA_ERROR;
return;
} }
if(!camera->startexposition()){ if(!camera->startexposition()){
LOGERR("Can't start exposition"); LOGERR("Can't start exposition");
WARNX(_("Can't start exposition")); WARNX(_("Can't start exposition"));
camstate = CAMERA_ERROR; camstate = CAMERA_ERROR;
return;
} }
} }
if(camstate == CAMERA_ERROR || (camstate == CAMERA_IDLE && sl_dtime() - Tcheck > 5.)){
Tcheck = sl_dtime();
if(!camera->check()){
LOGERR("Camera disconnected");
ERRX(_("Camera disconnected"));
}
if(camera->setDevNo && !camera->setDevNo(GP->camdevno)){
LOGERR("Can't set active camera # %d, try 0", GP->camdevno);
if(!camera->setDevNo(0)){
LOGERR("Can't set active camera # 0, restart");
ERRX(_("Something's wrong with camera"));
}
}
camstate = CAMERA_IDLE;
}
} }
static inline void cameracapturestate(){ // capturing - wait for exposition ends static inline void cameracapturestate(){ // capturing - wait for exposition ends
cc_capture_status cs; cc_capture_status cs;
@@ -221,6 +242,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
return; return;
} }
cc_lock_shm(TRUE); cc_lock_shm(TRUE);
LOGDBG("cameracapturestate(): SHM locked");
if(!camera->capture(ima)){ if(!camera->capture(ima)){
LOGERR("Can't capture image"); LOGERR("Can't capture image");
camstate = CAMERA_ERROR; camstate = CAMERA_ERROR;
@@ -233,6 +255,7 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
++ima->imnumber; // increment counter ++ima->imnumber; // increment counter
} }
cc_unlock_shm(); cc_unlock_shm();
LOGDBG("cameracapturestate(): SHM UNlocked");
TIMESTAMP("Captured and unlocked"); TIMESTAMP("Captured and unlocked");
} }
camstate = CAMERA_FRAMERDY; camstate = CAMERA_FRAMERDY;
@@ -434,7 +457,7 @@ static cc_hresult binhandler(_U_ int fd, const char *key, const char *val){
if(r){ if(r){
if(0 == strcmp(key, CC_CMD_HBIN)) snprintf(buf, 63, "%s=%d", key, GP->hbin); if(0 == strcmp(key, CC_CMD_HBIN)) snprintf(buf, 63, "%s=%d", key, GP->hbin);
else snprintf(buf, 63, "%s=%d", key, GP->vbin); else snprintf(buf, 63, "%s=%d", key, GP->vbin);
if(val) fixima(); //if(val) fixima();
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
} }
@@ -590,7 +613,7 @@ static cc_hresult formathandler(int fd, const char *key, const char *val){
if(!r) return CC_RESULT_FAIL; if(!r) return CC_RESULT_FAIL;
curformat = fmt; curformat = fmt;
DBG("curformat: w=%d, h=%d", curformat.w, curformat.h); DBG("curformat: w=%d, h=%d", curformat.w, curformat.h);
fixima(); //fixima();
} }
if(0 == strcmp(key, CC_CMD_FRAMEMAX)) snprintf(buf, 63, CC_CMD_FRAMEMAX "=%d,%d,%d,%d", if(0 == strcmp(key, CC_CMD_FRAMEMAX)) snprintf(buf, 63, CC_CMD_FRAMEMAX "=%d,%d,%d,%d",
frmformatmax.xoff, frmformatmax.yoff, frmformatmax.xoff+frmformatmax.w, frmformatmax.yoff+frmformatmax.h); frmformatmax.xoff, frmformatmax.yoff, frmformatmax.xoff+frmformatmax.w, frmformatmax.yoff+frmformatmax.h);
@@ -624,11 +647,11 @@ static cc_hresult expstatehandler(int fd, _U_ const char *key, const char *val){
else if(n == CAMERA_CAPTURE){ // start exposition else if(n == CAMERA_CAPTURE){ // start exposition
if(GP->exptime < 1e-9){ // need exposition time to be set if(GP->exptime < 1e-9){ // need exposition time to be set
return CC_RESULT_FAIL; return CC_RESULT_FAIL;
} }/*
if(camstate == CAMERA_CAPTURE){ if(camstate == CAMERA_CAPTURE){
DBG("Capture in process when user ask '%s=%s'", key, val); DBG("Capture in process when user ask '%s=%s'", key, val);
return CC_RESULT_BUSY; // in progress return CC_RESULT_BUSY; // in progress
} }*/
TIMESTAMP("Get FLAG_STARTCAPTURE"); TIMESTAMP("Get FLAG_STARTCAPTURE");
TIMEINIT(); TIMEINIT();
camflags |= FLAG_STARTCAPTURE; camflags |= FLAG_STARTCAPTURE;
@@ -658,7 +681,7 @@ static cc_hresult _8bithandler(int fd, _U_ const char *key, const char *val){
int s = atoi(val); int s = atoi(val);
if(s != 0 && s != 1) return CC_RESULT_BADVAL; if(s != 0 && s != 1) return CC_RESULT_BADVAL;
if(!camera->setbitdepth(!s)) return CC_RESULT_FAIL; if(!camera->setbitdepth(!s)) return CC_RESULT_FAIL;
fixima(); //fixima();
GP->_8bit = s; GP->_8bit = s;
} }
snprintf(buf, 63, CC_CMD_8BIT "=%d", GP->_8bit); snprintf(buf, 63, CC_CMD_8BIT "=%d", GP->_8bit);
@@ -669,8 +692,10 @@ static cc_hresult imnohandler(int fd, const char *key, const char _U_ *val){
if(!ima) return CC_RESULT_FAIL; if(!ima) return CC_RESULT_FAIL;
char buf[64]; char buf[64];
cc_lock_shm(TRUE); cc_lock_shm(TRUE);
LOGDBG("imnohandler(): SHM locked");
int No = ima->imnumber; int No = ima->imnumber;
cc_unlock_shm(); cc_unlock_shm();
LOGDBG("imnohandler(): SHM UNlocked");
snprintf(buf, 63, "%s=%d", key, No); snprintf(buf, 63, "%s=%d", key, No);
if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED; if(!cc_sendstrmessage(fd, buf)) return CC_RESULT_DISCONNECTED;
return CC_RESULT_SILENCE; return CC_RESULT_SILENCE;
@@ -1025,31 +1050,38 @@ static void *sendimage(void *C){
int client = *(int*)C; int client = *(int*)C;
if(ima->h < 1 || ima->w < 1) return NULL; if(ima->h < 1 || ima->w < 1) return NULL;
DBG("client fd: %d", client); DBG("client fd: %d", client);
cc_lock_shm(TRUE); double t0 = sl_dtime();
cc_IMG *locimage = calloc(1, sizeof(cc_IMG)); int locked = FALSE;
void *data = calloc(1, ima->bytelen); while(!(locked = cc_lock_shm(FALSE)) && sl_dtime() - t0 < MUTEX_LOCK_TMOUT);
if(!locimage || !data){ if(!locked){
cc_unlock_shm(); LOGERR("sendimage(): can't lock SHM");
if(data) free(data); close(client);
if(locimage) free(locimage); return NULL;
}
LOGDBG("sendimage(): SHM locked");
cc_IMG *locimage = cc_newimage(ima->bitpix, ima->w, ima->h);
if(!locimage || !cc_copyimage(locimage, ima, FALSE)){
cc_unlock_shm();
LOGDBG("sendimage(): SHM UNlocked");
LOGERR("Can't copy new frame to local image");
return NULL; return NULL;
} }
memcpy(locimage, ima, sizeof(cc_IMG));
memcpy(data, ima->data, ima->bytelen);
cc_unlock_shm(); cc_unlock_shm();
LOGDBG("sendimage(): SHM UNlocked");
do{ do{
// send image body // send image body
if(!cc_senddata(client, locimage, sizeof(cc_IMG))) break; if(!cc_senddata(client, locimage, sizeof(cc_IMG))) break;
// send image itself (client can close socket if don't need image data) // send image itself (client can close socket if don't need image data)
if(!cc_senddata(client, data, locimage->bytelen)) break; if(!cc_senddata(client, locimage->data, locimage->bytelen)) break;
// send FITS header (client can close socket if don't need it) // send FITS header (client can close socket if don't need it)
for(size_t i = 0; i < locimage->headerstrings; ++i){ // send header for(size_t i = 0; i < locimage->headerstrings; ++i){ // send header
if(!cc_senddata(client, &locimage->fitsheader[i], FLEN_CARD)) break; if(!cc_senddata(client, &locimage->fitsheader[i], FLEN_CARD)) break;
} }
}while(0); }while(0);
free(locimage); shutdown(client, SHUT_WR); // tell client we are closing socket
free(data); recv(client, locimage->data, locimage->bytelen, MSG_NOSIGNAL); // block until client close his side
close(client); cc_freeimage(&locimage);
close(client); // OK, we can close socket
TIMESTAMP("Image sent"); TIMESTAMP("Image sent");
DBG("%d closed", client); DBG("%d closed", client);
return NULL; return NULL;
@@ -1069,6 +1101,7 @@ void server(int sock, int imsock){
LOGERR("server(): error in listen() for command socket"); LOGERR("server(): error in listen() for command socket");
return; return;
} }
TIMEINIT();
// init everything // init everything
int ctr = 3; int ctr = 3;
if(startFocuser()) --ctr; if(startFocuser()) --ctr;
@@ -1079,7 +1112,7 @@ void server(int sock, int imsock){
camdevini(0); camdevini(0);
if(ctr == 3){ if(ctr == 3){
LOGERR("server(): no devices found"); LOGERR("server(): no devices found");
WARNX(_("No devices found")); ERRX(_("No devices found"));
} }
// start camera thread // start camera thread
pthread_t camthread; pthread_t camthread;
@@ -1123,7 +1156,7 @@ void server(int sock, int imsock){
DBG("client=%d", client); DBG("client=%d", client);
// sending image could be a very long operation -> run it in separate thread // sending image could be a very long operation -> run it in separate thread
if(client > -1){ if(client > -1){
if(ima->imnumber == 0){ if(!ima || ima->imnumber == 0){
WARNX(_("Client wants an image, but there's no data")); WARNX(_("Client wants an image, but there's no data"));
close(client); close(client);
}else{ }else{
@@ -1267,7 +1300,9 @@ static int parsestring(int fd, cc_handleritem *handlers, char *str){
if(h->handler) r = h->handler(fd, str, val); if(h->handler) r = h->handler(fd, str, val);
else r = CC_RESULT_FAIL; else r = CC_RESULT_FAIL;
} }
if(l) unlock(); if(l){
unlock();
}
if(r == CC_RESULT_DISCONNECTED){ if(r == CC_RESULT_DISCONNECTED){
DBG("handler return CC_RESULT_DISCONNECTED"); DBG("handler return CC_RESULT_DISCONNECTED");
return FALSE; return FALSE;