#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define XK_MISCELLANY /* Needed for defininition of Esc */ #include #include #include #include #define XSCREENSIZE(d,s) DisplayWidth(d,s) #define YSCREENSIZE(d,s) DisplayHeight(d,s) #define WORLD_XMIN 0.0 #define WORLD_XMAX 200.0 #define WORLD_YMIN 0.0 #define WORLD_YMAX 200.0 #define GREY1 8 #define GREY2 15 #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 ) ) char *progname = "midi"; long xmin, xmax, ymin, ymax; unsigned int screen_w, screen_h; float xrat, yrat; int screen_num, old_x, old_y, old_button, color_no, action_mode; Display *display; MIport *midi_port; MIevent midi[100]; Window glx_create_window(); void set_wm_hints(); void define_geom(); void draw_screen(); void midi_initialize(); void midi_event_generate(); void midi_transmit(); void midi_tx_3byte(); void main(int argc, char **argv) { Window top, glwin, root, child, windows[2]; XEvent event; char buffer[5]; int got_expose; int x, y, root_x, root_y; unsigned int keys_buttons; KeySym keysym; XComposeStatus compose; srandom(1); color_no = action_mode = 0; midi_initialize(); midi_tx_3byte( 159, 1, 127 ); /* to Draw */ midi_tx_3byte( 159, 1, 0 ); display = XOpenDisplay(NULL); screen_num = DefaultScreen(display); screen_w = XSCREENSIZE(display, screen_num); screen_h = YSCREENSIZE(display, screen_num); xmin = ymin = 0; xmax = screen_w - 1; ymax = screen_h - 1; xrat = (WORLD_XMAX - WORLD_XMIN) / (float)(xmax - xmin); yrat = (WORLD_YMAX - WORLD_YMIN) / (float)(ymax - ymin); top = XCreateSimpleWindow(display,RootWindow(display,screen_num),0,0,screen_w, screen_h,0,0,0); set_wm_hints(argc, argv, top); glwin = glx_create_window(display, top, 0, 0, screen_w, screen_h, 0); XSelectInput(display,top,KeyPressMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask); XSelectInput(display, glwin, ExposureMask); windows[0] = glwin; windows[1] = top; XSetWMColormapWindows(display, top, windows, 2); XMapWindow(display, glwin); XMapWindow(display, top); GLXwinset(display, glwin); define_geom(); XGrabButton(display, AnyButton, AnyModifier, RootWindow(display, screen_num), False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None); got_expose = FALSE; while (1) { gflush(); XNextEvent(display, &event); switch (event.type) { case Expose: if (event.xexpose.count) continue; got_expose = TRUE; break; case MotionNotify: case ButtonPress: case ButtonRelease: break; case KeyPress: XLookupString(&event, buffer, sizeof(buffer), &keysym, &compose); if (keysym == XK_Escape) { XCloseDisplay(display); MIclose( midi_port ); MIfreeport( midi_port ); exit(0); } continue; default: continue; } if (!XEventsQueued(display, QueuedAlready) && got_expose) { XQueryPointer(display,glwin,&root,&child,&root_x,&root_y,&x,&y,&keys_buttons); midi_event_generate(x, y, keys_buttons); draw_screen(x, y, keys_buttons); } } } static Window glx_create_window(Display* dpy, Window parent, int x, int y, int w, int h, int borderWidth) { static GLXconfig params[] = {{GLX_NORMAL,GLX_RGB,FALSE},{GLX_NORMAL,GLX_DOUBLE,TRUE},{0,0,0},}; GLXconfig *next, *retconfig; Colormap cmap = DefaultColormap(dpy, DefaultScreen(dpy)); XVisualInfo *vis; XVisualInfo template; XSetWindowAttributes cwa; int nret; Window win; retconfig = GLXgetconfig(dpy, DefaultScreen(dpy), params); for (next = retconfig; next->buffer; next++) { if (next->buffer == GLX_NORMAL) { if (next->mode == GLX_COLORMAP) { cmap = next->arg; } else if (next->mode == GLX_VISUAL) { template.visualid = next->arg; template.screen = DefaultScreen(dpy); vis = XGetVisualInfo(dpy,VisualScreenMask | VisualIDMask,&template,&nret); } } } cwa.colormap = cmap; cwa.border_pixel = 0; win = XCreateWindow(dpy, parent, x, y, w, h, borderWidth, vis->depth, InputOutput, vis->visual, CWColormap|CWBorderPixel, &cwa); for (next = retconfig; next->buffer; next++) { if ((next->buffer == GLX_NORMAL) && (next->mode == GLX_WINDOW)) { next->arg = win; break; } } GLXlink(dpy, retconfig); return win; } static void set_wm_hints(int argc, char *argv[], Window top) { XTextProperty windowName; XSizeHints size_hints; XClassHint class_hints; XWMHints wm_hints; MotifWmHints mwm_hints; Atom mwm_hints_atom; size_hints.flags = USPosition | PBaseSize | PMaxSize; size_hints.x = 0; size_hints.y = 0; size_hints.base_width = size_hints.max_width = screen_w; size_hints.base_height = size_hints.max_height = screen_h; XStringListToTextProperty(&progname, 1, &windowName); wm_hints.initial_state = NormalState; wm_hints.input = True; wm_hints.flags = StateHint | InputHint; class_hints.res_name = progname; class_hints.res_class = "test"; XSetWMProperties(display,top,&windowName,NULL,argv,argc,&size_hints,&wm_hints,&class_hints); mwm_hints_atom = XInternAtom(display, _XA_MOTIF_WM_HINTS, False); mwm_hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS; mwm_hints.decorations = 0; mwm_hints.functions = MWM_FUNC_CLOSE; XChangeProperty(display, top, mwm_hints_atom, mwm_hints_atom, 32, PropModeReplace, &mwm_hints, PROP_MWM_HINTS_ELEMENTS); } static void define_geom() { 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(GREY1); rectf(-3.0,-6.0,5.0,-7.0); rectf(4.0,-7.0,5.0,5.0); closeobj(); } static void draw_screen(int x, int y, unsigned int keys_buttons) { 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 }, }; static char disp_message[3][120] = { " ===== [1] DRAW Mode ( left = draw , middle = Error , right --> Paint ) =====", " ===== [2] PAINT Mode ( left = paint , middle = Effect , right --> Stamp ) =====", " ===== [3] STAMP Mode ( left = stamp , middle = Erase , right --> Draw ) =====", }; static int mode_color_table[6] = { 9, 10, 11, 12, 13, 14 }; static int first_time = TRUE; float xoff, yoff; if (first_time) { frontbuffer(TRUE); backbuffer(TRUE); } color( mode_color_table[color_no] ); clear(); color(BLACK); cmov2i( (Icoord)( 20 + 10 * action_mode ), (Icoord)( 150 - 40 * action_mode ) ); charstr( disp_message[action_mode] ); xoff = (float)(x - xmin) * xrat; yoff = (float)(ymax - ymin - y) * yrat; geom[0][1] = yoff + 6.0 - LEN; geom[1][0] = xoff; geom[1][1] = yoff + 6.0; geom[3][0] = xoff; crv(geom); pushmatrix(); translate(xoff,yoff,0.0); callobj(MOUSE_OBJ); if (keys_buttons & Button1Mask) rectf(-2.75,0.0,-1.25,4.5); if (keys_buttons & Button2Mask) rectf(-0.75,0.0, 0.75,4.5); if (keys_buttons & Button3Mask) rectf( 1.25,0.0, 2.75,4.5); popmatrix(); if (first_time) { frontbuffer(FALSE); first_time = FALSE; } else swapbuffers(); } 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 midi_event_generate(int x, int y, unsigned int keys_buttons) { int d, new_x, new_y, new_button = 0, point_event = 0, color_change = 0; new_x = 20 + (int)( (float)x * 80.9 / 1024.0 ); new_y = 20 + (int)( (float)( 767 - y ) * 80.9 / 768.0 ); if( keys_buttons & Button1Mask ) new_button = 1; if( keys_buttons & Button2Mask ) new_button = 2; if( keys_buttons & Button3Mask ) new_button = 3; if( old_x != new_x ){ old_x = new_x; point_event++; } if( old_y != new_y ){ old_x = new_x; point_event++; } if( old_button != new_button ){ if( ( new_button == 2 ) && ( old_button == 0 ) ){ color_change++; if( action_mode == 0 ){ midi_tx_3byte( 157, 120, 127 ); /* Error */ midi_tx_3byte( 157, 120, 0 ); } else if( action_mode == 1 ){ d = random() % 3; midi_tx_3byte( 159, 121 + d, 127 ); /* Effect */ midi_tx_3byte( 159, 121 + d, 0 ); } else if( action_mode == 2 ){ d = random() % 3; midi_tx_3byte( 159, 65 + d, 127 ); /* Erase */ midi_tx_3byte( 159, 65 + d, 0 ); } } else if( ( new_button == 3 ) && ( old_button == 0 ) ){ color_change++; if( action_mode == 0 ){ midi_tx_3byte( 159, 60, 127 ); /* to Paint */ midi_tx_3byte( 159, 60, 0 ); action_mode = 1; } else if( action_mode == 1 ){ d = 71 + 20 * ( random() % 2 ) + random() % 10; midi_tx_3byte( 159, d, 127 ); /* to Stamp */ midi_tx_3byte( 159, d, 0 ); action_mode = 2; } else if( action_mode == 2 ){ d = 1 + 20 * ( random() % 2 ) + random() % 16; midi_tx_3byte( 159, d, 127 ); /* to Draw */ midi_tx_3byte( 159, d, 0 ); action_mode = 0; } } else if( ( new_button == 1 ) && ( old_button == 0 ) ){ if( action_mode == 0 ){ midi_tx_3byte( 157, new_x, new_y ); midi_tx_3byte( 157, new_x, 0 ); } else if( action_mode == 1 ){ d = 41 + ( random() % 16 ); midi_tx_3byte( 159, d, 127 ); midi_tx_3byte( 159, d, 0 ); color_change++; } else if( action_mode == 2 ){ midi_tx_3byte( 158, new_x, new_y ); midi_tx_3byte( 158, new_x, 0 ); } } old_button = new_button; } else if( point_event != 0 ){ if( ( new_button == 1 ) && ( action_mode == 0 ) ){ midi_tx_3byte( 157, new_x, new_y ); midi_tx_3byte( 157, new_x, 0 ); } else if( ( new_button == 1 ) && ( action_mode == 2 ) ){ midi_tx_3byte( 158, new_x, new_y ); midi_tx_3byte( 158, new_x, 0 ); } } if( color_change != 0 ) color_no = (color_no+1) % 6; }