1
2 /*
3 A* -------------------------------------------------------------------
4 B* This file contains source code for the PyMOL computer program
5 C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
6 D* -------------------------------------------------------------------
7 E* It is unlawful to modify or remove this copyright notice.
8 F* -------------------------------------------------------------------
9 G* Please see the accompanying LICENSE file for further information.
10 H* -------------------------------------------------------------------
11 I* Additional authors of this source file include:
12 -*
13 -*
14 -*
15 Z* -------------------------------------------------------------------
16 */
17 #include"os_python.h"
18
19 #include"os_proprietary.h"
20
21 #include"os_predef.h"
22 #include"os_std.h"
23
24 #include"Base.h"
25 #include"OOMac.h"
26 #include"MemoryDebug.h"
27 #include"Ortho.h"
28 #include"Setting.h"
29 #include"Scene.h"
30 #include"ButMode.h"
31 #include"CGO.h"
32 #include"Executive.h"
33 #include"Editor.h"
34 #include"P.h"
35 #include"Util.h"
36 #include"main.h"
37 #include"PConv.h"
38 #include"Wizard.h"
39 #include"Seq.h"
40 #include"PyMOLOptions.h"
41 #include"OVContext.h"
42 #include"ShaderMgr.h"
43 #include"Sphere.h"
44 #include"Selector.h"
45 #include"Parse.h"
46
47 #ifdef _PYMOL_OPENVR
48 #include"OpenVRMode.h"
49 #endif
50
51 /*
52 * Setting level info table
53 *
54 * Levels are not hierarchical at the atom/bond level, that's why a simple
55 * sorted enumeration is not sufficient.
56 *
57 * global < object < object-state
58 * object-state < atom < atom-state
59 * object-state < bond < bond-state
60 */
61 const SettingLevelInfoType SettingLevelInfo[] = {
62 {"unused" , 0x00}, // 0b00000000
63 {"global" , 0x00}, // 0b00000000
64 {"object" , 0x01}, // 0b00000001
65 {"object-state" , 0x03}, // 0b00000011
66 {"atom" , 0x07}, // 0b00000111
67 {"atom-state" , 0x0F}, // 0b00001111
68 {"bond" , 0x13}, // 0b00010011
69 {"bond-state" , 0x33}, // 0b00110011
70 {NULL, 0}
71 };
72
73 // The following defines the static SettingInfo table
74 #define SETTINGINFO_IMPLEMENTATION
75 #include "SettingInfo.h"
76
77 template <> const char * SettingGet<const char *>(int index, const CSetting * I);
78
79 // get level name for setting index (for feedback)
SettingLevelGetName(PyMOLGlobals * G,int index)80 const char * SettingLevelGetName(PyMOLGlobals * G, int index) {
81 return SettingLevelInfo[SettingInfo[index].level].name;
82 }
83
84 // check if setting index is valid in given level-mask
SettingLevelCheckMask(PyMOLGlobals * G,int index,unsigned char mask)85 bool SettingLevelCheckMask(PyMOLGlobals * G, int index, unsigned char mask) {
86 unsigned char validmask = SettingLevelInfo[SettingInfo[index].level].mask;
87 return (0 == (mask & ~validmask));
88 }
89
90 // check if setting index is valid in given level
SettingLevelCheck(PyMOLGlobals * G,int index,unsigned char level)91 bool SettingLevelCheck(PyMOLGlobals * G, int index, unsigned char level) {
92 return SettingLevelCheckMask(G, index, SettingLevelInfo[level].mask);
93 }
94
95 /* ================================================================== */
96
SettingCopyAll(PyMOLGlobals * G,const CSetting * src,CSetting * dst)97 static CSetting *SettingCopyAll(PyMOLGlobals * G, const CSetting * src, CSetting * dst)
98 {
99 if(!dst) {
100 dst = pymol::calloc<CSetting>(1);
101 } else {
102 SettingPurge(dst);
103 }
104
105 SettingInit(G, dst);
106
107 if(dst && src) {
108
109 /* simply overwriting existing data (if any) ... in the future we
110 may need to release references etc. before doing this */
111
112 unsigned int size = VLAGetSize(src->info);
113 VLACheck(dst->info, SettingRec, size - 1);
114 UtilCopyMem(dst->info, src->info, sizeof(SettingRec) * size);
115 dst->size = src->size;
116
117 // need to properly copy strings
118 for (int index = 0; index < cSetting_INIT; ++index) {
119 if (SettingInfo[index].type == cSetting_string
120 && src->info[index].str_) {
121 dst->info[index].str_ = new std::string(*src->info[index].str_);
122 }
123 }
124 }
125 return dst;
126 }
127
SettingStoreDefault(PyMOLGlobals * G)128 void SettingStoreDefault(PyMOLGlobals * G)
129 {
130 G->Default = SettingCopyAll(G, G->Setting, G->Default);
131 }
132
SettingPurgeDefault(PyMOLGlobals * G)133 void SettingPurgeDefault(PyMOLGlobals * G)
134 {
135 if(G->Default) {
136 SettingPurge(G->Default);
137 FreeP(G->Default);
138 G->Default = NULL;
139 }
140 }
141
SettingUniqueDetachChain(PyMOLGlobals * G,int unique_id)142 void SettingUniqueDetachChain(PyMOLGlobals * G, int unique_id)
143 {
144 CSettingUnique *I = G->SettingUnique;
145 OVreturn_word result;
146 if(OVreturn_IS_OK(result = OVOneToOne_GetForward(I->id2offset, unique_id))) {
147 int offset = result.word;
148 int next;
149
150 OVOneToOne_DelForward(I->id2offset, unique_id);
151
152 {
153 SettingUniqueEntry *entry;
154 while(offset) {
155 entry = I->entry + offset;
156 next = entry->next;
157 entry->next = I->next_free;
158 I->next_free = offset;
159 offset = next;
160 }
161 }
162 } else {
163 /* uncaught error */
164 }
165 }
166
SettingUniqueExpand(PyMOLGlobals * G)167 static void SettingUniqueExpand(PyMOLGlobals * G)
168 {
169 CSettingUnique *I = G->SettingUnique;
170
171 if(!I->next_free) {
172 int new_n_alloc = (I->n_alloc * 3) / 2;
173 int a;
174 VLACheck(I->entry, SettingUniqueEntry, new_n_alloc);
175 for(a = I->n_alloc; a < new_n_alloc; a++) {
176 I->entry[a].next = I->next_free;
177 I->next_free = a;
178 }
179 I->n_alloc = new_n_alloc;
180 }
181 }
182
183 static
SettingFindSettingUniqueEntry(PyMOLGlobals * G,int unique_id,int setting_id)184 SettingUniqueEntry *SettingFindSettingUniqueEntry(PyMOLGlobals * G, int unique_id, int setting_id)
185 {
186 CSettingUnique *I = G->SettingUnique;
187 OVreturn_word result;
188 if(OVreturn_IS_OK(result = OVOneToOne_GetForward(I->id2offset, unique_id))) {
189 SettingUniqueEntry *entry;
190 for (int offset = result.word; offset; offset = entry->next) {
191 entry = I->entry + offset;
192 if(entry->setting_id == setting_id) {
193 return entry;
194 }
195 }
196 }
197 return NULL;
198 }
199
SettingUniqueCheck(PyMOLGlobals * G,int unique_id,int setting_id)200 int SettingUniqueCheck(PyMOLGlobals * G, int unique_id, int setting_id)
201 {
202 return SettingFindSettingUniqueEntry(G, unique_id, setting_id) != NULL;
203 }
204
205 /*
206 * Return true for convertible types and set int-compatible types to int
207 */
type_upcast(int & type)208 inline bool type_upcast(int &type) {
209 switch (type) {
210 case cSetting_int:
211 case cSetting_color:
212 case cSetting_boolean:
213 type = cSetting_int;
214 case cSetting_float:
215 return true;
216 }
217 return false;
218 }
219
SettingUniqueGetTypedValuePtr(PyMOLGlobals * G,int unique_id,int setting_id,int setting_type,void * value)220 bool SettingUniqueGetTypedValuePtr(PyMOLGlobals * G, int unique_id, int setting_id,
221 int setting_type, void * value)
222 {
223 auto entry = SettingFindSettingUniqueEntry(G, unique_id, setting_id);
224 if (!entry)
225 return false;
226
227 int type_from = SettingInfo[setting_id].type;
228
229 if (type_from != setting_type) {
230 if (!type_upcast(type_from) ||
231 !type_upcast(setting_type)) {
232 PRINTFB(G, FB_Setting, FB_Errors)
233 " Setting-Error: type mismatch\n" ENDFB(G);
234 return false;
235 }
236 }
237
238 if (setting_type == cSetting_float3){
239 *(const float **) value = entry->value.float3_;
240 } else if (setting_type == type_from) {
241 *(int *) value = entry->value.int_;
242 } else if (setting_type == cSetting_int) {
243 *(int *) value = (int) entry->value.float_;
244 } else { // setting_type == cSetting_float
245 *(float *) value = (float) entry->value.int_;
246 }
247
248 return true;
249 }
250
251 /*
252 * Warning: Returns colors as (fff) tuple instead of color index
253 */
SettingUniqueGetPyObject(PyMOLGlobals * G,int unique_id,int index)254 PyObject *SettingUniqueGetPyObject(PyMOLGlobals * G, int unique_id, int index)
255 {
256 int type = SettingGetType(G, index);
257
258 union {
259 int val_i;
260 float val_f;
261 const float * ptr_3f;
262 };
263
264 if (SettingUniqueGetTypedValuePtr(G, unique_id, index, type, &ptr_3f)) {
265 switch (type) {
266 case cSetting_boolean:
267 return CPythonVal_New_Boolean(val_i);
268 case cSetting_int:
269 return CPythonVal_New_Integer(val_i);
270 case cSetting_float:
271 return CPythonVal_New_Float(val_f);
272 case cSetting_color:
273 #ifdef _PYMOL_NOPY
274 return CPythonVal_New_Integer(val_i);
275 #else
276 return PYOBJECT_CALLFUNCTION(G->P_inst->colortype, "i", val_i);
277 #endif
278 case cSetting_float3:
279 {
280 PyObject *result = PyTuple_New(3);
281 PyTuple_SET_ITEM(result, 0, CPythonVal_New_Float(ptr_3f[0]));
282 PyTuple_SET_ITEM(result, 1, CPythonVal_New_Float(ptr_3f[1]));
283 PyTuple_SET_ITEM(result, 2, CPythonVal_New_Float(ptr_3f[2]));
284 return result;
285 }
286 }
287 }
288
289 return NULL;
290 }
291
SettingUniqueEntry_IsSame(SettingUniqueEntry * entry,int setting_type,const void * value)292 static int SettingUniqueEntry_IsSame(SettingUniqueEntry *entry, int setting_type, const void *value){
293 if (SettingInfo[entry->setting_id].type != setting_type){
294 return 0;
295 }
296 if (setting_type == cSetting_float3){
297 const float *v = (float*)value, *ev = entry->value.float3_;
298 return v[0]==ev[0] && v[1]==ev[1] && v[2]==ev[2];
299 } else {
300 return (entry->value.int_ == *(int *) value);
301 }
302 }
303
SettingUniqueEntry_Set(SettingUniqueEntry * entry,int value_type,const void * value)304 static void SettingUniqueEntry_Set(SettingUniqueEntry *entry, int value_type, const void *value){
305 int setting_type = SettingGetType(entry->setting_id);
306 switch (value_type) {
307 case cSetting_boolean:
308 case cSetting_int:
309 case cSetting_color:
310 if (setting_type == cSetting_float) {
311 entry->value.float_ = *(int*) value;
312 } else {
313 entry->value.int_ = *(int *) value;
314 }
315 break;
316 case cSetting_float:
317 if (setting_type != cSetting_float) {
318 entry->value.int_ = *(float *) value;
319 } else {
320 entry->value.float_ = *(float *) value;
321 }
322 break;
323 case cSetting_float3:
324 memcpy(entry->value.float3_, *(const float **) value, sizeof(float) * 3);
325 break;
326 default:
327 printf("SettingUniqueEntry_Set-Error: unsupported type %d\n", value_type);
328 }
329 }
330
331 /*
332 * Return false if setting was not set (nothing changed)
333 */
SettingUniqueUnset(PyMOLGlobals * G,int unique_id,int setting_id)334 bool SettingUniqueUnset(PyMOLGlobals * G, int unique_id, int setting_id)
335 {
336 auto I = G->SettingUnique;
337 auto result = OVOneToOne_GetForward(I->id2offset, unique_id);
338
339 if (OVreturn_IS_OK(result)) {
340 for (int prev = 0, offset = result.word; offset;
341 prev = offset, offset = I->entry[offset].next) {
342 if (I->entry[offset].setting_id != setting_id)
343 continue;
344
345 if(!prev) { /* if first entry in list */
346 OVOneToOne_DelForward(I->id2offset, unique_id);
347 if(I->entry[offset].next) { /* set new list start */
348 OVOneToOne_Set(I->id2offset, unique_id, I->entry[offset].next);
349 }
350 } else { /* otherwise excise from middle or end */
351 I->entry[prev].next = I->entry[offset].next;
352 }
353 I->entry[offset].next = I->next_free;
354 I->next_free = offset;
355
356 return true;
357 }
358 }
359 return false;
360 }
361
SettingUniqueSetTypedValue(PyMOLGlobals * G,int unique_id,int setting_id,int setting_type,const void * value)362 int SettingUniqueSetTypedValue(PyMOLGlobals * G, int unique_id, int setting_id,
363 int setting_type, const void *value)
364
365 /* set value to NULL in order to delete setting */
366 {
367 CSettingUnique *I = G->SettingUnique;
368 OVreturn_word result;
369 int isset = false;
370
371 if (!value) {
372 return SettingUniqueUnset(G, unique_id, setting_id);
373 }
374
375 if(OVreturn_IS_OK((result = OVOneToOne_GetForward(I->id2offset, unique_id)))) { /* setting list exists for atom */
376 int offset = result.word;
377 int prev = 0;
378 int found = false;
379 while(offset) {
380 SettingUniqueEntry *entry = I->entry + offset;
381 if(entry->setting_id == setting_id) {
382 found = true; /* this setting is already defined */
383 if (!SettingUniqueEntry_IsSame(entry, setting_type, value)){
384 SettingUniqueEntry_Set(entry, setting_type, value);
385 isset = true;
386 }
387 break;
388 }
389 prev = offset;
390 offset = entry->next;
391 }
392 if((!found) && value) { /* setting not found in existing list, so append new value */
393 if(!I->next_free)
394 SettingUniqueExpand(G);
395 if(I->next_free) {
396 offset = I->next_free;
397 {
398 SettingUniqueEntry *entry = I->entry + offset;
399 I->next_free = entry->next;
400 entry->next = 0;
401
402 if(prev) { /* append onto existing list */
403 I->entry[prev].next = offset;
404 entry->setting_id = setting_id;
405 SettingUniqueEntry_Set(entry, setting_type, value);
406 isset = true;
407 } else if(OVreturn_IS_OK(OVOneToOne_Set(I->id2offset, unique_id, offset))) {
408 /* create new list */
409 entry->setting_id = setting_id;
410 SettingUniqueEntry_Set(entry, setting_type, value);
411 isset = true;
412 }
413 }
414 }
415 }
416 } else if(value && (result.status == OVstatus_NOT_FOUND)) { /* new setting list for atom */
417 if(!I->next_free)
418 SettingUniqueExpand(G);
419 if(I->next_free) {
420 int offset = I->next_free;
421 SettingUniqueEntry *entry = I->entry + offset;
422
423 if(OVreturn_IS_OK(OVOneToOne_Set(I->id2offset, unique_id, offset))) {
424 I->next_free = entry->next;
425 entry->setting_id = setting_id;
426 entry->next = 0;
427 SettingUniqueEntry_Set(entry, setting_type, value);
428 isset = true;
429 }
430 }
431 } else {
432 /* unhandled error */
433 }
434 return isset;
435 }
436
437 #ifndef _PYMOL_NOPY
SettingUniqueSetPyObject(PyMOLGlobals * G,int unique_id,int index,PyObject * value)438 bool SettingUniqueSetPyObject(PyMOLGlobals * G, int unique_id, int index, PyObject *value)
439 {
440 if (!value)
441 return SettingUniqueUnset(G, unique_id, index);
442
443 int type = SettingGetType(G, index);
444
445 float val_3f[3];
446 union {
447 int val_i;
448 float val_f;
449 float * ptr_3f;
450 };
451
452 switch (type) {
453 case cSetting_boolean:
454 case cSetting_int:
455 ok_assert(1, PConvPyObjectToInt(value, &val_i));
456 break;
457 case cSetting_float:
458 ok_assert(1, PConvPyObjectToFloat(value, &val_f));
459 break;
460 case cSetting_color:
461 if (!PConvPyIntToInt(value, &val_i)) {
462 OrthoLineType sval;
463 ok_assert(1, PConvPyStrToStr(value, sval, OrthoLineLength));
464 val_i = ColorGetIndex(G, sval);
465 }
466 break;
467 case cSetting_float3:
468 if (!PConvPyListOrTupleToFloatArrayInPlace(value, val_3f, 3)) {
469 OrthoLineType sval;
470 ok_assert(1, PConvPyStrToStr(value, sval, OrthoLineLength) &&
471 sscanf(sval, "%f%f%f", &val_3f[0], &val_3f[1], &val_3f[2]) == 3);
472 }
473 ptr_3f = val_3f;
474 break;
475 default:
476 PRINTFB(G, FB_Python, FB_Errors)
477 " Python-Error: atom-state-level setting unsupported type=%d\n", type ENDFB(G);
478 return false;
479 }
480
481 return SettingUniqueSetTypedValue(G, unique_id, index, type, &val_i);
482
483 ok_except1:
484 PRINTFB(G, FB_Setting, FB_Errors)
485 " Setting-Error: type mismatch\n" ENDFB(G);
486 return false;
487 }
488 #endif
489
SettingUniqueResetAll(PyMOLGlobals * G)490 void SettingUniqueResetAll(PyMOLGlobals * G)
491 {
492 CSettingUnique *I = G->SettingUnique;
493
494 OVOneToOne_Reset(I->id2offset);
495 {
496 int a;
497 I->n_alloc = 10;
498 VLAFreeP(I->entry);
499 I->entry = VLACalloc(SettingUniqueEntry, I->n_alloc);
500 /* note: intentially skip index 0 */
501 for(a = 2; a < 10; a++) {
502 I->entry[a].next = a - 1;
503 }
504 I->next_free = I->n_alloc - 1;
505 }
506 }
507
SettingUniquePrintAll(PyMOLGlobals * G,int src_unique_id)508 int SettingUniquePrintAll(PyMOLGlobals * G, int src_unique_id)
509 {
510 int ok = true;
511 CSettingUnique *I = G->SettingUnique;
512 OVreturn_word src_result;
513 printf("SettingUniquePrintAll: ");
514 if(OVreturn_IS_OK(src_result = OVOneToOne_GetForward(I->id2offset, src_unique_id))) {
515 int src_offset = src_result.word;
516 SettingUniqueEntry *src_entry;
517 while(ok && src_offset) {
518 {
519 src_entry = I->entry + src_offset;
520 {
521 int setting_id = src_entry->setting_id;
522 int setting_type = SettingInfo[setting_id].type;
523 const char * setting_name = SettingInfo[setting_id].name;
524 switch (setting_type) {
525 case cSetting_int:
526 case cSetting_color:
527 case cSetting_boolean:
528 printf("%s:%d:%d:%d ", setting_name, setting_id, setting_type, src_entry->value.int_);
529 break;
530 case cSetting_float:
531 printf("%s:%d:%d:%f ", setting_name, setting_id, setting_type, src_entry->value.float_);
532 break;
533 case cSetting_float3:
534 printf("%s:%d:%d:%f,%f,%f ", setting_name, setting_id, setting_type, src_entry->value.float3_[0],
535 src_entry->value.float3_[1],
536 src_entry->value.float3_[2]);
537 break;
538 case cSetting_string:
539 printf("%s:%d:%d:s%d ", setting_name, setting_id, setting_type, src_entry->value.int_);
540 break;
541 }
542 }
543 }
544 src_offset = I->entry[src_offset].next; /* src_entry invalid, since I->entry may have changed */
545 }
546 }
547 printf("\n");
548 return ok;
549 }
550
SettingUniqueCopyAll(PyMOLGlobals * G,int src_unique_id,int dst_unique_id)551 int SettingUniqueCopyAll(PyMOLGlobals * G, int src_unique_id, int dst_unique_id)
552 {
553 int ok = true;
554 CSettingUnique *I = G->SettingUnique;
555 OVreturn_word dst_result;
556
557 if(OVreturn_IS_OK((dst_result = OVOneToOne_GetForward(I->id2offset, dst_unique_id)))) { /* setting list exists for atom */
558 PRINTFB(G, FB_Setting, FB_Errors)
559 " SettingUniqueCopyAll-Bug: merging settings not implemented\n"
560 ENDFB(G);
561 ok = false;
562 } else if(dst_result.status == OVstatus_NOT_FOUND) { /* new setting list for atom */
563 OVreturn_word src_result;
564 if(OVreturn_IS_OK(src_result = OVOneToOne_GetForward(I->id2offset, src_unique_id))) {
565 int dst_offset = 0;
566 for (int src_offset = src_result.word; src_offset;
567 src_offset = I->entry[src_offset].next) {
568 SettingUniqueExpand(G); // this may reallocate I->entry
569
570 if (!dst_offset) {
571 OVOneToOne_Set(I->id2offset, dst_unique_id, I->next_free);
572 } else {
573 I->entry[dst_offset].next = I->next_free;
574 }
575
576 dst_offset = I->next_free;
577 I->next_free = I->entry[dst_offset].next;
578 I->entry[dst_offset] = I->entry[src_offset];
579 I->entry[dst_offset].next = 0;
580 }
581 }
582 } else {
583 ok = false;
584 /* unhandled error */
585 }
586
587 return ok;
588 }
589
SettingUniqueInit(PyMOLGlobals * G)590 static void SettingUniqueInit(PyMOLGlobals * G)
591 {
592 CSettingUnique *I = G->SettingUnique;
593
594 if((I = (G->SettingUnique = pymol::calloc<CSettingUnique>(1)))) {
595 I->id2offset = OVOneToOne_New(G->Context->heap);
596 {
597 int a;
598 I->n_alloc = 10;
599 I->entry = VLACalloc(SettingUniqueEntry, I->n_alloc);
600 /* note: intentially skip index 0 */
601 for(a = 2; a < 10; a++) {
602 I->entry[a].next = a - 1; /* 1-based linked list with 0 as sentinel */
603 }
604 I->next_free = I->n_alloc - 1;
605 }
606 }
607 }
608
SettingUniqueFree(PyMOLGlobals * G)609 static void SettingUniqueFree(PyMOLGlobals * G)
610 {
611 CSettingUnique *I = G->SettingUnique;
612 VLAFreeP(I->entry);
613 OVOneToOne_Del(I->id2offset);
614 FreeP(I);
615 }
616
617 /*
618 * For unique_id remapping during partial session loading
619 */
SettingUniqueConvertOldSessionID(PyMOLGlobals * G,int old_unique_id)620 int SettingUniqueConvertOldSessionID(PyMOLGlobals * G, int old_unique_id)
621 {
622 CSettingUnique *I = G->SettingUnique;
623 int unique_id = old_unique_id;
624 if(I->old2new) {
625 OVreturn_word ret;
626 if(OVreturn_IS_OK(ret = OVOneToOne_GetForward(I->old2new, old_unique_id))) {
627 unique_id = ret.word;
628 } else {
629 unique_id = AtomInfoGetNewUniqueID(G);
630 OVOneToOne_Set(I->old2new, old_unique_id, unique_id);
631 }
632 } else {
633 AtomInfoReserveUniqueID(G, unique_id);
634 }
635 return unique_id;
636 }
637
638 /*
639 * Return true if the given setting index should not be stored to PSE.
640 *
641 * Blacklisted are unused and system-dependent settings.
642 */
is_session_blacklisted(int index)643 static bool is_session_blacklisted(int index) {
644 if (index >= cSetting_INIT ||
645 SettingInfo[index].level == cSettingLevel_unused) {
646 return true;
647 }
648
649 switch (index) {
650 case cSetting_antialias_shader:
651 case cSetting_ati_bugs:
652 case cSetting_cache_max:
653 case cSetting_cgo_shader_ub_color:
654 case cSetting_cgo_shader_ub_flags:
655 case cSetting_cgo_shader_ub_normal:
656 case cSetting_colored_feedback:
657 case cSetting_cylinder_shader_ff_workaround:
658 case cSetting_defer_updates:
659 case cSetting_fast_idle:
660 case cSetting_internal_feedback:
661 case cSetting_internal_gui:
662 case cSetting_internal_prompt:
663 case cSetting_logging:
664 case cSetting_max_threads:
665 case cSetting_mouse_grid:
666 case cSetting_mouse_scale:
667 case cSetting_nb_spheres_use_shader:
668 case cSetting_no_idle:
669 case cSetting_nvidia_bugs:
670 case cSetting_presentation:
671 case cSetting_precomputed_lighting:
672 case cSetting_render_as_cylinders:
673 case cSetting_security:
674 case cSetting_session_changed:
675 case cSetting_session_file:
676 case cSetting_session_migration:
677 case cSetting_session_version_check:
678 case cSetting_shaders_from_disk:
679 case cSetting_show_progress:
680 case cSetting_slow_idle:
681 case cSetting_stereo:
682 case cSetting_stereo_double_pump_mono:
683 case cSetting_stereo_mode:
684 case cSetting_suspend_deferred:
685 case cSetting_suspend_undo:
686 case cSetting_suspend_undo_atom_count:
687 case cSetting_suspend_updates:
688 case cSetting_text:
689 case cSetting_trilines:
690 case cSetting_use_geometry_shaders:
691 case cSetting_use_shaders:
692 case cSetting_pick32bit:
693 case cSetting_display_scale_factor:
694 #ifdef _PYMOL_IOS
695 case cSetting_cgo_sphere_quality:
696 case cSetting_dynamic_measures:
697 case cSetting_label_outline_color:
698 case cSetting_mouse_selection_mode:
699 case cSetting_sphere_mode:
700 case cSetting_sphere_quality:
701 case cSetting_stick_ball:
702 case cSetting_virtual_trackball:
703 #elif defined(_PYMOL_ACTIVEX)
704 case cSetting_async_builds:
705 #endif
706 return true;
707 }
708
709 return false;
710 }
711
SettingUniqueFromPyList(PyMOLGlobals * G,PyObject * list,int partial_restore)712 int SettingUniqueFromPyList(PyMOLGlobals * G, PyObject * list, int partial_restore)
713 {
714 int ok = true;
715 if(!partial_restore) {
716 SettingUniqueResetAll(G);
717 }
718 if(list)
719 if(PyList_Check(list)) {
720 ov_size n_id = PyList_Size(list);
721 ov_size a;
722 for(a = 0; a < n_id; a++) {
723 PyObject *id_list = PyList_GetItem(list, a);
724 int unique_id;
725 if(ok)
726 ok = PyList_Check(id_list);
727 if(ok)
728 ok = (PyList_Size(id_list) > 1);
729 if(ok)
730 ok = PConvPyIntToInt(PyList_GetItem(id_list, 0), &unique_id);
731 if(ok && partial_restore) {
732 unique_id = SettingUniqueConvertOldSessionID(G, unique_id);
733 }
734 if(ok) {
735 ov_size n_set = 0;
736
737 PyObject *setting_list = PyList_GetItem(id_list, 1);
738 if(ok)
739 ok = PyList_Check(setting_list);
740 if(ok)
741 n_set = PyList_Size(setting_list);
742 if(ok) {
743 ov_size b;
744 for(b = 0; b < n_set; b++) {
745 PyObject *entry_list = PyList_GetItem(setting_list, b);
746 if(ok)
747 ok = PyList_Check(entry_list);
748 if(ok)
749 ok = (PyList_Size(entry_list) > 2);
750 if(ok) {
751 int setting_id;
752 int setting_type;
753 float val_3f[3];
754 union {
755 int int_;
756 float float_;
757 float * float3_;
758 } value_store;
759 if(ok)
760 ok = PConvPyIntToInt(PyList_GetItem(entry_list, 0), &setting_id);
761 if(ok)
762 ok = PConvPyIntToInt(PyList_GetItem(entry_list, 1), &setting_type);
763 if(ok)
764 switch (setting_type) {
765
766 case cSetting_int:
767 case cSetting_color:
768 case cSetting_boolean:
769 ok = PConvPyIntToInt(PyList_GetItem(entry_list, 2),
770 &value_store.int_);
771 break;
772 case cSetting_float:
773 ok = PConvPyFloatToFloat(PyList_GetItem(entry_list, 2),
774 &value_store.float_);
775 break;
776 case cSetting_float3:
777 {
778 CPythonVal *el = CPythonVal_PyList_GetItem(G, entry_list, 2);
779 value_store.float3_ = val_3f;
780 ok = PConvPyListToFloatArrayInPlace(el, value_store.float3_, 3);
781 CPythonVal_Free(el);
782 }
783 break;
784 }
785 if(ok) {
786 SettingUniqueSetTypedValue(G, unique_id, setting_id,
787 setting_type, &value_store);
788 }
789 }
790 }
791 }
792 }
793 }
794 }
795 return ok;
796 }
797
SettingUniqueAsPyList(PyMOLGlobals * G)798 PyObject *SettingUniqueAsPyList(PyMOLGlobals * G)
799 {
800 PyObject *result = NULL;
801 CSettingUnique *I = G->SettingUnique;
802 {
803 ov_word hidden = 0;
804 OVreturn_word ret;
805 int n_entry = 0;
806 while(1) {
807 ret = OVOneToOne_IterateForward(I->id2offset, &hidden);
808 if(ret.status != OVstatus_YES)
809 break;
810 n_entry++;
811 }
812 result = PyList_New(n_entry);
813 if(result) {
814 hidden = 0;
815 n_entry = 0;
816 while(1) {
817 PyObject *setting_list = NULL;
818 int save_offset, unique_id;
819 ret = OVOneToOne_IterateForward(I->id2offset, &hidden);
820
821 if(ret.status != OVstatus_YES)
822 break;
823 unique_id = ret.word;
824 if(OVreturn_IS_OK(ret = OVOneToOne_GetForward(I->id2offset, unique_id))) {
825 int offset = ret.word;
826 int n_set = 0;
827
828 /* count number of settings for this unique_id */
829
830 SettingUniqueEntry *entry;
831 save_offset = offset;
832 while(offset) {
833 entry = I->entry + offset;
834 n_set++;
835 offset = entry->next;
836 }
837
838 /* create and insert list for each setting */
839
840 setting_list = PyList_New(n_set);
841 n_set = 0;
842 offset = save_offset;
843 while(offset) {
844 PyObject *setting_entry = PyList_New(3);
845 entry = I->entry + offset;
846 int type = SettingInfo[entry->setting_id].type;
847 PyList_SetItem(setting_entry, 0, PyInt_FromLong(entry->setting_id));
848 PyList_SetItem(setting_entry, 1, PyInt_FromLong(type));
849 switch (type) {
850 case cSetting_int:
851 case cSetting_color:
852 case cSetting_boolean:
853 PyList_SetItem(setting_entry, 2, PyInt_FromLong(entry->value.int_));
854 break;
855 case cSetting_float:
856 PyList_SetItem(setting_entry, 2,
857 PyFloat_FromDouble(*(float *) &entry->value.float_));
858 break;
859 case cSetting_float3:
860 PyList_SetItem(setting_entry, 2,
861 PConvFloatArrayToPyList((float *) &entry->value.float3_, 3));
862 break;
863 }
864 PyList_SetItem(setting_list, n_set, setting_entry);
865 n_set++;
866 offset = entry->next;
867 }
868 }
869
870 /* add this unique_id set into the overall list */
871
872 {
873 PyObject *unique_list = PyList_New(2);
874 PyList_SetItem(unique_list, 0, PyInt_FromLong(unique_id));
875 PyList_SetItem(unique_list, 1, setting_list);
876 PyList_SetItem(result, n_entry, unique_list);
877 }
878 n_entry++;
879 }
880 }
881 }
882 return (PConvAutoNone(result));
883 }
884
SettingSetSmart_i(PyMOLGlobals * G,CSetting * set1,CSetting * set2,int index,int value)885 int SettingSetSmart_i(PyMOLGlobals * G, CSetting * set1, CSetting * set2, int index,
886 int value)
887 {
888 int dummy;
889 if(set1 && SettingGetIfDefined_i(G, set1, index, &dummy)) {
890 return SettingSet_i(set1, index, value);
891 }
892 if(set2 && SettingGetIfDefined_i(G, set2, index, &dummy)) {
893 return SettingSet_i(set2, index, value);
894 }
895 return SettingSetGlobal_i(G, index, value);
896 }
897
SettingSetGlobalsFromPyList(PyMOLGlobals * G,PyObject * list)898 int SettingSetGlobalsFromPyList(PyMOLGlobals * G, PyObject * list)
899 {
900 int ok = true;
901
902 CSetting *I = G->Setting;
903
904 if(list)
905 if(PyList_Check(list))
906 ok = SettingFromPyList(I, list);
907
908 /* restore the following settings */
909
910 if(G->Option->no_quit) {
911 SettingSet_b(I, cSetting_presentation_auto_quit, 0);
912 }
913
914 ColorUpdateFrontFromSettings(G);
915 return (ok);
916 }
917
SettingGetGlobalsAsPyList(PyMOLGlobals * G)918 PyObject *SettingGetGlobalsAsPyList(PyMOLGlobals * G)
919 {
920 PyObject *result = NULL;
921 CSetting *I = G->Setting;
922 result = SettingAsPyList(I);
923 return (PConvAutoNone(result));
924 }
925
get_list(CSetting * I,int index,bool incl_blacklisted)926 static PyObject *get_list(CSetting * I, int index, bool incl_blacklisted)
927 {
928 PyObject *result = NULL, *value = NULL;
929 int setting_type = SettingInfo[index].type;
930
931 if (!incl_blacklisted && is_session_blacklisted(index)) {
932 return NULL;
933 }
934
935 switch (setting_type) {
936
937 case cSetting_boolean:
938 case cSetting_int:
939 case cSetting_color:
940 value = PyInt_FromLong(I->info[index].int_);
941 break;
942 case cSetting_float:
943 value = PyFloat_FromDouble(I->info[index].float_);
944 break;
945 case cSetting_float3:
946 value = PConvFloatArrayToPyList(I->info[index].float3_, 3);
947 break;
948 case cSetting_string:
949 value = PyString_FromString(SettingGet<const char *>(index, I));
950 break;
951 }
952
953 if (value) {
954 result = PyList_New(3);
955 PyList_SetItem(result, 0, PyInt_FromLong(index));
956 PyList_SetItem(result, 1, PyInt_FromLong(setting_type));
957 PyList_SetItem(result, 2, value);
958 }
959
960 return result;
961 }
962
SettingAsPyList(CSetting * I,bool incl_blacklisted)963 PyObject *SettingAsPyList(CSetting * I, bool incl_blacklisted)
964 {
965 PyObject *result = NULL;
966 int a;
967
968 if(I) {
969 std::vector<PyObject*> list;
970 list.reserve(cSetting_INIT);
971
972 for(a = 0; a < cSetting_INIT; a++) {
973 if(I->info[a].defined) {
974 PyObject * item = get_list(I, a, incl_blacklisted);
975 if (item != NULL) {
976 list.push_back(item);
977 }
978 }
979 }
980
981 result = PConvToPyObject(list);
982 }
983 return (PConvAutoNone(result));
984 }
985
986 /*========================================================================*/
SettingCheckUseShaders(CSetting * I,int quiet)987 static int SettingCheckUseShaders(CSetting * I, int quiet)
988 {
989 PyMOLGlobals * G = I->G;
990 if (SettingGetGlobal_i(G, cSetting_use_shaders)){
991 if (G->ShaderMgr->IsConfigured() && !G->ShaderMgr->ShadersPresent()){
992 SettingSet_b(I, cSetting_use_shaders, 0);
993 if (!quiet){
994 PRINTFB(G, FB_Setting, FB_Warnings)
995 "Setting-Error: use_shaders cannot be set when Shaders are not available, setting use_shaders back to false\n"
996 ENDFB(G);
997 }
998 return 1;
999 }
1000 }
1001 return 0;
1002 }
1003
1004 /*========================================================================*/
set_list(CSetting * I,PyObject * list)1005 static int set_list(CSetting * I, PyObject * list)
1006 {
1007 int index = -1;
1008 int setting_type = -1;
1009
1010 union {
1011 int val_i;
1012 float val_f;
1013 float val_3f[3];
1014 const char * val_s;
1015 };
1016
1017 if (list == NULL || CPythonVal_IsNone(list))
1018 return true;
1019
1020 ok_assert(1, PyList_Check(list));
1021 ok_assert(1, CPythonVal_PConvPyIntToInt_From_List(I->G, list, 0, &index));
1022 ok_assert(1, CPythonVal_PConvPyIntToInt_From_List(I->G, list, 1, &setting_type));
1023
1024 if (is_session_blacklisted(index))
1025 return true;
1026
1027 switch (setting_type) {
1028 case cSetting_boolean:
1029 case cSetting_int:
1030 case cSetting_color:
1031 ok_assert(1, CPythonVal_PConvPyIntToInt_From_List(I->G, list, 2, &val_i));
1032 if (setting_type == cSetting_color)
1033 val_i = ColorConvertOldSessionIndex(I->G, val_i);
1034 SettingSet_i(I, index, val_i);
1035 break;
1036 case cSetting_float:
1037 ok_assert(1, CPythonVal_PConvPyFloatToFloat_From_List(I->G, list, 2, &val_f));
1038 SettingSet_f(I, index, val_f);
1039 break;
1040 case cSetting_float3:
1041 ok_assert(1, CPythonVal_PConvPyListToFloatArrayInPlaceAutoZero_From_List(I->G, list, 2, val_3f, 3));
1042 SettingSet_3fv(I, index, val_3f);
1043 break;
1044 case cSetting_string:
1045 ok_assert(1, val_s = PyString_AsString(PyList_GetItem(list, 2)));
1046 SettingSet_s(I, index, val_s);
1047 break;
1048 default:
1049 ok_raise(1);
1050 }
1051
1052 return true;
1053 ok_except1:
1054 printf(" set_list-Error: i=%d, t=%d\n", index, setting_type);
1055 return false;
1056 }
1057
1058 /*========================================================================*/
1059 /*
1060 * Used to set object and object-state level settings from PSEs
1061 */
SettingNewFromPyList(PyMOLGlobals * G,PyObject * list)1062 CSetting *SettingNewFromPyList(PyMOLGlobals * G, PyObject * list)
1063 {
1064 int ok = true;
1065 ov_size size;
1066 ov_size a;
1067 CSetting *I = NULL;
1068 if(ok)
1069 ok = (list != NULL);
1070 if(ok)
1071 ok = PyList_Check(list);
1072 if(ok) {
1073 I = SettingNew(G);
1074 size = PyList_Size(list);
1075 for(a = 0; a < size; a++) {
1076 if(ok)
1077 ok = set_list(I, PyList_GetItem(list, a));
1078 }
1079 }
1080 return (I);
1081 }
1082
1083 /*========================================================================*/
SettingFromPyList(CSetting * I,PyObject * list)1084 int SettingFromPyList(CSetting * I, PyObject * list)
1085 {
1086 int ok = true;
1087 ov_size size;
1088 ov_size a;
1089
1090 if(ok)
1091 ok = (I != NULL);
1092 if(ok)
1093 ok = PyList_Check(list);
1094 if(ok) {
1095 size = PyList_Size(list);
1096 for(a = 0; a < size; a++) {
1097 if(!set_list(I, PyList_GetItem(list, a)))
1098 ok = false;
1099 }
1100 }
1101 return (ok);
1102 }
1103
1104 /*========================================================================*/
1105 /*
1106 * Get the indices of all settings that have changed since last calling
1107 * this function. Resets the "changed" flag.
1108 *
1109 * NOTE: assumes blocked interpreter
1110 *
1111 * name: object name or NULL/"" for global settings
1112 * state: object state
1113 */
SettingGetUpdateList(PyMOLGlobals * G,const char * name,int state)1114 std::vector<int> SettingGetUpdateList(PyMOLGlobals * G, const char * name, int state)
1115 {
1116 CSetting **handle, *I = G->Setting;
1117 int a;
1118 int n;
1119 std::vector<int> result;
1120
1121 if (name && name[0]) {
1122 // object-state settings
1123
1124 CObject *obj = ExecutiveFindObjectByName(G, name);
1125
1126 if (!obj ||
1127 !(handle = obj->getSettingHandle(state)) ||
1128 !(I = *handle))
1129 // not found -> empty list
1130 return result;
1131 }
1132
1133 n = VLAGetSize(I->info);
1134 for(a = 0; a < n; a++) {
1135 if(I->info[a].changed) {
1136 I->info[a].changed = false;
1137 result.push_back(a);
1138 }
1139 }
1140 return (result);
1141
1142 }
1143
1144
1145 /*========================================================================*/
SettingCheckHandle(PyMOLGlobals * G,CSetting ** handle)1146 void SettingCheckHandle(PyMOLGlobals * G, CSetting ** handle)
1147 {
1148 if(!*handle)
1149 *handle = SettingNew(G);
1150 }
1151
1152
1153 /*========================================================================*/
SettingGetTextValue(PyMOLGlobals * G,const CSetting * set1,const CSetting * set2,int index,char * buffer)1154 int SettingGetTextValue(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index,
1155 char *buffer)
1156 {
1157 const char * sptr = SettingGetTextPtr(G, set1, set2, index, buffer);
1158 if(!sptr)
1159 return 0;
1160
1161 if (sptr != buffer) {
1162 if(strlen(sptr) > OrthoLineLength) {
1163 PRINTFB(G, FB_Setting, FB_Warnings)
1164 "Setting-Warning: text longer than OrthoLineLength" ENDFB(G);
1165 }
1166
1167 strncpy(buffer, sptr, OrthoLineLength);
1168 }
1169
1170 return 1;
1171 }
1172
1173 /*========================================================================*/
1174 /*
1175 * Returns a pointer to the internal string representation if available,
1176 * or it formats the value into buffer and returns a pointer to buffer.
1177 */
SettingGetTextPtr(PyMOLGlobals * G,const CSetting * set1,const CSetting * set2,int index,char * buffer)1178 const char * SettingGetTextPtr(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2,
1179 int index, char *buffer)
1180 {
1181 int type;
1182 const char *sptr = NULL;
1183 const float *ptr;
1184 type = SettingGetType(G, index);
1185 switch (type) {
1186 case cSetting_boolean:
1187 sprintf(buffer, SettingGet_b(G, set1, set2, index) ? "on" : "off");
1188 break;
1189 case cSetting_int:
1190 sprintf(buffer, "%d", SettingGet_i(G, set1, set2, index));
1191 break;
1192 case cSetting_float:
1193 sprintf(buffer, "%1.5f", SettingGet_f(G, set1, set2, index));
1194 break;
1195 case cSetting_float3:
1196 ptr = SettingGet_3fv(G, set1, set2, index);
1197 sprintf(buffer, "[ %1.5f, %1.5f, %1.5f ]", ptr[0], ptr[1], ptr[2]);
1198 break;
1199 case cSetting_color:
1200 {
1201 int color = SettingGet_color(G, set1, set2, index);
1202 switch (color) {
1203 case cColorAtomic:
1204 strcpy(buffer, "atomic");
1205 break;
1206 case cColorObject:
1207 strcpy(buffer, "object");
1208 break;
1209 case cColorFront:
1210 strcpy(buffer, "front");
1211 break;
1212 case cColorBack:
1213 strcpy(buffer, "back");
1214 break;
1215 case -1:
1216 strcpy(buffer, "default");
1217 break;
1218 default:
1219 sptr = ColorGetName(G, color);
1220 if(sptr)
1221 return sptr;
1222 strcpy(buffer, "invalid");
1223 }
1224 }
1225 break;
1226 case cSetting_string:
1227 return SettingGet_s(G, set1, set2, index);
1228 default:
1229 return NULL;
1230 }
1231 return buffer;
1232 }
1233
1234
1235 #ifndef _PYMOL_NOPY
1236 /*========================================================================*/
SettingSetFromTuple(PyMOLGlobals * G,CSetting * I,int index,PyObject * tuple)1237 int SettingSetFromTuple(PyMOLGlobals * G, CSetting * I, int index, PyObject * tuple)
1238 /* must have interpret locked to make this call */
1239 {
1240 PyObject *value;
1241 int type;
1242 int ok = true;
1243 if(!I)
1244 I = G->Setting; /* fall back on global settings */
1245
1246 /* this data structure has been pre-checked at the python level... */
1247
1248 type = PyInt_AsLong(PyTuple_GetItem(tuple, 0));
1249 value = PyTuple_GetItem(tuple, 1);
1250 switch (type) {
1251 case cSetting_boolean:
1252 case cSetting_int:
1253 SettingSet_i(I, index, PyInt_AsLong(value));
1254 break;
1255 case cSetting_float:
1256 SettingSet_f(I, index, (float) PyFloat_AsDouble(value));
1257 break;
1258 case cSetting_float3:
1259 float tmp[3];
1260 PyArg_ParseTuple(value, "fff", tmp, tmp + 1, tmp + 2);
1261 SettingSet_3fv(I, index, tmp);
1262 break;
1263 case cSetting_color:
1264 SettingSet_color(I, index, PyString_AsString(value));
1265 break;
1266 case cSetting_string:
1267 SettingSet_s(I, index, PyString_AsString(value));
1268 break;
1269 default:
1270 ok = false;
1271 break;
1272 }
1273 return (ok);
1274 }
1275 #endif
1276
1277 /*========================================================================*/
SettingStringToTypedValue(PyMOLGlobals * G,int index,const char * st,int * type,int * value)1278 int SettingStringToTypedValue(PyMOLGlobals * G, int index, const char *st, int *type,
1279 int *value)
1280 {
1281 int ok = true;
1282 int newvalue ;
1283 float newfvalue;
1284 /* this data structure has been pre-checked at the python level... */
1285
1286 *type = SettingGetType(G, index);
1287
1288 switch (*type) {
1289 case cSetting_boolean:
1290 if((!*st) || (*st == '0') || (*st == 'F') || WordMatchExact(G, st, "on", true)
1291 || WordMatchExact(G, st, "false", true)){
1292 newvalue = 0;
1293 } else {
1294 newvalue = 1;
1295 }
1296 if (newvalue != *value){
1297 *value = newvalue;
1298 } else {
1299 ok = false;
1300 }
1301 break;
1302 case cSetting_int:
1303 if(sscanf(st, "%d", &newvalue) != 1){
1304 ok = false;
1305 } else if (newvalue!=*value){
1306 *value = newvalue;
1307 } else {
1308 ok = false;
1309 }
1310 break;
1311 case cSetting_float:
1312 if(sscanf(st, "%f", &newfvalue) != 1){
1313 ok = false;
1314 } else if (newfvalue != *((float *) value)){
1315 *(float*)value = newfvalue;
1316 } else {
1317 ok = false;
1318 }
1319 break;
1320 case cSetting_color:
1321 {
1322 int color_index = ColorGetIndex(G, st);
1323 if (*(value) != color_index){
1324 *(value) = color_index;
1325 } else {
1326 ok = false;
1327 }
1328 }
1329 break;
1330 default:
1331 ok = false;
1332 break;
1333 }
1334 return (ok);
1335 }
1336
SettingSetFromString(PyMOLGlobals * G,CSetting * I,int index,const char * st)1337 int SettingSetFromString(PyMOLGlobals * G, CSetting * I, int index, const char *st)
1338 {
1339 int type;
1340 int ok = true;
1341 if(!I)
1342 I = G->Setting; /* fall back on global settings */
1343
1344 /* this data structure has been pre-checked at the python level... */
1345
1346 type = SettingGetType(G, index);
1347
1348 switch (type) {
1349 case cSetting_boolean:
1350 if((!*st) || (*st == '0') || (*st == 'F') || WordMatchExact(G, st, "on", true)
1351 || WordMatchExact(G, st, "false", true))
1352 SettingSet_b(I, index, 0);
1353 else
1354 SettingSet_b(I, index, 1);
1355 break;
1356 case cSetting_int:
1357 {
1358 int tmp;
1359 if(sscanf(st, "%d", &tmp) == 1)
1360 SettingSet_i(I, index, tmp);
1361 else
1362 ok = false;
1363 }
1364 break;
1365 case cSetting_float:
1366 {
1367 float tmp;
1368 if(sscanf(st, "%f", &tmp) == 1)
1369 SettingSet_f(I, index, tmp);
1370 else
1371 ok = false;
1372 }
1373 break;
1374 case cSetting_float3:
1375 {
1376 float tmp[3];
1377 if(sscanf(st, "%f%f%f", tmp, tmp + 1, tmp + 2) == 3)
1378 SettingSet_3fv(I, index, tmp);
1379 else
1380 ok = false;
1381 }
1382 break;
1383 case cSetting_color:
1384 SettingSet_color(I, index, st);
1385 break;
1386 case cSetting_string:
1387 SettingSet_s(I, index, st);
1388 break;
1389 default:
1390 ok = false;
1391 break;
1392 }
1393 return (ok);
1394 }
1395
1396
1397 /*========================================================================*/
1398 #ifndef _PYMOL_NOPY
1399 /*
1400 * Warning: Returns colors as (fff) tuple instead of color index
1401 */
SettingGetPyObject(PyMOLGlobals * G,const CSetting * set1,const CSetting * set2,int index)1402 PyObject *SettingGetPyObject(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index)
1403 { /* assumes blocked python interpeter */
1404 PyObject *result = NULL;
1405 const float *ptr;
1406 int type = SettingGetType(G, index);
1407
1408 switch (type) {
1409 case cSetting_boolean:
1410 result = CPythonVal_New_Boolean(SettingGet_b(G, set1, set2, index));
1411 break;
1412 case cSetting_int:
1413 result = CPythonVal_New_Integer(SettingGet_i(G, set1, set2, index));
1414 break;
1415 case cSetting_float:
1416 result = CPythonVal_New_Float(SettingGet_f(G, set1, set2, index));
1417 break;
1418 case cSetting_float3:
1419 ptr = SettingGet_3fv(G, set1, set2, index);
1420 result = Py_BuildValue("(fff)", pymol::pretty_f2d(ptr[0]),
1421 pymol::pretty_f2d(ptr[1]), pymol::pretty_f2d(ptr[2]));
1422 break;
1423 case cSetting_color:
1424 {
1425 int retcol = SettingGet_color(G, set1, set2, index);
1426 if (retcol > 0){
1427 const float *col;
1428 col = ColorGet(G, retcol);
1429 result = Py_BuildValue("(fff)", col[0], col[1], col[2]);
1430 }
1431 }
1432 break;
1433 case cSetting_string:
1434 result = PyString_FromString(SettingGet_s(G, set1, set2, index));
1435 break;
1436 }
1437 return result;
1438 }
1439
SettingGetTuple(PyMOLGlobals * G,const CSetting * set1,const CSetting * set2,int index)1440 PyObject *SettingGetTuple(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index)
1441 { /* assumes blocked python interpeter */
1442 PyObject *result = NULL;
1443 const float *ptr;
1444 int type = SettingGetType(G, index);
1445
1446 switch (type) {
1447 case cSetting_boolean:
1448 case cSetting_int:
1449 case cSetting_color:
1450 result = Py_BuildValue("ii", type, SettingGet_i(G, set1, set2, index));
1451 break;
1452 case cSetting_float:
1453 result = Py_BuildValue(
1454 "if", type, pymol::pretty_f2d(SettingGet_f(G, set1, set2, index)));
1455 break;
1456 case cSetting_float3:
1457 ptr = SettingGet_3fv(G, set1, set2, index);
1458 result = Py_BuildValue("i(fff)", type, pymol::pretty_f2d(ptr[0]),
1459 pymol::pretty_f2d(ptr[1]), pymol::pretty_f2d(ptr[2]));
1460 break;
1461 case cSetting_string:
1462 result = Py_BuildValue("is", type, SettingGet_s(G, set1, set2, index));
1463 break;
1464 default:
1465 result = PConvAutoNone(Py_None);
1466 break;
1467 }
1468 return result;
1469 }
1470 #endif
1471
1472
1473 /*========================================================================*/
SettingNew(PyMOLGlobals * G)1474 CSetting *SettingNew(PyMOLGlobals * G)
1475 {
1476 OOAlloc(G, CSetting);
1477 SettingInit(G, I);
1478 return (I);
1479 }
1480
1481
1482 /*========================================================================*/
SettingPurge(CSetting * I)1483 void SettingPurge(CSetting * I)
1484 {
1485 if(I) {
1486 // need to free strings
1487 for(int index = 0; index < cSetting_INIT; ++index) {
1488 if (SettingInfo[index].type == cSetting_string) {
1489 I->info[index].delete_s();
1490 }
1491 }
1492
1493 VLAFreeP(I->info);
1494 I->size = 0;
1495 }
1496 }
1497
1498
1499 /*========================================================================*/
SettingFreeP(CSetting * I)1500 void SettingFreeP(CSetting * I)
1501 {
1502 if(I)
1503 SettingPurge(I);
1504 OOFreeP(I);
1505 }
1506
1507
1508 /*========================================================================*/
SettingInit(PyMOLGlobals * G,CSetting * I)1509 void SettingInit(PyMOLGlobals * G, CSetting * I)
1510 {
1511 I->G = G;
1512 I->size = sizeof(int); /* insures offset is never zero, except when undef */
1513 I->info = (SettingRec*) VLAMalloc(cSetting_INIT, sizeof(SettingRec), 5, 1); /* auto-zero */
1514 }
1515
1516
1517 /*========================================================================*/
1518 /*
1519 * Return false if type is numeric and default value is non-zero.
1520 */
SettingIsDefaultZero(int index)1521 bool SettingIsDefaultZero(int index)
1522 {
1523 switch (SettingInfo[index].type) {
1524 case cSetting_boolean:
1525 case cSetting_int:
1526 case cSetting_float:
1527 if (SettingInfo[index].value.i[0] == 0)
1528 return true;
1529 return false;
1530 }
1531
1532 return true;
1533 }
1534
1535
1536 /*========================================================================*/
1537 /*
1538 * Restore the default value from `src` or `SettingInfo`
1539 */
SettingRestoreDefault(CSetting * I,int index,const CSetting * src)1540 void SettingRestoreDefault(CSetting * I, int index, const CSetting * src)
1541 {
1542 // 1) from stored default if provided
1543 if (src) {
1544 UtilCopyMem(I->info + index, src->info + index, sizeof(SettingRec));
1545
1546 // need to properly copy strings
1547 if (SettingInfo[index].type == cSetting_string && src->info[index].str_) {
1548 I->info[index].str_ = new std::string(*src->info[index].str_);
1549 }
1550
1551 return;
1552 }
1553
1554 // 2) from SettingInfo
1555 auto &rec = SettingInfo[index];
1556
1557 switch (rec.type) {
1558 case cSetting_blank:
1559 break;
1560 case cSetting_boolean:
1561 case cSetting_int:
1562 I->info[index].set_i(rec.value.i[0]);
1563 break;
1564 case cSetting_float:
1565 I->info[index].set_f(rec.value.f[0]);
1566 break;
1567 case cSetting_float3:
1568 I->info[index].set_3f(rec.value.f);
1569 break;
1570 case cSetting_string:
1571 I->info[index].delete_s();
1572 break;
1573 case cSetting_color:
1574 SettingSet_color(I, index, rec.value.s);
1575 break;
1576 default:
1577 // coding error
1578 printf(" ERROR: unkown type\n");
1579 };
1580
1581 I->info[index].defined = false;
1582 }
1583
1584
1585 /*========================================================================*/
SettingUnset(CSetting * I,int index)1586 int SettingUnset(CSetting * I, int index)
1587 {
1588 if(I) {
1589 SettingRec *sr = I->info + index;
1590 if (!sr->defined) {
1591 return false;
1592 }
1593 sr->defined = false;
1594 sr->changed = true;
1595 }
1596 return true;
1597 }
1598
1599
1600 /*========================================================================*/
SettingGetType(int index)1601 int SettingGetType(int index)
1602 {
1603 return (SettingInfo[index].type);
1604 }
1605
1606
1607 /*========================================================================*/
1608 template <>
SettingGet(int index,const CSetting * I)1609 int SettingGet<int>(int index, const CSetting * I)
1610 {
1611 PyMOLGlobals *G = I->G;
1612 int result;
1613 switch (SettingInfo[index].type) {
1614 case cSetting_boolean:
1615 case cSetting_int:
1616 case cSetting_color:
1617 result = I->info[index].int_;
1618 break;
1619 case cSetting_float:
1620 result = (int) I->info[index].float_;
1621 break;
1622 default:
1623 PRINTFB(G, FB_Setting, FB_Errors)
1624 "Setting-Error: type read mismatch (int) %d\n", index ENDFB(G);
1625 result = 0;
1626 break;
1627 }
1628 return (result);
1629 }
1630
1631
1632 /*========================================================================*/
1633 template <>
SettingGet(int index,const CSetting * I)1634 bool SettingGet<bool>(int index, const CSetting * I)
1635 {
1636 PyMOLGlobals *G = I->G;
1637 switch (SettingInfo[index].type) {
1638 case cSetting_boolean:
1639 case cSetting_int:
1640 case cSetting_float:
1641 return I->info[index].int_ != 0;
1642 default:
1643 PRINTFB(G, FB_Setting, FB_Errors)
1644 "Setting-Error: type read mismatch (boolean) %d\n", index ENDFB(G);
1645 return false;
1646 }
1647 }
1648
1649
1650 /*========================================================================*/
1651 template <>
SettingGet(int index,const CSetting * I)1652 float SettingGet<float>(int index, const CSetting * I)
1653 {
1654 float result;
1655 PyMOLGlobals *G = I->G;
1656 switch (SettingInfo[index].type) {
1657 case cSetting_color:
1658 PRINTFB(G, FB_Setting, FB_Warnings)
1659 " Setting-Warning: type read mismatch (float/color) %d\n", index ENDFB(G);
1660 case cSetting_boolean:
1661 case cSetting_int:
1662 result = (float) I->info[index].int_;
1663 break;
1664 case cSetting_float:
1665 result = I->info[index].float_;
1666 break;
1667 default:
1668 PRINTFB(G, FB_Setting, FB_Errors)
1669 "Setting-Error: type read mismatch (float) %d\n", index ENDFB(G);
1670 result = 0.0F;
1671 }
1672 return (result);
1673 }
1674
1675
1676 /*========================================================================*/
1677 template <>
SettingGet(int index,const CSetting * I)1678 const char * SettingGet<const char *>(int index, const CSetting * I)
1679 {
1680 const char *result;
1681 PyMOLGlobals *G = I->G;
1682 switch (SettingInfo[index].type) {
1683 case cSetting_string:
1684 if(I->info[index].str_) {
1685 result = I->info[index].str_->c_str();
1686 } else {
1687 result = SettingInfo[index].value.s;
1688 }
1689 break;
1690 default:
1691 PRINTFB(G, FB_Setting, FB_Errors)
1692 "Setting-Error: type read mismatch (string) %d\n", index ENDFB(G);
1693 result = NULL;
1694 }
1695 return (char*) result;
1696 }
1697
1698
1699 /*========================================================================*/
1700 template <>
SettingGet(int index,const CSetting * I)1701 const float * SettingGet<const float *>(int index, const CSetting * I)
1702 {
1703 if (SettingInfo[index].type != cSetting_float3) {
1704 PyMOLGlobals *G = I->G;
1705 PRINTFB(G, FB_Setting, FB_Errors)
1706 " Setting-Error: type read mismatch (float3) %d\n", index ENDFB(G);
1707 return NULL;
1708 }
1709 return I->info[index].float3_;
1710 }
1711
1712
1713 /*========================================================================*/
SettingSet_i(CSetting * I,int index,int value)1714 int SettingSet_i(CSetting * I, int index, int value)
1715 {
1716 int ok = true;
1717 if(I) {
1718 PyMOLGlobals *G = I->G;
1719 {
1720 int setting_type = SettingInfo[index].type;
1721 switch (setting_type) {
1722 case cSetting_boolean:
1723 case cSetting_int:
1724 case cSetting_color:
1725 I->info[index].set_i(value);
1726 break;
1727 case cSetting_float:
1728 I->info[index].set_f((float) value);
1729 break;
1730 default:
1731 PRINTFB(G, FB_Setting, FB_Errors)
1732 "Setting-Error: type set mismatch (integer) %d\n", index ENDFB(G);
1733 ok = false;
1734 }
1735 }
1736 } else {
1737 ok = false;
1738 }
1739 return (ok);
1740 }
1741
1742
1743 /*========================================================================*/
SettingSet_color_from_3f(CSetting * I,int index,const float * vector)1744 static int SettingSet_color_from_3f(CSetting * I, int index, const float * vector)
1745 {
1746 int color_index;
1747 float vals[3];
1748 copy3f(vector, vals);
1749 clamp3f(vals);
1750 color_index = Color3fToInt(I->G, vals);
1751 return SettingSet_i(I, index, color_index);
1752 }
1753
SettingSet_color(CSetting * I,int index,const char * value)1754 int SettingSet_color(CSetting * I, int index, const char *value)
1755 {
1756 int ok = true;
1757 int color_index;
1758 if(I) {
1759 PyMOLGlobals *G = I->G;
1760 color_index = ColorGetIndex(G, value);
1761 if((color_index == -1) && (strcmp(value, "-1") &&
1762 strcmp(value, "-2") &&
1763 strcmp(value, "-3") &&
1764 strcmp(value, "-4") &&
1765 strcmp(value, "-5") && strcmp(value, "default"))) {
1766 float vals[3];
1767 ok = ParseFloat3List(value, vals);
1768 if (ok){
1769 clamp3f(vals);
1770 color_index = cColor_TRGB_Bits |
1771 ((int) (255 * vals[0] + 0.49999F)) << 16 |
1772 ((int) (255 * vals[1] + 0.49999F)) << 8 |
1773 ((int) (255 * vals[2] + 0.49999F));
1774 } else {
1775 PRINTFB(G, FB_Setting, FB_Errors)
1776 "Setting-Error: unknown color '%s'\n", value ENDFB(G);
1777 }
1778 }
1779 if (ok){
1780 SettingSet_i(I, index, color_index);
1781 }
1782 }
1783 return (ok);
1784 }
1785
1786
1787 /*========================================================================*/
SettingSet_f(CSetting * I,int index,float value)1788 int SettingSet_f(CSetting * I, int index, float value)
1789 {
1790 int ok = true;
1791 if(I) {
1792 PyMOLGlobals *G = I->G;
1793 {
1794 int setting_type = SettingInfo[index].type;
1795 switch (setting_type) {
1796 case cSetting_boolean:
1797 case cSetting_int:
1798 case cSetting_color:
1799 I->info[index].set_i((int) value);
1800 break;
1801 case cSetting_float:
1802 I->info[index].set_f(value);
1803 break;
1804 default:
1805 PRINTFB(G, FB_Setting, FB_Errors)
1806 "Setting-Error: type set mismatch (float) %d\n", index ENDFB(G);
1807 ok = false;
1808 }
1809 }
1810 } else {
1811 ok = false;
1812 }
1813 return (ok);
1814 }
1815
1816
1817 /*========================================================================*/
SettingSet_s(CSetting * I,int index,const char * value)1818 int SettingSet_s(CSetting * I, int index, const char *value)
1819 {
1820 int ok = true;
1821 if(I) {
1822 PyMOLGlobals *G = I->G;
1823 {
1824 int setting_type = SettingInfo[index].type;
1825 switch (setting_type) {
1826 case cSetting_string:
1827 I->info[index].set_s(value);
1828 break;
1829 case cSetting_color:
1830 return SettingSet_color(I, index, value);
1831 default:
1832 PRINTFB(G, FB_Setting, FB_Errors)
1833 "Setting-Error: type set mismatch (string) %d\n", index ENDFB(G);
1834 ok = false;
1835 }
1836 }
1837 } else {
1838 ok = false;
1839 }
1840 return (ok);
1841 }
1842
1843
1844 /*========================================================================*/
SettingSet_3fv(CSetting * I,int index,const float * vector)1845 int SettingSet_3fv(CSetting * I, int index, const float *vector)
1846 {
1847 switch (SettingInfo[index].type) {
1848 case cSetting_float3:
1849 I->info[index].set_3f(vector);
1850 return true;
1851 case cSetting_color:
1852 return SettingSet_color_from_3f(I, index, vector);
1853 default:
1854 PyMOLGlobals *G = I->G;
1855 PRINTFB(G, FB_Setting, FB_Errors)
1856 "Setting-Error: type set mismatch (float3) %d\n", index ENDFB(G);
1857 return false;
1858 }
1859 }
1860
1861
1862 /*========================================================================*/
SettingGetIndex(PyMOLGlobals * G,const char * name)1863 int SettingGetIndex(PyMOLGlobals * G, const char *name)
1864 {
1865 OVreturn_word result = get_setting_id(G->PyMOL, name);
1866
1867 if (OVreturn_IS_OK(result))
1868 return result.word;
1869
1870 return -1;
1871 }
1872
1873
1874 /*========================================================================*/
SettingGetName(PyMOLGlobals * G,int index,SettingName name)1875 int SettingGetName(PyMOLGlobals * G, int index, SettingName name)
1876 {
1877 UtilNCopy(name, SettingInfo[index].name, sizeof(SettingName));
1878 return (name[0] != 0);
1879 }
1880
1881 /*========================================================================*/
SettingGetName(int index)1882 const char * SettingGetName(int index)
1883 {
1884 return SettingInfo[index].name;
1885 }
1886
1887 /*========================================================================*/
SettingGenerateSideEffects(PyMOLGlobals * G,int index,const char * sele,int state,int quiet)1888 void SettingGenerateSideEffects(PyMOLGlobals * G, int index, const char *sele, int state, int quiet)
1889 {
1890 const char *inv_sele = (sele && sele[0]) ? sele : cKeywordAll;
1891 auto &rec = SettingInfo[index];
1892
1893 if (rec.level == cSettingLevel_unused) {
1894 const char * name = rec.name;
1895
1896 if (!quiet && name && name[0]){
1897 PRINTFB(G, FB_Setting, FB_Warnings)
1898 " Setting-Warning: '%s' is no longer used\n", name
1899 ENDFB(G);
1900 }
1901
1902 return;
1903 }
1904
1905 // range check for int (global only)
1906 if (rec.type == cSetting_int && rec.hasMinMax() && !(sele && sele[0])) {
1907 int value = SettingGetGlobal_i(G, index);
1908 bool clamped = true;
1909
1910 if (value < rec.value.i[1]) {
1911 value = rec.value.i[1];
1912 } else if (value > rec.value.i[2]) {
1913 value = rec.value.i[2];
1914 } else {
1915 clamped = false;
1916 }
1917
1918 if (clamped) {
1919 PRINTFB(G, FB_Setting, FB_Warnings)
1920 " Setting-Warning: %s range = [%d,%d]; setting to %d.\n",
1921 rec.name, rec.value.i[1], rec.value.i[2], value ENDFB(G);
1922 SettingSetGlobal_i(G, index, value);
1923 }
1924 }
1925
1926 switch (index) {
1927 case cSetting_stereo:
1928 SceneUpdateStereo(G);
1929 G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
1930 break;
1931 case cSetting_pick_surface:
1932 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
1933 SceneInvalidatePicking(G); // right now, when pick_surface is off, wipes each CGO's pickColor array
1934 }
1935 ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
1936 break;
1937 case cSetting_pickable:
1938 ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvAll);
1939 SceneChanged(G);
1940 break;
1941 case cSetting_grid_mode:
1942 if (!SettingGetGlobal_i(G, cSetting_grid_mode))
1943 G->ShaderMgr->ResetUniformSet();
1944 case cSetting_grid_slot:
1945 ExecutiveInvalidateGroups(G, false);
1946 SceneChanged(G);
1947 break;
1948 case cSetting_grid_max:
1949 SceneChanged(G);
1950 break;
1951 case cSetting_defer_builds_mode:
1952 ExecutiveRebuildAll(G);
1953 break;
1954 case cSetting_seq_view:
1955 case cSetting_seq_view_label_spacing:
1956 case cSetting_seq_view_label_mode:
1957 case cSetting_seq_view_label_start:
1958 case cSetting_seq_view_format:
1959 case cSetting_seq_view_color:
1960 case cSetting_seq_view_unaligned_mode:
1961 case cSetting_seq_view_gap_mode:
1962 SeqChanged(G);
1963 break;
1964 case cSetting_seq_view_fill_color:
1965 case cSetting_seq_view_fill_char:
1966 case cSetting_seq_view_label_color:
1967 OrthoDirty(G);
1968 break;
1969 case cSetting_show_frame_rate:
1970 OrthoDirty(G);
1971 break;
1972 case cSetting_group_full_member_names:
1973 case cSetting_group_arrow_prefix:
1974 OrthoDirty(G);
1975 break;
1976 case cSetting_static_singletons:
1977 SeqChanged(G);
1978 break;
1979 case cSetting_seq_view_location:
1980 PParse(G, "cmd.viewport(-1,-1)");
1981 SeqChanged(G);
1982 break;
1983 case cSetting_seq_view_overlay:
1984 PParse(G, "cmd.viewport(-1,-1)");
1985 break;
1986 case cSetting_stereo_mode:
1987 case cSetting_anaglyph_mode:
1988 G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
1989 SceneUpdateStereoMode(G);
1990 OrthoInvalidateDoDraw(G);
1991 OrthoDirty(G);
1992 PyMOL_NeedRedisplay(G->PyMOL);
1993 break;
1994 case cSetting_precomputed_lighting:
1995 G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
1996 case cSetting_light_count:
1997 case cSetting_spec_count:
1998 G->ShaderMgr->Set_Reload_Bits(RELOAD_CALLCOMPUTELIGHTING);
1999 case cSetting_dot_lighting:
2000 case cSetting_mesh_lighting:
2001 case cSetting_cgo_lighting:
2002 case cSetting_field_of_view:
2003 case cSetting_fog_start:
2004 case cSetting_two_sided_lighting:
2005 case cSetting_transparency_global_sort:
2006 case cSetting_dot_normals:
2007 case cSetting_mesh_normals:
2008 SceneInvalidate(G);
2009 break;
2010 case cSetting_spec_power:
2011 if (!quiet){
2012 PRINTFB(G, FB_Setting, FB_Debugging)
2013 "Setting-Details: spec_power is depreciated in PyMOL 1.5. This option will not work in future versions. Please set shininess to set the specular exponent for movable light sources.\n"
2014 ENDFB(G);
2015 }
2016 SceneInvalidate(G);
2017 break;
2018 case cSetting_light:
2019 case cSetting_light2:
2020 case cSetting_light3:
2021 case cSetting_light4:
2022 case cSetting_light5:
2023 case cSetting_light6:
2024 case cSetting_light7:
2025 case cSetting_reflect:
2026 case cSetting_direct:
2027 case cSetting_ambient:
2028 case cSetting_specular:
2029 case cSetting_specular_intensity:
2030 case cSetting_shininess:
2031 case cSetting_spec_reflect:
2032 case cSetting_spec_direct:
2033 case cSetting_spec_direct_power:
2034 case cSetting_power:
2035 case cSetting_reflect_power:
2036 if (SettingGetGlobal_b(G, cSetting_precomputed_lighting))
2037 G->ShaderMgr->Set_Reload_Bits(RELOAD_CALLCOMPUTELIGHTING);
2038 SceneInvalidate(G);
2039 break;
2040 case cSetting_use_display_lists:
2041 case cSetting_simplify_display_lists:
2042 case cSetting_excl_display_lists_shaders:
2043 if (!quiet){
2044 PRINTFB(G, FB_Setting, FB_Debugging)
2045 "Setting-Details: display lists were depreciated in PyMOL 1.7.x. The settings use_display_lists, simplify_display_lists, and excl_display_lists_shaders no longer work.\n"
2046 ENDFB(G);
2047 }
2048 case cSetting_use_geometry_shaders:
2049 if (SettingGetGlobal_i(G, cSetting_use_geometry_shaders) &&
2050 G->ShaderMgr->IsConfigured() && !G->ShaderMgr->GeometryShadersPresent()) {
2051 SettingSet_b(G->Setting, cSetting_use_geometry_shaders, 0);
2052 if (!quiet){
2053 PRINTFB(G, FB_Setting, FB_Warnings)
2054 "Setting-Error: geometry shaders not available\n" ENDFB(G);
2055 }
2056 return;
2057 }
2058
2059 G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
2060 ExecutiveInvalidateRep(G, inv_sele, cRepLabel, cRepInvRep);
2061 {
2062 // check if lines need to be invalidated
2063 bool line_as_cylinders = SettingGetGlobal_b(G, cSetting_use_shaders) &&
2064 SettingGetGlobal_b(G, cSetting_render_as_cylinders) &&
2065 SettingGetGlobal_b(G, cSetting_line_as_cylinders);
2066 if (!line_as_cylinders && !SettingGetGlobal_b(G, cSetting_trilines)){
2067 ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
2068 }
2069 }
2070 break;
2071 case cSetting_shaders_from_disk:
2072 G->ShaderMgr->Set_Reload_Bits(RELOAD_ALL_SHADERS);
2073 SceneInvalidate(G);
2074 break;
2075 case cSetting_use_shaders:
2076 {
2077 short changed = 0;
2078 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2079 if (SettingCheckUseShaders(G->Setting, quiet)){
2080 return;
2081 }
2082 }
2083 SceneInvalidate(G);
2084 if (SettingGetGlobal_b(G, cSetting_sphere_use_shader)){
2085 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2086 changed = 1;
2087 }
2088 if (SettingGetGlobal_b(G, cSetting_ribbon_use_shader)){
2089 ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
2090 changed = 1;
2091 }
2092 if (SettingGetGlobal_b(G, cSetting_nonbonded_use_shader)){
2093 ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
2094 changed = 1;
2095 }
2096 if (SettingGetGlobal_i(G, cSetting_nb_spheres_use_shader)){
2097 changed = 1;
2098 }
2099 if (SettingGetGlobal_b(G, cSetting_dash_use_shader)){
2100 ExecutiveInvalidateRep(G, inv_sele, cRepAngle, cRepInvRep);
2101 ExecutiveInvalidateRep(G, inv_sele, cRepDihedral, cRepInvRep);
2102 ExecutiveInvalidateRep(G, inv_sele, cRepDash, cRepInvRep);
2103 changed = 1;
2104 }
2105 if (SettingGetGlobal_b(G, cSetting_line_use_shader)){
2106 ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
2107 changed = 1;
2108 }
2109 if (SettingGetGlobal_b(G, cSetting_cartoon_use_shader)){
2110 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2111 changed = 1;
2112 }
2113 if (SettingGetGlobal_b(G, cSetting_cgo_use_shader) ||
2114 SettingGetGlobal_b(G, cSetting_stick_as_cylinders)){
2115 ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
2116 changed = 1;
2117 }
2118 if (SettingGetGlobal_b(G, cSetting_stick_use_shader) ||
2119 SettingGetGlobal_b(G, cSetting_stick_as_cylinders) ||
2120 (SettingGetGlobal_b(G, cSetting_stick_ball) &&
2121 SettingGetGlobal_b(G, cSetting_valence))){
2122 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2123 changed = 1;
2124 }
2125 if (SettingGetGlobal_b(G, cSetting_surface_use_shader) ||
2126 SettingGetGlobal_b(G, cSetting_dot_use_shader) ||
2127 SettingGetGlobal_b(G, cSetting_mesh_use_shader)){
2128 changed = 1;
2129 }
2130 if (changed){
2131 SceneChanged(G);
2132 }
2133 }
2134 break;
2135 case cSetting_stereo_shift:
2136 case cSetting_stereo_angle:
2137 case cSetting_stereo_dynamic_strength:
2138 SceneInvalidate(G);
2139 break;
2140 case cSetting_scene_buttons:
2141 case cSetting_scene_buttons_mode:
2142 SceneInvalidate(G);
2143 OrthoInvalidateDoDraw(G);
2144 break;
2145 case cSetting_dash_round_ends:
2146 case cSetting_dash_color:
2147 if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_dash_use_shader)){
2148 ExecutiveInvalidateRep(G, "all", cRepDash, cRepInvRep);
2149 }
2150 SceneInvalidate(G);
2151 break;
2152 case cSetting_angle_color:
2153 if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_dash_use_shader)){
2154 ExecutiveInvalidateRep(G, "all", cRepAngle, cRepInvRep);
2155 }
2156 SceneInvalidate(G);
2157 break;
2158 case cSetting_dihedral_color:
2159 if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_dash_use_shader)){
2160 ExecutiveInvalidateRep(G, "all", cRepDihedral, cRepInvRep);
2161 }
2162 SceneInvalidate(G);
2163 break;
2164 case cSetting_mouse_selection_mode:
2165 OrthoDirty(G);
2166 break;
2167 case cSetting_internal_gui_control_size:
2168 WizardRefresh(G);
2169 OrthoDirty(G);
2170 break;
2171 case cSetting_hide_underscore_names:
2172 ExecutiveInvalidateGroups(G, false);
2173 OrthoDirty(G);
2174 break;
2175 case cSetting_gradient_spacing:
2176 case cSetting_gradient_max_length:
2177 case cSetting_gradient_min_length:
2178 case cSetting_gradient_normal_min_dot:
2179 case cSetting_gradient_step_size:
2180 case cSetting_gradient_min_slope:
2181 case cSetting_gradient_symmetry:
2182 ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvRep);
2183 SceneChanged(G);
2184 break;
2185 case cSetting_min_mesh_spacing:
2186 case cSetting_mesh_grid_max:
2187 case cSetting_mesh_cutoff:
2188 case cSetting_mesh_carve_state:
2189 case cSetting_mesh_carve_cutoff:
2190 case cSetting_mesh_carve_selection:
2191 case cSetting_mesh_clear_state:
2192 case cSetting_mesh_clear_cutoff:
2193 case cSetting_mesh_clear_selection:
2194 case cSetting_mesh_mode:
2195 case cSetting_mesh_type:
2196 case cSetting_mesh_solvent:
2197 case cSetting_mesh_quality:
2198 case cSetting_mesh_skip:
2199 ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvRep);
2200 SceneChanged(G);
2201 break;
2202 case cSetting_valence:
2203 case cSetting_valence_mode:
2204 case cSetting_valence_size:
2205 case cSetting_valence_zero_mode:
2206 case cSetting_valence_zero_scale:
2207 case cSetting_half_bonds:
2208 case cSetting_line_stick_helper:
2209 case cSetting_hide_long_bonds:
2210 ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
2211 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2212 SceneChanged(G);
2213 break;
2214 case cSetting_stick_transparency:
2215 case cSetting_stick_debug:
2216 case cSetting_stick_round_nub:
2217 case cSetting_stick_as_cylinders:
2218 case cSetting_stick_good_geometry:
2219 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2220 SceneChanged(G);
2221 break;
2222 case cSetting_line_use_shader:
2223 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2224 ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
2225 SceneChanged(G);
2226 }
2227 break;
2228 case cSetting_ribbon_use_shader:
2229 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2230 ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
2231 SceneChanged(G);
2232 }
2233 break;
2234 case cSetting_dot_as_spheres:
2235 SceneInvalidate(G);
2236 SceneChanged(G);
2237 break;
2238 case cSetting_dot_use_shader:
2239 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2240 ExecutiveInvalidateRep(G, inv_sele, cRepDot, cRepInvRep);
2241 SceneChanged(G);
2242 }
2243 break;
2244 case cSetting_nonbonded_use_shader:
2245 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2246 ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
2247 SceneChanged(G);
2248 }
2249 break;
2250 case cSetting_nb_spheres_size:
2251 ExecutiveInvalidateRep(G, inv_sele, cRepNonbondedSphere, cRepInvRep);
2252 SceneChanged(G);
2253 break;
2254 case cSetting_nb_spheres_use_shader:
2255 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2256 SceneChanged(G);
2257 }
2258 break;
2259 case cSetting_render_as_cylinders:
2260 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2261 case cSetting_mesh_as_cylinders:
2262 case cSetting_line_as_cylinders:
2263 case cSetting_ribbon_as_cylinders:
2264 case cSetting_dash_as_cylinders:
2265 if (index == cSetting_dash_as_cylinders) {
2266 ExecutiveInvalidateRep(G, inv_sele, cRepAngle, cRepInvRep);
2267 ExecutiveInvalidateRep(G, inv_sele, cRepDihedral, cRepInvRep);
2268 ExecutiveInvalidateRep(G, inv_sele, cRepDash, cRepInvRep);
2269 }
2270 case cSetting_nonbonded_as_cylinders:
2271 case cSetting_alignment_as_cylinders:
2272 case cSetting_cartoon_nucleic_acid_as_cylinders:
2273 if (SettingGetGlobal_b(G, cSetting_render_as_cylinders)){
2274 if (G->ShaderMgr->shaders_present && !G->ShaderMgr->ShaderPrgExists("cylinder")){
2275 SettingSet_b(G->Setting, cSetting_render_as_cylinders, 0);
2276 if (!quiet){
2277 PRINTFB(G, FB_Setting, FB_Warnings)
2278 "Setting-Error: render_as_cylinders cannot be set when the Cylinder Shader is not available, setting render_as_cylinder back to false\n"
2279 ENDFB(G);
2280 }
2281 return;
2282 }
2283 switch (index){
2284 case cSetting_render_as_cylinders:
2285 case cSetting_cartoon_nucleic_acid_as_cylinders:
2286 case cSetting_use_shaders:
2287 if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_render_as_cylinders)){
2288 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2289 }
2290 }
2291 SceneChanged(G);
2292 }
2293 break;
2294 case cSetting_mesh_use_shader:
2295 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2296 SceneChanged(G);
2297 }
2298 break;
2299 case cSetting_slice_height_scale:
2300 case cSetting_slice_height_map:
2301 case cSetting_slice_grid:
2302 case cSetting_slice_dynamic_grid:
2303 case cSetting_slice_dynamic_grid_resolution:
2304 ExecutiveInvalidateRep(G, inv_sele, cRepSlice, cRepInvRep);
2305 SceneChanged(G);
2306 break;
2307 case cSetting_label_font_id:
2308 case cSetting_label_size:
2309 ExecutiveInvalidateRep(G, inv_sele, cRepLabel, cRepInvRep);
2310 SceneChanged(G);
2311 break;
2312 case cSetting_retain_order:
2313 case cSetting_pdb_hetatm_sort:
2314 case cSetting_pdb_insertions_go_first:
2315 ExecutiveSort(G, inv_sele);
2316 break;
2317 case cSetting_roving_lines:
2318 case cSetting_roving_sticks:
2319 case cSetting_roving_spheres:
2320 case cSetting_roving_labels:
2321 case cSetting_roving_selection:
2322 case cSetting_roving_ribbon:
2323 case cSetting_roving_cartoon:
2324 case cSetting_roving_polar_contacts:
2325 case cSetting_roving_polar_cutoff:
2326 case cSetting_roving_nonbonded:
2327 case cSetting_roving_nb_spheres:
2328 case cSetting_roving_map1_level:
2329 case cSetting_roving_map2_level:
2330 case cSetting_roving_map3_level:
2331 case cSetting_roving_map1_name:
2332 case cSetting_roving_map2_name:
2333 case cSetting_roving_map3_name:
2334 case cSetting_roving_isosurface:
2335 case cSetting_roving_isomesh:
2336 SceneRovingChanged(G);
2337 break;
2338 case cSetting_roving_byres:
2339 case cSetting_roving_detail:
2340 SceneRovingDirty(G);
2341 break;
2342 case cSetting_dash_transparency:
2343 case cSetting_dash_length:
2344 case cSetting_dash_gap:
2345 case cSetting_dash_radius:
2346 case cSetting_dash_width:
2347 case cSetting_angle_size:
2348 case cSetting_label_digits:
2349 case cSetting_label_distance_digits:
2350 case cSetting_label_angle_digits:
2351 case cSetting_label_dihedral_digits:
2352 case cSetting_angle_label_position:
2353 case cSetting_dihedral_size:
2354 case cSetting_dihedral_label_position:
2355 ExecutiveRebuildAllObjectDist(G);
2356 SceneChanged(G);
2357 break;
2358 case cSetting_button_mode:
2359 EditorMouseInvalid(G);
2360 OrthoDirty(G);
2361 break;
2362 case cSetting_stick_radius:
2363 case cSetting_stick_h_scale:
2364 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2365 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep); /* base width */
2366 SceneChanged(G);
2367 break;
2368 case cSetting_nb_spheres_quality:
2369 {
2370 ExecutiveInvalidateRep(G, inv_sele, cRepNonbondedSphere, cRepInvRep);
2371 SceneChanged(G);
2372 }
2373 case cSetting_cgo_sphere_quality:
2374 case cSetting_cgo_debug:
2375 {
2376 ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
2377 SceneChanged(G);
2378 break;
2379 }
2380 case cSetting_stick_quality:
2381 case cSetting_stick_ball:
2382 case cSetting_stick_nub:
2383 case cSetting_stick_ball_ratio:
2384 case cSetting_stick_ball_color:
2385 case cSetting_stick_fixed_radius:
2386 case cSetting_stick_valence_scale:
2387 case cSetting_stick_overlap:
2388 case cSetting_stick_color:
2389 case cSetting_stick_use_shader:
2390 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2391 SceneChanged(G);
2392 break;
2393 case cSetting_clamp_colors:
2394 case cSetting_ramp_blend_nearby_colors:
2395 ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
2396 SceneChanged(G);
2397 break;
2398 case cSetting_label_color:
2399 case cSetting_label_outline_color:
2400 case cSetting_label_position:
2401 ExecutiveRebuildAllObjectDist(G);
2402 ExecutiveInvalidateRep(G, inv_sele, cRepLabel, cRepInvRep);
2403 SceneChanged(G);
2404 break;
2405 case cSetting_cartoon_color:
2406 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2407 SceneChanged(G);
2408 break;
2409 case cSetting_ribbon_color:
2410 ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
2411 SceneChanged(G);
2412 break;
2413 case cSetting_cgo_line_width:
2414 case cSetting_line_width:
2415 {
2416 GLfloat *range = G->ShaderMgr->GetLineWidthRange();
2417 float line_width = SettingGetGlobal_f(G, index);
2418 {
2419 if (line_width <= 0.f){
2420 PRINTFB(G, FB_Setting, FB_Warnings)
2421 " Setting-Warning: %s is set incorrectly (%f), setting to 1\n",
2422 rec.name, line_width ENDFB(G);
2423 SettingSetGlobal_f(G, index, 1.f);
2424 } else if (G->HaveGUI && range[1] > 0.f && line_width > range[1]) {
2425 PRINTFB(G, FB_Setting, FB_Warnings)
2426 " Setting-Warning: %s is out of range of the graphics card's "
2427 "capability (range: %f-%f), lines might not be rendered correctly\n",
2428 rec.name, range[0], range[1] ENDFB(G);
2429 }
2430 }
2431 }
2432 case cSetting_line_color:
2433 case cSetting_line_radius:
2434 ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
2435 ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
2436 SceneChanged(G);
2437 break;
2438 case cSetting_scenes_changed:
2439 {
2440 int scene_buttons = SettingGetGlobal_i(G, cSetting_scene_buttons);
2441 if (scene_buttons)
2442 OrthoInvalidateDoDraw(G);
2443 }
2444 break;
2445 case cSetting_button_mode_name:
2446 {
2447 int internal_gui_mode = SettingGetGlobal_i(G, cSetting_internal_gui_mode);
2448 if (internal_gui_mode){
2449 OrthoInvalidateDoDraw(G);
2450 }
2451 }
2452 break;
2453 case cSetting_scene_current_name:
2454 SceneRestartFrameTimer(G);
2455 break;
2456 case cSetting_mesh_width:
2457 ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvColor);
2458 SceneChanged(G);
2459 break;
2460 case cSetting_ellipsoid_probability:
2461 case cSetting_ellipsoid_scale:
2462 case cSetting_ellipsoid_color:
2463 case cSetting_ellipsoid_transparency:
2464 ExecutiveInvalidateRep(G, inv_sele, cRepEllipsoid, cRepInvRep);
2465 SceneChanged(G);
2466 break;
2467 case cSetting_ellipsoid_quality:
2468 case cSetting_cgo_ellipsoid_quality:
2469 ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
2470 ExecutiveInvalidateRep(G, inv_sele, cRepEllipsoid, cRepInvRep);
2471 SceneChanged(G);
2472 break;
2473 case cSetting_mesh_color:
2474 case cSetting_mesh_negative_color:
2475 ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvColor);
2476 SceneChanged(G);
2477 break;
2478 case cSetting_ray_color_ramps:
2479 ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
2480 SceneChanged(G);
2481 break;
2482 case cSetting_sphere_mode:
2483 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2484 SceneInvalidate(G);
2485 break;
2486 case cSetting_cull_spheres:
2487 case cSetting_sphere_scale:
2488 case cSetting_sphere_transparency:
2489 case cSetting_sphere_solvent:
2490 case cSetting_sphere_point_max_size:
2491 case cSetting_sphere_point_size:
2492 case cSetting_sphere_use_shader:
2493 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2494 SceneInvalidate(G);
2495 break;
2496 case cSetting_sphere_quality:
2497 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2498 ExecutiveInvalidateRep(G, inv_sele, cRepNonbondedSphere, cRepInvRep);
2499 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2500 SceneChanged(G);
2501 break;
2502 case cSetting_nonbonded_size:
2503 case cSetting_nonbonded_transparency:
2504 ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
2505 ExecutiveInvalidateRep(G, inv_sele, cRepNonbondedSphere, cRepInvRep);
2506 SceneChanged(G);
2507 break;
2508 case cSetting_mesh_radius:
2509 ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvColor);
2510 SceneChanged(G);
2511 break;
2512 case cSetting_ambient_occlusion_scale:
2513 SceneChanged(G);
2514 break;
2515 case cSetting_ambient_occlusion_mode:
2516 ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
2517 switch (SettingGetGlobal_i(G, cSetting_ambient_occlusion_mode) % 4){
2518 case 1:
2519 SettingSetGlobal_i(G, cSetting_ambient_occlusion_smooth, 10);
2520 SettingSetGlobal_f(G, cSetting_ambient_occlusion_scale, 25.f);
2521 break;
2522 case 2:
2523 SettingSetGlobal_i(G, cSetting_ambient_occlusion_smooth, 5);
2524 SettingSetGlobal_f(G, cSetting_ambient_occlusion_scale, .9f);
2525 break;
2526 case 3:
2527 SettingSetGlobal_i(G, cSetting_ambient_occlusion_smooth, 5);
2528 SettingSetGlobal_f(G, cSetting_ambient_occlusion_scale, 1.1f);
2529 break;
2530 }
2531 SceneChanged(G);
2532 break;
2533 case cSetting_ambient_occlusion_smooth:
2534 case cSetting_surface_negative_color:
2535 case cSetting_surface_color:
2536 case cSetting_surface_ramp_above_mode:
2537 case cSetting_transparency:
2538 ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
2539 SceneChanged(G);
2540 break;
2541 case cSetting_dot_color:
2542 ExecutiveInvalidateRep(G, inv_sele, cRepDot, cRepInvColor);
2543 SceneChanged(G);
2544 break;
2545 case cSetting_sphere_color:
2546 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvColor);
2547 SceneChanged(G);
2548 break;
2549
2550 case cSetting_surface_quality:
2551 case cSetting_surface_mode:
2552 case cSetting_surface_normal:
2553 case cSetting_surface_type:
2554 case cSetting_surface_carve_state:
2555 case cSetting_surface_carve_cutoff:
2556 case cSetting_surface_carve_selection:
2557 case cSetting_surface_carve_normal_cutoff:
2558 case cSetting_surface_clear_state:
2559 case cSetting_surface_clear_cutoff:
2560 case cSetting_surface_clear_selection:
2561 case cSetting_surface_trim_cutoff:
2562 case cSetting_surface_trim_factor:
2563 case cSetting_surface_circumscribe:
2564 case cSetting_surface_solvent:
2565 case cSetting_surface_proximity:
2566 case cSetting_surface_cavity_mode:
2567 case cSetting_surface_cavity_radius:
2568 case cSetting_surface_cavity_cutoff:
2569 case cSetting_cavity_cull:
2570 case cSetting_surface_smooth_edges:
2571 ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvRep);
2572 SceneChanged(G);
2573 break;
2574 case cSetting_surface_use_shader:
2575 SceneChanged(G);
2576 break;
2577 case cSetting_surface_negative_visible:
2578 ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvRep);
2579 SceneChanged(G);
2580 break;
2581 case cSetting_mesh_negative_visible:
2582 ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvAll);
2583 SceneChanged(G);
2584 break;
2585 case cSetting_solvent_radius:
2586 ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvRep);
2587 ExecutiveInvalidateRep(G, inv_sele, cRepMesh, cRepInvRep);
2588 ExecutiveInvalidateRep(G, inv_sele, cRepDot, cRepInvRep);
2589 SceneChanged(G);
2590 break;
2591 case cSetting_trace_atoms_mode:
2592 ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
2593 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2594 SceneChanged(G);
2595 break;
2596 case cSetting_ribbon_smooth:
2597 case cSetting_ribbon_power:
2598 case cSetting_ribbon_power_b:
2599 case cSetting_ribbon_sampling:
2600 case cSetting_ribbon_radius:
2601 case cSetting_ribbon_width:
2602 case cSetting_ribbon_throw:
2603 case cSetting_ribbon_trace_atoms:
2604 case cSetting_ribbon_transparency:
2605 ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
2606 SceneChanged(G);
2607 break;
2608 case cSetting_draw_mode:
2609 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2610 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2611 break;
2612 case cSetting_cartoon_side_chain_helper:
2613 case cSetting_cartoon_nucleic_acid_mode:
2614 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2615 ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
2616 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2617 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2618 ExecutiveInvalidateRep(G, inv_sele, cRepEllipsoid, cRepInvRep);
2619 SceneChanged(G);
2620 break;
2621 case cSetting_ribbon_side_chain_helper:
2622 case cSetting_ribbon_nucleic_acid_mode:
2623 ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
2624 ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
2625 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2626 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2627 ExecutiveInvalidateRep(G, inv_sele, cRepEllipsoid, cRepInvRep);
2628 SceneChanged(G);
2629 break;
2630 case cSetting_ray_trace_mode: /* affects loop quality */
2631 G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
2632 case cSetting_cartoon_transparency:
2633 case cSetting_cartoon_ring_transparency:
2634 case cSetting_cartoon_trace_atoms:
2635 case cSetting_cartoon_refine:
2636 case cSetting_cartoon_nucleic_acid_color:
2637 case cSetting_cartoon_ring_mode:
2638 case cSetting_cartoon_ring_finder:
2639 case cSetting_cartoon_ring_width:
2640 case cSetting_cartoon_ring_color:
2641 case cSetting_cartoon_ladder_mode:
2642 case cSetting_cartoon_ladder_radius:
2643 case cSetting_cartoon_ladder_color:
2644 case cSetting_cartoon_sampling:
2645 case cSetting_cartoon_loop_quality:
2646 case cSetting_cartoon_loop_radius:
2647 case cSetting_cartoon_loop_cap:
2648 case cSetting_cartoon_tube_quality:
2649 case cSetting_cartoon_tube_radius:
2650 case cSetting_cartoon_tube_cap:
2651 case cSetting_cartoon_putty_quality:
2652 case cSetting_cartoon_putty_radius:
2653 case cSetting_cartoon_putty_range:
2654 case cSetting_cartoon_putty_scale_min:
2655 case cSetting_cartoon_putty_scale_max:
2656 case cSetting_cartoon_putty_scale_power:
2657 case cSetting_cartoon_putty_transform:
2658 case cSetting_cartoon_power:
2659 case cSetting_cartoon_power_b:
2660 case cSetting_cartoon_ring_radius:
2661 case cSetting_cartoon_rect_length:
2662 case cSetting_cartoon_rect_width:
2663 case cSetting_cartoon_oval_length:
2664 case cSetting_cartoon_oval_width:
2665 case cSetting_cartoon_oval_quality:
2666 case cSetting_cartoon_round_helices:
2667 case cSetting_cartoon_flat_sheets:
2668 case cSetting_cartoon_refine_normals:
2669 case cSetting_cartoon_smooth_loops:
2670 case cSetting_cartoon_dumbbell_width:
2671 case cSetting_cartoon_dumbbell_length:
2672 case cSetting_cartoon_dumbbell_radius:
2673 case cSetting_cartoon_fancy_helices:
2674 case cSetting_cartoon_fancy_sheets:
2675 case cSetting_cartoon_cylindrical_helices:
2676 case cSetting_cartoon_refine_tips:
2677 case cSetting_cartoon_helix_radius:
2678 case cSetting_cartoon_throw:
2679 case cSetting_cartoon_debug:
2680 case cSetting_cartoon_highlight_color:
2681 case cSetting_cartoon_discrete_colors:
2682 case cSetting_cartoon_smooth_first:
2683 case cSetting_cartoon_smooth_last:
2684 case cSetting_cartoon_smooth_cycles:
2685 case cSetting_cartoon_flat_cycles:
2686 case cSetting_cartoon_gap_cutoff:
2687 case cSetting_cartoon_all_alt:
2688 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2689 SceneChanged(G);
2690 break;
2691 case cSetting_cartoon_use_shader:
2692 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2693 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2694 SceneChanged(G);
2695 }
2696 break;
2697 case cSetting_cgo_use_shader:
2698 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2699 ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
2700 SceneChanged(G);
2701 }
2702 break;
2703 case cSetting_cgo_shader_ub_flags:
2704 if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_cgo_use_shader)){
2705 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2706 SceneChanged(G);
2707 }
2708 break;
2709 case cSetting_cgo_shader_ub_color:
2710 if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_cgo_use_shader)){
2711 ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
2712 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2713 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2714 SceneChanged(G);
2715 }
2716 break;
2717 case cSetting_cgo_shader_ub_normal:
2718 if (SettingGetGlobal_b(G, cSetting_use_shaders) && SettingGetGlobal_b(G, cSetting_cgo_use_shader)){
2719 ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvRep);
2720 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2721 // if spheres rendered with geometry, then normals are used
2722 // this should really only invalidate spheres that use normals (sphere_mode=0, not sure about other modes)
2723 // but invalidating all spheres for now
2724 ExecutiveInvalidateRep(G, inv_sele, cRepSphere, cRepInvRep);
2725 SceneChanged(G);
2726 }
2727 break;
2728 case cSetting_trilines:
2729 ExecutiveInvalidateRep(G, inv_sele, cRepLine, cRepInvRep);
2730 ExecutiveInvalidateRep(G, inv_sele, cRepCyl, cRepInvRep);
2731 ExecutiveInvalidateRep(G, inv_sele, cRepRibbon, cRepInvRep);
2732 ExecutiveInvalidateRep(G, inv_sele, cRepCartoon, cRepInvRep);
2733 ExecutiveInvalidateRep(G, inv_sele, cRepDash, cRepInvRep);
2734 ExecutiveInvalidateRep(G, inv_sele, cRepNonbonded, cRepInvRep);
2735 SceneChanged(G);
2736 break;
2737 case cSetting_dot_width:
2738 case cSetting_dot_radius:
2739 case cSetting_dot_density:
2740 case cSetting_dot_mode:
2741 case cSetting_dot_solvent:
2742 case cSetting_dot_hydrogens:
2743 case cSetting_trim_dots:
2744 ExecutiveInvalidateRep(G, inv_sele, cRepDot, cRepInvRep);
2745 SceneChanged(G);
2746 break;
2747 case cSetting_bg_gradient:
2748 ColorUpdateFrontFromSettings(G);
2749 ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
2750 G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
2751 SceneChanged(G);
2752 break;
2753 case cSetting_bg_image_mode:
2754 case cSetting_bg_image_filename:
2755 G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
2756 case cSetting_bg_image_linear:
2757 case cSetting_bg_image_tilesize:
2758 OrthoBackgroundTextureNeedsUpdate(G);
2759 SceneChanged(G);
2760 break;
2761 case cSetting_bg_rgb_top:
2762 case cSetting_bg_rgb_bottom:
2763 {
2764 /* clamp this value */
2765 const char * bg_image_filename = SettingGet_s(G, NULL, NULL, cSetting_bg_image_filename);
2766 if(!(bg_image_filename && bg_image_filename[0]) &&
2767 SettingGetGlobal_b(G, cSetting_bg_gradient) && !OrthoBackgroundDataIsSet(*G->Ortho)) {
2768 ColorUpdateFrontFromSettings(G);
2769 ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
2770 OrthoBackgroundTextureNeedsUpdate(G);
2771 }
2772 }
2773 SceneChanged(G);
2774 break;
2775 case cSetting_bg_rgb:
2776 {
2777 /* clamp this value */
2778 const float *v = ColorGet(G, SettingGet_color(G, NULL, NULL, cSetting_bg_rgb));
2779 {
2780 const char * bg_image_filename = SettingGet_s(G, NULL, NULL, cSetting_bg_image_filename);
2781 if(!(bg_image_filename && bg_image_filename[0]) && !OrthoBackgroundDataIsSet(*G->Ortho)) {
2782 ColorUpdateFront(G, v);
2783 ExecutiveInvalidateRep(G, inv_sele, cRepAll, cRepInvColor);
2784 }
2785 }
2786 }
2787 SceneChanged(G);
2788 break;
2789 case cSetting_selection_width:
2790 case cSetting_selection_width_scale:
2791 case cSetting_selection_width_max:
2792 case cSetting_selection_round_points:
2793 ExecutiveInvalidateSelectionIndicatorsCGO(G);
2794 case cSetting_line_smooth:
2795 case cSetting_ortho:
2796 case cSetting_chromadepth:
2797 case cSetting_transparency_mode:
2798 if (index == cSetting_transparency_mode)
2799 #ifdef _WEBGL
2800 #endif
2801 ExecutiveInvalidateRep(G, inv_sele, cRepCGO, cRepInvAll);
2802 case cSetting_depth_cue:
2803 case cSetting_fog:
2804 case cSetting_ray_transparency_oblique:
2805 G->ShaderMgr->Set_Reload_Bits(RELOAD_VARIABLES);
2806 case cSetting_ray_transparency_oblique_power:
2807 SceneInvalidate(G);
2808 break;
2809 case cSetting_sculpting:
2810 OrthoDirty(G);
2811 break;
2812 case cSetting_auto_overlay:
2813 OrthoRemoveAutoOverlay(G); /* always start clean */
2814 break;
2815 case cSetting_overlay:
2816 case cSetting_overlay_lines:
2817 case cSetting_text:
2818 OrthoDirty(G);
2819 break;
2820 case cSetting_internal_gui_mode:
2821 case cSetting_internal_gui_width:
2822 case cSetting_internal_gui:
2823 case cSetting_internal_feedback:
2824 case cSetting_mouse_grid:
2825 case cSetting_movie_panel_row_height:
2826 case cSetting_movie_panel:
2827 if(!SettingGetGlobal_b(G, cSetting_suspend_updates)) {
2828 OrthoCommandIn(G, "viewport");
2829 }
2830 break;
2831 case cSetting_suspend_updates:
2832 if(!SettingGetGlobal_b(G, cSetting_suspend_updates)) {
2833 SceneChanged(G); /* force big update upon resumption */
2834 OrthoDirty(G);
2835 }
2836 break;
2837 case cSetting_security:
2838 G->Security = SettingGetGlobal_i(G, cSetting_security);
2839 break;
2840 case cSetting_state:
2841 if (SettingGet<int>(G, index) < 0 /* all */) {
2842 PRINTFB(G, FB_Setting, FB_Warnings)
2843 " Setting-Warning: state can't be less than 0.\n" ENDFB(G);
2844 }
2845 case cSetting_all_states:
2846 case cSetting_frame:
2847 ExecutiveInvalidateSelectionIndicatorsCGO(G);
2848 SceneInvalidatePicking(G);
2849 SceneChanged(G);
2850 break;
2851 case cSetting_dynamic_width:
2852 case cSetting_dynamic_width_factor:
2853 case cSetting_dynamic_width_min:
2854 case cSetting_dynamic_width_max:
2855 SceneChanged(G);
2856 break;
2857 case cSetting_rock:
2858 case cSetting_sweep_mode:
2859 case cSetting_sweep_phase:
2860 case cSetting_sweep_angle:
2861 case cSetting_sweep_speed:
2862 SceneRestartSweepTimer(G);
2863 break;
2864 case cSetting_motion_power:
2865 case cSetting_motion_bias:
2866 case cSetting_motion_simple:
2867 case cSetting_motion_linear:
2868 case cSetting_motion_hand:
2869 case cSetting_movie_loop:
2870 if(SettingGetGlobal_b(G, cSetting_movie_auto_interpolate)) {
2871 ExecutiveMotionReinterpolate(G);
2872 }
2873 break;
2874 case cSetting_volume_bit_depth:
2875 ExecutiveInvalidateRep(G, inv_sele, cRepVolume, cRepInvAll);
2876 SceneInvalidate(G);
2877 break;
2878 case cSetting_volume_layers:
2879 ExecutiveInvalidateRep(G, inv_sele, cRepVolume, cRepInvColor);
2880 SceneInvalidate(G);
2881 break;
2882 case cSetting_cgo_transparency:
2883 SceneInvalidate(G);
2884 SceneChanged(G);
2885 break;
2886 case cSetting_label_connector_mode:
2887 {
2888 int lc_mode = SettingGetGlobal_i(G, cSetting_label_connector_mode);
2889 if(lc_mode < 0 || lc_mode > 4){
2890 if (!quiet){
2891 PRINTFB(G, FB_Setting, FB_Warnings)
2892 "Setting-Warning: label_connector_mode range = [0,4]"
2893 ENDFB(G);
2894 }
2895 }
2896 }
2897 case cSetting_float_labels:
2898 case cSetting_label_z_target:
2899 case cSetting_label_connector:
2900 case cSetting_label_connector_color:
2901 case cSetting_label_connector_width:
2902 case cSetting_label_connector_ext_length:
2903 case cSetting_label_bg_color:
2904 case cSetting_label_placement_offset:
2905 case cSetting_label_relative_mode:
2906 case cSetting_label_screen_point:
2907 case cSetting_label_multiline_spacing:
2908 case cSetting_label_multiline_justification:
2909 case cSetting_label_padding:
2910 case cSetting_label_bg_transparency:
2911 case cSetting_label_bg_outline:
2912 case cSetting_ray_label_connector_flat:
2913 ExecutiveInvalidateRep(G, inv_sele, cRepLabel, cRepInvAll );
2914 break;
2915 case cSetting_surface_color_smoothing:
2916 case cSetting_surface_color_smoothing_threshold:
2917 ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
2918 SceneChanged(G);
2919 break;
2920 case cSetting_smooth_half_bonds:
2921 SceneChanged(G);
2922 break;
2923 case cSetting_antialias_shader:
2924 case cSetting_atom_type_format:
2925 case cSetting_colored_feedback:
2926 case cSetting_load_atom_props_default:
2927 case cSetting_load_object_props_default:
2928 case cSetting_suspend_undo:
2929 case cSetting_volume_mode:
2930 PRINTFB(G, FB_Setting, FB_Warnings)
2931 " Setting-Warning: %s is not supported in Open-Source version of PyMOL\n",
2932 SettingInfo[index].name
2933 ENDFB(G);
2934 break;
2935 break;
2936 case cSetting_surface_debug:
2937 if (SettingGetGlobal_b(G, cSetting_use_shaders)){
2938 ExecutiveInvalidateRep(G, inv_sele, cRepSurface, cRepInvColor);
2939 }
2940 break;
2941 case cSetting_pick32bit:
2942 SceneInvalidatePicking(G);
2943 break;
2944 case cSetting_display_scale_factor:
2945 {
2946 int scaleFactor = SettingGetGlobal_i(G, cSetting_display_scale_factor);
2947 if (scaleFactor > 0) {
2948 _gScaleFactor = scaleFactor;
2949 ExecutiveInvalidateRep(G, NULL, cRepLabel, cRepInvRep);
2950 OrthoCommandIn(G, "viewport");
2951 } else {
2952 SettingSetGlobal_i(G, cSetting_display_scale_factor, 1);
2953 PRINTFB(G, FB_Setting, FB_Warnings)
2954 "Setting-Error: Cannot set a display scale factor of 0\n"
2955 ENDFB(G);
2956 }
2957 break;
2958 }
2959 #ifdef _PYMOL_OPENVR
2960 case cSetting_openvr_gui_distance:
2961 case cSetting_openvr_gui_fov:
2962 // case cSetting_openvr_gui_alpha:
2963 // case cSetting_openvr_gui_use_alpha:
2964 case cSetting_openvr_gui_scene_color:
2965 case cSetting_openvr_gui_scene_alpha:
2966 case cSetting_openvr_gui_back_color:
2967 case cSetting_openvr_gui_back_alpha:
2968 // case cSetting_openvr_gui_use_backdrop:
2969 // case cSetting_openvr_gui_overlay:
2970 // case cSetting_openvr_gui_text:
2971 OpenVRMenuSettingsChanged(G);
2972 break;
2973 case cSetting_openvr_disable_clipping:
2974 OpenVRClippingChanged(G);
2975 break;
2976 case cSetting_openvr_laser_width:
2977 OpenVRLaserWidthChanged(G);
2978 break;
2979 #endif
2980 default:
2981 break;
2982 }
2983 }
2984
2985
2986 /*========================================================================*/
SettingFreeGlobal(PyMOLGlobals * G)2987 void SettingFreeGlobal(PyMOLGlobals * G)
2988 {
2989 CSetting *I = G->Setting;
2990 SettingUniqueFree(G);
2991 SettingPurge(I);
2992 if(G->Default) {
2993 SettingPurge(G->Default);
2994 FreeP(G->Default);
2995 }
2996 FreeP(G->Setting);
2997 }
2998
2999
3000 /*========================================================================*/
SettingInitGlobal(PyMOLGlobals * G,int alloc,int reset_gui,int use_default)3001 void SettingInitGlobal(PyMOLGlobals * G, int alloc, int reset_gui, int use_default)
3002 {
3003 CSetting *I = G->Setting;
3004
3005 /* use function pointers to prevent the compiler from inlining every
3006 call in this block (a waste of RAM and time) */
3007
3008 int (*set_i) (CSetting * I, int index, int value) = SettingSet_i;
3009 int (*set_b) (CSetting * I, int index, int value) = SettingSet_b;
3010
3011 if(alloc || !I) {
3012 I = (G->Setting = pymol::calloc<CSetting>(1));
3013 SettingUniqueInit(G);
3014 SettingInit(G, I);
3015 }
3016
3017 if(G->Default && use_default) {
3018
3019 SettingCopyAll(G, G->Default, G->Setting);
3020
3021 } else {
3022
3023 // copy defaults from SettingInfo table
3024 for(int index = 0; index < cSetting_INIT; ++index) {
3025 if (!reset_gui) switch (index) {
3026 case cSetting_internal_gui_width:
3027 case cSetting_internal_gui:
3028 continue;
3029 }
3030
3031 SettingRestoreDefault(I, index);
3032 }
3033
3034 // open-source has no volume_mode=1
3035 set_i(I, cSetting_volume_mode, 0);
3036
3037 // command line arguments overwrites
3038 set_b(I, cSetting_auto_show_lines, G->Option->sphere_mode < 0);
3039 set_i(I, cSetting_auto_zoom, G->Option->zoom_mode);
3040 set_b(I, cSetting_auto_show_nonbonded, G->Option->sphere_mode < 0);
3041 set_b(I, cSetting_presentation, G->Option->presentation);
3042 set_i(I, cSetting_defer_builds_mode, G->Option->defer_builds_mode);
3043 set_b(I, cSetting_presentation_auto_quit, !G->Option->no_quit);
3044 set_b(I, cSetting_auto_show_spheres, G->Option->sphere_mode >= 0);
3045 set_i(I, cSetting_internal_feedback, G->Option->internal_feedback);
3046
3047 if(G->Option->stereo_mode) {
3048 set_i(I, cSetting_stereo_mode, G->Option->stereo_mode);
3049 } else if(G->StereoCapable || G->Option->blue_line) {
3050 set_i(I, cSetting_stereo_mode, cStereo_quadbuffer); /* quadbuffer if we can */
3051 }
3052
3053 /* In order to get electrostatic potentials in kT from the Coulomb equation...
3054
3055 PyMOL charges: Q, in e
3056 PyMOL distances: r, in Angstrom
3057 Coulomb Constant: K = 8.987552e9 ((J*m)/(C^2))
3058 Angstrom Convertor: 1 A = 1e-10 m
3059 Coulomb Convertor: 1 e = 1.60217733e-19 C
3060 Angstrom Convertor: 1 A = 10e-10 m
3061 Dielectric Constant: D (unitless)
3062
3063 ePot = (KQ)/(Dr) =
3064
3065 8.987552e9 J*m 1.6021773e-19 C 1.6021773e-19 C 1 A Q
3066 ---------------- * --------------- * --------------- * ---------- * --- =
3067 C^2 1 e 1 e 1e-10 m Dr
3068
3069 2.3070795237e-18 J*A Q
3070 = ---------------------- * ---
3071 e^2 Dr
3072
3073 Boltzmann Constant: k = 1.380658e-23 (J/K)
3074 Temperature: 300 Kelvin
3075
3076 kT = 1.380658e-23 * 300 = 4.141974e-21 J
3077
3078 2.3070795237e-18 J*A 1 kT Q
3079 ePot = --------------------- * ------------------ * ---
3080 e^2 4.141974e-21 J Dr
3081
3082 557.00000 kT*A Q
3083 ePot = -------------- * --- which will give kT/e units when applied
3084 e^2 Dr
3085 */
3086
3087 #ifdef WIN32
3088 /* BEGIN PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */
3089 set_b(I, cSetting_cache_display, 0);
3090
3091 // PYMOL-3143/PYMOL-3181 Intel HD Graphics
3092 // 4.5.0 - Build *.20.100.*
3093 // Driver update breaks lighting
3094 set_b(I, cSetting_precomputed_lighting, 1);
3095
3096 #ifndef _PYMOL_ACTIVEX
3097 {
3098 SYSTEM_INFO SysInfo;
3099 GetSystemInfo(&SysInfo);
3100 {
3101 DWORD count = SysInfo.dwNumberOfProcessors;
3102 if(count > 1) {
3103 set_i(I, cSetting_max_threads, count);
3104 }
3105 }
3106 }
3107 /* END PROPRIETARY CODE SEGMENT */
3108 #endif
3109 #endif
3110
3111 #ifndef _PYMOL_FREETYPE
3112 set_i(I, cSetting_label_font_id, 0);
3113 #endif
3114
3115 #ifdef _PYMOL_IOS
3116 #endif
3117 }
3118 G->ShaderMgr->Set_Reload_Bits(RELOAD_ALL_SHADERS);
3119 }
3120
SettingCheckFontID(PyMOLGlobals * G,CSetting * set1,CSetting * set2,int font_id)3121 int SettingCheckFontID(PyMOLGlobals * G, CSetting * set1, CSetting * set2, int font_id){
3122 int ret = font_id;
3123 if (font_id < 5){ // we are no longer supporting GLUT labels since they are not resizeable
3124 PRINTFB(G, FB_Setting, FB_Warnings)
3125 "RepLabel-Warning: GLUT labels (label_font_id 0-4) are no longer available for labelling\n the scene since they are not resizeable label_font_id=%d setting back to 5 (default) \n",
3126 font_id ENDFB(G);
3127 if (SettingGet_i(G, set1, NULL, cSetting_label_font_id) == font_id && SettingSet_i(set1, cSetting_label_font_id, 5)){
3128 } else if (SettingGet_i(G, set2, NULL, cSetting_label_font_id) == font_id && SettingSet_i(set2, cSetting_label_font_id, 5)){
3129 } else if (SettingGetGlobal_i(G, cSetting_label_font_id) == font_id){
3130 SettingSetGlobal_i(G, cSetting_label_font_id, 5);
3131 };
3132 ret = 5;
3133 }
3134 return ret;
3135 }
3136
3137 /*
3138 * State index iterator constructor, see Setting.h for documentation.
3139 */
StateIterator(PyMOLGlobals * G,CSetting * set,int state_,int nstate)3140 StateIterator::StateIterator(PyMOLGlobals * G, CSetting * set, int state_, int nstate) {
3141 if(state_ == -2) {
3142 // current state
3143 state_ = SettingGet_i(G, set, NULL, cSetting_state) - 1;
3144 }
3145
3146 if(state_ == -1) {
3147 // all states
3148 state = 0;
3149 end = nstate;
3150 } else {
3151 // given state or static singleton
3152 state = (state_ > 0 && nstate == 1
3153 && SettingGet_b(G, set, NULL, cSetting_static_singletons)) ? 0 : state_;
3154 end = state + 1;
3155 }
3156
3157 if (state < 0)
3158 state = 0;
3159
3160 if (end > nstate)
3161 end = nstate;
3162
3163 state--;
3164 }
3165
StateIterator(CObject * obj,int state_)3166 StateIterator::StateIterator(CObject* obj, int state_)
3167 : StateIterator(obj->G, obj->Setting, state_, obj->getNFrame())
3168 {
3169 }
3170
3171 /*
3172 * Helper function to init CPyMOL.Setting, a (name: index) dictionary.
3173 * Called in PyMOL_InitAPI
3174 */
CPyMOLInitSetting(OVLexicon * Lex,OVOneToOne * Setting)3175 bool CPyMOLInitSetting(OVLexicon * Lex, OVOneToOne * Setting) {
3176 for(int index = 0; index < cSetting_INIT; ++index) {
3177 auto &rec = SettingInfo[index];
3178
3179 if (rec.level == cSettingLevel_unused)
3180 continue;
3181
3182 OVreturn_word result = OVLexicon_GetFromCString(Lex, rec.name);
3183
3184 if( !OVreturn_IS_OK(result) ||
3185 !OVreturn_IS_OK(OVOneToOne_Set(Setting, result.word, index)))
3186 return false;
3187 }
3188
3189 return true;
3190 }
3191
3192 #ifndef _PYMOL_NOPY
3193 /*
3194 * Export the settings names to Python a as (name: index) dictionary.
3195 * Replacement for pymol.settings.SettingIndex
3196 */
SettingGetSettingIndices()3197 PyObject * SettingGetSettingIndices() {
3198 PyObject * val;
3199 PyObject * dict = PyDict_New();
3200
3201 for(int index = 0; index < cSetting_INIT; ++index) {
3202 auto &rec = SettingInfo[index];
3203
3204 if (rec.level == cSettingLevel_unused)
3205 continue;
3206
3207 if ((val = PyInt_FromLong(index))) {
3208 PyDict_SetItemString(dict, rec.name, val);
3209 Py_DECREF(val);
3210 }
3211 }
3212
3213 return dict;
3214 }
3215
3216 /*
3217 * Return a list of all setting indices for the given unique id
3218 */
SettingUniqueGetIndicesAsPyList(PyMOLGlobals * G,int unique_id)3219 PyObject * SettingUniqueGetIndicesAsPyList(PyMOLGlobals * G, int unique_id)
3220 {
3221 CSettingUnique *I = G->SettingUnique;
3222 PyObject * list = PyList_New(0);
3223 OVreturn_word result;
3224
3225 if(unique_id && OVreturn_IS_OK(result = OVOneToOne_GetForward(I->id2offset, unique_id))) {
3226 SettingUniqueEntry *entry;
3227 for (int offset = result.word; offset; offset = entry->next) {
3228 entry = I->entry + offset;
3229 PyObject *item = PyInt_FromLong(entry->setting_id);
3230 PyList_Append(list, item);
3231 Py_DECREF(item);
3232 }
3233 }
3234
3235 return list;
3236 }
3237 #endif
3238
3239 /*
3240 * Getters for templatted programming
3241 */
3242
_SettingGetFirstDefined(int index,PyMOLGlobals * G,const CSetting * set1,const CSetting * set2)3243 const CSetting * _SettingGetFirstDefined(int index,
3244 PyMOLGlobals * G,
3245 const CSetting * set1,
3246 const CSetting * set2) {
3247 if (set1 && set1->info[index].defined)
3248 return set1;
3249 if (set2 && set2->info[index].defined)
3250 return set2;
3251 return G->Setting;
3252 }
3253