1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710
|
/********************************************************************************
zfuncs.h include file for zfuncs functions
Copyright 2007-2024 Michael Cornelison
source code URL: https://kornelix.net
contact: mkornelix@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. See https://www.gnu.org/licenses
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
*********************************************************************************/
#include <sys/sysinfo.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <sys/file.h>
#include <sys/utsname.h>
#include <malloc.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <execinfo.h>
#include <locale.h>
#include <glob.h>
#include <gtk/gtk.h>
#define VERTICAL GTK_ORIENTATION_VERTICAL // GTK shortcuts
#define HORIZONTAL GTK_ORIENTATION_HORIZONTAL
#define PIXBUF GdkPixbuf
#define GDKCOLOR GdkColorspace
#define int8 ch // number types
#define int16 short
#define int32 int
#define int64 long long // long long is always 64 bits
#define uint8 unsigned char
#define uint16 unsigned short
#define uint32 unsigned int
#define uint64 unsigned long long
#define ch char
#define uch unsigned char
#define cch const char
#define VOL volatile
#define STATB struct stat // stat() file status buffer
#define mutex_t pthread_mutex_t // abbreviations
#define mutex_init pthread_mutex_init
#define mutex_lock pthread_mutex_lock
#define mutex_trylock pthread_mutex_trylock
#define mutex_unlock pthread_mutex_unlock
#define mutex_destroy pthread_mutex_destroy
#define XFCC 1000 // max. file pathname cc tolerated
#define null NULL
#define true 1
#define false 0
#define NOP
// trace execution: source file, function, line no, caller address
#define TRACE trace(__FILE__,__FUNCTION__,__LINE__,__builtin_return_address(0));
// system functions ============================================================
void *zmalloc(int64 cc, ch *tag); // malloc() wrapper
void zfree(void *pp); // free() wrapper
int zmalloc_test(int64 cc); // test if cc free memory available
double realmemory(); // get available real memory in MB units
double availmemory(); // get available memory (+swap) in MB units
ch * zstrdup(ch *zstring, ch *tag, int addcc = 0); // strdup() wrapper with added space
int zstrcopy(ch *&zstring, ch *string, ch *tag, int addcc = 0); // replace string with new string + added cc
void zmalloc_report(GtkWidget *parent); // memory usage by tag > popup report
void zmalloc_growth(GtkWidget *parent); // memory growth by tag > popup report
void xmessage(ch *message); // popup message not needing GTK
void zexit(int popup, ch *message, ...); // exit a process and kill child processes
void zbacktrace(); // produce a backtrace to stdout
void zappcrash(ch *format, ...); // crash with popup message in text window
void catch_signals(); // catch signals and do backtrace dump
void trace(ch *file, ch *func, int line, void *addr); // implements TRACE macro
void tracedump(); // dump program trace data
ch * combine_argvs(int argc, ch *argv[], int Nth); // combine argv[ii] elements Nth to last
double get_seconds(int init = 0); // get elapsed seconds since last call
void print_seconds(ch *label); // print seconds since last call
double get_seconds(timespec *ts); // real seconds from timespec struct
void start_timer(double &time0); // start a timer
double get_timer(double &time0); // get elapsed time in seconds
double CPUtime(); // get elapsed process CPU time
int memused(); // get process real memory, MB
void compact_time(time_t DT, ch *compactDT); // time_t DT to yyyymmddhhmmss
void pretty_datetime(time_t DT, ch *prettyDT); // time_t DT to yyyy:mm:dd hh:mm:ss
void secs_datetime(double secs, int datetime[6]); // seconds to year/mon/day/hour/min/secs
void datetime_secs(int datetime[6], double *secs); // year/mon/day/hour/min/secs to seconds
int parseprocfile(ch *pfile, ch *pname, double *value, ...); // get data from /proc file
int parseprocrec(ch *prec, int field, double *value, ...); // get data from /proc file record
int coretemp(); // get CPU temperature (package temp)
int disktemp(ch *disk); // get disk temp, e.g. "/dev/sda"
void zsleep(double dsecs); // sleep specified seconds
void zloop(double dsecs); // loop specified seconds
void spinlock(int lock); // lock/unlock enclosed code block
int global_lock(ch *lockfile); // obtain exclusive lock, multi-process
void global_unlock(int fd, ch *lockfile); // release the lock
int resource_lock(int &resource); // simple lock/unlock usable with GTK
void resource_unlock(int &resource); // (never waits, returns lock status)
int zget_locked(int ¶m); // lock and get multi-thread parameter
void zput_locked(int ¶m, int value); // put and unlock multi-thread parameter
int zadd_locked(int ¶m, int incr); // increment multi-thread parameter
pthread_t start_detached_thread(void * tfunc(void *), void * arg); // start detached thread function
pthread_t start_Jthread(void * threadfunc(void *), void * arg); // start joinable thread function
int wait_Jthread(pthread_t tid); // wait for completion (join thread)
void synch_threads(int NT = 0); // synchronize NT threads
int main_thread(); // return 1 if main() thread, else 0
int zshell(ch *options, ch *command, ...); // do shell command and get status
int kill_procname(ch *wildname); // kill processes matching wilcard name
int signalProc(ch *pname, ch *signal); // send signal to process by process name
ch * fgets_trim(ch * buff, int bcc, FILE *, int bf = 0); // fgets() + trim trailing \n \r (blanks)
ch * fgets_pend(ch * buff, int bcc, FILE *); // fgets() non-blocking wrapper
int samefolder(ch *file1, ch *file2); // returns 1 if files in same folder
int parsefile(ch *path, ch *&folder, ch *&file, ch *&ext); // parse components of a file name
void parsefile_free(ch *&folder, ch *&file, ch *&ext); // zfree file name components
int renamez(ch *file1, ch *file2); // rename, also across file systems
int check_create_dir(ch *path); // check if folder exists, ask to create
int cp_copy(ch *sfile, ch *dfile); // same, using shell "cp -f -p"
uint diskspace(ch *file); // get disk space for given file, MB
ch * get_file_extension(ch *file); // get correct .ext if file.ext is wrong
int zreaddir(ch *folder, ch **&files); // return all files in a folder, sorted
int zreadfile(ch *filename, ch **&rrecs); // read file, return array of records
int zwritefile(ch *filename, ch **&rrecs); // write array of records to file
void zreadfile_free(ch **&rrecs); // free zreadfile() memory
// string functions ============================================================
int strmatch(cch *str1, cch *str2); // true if strings equal, null strings allowed
int strmatchN(cch *str1, cch *str2, int cc); // true if leading N characters equal
int strmatchcase(cch *str1, cch *str2); // true if strings equal except for case
int strmatchcaseN(cch *str1, cch *str2, int cc); // true if leading N chars equal except case
ch * substringR(ch *string, ch *delims, int Nth); // get Nth delimited substring, thread-safe
ch * substringR(ch *string, ch delim, int Nth); // same, single delimiter
ch * substring(ch *string, ch *delims, int Nth); // same, no zfree() needed, not thread-safe
ch * substring(ch *string, ch delim, int Nth); // same, single delimiter
int get_substrings(ch *instr, ch dlm, int cnt, int maxcc, ch **outstr); // get all substrings from delimited string
int strHash(ch *string, uint max); // string --> random int 0 to max-1
int strncpy0(ch *dest, ch *source, uint cc); // strncpy, insure null, return 0 if fit
void strnPad(ch *dest, ch *source, int cc); // strncpy with blank padding to cc
int strTrim(ch *dest, ch *source); // remove trailing blanks
int strTrim(ch *string); // remove trailing blanks
int strTrim2(ch *dest, ch *source); // remove leading and trailing blanks
int strTrim2(ch *string); // remove leading and trailing blanks
int strCompress(ch *dest, ch *source); // remove all blanks incl. embedded
int strCompress(ch *string); // remove all blanks
int strncatv(ch *dest, int maxcc, ch *source, ...); // catenate strings (last = null)
int strmatchV(ch *string, ...); // compare to N strings, return 1-N or 0
void strToUpper(ch *dest, ch *source); // move and conv. string to upper case
void strToUpper(ch *string); // conv. string to upper case
void strToLower(ch *dest, ch *source); // move and conv. string to lower case
void strToLower(ch *string); // conv. string to lower case
int repl_1str(ch *strin, ch *strout, int maxcc, ch *ssin, ch *ssout); // copy string and replace 1 substring
int repl_Nstrs(ch *strin, ch *strout, int maxcc, ...); // copy string and replace N substrings
int breakup_text(ch *in, ch **&out, ch *delims, int cc1, int cc2); // break long string into substrings
void strncpyx(ch *out, ch *in, int ccin); // conv. string to hex format
void StripZeros(ch *pNum); // 1.230000E+12 --> 1.23E+12
int blank_null(ch *string); // test for blank/null string
int clean_escapes(ch *string); // replace \x escapes with real characters
int utf8len(ch *utf8string); // get graphic cc for UTF8 string
int utf8substring(ch *utf8out, ch *utf8in, int pos, int cc); // get graphic substring from UTF8 string
int utf8_check(ch *string); // check utf8 string for encoding errors
int utf8_clean(ch *string); // clean utf8 string: '?' > bad characters
int utf8_position(ch *utf8in, int Nth); // get byte position of Nth graphic char.
int zsed(ch *file, ...); // replace string1/3/5... with string2/4/6...
ch * zstrstr(ch *haystack, ch *needle); // work like strstr() and strcasestr()
ch * zstrcasestr(ch *haystack, ch *needle); // (but "" does NOT match any string)
ch * zstrcpy(ch *dest, ch *source); // strcpy with overlap allowed
ch * zstrncpy(ch *dest, ch *source, int cc); // strncpy with overlap allowed
int zstrcmp(ch *s1, ch *s2); // like strcmp, but \n terminates like null
int zstrcmp2(ch *s1, ch *s2); // strcmp using ch *args, not cch*
int zstrcasecmp(ch *s1, ch *s2); // strcasecmp using ch *args, not cch*
ch * zescape_quotes(ch *string); // escape quotes for use in shell commands
// number conversion ===========================================================
int convSI (ch *s, int &i, ch **delm = 0); // string to int
int convSI (ch *s, int &i, int low, int hi, ch **delm = 0); // (with low/high limit checking)
int convSD (ch *s, double &d, ch **delm = 0); // string to double
int convSD (ch *s, double &d, double low, double hi, ch **delm = 0); // (with low/high limit checking)
int convSF (ch *s, float &f, ch **delm = 0); // string to double
int convSF (ch *s, float &f, float low, float hi, ch **delm = 0); // (with low/high limit checking)
int convIS (int iin, ch *outp, int *cc = 0); // int to string, returned cc
int convDS (double din, int prec, ch *outp, int *cc = 0); // double to string, precision, output cc
double atofz(ch *string); // atof() for comma/period decimal points
ch * formatKBMB(double fnum, int prec); // format nnn B, nn.n KB, n.nn MB, etc.
// wildcard functions ==========================================================
int MatchWild(ch * wildstr, ch * str); // wildcard string match (match = 0)
int MatchWildCase(ch * wildstr, ch * str); // wildcard string match, ignoring case
ch * SearchWild(ch *wpath, int &flag); // wildcard file search
ch * SearchWildCase(ch *wpath, int &flag); // wildcard file search, ignoring case
int zfind(ch *pattern, ch **&flist, int &NF); // wildcard file search using glob()
// search and sort functions ===================================================
int bsearch(int seekint, int nn, int list[]); // binary search sorted list[nn]
int bsearch(ch *seekrec, ch *allrecs, int recl, int nrecs); // binary search sorted records
int bsearch(ch *seekrec, ch **allrecs, int N, int nrecs); // binary search sorted pointers to recs
typedef int HeapSortUcomp(ch *rec1, ch *rec2); // return -1/0/+1 if rec1 </=/> rec2
// single-thread versions
void heapsort(int vv[], int nn); // Heap Sort - integer
void heapsort(float vv[], int nn); // Heap Sort - float
void heapsort(double vv[], int nn); // Heap Sort - double
void heapsort(ch *vv[], int nn, HeapSortUcomp); // Heap Sort - char *, user-defined order
// 4-thread versions
void HeapSort(int vv[], int nn); // Heap Sort - integer
void HeapSort(float vv[], int nn); // Heap Sort - float
void HeapSort(double vv[], int nn); // Heap Sort - double
void HeapSort(ch *vv[], int nn); // Heap Sort - char *, ascending order
void HeapSort(ch *vv1[], ch *vv2[], int nn); // Heap Sort - parallel char *, ascending
void HeapSort(ch *vv[], int nn, HeapSortUcomp); // Heap Sort - char *, user-defined order
void HeapSort(ch *recs, int RL, int NR, HeapSortUcomp); // Heap Sort - records, user-defined order
int MemSort(ch * RECS, int RL, int NR, int KEYS[][3], int NK); // memory sort, records with multiple keys
int zmember(int testval, int matchval1, ...); // test if value matches any in a list
// hash table class ============================================================
class HashTab
{
static int tries1; // insert tries
static int tries2; // find/delete tries
int cap; // table capacity
int count; // strings contained
int cc; // string length
ch *table = 0; // table[cc][cap]
public:
HashTab(int cc, int cap); // constructor
~HashTab(); // destructor
int Add(ch * string); // add a new string
int Del(ch * string); // delete a string
int Find(ch * string); // find a string
int GetCount() { return count; }; // get string count
int GetNext(int & first, ch * string); // get first/next string
int Dump(); // dump hash table
};
// list processing functions ===================================================
typedef struct { // list data type
int count; // count of member strings
ch **mber = 0; // member strings, null == missing
} zlist_t;
zlist_t * zlist_new(int count); // create zlist with 'count' empty members
void zlist_free(zlist_t *zlist); // delete zlist, free memory
void zlist_dump(zlist_t *zlist); // dump zlist to stdout
int zlist_count(zlist_t *zlist); // get zlist member count
ch * zlist_get(zlist_t *zlist, int Nth); // get a zlist member
void zlist_put(zlist_t *zlist, ch *string, int Nth); // put a zlist member (replace existing)
void zlist_insert(zlist_t *zlist, ch *string, int Nth); // insert Nth member, old Nth >> Nth+1
void zlist_remove(zlist_t *zlist, int Nth); // remove a zlist member (count -= 1)
void zlist_clear(zlist_t *zlist, int Nth); // clear zlist from Nth member to end
void zlist_purge(zlist_t *zlist); // purge zlist of all null members
int zlist_add(zlist_t *zlist, ch *string, int Funiq); // add new member at first null or append
int zlist_append(zlist_t *zlist, ch *string, int Funiq); // append new member at end (if unique)
int zlist_prepend(zlist_t *zlist, ch *string, int Funiq); // prepend new member at posn 0 (if unique)
int zlist_find(zlist_t *zlist, ch *string, int posn); // find next match from posn
int zlist_findwild(zlist_t *zlist, ch *wstring, int posn); // find next wildcard match from posn
zlist_t * zlist_copy(zlist_t *zlist1); // copy a zlist
zlist_t * zlist_insert_zlist(zlist_t *zlist1, zlist_t *zlist2, int Nth); // insert zlist2 into zlist1 at posn Nth
zlist_t * zlist_remove(zlist_t *zlist1, zlist_t *zlist2); // remove all members of zlist2 from zlist1
void zlist_sort(zlist_t *zlist); // sort zlist ascending
void zlist_sort(zlist_t *zlist, int ccfunc(ch *, ch *)); // sort zlist via caller compare function
int zlist_to_file(zlist_t *zlist, ch *filename); // make file from zlist
zlist_t * zlist_from_file(ch *filename); // make zlist from file
zlist_t * zlist_from_folder(ch *foldername); // make zlist from files in a folder
// random number functions =====================================================
int lrandz(int64 * seed); // returns 0 to 0x7fffffff
int lrandz(); // built-in seed
double drandz(int64 * seed); // returns 0.0 to 0.99999...
double drandz(); // built-in seed
// spline curve-fitting functions ==============================================
void spline1(int nn, float *dx, float *dy); // define a curve using nn data points
float spline2(float x); // return y-value for given x-value
// FIFO queue for text strings, single or dual-thread access ===================
typedef struct {
int qcap; // queue capacity
int qnewest; // newest entry position, circular
int qoldest; // oldest entry position, circular
int qdone; // flag, last entry added to queue
ch **qtext; // up to qcap text strings
} Qtext;
void Qtext_open(Qtext *qtext, int cap); // initialize Qtext queue, empty
void Qtext_put(Qtext *qtext, ch *format, ...); // add text string to Qtext queue
ch * Qtext_get(Qtext *qtext); // remove text string from Qtext queue
void Qtext_close(Qtext *qtext); // close Qtext, zfree() leftover strings
// compute variance for a list of numbers (std. deviation = sqrtf(variance))
float variance(float *vals, int N);
// application initialization and administration ===============================
int zinitapp(ch *appvers, int argc, ch *argv[]); // initialize app (appname-N.N, custom homedir)
ch * get_zprefix(); // get /usr or /usr/local ...
ch * get_zhomedir(); // get /home/user/.appname/
ch * get_zdatadir(); // get data folder
ch * get_zimagedir(); // get image folder
ch * get_zdocdir(); // get document folder
void zabout(GtkWidget *parent); // popup app 'about' information
void zsetfont(ch *newfont); // set new app font and size
int widget_font_metrics(GtkWidget *widget, int &fww, int &fhh); // get widget font char width/height
int get_zfilespec(ch *ftype, ch *fname, ch *filespec); // get installation data file
void showz_logfile(GtkWidget *parent); // show log file in popup window
void showz_textfile(ch *type, ch *file, GtkWidget *parent); // show text file [.gz] in popup window
void showz_docfile(GtkWidget *, ch *docfile, ch *topic); // show docfile topic and assoc. image
/********************************************************************************
GTK utility functions
*********************************************************************************/
void zmainloop(int skip = 0); // do main loop, process menu events
void zmainsleep(float secs); // do main loop and sleep designated time
/********************************************************************************/
// cairo drawing region for GDK window
typedef struct {
GdkWindow *win;
cairo_rectangle_int_t rect;
cairo_region_t *reg;
GdkDrawingContext *ctx;
cairo_t *dcr = 0;
} draw_context_t;
cairo_t * draw_context_create(GdkWindow *gdkwin, draw_context_t &context);
void draw_context_destroy(draw_context_t &context);
/********************************************************************************/
// connect KB and mouse events to widget response function
#define G_SIGNAL(widget,event,func,arg) \
g_signal_connect(G_OBJECT(widget),event,G_CALLBACK(func),(void *) arg)
/********************************************************************************/
// txwidget functions - scrollable text widget for text reports and line editing
// widget = zdialog_gtkwidget(zd,txwidget) where txwidget is a zdialog "text" widget type
void txwidget_clear(GtkWidget *widget); // clear all text
void txwidget_clear(GtkWidget *widget, int line); // clear text from line to end
int txwidget_linecount(GtkWidget *widget); // get current line count
void txwidget_append(GtkWidget *widget, int bold, ch *format, ...); // append line
void txwidget_append2(GtkWidget *widget, int bold, ch *format, ...); // append line and scroll to end
void txwidget_insert(GtkWidget *widget, int bold, int line, ch *format, ...); // insert line
void txwidget_replace(GtkWidget *widget, int bold, int line, ch *format, ...); // replace line
void txwidget_delete(GtkWidget *widget, int line); // delete line
int txwidget_find(GtkWidget *widget, ch *matchtext, int line1, int hilite); // find matching line
void txwidget_insert_pixbuf(GtkWidget *widget, int line, GdkPixbuf *pixbuf); // insert pixbuf image
void txwidget_scroll(GtkWidget *widget, int line); // scroll line on screen
void txwidget_scroll_top(GtkWidget *widget, int line); // scroll line to top of window
void txwidget_get_visible_lines(GtkWidget *widget, int &top, int &bott); // get range of visible lines
void txwidget_dump(GtkWidget *widget, ch *filename); // dump all text into a file
void txwidget_save(GtkWidget *widget, GtkWindow *parent); // same, with save-as dialog
ch * txwidget_line(GtkWidget *widget, int line, int strip); // retrieve line (strip \n)
void txwidget_highlight_line(GtkWidget *widget, int line); // highlight line
ch * txwidget_word(GtkWidget *, int line, int posn, ch *dlims, ch &end); // retrieve word
void txwidget_highlight_word(GtkWidget *widget, int line, int posn, int cc); // highlight word
void txwidget_bold_word(GtkWidget *widget, int line, int posn, int cc); // make word bold
void txwidget_underline_word(GtkWidget *widget, int line, int posn, int cc); // make word underlined
void txwidget_font_attributes(GtkWidget *widget); // set font attributes for all text
typedef int txwidget_CBfunc_t(GtkWidget *, int line, int posn, ch *input); // widget event function to receive
void txwidget_set_eventfunc(GtkWidget *, txwidget_CBfunc_t func); // mouse click and KB events
/********************************************************************************/
// functions to simplify building menus, tool bars, status bars
typedef void cbFunc(GtkWidget *, ch *mname); // menu or button response function
GtkWidget * create_menubar(GtkWidget *vbox); // create menubar in packing box
GtkWidget * add_menubar_item(GtkWidget *mbar, ch *mname, cbFunc func = 0); // add menu item to menubar
GtkWidget * add_submenu_item(GtkWidget *mitem, ch *subname, // add submenu item to menu item
cbFunc func = 0, ch *mtip = 0); // with opt. function and popup tip
GtkWidget * create_toolbar(GtkWidget *vbox, int iconsize = 24); // toolbar in packing box (no vert gtk3)
GtkWidget * add_toolbar_button(GtkWidget *tbar, ch *lab, ch *tip, // add button with label, tool-tip, icon
ch *icon, cbFunc func);
GtkWidget * create_stbar(GtkWidget *vbox); // create status bar in packing box
int stbar_message(GtkWidget *stbar, ch *message); // display message in status bar
/********************************************************************************/
GtkWidget * create_popmenu(); // create an empty popup menu
void add_popmenu(GtkWidget *popmenu, ch *item, cbFunc func, ch *arg, ch *tip); // add menu item to popup menu
void popup_menu(GtkWidget *, GtkWidget *popmenu); // pop-up menu at current mouse posn.
ch * popup_choose(zlist_t *zlist); // popup to choose item from list
ch * popup_choose(ch *file); // same, list from text file
/********************************************************************************/
// create vertical menu/toolbar in vertical packing box
struct vmenuent { // menu data from caller
ch *name = 0; // menu name, text
ch *icon = 0; // opt. icon file name
ch *desc = 0; // description (mouse hover popup)
cbFunc *LMfunc; // menu func for left mouse click
cbFunc *RMfunc; // menu func for right mouse click
cbFunc *setupfunc; // opt. setup func for menu func
ch *arg = 0; // callback arg for menu func
ch *setuparg = 0; // callback arg for setup func
ch *RMarg = 0; // callback arg for RMfunc
PIXBUF *pixbuf; // icon pixbuf or null
PangoLayout *playout1, *playout2; // normal and bold menu text
int namex, namey; // menu name position in layout
int iconx, icony; // menu icon position
int ylo, yhi; // menu height limits
int iconww, iconhh; // icon width and height
};
struct Vmenu {
GtkWidget *vbox; // parent window (container)
GtkWidget *topwin; // top-level window of parent
GtkWidget *layout; // drawing window
float fgRGB[3]; // font color, RGB scaled 0-1
float bgRGB[3]; // background color, RGB scaled 0-1
int xmax, ymax; // layout size
int mcount; // menu entry count
vmenuent menu[100];
};
Vmenu *Vmenu_new(GtkWidget *vbox, float fgRGB[3], float bgRGB[3]); // create new menu in parent vbox
void Vmenu_add(Vmenu *vbm, ch *name, ch *icon, int iconww, int iconhh, // add menu item with response function
ch *desc, cbFunc func, ch *arg); // function may be popup_menu()
void Vmenu_add_setup(Vmenu *vbm, int me, cbFunc RMfunc, ch *arg); // add opt. setup function
void Vmenu_add_RMfunc(Vmenu *vbm, int me, cbFunc RMfunc, ch *arg); // add function for right mouse click
void Vmenu_block(int flag); // block or unblock menu
/********************************************************************************/
// spline curve edit functions
typedef void spcfunc_t(int spc); // callback function, spline curve edit
struct spldat { // spline curve data
GtkWidget *drawarea; // drawing area for spline curves
spcfunc_t *spcfunc; // callback function when curve changed
int Nscale; // no. of fixed scale lines, 0-10
float xscale[2][10]; // 2 x-values for end points
float yscale[2][10]; // 2 y-values for end points
int Nspc; // number of curves, 1-10
int fact[10]; // curve is active
int vert[10]; // curve is vert. (1) or horz. (0)
int mod[10]; // curve is edited/modified
int nap[10]; // anchor points per curve
float apx[10][50], apy[10][50]; // up to 50 anchor points per curve
float yval[10][1000]; // y-values for x = 0 to 1 by 0.001
};
spldat * splcurve_init(GtkWidget *frame, void func(int spc)); // initialize spline curves
int splcurve_adjust(void *, GdkEventButton *event, spldat *); // curve editing function
int splcurve_addnode(spldat *, int spc, float px, float py); // add a new node to a curve
int splcurve_resize(GtkWidget *); // adjust drawing area height
int splcurve_draw(GtkWidget *, cairo_t *, spldat *); // spline curve draw signal function
int splcurve_generate(spldat *, int spc); // generate data from anchor points
float splcurve_yval(spldat *, int spc, float xval); // get curve y-value
int splcurve_load(spldat *sd, FILE *fid); // load curve from a file
int splcurve_save(spldat *sd, FILE *fid); // save curve to a file
/********************************************************************************/
// functions to implement GTK dialogs with less complexity
// widget types: dialog, hbox, vbox, hsep, vsep, frame, scrwin, label, link,
// entry, edit, text, radio, check, button, togbutt, spin,
// combo, hscale, vscale, imagebutt, colorbutt, icon, image
#define zdmaxwidgets 300
#define zdmaxbutts 10
#define zdsentinel 0x97530000
#define zdialog_max 20
struct zwidget {
ch *type = 0; // hbox, vbox, label, entry ...
ch *wname = 0; // widget name
ch *pname = 0; // parent (container) name
ch *data = 0; // widget data, initial / returned
int size; // text entry cc or image pixel size
int homog; // hbox/vbox: equal spacing flag
int expand; // widget is expandable flag
int space; // extra padding space (pixels)
int wrap; // wrap mode for edit widget
int rescale; // widget is rescaled for more resolution
double lval, nval, hval; // scale range and neutral value
double lolim, hilim, step; // range and step value for number widget
zlist_t *zlist; // combo box list of text entries
GtkWidget *widget; // GTK widget pointer
};
struct zdialog {
int sentinel1; // validity sentinel1
int uniqueID; // unique ID, monotone increasing
ch *title = 0; // dialog title
void *eventCB; // dialog event user callback function
void *popup_report_CB; // callback function for popup_report
int zrunning; // dialog is running (0,1)
int zstat; // dialog status (from completion button)
ch zstat_button[40]; // completion button label
int disabled; // widget signals/events are disabled
int saveposn; // save and recall window position each use
int saveinputs; // save and recall user inputs each use
GtkWidget *dialog; // dialog window or null (box parent)
GtkWidget *parent; // parent window or null
ch *ptype = 0; // null or "window" or "box" parent
ch *compbutton[zdmaxbutts]; // dialog completion button labels
GtkWidget *compwidget[zdmaxbutts]; // dialog completion button widgets
zwidget widget[zdmaxwidgets]; // dialog widgets (EOF = type = 0)
ch event[40]; // active event or widget
GtkWidget *lastwidget; // last widget active
int sentinel2; // validity sentinel2
};
zdialog *zdialog_new(ch *title, GtkWidget *parent, ...); // create a zdialog with opt. buttons
void zdialog_set_title(zdialog *zd, ch *title); // change zdialog title
void zdialog_set_modal(zdialog *zd); // set zdialog modal
void zdialog_set_decorated(zdialog *zd, int decorated); // set zdialog decorated or not
void zdialog_present(zdialog *zd); // zdialog visible and on top
void zdialog_can_focus(zdialog *zd, int Fcan); // zdialog can/not have focus (e.g. report)
void zdialog_set_focus(zdialog *zd, ch *widget = null); // set focus on window [ widget ]
int zdialog_add_widget_long(zdialog *zd, // add widget to zdialog
ch *type, ch *wname, ch *pname, // required args
ch *data = 0, int size = 0, int homog = 0, // optional args
int expand = 0, int space = 0, int wrap = 0);
int zdialog_add_widget(zdialog *zd, // add widget to zdialog
ch *type, ch *wname, ch *pname, // (alternative form)
ch *data = 0, ch *options = 0); // "size=nn|homog|expand|space=nn|wrap"
int zdialog_valid(zdialog *zd, ch *title = 0); // return 1/0 if zdialog valid/invalid
int zdialog_valid2(zdialog *zd, ch *title = 0); // silent version of above
int zdialog_find_widget(zdialog *zd, ch *wname); // find zdialog widget from widget name
GtkWidget * zdialog_gtkwidget(zdialog *zd, ch *wname); // GTK widget from zdialog widget name
int zdialog_set_image(zdialog *zd, ch *wname, GdkPixbuf *); // set "image" widget from a GDK pixbuf
int zdialog_add_ttip(zdialog *zd, ch *wname, ch *ttip); // add popup tool tip to a widget
int zdialog_resize(zdialog *zd, int width, int height); // set size > widget sizes
int zdialog_put_data(zdialog *zd, ch *wname, ch *data); // put data in widget (entry, spin ...)
ch * zdialog_get_data(zdialog *zd, ch *wname); // get widget data
int zdialog_set_limits(zdialog *, ch *wname, double min, double max); // set new widget limits (spin, scale)
int zdialog_get_limits(zdialog *, ch *wname, double &min, double &max); // get widget limits (spin, scale)
int zdialog_rescale(zdialog *zd, ch *wname, float, float, float); // rescale widget, lo/neut/hi vals
typedef int zdialog_event(zdialog *zd, ch *wname); // widget event callback function
int zdialog_run(zdialog *zd, zdialog_event = 0, ch *posn = 0); // run dialog, handle events
void KBevent(GdkEventKey *event); // extern: pass KB events to main app
int zdialog_send_event(zdialog *zd, ch *event); // send an event to an active dialog
int zdialog_send_response(zdialog *zd, int zstat); // complete a dialog, set status
int zdialog_show(zdialog *zd, int flag); // show or hide a dialog
int zdialog_destroy(zdialog *zd); // destroy dialog (caller resp.)
int zdialog_free(zdialog *&zd); // free zdialog memory
int zdialog_wait(zdialog *zd); // wait for dialog completion
int zdialog_goto(zdialog *zd, ch *wname); // put cursor at named widget
void zdialog_set_cursor(zdialog *zd, GdkCursor *cursor); // set cursor for dialog window
int zdialog_stuff(zdialog *zd, ch *wname, ch *data); // stuff string data into widget
int zdialog_stuff(zdialog *zd, ch *wname, int data); // stuff int data
int zdialog_stuff(zdialog *zd, ch *wname, double data); // stuff double data
int zdialog_stuff(zdialog *zd, ch *wname, double data, ch *format); // stuff double data, formatted
int zdialog_labelfont(zdialog *zd, ch *lab, ch *font, ch *txt); // stuff label text with font
int zdialog_fetch(zdialog *zd, ch *wname, ch *data, int maxcc); // get string data from widget
int zdialog_fetch(zdialog *zd, ch *wname, int &data); // get int data
int zdialog_fetch(zdialog *zd, ch *wname, double &data); // get double data
int zdialog_fetch(zdialog *zd, ch *wname, float &data); // get float data
int zdialog_combo_clear(zdialog *zd, ch *wname); // clear combo box entries
int zdialog_combo_popup(zdialog *zd, ch *wname); // open combo box pick list
int zdialog_load_widgets(zdialog *zd, spldat *sd, ch *fname, FILE *fid); // load zdialog widgets from a file
int zdialog_save_widgets(zdialog *zd, spldat *sd, ch *fname, FILE *fid); // save zdialog widgets to a file
int zdialog_load_prev_widgets(zdialog *zd, spldat *sd, ch *fname); // save last-used zdialog widgets
int zdialog_save_last_widgets(zdialog *zd, spldat *sd, ch *fname); // load last-used zdialog widgets
int zdialog_geometry(ch *action); // load/save zdialog window positiion/size
void zdialog_set_position(zdialog *zd, ch *posn); // set initial/new zdialog window position
void zdialog_save_position(zdialog *zd); // save zdialog window position
int zdialog_inputs(ch *action); // load or save zdialog input fields
int zdialog_save_inputs(zdialog *zd); // save zdialog input fields when finished
int zdialog_load_inputs(zdialog *zd); // restore zdialog inputs from prior use
ch * zdialog_text(GtkWidget *parent, ch *title, ch *inittext); // get N text input lines from user
ch * zdialog_text1(GtkWidget *parent, ch *title, ch *inittext); // get one text input line from user
ch * zdialog_password(GtkWidget *parent, ch *title, ch *inittext); // same, but input is replaced with '*'s
int zdialog_choose(GtkWidget *parent, ch *where, ch *message, ...); // show message, return button choice
int zdialog_edit_textfile(GtkWidget *parent, char *file); // popup zdialog to edit a text file
// write text report in popup window
zdialog * popup_report_open(ch *title, GtkWidget *parent, int ww, int hh, // open popup report - pixel size,
int wrap, int Fheader, txwidget_CBfunc_t CBfunc, ...); // wrap, header line, callback function
void popup_report_header(zdialog *zd, int bold, ch *format, ...); // write non-scrolling header line
void popup_report_write(zdialog *zd, int bold, ch *format, ...); // write text line
void popup_report_write2(zdialog *zd, int bold, ch *format, ...); // write text line and scroll to end
void popup_report_top(zdialog *zd); // go to top of report window
void popup_report_bottom(zdialog *zd); // go to bottom of report window
void popup_report_clear(zdialog *zd); // clear report window
void popup_report_clear(zdialog *zd, int line); // clear from line to end
void popup_report_insert(zdialog *zd, int bold, int line, ch *format, ...); // insert new line
void popup_report_replace(zdialog *zd, int bold, int line, ch *format, ...); // replace existing line
void popup_report_delete(zdialog *zd, int line); // delete line
int popup_report_find(zdialog *zd, ch *matchtext, int line1); // find matching line
void popup_report_insert_pixbuf(zdialog *zd, int line, GdkPixbuf *pixbuf); // insert pixbuf image after line
void popup_report_scroll(zdialog *zd, int line); // scroll to make line visible
void popup_report_scroll_top(zdialog *zd, int line); // scroll to put line at top
void popup_report_get_visible_lines(zdialog *zd, int &top, int &bott); // get visible lines range
ch * popup_report_line(zdialog *zd, int line, int strip); // retrieve line (strip \n)
ch * popup_report_word(zdialog *zd, int line, int posn, ch *dlims, ch &end); // retrieve word
void popup_report_highlight_line(zdialog *zd, int line); // highlight line
void popup_report_highlight_word(zdialog *zd, int line, int posn, int cc); // highlight word
void popup_report_underline_word(zdialog *zd, int line, int posn, int cc); // underline word
void popup_report_bold_word(zdialog *zd, int line, int posn, int cc); // bold word
void popup_report_font_attributes(zdialog *zd); // font attributes for entire report
void popup_report_close(zdialog *zd, int secs); // close window after seconds
int popup_command(ch *cmd, int ww=400, int hh=300, GtkWidget *p=0, int top=0); // shell command to popup window
int monitor_file(ch *file); // monitor a text file in a popup window
// popups: message, dialog, image
ch * boldred(ch *message); // convert dialog message to bold/red font
void zmessageACK_init(); // initz. for thread usage
void zmessageACK(GtkWidget *parent, ch *format, ... ); // display message, wait for OK
int zmessageYN(GtkWidget *parent, ch *format, ... ); // display message, wait for YES/NO
zdialog * zmessage_post(GtkWidget *, ch *loc, int s, ch *f, ...); // show message, timeout or cancel
void poptext_screen(ch *text, int px, int py, float s1, float s2); // show popup text at screen posn
void poptext_mouse(ch *text, int dx, int dy, float s1, float s2); // same, at mouse posn + offset
void poptext_widget(GtkWidget *, ch *tx, int x, int y, float s1, float s2); // same, at widget posn + offset
int poptext_killnow(); // kill current popup window
// file chooser dialogs for one file, multiple files, or folder
ch * zgetfile(ch *title, GtkWindow *parent, ch *action, ch *file, int hidden = 0);
ch ** zgetfiles(ch *title, GtkWindow *parent, ch *action, ch *file, int hidden = 0);
ch * zgetfolder(ch *title, GtkWindow *parent, ch *initfolder);
// print an image file, choosing printer, paper, orientation, margins, and scale
void print_image_file(GtkWidget *parent, ch *imagefile);
// drag and drop functions
typedef ch * drag_drop_source_func(); // user function, set drag-drop text
typedef void drag_drop_dest_func(int x, int y, ch *text); // user function, get drag-drop text
void drag_drop_source(GtkWidget *window, drag_drop_source_func); // connect source window to user function
void drag_drop_dest(GtkWidget *window, drag_drop_dest_func); // connect dest. window to user function
// miscellaneous GDK/GTK functions
PIXBUF * get_thumbnail(ch *fpath, int size); // get sized thumbnail for image file
GdkCursor * zmakecursor(ch *iconfile); // make a cursor from an image file
PIXBUF * gdk_pixbuf_stripalpha(PIXBUF *pixbuf); // strip alpha channel from pixbuf
PIXBUF * text_pixbuf(ch *text, ch *font, int fsize, GtkWidget *); // create pixbuf with text using font
int move_pointer(GtkWidget *, int px, int py); // move the mouse pointer to px, py
void window_to_mouse(GtkWidget *window); // move GtkWidget/window to mouse position
|