static status updatePopupGesture(PopupGesture g, EventObj ev) { PopupObj p; Any rec = getMasterEvent(ev); DEBUG(NAME_popup, Cprintf("updatePopupGesture(): rec=%s\n", pp(rec))); if ( notNil(g->popup) ) { if ( instanceOfObject(g->popup, ClassFunction) ) { TRY( p = getForwardReceiverFunction((Function) g->popup, rec, rec, ev, EAV) ); TRY( p = checkType(p, nameToType(NAME_popup), g)); } else p = g->popup; } else { if ( !(p = get(rec, NAME_popup, EAV)) || !instanceOfObject(p, ClassPopup) ) fail; } assign(g, current, p); if ( isNil(g->context) ) assign(g, context, notNil(p->context) ? p->context : rec); send(p, NAME_update, g->context, EAV); if ( p->active == OFF || emptyChain(p->members) ) { send(g, NAME_cancel, ev, EAV); fail; } succeed; }
status RedrawAreaButton(Button b, Area a) { int x, y, w, h; int defb; int rm = 0; /* right-margin */ PceWindow sw; int kbf; /* Button has keyboard focus */ int obhf; /* Other button has focus */ int focus; int swapbg = FALSE; int up; int flags = 0; Elevation z; if ( b->look == NAME_winMenuBar || b->look == NAME_gtkMenuBar ) return RedrawMenuBarButton(b, a); if ( b->active == OFF ) flags |= LABEL_INACTIVE; up = (b->status == NAME_active || b->status == NAME_inactive); defb = (b->default_button == ON); initialiseDeviceGraphical(b, &x, &y, &w, &h); NormaliseArea(x, y, w, h); if ( (sw = getWindowGraphical((Graphical)b)) ) { kbf = (sw->keyboard_focus == (Graphical) b); obhf = (!kbf && instanceOfObject(sw->keyboard_focus, ClassButton)); focus = (sw->input_focus == ON); } else kbf = obhf = focus = FALSE; /* should not happen */ if ( !ws_draw_button_face((DialogItem)b, x, y, w, h, up, defb, kbf && focus) ) draw_generic_button_face(b, x, y, w, h, up, defb, kbf && focus); if ( b->look == NAME_openLook && b->status == NAME_preview && !((z = getClassVariableValueObject(b, NAME_elevation)) && notNil(z)) ) { swapbg = TRUE; r_swap_background_and_foreground(); } if ( notNil(b->popup) && !instanceOfObject(b->label, ClassImage) ) rm = draw_button_popup_indicator(b, x, y, w, h, up); RedrawLabelDialogItem(b, accelerator_code(b->accelerator), x, y, w-rm, h, NAME_center, NAME_center, flags); if ( swapbg ) r_swap_background_and_foreground(); return RedrawAreaGraphical(b, a); }
static ListBrowser get_list_browser(EventObj ev) { if ( instanceOfObject(ev->receiver, ClassListBrowser) ) return (ListBrowser)ev->receiver; if ( instanceOfObject(ev->receiver, ClassBrowser) ) { Browser b = (Browser)ev->receiver; return(b->list_browser); } fail; }
static inline Int _getVar(Equation e, Var var, va_list args) /* Var, Int, Var, Int, ... */ { int argc, i; Var vars[FWD_PCE_MAX_ARGS]; Any vals[FWD_PCE_MAX_ARGS]; Any savd[FWD_PCE_MAX_ARGS]; numeric_value v; for(argc = 0; (vars[argc] = va_arg(args, Var)) != NULL; argc++) { assert(argc <= FWD_PCE_MAX_ARGS); assert(instanceOfObject(vars[argc], ClassVar)); vals[argc] = va_arg(args, Expression); assert(vals[argc] != NULL); } for(i=0; i<argc; i++) { savd[i] = vars[i]->value; setVar(vars[i], vals[i]); } evaluateEquation(e, var, &v); for(i=0; i<argc; i++) setVar(vars[i], savd[i]); return ar_int_result(e, &v); }
status ws_create_colour(Colour c, DisplayObj d) { Int Rgb; if ( c->kind == NAME_named ) { HashTable ht = LoadColourNames(); if ( (Rgb = getMemberHashTable(ht, c->name)) || (Rgb = getMemberHashTable(ht, canonical_colour_name(c->name))) ) { COLORREF rgb = (COLORREF) valInt(Rgb); int r = GetRValue(rgb) * 257; int g = GetGValue(rgb) * 257; int b = GetBValue(rgb) * 257; assign(c, red, toInt(r)); assign(c, green, toInt(g)); assign(c, blue, toInt(b)); registerXrefObject(c, d, (void *)(uintptr_t)rgb); } else fail; } else { COLORREF rgb = RGB(valInt(c->red)/256, valInt(c->green)/256, valInt(c->blue)/256); registerXrefObject(c, d, (void *)(uintptr_t)rgb); } if ( instanceOfObject(d->colour_map, ClassColourMap) && d->colour_map->read_only == OFF ) ws_alloc_colour(d->colour_map, c); succeed; }
void considerLocStillEvent() { if ( !loc_still_posted ) { unsigned long now = mclock(); if ( now - host_last_time < (unsigned long)loc_still_time ) { DEBUG(NAME_locStill, Cprintf("TimeDiff = %d (ignored)\n", now - host_last_time)); return; } if ( !pceMTTryLock(LOCK_PCE) ) return; if ( instanceOfObject(last_window, ClassWindow) && !onFlag(last_window, F_FREED|F_FREEING) && valInt(last_x) > 0 && valInt(last_y) > 0 ) { ServiceMode(is_service_window(last_window), { AnswerMark mark; EventObj e; markAnswerStack(mark); e = newObject(ClassEvent, NAME_locStill, last_window, last_x, last_y, last_buttons, toInt(last_time + now - host_last_time), EAV); addCodeReference(e); postNamedEvent(e, (Graphical) last_window, DEFAULT, NAME_postEvent); delCodeReference(e); freeableObj(e); rewindAnswerStack(mark, NIL); }) }
static status verifyResizeGesture(ResizeGesture g, EventObj ev) { int frac = valInt(getClassVariableValueObject(g, NAME_marginFraction)); int mx = valInt(getClassVariableValueObject(g, NAME_marginWidth)); Int X, Y; int x, y, w, h; Graphical gr = ev->receiver; if ( !instanceOfObject(gr, ClassGraphical) || isNil(gr->device) ) fail; get_xy_event(ev, ev->receiver, ON, &X, &Y); x = valInt(X), y = valInt(Y); w = valInt(gr->area->w); h = valInt(gr->area->h); if ( x < w/frac && x < mx ) /* determine horizontal-mode */ assign(g, h_mode, NAME_left); else if ( x > ((frac-1) * w)/frac && x > w - mx ) assign(g, h_mode, NAME_right); else assign(g, h_mode, NAME_keep); if ( y < h/frac && y < mx ) /* determine vertical-mode */ assign(g, v_mode, NAME_top); else if ( y > ((frac-1) * h)/frac && y > h - mx ) assign(g, v_mode, NAME_bottom); else assign(g, v_mode, NAME_keep); if ( g->h_mode == NAME_keep && g->v_mode == NAME_keep ) fail; succeed; }
status ws_create_window(PceWindow sw, PceWindow parent) { Widget w; DisplayObj d = getDisplayGraphical((Graphical)sw); /* create the widget */ { Arg args[8]; Cardinal n = 0; int pen = valInt(sw->pen); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Actually, it appears Xt is ignoring the geometry parameters. Hence, ws_realise_frame() sends ->geometry to all windows. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ XtSetArg(args[n], XtNx, valInt(sw->area->x)); n++; XtSetArg(args[n], XtNy, valInt(sw->area->y)); n++; XtSetArg(args[n], XtNwidth, valInt(sw->area->w) - 2*pen); n++; XtSetArg(args[n], XtNheight, valInt(sw->area->h) - 2*pen); n++; XtSetArg(args[n], XtNborderWidth, pen); n++; XtSetArg(args[n], XtNinput, True); n++; if ( instanceOfObject(sw->background, ClassColour) ) { XtSetArg(args[n], XtNbackground, getPixelColour(sw->background, d)); n++; } else { Pixmap pm = (Pixmap) getXrefObject(sw->background, d); XtSetArg(args[n], XtNbackgroundPixmap, pm); n++; } DEBUG(NAME_create, Cprintf("Calling XtCreateWidget ...")); w = XtCreateWidget(strName(sw->name), canvasWidgetClass, isDefault(parent) ? widgetFrame(sw->frame) : widgetWindow(parent), args, n); DEBUG(NAME_create, Cprintf("Widget = %p\n", w)); } if ( !w ) return errorPce(w, NAME_createFailed); setWidgetWindow(sw, w); XtAddCallback(w, XtNeventCallback, event_window, sw); XtAddCallback(w, XtNexposeCallback, expose_window, sw); XtAddCallback(w, XtNresizeCallback, resize_window, sw); XtAddCallback(w, XtNdestroyCallback, destroy_window, sw); if ( notDefault(parent) ) /* make a sub-window */ { XtManageChild(w); send(sw, NAME_displayed, ON, EAV); } succeed; }
void * pcePointerToC(PceObject obj) { if ( instanceOfObject(obj, ClassCPointer) ) { CPointer ptr = (CPointer)obj; return ptr->pointer; } return PCE_NO_POINTER; }
void ws_uncreate_colour(Colour c, DisplayObj d) { if ( isDefault(d) ) d = CurrentDisplay(NIL); if ( instanceOfObject(d->colour_map, ClassColourMap) && d->colour_map->read_only == OFF ) ws_unalloc_colour(d->colour_map, c); unregisterXrefObject(c, d); }
static status initialiseReal(Real r, Any arg) { double v; setFlag(r, F_ISREAL); if ( isInteger(arg) ) { v = (double)valInt(arg); } else if ( instanceOfObject(arg, ClassNumber) ) { v = (double)((Number)arg)->value; } else if ( instanceOfObject(arg, ClassReal) ) { Real a = arg; return valueReal(r, a); } else return errorPce(ClassReal, NAME_cannotConvert, arg); setReal(r, v); succeed; }
static status initiateResizeOutlineGesture(ResizeOutlineGesture g, EventObj ev) { Graphical gr = ev->receiver; if ( !instanceOfObject(gr, ClassGraphical) ) fail; send(g->outline, NAME_area, gr->area, EAV); send(gr->device, NAME_display, g->outline, EAV); postEvent(ev, (Graphical) g->outline, (Recogniser) g->outline_gesture); succeed; }
void ws_close_output_stream(Stream s) { if ( s->wrfd >= 0 ) { #ifdef HAVE_SHUTDOWN if ( instanceOfObject(s, ClassSocket) ) shutdown(s->wrfd, SHUT_WR); /* else Seems we must do both to free the descriptor */ #endif close(s->wrfd); s->wrfd = -1; } }
static status initialiseDictItem(DictItem di, Any key, CharArray lbl, Any obj, Name style) { if ( instanceOfObject(key, ClassCharArray) && !isName(key) ) key = toName(key); assign(di, key, key); assign(di, label, lbl); assign(di, index, ZERO); assign(di, object, (isDefault(obj) ? NIL : obj)); assign(di, dict, NIL); assign(di, style, style); succeed; }
static status computeLabel(Label lb) { if ( notNil(lb->request_compute) ) { int w, h, b; TRY(obtainClassVariablesObject(lb)); b = valInt(lb->border); if ( notNil(lb->elevation) ) b += abs(valInt(lb->elevation->height)); if ( instanceOfObject(lb->selection, ClassCharArray) ) { String s = &((CharArray)lb->selection)->data; int minw; int ex = valInt(getExFont(lb->font)); if ( lb->wrap == NAME_clip ) { LocalString(buf, s->iswide, s->size+1); str_one_line(buf, s); s = buf; } str_size(s, lb->font, &w, &h); w += ex; if ( notDefault(lb->width) ) minw = valInt(lb->width) - 2*b; else minw = (valInt(lb->length)+1) * ex; w = max(w, minw); } else /*if ( instanceOfObject(lb->selection, ClassImage) )*/ { Image image = (Image) lb->selection; w = valInt(image->size->w); h = valInt(image->size->h); } w += 2*b; h += 2*b; CHANGING_GRAPHICAL(lb, assign(lb->area, w, toInt(w)); assign(lb->area, h, toInt(h)); changedEntireImageGraphical(lb)); assign(lb, request_compute, NIL); }
status ws_create_font(FontObj f, DisplayObj d) { XpceFontInfo xref; DisplayWsXref r = d->ws_ref; XftFont *xft = NULL; if ( !instanceOfObject(f->x_name, ClassCharArray) || !isstrA(&f->x_name->data) ) /* HACK */ { XftPattern *p = XftPatternCreate(); XftPattern *match; FcResult fcrc; int i; char *fam; int mono = FALSE; Real scale = getClassVariableValueObject(f, NAME_scale); double fscale = (scale ? valReal(scale) : 1.0); if ( f->family == NAME_screen ) { fam = "monospace"; mono = TRUE; } else fam = strName(f->family); XftPatternAddString(p, XFT_FAMILY, fam); XftPatternAddDouble(p, XFT_PIXEL_SIZE, (double)valInt(f->points)*fscale); if ( f->style == NAME_italic ) XftPatternAddInteger(p, XFT_SLANT, XFT_SLANT_ITALIC); else if ( f->style == NAME_roman ) XftPatternAddInteger(p, XFT_SLANT, XFT_SLANT_ROMAN); else if ( f->style == NAME_bold ) XftPatternAddInteger(p, XFT_WEIGHT, XFT_WEIGHT_BOLD); if ( mono ) { DEBUG(NAME_font, Cprintf("Asking for fixed\n")); XftPatternAddInteger(p, XFT_SPACING, XFT_MONO); } if ( !(match = XftFontMatch(r->display_xref, r->screen, p, &fcrc)) ) { DEBUG(NAME_font, Cprintf("XftFontMatch() failed. Calling replaceFont()\n")); return replaceFont(f, d); } #ifdef HAVE_XFTNAMEUNPARSE DEBUG(NAME_font, { char buf[1024]; XftNameUnparse(match, buf, sizeof(buf)); Cprintf("Match = '%s'\n", buf); });
static status terminateEditTextGesture(EditTextGesture g, EventObj ev) { TextObj t = ev->receiver; if ( instanceOfObject(t, ClassText) && notNil(t->selection) ) send(t, NAME_copy, EAV); if ( g->activate == ON ) { PceWindow sw = getWindowGraphical((Graphical)t); if ( sw ) send(sw, NAME_keyboardFocus, t, EAV); } succeed; }
static Graphical getLabelItem(Graphical item) { Chain ch; if ( (ch = getAllHypersObject(item, OFF)) ) { Cell cell; for_cell(cell, ch) { Hyper h = cell->value; if ( h->to == item && h->backward_name == NAME_label && instanceOfObject(h->from, ClassGraphical) ) answer(h->from); /* I'm an item */ if ( h->from == item && h->forward_name == NAME_item ) fail; /* I'm a label */ }
static status RedrawAreaLabel(Label lb, Area a) { int x, y, w, h; Elevation z = lb->elevation; int preview = (lb->status == NAME_preview && notNil(lb->message)); initialiseDeviceGraphical(lb, &x, &y, &w, &h); if ( notNil(z) ) r_3d_box(x, y, w, h, 0, z, !preview); x += valInt(lb->border); y += valInt(lb->border); w -= 2*valInt(lb->border); h -= 2*valInt(lb->border); if ( lb->wrap == NAME_clip ) d_clip(x, y, w, h); if ( instanceOfObject(lb->selection, ClassCharArray) ) { String s = &((CharArray)lb->selection)->data; if ( notNil(z) ) x += valInt(getExFont(lb->font))/2; if ( lb->wrap == NAME_clip ) { LocalString(buf, s->iswide, s->size+1); str_one_line(buf, s); s = buf; } str_label(s, 0, lb->font, x, y, w, h, NAME_left, NAME_top, lb->active == ON ? 0 : LABEL_INACTIVE); } else /*if ( instanceOfObject(lb->selection, ClassImage) )*/ { Image image = (Image) lb->selection; r_image(image, 0, 0, x, y, w, h, ON); } if ( lb->wrap == NAME_clip ) d_clip_done(); if ( preview && isNil(z) ) r_complement(x, y, w, h); return RedrawAreaGraphical(lb, a); }
static status dragPopupGesture(PopupGesture g, EventObj ev) { if ( notNil(g->current) && g->current->displayed == ON ) { DEBUG(NAME_popup, Cprintf("Posting drag to %s\n", pp(g->current))); return postEvent(ev, (Graphical) g->current, DEFAULT); } else { if ( notNil(g->max_drag_distance) ) { PceWindow sw; if ( instanceOfObject((sw=ev->window), ClassWindow) && valInt(getDistanceEvent(sw->focus_event, ev)) > valInt(g->max_drag_distance) ) send(g, NAME_cancel, ev, EAV); } } fail; }
static status initiateBrowserSelectGesture(BrowserSelectGesture g, EventObj ev) { ListBrowser lb = get_list_browser(ev); if ( !lb ) fail; if ( instanceOfObject(lb->selection, ClassChain) ) assign(g, saved_selection, getCopyChain(lb->selection)); else assign(g, saved_selection, lb->selection); if ( selectBrowserSelectGesture(g, ev) ) succeed; send(lb, NAME_changeSelection, NAME_clear, EAV); succeed; }
void ws_close_input_stream(Stream s) { if ( s->rdstream ) { fclose(s->rdstream); s->rdstream = NULL; } if ( s->rdfd >= 0 ) { #ifdef HAVE_SHUTDOWN if ( instanceOfObject(s, ClassSocket) ) shutdown(s->rdfd, SHUT_RD); else #endif close(s->rdfd); s->rdfd = -1; } ws_no_input_stream(s); }
static Method getMethodMethodList(Any list, Name sel) { if ( instanceOfObject(list, ClassMethod) ) { Method m = list; if ( m->name == sel ) answer(m); fail; } else if ( instanceOfObject(list, ClassChain) ) { Chain ch = list; Cell cell; Method m; for_cell(cell, ch) { if ( (m = getMethodMethodList(cell->value, sel)) ) answer(m); } fail; } else { errorPce(list, NAME_unexpectedType, CtoType("method|chain"));
static status initialiseBlockv(Block b, int argc, Any *argv) { int n; initialiseCode((Code) b); assign(b, members, newObject(ClassChain, EAV)); for(n=0; n<argc; n++) { if ( instanceOfObject(argv[n], ClassVar) ) { if ( isNil(b->parameters) ) assign(b, parameters, newObjectv(ClassCodeVector, 1, &argv[n])); else appendVector(b->parameters, 1, &argv[n]); } else break; } for( ; n < argc; n++ ) appendChain(b->members, argv[n]); succeed; }
Any ws_event_in_subwindow(EventObj ev, Any root) { DisplayObj d = getDisplayEvent(ev); DisplayWsXref r = d->ws_ref; Window src_w = XtWindow(widgetWindow(ev->window)); int dx, dy; Window child; int root_is_display; if ( isDefault(root) ) root = d; if ( (root_is_display = instanceOfObject(root, ClassDisplay)) ) { XWindowAttributes atts; int depth = MAX_DECORATION_NESTING; if ( d != root ) { errorPce(ev, NAME_notSameDisplay, root); fail; } XGetWindowAttributes(r->display_xref, XtWindow(r->shell_xref), &atts); XTranslateCoordinates(r->display_xref, src_w, atts.root, valInt(ev->x), valInt(ev->y), &dx, &dy, &child); #if 0 DEBUG(NAME_pointer, /* TEST STUFF */ ({ Window rr, cr; int rx, ry, wx, wy, mask; if ( XQueryPointer(r->display_xref, atts.root, &rr, &cr, &rx, &ry, &wx, &wy, &mask) ) { Cprintf("XTranslateCoordinates --> %d\nXQueryPointer --> %d\n", child, cr); } }));
static status dragEditTextGesture(EditTextGesture g, EventObj ev) { Graphical t = ev->receiver; Int end = get(t, NAME_pointed, getPositionEvent(ev, DEFAULT), EAV); if ( notNil(g->max_drag_distance) ) { PceWindow sw; if ( instanceOfObject((sw=ev->window), ClassWindow) && valInt(getDistanceEvent(sw->focus_event, ev)) > valInt(g->max_drag_distance) ) assign(g, activate, OFF); } if ( end ) { send(t, NAME_selection, g->selection_origin, end, EAV); send(t, NAME_caret, end, EAV); succeed; } fail; }
status initialiseStringv(StringObj str, CharArray fmt, int argc, Any *argv) { if ( isDefault(fmt) ) { str_inithdr(&str->data, FALSE); str->data.s_size = 0; str_alloc(&str->data); } else if ( (Name) fmt == name_procent_s && argc == 1 && instanceOfObject(argv[0], ClassCharArray) ) { CharArray v = argv[0]; str_cphdr(&str->data, &v->data); if ( v->data.s_readonly ) { str->data.s_textA = v->data.s_textA; DEBUG(NAME_readOnly, Cprintf("Shared %s\n", pp(str))); } else { str_alloc(&str->data); memcpy(str->data.s_textA, v->data.s_textA, str_datasize(&v->data)); } } else TRY(str_writefv(&str->data, fmt, argc, argv)); succeed; }
status placeImageTableCell(TableCell cell) { Graphical gr = cell->image; Table tab = table_of_cell(cell); table_cell_dimensions d; int grx, gry; Any av[4]; Point ref = NULL; Name halign = getHalignTableCell(cell); Name valign = getValignTableCell(cell); ComputeGraphical(gr); /* make sure */ av[2] = DEFAULT; /* width */ av[3] = DEFAULT; /* height */ dims_table_cell(cell, &d); if ( halign == NAME_left ) /* determine X-placement */ grx = d.x + d.px; else if ( halign == NAME_right ) grx = d.x + d.w-d.px-valInt(gr->area->w); else if ( halign == NAME_center ) grx = d.x + (d.w-valInt(gr->area->w)+1)/2; else if ( halign == NAME_stretch ) { grx = d.x + d.px; av[2] = toInt(d.w-2*d.px); } else /* if ( halign == NAME_reference ) */ { ref = getIf(gr, NAME_reference, NIL); if ( notNil(ref) ) grx = d.x + d.rx - valInt(ref->x); else grx = d.x + d.px; } if ( valign == NAME_top ) /* determine Y-placement */ gry = d.y + d.py; else if ( valign == NAME_bottom ) gry = d.y + d.h-d.py-valInt(gr->area->h); else if ( valign == NAME_center ) gry = d.y + (d.h-valInt(gr->area->h)+1)/2; else if ( valign == NAME_stretch ) { gry = d.y + d.py; av[3] = toInt(d.h-2*d.py); } else /* if ( halign == NAME_reference ) */ { if ( !ref ) ref = getIf(gr, NAME_reference, NIL); if ( notNil(ref) ) gry = d.y + d.ry - valInt(ref->y); else gry = d.y + d.py; } av[0] = toInt(grx); av[1] = toInt(gry); if ( instanceOfObject(gr, ClassWindow) && /* HACK */ notNil(((PceWindow)gr)->decoration) ) gr = (Graphical)((PceWindow)gr)->decoration; qadSendv(gr, NAME_doSet, 4, av); if ( gr->device != tab->device ) send(tab->device, NAME_display, gr, EAV); succeed; }
static ssize_t Sread_object(void *handle, char *buf, size_t size) { OpenObject h = handle; Any argv[2]; CharArray sub; int chread; size_t advance; if ( isFreedObj(h->object) ) { errno = EIO; return -1; } if ( h->encoding == ENC_WCHAR ) { advance = size/sizeof(wchar_t); } else if ( h->encoding == ENC_OCTET ) { advance = size; } else { assert(0); errno = EIO; return -1; } argv[0] = toInt(h->point); argv[1] = toInt(advance); if ( (sub = getv(h->object, NAME_readAsFile, 2, argv)) && instanceOfObject(sub, ClassCharArray) ) { String s = &sub->data; assert(s->size <= advance); if ( h->encoding == ENC_WCHAR ) { if ( isstrA(s) ) { charW *dest = (charW*)buf; const charA *f = s->s_textA; const charA *e = &f[s->size]; while(f<e) *dest++ = *f++; } else { memcpy(buf, s->s_textW, s->size*sizeof(charW)); } chread = s->size * sizeof(wchar_t); } else { if ( isstrA(s) ) { memcpy(buf, s->s_textA, s->size); } else { errno = EIO; chread = -1; } chread = s->size; } h->point += s->size; } else { errno = EIO; chread = -1; } return chread; }
IOSTREAM * Sopen_object(Any obj, const char *mode) { if ( instanceOfObject(obj, ClassFile) ) { Name name = getOsNameFile(obj); IOSTREAM *s; if ( (s=Sopen_file(nameToFN(name), mode)) ) { if ( !strchr(mode, 'b') ) { FileObj f = obj; Name oldstat = f->status; IOSTREAM *ofd = f->fd; int rc; /* HACKS */ f->status = (mode[0] == 'r' ? NAME_read : NAME_write); f->fd = s; switch(mode[0]) { case 'r': { if ( (rc = doBOMFile(f)) ) setStreamEncodingSourceSink(obj, s); break; } case 'w': { setStreamEncodingSourceSink(obj, s); rc = doBOMFile(f); break; } default: { setStreamEncodingSourceSink(obj, s); rc = 0; } } s->newline = (f->newline_mode == NAME_posix ? SIO_NL_POSIX : f->newline_mode == NAME_dos ? SIO_NL_DOS : SIO_NL_DETECT); f->fd = ofd; f->status = oldstat; if ( !rc ) return NULL; } return s; } errorPce(obj, NAME_openFile, mode[0] == 'r' ? NAME_read : NAME_write, getOsErrorPce(PCE)); return s; } else if ( instanceOfObject(obj, ClassRC) && TheCallbackFunctions.rc_open ) { IOSTREAM *s; RC rc = obj; char *rc_class; if ( notDefault(rc->rc_class) ) rc_class = strName(rc->rc_class); else rc_class = NULL; if ( notNil(rc->context) && TheCallbackFunctions.setHostContext ) { Any savedcontext = (*TheCallbackFunctions.setHostContext)(rc->context); s = (*TheCallbackFunctions.rc_open)(strName(rc->name), rc_class, mode); (*TheCallbackFunctions.setHostContext)(savedcontext); } else s = (*TheCallbackFunctions.rc_open)(strName(rc->name), rc_class, mode); if ( !s ) errorPce(obj, NAME_openFile, mode[0] == 'r' ? NAME_read : NAME_write, getOsErrorPce(PCE)); return s; } else { int flags = SIO_TEXT|SIO_RECORDPOS; OpenObject h; IOSTREAM *stream; switch(mode[0]) { case 'r': flags |= SIO_INPUT; break; case 'w': flags |= SIO_OUTPUT; break; default: errno = EINVAL; return NULL; } for(mode++; *mode; mode++) { switch(*mode) { case 'b': /* binary */ flags &= ~SIO_TEXT; break; case 'r': /* no record */ flags &= ~SIO_RECORDPOS; break; default: errno = EINVAL; return NULL; } } h = alloc(sizeof(*h)); h->point = 0; h->object = obj; addCodeReference(obj); stream = Snew(h, flags, &Sobjectfunctions); if ( (flags&SIO_TEXT) ) stream->encoding = ENC_WCHAR; /* see comment above */ else stream->encoding = ENC_OCTET; h->encoding = stream->encoding; return stream; } }