1head 1.1; 2access; 3symbols; 4locks 5 juhana:1.1; strict; 6comment @ * @; 7 8 91.1 10date 98.10.28.21.50.29; author juhana; state Exp; 11branches; 12next ; 13 14 15desc 16@@ 17 18 191.1 20log 21@Initial revision 22@ 23text 24@/* 25 * xwave - an interactive audio player, recorder, editor 26 * for the XWindow System 27 * 28 * Copyright (C) 1996 Kai Kollmorgen 29 * (kkollmor@@informatik.uni-rostock.de) 30 * 31 * 32 * This program is free software; you can redistribute it and/or modify 33 * it under the terms of the GNU General Public License as published by 34 * the Free Software Foundation; either version 2 of the License, or 35 * (at your option) any later version. 36 * 37 * This program is distributed in the hope that it will be useful, 38 * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 * GNU General Public License for more details. 41 * 42 * You should have received a copy of the GNU General Public License 43 * along with this program; if not, write to the Free Software 44 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 45 * 46 */ 47 48#include <stdio.h> 49#include <stdlib.h> 50#include <unistd.h> 51#include <fcntl.h> 52#include <dirent.h> 53 54#include <X11/Xlib.h> /* GC and other */ 55#include <X11/Intrinsic.h> /* Intrinsics Definitions */ 56#include <X11/StringDefs.h> /* Standard Name-String definitions */ 57#include <X11/Shell.h> 58#include <X11/Xatom.h> 59#include <X11/cursorfont.h> 60 61#include <X11/Xaw/Box.h> /*Athena Widget Set */ 62#include <X11/Xaw/Form.h> 63#include <X11/Xaw/Simple.h> 64#include <X11/Xaw/Label.h> 65#include <X11/Xaw/Scrollbar.h> 66 67#include "types.h" 68#include "xwave.h" 69#include "menu.h" 70#include "button.h" 71#include "status.h" 72#include "audio.h" 73#include "audio_file.h" 74#include "misc.h" 75#include "xwave_widget.h" 76#include "sample_settings.h" 77#include "graphics.h" 78#include "record_dialog.h" 79#include "filebrowse.h" 80#include "fileop.h" 81#include "bitmaps/xwave.xbm" 82#include "bitmaps/canvas.xbm" 83 84static void setwave_action (Widget w,Next_Wave *nw, XEvent *event, 85 Boolean *flg); 86static void delete_toplevel (Widget w,Main_Data *md, XEvent *event, 87 Boolean *flg); 88static void reparent_canvas (Widget w,Next_Wave *nw, XReparentEvent *event, 89 Boolean *flg); 90static void reparent_toplevel (Widget w,Main_Data *md, XReparentEvent *event, 91 Boolean *flg); 92static void pop_canvas_menu (Widget w,Main_Data *md, XButtonEvent *event, 93 Boolean *flg); 94static void usage(); 95static void XtWarningHandler(String msg); 96 97/* in this struct we have all data about open files */ 98 99Main_Data *MD; 100 101AppResources app_resources; 102 103static Cursor previewC[3]; 104static Atom delwin=None,protocols=None,focus=None; 105static char **load_files; 106static int no_load_files; 107 108static XtResource resources[] = { 109 {"version","Version",XtRString,sizeof(String), 110 XtOffsetOf(AppResources,version),XtRImmediate,"0.0"}, 111 {"device","Device",XtRString,sizeof(String), 112 XtOffsetOf(AppResources,device),XtRImmediate,"/dev/dsp"}, 113 {"wdir","WDir",XtRString,sizeof(String), 114 XtOffsetOf(AppResources,wdir),XtRImmediate,"."}, 115 {"tdir","TDir",XtRString,sizeof(String), 116 XtOffsetOf(AppResources,tdir),XtRImmediate,"/tmp"}, 117 {"wavemainfgl","WaveMainFgl",XtRString,sizeof(String), 118 XtOffsetOf(AppResources,wavemainfgl),XtRImmediate,"blue"}, 119 {"wavemainfgr","WaveMainFgr",XtRString,sizeof(String), 120 XtOffsetOf(AppResources,wavemainfgr),XtRImmediate,"red"}, 121 {"markcolor","MarkColor",XtRString,sizeof(String), 122 XtOffsetOf(AppResources,markcolor),XtRImmediate,"green"}, 123 {"default_recname","Default_recname",XtRString,sizeof(String), 124 XtOffsetOf(AppResources,default_recname),XtRImmediate,"record"}, 125 {"default_newname","Default_newname",XtRString,sizeof(String), 126 XtOffsetOf(AppResources,default_newname),XtRImmediate,"unnamed"}, 127 {"playlinefg","PlayLineFg",XtRString,sizeof(String), 128 XtOffsetOf(AppResources,playlinefg),XtRImmediate,"black"}, 129 {"err_overwrite","Err_overwrite",XtRString,sizeof(String), 130 XtOffsetOf(AppResources,err_overwrite),XtRImmediate,"not defined"}, 131 {"err_openfile","Err_openfile",XtRString,sizeof(String), 132 XtOffsetOf(AppResources,err_openfile),XtRImmediate,"not defined"}, 133 {"err_fileinuse","Err_fileinuse",XtRString,sizeof(String), 134 XtOffsetOf(AppResources,err_fileinuse),XtRImmediate,"not defined"}, 135 {"err_modified","Err_modified",XtRString,sizeof(String), 136 XtOffsetOf(AppResources,err_modified),XtRImmediate,"not defined"}, 137 {"err_16bit","Err_16bit",XtRString,sizeof(String), 138 XtOffsetOf(AppResources,err_16bit),XtRImmediate,"not defined"}, 139 {"err_stereo","Err_stereo",XtRString,sizeof(String), 140 XtOffsetOf(AppResources,err_stereo),XtRImmediate,"not defined"}, 141 {"err_44khz","Err_44khz",XtRString,sizeof(String), 142 XtOffsetOf(AppResources,err_44khz),XtRImmediate,"not defined"}, 143 {"err_44khzstereo","Err_44khzstereo",XtRString,sizeof(String), 144 XtOffsetOf(AppResources,err_44khzstereo), 145 XtRImmediate,"not defined"}, 146 {"err_permissions","Err_permissions",XtRString,sizeof(String), 147 XtOffsetOf(AppResources,err_permissions), 148 XtRImmediate,"not defined"}, 149 {"err_notsupported","Err_notsupported",XtRString,sizeof(String), 150 XtOffsetOf(AppResources,err_notsupported),XtRImmediate, 151 "not defined"}, 152 {"err_wrongformat","Err_wrongformat",XtRString,sizeof(String), 153 XtOffsetOf(AppResources,err_wrongformat),XtRImmediate, 154 "not defined"}, 155 {"err_mem","Err_mem",XtRString,sizeof(String), 156 XtOffsetOf(AppResources,err_mem),XtRImmediate,"not defined"}, 157 {"err_input","Err_input",XtRString,sizeof(String), 158 XtOffsetOf(AppResources,err_input),XtRImmediate,"not defined"}, 159 {"err_bg","Err_bg",XtRString,sizeof(String), 160 XtOffsetOf(AppResources,err_bg),XtRImmediate,"not defined"}, 161 {"err_nohome","Err_nohome",XtRString,sizeof(String), 162 XtOffsetOf(AppResources,err_nohome),XtRImmediate,"not defined"}, 163 {"err_notmp","Err_notmp",XtRString,sizeof(String), 164 XtOffsetOf(AppResources,err_notmp),XtRImmediate,"not defined"}, 165 {"err_notimplement","Err_notimplement",XtRString,sizeof(String), 166 XtOffsetOf(AppResources,err_notimplement),XtRImmediate, 167 "not defined"}, 168 {"default_ext","Default_ext",XtRString,sizeof(String), 169 XtOffsetOf(AppResources,default_ext),XtRImmediate,"*wav"}, 170 {"maxmem","MaxMem",XtRInt,sizeof(int), 171 XtOffsetOf(AppResources,maxmem),XtRImmediate,(XtPointer)1000}, 172 {"cv_maxpoints","CV_Maxpoints",XtRInt,sizeof(int), 173 XtOffsetOf(AppResources,cv_maxpoints),XtRImmediate,(XtPointer)10}, 174 {"default_ftype","Default_ftype",XtRInt,sizeof(int), 175 XtOffsetOf(AppResources,default_comp),XtRImmediate,(XtPointer)0}, 176 {"default_comp","Default_comp",XtRInt,sizeof(int), 177 XtOffsetOf(AppResources,default_comp),XtRImmediate,(XtPointer)0}, 178 {"doubleplay","DoublePlay",XtRBoolean,sizeof(Boolean), 179 XtOffsetOf(AppResources,doubleplay),XtRImmediate,(XtPointer)True}, 180 {"raisecanvas","RaiseCanvas",XtRBoolean,sizeof(Boolean), 181 XtOffsetOf(AppResources,raisecanvas),XtRImmediate,(XtPointer)True} 182}; 183 184static XrmOptionDescRec options[] = { 185 { "-device",".device",XrmoptionSepArg,(XtPointer)"/dev/dsp"}, 186 { "-wdir",".wdir",XrmoptionSepArg,(XtPointer)"."}, 187 { "-maxmem",".maxmem",XrmoptionSepArg,(XtPointer)1000} 188}; 189 190 191static String fallback_resources[]={ 192 NULL, 193}; 194 195static void usage() 196{ 197 printf("XWave Version %s:\n\n",VERSION); 198 printf("-?, -h, -help, display this help.\n"); 199 printf("-device, the play/rec device (usually /dev/dsp).\n"); 200 printf("-wdir, set working directory.\n"); 201 printf("-maxmem, max. amount of memory to load whole sample in memory.\n"); 202 printf("If sample is greater than maxmem, we do everything on HDD.\n"); 203 exit(1); 204} 205 206void XtWarningHandler(String msg) 207{ 208 if (strncmp(msg,"XtRemoveGrab",strlen("XtRemoveGrab"))==0) return; 209 if (MD!=NULL) 210 warn_popup(MD->mw->form,msg); 211 else printf("%s\n",msg); 212} 213 214 215void main (int argc, char *argv[]) 216{ 217 XtAppContext context; 218 Widget toplevel,form,widget,graph; 219 Pixmap xwIcon; 220 XGCValues xgcv; 221 Dimension width,height; 222 Display *dpy; 223 XSetWindowAttributes wattr; 224 225 /* 226#if defined (_LITTLE_ENDIAN) || BYTE_ORDER == LITTLE_ENDIAN 227 printf("little_endian\n"); 228#endif 229#if defined (_BIG_ENDIAN) || BYTE_ORDER == BIG_ENDIAN 230 printf("big_endian\n"); 231#endif 232 */ 233 234 MD=NULL; 235 toplevel = XtVaAppInitialize (&context, 236 "XWave", 237 options, XtNumber(options), 238 &argc, argv, 239 fallback_resources, 240 NULL); 241 242 XtGetApplicationResources(toplevel,(XtPointer)&app_resources, 243 resources,XtNumber(resources),NULL,0); 244 245 if (argc>1) { 246 int i; 247 if (strcmp(argv[1],"-?")==0) usage(); 248 if (strcmp(argv[1],"-h")==0) usage(); 249 if (strcmp(argv[1],"-help")==0) usage(); 250 if (strcmp(argv[1],"-wdir")==0) usage(); 251 if (strcmp(argv[1],"-maxmem")==0) usage(); 252 if (strcmp(argv[1],"-device")==0) usage(); 253 no_load_files=argc-1; 254 load_files=(char **) XtCalloc(sizeof(char**),argc); 255 for (i=1;i<argc;i++) { 256 load_files[i-1]=argv[i]; 257 } 258 } 259 260 if (strcmp(app_resources.version,"0.0")==0) { 261 initwarn_popup(toplevel,NORESOURCE); 262 } 263 264 if (strcmp(app_resources.version,VERSION)!=0) { 265 initwarn_popup(toplevel,WRONGRESOURCE); 266 } 267 268 XtAppSetWarningHandler(context,(XtErrorHandler) XtWarningHandler); 269 dpy=XtDisplay(toplevel); 270 271 /* 272 XSynchronize(dpy,TRUE); 273 */ 274 /* alloc mem for Main_Data (this is global) */ 275 276 if ((MD=calloc(sizeof(Main_Data),1))==NULL) { 277 initwarn_popup(toplevel,app_resources.err_mem); 278 exit(-1); 279 } 280 MD->mb=calloc(sizeof(Main_Bool),1); 281 MD->mg=calloc(sizeof(Main_Graphic),1); 282 MD->mw=calloc(sizeof(Main_Widget),1); 283 MD->cd=calloc(sizeof(Clip_Data),1); 284 if ((MD->mb==NULL)||(MD->mg==NULL)||(MD->mw==NULL)||(MD->cd==NULL)) { 285 initwarn_popup(toplevel,app_resources.err_mem); 286 exit(-1); 287 } 288 MD->nw=NULL; 289 MD->wd=NULL; 290 if ((MD->cd->wd=calloc(sizeof(Wave_Data),1))==NULL) { 291 initwarn_popup(toplevel,app_resources.err_mem); 292 exit(-1); 293 } 294 if ((MD->cd->wd->name= 295 calloc(strlen(app_resources.tdir)+strlen(CLIPFILE)+1,1))==NULL) { 296 initwarn_popup(toplevel,app_resources.err_mem); 297 exit(-1); 298 } 299 sprintf(MD->cd->wd->name,"%s/%s",app_resources.tdir,CLIPFILE); 300 301 MD->mg->pixmap=None; 302 MD->maxmem=app_resources.maxmem * 1024; 303 if ((MD->mg->fbuf=(ushort*) malloc(MAXUSHORT))==NULL) { 304 initwarn_popup(toplevel,app_resources.err_mem); 305 exit(-1); 306 } 307 308 /* get environment variables */ 309 310 if ((MD->home=getenv(HOME_ENV))==NULL) { 311 initwarn_popup(toplevel,app_resources.err_nohome); 312 exit(-1); 313 } 314#ifdef sun 315 if (getenv(AUDIODEV_ENV)!=NULL) app_resources.device=getenv(AUDIODEV_ENV); 316#endif 317 /* set the tmp directory, should really have permissions to write here */ 318 if (!can_write(app_resources.tdir)) { 319 if (can_write(TMP)) { 320 if (strlen(app_resources.tdir)>=strlen(TMP)) 321 strcpy(app_resources.tdir,TMP); 322 else app_resources.tdir=XtNewString(TMP); 323 } else { 324 if (can_write(MD->home)) app_resources.tdir=MD->home; 325 else { 326 initwarn_popup(toplevel,app_resources.err_notmp); 327 exit(-1); 328 } 329 } 330 } 331 check_audio(MD->mb); 332 if (!MD->mb->canplay) app_resources.device=XtNewString("no device"); 333 334 MD->no=0; 335 MD->mb->playing=False; 336 MD->mb->exposing=False; 337 MD->mb->isclip=False; 338 339 form = MW ("main_form",formWidgetClass,toplevel,NULL); 340 MD->mw->form=form; 341 342 widget= MW ("menu_form",formWidgetClass,form, 343 XtNtop,XawChainTop,XtNbottom,XawChainTop, 344 XtNleft,XawChainLeft,XtNright,XawChainRight, 345 NULL); 346 347 create_topmenu(widget); 348 349 widget=MW ("main_line",formWidgetClass,form, 350 XtNfromVert,widget,XtNborderWidth,2, 351 XtNtop,XawChainTop,XtNbottom,XawChainTop, 352 XtNleft,XawChainLeft,XtNright,XawChainRight, 353 NULL); 354 355 widget=MW ("border_form",formWidgetClass,form, 356 XtNfromVert,widget,XtNborderWidth,0, 357 XtNtop,XawChainTop,XtNbottom,XawChainTop, 358 XtNleft,XawChainLeft,XtNright,XawChainLeft, 359 NULL); 360 361 create_button(widget); 362 363 graph=MW ("main_graph",simpleWidgetClass,form, 364 XtNfromVert,widget,XtNheight,PREVIEWHEIGHT, 365 XtNtop,XawChainBottom,XtNbottom,XawChainBottom,NULL); 366 367 MD->mw->graph=graph; 368 xgcv.foreground=ConvertColor(graph,app_resources.wavemainfgl); 369 MD->mg->gcl=XtGetGC(MD->mw->graph,GCForeground, &xgcv); 370 xgcv.foreground=ConvertColor(graph,app_resources.wavemainfgr); 371 MD->mg->gcr=XtGetGC(MD->mw->graph,GCForeground, &xgcv); 372 xgcv.foreground=ConvertColor(graph,app_resources.markcolor); 373 xgcv.function=GXxor; 374 MD->mg->markgc=XtGetGC(MD->mw->graph,GCForeground|GCFunction,&xgcv); 375 xgcv.foreground=ConvertColor(graph,app_resources.playlinefg); 376 MD->mg->playgc=XtGetGC(MD->mw->graph,GCForeground, &xgcv); 377 378 XtVaGetValues(MD->mw->form,XtNcursor,&previewC[CURSOR_DEFAULT],NULL); 379 previewC[CURSOR_MARK]=XCreateFontCursor(dpy,XC_sb_h_double_arrow); 380 previewC[CURSOR_CLOCK]=XCreateFontCursor(dpy,XC_watch); 381 382 widget=MW ("status_form",formWidgetClass,form, 383 XtNfromVert,graph,XtNborderWidth,0, 384 XtNtop,XawChainBottom,XtNbottom,XawChainBottom, 385 XtNleft,XawChainLeft,XtNright,XawChainRight, 386 NULL); 387 388 create_status(widget); 389 390 /* create ATOM WM_DELETE_WINDOW and WM_TAKEFOCUS, this is for the DELETE 391 * MenuItem of WINDOWMANAGERS 392 * the Properties are only set, if an REPARENT EVENT occurs 393 * most of the WM use this to set an own window (i hope) 394 */ 395 396 delwin=XInternAtom(dpy, "WM_DELETE_WINDOW", TRUE); 397 focus=XInternAtom(dpy, "WM_TAKE_FOCUS", TRUE); 398 protocols = XInternAtom(dpy, "WM_PROTOCOLS", TRUE); 399 400 XtAddEventHandler(toplevel, StructureNotifyMask, FALSE, 401 (XtEventHandler)reparent_toplevel, (XtPointer) MD); 402 403 create_canvas_menu(toplevel,MD->mw); 404 405 XtRealizeWidget(toplevel); 406 407 /* create the file_dialog datas, now we can popup file_dialog very fast */ 408 create_file_dialog(toplevel); 409 410 /* create the sample_dialog data */ 411 create_sample_dialog(toplevel); 412 413 /* create the record_dialog data */ 414 create_record_dialog(toplevel); 415 416 /* set the icon for main window */ 417 xwIcon = XCBFD(dpy,XtWindow(form),(char *)xwave_bits, 418 xwave_width, xwave_height); 419 420 /* set min,max width and height and icon */ 421 XtVaSetValues(toplevel,XtNiconPixmap,xwIcon,NULL); 422 XtVaGetValues(toplevel,XtNheight,&height,XtNwidth,&width,NULL); 423 XtVaSetValues(toplevel,XtNminWidth,width,XtNmaxHeight,height,XtNminHeight, 424 height,NULL); 425 426 XtAddEventHandler(graph, ExposureMask, FALSE, 427 (XtEventHandler)expose_action, (XtPointer) MD); 428 XtAddEventHandler(graph, StructureNotifyMask, FALSE, 429 (XtEventHandler)config_action, (XtPointer) MD); 430 XtAddEventHandler(graph, Button1MotionMask, FALSE, 431 (XtEventHandler)mark_action, (XtPointer) MD); 432 XtAddEventHandler(graph, ButtonPressMask, FALSE, 433 (XtEventHandler)buttonp_action, (XtPointer) MD); 434 XtAddEventHandler(graph, ButtonReleaseMask, FALSE, 435 (XtEventHandler)buttonr_action, (XtPointer) MD); 436 437 /* if server can backing store, we want backing store */ 438 wattr.backing_store=DoesBackingStore(DefaultScreenOfDisplay(dpy)); 439 XChangeWindowAttributes(dpy,XtWindow(graph),CWBackingStore,&wattr); 440 441 XtAppMainLoop(context); 442} 443 444void new_canvas(Widget w,Next_Wave *nw) 445{ 446 Widget popup,form; 447 Pixmap cwIcon; 448 static XtTranslations trans; 449 XGCValues xgcv; 450 Dimension width,height; 451 Display *dpy; 452 XSetWindowAttributes wattr; 453 454 trans= XtParseTranslationTable("<Btn3Down>: XtMenuPopup(cv_menu)"); 455 popup=XtVaCreatePopupShell(nw->wd->name,topLevelShellWidgetClass,w,NULL); 456 457 nw->cw->popup=popup; 458 nw->cg->pixmap=None; 459 460 form = MW ("cv_main_form",formWidgetClass,popup, 461 XtNresizable,TRUE, 462 XtNborderWidth,0, 463 NULL); 464 465 466 nw->cw->graph= MW ("cv_graph",simpleWidgetClass,form, 467 XtNtranslations, trans, 468 XtNtop,XawChainTop,XtNbottom,XawChainBottom, 469 XtNleft,XawChainLeft,XtNright,XawChainRight, 470 NULL); 471 472 nw->cw->scroll = MW ("cv_pos_scroll", scrollbarWidgetClass,form, 473 XtNfromVert,nw->cw->graph, 474 XtNorientation,XtorientHorizontal, 475 XtNtop,XawChainBottom,XtNbottom,XawChainBottom, 476 XtNleft,XawChainLeft,XtNright,XawChainRight, 477 NULL); 478 479 XtVaGetValues(nw->cw->graph,XtNwidth,&width,NULL); 480 XtVaSetValues(nw->cw->scroll,XtNwidth,width,NULL); 481 482 nw->cw->zscroll = MW ("cv_zoom_scroll", scrollbarWidgetClass,form, 483 XtNfromHoriz,nw->cw->graph, 484 XtNorientation,XtorientVertical, 485 XtNtop,XawChainTop,XtNbottom,XawChainBottom, 486 XtNleft,XawChainRight,XtNright,XawChainRight,NULL); 487 488 XtVaGetValues(nw->cw->graph,XtNheight,&height,NULL); 489 XtVaSetValues(nw->cw->zscroll,XtNheight,height,NULL); 490 491 xgcv.foreground=ConvertColor(nw->cw->graph,app_resources.wavemainfgl); 492 nw->cg->gcl=XtGetGC(nw->cw->graph,GCForeground, &xgcv); 493 xgcv.foreground=ConvertColor(nw->cw->graph,app_resources.wavemainfgr); 494 nw->cg->gcr=XtGetGC(nw->cw->graph,GCForeground, &xgcv); 495 xgcv.foreground=ConvertColor(nw->cw->graph,app_resources.markcolor); 496 xgcv.function=GXxor; 497 nw->cg->markgc=XtGetGC(nw->cw->graph,GCForeground|GCFunction,&xgcv); 498 499 XtAddEventHandler(popup, StructureNotifyMask, False, 500 (XtEventHandler)reparent_canvas, (XtPointer) nw); 501 502 XtAddEventHandler(nw->cw->graph, ButtonPressMask|Button1MotionMask, False, 503 (XtEventHandler)mark_canvas, (XtPointer) MD); 504 505 XtPopup(popup,XtGrabNone); 506 507 XtAddEventHandler(nw->cw->graph, ExposureMask, False, 508 (XtEventHandler)expose_canvas, (XtPointer) MD); 509 XtAddEventHandler(nw->cw->graph, StructureNotifyMask, False, 510 (XtEventHandler)config_canvas, (XtPointer) MD); 511 512 XtVaGetValues(popup,XtNheight,&height,XtNwidth,&width,NULL); 513 XtVaSetValues(popup,XtNminWidth,width/2,XtNminHeight,height/2,NULL); 514 515 XtAddCallback(nw->cw->scroll, XtNjumpProc, jump_canvas, (XtPointer) MD); 516 XtAddCallback(nw->cw->scroll, XtNscrollProc, scroll_canvas, (XtPointer) MD); 517 518 XtAddCallback(nw->cw->zscroll, XtNjumpProc, zjump_canvas, (XtPointer) MD); 519 XtAddCallback(nw->cw->zscroll, XtNscrollProc, zscroll_canvas, 520 (XtPointer) MD); 521 522 XtAddEventHandler(nw->cw->graph, ButtonPressMask, False, 523 (XtEventHandler)pop_canvas_menu, (XtPointer) MD); 524 525 /* if server can backing store, we want backing store */ 526 dpy=XtDisplay(nw->cw->graph); 527 wattr.backing_store=DoesBackingStore(DefaultScreenOfDisplay(dpy)); 528 XChangeWindowAttributes(dpy,XtWindow(nw->cw->graph),CWBackingStore,&wattr); 529 530 cwIcon = XCBFD(dpy,XtWindow(form),(char *)canvas_bits, 531 canvas_width, canvas_height); 532 XtVaSetValues(popup,XtNiconPixmap,cwIcon,NULL); 533 534 add_menu_entry(nw); 535} 536 537static void setwave_action (Widget w,Next_Wave *nw, XEvent *event, 538 Boolean *flg) 539{ 540 XClientMessageEvent *cevent=(XClientMessageEvent*)event; 541 if (MD->mb->exposing) return; 542 if (cevent->type!=ClientMessage) return; 543 if (cevent->message_type==protocols && cevent->data.l[0]==focus) 544 set_actual_canvas(nw); 545 if (cevent->message_type==protocols && cevent->data.l[0]==delwin) { 546 if (MD->mb->playing) { 547 warn_popup(w,"Stop playing to close file !"); 548 return; 549 } 550 close_call(w,MD,NULL); 551 } 552} 553 554void set_actual_canvas(Next_Wave *nw) 555{ 556 557 if (MD->wd==nw->wd) return; 558 if (MD->mb->playing) return; 559 560 MD->wd=nw->wd; 561 MD->cw=nw->cw; 562 MD->cb=nw->cb; 563 MD->cg=nw->cg; 564 MD->mg->step=(float)MD->wd->tlength/(float)MD->mg->width; 565 566 if (app_resources.raisecanvas) window_order(nw->cw->popup,Above); 567 568 update_display(MD); 569 return; 570} 571 572static void reparent_canvas (Widget w,Next_Wave *nw, XReparentEvent *event, 573 Boolean *flg) 574{ 575 if (event->type!=ReparentNotify) return; 576 577 XtAddRawEventHandler(w, 0, True, 578 (XtEventHandler)setwave_action, (XtPointer) nw); 579 if (delwin!=None || protocols!=None) { 580 XChangeProperty(XtDisplay(w), XtWindow(w), 581 protocols,XA_ATOM, 32, PropModeReplace, 582 (unsigned char *) &delwin, 1); 583 } 584 if (focus!=None || protocols!=None) { 585 XChangeProperty(XtDisplay(w), XtWindow(w), 586 protocols,XA_ATOM, 32, PropModeAppend, 587 (unsigned char *) &focus, 1); 588 } 589} 590 591static void reparent_toplevel (Widget w,Main_Data *md, XReparentEvent *event, 592 Boolean *flg) 593{ 594 Display *dpy=XtDisplay(w); 595 if (event->type!=ReparentNotify) return; 596 597 XtAddRawEventHandler(w, 0, TRUE, 598 (XtEventHandler)delete_toplevel, (XtPointer) md); 599 600 if (delwin!=None || protocols!=None) { 601 XChangeProperty(dpy, XtWindow(w), 602 protocols,XA_ATOM, 32, PropModeReplace, 603 (unsigned char *) &delwin, 1); 604 } 605 md->mg->lpixmap=XCreatePixmap(dpy, XtWindow(md->mw->graph),1/*width*/, 606 PREVIEWHEIGHT, 607 DefaultDepth(dpy,DefaultScreen(dpy))); 608 609 if (no_load_files>0) { 610 int i,type; 611 for (i=0;i<no_load_files;i++) { 612 fprintf(stderr,"Loading %s... ",load_files[i]); 613 fflush(stderr); 614 type=load_file(load_files[i],AF_NORAW,AF_COMP_UNDEFINED); 615 switch (type) { 616 case AF_ERROR: 617 fprintf(stderr,"error.\n"); 618 break; 619 case AF_RAW: 620 fprintf(stderr,"can't load raw files from cmdline !\n"); 621 break; 622 case AF_NOTSUPPORTED: 623 fprintf(stderr,"filetype not supported !\n"); 624 break; 625 default: 626 fprintf(stderr,"done.\n"); 627 break; 628 } 629 } 630 } 631 XtFree((char*)load_files); 632 633 update_status(md); 634 635 /* set working directory to wdir-Resource */ 636 chdir(app_resources.wdir); 637 /* 638 if (XInternAtom(dpy, "_SUN_WM_PROTOCOLS", TRUE)!=None) 639 warn_popup(w,"SUN WM present (olwm,olvwm), expect problems !"); 640 */ 641 if (DoesBackingStore(DefaultScreenOfDisplay(dpy))==NotUseful) { 642 warn_popup(w,"Your X-Server doesn't support BackingStore !\nThis will slow down the screen updates !"); 643 } 644 if (!MD->mb->canplay) { 645 warn_popup(w,"Couldn't access audio device !\nNo play and record !"); 646 } 647} 648 649static void delete_toplevel (Widget w,Main_Data *md, XEvent *event, 650 Boolean *flg) 651{ 652 XClientMessageEvent *cevent=(XClientMessageEvent*)event; 653 if (md->mb->exposing) return; 654 if (cevent->type!=ClientMessage) return; 655 if (cevent->message_type==protocols && cevent->data.l[0]==delwin) 656 if (md->mb->playing) { 657 warn_popup(w,"Stop playing to quit !"); 658 return; 659 } 660 quit_call(w,md,NULL); 661} 662 663void set_cursor(Widget w,byte which) 664{ 665 XtVaSetValues(w,XtNcursor,previewC[which],NULL); 666} 667 668void watch_cursor(bool state) 669{ 670 Window win=XtWindow(FindWmShell(MD->mw->form)); 671 Display *dpy=XtDisplay(MD->mw->form); 672 Next_Wave *nw=MD->nw; 673 674 if (state) { 675 XDefineCursor(dpy,win,previewC[CURSOR_CLOCK]); 676 while (nw!=NULL) { 677 win=XtWindow(FindWmShell(nw->cw->popup)); 678 dpy=XtDisplay(nw->cw->popup); 679 XDefineCursor(dpy,win,previewC[CURSOR_CLOCK]); 680 nw=nw->nw; 681 } 682 } else { 683 XUndefineCursor(dpy,win); 684 while (nw!=NULL) { 685 win=XtWindow(FindWmShell(nw->cw->popup)); 686 dpy=XtDisplay(nw->cw->popup); 687 XUndefineCursor(dpy,win); 688 nw=nw->nw; 689 } 690 } 691 XFlush(dpy); 692} 693 694static void pop_canvas_menu (Widget w,Main_Data *md, XButtonEvent *event, 695 Boolean *flg) 696{ 697 if (event->button==3) { /* right mbutton (3-chord-mouse) */ 698 Screen *scr=XtScreen(w); 699 Position x,y; 700 Dimension width,height; 701 702 x=event->x_root; 703 y=event->y_root; 704 XtVaGetValues(md->mw->cmenu,XtNwidth,&width,XtNheight,&height,NULL); 705 if (y>scr->height-height) y-=y+height-scr->height; 706 else y-=10; 707 if (x<width/2) x=0; 708 else if (x<scr->width-width/2) x-=width/2; 709 else { 710 width-=scr->width-x; 711 x-=width; 712 } 713 XtVaSetValues(md->mw->cmenu,XtNx,x,XtNy,y,NULL); 714 } 715 if (!md->mb->playing) { 716 set_cmenu_state(CM_ZOOM,CM_COPY,md->wd->ismark); 717 set_cmenu_state(CM_PASTE_I,CM_PASTE_M,md->mb->isclip); 718 } 719} 720 721@ 722