Path: utzoo!mnetor!tmsoft!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!samsung!munnari.oz.au!metro!sunaus.oz!newstop!sun!hpcvlx.cv.hp.com From: brianw@hpcvlx.cv.hp.com (Brian Wilson) Newsgroups: comp.sources.x Subject: v08i054: wscrawl, Part02/05 Message-ID: <138939@sun.Eng.Sun.COM> Date: 15 Jul 90 18:57:15 GMT Sender: news@sun.Eng.Sun.COM Lines: 1137 Approved: argv@sun.com Submitted-by: Brian Wilson Posting-number: Volume 8, Issue 54 Archive-name: wscrawl/part02 #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # If this archive is complete, you will see the following message at the end: # "End of archive 2 (of 5)." # Contents: wscrawl/README wscrawl/xac # Wrapped by argv@turnpike on Sun Jul 15 11:47:10 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'wscrawl/README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'wscrawl/README'\" else echo shar: Extracting \"'wscrawl/README'\" \(3336 characters\) sed "s/^X//" >'wscrawl/README' <<'END_OF_FILE' X X WSCRAWL X (multi-display, multi-user, communications program) X by Brian Wilson, brianw@cv.hp.com X X XWhat "wscrawl" is: X------------------ X X The program "wscrawl" is a demo of the networking capabilities of XX-Windows. The word "wscrawl" stands for "window-scrawl". The user may Xthink of wscrawl as a paint program shared by any number of people at Xthe same time. When wscrawl is run, it opens up a separate window on each Xparticipant's display. From that point onward, each participant sees Xthe actions and ideas of every other participant as they occur. Each individual Xmay simply watch, or participate at any moment. Any individual may exit Xout of the session at any time without affecting the other participants. X X X XTo quickly get the concept of wscrawl: X-------------------------------------- X X 1) set your DISPLAY environment variable appropriately. X (example for me at my workstation: "export DISPLAY=hpcvxbw:0") X X 2) have a friend (with X11 running) xhost your workstation X (example for my friend: "xhost +" <-- xhost everyone in the world) X X 3) start a wscrawl session between the two of you X (example for me: "wscrawl -d hpcvxca:0" <-- my friend is hpcvxca:0) X X 4) push the left mouse button down and move the mouse. For some menu X options, click on the menus at the top of the wscrawl window. X X 5) Concepts to try: X X a) Play tic-tac-toe between two workstations. Change colors of pen X and draw the board in the center of the wscrawl window. Each X player should use a different color. X X b) type a message to your friend. This is done by selecting the X "Type" item from the "Control" menu, then clicking the left X button somewhere. Type on the keyboard. Try changine fonts. X X c) Wscrawl to someone out of sight earshot. Wscrawl to them, X and then call them on the telephone. By talking and scrawling X diagrams, you can simulate being there with an pad and pencil. X X d) resize your wscrawl window. Notice that ALL wscrawl windows X on ALL displays will resize accordingly. This guarantees you X are all seeing the same picture at all times. Resize your window X to the size of the display you are working at. X X e) any person out of the total group may select "Close Window" from X the "Control" menu at any time. This change is duely noted in X the "STATUS" window at the bottom of each wscrawl window. The X other people may continue to scrawl with no problems. X X f) scrawl a picture, then pull down the "Control" menu and select X "Add a Display". Type the name of your friend into the dialog X box and hit return. After a few seconds, your friend will see X this new picture. X X g) Fire up several wscrawl windows on your one display. For me, X I would type "wscrawl -d hpcvxbw:0 -d hpcvxbw:0 -d hpcvxbw:0". X See how it behaves. X X h) Try some "File I/O". Wscrawl saves and reads both standard X X bitmap files and xwd standard files. Import or export some X of your favorite bitmaps, or dump a window using "xwd" and X load it into wscrawl. X X XQuestions, comments, hacked source code: X---------------------------------------- XBrian Wilson Xbrianw@cv.hp.com X END_OF_FILE if test 3336 -ne `wc -c <'wscrawl/README'`; then echo shar: \"'wscrawl/README'\" unpacked with wrong size! fi # end of 'wscrawl/README' fi if test -f 'wscrawl/xac' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'wscrawl/xac'\" else echo shar: Extracting \"'wscrawl/xac'\" \(37771 characters\) sed "s/^X//" >'wscrawl/xac' <<'END_OF_FILE' X "-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1"); X else if (strcmp(font_file_name, "courR14") == 0) X strcpy(xlfd_string, X "-adobe-courier-medium-r-normal--14-140-75-75-m-90-iso8859-1"); X else if (strcmp(font_file_name, "timBI18") == 0) X strcpy(xlfd_string, X "-adobe-times-bold-i-normal--18-180-75-75-p-98-iso8859-1"); X else if (strcmp(font_file_name, "courR24") == 0) X strcpy(xlfd_string, X "-adobe-courier-medium-r-normal--24-240-75-75-m-150-iso8859-1"); X else if (strcmp(font_file_name, "timR24") == 0) X strcpy(xlfd_string, X "-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1"); X else if (strcmp(font_file_name, "timBI24") == 0) X strcpy(xlfd_string, X "-adobe-times-bold-i-normal--24-240-75-75-p-128-iso8859-1"); X else if (strcmp(font_file_name, "ncenR24") == 0) X strcpy(xlfd_string, X "-adobe-new century schoolbook-medium-r-normal--24-240-75-75-p-137-iso8859-1"); X else if (strcmp(font_file_name, "vbee-36") == 0) X strcpy(xlfd_string, "vbee-36"); X else if (strcmp(font_file_name, "vr-40") == 0) X strcpy(xlfd_string, "vr-40"); X else if (strcmp(font_file_name, "vgl-40") == 0) X strcpy(xlfd_string, "vgl-40"); X else if (strcmp(font_file_name, "vgl-40") == 0) X strcpy(xlfd_string, "vsgn-57"); X else X return(FALSE); /*not one of these fonts*/ X X if ((the_font_struct = XLoadQueryFont(disp_info[i].disp, X xlfd_string)) != NULL) X { X gcvalues.font = the_font_struct->fid; X disp_info[disp_num].the_font_struct = the_font_struct; X gcvalues.font = the_font_struct->fid; X XChangeGC(disp_info[i].disp, disp_info[disp_num].win_gc[i], GCFont, X &gcvalues); X return(TRUE); X } X else X return(FALSE); X} X X X/* X * menu_selection - this function does the appropriate actions as specified X * by the menu referenced by the menu_num and item_num passed as X * parameters. X */ Xmenu_selection(disp_num, menu_num, num_people_drawing, item_num) Xint disp_num, menu_num, *num_people_drawing, item_num; X{ X int i, temp_num; X XColor scrn_def_ret, exact_def_ret; X XFontStruct *the_font_struct; X XWindowAttributes attr_ret; X X switch (menu_num) X { X case 0: /*Control menu*/ X switch (item_num) X { X case 1: /*scrawl*/ X if (disp_info[disp_num].cursor_on == TRUE) X { X disp_info[disp_num].cursor_on = FALSE; X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X if (disp_info[disp_num].scrawl_mode == TYPING) X (*num_people_drawing)--; /*stopped input for now*/ X disp_info[disp_num].scrawl_mode = SCRAWLING; X disp_info[disp_num].menu[menu_num].checked_item = 1; X disp_info[disp_num].pen_width = X disp_info[disp_num].pen_widths.scrawl; X for (i=1; i= disp_info[disp_num].pen_width) X { X disp_info[disp_num].menu[2].checked_item=i; X break; X } X } X for (i=0; i= disp_info[disp_num].pen_width) X { X disp_info[disp_num].menu[2].checked_item=i; X break; X } X } X XDefineCursor(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X XCreateFontCursor(disp_info[disp_num].disp, X XC_spraycan)); X break; X case 3: /*type*/ X if (disp_info[disp_num].scrawl_mode != TYPING) X (*num_people_drawing)++; /*started input for now*/ X disp_info[disp_num].scrawl_mode = TYPING; X disp_info[disp_num].menu[menu_num].checked_item = 3; X XDefineCursor(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X XCreateFontCursor(disp_info[disp_num].disp, XC_xterm)); X break; X case 4: /*eraser*/ X if (disp_info[disp_num].cursor_on == TRUE) X { X disp_info[disp_num].cursor_on = FALSE; X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X if (disp_info[disp_num].scrawl_mode == TYPING) X (*num_people_drawing)--; /*stopped input for now*/ X disp_info[disp_num].scrawl_mode = ERASING; X disp_info[disp_num].menu[menu_num].checked_item = 4; X disp_info[disp_num].pen_width = X disp_info[disp_num].pen_widths.eraser; X for (i=1; i= disp_info[disp_num].pen_width) X { X disp_info[disp_num].menu[2].checked_item=i; X break; X } X } X XDefineCursor(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X XCreateFontCursor(disp_info[disp_num].disp, X XC_draped_box)); X break; X case 5: /*shapes*/ X if (disp_info[disp_num].cursor_on == TRUE) X { X disp_info[disp_num].cursor_on = FALSE; X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X if (disp_info[disp_num].scrawl_mode == TYPING) X (*num_people_drawing)--; /*stopped input for now*/ X disp_info[disp_num].scrawl_mode = SELECTING_AN_AREA; X disp_info[disp_num].menu[menu_num].checked_item = 5; X disp_info[disp_num].pen_width = X disp_info[disp_num].pen_widths.shape; X for (i=1; i= disp_info[disp_num].pen_width) X { X disp_info[disp_num].menu[2].checked_item = i; X break; X } X } X disp_info[disp_num].dialog_what = DRAW_SHAPE; X for (i=0; ifid; X disp_info[disp_num].the_font_struct = X the_font_struct; X gcvalues.font = the_font_struct->fid; X XChangeGC(disp_info[i].disp, X disp_info[disp_num].win_gc[i], GCFont, X &gcvalues); X } X else if (load_moron_fonts(disp_num, i, X menu_text[4][item_num]) == FALSE) X { X printf("Couldn't allocate font.\n"); X } X } X } X X if (disp_info[disp_num].cursor_on == TRUE) /*turn it off */ X { /*and don't tell*/ X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X X disp_info[disp_num].prompt_width = X disp_info[disp_num].the_font_struct->max_bounds.width; X disp_info[disp_num].char_height = X (disp_info[disp_num].the_font_struct)->max_bounds.ascent + X (disp_info[disp_num].the_font_struct)->max_bounds.descent; X disp_info[disp_num].type_history = NULL; X disp_info[disp_num].menu[menu_num].checked_item = item_num; X X if (disp_info[disp_num].cursor_on == TRUE) /*it is really off*/ X { /*'cause look above*/ X disp_info[disp_num].cursor_on = TRUE; X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X break; X case 5: /*Shape menu*/ X menu_selection(disp_num, 0, num_people_drawing, 5);/*choose shape*/ X disp_info[disp_num].menu[menu_num].checked_item = item_num; X switch(item_num) X { X case 1: X disp_info[disp_num].current_shape = STRAIGHT_LINE; X break; X case 2: X disp_info[disp_num].current_shape = OUTLINE_RECT; X break; X case 3: X disp_info[disp_num].current_shape = FILLED_RECT; X break; X case 4: X disp_info[disp_num].current_shape = OUTLINE_OVAL; X break; X case 5: X disp_info[disp_num].current_shape = FILLED_OVAL; X break; X default: break; X } X break; X case 6: /*File I/O menu*/ X switch(item_num) X { X case 1: /*Save Bitmap*/ X if (disp_info[disp_num].cursor_on == TRUE) X { X disp_info[disp_num].cursor_on = FALSE; X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X if (disp_info[disp_num].scrawl_mode == TYPING) X (*num_people_drawing)--; /*stopped input for now*/ X disp_info[disp_num].previous_scrawl_mode = X disp_info[disp_num].scrawl_mode; X disp_info[disp_num].scrawl_mode = SELECTING_AN_AREA; X disp_info[disp_num].dialog_what = SAVE_BITMAP; X XDefineCursor(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X XCreateFontCursor(disp_info[disp_num].disp, X XC_crosshair)); X break; X case 2: /*Read In Bitmap*/ X if (disp_info[disp_num].cursor_on == TRUE) X { X disp_info[disp_num].cursor_on = FALSE; X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X if (disp_info[disp_num].scrawl_mode == TYPING) X (*num_people_drawing)--; /*stopped input for now*/ X XDefineCursor(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X XCreateFontCursor(disp_info[disp_num].disp, X XC_cross)); X disp_info[disp_num].dialog_reply_index = 0; X disp_info[disp_num].dialog_text_prompt = X "File To Read Bitmap From:"; X put_up_dialog(disp_num); X disp_info[disp_num].previous_scrawl_mode = X disp_info[disp_num].scrawl_mode; X disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG; X disp_info[disp_num].dialog_what = READ_IN_BITMAP; X break; X case 3: /*Read Text File*/ X if (disp_info[disp_num].cursor_on == TRUE) X { X disp_info[disp_num].cursor_on = FALSE; X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X if (disp_info[disp_num].scrawl_mode == TYPING) X (*num_people_drawing)--; /*stopped input for now*/ X XDefineCursor(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X XCreateFontCursor(disp_info[disp_num].disp, X XC_cross)); X disp_info[disp_num].dialog_reply_index = 0; X disp_info[disp_num].dialog_text_prompt = X "File To Read Text From:"; X put_up_dialog(disp_num); X disp_info[disp_num].previous_scrawl_mode = X disp_info[disp_num].scrawl_mode; X disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG; X disp_info[disp_num].dialog_what = READ_TEXTFILE; X break; X case 4: /*Save Image*/ X if (disp_info[disp_num].cursor_on == TRUE) X { X disp_info[disp_num].cursor_on = FALSE; X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X if (disp_info[disp_num].scrawl_mode == TYPING) X (*num_people_drawing)--; /*stopped input for now*/ X disp_info[disp_num].previous_scrawl_mode = X disp_info[disp_num].scrawl_mode; X disp_info[disp_num].scrawl_mode = SELECTING_AN_AREA; X disp_info[disp_num].dialog_what = SAVE_IMAGE; X XDefineCursor(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X XCreateFontCursor(disp_info[disp_num].disp, X XC_crosshair)); X break; X case 5: /*Read In Image*/ X if (disp_info[disp_num].cursor_on == TRUE) X { X disp_info[disp_num].cursor_on = FALSE; X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X disp_info[disp_num].cursor_gc, X disp_info[disp_num].cur_pos.x, X disp_info[disp_num].cur_pos.y, X disp_info[disp_num].cur_pos.x + X disp_info[disp_num].prompt_width, X disp_info[disp_num].cur_pos.y); X } X if (disp_info[disp_num].scrawl_mode == TYPING) X (*num_people_drawing)--; /*stopped input for now*/ X XDefineCursor(disp_info[disp_num].disp, X disp_info[disp_num].win_id, X XCreateFontCursor(disp_info[disp_num].disp, X XC_cross)); X disp_info[disp_num].dialog_reply_index = 0; X disp_info[disp_num].dialog_text_prompt = X "File To Read Image From:"; X put_up_dialog(disp_num); X disp_info[disp_num].previous_scrawl_mode = X disp_info[disp_num].scrawl_mode; X disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG; X disp_info[disp_num].dialog_what = READ_IN_IMAGE; X break; X } X break; X default: X printf("ERROR: Unknown menu number in menu_selection().\n"); X exit(0); X break; X } X} X X X/* X * draw_menu_text - this function draws the menu contents such as text X * and checkmarks as specified by the display and the menu_num. X * This is usually called in response to an expose event, etc. X */ Xdraw_menu_text(disp_num, menu_num) Xint disp_num, menu_num; X{ X int i; X X /* X * draw the bar under the menu heading X */ X XDrawLine(disp_info[disp_num].disp, X disp_info[disp_num].menu[menu_num].win_id, X disp_info[disp_num].fg_menu_gc, 0, MENU_ITEM_HEIGHT+1, X MENU_ITEM_WIDTH, MENU_ITEM_HEIGHT+1); X X /* X * draw all the text X */ X for (i=0; imax_bounds.width; X disp_info[input_disp].char_height = X (disp_info[input_disp].the_font_struct)->max_bounds.ascent + X (disp_info[input_disp].the_font_struct)->max_bounds.descent; X disp_info[input_disp].type_history = NULL; X X /*draw the cursor*/ X disp_info[input_disp].cursor_on = TRUE; X XDrawLine(disp_info[input_disp].disp, disp_info[input_disp].win_id, X disp_info[input_disp].cursor_gc, X disp_info[input_disp].cur_pos.x, X disp_info[input_disp].cur_pos.y, X disp_info[input_disp].cur_pos.x + X disp_info[input_disp].prompt_width, X disp_info[input_disp].cur_pos.y); X } X X if (XPending(disp_info[input_disp].disp)) /*check if there is a KeyPress*/ X { X XNextEvent(disp_info[input_disp].disp, &the_event); X if (the_event.type != KeyPress) X { X XPutBackEvent(disp_info[input_disp].disp, &the_event); X return(0); X } X else /*it IS a KeyPressedEvent*/ X { X the_char[0] = 0; X XLookupString((XKeyEvent *) (&the_event),the_char,10, &ksr, NULL); X if (the_char[0] == 0) X return(0); /*it was a shift or some such*/ X if (the_char[0] == 13) /*13 == Carriage Return*/ X { X /*erase the cursor*/ X disp_info[input_disp].cursor_on = FALSE; X XDrawLine(disp_info[input_disp].disp, X disp_info[input_disp].win_id, X disp_info[input_disp].cursor_gc, X disp_info[input_disp].cur_pos.x, X disp_info[input_disp].cur_pos.y, X disp_info[input_disp].cur_pos.x + END_OF_FILE if test 37771 -ne `wc -c <'wscrawl/xac'`; then echo shar: \"'wscrawl/xac'\" unpacked with wrong size! fi # end of 'wscrawl/xac' fi echo shar: End of archive 2 \(of 5\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 4 5 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 5 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.