/* ---------------------------------------------------------------- * * cbx_async.c * * Asynchonous Xlib - message box functions * * v0.01 2000-08-02 Christoph C. Birk (birk@obs.carnegiescience.edu) * 1.00 2000-10-39 'ccbalib.c' * 1.01 2001-06-21 CBX_TextExtent_Ext() * 4.00 2002-04-09 v4 * 4.070 2015-02-03 use CXT_OpenMainWindow() * * ---------------------------------------------------------------- */ #define IS_CXTLIB_C /* DEFINEs -------------------------------------------------------- */ #ifndef DEBUG #define DEBUG 1 #endif #define XDEBUG 0 #ifdef FONTSIZE #define PXh FONTSIZE #else #define PXh 14 #endif #define PXw (10+(PXh-14)/2) #define XXh (PXh+4) #define PREFUN __func__ /* INCLUDEs ------------------------------------------------------- */ #include /* malloc(),free() */ #include /* strlen() */ #if (DEBUG > 0) #include /* stderr */ #endif #include "cxt.h" /* EXTERNs -------------------------------------------------------- */ extern void cbx_msleep (int); extern int cbx_max (int,int); /* STATICs -------------------------------------------------------- */ static void* amb_AsyncMessageOpen (void*); static void* amb_AsyncAbortBoxOpen (void*); static void* amb_AsyncMessageBox (void*); static int cbx_threaddetach (void*(*)(void*),void*); static int cbx_threadcreate (void*(*)(void*),void*,pthread_t*); static char* cbx_genv2 (char*,char*); /* ---------------------------------------------------------------- */ /* utils */ /* ---------------------------------------------------------------- */ static int cbx_threaddetach(void*(*start_routine)(void*),void* arg) { int err; pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); err = pthread_create(&tid,&attr,start_routine,arg); pthread_attr_destroy(&attr); return(err); } /* ---------------------------------------------------------------- */ static int cbx_threadcreate(void*(*start_routine)(void*), void* arg,pthread_t* tid) { int err; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE); err = pthread_create(tid,&attr,start_routine,arg); pthread_attr_destroy(&attr); return(err); } /* ---------------------------------------------------------------- */ /* MessageBox() */ /* ---------------------------------------------------------------- */ void CBX_AsyncMessageBox(const char* title,const char* text) { AMB *amb; amb = (AMB*)malloc(sizeof(AMB)); /* allocate memory */ amb->done = 0; strcpy(amb->title,title); strcpy(amb->text,text); cbx_threaddetach(amb_AsyncMessageBox,(void*)amb); cbx_msleep(200); } /* ---------------------------------------------------------------- */ static void* amb_AsyncMessageBox(void* param) { MainWindow mwin; int w=11*PXw,w2; const int h=5*PXh,OKy=h-(5*PXw)/2,OKw=4*PXw; XSizeHints hint; XEvent event; AMB *amb=(AMB*)param; w = cbx_max(w,(strlen(amb->text)+1)*PXw); amb->box = CXT_OpenMainWindow(&mwin,CBX_CENTER,w,h, &hint,amb->title,"A-Message",True); amb->disp = mwin.disp; #if (XDEBUG > 0) (void)CBX_Lock(0); XSynchronize(amb->disp,True); CBX_Unlock(); #endif amb->gfs = CBX_CreateGfC(&mwin,cbx_genv2("CBXFONT","courier"),"bold",PXh); w2 = CBX_TextWidth(&mwin,amb->text)+PXw; w = cbx_max(w,w2); CBX_MoveResizeMainWindow(&mwin,CBX_CENTER,w,h); (void)CBX_CreateButton(&mwin,&amb->but,(w-4*PXw)/2,OKy,OKw,XXh,"OK"); while (amb->done == 0) { /* event loop */ (void)CBX_Lock(0); if (XCheckTypedWindowEvent(amb->disp,amb->box,Expose,&event)) { XDrawString(amb->disp,amb->box,amb->gfs.gc,PXw/2+(w-w2)/2,(3*PXh)/2, amb->text,strlen(amb->text)); CBX_Unlock(); CBX_UpdateButton(&amb->but); } else if (XCheckTypedWindowEvent(amb->disp,amb->but.win,ButtonPress,&event)) { CBX_Unlock(); if (CBX_HandleButton(&amb->but) == CBX_PRESSED) amb->done = 1; } else { CBX_Unlock(); cbx_msleep(200); } } /* while(!done) */ CBX_ClearXQueue_Ext(amb->disp); CBX_CloseMainWindow(&mwin); free((void*)amb); /* free AMB structure */ return(NULL); } /* ---------------------------------------------------------------- */ /* MessageOpen(),Close() */ /* ---------------------------------------------------------------- */ AMB* CBX_AsyncMessageOpen(const char* title,const char* text) { AMB *amb; amb = (AMB*)malloc(sizeof(AMB)); /* allocate memory */ amb->done = 0; strcpy(amb->title,title); strcpy(amb->text,text); cbx_threadcreate(amb_AsyncMessageOpen,(void*)amb,&amb->tid); cbx_msleep(200); return(amb); } /* ---------------------------------------------------------------- */ static void* amb_AsyncMessageOpen(void* param) { MainWindow mwin; int w=11*PXw,w1,w2; const int h=3*PXh; XSizeHints hint; XEvent event; AMB *amb=(AMB*)param; w1 = PXw*(strlen(amb->title)+3); w2 = PXw*(strlen(amb->text)+1); w = cbx_max(w,cbx_max(w1,w2)); amb->box = CXT_OpenMainWindow(&mwin,CBX_CENTER,w,h,&hint,amb->title, "A-Message",False); amb->disp = mwin.disp; #if (XDEBUG > 0) (void)CBX_Lock(0); XSynchronize(amb->disp,True); CBX_Unlock(); #endif amb->gfs = CBX_CreateGfC(&mwin,cbx_genv2("CBXFONT","courier"),"bold",PXh); w1 = CBX_TextWidth(&mwin,amb->title)+3*PXw; w2 = CBX_TextWidth(&mwin,amb->text)+PXw; w = cbx_max(w,cbx_max(w1,w2)); CBX_ResizeMainWindow(&mwin,w,h); while (amb->done == 0) { /* event loop */ (void)CBX_Lock(0); if (XCheckTypedWindowEvent(amb->disp,amb->box,Expose,&event)) { XDrawString(amb->disp,amb->box,amb->gfs.gc,PXw/2,2*PXh, amb->text,strlen(amb->text)); CBX_Unlock(); } else { CBX_Unlock(); cbx_msleep(500); } } /* while(!done) */ CBX_ClearXQueue_Ext(amb->disp); CBX_CloseMainWindow(&mwin); free((void*)amb); /* free AMB structure */ return(NULL); } /* ---------------------------------------------------------------- */ void CBX_AsyncMessageClose(AMB* amb) { pthread_t tid; tid = amb->tid; amb->done = 1; pthread_join(tid,NULL); } /* ---------------------------------------------------------------- */ void CBX_AsyncMessageUpdate(AMB* amb,const char* text) { int w; XWindowAttributes xwa; #if (DEBUG > 1) fprintf(stderr,"%s() ...\n",PREFUN); #endif strcpy(amb->text,text); w = CBX_TextWidth_Ext(amb->gfs,amb->text)+PXw; (void)CBX_Lock(0); XGetWindowAttributes(amb->disp,amb->box,&xwa); /* get window attributes */ if (xwa.width < w) { XResizeWindow(amb->disp,amb->box,w,xwa.height); } XClearWindow(amb->disp,amb->box); CBX_Unlock(); CBX_SendExpose_Ext(amb->disp,amb->box); #if (DEBUG > 1) fprintf(stderr,"%s() ... done\n",PREFUN); #endif } /* ---------------------------------------------------------------- */ /* AbortBox() */ /* ---------------------------------------------------------------- */ void CBX_AsyncAbortBoxOpen(AMB* amb,const char* title,const char* text) { amb->done = 0; strcpy(amb->title,title); strcpy(amb->text,text); cbx_threadcreate(amb_AsyncAbortBoxOpen,(void*)amb,&amb->tid); cbx_msleep(200); } /* ---------------------------------------------------------------------- */ void CBX_AsyncAbortBoxClose(AMB* amb) { pthread_t tid; tid = amb->tid; amb->done = 1; pthread_join(tid,NULL); } /* ---------------------------------------------------------------------- */ void CBX_AsyncAbortBoxUpdate(AMB* amb,const char* text) { int w; XWindowAttributes xwa; strcpy(amb->text,text); w = CBX_TextWidth_Ext(amb->gfs,amb->text)+2*PXw; (void)CBX_Lock(0); XGetWindowAttributes(amb->disp,amb->box,&xwa); /* get window attributes */ if (xwa.width < w) { XResizeWindow(amb->disp,amb->box,w,xwa.height); XMoveWindow(amb->disp,amb->but.win,(w-6*PXw)/2,4*PXh); } XClearWindow(amb->disp,amb->box); CBX_Unlock(); CBX_SendExpose_Ext(amb->disp,amb->box); } /* ---------------------------------------------------------------- */ static void* amb_AsyncAbortBoxOpen(void* param) { MainWindow mwin; int w=11*PXw,w1,w2; const int h=6*PXh,ABy=h-2*PXh,ABw=6*PXw; XSizeHints hint; XEvent event; AMB *amb=(AMB*)param; w1 = PXw*(strlen(amb->title)+3); w2 = PXw*(strlen(amb->text)+1); w = cbx_max(w,cbx_max(w1,w2)); amb->box = CXT_OpenMainWindow(&mwin,CBX_CENTER,w,h,&hint,amb->title, "AbortBox",False); amb->disp = mwin.disp; #if (XDEBUG > 0) (void)CBX_Lock(0); XSynchronize(amb->disp,True); CBX_Unlock(); #endif amb->gfs = CBX_CreateGfC(&mwin,cbx_genv2("CBXFONT","courier"),"bold",PXh); w1 = CBX_TextWidth(&mwin,amb->title)+3*PXw; w2 = CBX_TextWidth(&mwin,amb->text)+PXw; w = cbx_max(w,cbx_max(w1,w2)); CBX_ResizeMainWindow(&mwin,w,h); (void)CBX_CreateButton(&mwin,&amb->but,(w-5*PXw)/2,ABy,ABw,XXh,"Abort"); while (amb->done == 0) { /* event loop */ (void)CBX_Lock(0); if (XCheckTypedWindowEvent(amb->disp,amb->box,Expose,&event)) { XDrawString(amb->disp,amb->box,amb->gfs.gc,PXw,2*PXh, amb->text,strlen(amb->text)); CBX_Unlock(); CBX_UpdateButton(&amb->but); } else if (XCheckTypedWindowEvent(amb->disp,amb->but.win,ButtonPress,&event)) { CBX_Unlock(); if (CBX_HandleButton(&amb->but) == CBX_PRESSED) amb->done = 1; } else { CBX_Unlock(); cbx_msleep(200); } } /* while(!done) */ CBX_ClearXQueue_Ext(amb->disp); CBX_CloseMainWindow(&mwin); return(NULL); } /* ---------------------------------------------------------------- */ static char* cbx_genv2(char *first,char *def_pointer) { if (getenv(first) == NULL) return(def_pointer); return(getenv(first)); } /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */