#include #include #include #include #include #include #include #include #define WORLD_XMIN 0.0 #define WORLD_XMAX 200.0 #define WORLD_YMIN 0.0 #define WORLD_YMAX 200.0 #define GREY 8 #define MOUSE_OBJ 1 #define LEN 700.0 /*** (^_^;) Bug Recovery of SGI Media Library --> Original MIDI Defines !! (^_^;) ***/ #define MES(x) ( (x[0]).mm.msgbuf ) #define midi_set_status(x,d) ( MES(x) = ( ( d > 0xbf ) && ( d < 0xe0 ) ) ? 0x40000000 : 0x60000000, \ MES(x) &= 0xff0fffff, MES(x) |= ( ( d & 0xf0 ) << 16 ) ) #define midi_set_channel(x,d) ( MES(x) &= 0xfff0ffff, MES(x) |= ( ( d & 0x0f ) << 16 ) ) #define midi_set_keyno(x,d) ( MES(x) &= 0xffff00ff, MES(x) |= ( ( d & 0x7f ) << 8 ) ) #define midi_set_velocity(x,d) ( MES(x) &= 0xffffff00, MES(x) |= ( d & 0x7f ) ) MIport *midi_port; MIevent midi[100]; XtAppContext app_context; int mx, my, xmin, xmax, ymin, ymax, button[3], color_no, action_mode, error_st; float xrat, yrat, cx, cy; int mode_color_table[7] = { 9, 10, 11, 12, 13, 14, 15 }; void init_window(), do_resize(), input(), draw_screen(), quit(), clear_screen(); void draw_mode(), paint_mode(), stamp_mode(), effect_mode(), erase_mode(); void midi_initialize(), midi_event_generate(), midi_transmit(), midi_tx_3byte(); main(int argc, char **argv) { Arg args[20]; int n; Widget glw, toplevel, form, frame, pushb[10]; GLXconfig glxConfig [] = { { GLX_NORMAL, GLX_RGB, FALSE }, { GLX_NORMAL, GLX_DOUBLE, TRUE }, { 0,0,0 }, }; long background[] = { 0, 0, 0 }; toplevel = XtAppInitialize(&app_context, "", (XrmOptionDescList)NULL , 0, (Cardinal*)&argc, (String*)argv, (String*)NULL, (ArgList)NULL, 0); n = 0; XtSetArg(args[n], XtNwidth, 600); n++; XtSetArg(args[n], XtNheight, 350); n++; form = XtCreateManagedWidget("", xmFormWidgetClass, toplevel, args, n); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomOffset, 10); n++; XtSetArg(args[n], XmNrightOffset, 40); n++; pushb[0] = XtCreateManagedWidget("Quit", xmPushButtonWidgetClass, form, args, n); XtAddCallback(pushb[0], XmNactivateCallback, quit,0); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomOffset, 10); n++; XtSetArg(args[n], XmNleftOffset, 40); n++; pushb[1] = XtCreateManagedWidget("Draw", xmPushButtonWidgetClass, form, args, n); XtAddCallback(pushb[1], XmNactivateCallback, draw_mode,0); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomOffset, 10); n++; XtSetArg(args[n], XmNleftWidget, pushb[1]); n++; XtSetArg(args[n], XmNleftOffset, 30); n++; pushb[2] = XtCreateManagedWidget("Paint", xmPushButtonWidgetClass, form, args, n); XtAddCallback(pushb[2], XmNactivateCallback, paint_mode,0); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomOffset, 10); n++; XtSetArg(args[n], XmNleftWidget, pushb[2]); n++; XtSetArg(args[n], XmNleftOffset, 30); n++; pushb[3] = XtCreateManagedWidget("Stamp", xmPushButtonWidgetClass, form, args, n); XtAddCallback(pushb[3], XmNactivateCallback, stamp_mode,0); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomOffset, 10); n++; XtSetArg(args[n], XmNleftWidget, pushb[3]); n++; XtSetArg(args[n], XmNleftOffset, 30); n++; pushb[4] = XtCreateManagedWidget("Effect", xmPushButtonWidgetClass, form, args, n); XtAddCallback(pushb[4], XmNactivateCallback, effect_mode,0); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomOffset, 10); n++; XtSetArg(args[n], XmNleftWidget, pushb[4]); n++; XtSetArg(args[n], XmNleftOffset, 30); n++; pushb[5] = XtCreateManagedWidget("Erase", xmPushButtonWidgetClass, form, args, n); XtAddCallback(pushb[5], XmNactivateCallback, erase_mode,0); n = 0; XtSetArg(args[n], XtNx, 30); n++; XtSetArg(args[n], XtNy, 30); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopOffset, 20); n++; XtSetArg(args[n], XmNleftOffset, 20); n++; XtSetArg(args[n], XmNrightOffset, 20); n++; XtSetArg(args[n], XmNbottomWidget, pushb[0]); n++; XtSetArg(args[n], XmNbottomOffset, 10); n++; frame = XtCreateManagedWidget("", xmFrameWidgetClass, form, args, n); n = 0; XtSetArg(args[n], GlxNglxConfig, glxConfig); n++; glw = XtCreateManagedWidget("", glxMDrawWidgetClass, frame, args, n); XtAddCallback(glw, GlxNginitCallback, init_window, 0); XtAddCallback(glw, GlxNinputCallback, input, 0); XtAddCallback(glw, GlxNresizeCallback, do_resize, 0); WidgetBackgroundToGlC3i(glw,background); XtRealizeWidget(toplevel); installColormap(toplevel,glw); XtAppMainLoop(app_context); } static void quit(Widget w, caddr_t client_data, caddr_t call_data) { midi_tx_3byte( 160, 127, 127 ); midi_tx_3byte( 160, 127, 0 ); MIclose( midi_port ); MIfreeport( midi_port ); exit (0); } static void init_window(Widget w, caddr_t client_data, GlxDrawCallbackStruct *call_data) { Matrix C_spline={{-0.5,1.5,-1.5,0.5},{1.0,-2.5,2.0,-0.5},{-0.5,0.0,0.5,0.0},{0.0,1.0,0.0,0.0},}; ortho2( WORLD_XMIN, WORLD_XMAX, WORLD_YMIN, WORLD_YMAX ); defbasis( 100, C_spline ); curveprecision( 20 ); curvebasis( 100); makeobj(MOUSE_OBJ); color(WHITE); rectf(-4.0,-6.0,4.0,6.0); color(BLACK); rect(-4.0,-6.0,4.0,6.0); rect(-2.75,0.0,-1.25,4.5); rect(-0.75,0.0, 0.75,4.5); rect( 1.25,0.0, 2.75,4.5); color(GREY); rectf(-3.0,-6.0,5.0,-7.0); rectf(4.0,-7.0,5.0,5.0); closeobj(); button[0] = button[1] = button[2] = 0; do_resize(w,client_data,call_data); srandom(1); color_no = 6; action_mode = error_st = 0; midi_initialize(); midi_tx_3byte( 159, 1, 127 ); /* to Draw */ midi_tx_3byte( 159, 1, 0 ); } static void do_resize(Widget w, caddr_t client_data, GlxDrawCallbackStruct *call_data) { GLXwinset(XtDisplay(w), XtWindow(w)); xmin = 0; xmax = (Screencoord)call_data->width - 1; ymin = 0; ymax = (Screencoord)call_data->height - 1; xrat = (WORLD_XMAX - WORLD_XMIN) / (float)(xmax - xmin); yrat = (WORLD_YMAX - WORLD_YMIN) / (float)(ymax - ymin); viewport( 0, xmax, 0, ymax ); mx = xmax / 2; my = ymax / 2; draw_screen(w); } static void midi_initialize() { MIconfig *c; c = MInewconfig(); midi_port = MInewport(); if( MIopen( midi_port, "rw", &c ) < 0 ) exit(-1); } static void midi_transmit( int status, int channel, int keyno, int velocity ) { midi_set_status( midi, ( status & 0xf0 ) ); midi_set_channel( midi, ( channel & 0x0f ) ); midi_set_keyno( midi, ( keyno & 0x7f ) ); midi_set_velocity ( midi, ( velocity & 0x7f ) ); if( MIsend( midi_port, midi, 1 ) < 0 ) exit(-1); } static void midi_tx_3byte( int status_byte, int keyno, int velocity ) { midi_transmit( ( status_byte & 0xf0 ), ( status_byte & 0x0f ), keyno, velocity ); } static void draw_screen(Widget w) { static Coord geom[4][3] = { { WORLD_XMIN, 6.0-LEN, 0.0 }, { 0.0, 6.0, 0.0 }, { WORLD_XMIN, WORLD_YMAX, 0.0 }, { 0.0, WORLD_YMAX+LEN, 0.0 }, }; GLXwinset(XtDisplay(w), XtWindow(w)); color( mode_color_table[color_no] ); clear(); color(BLACK); geom[0][1] = cy + 6.0 - LEN; geom[1][0] = cx; geom[1][1] = cy + 6.0; geom[3][0] = cx; crvn(4,geom); pushmatrix(); translate( cx, cy, 0.0 ); callobj(MOUSE_OBJ); if ( button[0] == 1 ) rectf(-2.75,0.0,-1.25,4.5); if ( button[1] == 1 ) rectf(-0.75,0.0, 0.75,4.5); if ( button[2] == 1 ) rectf( 1.25,0.0, 2.75,4.5); popmatrix(); swapbuffers(); } static void clear_screen(Widget w) { GLXwinset(XtDisplay(w), XtWindow(w)); color( mode_color_table[color_no] ); clear(); swapbuffers(); error_st = 0; } static void draw_mode(Widget w, caddr_t client_data, caddr_t call_data) { int d, p=0; if( action_mode == 0 ) p = 20; else error_st == 0; d = 1 + p + random() % 16; /* midi_tx_3byte( 159, d, 127 ); midi_tx_3byte( 159, d, 0 ); */ action_mode = 0; color_no = (color_no+1) % 6; clear_screen(w); } static void paint_mode(Widget w, caddr_t client_data, caddr_t call_data) { } static void stamp_mode(Widget w, caddr_t client_data, caddr_t call_data) { } static void effect_mode(Widget w, caddr_t client_data, caddr_t call_data) { } static void erase_mode(Widget w, caddr_t client_data, caddr_t call_data) { } static void input(Widget w, caddr_t client_data, GlxDrawCallbackStruct *call_data) { int d, new_x, new_y, in_out = 0; mx = call_data->event->xbutton.x; my = call_data->event->xbutton.y; cx = (float)(mx - xmin) * xrat; cy = (float)(ymax - ymin - my) * yrat; new_x = 20 + (int)( cx * 0.4 ); new_y = 20 + (int)( cy * 0.4 ); switch(call_data->event->type){ case ButtonPress: switch(call_data->event->xbutton.button){ case Button1: button[0] = 1; if( action_mode == 0 ){ midi_tx_3byte( 144, new_x, new_y ); midi_tx_3byte( 144, new_x, 0 ); } break; case Button2: button[1] = 1; break; case Button3: button[2] = 1; break; } draw_screen(w); break; case ButtonRelease: switch(call_data->event->xbutton.button){ case Button1: button[0] = 0; break; case Button2: button[1] = 0; break; case Button3: button[2] = 0; break; } draw_screen(w); break; case MotionNotify: if (call_data->event->xmotion.state){ if( button[0] == 1 ){ if( (cx<0.0)||(cx>200.0)||(cy<0.0)||(cy>200.0) ) in_out = 1; if( (error_st == 0) && (in_out == 1) ){ midi_tx_3byte( 144, 120, 127 ); midi_tx_3byte( 144, 120, 0 ); error_st = 1; } else if( in_out == 0 ){ if( action_mode == 0 ){ midi_tx_3byte( 144, new_x, new_y ); midi_tx_3byte( 144, new_x, 0 ); } if( error_st == 1 ) error_st = 0; } } draw_screen(w); } break; } }