Rev 143 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 143 | f9daq | 1 | #include <formatio.h> |
| 2 | #include <utility.h> |
||
| 3 | #include <python.h> |
||
| 4 | #include <ansi_c.h> |
||
| 5 | #include <cvirte.h> |
||
| 6 | #include <userint.h> |
||
| 7 | #include "TestGui.h" |
||
| 8 | #include "ExportCVIFunctions.h" |
||
| 9 | // http://www.linuxjournal.com/node/8497/print |
||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | static int pTSQData[2]; |
||
| 14 | static int tfID; |
||
| 15 | CmtThreadPoolHandle threadHandle = 0; |
||
| 16 | CmtTSQHandle queueHandle; |
||
| 17 | int panelHandle; |
||
| 18 | |||
| 19 | int ProcessUserEvent(int pID, int rID,int mode); |
||
| 20 | |||
| 21 | char strbuf[0xFF]; |
||
| 22 | int mprintf(const char *format, ...) { |
||
| 23 | va_list aptr; |
||
| 24 | int ret,log; |
||
| 25 | FILE *flog; |
||
| 26 | |||
| 27 | va_start(aptr, format); |
||
| 28 | ret = vsprintf(strbuf, format, aptr); |
||
| 29 | va_end(aptr); |
||
| 30 | SetCtrlVal(panelHandle,PANEL_STDIO,strbuf); |
||
| 31 | return(ret); |
||
| 32 | } |
||
| 33 | |||
| 34 | // map uir controls .... |
||
| 35 | #define MAX_UIRCTRLMAP_SIZE 1000 |
||
| 36 | typedef struct { |
||
| 37 | char name[32]; |
||
| 38 | int id; |
||
| 39 | int handle; |
||
| 40 | } UirCtrlMap; |
||
| 41 | UirCtrlMap gUirCtrlMap[MAX_UIRCTRLMAP_SIZE]; |
||
| 42 | int gNUirCtrlMap=0; |
||
| 43 | |||
| 44 | int GetControlID(const char *ctrl) { |
||
| 45 | for (int i=0; i<gNUirCtrlMap; i++) { |
||
| 46 | if (strcmp(ctrl,gUirCtrlMap[i].name)==0) return ctrl,gUirCtrlMap[i].id; |
||
| 47 | } |
||
| 48 | return -1; |
||
| 49 | } |
||
| 50 | |||
| 51 | int GetPanelHandle(const char *ctrl) { |
||
| 52 | |||
| 53 | if ( strstr(ctrl, "PANEL_")!= NULL ) return panelHandle; |
||
| 54 | |||
| 55 | return 0; |
||
| 56 | } |
||
| 57 | |||
| 58 | DLLEXPORT int pySetPanelHandle(int handle) { |
||
| 59 | |||
| 60 | panelHandle = handle; |
||
| 61 | return 0; |
||
| 62 | } |
||
| 63 | |||
| 64 | DLLEXPORT int pySetQueueHandle(int handle) { |
||
| 65 | |||
| 66 | queueHandle = handle; |
||
| 67 | return 0; |
||
| 68 | } |
||
| 69 | |||
| 70 | DLLEXPORT int pySetThreadHandle(int handle) { |
||
| 71 | |||
| 72 | threadHandle = handle; |
||
| 73 | return 0; |
||
| 74 | } |
||
| 75 | |||
| 76 | |||
| 77 | DLLEXPORT int pyLoadUirHeader(const char *fname) { |
||
| 78 | int ndim=MAX_PATHNAME_LEN; |
||
| 79 | char line[MAX_PATHNAME_LEN]; |
||
| 80 | char cmd[MAX_PATHNAME_LEN]; |
||
| 81 | FILE *fp = NULL; |
||
| 82 | ssize_t size; |
||
| 83 | int n0= gNUirCtrlMap; |
||
| 84 | if ( GetFileInfo(fname,&size) ) fp = fopen(fname,"r"); |
||
| 85 | if (!fp) { |
||
| 86 | mprintf("Error! Cannot open header file %s\n",fname); |
||
| 87 | return -1; |
||
| 88 | } |
||
| 89 | |||
| 90 | while (fgets(line,ndim,fp)!=NULL ) { |
||
| 91 | char ctrl[32]; |
||
| 92 | int ctrlid; |
||
| 93 | int nb = sscanf(line,"%s%s%d",cmd, ctrl, &ctrlid); |
||
| 94 | if (strstr(cmd,"#define")!=NULL && nb==3) { |
||
| 95 | strcpy(gUirCtrlMap[gNUirCtrlMap].name, ctrl ); |
||
| 96 | if (gNUirCtrlMap<MAX_UIRCTRLMAP_SIZE) { |
||
| 97 | gUirCtrlMap[gNUirCtrlMap].id = ctrlid; |
||
| 98 | gUirCtrlMap[gNUirCtrlMap].handle = GetPanelHandle(ctrl); |
||
| 99 | mprintf("%s= Ctrl '%d' Panel'%d'\n", ctrl,ctrlid, gUirCtrlMap[gNUirCtrlMap].handle); |
||
| 100 | gNUirCtrlMap++; |
||
| 101 | } else { |
||
| 102 | mprintf("ERROR: Increase gNUirCtrlMap\n"); |
||
| 103 | } |
||
| 104 | } |
||
| 105 | } |
||
| 106 | fclose(fp); |
||
| 107 | mprintf("Number of Controls loaded from File %s = %d \n", fname,gNUirCtrlMap-n0); |
||
| 108 | return 0; |
||
| 109 | } |
||
| 110 | |||
| 111 | DLLEXPORT int pyGetCtrlVal(char *param, char *paramValue){ |
||
| 112 | int pID= GetPanelHandle(param); |
||
| 113 | int rID= GetControlID(param); |
||
| 114 | int datatype; |
||
| 115 | int retval=-1; |
||
| 116 | if (rID>0 && pID>0) { |
||
| 117 | GetCtrlAttribute (pID, rID, ATTR_DATA_TYPE, &datatype); |
||
| 118 | retval = GetCtrlVal(pID, rID, paramValue); |
||
| 119 | switch (datatype) { |
||
| 120 | case VAL_INTEGER: |
||
| 121 | mprintf("[GetCtrlVal] %s value=%d panel=%d control=%d\n",param, *(int *) paramValue,pID,rID); |
||
| 122 | break; |
||
| 123 | case VAL_UNSIGNED_INTEGER: |
||
| 124 | mprintf("[GetCtrlVal] %s value=%u panel=%d control=%d\n",param, *(unsigned int *) paramValue,pID,rID); |
||
| 125 | break; |
||
| 126 | case VAL_SHORT_INTEGER: |
||
| 127 | mprintf("[GetCtrlVal] %s value=%d panel=%d control=%d\n",param, *(short *) paramValue,pID,rID); |
||
| 128 | break; |
||
| 129 | case VAL_UNSIGNED_SHORT_INTEGER: |
||
| 130 | mprintf("[GetCtrlVal] %s value=%d panel=%d control=%d\n",param, *(unsigned short *) paramValue,pID,rID); |
||
| 131 | break; |
||
| 132 | case VAL_DOUBLE : |
||
| 133 | mprintf("[GetCtrlVal] %s value=%f panel=%d control=%d\n",param, *(double *) paramValue,pID,rID); |
||
| 134 | break; |
||
| 135 | case VAL_STRING : |
||
| 136 | default: |
||
| 137 | mprintf("[GetCtrlVal] %s value=%s panel=%d control=%d\n",param, paramValue,pID,rID); |
||
| 138 | break; |
||
| 139 | |||
| 140 | } |
||
| 141 | } |
||
| 142 | |||
| 143 | return retval; |
||
| 144 | } |
||
| 145 | |||
| 146 | |||
| 147 | DLLEXPORT int pyQueueUserEvent(char *param){ |
||
| 148 | |||
| 149 | int pID= GetPanelHandle(param); |
||
| 150 | int rID= GetControlID(param); |
||
| 151 | int retval=-1; |
||
| 152 | mprintf("QueueUserEvent %s panelHandle %d controlID %d\n",param, pID, rID ); |
||
| 153 | |||
| 154 | if (rID>0 && pID>0) { |
||
| 155 | int data[2] = {pID,rID}; |
||
| 156 | mprintf("queueHandle %d\n", queueHandle ); |
||
| 157 | retval = CmtWriteTSQData (queueHandle, data, 1, TSQ_INFINITE_TIMEOUT, NULL); |
||
| 158 | |||
| 159 | } |
||
| 160 | return retval; |
||
| 161 | } |
||
| 162 | |||
| 163 | |||
| 164 | DLLEXPORT int pyProcessUserEvent(char *param){ |
||
| 165 | |||
| 166 | int pID= GetPanelHandle(param); |
||
| 167 | int rID= GetControlID(param); |
||
| 168 | int retval=-1; |
||
| 169 | mprintf("ProcessUserEvent %s panelHandle %d controlID %d\n",param, pID, rID ); |
||
| 170 | if (rID>0 && pID>0) retval = ProcessUserEvent(pID, rID,0); |
||
| 171 | return retval; |
||
| 172 | } |
||
| 173 | |||
| 174 | |||
| 175 | |||
| 176 | DLLEXPORT int pySetCtrlVal(char *param, char *paramValue) |
||
| 177 | { |
||
| 178 | |||
| 179 | |||
| 180 | int pID= GetPanelHandle(param); |
||
| 181 | int rID= GetControlID(param); |
||
| 182 | int datatype; |
||
| 183 | int ret=0; |
||
| 184 | if (rID>0 && pID>0) { |
||
| 185 | GetCtrlAttribute (pID, rID, ATTR_DATA_TYPE, &datatype); |
||
| 186 | |||
| 187 | switch (datatype) { |
||
| 188 | case VAL_INTEGER: |
||
| 189 | ret=SetCtrlVal (pID, rID, atoi(paramValue)); |
||
| 190 | break; |
||
| 191 | case VAL_UNSIGNED_INTEGER: |
||
| 192 | ret=SetCtrlVal (pID, rID, strtoul(paramValue,NULL,0)); |
||
| 193 | break; |
||
| 194 | case VAL_SHORT_INTEGER: |
||
| 195 | ret=SetCtrlVal (pID, rID, atoi(paramValue)); |
||
| 196 | break; |
||
| 197 | case VAL_UNSIGNED_SHORT_INTEGER: |
||
| 198 | ret=SetCtrlVal (pID, rID, strtoul(paramValue,NULL,0)); |
||
| 199 | break; |
||
| 200 | case VAL_DOUBLE : |
||
| 201 | ret=SetCtrlVal (pID, rID, atof(paramValue)); |
||
| 202 | break; |
||
| 203 | case VAL_STRING : |
||
| 204 | ret=SetCtrlVal (pID, rID, paramValue ); |
||
| 205 | break; |
||
| 206 | default: |
||
| 207 | mprintf("[SetCtrlVal] ATTR_DATA_TYPE of the %s not supported datatype %d\n", param, datatype); |
||
| 208 | } |
||
| 209 | mprintf("[SetCtrlVal] %s %s panel=%d control=%d\n",param, paramValue,pID,rID); |
||
| 210 | } else { |
||
| 211 | mprintf("[SetCtrlVal] Invalid Ctrl %s %s panel=%d control=%d nctrls=%d\n",param, paramValue,pID,rID,gNUirCtrlMap); |
||
| 212 | } |
||
| 213 | |||
| 214 | |||
| 215 | return ret; |
||
| 216 | } |
||
| 217 | |||
| 218 | DLLEXPORT int pyPrint(int panel) |
||
| 219 | { |
||
| 220 | |||
| 221 | mprintf("Hi! %d\n", panel); |
||
| 222 | //return SetCtrlVal(panel, ctrl,text ); |
||
| 223 | return 0; |
||
| 224 | } |
||
| 225 | |||
| 226 | |||
| 227 | |||
| 228 | void CVICALLBACK QueueUserEventCallback (CmtTSQHandle queueHandle, unsigned int event, int value, void *callbackData) { |
||
| 229 | int *data= (int *) callbackData; |
||
| 230 | int mdata[2]; |
||
| 231 | CmtReadTSQData (queueHandle, mdata, 1, 0, 0); |
||
| 232 | mprintf("QueueUserEvent --->Thread Safe Queue %d %d\n", mdata[0],mdata[1]); |
||
| 233 | QueueUserEvent (1001, mdata[0], mdata[1]); |
||
| 234 | } |
||
| 235 | |||
| 236 | |||
| 237 | |||
| 238 | |||
| 239 | int CVICALLBACK Test(void *functionData) |
||
| 240 | { |
||
| 241 | |||
| 242 | mprintf("Test\n"); |
||
| 243 | |||
| 244 | return 0; |
||
| 245 | } |
||
| 246 | |||
| 247 | |||
| 248 | int CVICALLBACK ExecPython(void *functionData) |
||
| 249 | { |
||
| 250 | |||
| 251 | char *argv="testgui.py"; |
||
| 252 | int argc=1; |
||
| 253 | Py_Initialize(); |
||
| 254 | mprintf("Py_Main() %d\n", Py_Main(argc, &argv)); |
||
| 255 | Py_Finalize(); |
||
| 256 | return 0; |
||
| 257 | } |
||
| 258 | |||
| 259 | |||
| 260 | |||
| 261 | int cRunPython = 0; |
||
| 262 | |||
| 263 | int CVICALLBACK RunPython(void *functionData) |
||
| 264 | { |
||
| 265 | |||
| 266 | char *fname="testgui.py"; |
||
| 267 | |||
| 268 | char handles[0xFF]; |
||
| 269 | |||
| 270 | int argc=0, merr=0; |
||
| 271 | char *argv = "TestGui.exe"; |
||
| 272 | |||
| 273 | while ( cRunPython ) { |
||
| 274 | mprintf("RunPython not finished yet... Waiting ....\n"); |
||
| 275 | Delay(0.5);// To Ensure only one python interpreter is running |
||
| 276 | } |
||
| 277 | cRunPython = 1; |
||
| 278 | Py_Initialize(); |
||
| 279 | |||
| 280 | mprintf("Py_IsInitialized(); %d\n", Py_IsInitialized()); |
||
| 281 | mprintf("Py_GetVersion() %s\n", Py_GetVersion() ); |
||
| 282 | |||
| 283 | PyRun_SimpleString("import sys\n"); |
||
| 284 | PyRun_SimpleString("sys.stdout = sys.stderr = open(\"log_file.txt\", \"w\")\n" ); |
||
| 285 | sprintf(handles, "panel=%d\nqueue=%d\n", panelHandle, (int) queueHandle); |
||
| 286 | mprintf(handles); |
||
| 287 | PyRun_SimpleString(handles); |
||
| 288 | PyRun_SimpleString( |
||
| 289 | "print('Example , how to use python from NI LWCVI')\n" |
||
| 290 | "from time import time,ctime\n" |
||
| 291 | "print( 'Today is',ctime(time()))\n" |
||
| 292 | ); |
||
| 293 | |||
| 294 | |||
| 295 | PyObject *obj = Py_BuildValue("s", fname); |
||
| 296 | FILE *fp = _Py_fopen_obj(obj, "r+"); |
||
| 297 | //fp = fopen(fname,"r"); // tole ne dela |
||
| 298 | if(fp != NULL) merr = PyRun_SimpleFile(fp, fname); |
||
| 299 | mprintf("PyRun_SimpleFile(%s) %d ---->output\n",fname, merr); |
||
| 300 | |||
| 301 | Py_Finalize(); |
||
| 302 | char line[MAX_PATHNAME_LEN]; |
||
| 303 | FILE *fpout= fopen("log_file.txt","r"); |
||
| 304 | if (fpout) { |
||
| 305 | while (fgets(line,MAX_PATHNAME_LEN,fpout)!=NULL) mprintf(line); |
||
| 306 | fclose(fpout); |
||
| 307 | } |
||
| 308 | |||
| 309 | cRunPython = 0; |
||
| 310 | |||
| 311 | return 0; |
||
| 312 | } |
||
| 313 | |||
| 314 | void SetDimming(int state) { |
||
| 315 | mprintf("SetDimming %d\n", state); |
||
| 316 | SetCtrlAttribute (panelHandle, PANEL_START, ATTR_DIMMED, state); |
||
| 317 | SetCtrlAttribute (panelHandle, PANEL_INTERPRETER, ATTR_DIMMED, state); |
||
| 318 | SetCtrlAttribute (panelHandle, PANEL_TEST, ATTR_DIMMED, state); |
||
| 319 | } |
||
| 320 | |||
| 321 | int nthreads=0; |
||
| 322 | void CVICALLBACK EndOfThread ( CmtThreadPoolHandle poolhandle, |
||
| 323 | CmtThreadFunctionID functionID, unsigned int event, |
||
| 324 | int value, void *callbackData ) { |
||
| 325 | mprintf("%d End of Thread handle=%d functionID=%d\n", nthreads, (int)poolhandle, functionID); |
||
| 326 | |||
| 327 | nthreads--; |
||
| 328 | if (!nthreads) SetDimming(0); |
||
| 329 | return ; |
||
| 330 | |||
| 331 | } |
||
| 332 | |||
| 333 | |||
| 334 | |||
| 335 | |||
| 336 | int ProcessUserEvent(int pID, int rID,int mode){ |
||
| 337 | |||
| 338 | ThreadFunctionPtr thread = NULL; |
||
| 339 | int retval=0; |
||
| 340 | switch (rID) { |
||
| 341 | case PANEL_START: |
||
| 342 | thread=RunPython; |
||
| 343 | break; |
||
| 344 | case PANEL_INTERPRETER: |
||
| 345 | thread=ExecPython; |
||
| 346 | break; |
||
| 347 | case PANEL_TEST: |
||
| 348 | thread=Test; |
||
| 349 | break; |
||
| 350 | case PANEL_EXIT : |
||
| 351 | return 1; |
||
| 352 | default: |
||
| 353 | mprintf("Unknown Event panel %d control %d\n",pID,rID); |
||
| 354 | |||
| 355 | } |
||
| 356 | |||
| 357 | if (thread!=NULL) { |
||
| 358 | |||
| 359 | if (mode) { |
||
| 360 | SetDimming(1); |
||
| 361 | mprintf("%d ProcessUserEvent in new Thread panel=%d button=%d mode=%d\n",nthreads, pID, rID, mode); |
||
| 362 | retval = CmtScheduleThreadPoolFunctionAdv (threadHandle, thread, &rID, |
||
| 363 | DEFAULT_THREAD_PRIORITY, |
||
| 364 | EndOfThread, |
||
| 365 | EVENT_TP_THREAD_FUNCTION_END, |
||
| 366 | NULL, RUN_IN_SCHEDULED_THREAD, |
||
| 367 | &tfID); |
||
| 368 | if (retval<0) { |
||
| 369 | char txt[MAX_PATHNAME_LEN]; |
||
| 370 | CmtGetErrorMessage(retval, txt); |
||
| 371 | MessagePopup("CmtScheduleThreadPoolFunctionAdv", txt); |
||
| 372 | } else nthreads++; |
||
| 373 | } else { |
||
| 374 | mprintf("ProcessUserEvent panel=%d button=%d mode=%d\n", pID, rID, mode); |
||
| 375 | thread(NULL); |
||
| 376 | } |
||
| 377 | } |
||
| 378 | ProcessSystemEvents(); |
||
| 379 | |||
| 380 | return retval; |
||
| 381 | } |
||
| 382 | |||
| 383 | |||
| 384 | |||
| 385 | int main (int argc, char *argv[]) |
||
| 386 | { |
||
| 387 | if (InitCVIRTE (0, argv, 0) == 0) |
||
| 388 | return -1; /* out of memory */ |
||
| 389 | if ((panelHandle = LoadPanel (0, "TestGui.uir", PANEL)) < 0) |
||
| 390 | return -1; |
||
| 391 | //pyLoadUirHeader("TestGui.h"); |
||
| 392 | |||
| 393 | int status=0; |
||
| 394 | CmtNewThreadPool (10, &threadHandle); |
||
| 395 | if ( status = CmtNewTSQ (1, 2*sizeof(int), OPT_TSQ_AUTO_FLUSH_ALL, &queueHandle) <0) |
||
| 396 | mprintf("CmtNewTSQ cannot be installed\n"); |
||
| 397 | else { |
||
| 398 | mprintf("CmtNewTSQ handle %d\n", (int) queueHandle ); |
||
| 399 | } |
||
| 400 | if ( status = CmtInstallTSQCallback (queueHandle, EVENT_TSQ_ITEMS_IN_QUEUE, EVENT_TSQ_QUEUE_SIZE, |
||
| 401 | QueueUserEventCallback, pTSQData, CmtGetCurrentThreadID(), NULL) <0) |
||
| 402 | mprintf("CmtInstallTSQCallback cannot be installed\n"); ; |
||
| 403 | |||
| 404 | DisplayPanel (panelHandle); |
||
| 405 | |||
| 406 | int pID, rID, retval; |
||
| 407 | do { |
||
| 408 | GetUserEvent (1, &pID, &rID); |
||
| 409 | retval = ProcessUserEvent(pID,rID,1); |
||
| 410 | } while (!retval); |
||
| 411 | |||
| 412 | CmtDiscardThreadPool (threadHandle); |
||
| 413 | DiscardPanel (panelHandle); |
||
| 414 | return 0; |
||
| 415 | } |
||
| 416 | |||
| 417 | |||
| 418 | |||
| 419 | |||
| 420 | |||
| 421 | /* |
||
| 422 | |||
| 423 | static PyObject * SetCtrlVal_wrapper(PyObject * self, PyObject * args) |
||
| 424 | { |
||
| 425 | char * input; |
||
| 426 | char result[0xFF]; |
||
| 427 | PyObject * ret; |
||
| 428 | |||
| 429 | // parse arguments |
||
| 430 | if (!PyArg_ParseTuple(args, "s", &input)) { |
||
| 431 | return NULL; |
||
| 432 | } |
||
| 433 | |||
| 434 | // run the actual function |
||
| 435 | int retval = SetCtrlVal(panelHandle, PANEL_TXT,input ); |
||
| 436 | sprintf(result,"%d", retval); |
||
| 437 | // build the resulting string into a Python object. |
||
| 438 | ret = PyBytes_FromString(result); |
||
| 439 | free(result); |
||
| 440 | |||
| 441 | return ret; |
||
| 442 | } |
||
| 443 | |||
| 444 | |||
| 445 | static PyMethodDef module_methods[] = { |
||
| 446 | {"fib",(PyCFunction) SetCtrlVal_wrapper, METH_VARARGS,"Outputs the text to the PANEL_TXT"}, |
||
| 447 | {NULL,NULL,0,NULL} |
||
| 448 | }; |
||
| 449 | |||
| 450 | static struct PyModuleDef cModPyDem = |
||
| 451 | { |
||
| 452 | PyModuleDef_HEAD_INIT, |
||
| 453 | "SetCtrlVal", // name of module |
||
| 454 | "", // module documentation, may be NULL |
||
| 455 | -1, // size of per-interpreter state of the module, or -1 if the module keeps state in global variables. |
||
| 456 | module_methods |
||
| 457 | }; |
||
| 458 | |||
| 459 | |||
| 460 | PyMODINIT_FUNC PyInit_cModPyDem(void) |
||
| 461 | { |
||
| 462 | return PyModule_Create(&cModPyDem); |
||
| 463 | } |
||
| 464 | |||
| 465 | */ |
||
| 466 | |||
| 467 | |||
| 468 |