From 0f4fcf50157d30ee4fc156c328c2db1e12ae7def Mon Sep 17 00:00:00 2001 From: Edward Emelianov Date: Wed, 7 Feb 2024 17:01:58 +0300 Subject: [PATCH] add custom plugin commands; start developing 'artifical star' plugin to generate 'vagrant stars' --- Astar_cameras/CMakeLists.txt | 15 ++ Astar_cameras/artifical_star.c | 385 +++++++++++++++++++++++++++ CMakeLists.txt | 15 +- Dummy_cameras/dummyfunc.c | 51 ++-- ccdcapture.c | 122 ++++++++- ccdcapture.h | 83 +++--- ccdfunc.c | 22 +- client.c | 1 - cmdlnopts.c | 2 +- locale/ru/LC_MESSAGES/ccd_capture.mo | Bin 13552 -> 15624 bytes locale/ru/messages.po | 140 +++++----- locale/ru/ru.po | 208 ++++++--------- server.c | 13 +- 13 files changed, 780 insertions(+), 277 deletions(-) create mode 100644 Astar_cameras/CMakeLists.txt create mode 100644 Astar_cameras/artifical_star.c diff --git a/Astar_cameras/CMakeLists.txt b/Astar_cameras/CMakeLists.txt new file mode 100644 index 0000000..fa299c2 --- /dev/null +++ b/Astar_cameras/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.20) +set(CCDLIB devastar) + +SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(${CCDLIB} REQUIRED usefull_macros improc) + +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC) +include_directories(${${CCDLIB}_INCLUDE_DIRS} ..) +link_directories(${${CCDLIB}_LIBRARY_DIRS}) + +add_library(${CCDLIB} SHARED ${SRC}) +target_link_libraries(${CCDLIB} ${${CCDLIB}_LIBRARIES} -fPIC) +install(TARGETS ${CCDLIB} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/Astar_cameras/artifical_star.c b/Astar_cameras/artifical_star.c new file mode 100644 index 0000000..2b81bea --- /dev/null +++ b/Astar_cameras/artifical_star.c @@ -0,0 +1,385 @@ +/* + * This file is part of the CCD_Capture project. + * Copyright 2022 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ccdcapture.h" +#include "omp.h" + +extern cc_Camera camera; +extern cc_Focuser focuser; +extern cc_Wheel wheel; + +static const int filtermax = 5; +static const float focmaxpos = 10.; +static int curhbin = 1, curvbin = 1; +static int filterpos = 0; +static float focuserpos = 1., brightness = 1., gain = 0.; +static float camtemp = -30., exptime = 0.; +static cc_capture_status capstat = CAPTURE_NO; +static double texpstart = 0.; +static uint8_t bitpix = 16; // bit depth: 8 or 16 + +typedef struct{ + int width; int height; // size of field where the 'star' can move + int x0; int y0; // center of star field in array coordinates + double fwhm; // stars FWHM, arcsec + double scale; // CCD scale: arcsec/pix + double mag; // star magnitude: 0m is 16384 ADUs per second per arcsec^2 +} settings_t; + +static settings_t settings = { + .width = 500, .height = 500, + .x0 = 512, .y0 = 512, + .fwhm = 1.5, .scale = 0.03, .mag = 10. +}; +// min/max for parameters +static const int wmin = 100, hmin = 100; +static const double fwhmmin = 0.1, fwhmmax = 10., scalemin = 0.001, scalemax = 3600., magmin = -30., magmax = 30.; + +static int campoll(cc_capture_status *st, float *remain){ + if(capstat != CAPTURE_PROCESS){ + if(st) *st = capstat; + if(remain) *remain = 0.; + return TRUE; + } + if(dtime() - texpstart > exptime){ + if(st) *st = CAPTURE_READY; + if(remain) *remain = 0.; + capstat = CAPTURE_NO; + return TRUE; + } + if(st) *st = capstat; + if(remain) *remain = exptime + texpstart - dtime(); + return TRUE; +} + +static int startexp(){ + if(capstat == CAPTURE_PROCESS) return FALSE; + capstat = CAPTURE_PROCESS; + texpstart = dtime(); + return TRUE; +} + +static void gen16(cc_IMG *ima){ + static int n = 0; + int y1 = ima->h * curvbin, x1 = ima->w * curhbin; + OMP_FOR() + for(int y = 0; y < y1; y += curvbin){ + uint16_t *d = &((uint16_t*)ima->data)[y*ima->w/curvbin]; + for(int x = 0; x < x1; x += curhbin){ // sinusoide 100x200 + //*d++ = (uint16_t)(((n+x)%100)/99.*65535.); + *d++ = (uint16_t)((1. + sin((n+x) * (2.*M_PI)/11.)*sin((n+y) * (2.*M_PI)/22.))*32767.); + } + } + ++n; +} +static void gen8(cc_IMG *ima){ + static int n = 0; + int y1 = ima->h * curvbin, x1 = ima->w * curhbin; + OMP_FOR() + for(int y = 0; y < y1; y += curvbin){ + uint8_t *d = &((uint8_t*)ima->data)[y*ima->w/curvbin]; + for(int x = 0; x < x1; x += curhbin){ // sinusoide 100x200 + //*d++ = (uint16_t)(((n+x)%100)/99.*65535.); + *d++ = (uint8_t)((1. + sin((n+x) * (2.*M_PI)/11.)*sin((n+y) * (2.*M_PI)/22.))*127.); + } + } + ++n; +} + +static int camcapt(cc_IMG *ima){ + if(!ima || !ima->data) return FALSE; +#ifdef EBUG + double t0 = dtime(); +#endif + ima->bitpix = bitpix; + bzero(ima->data, ima->h*ima->w*cc_getNbytes(ima)); + if(bitpix == 16) gen16(ima); + else gen8(ima); + DBG("Time of capture: %g", dtime() - t0); + return TRUE; +} + +static int camsetbit(int b){ + bitpix = (b) ? 16 : 8; + return TRUE; +} + +static int camgetbp(uint8_t *bp){ + if(bp) *bp = bitpix; + return TRUE; +} + +static void camcancel(){ + capstat = CAPTURE_NO; +} + +static int setdevno(int n){ + if(n) return FALSE; + return TRUE; +} + +static int camsetbrig(float b){ + brightness = b; + return TRUE; +} + +static int camgetbrig(float *b){ + if(!b) return FALSE; + *b = brightness; + return TRUE; +} + +static int camsetexp(float t){ + exptime = t; + return TRUE; +} +static int camsetgain(float g){ + gain = g; + return TRUE; +} + +static int camgetgain(float *g){ + if(g) *g = gain; + return TRUE; +} + +static int camsett(float t){ + camtemp = t; + return TRUE; +} + +static int camgett(float *t){ + if(t) *t = camtemp; + return TRUE; +} + +static int gett(float *t){ + if(t) *t = M_PI; + return TRUE; +} + +static int camsetbin(int h, int v){ + DBG("set bin %dx%d", h, v); + curhbin = h; curvbin = v; + return TRUE; +} + +static int camshutter(_U_ cc_shutter_op s){ + return TRUE; +} + +static int camsetgeom(cc_frameformat *f){ + if(!f) return FALSE; + camera.geometry = *f; + return TRUE; +} + +static int camgetnam(char *n, int l){ + strncpy(n, "Dummy camera", l); + return TRUE; +} + +static int camgmg(float *mg){ + if(mg) *mg = 10.; + return TRUE; +} + +static int camggl(cc_frameformat *max, cc_frameformat *step){ + if(max) *max = camera.array; + if(step) *step = (cc_frameformat){1,1,1,1}; + return TRUE; +} + +static int camgetbin(int *binh, int *binv){ + if(binh) *binh = curhbin; + if(binv) *binv = curvbin; + return TRUE; +} + +static int camgetio(int *io){ + if(io) *io = 0xDEADBEEF; + return TRUE; +} + +static int camfan(_U_ cc_fan_speed spd){return TRUE;} + +static int focsetpos(_U_ int a, float n){ + if(n < 0. || n > focmaxpos) return FALSE; + focuserpos = n; + return TRUE; +} + +static int fochome(_U_ int a){ + focuserpos = 0.; + return TRUE; +} + +static int focgetnam(char *n, int l){ + strncpy(n, "Dummy focuser", l); + return TRUE; +} + +static int focpos(float *p){ + if(p) *p = focuserpos; + return TRUE; +} + +static int focMp(float *p){ + if(p) *p = focmaxpos; + return TRUE; +} + +static int focmp(float *p){ + if(p) *p = 0.; + return TRUE; +} + +static int whlsetpos(int n){ + if(n >= filtermax || n < 0) return FALSE; + filterpos = n; + return TRUE; +} + +static int whlgetpos(int *n){ + if(n) *n = filterpos; + return TRUE; +} + +static int whlgmp(int *n){ + if(n) *n = filtermax; + return TRUE; +} + +static int whlgetnam(char *n, int l){ + strncpy(n, "Dummy filter wheel", l); + return TRUE; +} + +// cmd, help, handler, ptr, min, max, type +static cc_parhandler_t handlers[] = { + {"width", "width of star moving field", NULL, (void*)&settings.width, (void*)&wmin, NULL, CC_PAR_INT}, + {"height", "height of star moving field", NULL, (void*)&settings.height, (void*)&hmin, NULL, CC_PAR_INT}, + {"xc", "x center of field in array coordinates", NULL, (void*)&settings.x0, NULL, NULL, CC_PAR_INT}, + {"yc", "y center of field in array coordinates", NULL, (void*)&settings.y0, NULL, NULL, CC_PAR_INT}, + {"fwhm", "star FWHM, arcsec", NULL, (void*)&settings.fwhm, (void*)&fwhmmin, (void*)&fwhmmax, CC_PAR_DOUBLE}, + {"scale", "CCD scale: arcsec/pix", NULL, (void*)&settings.scale, (void*)&scalemin, (void*)&scalemax, CC_PAR_DOUBLE}, + {"mag", "star magnitude: 0m is 16384 ADUs per second per arcsec^2", NULL, (void*)&settings.mag, (void*)&magmin, (void*)&magmax, CC_PAR_DOUBLE}, + //{"", "", NULL, (void*)&, (void*)&, (void*)&settings., CC_PAR_DOUBLE}, + CC_PARHANDLER_END +}; + +static cc_hresult plugincmd(const char *str, cc_charbuff *buf){ + return cc_plugin_customcmd(str, handlers, buf); +} + +static int stub(){ + return TRUE; +} + +static void vstub(){ + FNAME(); + return; +} +static int istub(_U_ int N){return TRUE;} + +/* + * Global objects: camera, focuser and wheel + */ +__attribute__ ((visibility("default"))) cc_Camera camera = { + .check = stub, + .Ndevices = 1, + .close = vstub, + .pollcapture = campoll, + .capture = camcapt, + .cancel = camcancel, + .startexposition = startexp, + .plugincmd = plugincmd, + // setters: + .setDevNo = setdevno, + .setbrightness = camsetbrig, + .setexp = camsetexp, + .setgain = camsetgain, + .setT = camsett, + .setbin = camsetbin, + .setnflushes = istub, + .shuttercmd = camshutter, + .confio = istub, + .setio = istub, + .setframetype = istub, + .setbitdepth = camsetbit, + .setfastspeed = istub, + .setgeometry = camsetgeom, + .setfanspeed = camfan, + // getters: + .getbitpix = camgetbp, + .getbrightness = camgetbrig, + .getModelName = camgetnam, + .getgain = camgetgain, + .getmaxgain = camgmg, + .getgeomlimits = camggl, + .getTcold = camgett, + .getThot = camgett, + .getTbody = gett, + .getbin = camgetbin, + .getio = camgetio, + .pixX = 10., + .pixY = 10., + .field = (cc_frameformat){.h = 1024, .w = 1024, .xoff = 10, .yoff = 10}, + .array = (cc_frameformat){.h = 1050, .w = 1050, .xoff = 0, .yoff = 0}, + .geometry = {0}, +}; + +__attribute__ ((visibility("default"))) cc_Focuser focuser = { + .check = stub, + .Ndevices = 1, + .close = vstub, + // setters: + .setDevNo = setdevno, + .setAbsPos = focsetpos, + .home = fochome, + // getters: + .getModelName = focgetnam, + .getTbody = gett, + .getPos = focpos, + .getMaxPos = focMp, + .getMinPos = focmp, +}; + +__attribute__ ((visibility("default"))) cc_Wheel wheel = { + .check = stub, + .Ndevices = 1, + .close = vstub, + // setters + .setDevNo = setdevno, + .setPos = whlsetpos, + // getters + .getModelName = whlgetnam, + .getTbody = gett, + .getPos = whlgetpos, + .getMaxPos = whlgmp, +}; diff --git a/CMakeLists.txt b/CMakeLists.txt index 07513e4..2f300cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,8 @@ message("VER: ${VERSION}") # list of options option(DEBUG "Compile in debug mode" OFF) -option(IMAGEVIEW "Build with imageview module" OFF) +option(DUMMY "Dummy camera plugin" ON) +option(IMAGEVIEW "Build with imageview module" ON) option(ZWO "Add support of ZWO cameras" OFF) option(FLI "Add support of FLI cameras" OFF) option(BASLER "Add support of BASLER cameras" OFF) @@ -23,6 +24,7 @@ option(HIKROBOT "Add support of HIKROBOT cameras" OFF) option(FLYCAP "Add support of Grasshopper FlyCap cameras" OFF) option(APOGEE "Add support of Apogee cameras" OFF) option(EXAMPLES "Some examples" OFF) +option(ASTAR "Artifical star plugin" OFF) # default flags set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wextra -fno-builtin-strlen") @@ -75,6 +77,7 @@ if(OPENMP_FOUND) add_definitions(-DOMP_FOUND) endif() +# view image in OpenGL window if(IMAGEVIEW) list(APPEND SOURCES events.c imageview.c) find_package(OpenGL REQUIRED) @@ -84,9 +87,13 @@ if(IMAGEVIEW) list(APPEND ${PROJ}_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) add_definitions(-DIMAGEVIEW) endif() - -add_subdirectory(Dummy_cameras) - +# Dummy and artifical star plugins +if(DUMMY) + add_subdirectory(Dummy_cameras) +endif() +if(ASTAR) + add_subdirectory(Astar_cameras) +endif() # additional modules with CCD/CMOS support if(ZWO) add_subdirectory(ZWO_cameras) diff --git a/Dummy_cameras/dummyfunc.c b/Dummy_cameras/dummyfunc.c index fcb95b9..23fb0aa 100644 --- a/Dummy_cameras/dummyfunc.c +++ b/Dummy_cameras/dummyfunc.c @@ -43,6 +43,7 @@ static double texpstart = 0.; static uint8_t bitpix = 16; // bit depth: 8 or 16 // sinusoide periods static double sinPx = 100., sinPy = 200.; +static const double sinmin = 1.; static int campoll(cc_capture_status *st, float *remain){ if(capstat != CAPTURE_PROCESS){ @@ -256,35 +257,27 @@ static int whlgetnam(char *n, int l){ return TRUE; } -static const char* const helpmsg = - "Dummy camera custom plugin commands:\n" - "\tpx - set/get sin period over X axis (pix)\n" - "\tpy - -//- over Y axis\n" -; -static const char* const pmust = "Period must be not less than 1"; -static const char *plugincmd(const char *str){ - static char ans[BUFSIZ+1]; - snprintf(ans, BUFSIZ, "%s", str); - char *val = cc_get_keyval(ans); - if(val){ // setters - if(0 == strcmp("px", ans)){ - double f = atof(val); - if(f < 1.) return pmust; - sinPx = f; - }else if(0 == strcmp("py", ans)){ - double f = atof(val); - if(f < 1.) return pmust; - sinPy = f; - } - } // getters/return - if(0 == strcmp("px", ans)){ - snprintf(ans, BUFSIZ, "px=%g", sinPx); - return (const char*) ans; - }else if(0 == strcmp("py", ans)){ - snprintf(ans, BUFSIZ, "yx=%g", sinPy); - return (const char*) ans; - } - return helpmsg; +/* +static int checker(const char *str, cc_charbuff *ans){ + char *eq = strchr(str, '='); + if(eq){ + float x = (float)atof(eq+1); + if(x < 1.){if(ans) cc_charbufaddline(ans, "Value must be >= 1.");} + else return TRUE; + }else return TRUE; // getter + return FALSE; +}*/ + + +// cmd, help, handler, ptr, type +static cc_parhandler_t handlers[] = { + {"px", "set/get sin period over X axis (pix)", NULL, (void*)&sinPx, (void*)&sinmin, NULL, CC_PAR_DOUBLE}, + {"py", "set/get sin period over Y axis (pix)", NULL, (void*)&sinPy, (void*)&sinmin, NULL, CC_PAR_DOUBLE}, + CC_PARHANDLER_END +}; + +static cc_hresult plugincmd(const char *str, cc_charbuff *buf){ + return cc_plugin_customcmd(str, handlers, buf); } static int stub(){ diff --git a/ccdcapture.c b/ccdcapture.c index 90b9912..5dbf298 100644 --- a/ccdcapture.c +++ b/ccdcapture.c @@ -189,8 +189,6 @@ static const char *resmessages[RESULT_NUM] = { [RESULT_FAIL] = "FAIL", [RESULT_BADVAL] = "BADVAL", [RESULT_BADKEY] = "BADKEY", -// [RESULT_SILENCE] = NULL, // nothing to send -// [RESULT_DISCONNECTED] = NULL, // not to send }; const char *cc_hresult2str(cc_hresult r){ @@ -732,3 +730,123 @@ int cc_charbuf2kw(cc_charbuff *b, fitsfile *f){ } return TRUE; } + +static size_t print_val(cc_partype_t t, void *val, char *buf, size_t bufl){ + size_t l = 0; + switch(t){ + case CC_PAR_INT: + l = snprintf(buf, bufl, "%d", *(int*)val); + break; + case CC_PAR_FLOAT: + l = snprintf(buf, bufl, "%g", *(float*)val); + break; + case CC_PAR_DOUBLE: + l = snprintf(buf, bufl, "%g", *(double*)val); + break; + default: + l = snprintf(buf, bufl, "hoojnya"); + break; + } + return l; +} + +/** + * @brief cc_plugin_customcmd - common handler for custom plugin commands + * @param str - string like "par" (getter/cmd) or "par=val" (setter) + * @param handlers - NULL-terminated array of handlers for custom commands + * @param ans - buffer for output string + * @return RESULT_OK if all OK or error code + */ +cc_hresult cc_plugin_customcmd(const char *str, cc_parhandler_t *handlers, cc_charbuff *ans){ + if(!str || !handlers) return RESULT_FAIL; + char key[256]; + snprintf(key, 255, "%s", str); + char *val = cc_get_keyval(key); + cc_parhandler_t *phptr = handlers; + cc_hresult result = RESULT_BADKEY; + char buf[512]; +#define ADDL(...) do{if(ans){size_t l = snprintf(bptr, L, __VA_ARGS__); bptr += l; L -= l;}}while(0) +#define PRINTVAL(v) do{if(ans){size_t l = print_val(phptr->type, phptr->v, bptr, L); bptr += l; L -= l;}}while(0) + while(phptr->cmd){ + if(0 == strcmp(key, phptr->cmd)){ + char *bptr = buf; size_t L = 511; + result = RESULT_OK; + if(phptr->checker) result = phptr->checker(str, ans); + if(phptr->ptr){ // setter/getter + if(val){if(result == RESULT_OK){// setter: change value only if [handler] returns OK (`handler` could be value checker) + int ival; float fval; double dval; +#define UPDATE_VAL(type, val, pr) do{ \ + if(phptr->max && val > *(type*)phptr->max){ADDL("max=" pr, *(type*)phptr->max); result = RESULT_BADVAL;} \ + if(phptr->min && val < *(type*)phptr->min){ADDL("min=" pr, *(type*)phptr->min); result = RESULT_BADVAL;} \ + if(result == RESULT_OK) *(type*)phptr->ptr = val; \ +}while(0) + switch(phptr->type){ + case CC_PAR_INT: + ival = atoi(val); + UPDATE_VAL(int, ival, "%d"); + break; + case CC_PAR_FLOAT: + fval = (float)atof(val); + UPDATE_VAL(float, fval, "%g"); + break; + case CC_PAR_DOUBLE: + dval = atof(val); + UPDATE_VAL(double, dval, "%g"); + break; + default: + result = RESULT_FAIL; + } +#undef UPDATE_VAL + }}else result = RESULT_SILENCE; // getter - don't show "OK" + DBG("res=%d", result); + if(result == RESULT_SILENCE || result == RESULT_OK){ + ADDL("%s=", phptr->cmd); + PRINTVAL(ptr); + } + if(ans) cc_charbufaddline(ans, buf); + } + break; + } + ++phptr; + } + if(ans && result == RESULT_BADKEY){ // cmd not found - display full help + cc_charbufaddline(ans, "Custom plugin commands:\n"); + phptr = handlers; + while(phptr->cmd){ + char *bptr = buf; size_t L = 511; + ADDL("\t%s", phptr->cmd); + if(phptr->ptr){ + ADDL(" = ("); + switch(phptr->type){ + case CC_PAR_INT: + ADDL("int"); + break; + case CC_PAR_FLOAT: + ADDL("float"); + break; + case CC_PAR_DOUBLE: + ADDL("double"); + break; + default: + ADDL("undefined"); + } + ADDL(")"); + if(phptr->min || phptr->max){ + ADDL(" ["); + if(phptr->min) PRINTVAL(min); + else ADDL("-inf"); + ADDL(", "); + if(phptr->max) PRINTVAL(max); + else ADDL("inf"); + ADDL("]"); + } + } + ADDL(" - "); + ADDL("%s\n", phptr->helpstring); + cc_charbufaddline(ans, buf); + ++phptr; + } + } +#undef ADDL + return result; +} diff --git a/ccdcapture.h b/ccdcapture.h index cf8a0b9..3209da4 100644 --- a/ccdcapture.h +++ b/ccdcapture.h @@ -41,6 +41,26 @@ typedef struct __attribute__((packed, aligned(4))){ /* `data` is uint8_t or uint16_t depending on `bitpix` */ } cc_IMG; +typedef struct{ + char* buf; // databuffer + size_t bufsize; // size of `buf` + size_t buflen; // current buffer length + char *string; // last \n-ended string from `buf` + size_t strlen; // max length of `string` + pthread_mutex_t mutex; // mutex for atomic data access +} cc_strbuff; + +typedef struct{ + char* buf; // databuffer + size_t bufsize; // size of `buf` + size_t buflen; // current buffer length + pthread_mutex_t mutex; // mutex for atomic data access +} cc_charbuff; + +#define cc_buff_lock(b) pthread_mutex_lock(&((b)->mutex)) +#define cc_buff_trylock(b) pthread_mutex_trylock(&((b)->mutex)) +#define cc_buff_unlock(b) pthread_mutex_unlock(&((b)->mutex)) + // format of single frame typedef struct{ int w; int h; // width & height @@ -70,6 +90,17 @@ typedef enum{ FAN_HIGH, } cc_fan_speed; +typedef enum{ + RESULT_OK, // 0: all OK + RESULT_BUSY, // 1: camera busy and no setters can be done + RESULT_FAIL, // 2: failed running command + RESULT_BADVAL, // 3: bad key's value + RESULT_BADKEY, // 4: bad key + RESULT_SILENCE, // 5: send nothing to client + RESULT_DISCONNECTED,// 6: client disconnected + RESULT_NUM +} cc_hresult; + // all setters and getters of Camera, Focuser and cc_Wheel should return TRUE if success or FALSE if failed or unsupported // camera typedef struct{ @@ -110,10 +141,10 @@ typedef struct{ int (*getTbody)(float *t); // body T int (*getbin)(int *binh, int *binv); int (*getio)(int *s); // get IO-port state - const char* (*plugincmd)(const char *str); // custom camera plugin command (get string as input, send string as output or NULL if failed) + cc_hresult (*plugincmd)(const char *str, cc_charbuff *ans); // custom camera plugin command (get string as input, send string as output or NULL if failed) float pixX, pixY; // pixel size in um - cc_frameformat field; // max field of view - cc_frameformat array; // array format + cc_frameformat field; // max field of view (full CCD field without overscans) + cc_frameformat array; // array format (with overscans) cc_frameformat geometry; // current geometry settings (as in setgeometry) } cc_Camera; @@ -165,17 +196,6 @@ typedef struct{ // client will disconnect after this time from last server message #define CC_CLIENT_TIMEOUT (3.0) -typedef enum{ - RESULT_OK, // 0: all OK - RESULT_BUSY, // 1: camera busy and no setters can be done - RESULT_FAIL, // 2: failed running command - RESULT_BADVAL, // 3: bad key's value - RESULT_BADKEY, // 4: bad key - RESULT_SILENCE, // 5: send nothing to client - RESULT_DISCONNECTED,// 6: client disconnected - RESULT_NUM -} cc_hresult; - // fd - socket fd to send private messages, key, val - key and its value typedef cc_hresult (*cc_mesghandler)(int fd, const char *key, const char *val); @@ -254,25 +274,26 @@ typedef enum{ #define CC_CMD_WDEVNO "wdevno" #define CC_CMD_WPOS "wpos" -typedef struct{ - char* buf; // databuffer - size_t bufsize; // size of `buf` - size_t buflen; // current buffer length - char *string; // last \n-ended string from `buf` - size_t strlen; // max length of `string` - pthread_mutex_t mutex; // mutex for atomic data access -} cc_strbuff; +typedef enum{ // parameter type + CC_PAR_INT, + CC_PAR_FLOAT, + CC_PAR_DOUBLE, +} cc_partype_t; -typedef struct{ - char* buf; // databuffer - size_t bufsize; // size of `buf` - size_t buflen; // current buffer length - pthread_mutex_t mutex; // mutex for atomic data access -} cc_charbuff; +typedef struct{ // custom plugin parameters + const char *cmd; // text parameter/command + const char *helpstring; // help string for this parameter + cc_hresult (*checker)(const char *str, cc_charbuff *ans); // value checker or custom handler (if don't satisfy common getter/setter); return possible answer in `ans` + void *ptr; // pointer to variable (if exists) + void *min; // min/max values of `ptr` (or NULL if don't need to check) + void *max; + cc_partype_t type; // argument type +} cc_parhandler_t; -#define cc_buff_lock(b) pthread_mutex_lock(&b->mutex) -#define cc_buff_trylock(b) pthread_mutex_trylock(&b->mutex) -#define cc_buff_unlock(b) pthread_mutex_unlock(&b->mutex) +// this record should be last in cc_parhandler_t array for `cc_plugin_customcmd` +#define CC_PARHANDLER_END {0} + +cc_hresult cc_plugin_customcmd(const char *str, cc_parhandler_t *handlers, cc_charbuff *ans); cc_Focuser *open_focuser(const char *pluginname); cc_Camera *open_camera(const char *pluginname); diff --git a/ccdfunc.c b/ccdfunc.c index 28d69b9..1c31fd2 100644 --- a/ccdfunc.c +++ b/ccdfunc.c @@ -217,7 +217,6 @@ int saveFITS(cc_IMG *img, char **outp){ } }else{ // user pointed output file prefix if(!check_filenameprefix(fnam, PATH_MAX)){ - // Не могу сохранить файл WARNX(_("Can't save file with prefix %s"), GP->outfileprefix); LOGERR("Can't save image with prefix %s", GP->outfileprefix); } @@ -453,7 +452,7 @@ retn: cc_Wheel *startWheel(){ if(!GP->wheeldev && !GP->commondev){ - verbose(3, _("cc_Wheel device not pointed")); + verbose(3, _("Wheel device not pointed")); return NULL; }else{ char *plugin = GP->commondev ? GP->commondev : GP->wheeldev; @@ -518,7 +517,7 @@ void wheels(){ pos = GP->setwheel; if(pos == -1) goto retn; // no wheel commands if(pos < 0 || pos > maxpos){ - WARNX(_("cc_Wheel position should be from 0 to %d"), maxpos); + WARNX(_("Wheel position should be from 0 to %d"), maxpos); goto retn; } if(!wheel->setPos(pos)) @@ -605,11 +604,19 @@ int prepare_ccds(){ if(!camera->plugincmd) WARNX(_("Camera plugin have no custom commands")); else{ char **p = GP->plugincmd; + cc_charbuff *b = cc_charbufnew(); DBG("got %s", *p); while(p && *p){ - printf("Command: %s\nAnswer: %s\n", *p, camera->plugincmd(*p)); + cc_charbufclr(b); + cc_hresult r = camera->plugincmd(*p, b); + if(r == RESULT_OK || r == RESULT_SILENCE) green("Command '%s'", *p); + else red("Command '%s'", *p); + if(r != RESULT_SILENCE) printf(" returns \"%s\"", cc_hresult2str(r)); + if(b->buflen) printf("\n%s", b->buf); + else printf("\n"); ++p; } + cc_charbufdel(&b); } } if(GP->fanspeed > -1){ @@ -650,7 +657,6 @@ int prepare_ccds(){ WARNX(_("Can't run shutter command %s (unsupported?)"), str[GP->shtr_cmd]); } if(GP->confio > -1){ - // "Попытка сконфигурировать порт I/O как %d\n" verbose(1, _("Try to configure I/O port as %d"), GP->confio); if(!camera->confio(GP->confio)) WARNX(_("Can't configure (unsupported?)")); @@ -663,7 +669,6 @@ int prepare_ccds(){ WARNX(_("Can't get IOport state (unsupported?)")); } if(GP->setio > -1){ - // "Попытка записи %d в порт I/O\n" verbose(1, _("Try to write %d to I/O port"), GP->setio); if(!camera->setio(GP->setio)) WARNX(_("Can't set IOport")); @@ -717,7 +722,8 @@ int prepare_ccds(){ WARNX(_("Can't set readout speed")); else verbose(1, _("Readout mode: %s"), GP->fast ? "fast" : "normal"); if(!GP->outfile) verbose(1, _("Only show statistics")); - if(!camera->getbin(&GP->hbin, &GP->vbin)) // GET binning should be AFTER setgeometry! + // GET binning should be AFTER setgeometry! + if(!camera->getbin(&GP->hbin, &GP->vbin)) WARNX(_("Can't get current binning")); verbose(2, "Binning: %d x %d", GP->hbin, GP->vbin); rtn = TRUE; @@ -742,7 +748,6 @@ DBG("w=%d, h=%d", raw_width, raw_height); for(int j = 0; j < GP->nframes; ++j){ TIMESTAMP("Start next cycle"); TIMEINIT(); - // Захват кадра %d\n verbose(1, _("Capture frame %d"), j); if(!camera->startexposition()){ WARNX(_("Can't start exposition")); @@ -769,7 +774,6 @@ DBG("w=%d, h=%d", raw_width, raw_height); if(GP->pause_len && j != (GP->nframes - 1)){ double delta, time1 = dtime() + GP->pause_len; while((delta = time1 - dtime()) > 0.){ - // %d секунд до окончания паузы\n verbose(1, _("%d seconds till pause ends\n"), (int)delta); float tmpf; if(camera->getTcold(&tmpf)) verbose(1, "CCDTEMP=%.1f\n", tmpf); diff --git a/client.c b/client.c index a25bdf6..0c6054a 100644 --- a/client.c +++ b/client.c @@ -267,7 +267,6 @@ void client(int sock){ while(1){ SENDCMDW(CC_CMD_CAMTEMPER); if((delta = time1 - dtime()) < __FLT_EPSILON__) break; - // %d секунд до окончания паузы\n if(delta > 1.) verbose(1, _("%d seconds till pause ends\n"), (int)delta); if(delta > 6.) sleep(5); else if(delta > 1.) sleep((int)delta); diff --git a/cmdlnopts.c b/cmdlnopts.c index 2dcf6fb..d0608c5 100644 --- a/cmdlnopts.c +++ b/cmdlnopts.c @@ -111,7 +111,7 @@ myoption cmdlnopts[] = { {"restart", NO_ARGS, &G.restart,1, arg_none, NULL, N_("restart image server")}, {"shmkey", NEED_ARG, NULL, 'k', arg_int, APTR(&G.shmkey), N_("shared memory (with image data) key (default: 7777777)")}, - {"forceimsock",NO_ARGS, &G.forceimsock,1, arg_none, NULL, N_("force using image through socket transition even if can use SHM)")}, + {"forceimsock",NO_ARGS, &G.forceimsock,1, arg_none, NULL, N_("force using image through socket transition even if can use SHM")}, {"infty", NEED_ARG, NULL, NA, arg_int, APTR(&G.infty), N_("start (!=0) or stop(==0) infinity capturing loop")}, #ifdef IMAGEVIEW diff --git a/locale/ru/LC_MESSAGES/ccd_capture.mo b/locale/ru/LC_MESSAGES/ccd_capture.mo index 04e3f03745a3979c1338d21d30272d6f4a605b5a..dde71bee57458659298e17cccb5293e9da898328 100644 GIT binary patch delta 4749 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 delta 2749 zcmYk;drXye9LMqB;dlwTUj^iHKuzw6NJ!jHkR}2t;w4QiMMTgfZ@|)d7)oooZ1q@+ zhTUr}?VlbeHJeIoZQ{)Cu8o=6SR0FGE3?*Wy+7wXw0`S*UccwzJip8L_kE5%{p77S z-?iu|FB)1mkxY!bjd=?Prt?9|oMB8lX5lQX#aL{`I6Qz6_yQ*4o6h}@F_P;qF$RCY znRo|NF(Sm6xyJZRJ{>){3NvsgYQpDH3$jrIeU8z11EcUa)B>i38dHYJn1kz36ZD}L z`ZntMk1!rboWI||H0C!Z%$OALpjKFcTJai8!gge(rq8*55;gF7Ou(;E3z@(?bcYAV zDL`ec1~qXDY9R+u3w#z+H2*0&+R=#PC~BuaqZZ&Izgj>t-i=i_2iuUZn4_qL97i@~ z&Y-?GjGA!V@h{Xoq1>cvQqiZKTM;%p_B&p|OzuyOCjUCKd}h@S*Q08o2g#;+1+~)?*o2pnXH5>PD8O>e z#SYYt2T&OsMy2=~YNvmrjv$O(XuLV7=W1ffzs|gq8(P3oEXC8P9o@ovFp>kN-i#MD zKpnD4vkNtFFY@A;ehk9nsH1ot^}Y8|nLLLKX)dE`?xv59cB)advv5>KJXnEs&h-(@ z=6VoGg1Lzr@HT3}Q`m*x7B4CTO{k1?<4hMvh8k~>LMg=GQAgm*Cf|DP8c{{mi8c5f zF2?UrRh`DD#aNH?u@5)m8EnBg4qj)z9~YDjY65nFeW;H5Bdr)U|64&APs0EgApgdzbP!kj)?>p`0jJ#ZaMF^Y=Qbv@pX2T=>XfQ#@t>dX@v#f#ff z_fMgYZVV4&8Ru1tL%15l7*yjlqiX8VeDbdpeaH2=;lR1=hjzb$i|g#8DacD;wtYIRm_LPxQRSV?pfYE1;$ z_qSL+JBj54iSrk&HWNl@6FNFIZDfYON9r9N0`n_1n~4a5V*js&(u*O|ojY?-=c(6e z2eFS(izlM}J^udzbu?|x^$H~0rh|CGxko+we@n9T{__@?E<*37nqIldrn7G)_|5S* z{lq@v^hF3kG5e25*Ncf@B25=Goprsx7x>LkH_o|k#Od1qcEU@ja_a~+6`5Y82MLPV z|5FNPw?1eYM7zHic=sQpA4yChiii!w|C`>9r9=x+Ml=v=B{h7g(xZq+iE!d^!b1cR zlWi*swzfT0Ne9ZoH(U8k3EX}sREnVRH7lR%aHvj+t diff --git a/locale/ru/messages.po b/locale/ru/messages.po index 72ee692..a8b0e7c 100644 --- a/locale/ru/messages.po +++ b/locale/ru/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-02-01 14:36+0300\n" +"POT-Creation-Date: 2024-02-07 17:00+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -254,7 +254,7 @@ msgid "shared memory (with image data) key (default: 7777777)" msgstr "" #: cmdlnopts.c:114 -msgid "force using image through socket transition even if can use SHM)" +msgid "force using image through socket transition even if can use SHM" msgstr "" #: cmdlnopts.c:115 @@ -269,289 +269,283 @@ msgstr "" msgid "Camera device unknown" msgstr "" -#. п²п╣ п╪п╬пЁя┐ я│п╬я┘я─п╟п╫п╦я┌я▄ я└п╟п╧п╩ -#: ccdfunc.c:221 +#: ccdfunc.c:220 #, c-format msgid "Can't save file with prefix %s" msgstr "" -#: ccdfunc.c:269 +#: ccdfunc.c:268 #, c-format msgid "File saved as '%s'" msgstr "" -#: ccdfunc.c:278 +#: ccdfunc.c:277 msgid "Error saving file" msgstr "" -#: ccdfunc.c:356 +#: ccdfunc.c:355 #, c-format msgid "Image stat:\n" msgstr "" -#: ccdfunc.c:365 +#: ccdfunc.c:364 msgid "Focuser device not pointed" msgstr "" -#: ccdfunc.c:372 +#: ccdfunc.c:371 msgid "No focusers found" msgstr "" -#: ccdfunc.c:403 +#: ccdfunc.c:402 #, c-format msgid "Found %d focusers, you point number %d" msgstr "" -#: ccdfunc.c:407 +#: ccdfunc.c:406 msgid "Can't set active focuser number" msgstr "" -#: ccdfunc.c:421 +#: ccdfunc.c:420 msgid "Can't get focuser limit positions" msgstr "" -#: ccdfunc.c:428 +#: ccdfunc.c:427 msgid "Can't get current focuser position" msgstr "" -#: ccdfunc.c:442 +#: ccdfunc.c:441 #, c-format msgid "Can't set position %g: out of limits [%g, %g]" msgstr "" -#: ccdfunc.c:446 +#: ccdfunc.c:445 msgid "Can't home focuser" msgstr "" -#: ccdfunc.c:448 +#: ccdfunc.c:447 #, c-format msgid "Can't set position %g" msgstr "" -#: ccdfunc.c:456 -msgid "cc_Wheel device not pointed" +#: ccdfunc.c:455 +msgid "Wheel device not pointed" msgstr "" -#: ccdfunc.c:463 +#: ccdfunc.c:462 msgid "No wheels found" msgstr "" -#: ccdfunc.c:494 +#: ccdfunc.c:493 #, c-format msgid "Found %d wheels, you point number %d" msgstr "" -#: ccdfunc.c:498 +#: ccdfunc.c:497 msgid "Can't set active wheel number" msgstr "" -#: ccdfunc.c:514 +#: ccdfunc.c:513 msgid "Can't get max wheel position" msgstr "" -#: ccdfunc.c:521 +#: ccdfunc.c:520 #, c-format -msgid "cc_Wheel position should be from 0 to %d" +msgid "Wheel position should be from 0 to %d" msgstr "" -#: ccdfunc.c:525 +#: ccdfunc.c:524 #, c-format msgid "Can't set wheel position %d" msgstr "" -#: ccdfunc.c:542 +#: ccdfunc.c:541 #, c-format msgid "%.1f seconds till exposition ends" msgstr "" -#: ccdfunc.c:557 +#: ccdfunc.c:556 msgid "Camera device not pointed" msgstr "" -#: ccdfunc.c:564 ccdfunc.c:565 +#: ccdfunc.c:563 ccdfunc.c:564 msgid "No cameras found" msgstr "" -#: ccdfunc.c:595 +#: ccdfunc.c:594 #, c-format msgid "Found %d cameras, you point number %d" msgstr "" -#: ccdfunc.c:599 +#: ccdfunc.c:598 msgid "Can't set active camera number" msgstr "" -#: ccdfunc.c:605 +#: ccdfunc.c:604 msgid "Camera plugin have no custom commands" msgstr "" -#: ccdfunc.c:618 +#: ccdfunc.c:625 msgid "Can't set fan speed" msgstr "" -#: ccdfunc.c:619 +#: ccdfunc.c:626 #, c-format msgid "Set fan speed to %d" msgstr "" -#: ccdfunc.c:624 +#: ccdfunc.c:631 #, c-format msgid "Camera model: %s" msgstr "" -#: ccdfunc.c:625 +#: ccdfunc.c:632 #, c-format msgid "Pixel size: %g x %g" msgstr "" -#: ccdfunc.c:631 +#: ccdfunc.c:638 #, c-format msgid "Full array: %s" msgstr "" -#: ccdfunc.c:634 +#: ccdfunc.c:641 #, c-format msgid "Field of view: %s" msgstr "" -#: ccdfunc.c:637 +#: ccdfunc.c:644 #, c-format msgid "Current format: %s" msgstr "" -#: ccdfunc.c:640 +#: ccdfunc.c:647 #, c-format msgid "Can't set T to %g degC" msgstr "" -#: ccdfunc.c:648 +#: ccdfunc.c:655 #, c-format msgid "Shutter command: %s\n" msgstr "" -#: ccdfunc.c:650 +#: ccdfunc.c:657 #, c-format msgid "Can't run shutter command %s (unsupported?)" msgstr "" -#. "п÷п╬п©я▀я┌п╨п╟ я│п╨п╬п╫я└п╦пЁя┐я─п╦я─п╬п╡п╟я┌я▄ п©п╬я─я┌ I/O п╨п╟п╨ %d\n" -#: ccdfunc.c:654 +#: ccdfunc.c:660 #, c-format msgid "Try to configure I/O port as %d" msgstr "" -#: ccdfunc.c:656 +#: ccdfunc.c:662 msgid "Can't configure (unsupported?)" msgstr "" -#: ccdfunc.c:663 +#: ccdfunc.c:669 msgid "Can't get IOport state (unsupported?)" msgstr "" -#. "п÷п╬п©я▀я┌п╨п╟ п╥п╟п©п╦я│п╦ %d п╡ п©п╬я─я┌ I/O\n" -#: ccdfunc.c:667 +#: ccdfunc.c:672 #, c-format msgid "Try to write %d to I/O port" msgstr "" -#: ccdfunc.c:669 +#: ccdfunc.c:674 msgid "Can't set IOport" msgstr "" -#: ccdfunc.c:676 +#: ccdfunc.c:681 #, c-format msgid "Set gain to %g" msgstr "" -#: ccdfunc.c:677 +#: ccdfunc.c:682 #, c-format msgid "Can't set gain to %g" msgstr "" -#: ccdfunc.c:682 +#: ccdfunc.c:687 #, c-format msgid "Set brightness to %g" msgstr "" -#: ccdfunc.c:683 +#: ccdfunc.c:688 #, c-format msgid "Can't set brightness to %g" msgstr "" -#: ccdfunc.c:689 server.c:265 +#: ccdfunc.c:694 server.c:265 #, c-format msgid "Can't set binning %dx%d" msgstr "" -#: ccdfunc.c:701 server.c:266 +#: ccdfunc.c:706 server.c:266 msgid "Can't set given geometry" msgstr "" -#: ccdfunc.c:705 +#: ccdfunc.c:710 #, c-format msgid "Can't set %d flushes" msgstr "" -#: ccdfunc.c:709 +#: ccdfunc.c:714 #, c-format msgid "Can't set exposure time to %f seconds" msgstr "" -#: ccdfunc.c:712 +#: ccdfunc.c:717 msgid "Can't change frame type" msgstr "" -#: ccdfunc.c:715 +#: ccdfunc.c:720 msgid "Can't set bit depth" msgstr "" -#: ccdfunc.c:717 +#: ccdfunc.c:722 msgid "Can't set readout speed" msgstr "" -#: ccdfunc.c:718 +#: ccdfunc.c:723 #, c-format msgid "Readout mode: %s" msgstr "" -#: ccdfunc.c:719 +#: ccdfunc.c:724 msgid "Only show statistics" msgstr "" -#. GET binning should be AFTER setgeometry! -#: ccdfunc.c:721 +#: ccdfunc.c:727 msgid "Can't get current binning" msgstr "" -#. п≈п╟я┘п╡п╟я┌ п╨п╟п╢я─п╟ %d\n -#: ccdfunc.c:746 +#: ccdfunc.c:751 #, c-format msgid "Capture frame %d" msgstr "" -#: ccdfunc.c:748 ccdfunc.c:823 server.c:150 +#: ccdfunc.c:753 ccdfunc.c:827 server.c:150 msgid "Can't start exposition" msgstr "" -#: ccdfunc.c:753 +#: ccdfunc.c:758 msgid "Can't capture image" msgstr "" -#: ccdfunc.c:756 +#: ccdfunc.c:761 msgid "Read grabbed image" msgstr "" -#: ccdfunc.c:760 ccdfunc.c:836 +#: ccdfunc.c:765 ccdfunc.c:840 msgid "Can't grab image" msgstr "" -#. %d я│п╣п╨я┐п╫п╢ п╢п╬ п╬п╨п╬п╫я┤п╟п╫п╦я▐ п©п╟я┐п╥я▀\n -#: ccdfunc.c:773 client.c:271 +#: ccdfunc.c:777 client.c:270 #, c-format msgid "%d seconds till pause ends\n" msgstr "" -#: ccdfunc.c:834 +#: ccdfunc.c:838 msgid "Some error when capture" msgstr "" @@ -563,7 +557,7 @@ msgstr "" msgid "Can't make exposition" msgstr "" -#: client.c:287 +#: client.c:286 msgid "Server timeout" msgstr "" diff --git a/locale/ru/ru.po b/locale/ru/ru.po index 2911dad..c7e138f 100644 --- a/locale/ru/ru.po +++ b/locale/ru/ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2024-02-01 14:35+0300\n" + "POT-Creation-Date: 2024-02-07 17:00+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,13 +16,12 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n" "Content-Type: text/plain; charset=koi8-r\n" "Content-Transfer-Encoding: 8bit\n" -#: ccdfunc.c:542 +#: ccdfunc.c:541 #, c-format msgid "%.1f seconds till exposition ends" msgstr "%.1f секунд до окончания экспозиции" -#. %d я│п╣п╨я┐п╫п╢ п╢п╬ п╬п╨п╬п╫я┤п╟п╫п╦я▐ п©п╟я┐п╥я▀\n -#: ccdfunc.c:773 client.c:271 +#: ccdfunc.c:777 client.c:270 #, c-format msgid "%d seconds till pause ends\n" msgstr "%d секунд до окончания паузы\n" @@ -39,7 +38,7 @@ msgstr " msgid "CMOS gain level" msgstr "уровень Gain CMOS" -#: ccdfunc.c:557 +#: ccdfunc.c:556 msgid "Camera device not pointed" msgstr "Устройство свеоприемника не подключено" @@ -47,53 +46,52 @@ msgstr " msgid "Camera device unknown" msgstr "Устройство свеоприемника не опознано" -#: ccdfunc.c:624 +#: ccdfunc.c:631 #, c-format msgid "Camera model: %s" msgstr "Модель светоприемника: %s" -#: ccdfunc.c:605 +#: ccdfunc.c:604 msgid "Camera plugin have no custom commands" -msgstr "" +msgstr "У плагина камеры нет особых команд" -#: ccdfunc.c:753 +#: ccdfunc.c:758 msgid "Can't capture image" msgstr "Не могу захватить изображение" -#: ccdfunc.c:712 +#: ccdfunc.c:717 msgid "Can't change frame type" msgstr "Не могу изменить тип кадра" -#: ccdfunc.c:656 +#: ccdfunc.c:662 msgid "Can't configure (unsupported?)" msgstr "Не могу сконфигурировать (опция не поддерживается?)" -#: ccdfunc.c:663 +#: ccdfunc.c:669 msgid "Can't get IOport state (unsupported?)" msgstr "Не могу получить состояние порта I/O (не поддерживается?)" -#. GET binning should be AFTER setgeometry! -#: ccdfunc.c:721 +#: ccdfunc.c:727 msgid "Can't get current binning" msgstr "Не могу получить текущее значение биннинга" -#: ccdfunc.c:428 +#: ccdfunc.c:427 msgid "Can't get current focuser position" msgstr "Не могу определить текущую позицию фокусера" -#: ccdfunc.c:421 +#: ccdfunc.c:420 msgid "Can't get focuser limit positions" msgstr "Не могу определить предельную позицию фокусера" -#: ccdfunc.c:514 +#: ccdfunc.c:513 msgid "Can't get max wheel position" msgstr "Не могу определить предельную позицию колеса" -#: ccdfunc.c:760 ccdfunc.c:836 +#: ccdfunc.c:765 ccdfunc.c:840 msgid "Can't grab image" msgstr "Не могу захватить изображение" -#: ccdfunc.c:446 +#: ccdfunc.c:445 msgid "Can't home focuser" msgstr "Не могу установить фокусер в нуль" @@ -109,152 +107,150 @@ msgstr " msgid "Can't open OpenGL window, image preview will be inaccessible" msgstr "Не могу открыть окно OpenGL, отображение будет недоступно" -#: ccdfunc.c:650 +#: ccdfunc.c:657 #, c-format msgid "Can't run shutter command %s (unsupported?)" msgstr "Не могу выполнить команду затвора %s (не поддерживается?)" -#. п²п╣ п╪п╬пЁя┐ я│п╬я┘я─п╟п╫п╦я┌я▄ я└п╟п╧п╩ -#: ccdfunc.c:221 +#: ccdfunc.c:220 #, c-format msgid "Can't save file with prefix %s" msgstr "Не могу сохранить файл с префиксом %s" -#: ccdfunc.c:705 +#: ccdfunc.c:710 #, c-format msgid "Can't set %d flushes" msgstr "Не могу установить %d сбросов" -#: ccdfunc.c:669 +#: ccdfunc.c:674 msgid "Can't set IOport" msgstr "Не могу поменять значения порта I/O" -#: ccdfunc.c:640 +#: ccdfunc.c:647 #, c-format msgid "Can't set T to %g degC" msgstr "Не могу установить температуру в %g градЦ" -#: ccdfunc.c:599 +#: ccdfunc.c:598 msgid "Can't set active camera number" msgstr "Не могу установить номер активной камеры" -#: ccdfunc.c:407 +#: ccdfunc.c:406 msgid "Can't set active focuser number" msgstr "Не могу установить номер активного фокусера" -#: ccdfunc.c:498 +#: ccdfunc.c:497 msgid "Can't set active wheel number" msgstr "Не могу установить номер активного колеса" -#: ccdfunc.c:689 server.c:265 +#: ccdfunc.c:694 server.c:265 #, c-format msgid "Can't set binning %dx%d" msgstr "Не могу установить биннинг %dx%d" -#: ccdfunc.c:715 +#: ccdfunc.c:720 msgid "Can't set bit depth" msgstr "Не могу установить разрядность АЦП" -#: ccdfunc.c:683 +#: ccdfunc.c:688 #, c-format msgid "Can't set brightness to %g" msgstr "Не могу установить яркость в %g" -#: ccdfunc.c:709 +#: ccdfunc.c:714 #, c-format msgid "Can't set exposure time to %f seconds" msgstr "Не могу установить экспозицию в %f секунд" -#: ccdfunc.c:618 +#: ccdfunc.c:625 msgid "Can't set fan speed" msgstr "Не могу установить скорость вентиляторов" -#: ccdfunc.c:677 +#: ccdfunc.c:682 #, c-format msgid "Can't set gain to %g" msgstr "Не могу установить Gain в %g" -#: ccdfunc.c:701 server.c:266 +#: ccdfunc.c:706 server.c:266 msgid "Can't set given geometry" msgstr "Не могу установить геометрию" -#: ccdfunc.c:448 +#: ccdfunc.c:447 #, c-format msgid "Can't set position %g" msgstr "Не могу изменить позицию на %g" -#: ccdfunc.c:442 +#: ccdfunc.c:441 #, c-format msgid "Can't set position %g: out of limits [%g, %g]" msgstr "Не могу установить позицию %g: вне пределов [%g, %g]" -#: ccdfunc.c:717 +#: ccdfunc.c:722 msgid "Can't set readout speed" msgstr "Не могу установить скорость считывания" -#: ccdfunc.c:525 +#: ccdfunc.c:524 #, c-format msgid "Can't set wheel position %d" msgstr "Не могу установить положение колеса %d" -#: ccdfunc.c:748 ccdfunc.c:823 server.c:150 +#: ccdfunc.c:753 ccdfunc.c:827 server.c:150 msgid "Can't start exposition" msgstr "Не могу начать экспозицию" -#. п≈п╟я┘п╡п╟я┌ п╨п╟п╢я─п╟ %d\n -#: ccdfunc.c:746 +#: ccdfunc.c:751 #, c-format msgid "Capture frame %d" msgstr "Захват кадра %d" -#: ccdfunc.c:637 +#: ccdfunc.c:644 #, c-format msgid "Current format: %s" -msgstr "" +msgstr "Текущий формат: %s" #: cmdlnopts.c:118 msgid "Display image in OpenGL window" -msgstr "Отображение изображения в окне OpenGL" +msgstr "отображение изображения в окне OpenGL" #: imageview.c:746 #, c-format msgid "Equalization of histogram: %s" msgstr "Эквализация гистограммы: %s" -#: ccdfunc.c:278 +#: ccdfunc.c:277 msgid "Error saving file" msgstr "Ошибка сохранения файла" -#: ccdfunc.c:634 +#: ccdfunc.c:641 #, c-format msgid "Field of view: %s" msgstr "Поле зрения: %s" -#: ccdfunc.c:269 +#: ccdfunc.c:268 #, c-format msgid "File saved as '%s'" msgstr "Файл сохранен как '%s'" -#: ccdfunc.c:365 +#: ccdfunc.c:364 msgid "Focuser device not pointed" msgstr "Устройство фокусера не указано" -#: ccdfunc.c:595 +#: ccdfunc.c:594 #, c-format msgid "Found %d cameras, you point number %d" msgstr "Обнаружено %d камер, вы указали %d" -#: ccdfunc.c:403 +#: ccdfunc.c:402 #, c-format msgid "Found %d focusers, you point number %d" msgstr "Обнаружено %d фокусеров, вы указали %d" -#: ccdfunc.c:494 +#: ccdfunc.c:493 #, c-format msgid "Found %d wheels, you point number %d" msgstr "Обнаружено %d колес, вы указали %d" -#: ccdfunc.c:631 +#: ccdfunc.c:638 #, c-format msgid "Full array: %s" msgstr "Полный формат: %s" @@ -265,11 +261,10 @@ msgid "Histogram conversion: %s" msgstr "Преобразование гистограммы: %s" #: cmdlnopts.c:108 -#, fuzzy msgid "INET image socket port" -msgstr "порт локального сетевого сокета" +msgstr "порт локального сетевого сокета передачи изображения" -#: ccdfunc.c:356 +#: ccdfunc.c:355 #, c-format msgid "Image stat:\n" msgstr "Статистика по изображению: \n" @@ -282,80 +277,86 @@ msgstr "N msgid "No camera device" msgstr "Не указано устройство камеры" -#: ccdfunc.c:564 ccdfunc.c:565 +#: ccdfunc.c:563 ccdfunc.c:564 msgid "No cameras found" msgstr "Камер не обнаружено" -#: ccdfunc.c:372 +#: ccdfunc.c:371 msgid "No focusers found" msgstr "Фокусеров не обнаружено" -#: ccdfunc.c:463 +#: ccdfunc.c:462 msgid "No wheels found" msgstr "Турелей не обнаружено" -#: ccdfunc.c:719 +#: ccdfunc.c:724 msgid "Only show statistics" msgstr "Только отобразить статистику" -#: ccdfunc.c:625 +#: ccdfunc.c:632 #, c-format msgid "Pixel size: %g x %g" msgstr "Размер пикселя: %g x %g" -#: ccdfunc.c:756 +#: ccdfunc.c:761 msgid "Read grabbed image" msgstr "Считывание изображения" -#: ccdfunc.c:718 +#: ccdfunc.c:723 #, c-format msgid "Readout mode: %s" msgstr "Режим считывания: %s" -#: client.c:287 +#: client.c:286 msgid "Server timeout" msgstr "Таймаут сервера" -#: ccdfunc.c:682 +#: ccdfunc.c:687 #, c-format msgid "Set brightness to %g" msgstr "Установить яркость в %g" -#: ccdfunc.c:619 +#: ccdfunc.c:626 #, c-format msgid "Set fan speed to %d" msgstr "Не могу установить скорость вентиляторов в %d" -#: ccdfunc.c:676 +#: ccdfunc.c:681 #, c-format msgid "Set gain to %g" msgstr "Установить Gain в %g" -#: ccdfunc.c:648 +#: ccdfunc.c:655 #, c-format msgid "Shutter command: %s\n" msgstr "Команда затвора: %s\n" -#: ccdfunc.c:834 +#: ccdfunc.c:838 msgid "Some error when capture" -msgstr "" +msgstr "Ошибка при захвате" -#. "п÷п╬п©я▀я┌п╨п╟ я│п╨п╬п╫я└п╦пЁя┐я─п╦я─п╬п╡п╟я┌я▄ п©п╬я─я┌ I/O п╨п╟п╨ %d\n" -#: ccdfunc.c:654 +#: ccdfunc.c:660 #, c-format msgid "Try to configure I/O port as %d" msgstr "Попытка сконфигурировать порт I/O как %d" -#. "п÷п╬п©я▀я┌п╨п╟ п╥п╟п©п╦я│п╦ %d п╡ п©п╬я─я┌ I/O\n" -#: ccdfunc.c:667 +#: ccdfunc.c:672 #, c-format msgid "Try to write %d to I/O port" msgstr "Попытка записи %d в порт I/O" #: cmdlnopts.c:106 -#, fuzzy msgid "UNIX socket name (command socket)" -msgstr "Имя UNIX-сокета" +msgstr "имя UNIX-сокета" + +#: ccdfunc.c:455 +msgid "Wheel device not pointed" +msgstr "Устройство турели не указано" + +#: ccdfunc.c:520 +#, c-format +msgid "Wheel position should be from 0 to %d" +msgstr "Позиция колеса должна быть от 0 до %d" #: cmdlnopts.c:82 msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all " @@ -391,16 +392,6 @@ msgstr " msgid "cancel current exposition" msgstr "отмена текущей экспозиции" -#: ccdfunc.c:456 -#, fuzzy -msgid "cc_Wheel device not pointed" -msgstr "Устройство турели не указано" - -#: ccdfunc.c:521 -#, fuzzy, c-format -msgid "cc_Wheel position should be from 0 to %d" -msgstr "Позиция колеса должна быть от 0 до %d" - #: cmdlnopts.c:88 msgid "close shutter" msgstr "закрыть затвор" @@ -416,9 +407,8 @@ msgstr " "pin1 - младший бит, 1 - выход, 0 - вход)" #: cmdlnopts.c:48 -#, fuzzy msgid "custom camera device plugin command" -msgstr "плагин камеры (например, devfli.so)" +msgstr "особые команды плагина камеры" #: cmdlnopts.c:61 msgid "fast readout mode" @@ -437,8 +427,9 @@ msgid "focuser device plugin (e.g. devzwo.so)" msgstr "плагин фокусера (например, devzwo.so)" #: cmdlnopts.c:114 -msgid "force using image through socket transition even if can use SHM)" -msgstr "" +msgid "force using image through socket transition even if can use SHM" +msgstr "принудительно брать изображения из сокета даже если возможно " + "пользоваться разделяемой памятью" #: cmdlnopts.c:91 msgid "get value of I/O port pins" @@ -457,7 +448,6 @@ msgid "list connected devices" msgstr "список подключенных устройств" #: cmdlnopts.c:107 -#, fuzzy msgid "local INET command socket port" msgstr "порт локального сетевого сокета" @@ -524,7 +514,7 @@ msgstr " #: cmdlnopts.c:110 msgid "passive viewer (only get last images)" -msgstr "" +msgstr "пассивный просмотр (только последние кадры)" #: cmdlnopts.c:65 msgid "program author" @@ -544,11 +534,11 @@ msgstr " #: cmdlnopts.c:90 msgid "run exposition on HIGH @ pin5 I/O port" -msgstr "" +msgstr "запуск экспозиции по ВЫСОКОМУ сигналу на контакте 5 порта I/O" #: cmdlnopts.c:89 msgid "run exposition on LOW @ pin5 I/O port" -msgstr "" +msgstr "запуск экспозиции по НИЗКОМУ сигналу на контакте 5 порта I/O" #: cmdlnopts.c:60 msgid "run in 8-bit mode" @@ -576,7 +566,7 @@ msgstr " #: cmdlnopts.c:113 msgid "shared memory (with image data) key (default: 7777777)" -msgstr "" +msgstr "ключ разделяемой памяти с данными изображения (по умолчанию: 7777777)" #: cmdlnopts.c:56 msgid "show this help" @@ -584,7 +574,7 @@ msgstr " #: cmdlnopts.c:115 msgid "start (!=0) or stop(==0) infinity capturing loop" -msgstr "" +msgstr "начать (!=0) или закончить (==0) бесконечный цикл захвата изображений" #: cmdlnopts.c:58 msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" @@ -601,29 +591,3 @@ msgstr " #: cmdlnopts.c:51 msgid "wheel device plugin (e.g. devdummy.so)" msgstr "плагин устройства турели (например, devdummy.so)" - -#, c-format -#~ msgid "Can't find camera in plugin %s: %s" -#~ msgstr "Не могу найти плагин камеры %s: %s" - -#, c-format -#~ msgid "Can't find focuser in plugin %s: %s" -#~ msgstr "Не могу найти плагин фокусера %s: %s" - -#, c-format -#~ msgid "Can't find plugin %s: %s" -#~ msgstr "Не могу найти плагин %s: %s" - -#, c-format -#~ msgid "Can't find wheel in plugin %s: %s" -#~ msgstr "Не могу найти плагин турели %s: %s" - -#~ msgid "Neither filename nor filename prefix pointed!" -#~ msgstr "Ни имя файла, ни префикс не указаны!" - -#~ msgid "PID file (default: " -#~ msgstr "PID-файл (по умолчанию: " - -#, fuzzy -#~ msgid "local INET socket port to send/receive images" -#~ msgstr "порт локального сетевого сокета" diff --git a/server.c b/server.c index 51f426d..d7c472f 100644 --- a/server.c +++ b/server.c @@ -958,11 +958,14 @@ static cc_hresult inftyhandler(int fd, _U_ const char *key, const char *val){ // custom camera plugin command static cc_hresult pluginhandler(int fd, _U_ const char *key, const char *val){ if(!camera->plugincmd) return RESULT_BADKEY; - const char *r = camera->plugincmd(val); - if(!r) return RESULT_FAIL; - if(*r == 0) return RESULT_OK; - if(!cc_sendstrmessage(fd, r)) return RESULT_DISCONNECTED; - return RESULT_SILENCE; + static cc_charbuff *ans = NULL; + if(!ans) ans = cc_charbufnew(); + cc_buff_lock(ans); + cc_charbufclr(ans); + cc_hresult r = camera->plugincmd(val, ans); + cc_buff_unlock(ans); + if(ans->buflen && !cc_sendstrmessage(fd, ans->buf)) r = RESULT_DISCONNECTED; + return r; } // get headers