int wdelch(WINDOW *win) { chtype *temp1, *temp2; chtype *end; int cury = win->_cury; short curx = win->_curx; chtype *cp; int s; end = &win->_y[cury][win->_maxx - 1]; temp2 = &win->_y[cury][curx + 1]; temp1 = temp2 - 1; s = 1; win->_nbyte = -1; if (_scrmax > 1) { if (ISMBIT(*temp1)) { win->_insmode = TRUE; if (_mbvalid(win) == ERR) return (ERR); curx = win->_curx; temp1 = &win->_y[cury][curx]; } if (ISMBIT(*end)) { for (cp = end; cp >= temp1; --cp) if (!ISCBIT(*cp)) break; if (cp + _curs_scrwidth[TYPE(*cp)] > end+1) end = cp - 1; } if (ISMBIT(*temp1)) s = _curs_scrwidth[TYPE(RBYTE(*temp1))]; end -= s - 1; temp2 = &win->_y[cury][curx+s]; } while (temp1 < end) *temp1++ = *temp2++; while (s--) *temp1++ = win->_bkgd; #ifdef _VR3_COMPAT_CODE if (_y16update) (*_y16update)(win, 1, win->_maxx - curx, cury, curx); #endif /* _VR3_COMPAT_CODE */ win->_lastch[cury] = win->_maxx - 1; if (win->_firstch[cury] > curx) win->_firstch[cury] = curx; win->_flags |= _WINCHANGED; if (win->_sync) wsyncup(win); return (win->_immed ? wrefresh(win) : OK); }
/** * Checks if given stroke colour is already set in PDF gstate and if not, * update the gstate accordingly. * \param page PDF page where the update needs to happen. * \param col Wanted stroke colour. */ void pdfw_gs_strokecolour(HPDF_Page page, colour col) { if (col == pdfw_gs[pdfw_gs_level].strokeColour) return; pdfw_gs[pdfw_gs_level].strokeColour = col; if (RBYTE(col) == GBYTE(col) && GBYTE(col) == BBYTE(col)) HPDF_Page_SetGrayStroke(pdf_page, R(col)); else HPDF_Page_SetRGBStroke(pdf_page, R(col), G(col), B(col)); }
/** * Checks if given fill colour is already set in PDF gstate and if not, * update the gstate accordingly. * \param page PDF page where the update needs to happen. * \param col Wanted fill colour. */ void pdfw_gs_fillcolour(HPDF_Page page, colour col) { if (col == pdfw_gs[pdfw_gs_level].fillColour) return; pdfw_gs[pdfw_gs_level].fillColour = col; if (RBYTE(col) == GBYTE(col) && GBYTE(col) == BBYTE(col)) HPDF_Page_SetGrayFill(pdf_page, R(col)); else HPDF_Page_SetRGBFill(pdf_page, R(col), G(col), B(col)); }
int winwstr(WINDOW *win, wchar_t *wstr) { int counter = 0; int cy = win->_cury; chtype *ptr = &(win->_y[cy][win->_curx]), *pmax = &(win->_y[cy][win->_maxx]); chtype *p1st = &(win->_y[cy][0]); wchar_t wc; int sw, s; char *cp, cbuf[CSMAX+1]; while (ISCBIT(*ptr) && (p1st < ptr)) ptr--; while (ptr < pmax) { wc = RBYTE(*ptr); sw = mbscrw((int)wc); (void) mbeucw((int)wc); cp = cbuf; for (s = 0; s < sw; s++, ptr++) { if ((wc = RBYTE(*ptr)) == MBIT) continue; /* LINTED */ *cp++ = (char) wc; if ((wc = LBYTE(*ptr) | MBIT) == MBIT) continue; /* LINTED */ *cp++ = (char) wc; } *cp = '\0'; if (_curs_mbtowc(&wc, cbuf, CSMAX) <= 0) break; *wstr++ = wc; } *wstr = (wchar_t)0; return (counter); }
int mbcharlen(char *sp) { int n, m, k, ty; chtype c; n = 0; for (; *sp != '\0'; ++sp, ++n) if (ISMBIT(*sp)) { c = RBYTE(*sp); ty = TYPE(c & 0377); m = cswidth[ty] - (ty == 0 ? 1 : 0); for (sp += 1, k = 1; *sp != '\0' && k <= m; ++k, ++sp) { c = RBYTE(*sp); if (TYPE(c) != 0) break; } if (k <= m) break; } return (n); }
/* ** Incoming on the ROUTE_RUP ** I wrote this while I was tired. Forgive me. */ int RIORouteRup( struct rio_info *p, uint Rup, struct Host *HostP, PKT *PacketP ) { struct PktCmd *PktCmdP = (struct PktCmd *)PacketP->data; struct PktCmd_M *PktReplyP; struct CmdBlk *CmdBlkP; struct Port *PortP; struct Map *MapP; struct Top *TopP; int ThisLink, ThisLinkMin, ThisLinkMax; int port; int Mod, Mod1, Mod2; ushort RtaType; uint RtaUniq; uint ThisUnit, ThisUnit2; /* 2 ids to accommodate 16 port RTA */ uint OldUnit, NewUnit, OldLink, NewLink; char *MyType, *MyName; int Lies; unsigned long flags; #ifdef STACK RIOStackCheck("RIORouteRup"); #endif #ifdef CHECK CheckPacketP(PacketP); CheckHostP(HostP); CheckRup(Rup); CheckHost(Host); #endif /* ** Is this unit telling us it's current link topology? */ if ( RBYTE(PktCmdP->Command) == ROUTE_TOPOLOGY ) { MapP = HostP->Mapping; /* ** The packet can be sent either by the host or by an RTA. ** If it comes from the host, then we need to fill in the ** Topology array in the host structure. If it came in ** from an RTA then we need to fill in the Mapping structure's ** Topology array for the unit. */ if ( Rup >= (ushort)MAX_RUP ) { ThisUnit = HOST_ID; TopP = HostP->Topology; MyType = "Host"; MyName = HostP->Name; ThisLinkMin = ThisLinkMax = Rup - MAX_RUP; } else { ThisUnit = Rup+1; TopP = HostP->Mapping[Rup].Topology; MyType = "RTA"; MyName = HostP->Mapping[Rup].Name; ThisLinkMin = 0; ThisLinkMax = LINKS_PER_UNIT - 1; } /* ** Lies will not be tolerated. ** If any pair of links claim to be connected to the same ** place, then ignore this packet completely. */ Lies = 0; for ( ThisLink=ThisLinkMin + 1; ThisLink <= ThisLinkMax; ThisLink++) { /* ** it won't lie about network interconnect, total disconnects ** and no-IDs. (or at least, it doesn't *matter* if it does) */ if ( RBYTE(PktCmdP->RouteTopology[ThisLink].Unit) > (ushort)MAX_RUP ) continue; for ( NewLink=ThisLinkMin; NewLink < ThisLink; NewLink++ ) { if ( (RBYTE(PktCmdP->RouteTopology[ThisLink].Unit) == RBYTE(PktCmdP->RouteTopology[NewLink].Unit)) && (RBYTE(PktCmdP->RouteTopology[ThisLink].Link) == RBYTE(PktCmdP->RouteTopology[NewLink].Link)) ) { Lies++; } } } if ( Lies ) { rio_dprintk (RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n",Lies); rio_dprintk (RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n", RBYTE(PktCmdP->RouteTopology[0].Unit), 'A'+RBYTE(PktCmdP->RouteTopology[0].Link), RBYTE(PktCmdP->RouteTopology[1].Unit), 'A'+RBYTE(PktCmdP->RouteTopology[1].Link), RBYTE(PktCmdP->RouteTopology[2].Unit), 'A'+RBYTE(PktCmdP->RouteTopology[2].Link), RBYTE(PktCmdP->RouteTopology[3].Unit), 'A'+RBYTE(PktCmdP->RouteTopology[3].Link)); return TRUE; } /* ** now, process each link. */ for ( ThisLink=ThisLinkMin; ThisLink <= ThisLinkMax; ThisLink++) { /* ** this is what it was connected to */ OldUnit = TopP[ThisLink].Unit; OldLink = TopP[ThisLink].Link; /* ** this is what it is now connected to */ NewUnit = RBYTE(PktCmdP->RouteTopology[ThisLink].Unit); NewLink = RBYTE(PktCmdP->RouteTopology[ThisLink].Link); if ( OldUnit != NewUnit || OldLink != NewLink ) { /* ** something has changed! */ if ( NewUnit > MAX_RUP && NewUnit != ROUTE_DISCONNECT && NewUnit != ROUTE_NO_ID && NewUnit != ROUTE_INTERCONNECT ) { rio_dprintk (RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n", MyType, MyName, NewUnit, NewLink); } else { /* ** put the new values in */ TopP[ThisLink].Unit = NewUnit; TopP[ThisLink].Link = NewLink; RIOSetChange(p); if ( OldUnit <= MAX_RUP ) { /* ** If something has become bust, then re-enable them messages */ if (! p->RIONoMessage) RIOConCon(p,HostP,ThisUnit,ThisLink,OldUnit,OldLink,DISCONNECT); } if ( ( NewUnit <= MAX_RUP ) && !p->RIONoMessage ) RIOConCon(p,HostP,ThisUnit,ThisLink,NewUnit,NewLink,CONNECT); if ( NewUnit == ROUTE_NO_ID ) rio_dprintk (RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n", MyType,MyName,'A'+ThisLink); if ( NewUnit == ROUTE_INTERCONNECT ) { if (! p->RIONoMessage) cprintf("%s '%s' (%c) is connected to another network.\n", MyType,MyName,'A'+ThisLink); } /* ** perform an update for 'the other end', so that these messages ** only appears once. Only disconnect the other end if it is pointing ** at us! */ if ( OldUnit == HOST_ID ) { if ( HostP->Topology[OldLink].Unit == ThisUnit && HostP->Topology[OldLink].Link == ThisLink ) { rio_dprintk (RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink+'A'); HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT; HostP->Topology[OldLink].Link = NO_LINK; } else { rio_dprintk (RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n", OldLink+'A',HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'); } } else if ( OldUnit <= MAX_RUP ) { if ( HostP->Mapping[OldUnit-1].Topology[OldLink].Unit == ThisUnit && HostP->Mapping[OldUnit-1].Topology[OldLink].Link == ThisLink ) { rio_dprintk (RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n", HostP->Mapping[OldUnit-1].Name,OldLink+'A'); HostP->Mapping[OldUnit-1].Topology[OldLink].Unit=ROUTE_DISCONNECT; HostP->Mapping[OldUnit-1].Topology[OldLink].Link=NO_LINK; } else { rio_dprintk (RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n", HostP->Mapping[OldUnit-1].Name,OldLink+'A', HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'); } } if ( NewUnit == HOST_ID ) { rio_dprintk (RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n", NewLink+'A',MyName,ThisLink+'A'); HostP->Topology[NewLink].Unit = ThisUnit; HostP->Topology[NewLink].Link = ThisLink; } else if ( NewUnit <= MAX_RUP ) { rio_dprintk (RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n", HostP->Mapping[NewUnit-1].Name,NewLink+'A',MyName,ThisLink+'A'); HostP->Mapping[NewUnit-1].Topology[NewLink].Unit=ThisUnit; HostP->Mapping[NewUnit-1].Topology[NewLink].Link=ThisLink; } } RIOSetChange(p); RIOCheckIsolated(p, HostP, OldUnit ); } } return TRUE; } /* ** The only other command we recognise is a route_request command */ if ( RBYTE(PktCmdP->Command) != ROUTE_REQUEST ) { rio_dprintk (RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %d ROUTE_RUP\n", RBYTE(PktCmdP->Command),Rup,(int)HostP); return TRUE; } RtaUniq = (RBYTE(PktCmdP->UniqNum[0])) + (RBYTE(PktCmdP->UniqNum[1]) << 8) + (RBYTE(PktCmdP->UniqNum[2]) << 16) + (RBYTE(PktCmdP->UniqNum[3]) << 24); /* ** Determine if 8 or 16 port RTA */ RtaType = GetUnitType(RtaUniq); rio_dprintk (RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq); Mod = RBYTE(PktCmdP->ModuleTypes); Mod1 = LONYBLE(Mod); if (RtaType == TYPE_RTA16) { /* ** Only one ident is set for a 16 port RTA. To make compatible ** with 8 port, set 2nd ident in Mod2 to the same as Mod1. */ Mod2 = Mod1; rio_dprintk (RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n", p->RIOModuleTypes[Mod1].Name); } else { Mod2 = HINYBLE(Mod); rio_dprintk (RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n", p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name); } if ( RtaUniq == 0xffffffff ) { ShowPacket( DBG_SPECIAL, PacketP ); } /* ** try to unhook a command block from the command free list. */ if ( !(CmdBlkP = RIOGetCmdBlk()) ) { rio_dprintk (RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n"); return 0; } /* ** Fill in the default info on the command block */ CmdBlkP->Packet.dest_unit = Rup; CmdBlkP->Packet.dest_port = ROUTE_RUP; CmdBlkP->Packet.src_unit = HOST_ID; CmdBlkP->Packet.src_port = ROUTE_RUP; CmdBlkP->Packet.len = PKT_CMD_BIT | 1; CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; PktReplyP = (struct PktCmd_M *)CmdBlkP->Packet.data; if (! RIOBootOk(p, HostP, RtaUniq)) { rio_dprintk (RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq); PktReplyP->Command = ROUTE_FOAD; HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7); RIOQueueCmdBlk(HostP, Rup, CmdBlkP); return TRUE; } /* ** Check to see if the RTA is configured for this host */ for ( ThisUnit=0; ThisUnit<MAX_RUP; ThisUnit++ ) { rio_dprintk (RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n", ThisUnit, HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ? "Slot-In-Use":"Not In Use", HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ? "Slot-Tentative":"Not Tentative", HostP->Mapping[ThisUnit].RtaUniqueNum); /* ** We have an entry for it. */ if ( (HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq) ) { if (RtaType == TYPE_RTA16) { ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1; rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n", RtaUniq,ThisUnit,ThisUnit2); } else rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n", RtaUniq,ThisUnit); /* ** If we have no knowledge of booting it, then the host has ** been re-booted, and so we must kill the RTA, so that it ** will be booted again (potentially with new bins) ** and it will then re-ask for an ID, which we will service. */ if ( (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) && !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED) ) { if ( !(HostP->Mapping[ThisUnit].Flags & MSG_DONE) ) { if ( !p->RIONoMessage ) cprintf("RTA '%s' is being updated.\n",HostP->Mapping[ThisUnit].Name); HostP->Mapping[ThisUnit].Flags |= MSG_DONE; } PktReplyP->Command = ROUTE_FOAD; HostP->Copy("RT_FOAD",PktReplyP->CommandText,7); RIOQueueCmdBlk(HostP, Rup, CmdBlkP); return TRUE; } /* ** Send the ID (entry) to this RTA. The ID number is implicit as ** the offset into the table. It is worth noting at this stage ** that offset zero in the table contains the entries for the ** RTA with ID 1!!!! */ PktReplyP->Command = ROUTE_ALLOCATE; PktReplyP->IDNum = ThisUnit+1; if (RtaType == TYPE_RTA16) { if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) /* ** Adjust the phb and tx pkt dest_units for 2nd block of 8 ** only if the RTA has ports associated (SLOT_IN_USE) */ RIOFixPhbs(p, HostP, ThisUnit2); PktReplyP->IDNum2 = ThisUnit2+1; rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2); } else { PktReplyP->IDNum2 = ROUTE_NO_ID; rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum); } HostP->Copy("RT_ALLOCAT",PktReplyP->CommandText,10); RIOQueueCmdBlk( HostP, Rup, CmdBlkP); /* ** If this is a freshly booted RTA, then we need to re-open ** the ports, if any where open, so that data may once more ** flow around the system! */ if ( (HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) && (HostP->Mapping[ThisUnit].SysPort != NO_PORT) ) { /* ** look at the ports associated with this beast and ** see if any where open. If they was, then re-open ** them, using the info from the tty flags. */ for ( port=0; port<PORTS_PER_RTA; port++ ) { PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]; if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) ) { rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n"); rio_spin_lock_irqsave(&PortP->portSem, flags); PortP->MagicFlags |= MAGIC_REBOOT; rio_spin_unlock_irqrestore(&PortP->portSem, flags); } } if (RtaType == TYPE_RTA16) { for ( port=0; port<PORTS_PER_RTA; port++ ) { PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort]; if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) ) { rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n"); rio_spin_lock_irqsave(&PortP->portSem, flags); PortP->MagicFlags |= MAGIC_REBOOT; rio_spin_unlock_irqrestore(&PortP->portSem, flags); } } } } /* ** keep a copy of the module types! */ HostP->UnixRups[ThisUnit].ModTypes = Mod; if (RtaType == TYPE_RTA16) HostP->UnixRups[ThisUnit2].ModTypes = Mod; /* ** If either of the modules on this unit is read-only or write-only ** or none-xprint, then we need to transfer that info over to the ** relevant ports. */ if ( HostP->Mapping[ThisUnit].SysPort != NO_PORT ) { for ( port=0; port<PORTS_PER_MODULE; port++ ) { p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; } if (RtaType == TYPE_RTA16) { for ( port=0; port<PORTS_PER_MODULE; port++ ) { p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; p->RIOPortp[port+PORTS_PER_MODULE+HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; } } } /* ** Job done, get on with the interrupts! */ return TRUE; } } /* ** There is no table entry for this RTA at all. ** ** Lets check to see if we actually booted this unit - if not, ** then we reset it and it will go round the loop of being booted ** we can then worry about trying to fit it into the table. */ for ( ThisUnit=0; ThisUnit<HostP->NumExtraBooted; ThisUnit++ ) if ( HostP->ExtraUnits[ThisUnit] == RtaUniq ) break; if ( ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS ) { /* ** if the unit wasn't in the table, and the table wasn't full, then ** we reset the unit, because we didn't boot it. ** However, if the table is full, it could be that we did boot ** this unit, and so we won't reboot it, because it isn't really ** all that disasterous to keep the old bins in most cases. This ** is a rather tacky feature, but we are on the edge of reallity ** here, because the implication is that someone has connected ** 16+MAX_EXTRA_UNITS onto one host. */ static int UnknownMesgDone = 0; if ( !UnknownMesgDone ) { if (! p->RIONoMessage) cprintf("One or more unknown RTAs are being updated.\n"); UnknownMesgDone = 1; } PktReplyP->Command = ROUTE_FOAD; HostP->Copy("RT_FOAD",PktReplyP->CommandText,7); } else { /* ** we did boot it (as an extra), and there may now be a table ** slot free (because of a delete), so we will try to make ** a tentative entry for it, so that the configurator can see it ** and fill in the details for us. */ if (RtaType == TYPE_RTA16) { if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0) { RIODefaultName(p, HostP, ThisUnit); FillSlot(ThisUnit, ThisUnit2, RtaUniq, HostP); } } else { if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0) { RIODefaultName(p, HostP, ThisUnit); FillSlot(ThisUnit, 0, RtaUniq, HostP); } } PktReplyP->Command = ROUTE_USED; HostP->Copy("RT_USED",PktReplyP->CommandText,7); } RIOQueueCmdBlk( HostP, Rup, CmdBlkP); return TRUE; }
/* * Add ncols worth of data to win, using string as input. * Return the number of chtypes copied. * Note: chtype contains 32/16 bit process code. */ int waddwchnstr(WINDOW *win, chtype *string, int ncols) { int my_x = win->_curx; int my_y = win->_cury; short my_maxx; int counter; chtype *ptr = &(win->_y[my_y][my_x]); chtype *sptr = ptr; char mbbuf[CSMAX+1]; int mp, s, scrw; chtype rawc; chtype attr; short my_x1 = win->_curx; while (ISCBIT(*ptr)) { ptr--; my_x1--; } while (ptr < sptr) *ptr++ = win->_bkgd; if (ncols == -1) ncols = MAXINT; counter = win->_maxx - my_x; while ((ncols > 0) && (*string) && (counter > 0)) { attr = *string & A_WATTRIBUTES; rawc = *string & A_WCHARTEXT; /* conver wchar_t to mbuti byte string */ for (mp = 0; mp < sizeof (mbbuf); mp++) mbbuf[mp] = '\0'; if (_curs_wctomb(mbbuf, rawc) <= 0) goto out; /* if there are no cols on screen, end */ if ((scrw = wcscrw(rawc)) > counter) goto out; if (rawc & WCHAR_CSMASK) { /* store multi-byte string into chtype */ for (s = 0, mp = 0; s < scrw; s++, mp += 2) { *ptr = _CHAR(RBYTE(mbbuf[mp]) | RBYTE(mbbuf[mp + 1]) << 8) | CBIT; SETMBIT(*ptr); if (mp > 0) SETCBIT(*ptr); else CLRCBIT(*ptr); *ptr |= attr; ptr++; } } else { /* store single-byte string into chtype */ *ptr = mbbuf[0]; *ptr |= attr; ptr++; } ncols--; string++; counter -= scrw; } out : while (ISCBIT(*ptr)) *ptr++ = win->_bkgd; /* LINTED */ my_maxx = (short) (ptr - sptr + my_x); if (my_x1 < win->_firstch[my_y]) win->_firstch[my_y] = my_x1; if (my_maxx > win->_lastch[my_y]) win->_lastch[my_y] = my_maxx; win->_flags |= _WINCHANGED; /* sync with ancestor structures */ if (win->_sync) wsyncup(win); return (win->_immed ? wrefresh(win) : OK); }
int wbkgd(WINDOW *win, chtype nbkgd) { short maxx; int x, y; chtype *wcp, obkgda, obkgdc, nbkgda, nbkgdc, acolor, c; short *begch, *endch; /* if 'nbkgd' contains color information, but this is not a color */ /* terminal, erase that information. */ if ((nbkgd & A_COLOR) && (cur_term->_pairs_tbl == NULL)) nbkgd &= ~A_COLOR; if (nbkgd == win->_bkgd) return (OK); obkgdc = _CHAR(win->_bkgd); obkgda = _ATTR(win->_bkgd); nbkgdc = _CHAR(nbkgd); nbkgda = _ATTR(nbkgd); /* switch byte order if necessary */ if (ISCBIT(nbkgdc)) nbkgdc = _CHAR((RBYTE(nbkgdc) << 8) | (LBYTE(nbkgdc)|MBIT)) | CBIT; c = RBYTE(nbkgdc); if ((nbkgdc < ' ' || nbkgdc == _CTRL('?')) || _curs_scrwidth[TYPE(c)] > 1) nbkgdc = obkgdc; nbkgd = (nbkgdc & ~CBIT) | nbkgda; win->_bkgd = nbkgd; /* delete the old background from the attribute field and replace */ /* it with the new background. Note: if the same attribute was */ /* first set by wbkgd() and then by wattron(), or vice versa, it */ /* will be deleted, so the effect of wattron() will be lost. */ /* This applies to both video and color attributes. */ if ((acolor = (win->_attrs & A_COLOR)) != 0) { if (acolor == (obkgda & A_COLOR)) { win->_attrs = _ATTR((win->_attrs & ~obkgda) | nbkgda); } else { win->_attrs = _ATTR((win->_attrs & (~obkgda | A_COLOR)) | (nbkgda & ~A_COLOR)); } } else win->_attrs = _ATTR((win->_attrs & ~obkgda) | nbkgda); maxx = win->_maxx - 1; begch = win->_firstch; endch = win->_lastch; for (y = win->_maxy-1; y >= 0; --y, ++begch, ++endch) { for (x = maxx, wcp = win->_y[y]; x-- >= 0; ++wcp) { if ((c = _CHAR(*wcp)) == obkgdc) c = nbkgdc; if ((acolor = (*wcp & A_COLOR)) != 0) { if (acolor == (obkgda & A_COLOR)) *wcp = c | _ATTR((*wcp & ~obkgda) | nbkgda); else *wcp = c | _ATTR((*wcp & (~obkgda | A_COLOR)) | (nbkgda & ~A_COLOR)); } else *wcp = c | _ATTR((*wcp & ~obkgda) | nbkgda); } *begch = 0; *endch = maxx; } win->_flags |= _WINCHANGED; if (win->_sync) wsyncup(win); return (win->_immed ? wrefresh(win) : OK); }
static void _updateln(int wy) { chtype *wcp, *scp, *wp, *sp, wc, sc; int wx, lastx, x, mtch, idch, blnkx, idcx, video_attrx, color_attrx, maxi, endns, begns, wx_sav, multi_col; bool redraw, changed, didcolor, didvideo; redraw = (_virtscr->_firstch[wy] == _REDRAW); endns = _ENDNS[wy]; begns = _BEGNS[wy]; /* easy case */ if (!redraw && (_virtscr->_lastch[wy] == _BLANK) && (begns >= scrco)) return; /* line images */ wcp = magic_cookie_glitch <= 0 ? _virtscr->_y[wy] : _shove(wy); scp = curscr->_y[wy]; /* the interval to be updated */ if (redraw || magic_cookie_glitch >= 0) { wx = 0; lastx = scrco; } else { wx = _virtscr->_firstch[wy]; lastx = _virtscr->_lastch[wy] == _BLANK ? scrco : _virtscr->_lastch[wy] + 1; } /* skip equal parts */ if (!redraw) { /* skip the starting equal part */ wp = wcp + wx; sp = scp + wx; for (; wx < lastx; ++wx) if (*wp++ != *sp++) break; if (wx >= lastx) return; /* start update at an entire character */ for (sp = scp+wx, wp = wcp+wx; wp > wcp; --wp, --sp, --wx) if (!ISCBIT(*wp) && !ISCBIT(*sp)) break; /* skip the ending equal part */ wp = wcp + lastx - 1; sp = scp + lastx - 1; for (; lastx > wx; --lastx) if (*wp-- != *sp--) break; ++wp; ++wp; ++sp; ++sp; for (; lastx < scrco; ++wp, ++sp, ++lastx) if (!ISCBIT(*wp) && !ISCBIT(*sp)) break; } /* place to do clear-eol */ if (!clr_eol || endns >= lastx) blnkx = scrco; else if (_virtscr->_lastch[wy] == _BLANK) blnkx = -1; else { for (blnkx = lastx - 1, wp = wcp + blnkx; blnkx >= wx; --blnkx, --wp) if (_DARKCHAR(*wp)) break; for (sp = scp + blnkx + 1; blnkx < scrco - 1; ++sp, ++blnkx) if (!ISCBIT(*sp)) break; if (blnkx + _COST(Clr_eol) >= lastx) blnkx = scrco; } /* on cookie terminals, we may need to do more work */ if (marks) { /* video_attrx = color_attrx = scrco; */ video_attrx = color_attrx = (lastx >= scrco) ? lastx - 1 : lastx; /* find the last video attribute on the line */ wp = wcp + video_attrx; for (; video_attrx >= wx; --video_attrx, --wp) if (_VIDEO(*wp) != A_NORMAL) break; /* find the last color attribute on the line */ if (color_marks) { wp = wcp + color_attrx; for (; color_attrx >= wx; --color_attrx, --wp) if (_COLOR(*wp) != A_NORMAL) break; if (color_attrx < lastx) color_attrx++; } if (video_attrx < lastx) video_attrx++; if (video_attrx >= scrco) --video_attrx; if (color_marks && color_attrx >= scrco) --color_attrx; if (magic_cookie_glitch > 0 && wy == scrli - 1 && video_attrx == scrco - 1) --video_attrx; if (color_marks && magic_cookie_glitch > 0 && wy == scrli - 1 && color_attrx == scrco - 1) --color_attrx; for (wp = wcp+video_attrx; wp >= wcp+wx; --wp) if (!ISCBIT(*wp)) break; } /* place for insert/delete chars */ #define SLACK 4 if (redraw || (!SP->dchok && !SP->ichok) || !(_virtscr->_use_idc) || endns < wx || (endns >= lastx && (scrco - lastx) > SLACK)) { idcx = scrco; } else if (!marks) idcx = -1; else { /* on cookie term, only do idch where no attrs */ /* are used */ for (idcx = scrco - 1, wp = wcp + idcx; idcx >= wx; --idcx, --wp) if (_ATTR(*wp) || _ISMARK1(wy, idcx) || _ISMARK2(wy, idcx)) break; if (idcx >= scrco - SLACK) idcx = scrco; } if (idcx < lastx && endns >= lastx) lastx = scrco; /* max amount of insert allow */ if (idcx == scrco || !SP->ichok) maxi = 0; else if (lastx == scrco) maxi = scrco; else maxi = lastx - (endns + 1); /* go */ wcp += wx; scp += wx; didvideo = changed = FALSE; didcolor = (color_marks) ? FALSE : TRUE; while (wx < lastx) { /* skip things that are already right */ if (!redraw) { multi_col = 0; wx_sav = wx; for (; wx < lastx; ++wx, ++wcp, ++scp) if (*wcp != *scp) break; if (wx >= lastx) goto done; for (; wx > wx_sav; --wx, --wcp, --scp) { if (!ISCBIT(*wcp) && !ISCBIT(*scp)) break; multi_col = 1; } } /* try clear-bol, we'll assume exclusive clr_bol */ if (!changed && !marks && clr_bol && blnkx > wx && begns >= wx) { for (x = wx, wp = wcp; x < lastx; ++x, ++wp) if (_DARKCHAR(*wp)) break; /* clearing only whole screen characters */ for (sp = scp+(x-wx); x >= wx; --x, --sp) if (!ISCBIT(*sp)) break; x -= 1; if ((x - (redraw ? 0 : begns)) > _COST(Clr_bol)) { (void) mvcur(cy, cx, wy, x); /* MORE?: colors - mvcur will shuts of */ /* colors when msgr is not defined */ /* SS: colors */ if (back_color_erase) _turn_off_background(); _PUTS(clr_bol, 1); /* LINTED */ cy = (short) wy; /* LINTED */ cx = (short) x; mtch = x - wx; (void) memcpy((char *) scp, (char *) wcp, (mtch * sizeof (chtype))); wcp += mtch; scp += mtch; wx = x; } } /* screen image is changing */ changed = TRUE; /* move to the point to start refresh */ if (cy != wy || cx != wx) (void) mvcur(cy, cx, wy, wx); /* LINTED */ cy = (short) wy; /* LINTED */ cx = (short) wx; /* update screen image */ while (wx < lastx) { wc = *wcp; sc = *scp; if (!redraw && !multi_col && wc == sc) break; /* real video attributes */ if (marks) curscr->_attrs = _ATTR(sc); /* blanks only */ if (wx > blnkx) { /* SS: colors */ if (back_color_erase) _turn_off_background(); _PUTS(clr_eol, 1); /* LINTED */ curscr->_curx = (short) wx; /* LINTED */ curscr->_cury = (short) wy; (void) wclrtoeol(curscr); if (marks && wx > 0 && _ATTR(*(scp - 1)) != A_NORMAL) { _VIDS(A_NORMAL, _ATTR(*(scp - 1))); if (_VIDEO(*scp - 1)) _setmark1(wy, wx, NULL); if (_COLOR(*scp - 1)) _setmark2(wy, wx, NULL); } goto done; } /* try insert/delete chars */ if (wx > idcx && !ISCBIT(*scp) && (mtch = _useidch(wcp, scp, lastx - wx, maxi, &idch))) { maxi -= idch; wx += mtch; scp += mtch; wcp += mtch; break; } /* about to output chars, make sure insert */ /* mode is off */ if (SP->phys_irm) _OFFINSERT(); /* color and video attributes */ if (_ATTR(wc) != curscr->_attrs) { bool color_change = FALSE; bool video_change = FALSE; if (marks) if (_VIDEO(wc) != _VIDEO(curscr->_attrs)) video_change = TRUE; if (color_marks) if (_COLOR(wc) != _COLOR(curscr->_attrs)) color_change = TRUE; /* the following may occurs when, for */ /* example the application */ /* is written for color terminal and then */ /* run on a monocrome */ if (marks && !video_change && !color_change) goto no_change; /* prevent spilling out of line */ if (marks && !(didcolor && didvideo)) { if ((video_change && !_ISMARK1(wy, video_attrx)) || (color_change && !_ISMARK2(wy, color_attrx))) { int tempx; chtype sa = curscr->_attrs; bool first = FALSE; bool second = FALSE; if (!didvideo && video_change && !_ISMARK1(wy, video_attrx)) { didvideo = TRUE; (void) mvcur(wy, wx, wy, video_attrx); _VIDS(_VIDEO(_virtscr->_y[wy] [video_attrx]), _VIDEO(_virtscr->_y[wy] [video_attrx-1])); _setmark1(wy, video_attrx, NULL); first = TRUE; } if (!didcolor && color_change && !_ISMARK2(wy, color_attrx)) { didcolor = TRUE; tempx = first ? video_attrx : wx; if (tempx != color_attrx) (void) mvcur(wy, tempx, wy, color_attrx); /* * sc = _COLOR(curscr->_y[wy][color_attrx]); *_VIDS(sc, (~sc & A_COLOR)); */ _VIDS(_COLOR(_virtscr->_y[wy] [color_attrx]), _COLOR(_virtscr->_y[wy] [color_attrx-1])); _setmark2(wy, color_attrx, NULL); second = TRUE; } (void) mvcur(wy, (second ? color_attrx : video_attrx), wy, wx); curscr->_attrs = sa; } } _VIDS(_ATTR(wc), curscr->_attrs); /* on cookie terminals mark the interval */ if (video_change) _setmark1(wy, wx, scp); if (color_change) _setmark2(wy, wx, scp); } /* end-of-line */ no_change: x = 1; if (_scrmax > 1) x = _curs_scrwidth[TYPE(RBYTE(wc))]; if (wx == scrco - x) { _rmargin(wx); goto done; } if (transparent_underline && erase_overstrike && _CHAR(wc) == '_') { (void) _outch(' '); (void) mvcur(wy, wx + 1, wy, wx); } /* put out the character */ (void) _outwch(tilde_glitch && _CHAR(wc) == '~' ? '`' : wc); *scp++ = wc; wcp++; wx++; cx++; /* output entire multi-byte chars */ while (wx < lastx && ISCBIT(*wcp)) { (void) _outwch(*wcp); *scp++ = *wcp++; wx++; cx++; } } } done: if (changed) { /* update the blank structure */ for (wx = 0, scp = curscr->_y[wy]; wx < scrco; ++wx, ++scp) if (_DARKCHAR(*scp)) break; /* LINTED */ _BEGNS[wy] = (short) wx; if (wx == scrco) _ENDNS[wy] = -1; else { wx = scrco - 1; scp = curscr->_y[wy] + wx; for (; wx >= 0; --wx, --scp) if (_DARKCHAR(*scp)) break; /* LINTED */ _ENDNS[wy] = (short) wx; } /* update the hash structure */ _CURHASH[wy] = _BEGNS[wy] < scrco ? _NOHASH : 0; } }
static void _rmargin(int wx) { int x, w, ix; chtype sc; chtype *wcp = _virtscr->_y[cy]; /* screen may scroll */ if (cy == scrli - 1) { /* can't do anything */ if (!SP->ichok) return; /* the width of the new character */ w = _curs_scrwidth[TYPE(RBYTE(wcp[wx]))]; /* the place to put it without causing scrolling */ for (x = wx - 1; x > 0; --x) if (!ISCBIT(wcp[x])) break; sc = curscr->_y[cy][x]; (void) mvcur(cy, cx, cy, x); if (_ATTR(wcp[wx]) != curscr->_attrs) _VIDS(_ATTR(wcp[wx]), curscr->_attrs); (void) _outwch(tilde_glitch && _CHAR(wcp[wx]) == '~' ? '`' : wcp[wx]); for (ix = wx + 1; ix < scrco; ++ix) { (void) _outwch(wcp[ix]); } /* insert sc back in and push wcp[wx] right */ (void) mvcur(cy, x+w, cy, x); /* SS: colors */ if (back_color_erase) _turn_off_background(); if (SP->imode && !SP->phys_irm) _ONINSERT(); /* width of the old character that was overwritten */ w = _curs_scrwidth[TYPE(RBYTE(curscr->_y[cy][x]))]; if (insert_character) for (ix = 0; ix < w; ++ix) _PUTS(insert_character, 1); else if (parm_ich && !SP->imode) _PUTS(tparm_p1(parm_ich, w), 1); if (_ATTR(sc) != curscr->_attrs) _VIDS(_ATTR(sc), curscr->_attrs); for (ix = x; w > 0; --w, ++ix) (void) _outwch(curscr->_y[cy][ix]); /* make sure the video attrs are ok */ if (marks && (_ATTR(sc) || _ATTR(wcp[wx]))) _VIDS(_ATTR(wcp[wx]), ~_ATTR(sc)); /* update screen image */ /* LINTED */ cx = (short) wx; curscr->_y[cy][wx] = wcp[wx]; for (x = wx + 1; x < scrco; ++x) { (void) _outwch(wcp[x]); curscr->_y[cy][x] = wcp[x]; } return; } /* put char out and update screen image */ (void) _outwch(tilde_glitch && _CHAR(wcp[wx]) == '~' ? '`' : wcp[wx]); curscr->_y[cy][wx] = wcp[wx]; for (x = wx + 1; x < scrco; ++x) { (void) _outwch(wcp[x]); curscr->_y[cy][x] = wcp[x]; } /* make sure that wrap-around happens */ if (!auto_right_margin || eat_newline_glitch) { (void) _outch('\r'); (void) _outch('\n'); } cx = 0; ++cy; }
int copywin(WINDOW *Srcwin, WINDOW *Dstwin, int minRowSrc, int minColSrc, int minRowDst, int minColDst, int maxRowDst, int maxColDst, int over_lay) { int ySrc, yDst, which_copy, t; int height = (maxRowDst - minRowDst) + 1, width = (maxColDst - minColDst) + 1; chtype **_yDst = Dstwin->_y, **_ySrc = Srcwin->_y, bkSrc = Srcwin->_bkgd, atDst = Dstwin->_attrs, *spSrc, *spDst, *epSrc, *epDst, *savepS, *savepD, width_bytes, numcopied; #ifdef DEBUG if (outf) fprintf(outf, "copywin(%0.2o, %0.2o);\n", Srcwin, Dstwin); #endif /* DEBUG */ /* * If we are going to be copying from curscr, * first offset into curscr the offset the Dstwin knows about. */ if (Srcwin == curscr) minRowSrc += Dstwin->_yoffset; /* * There are three types of copy. * 0 - Straight memcpy allowed * 1 - We have to first check to see if the source character is a blank * 2 - Dstwin has attributes or bkgd that must changed * on a char-by-char basis. */ if ((which_copy = (over_lay) ? 1 : (2 * ((Dstwin->_attrs != A_NORMAL) || (Dstwin->_bkgd != _BLNKCHAR)))) == 0) width_bytes = width * (int)sizeof (chtype); /* for each Row */ for (ySrc = minRowSrc, yDst = minRowDst; height-- > 0; ySrc++, yDst++) { if (which_copy) { spSrc = &_ySrc[ySrc][minColSrc]; spDst = &_yDst[yDst][minColDst]; numcopied = width; epSrc = savepS = &_ySrc[ySrc][maxColDst]; epDst = savepD = &_yDst[yDst][maxColDst]; /* only copy into an area bounded by whole characters */ for (; spDst <= epDst; spSrc++, spDst++) if (!ISCBIT(*spDst)) break; if (spDst > epDst) continue; for (; epDst >= spDst; --epDst, --epSrc) if (!ISCBIT(*epDst)) break; t = _curs_scrwidth[TYPE(RBYTE(*epDst))] - 1; if (epDst+t <= savepD) epDst += t, epSrc += t; else epDst -= 1, epSrc -= 1; if (epDst < spDst) continue; /* don't copy partial characters */ for (; spSrc <= epSrc; ++spSrc, ++spDst) if (!ISCBIT(*spSrc)) break; if (spSrc > epSrc) continue; for (; epSrc >= spSrc; --epSrc, --epDst) if (!ISCBIT(*epSrc)) break; t = _curs_scrwidth[TYPE(RBYTE(*epSrc))] - 1; if (epSrc+t <= savepS) epSrc += t, epDst += t; else epSrc -= 1, epDst -= 1; if (epSrc < spSrc) continue; /* make sure that the copied-to place is clean */ if (ISCBIT(*spDst)) (void) _mbclrch(Dstwin, minRowDst, /*LINTED*/ (intptr_t)(spDst - *_yDst[yDst])); if (ISCBIT(*epDst)) (void) _mbclrch(Dstwin, minRowDst, /*LINTED*/ (intptr_t)(epDst - *_yDst[yDst])); /*LINTED*/ numcopied = (chtype) (epDst - spDst + 1); if (which_copy == 1) { /* overlay */ for (; numcopied-- > 0; spSrc++, spDst++) /* Check to see if the char is a "blank/bkgd". */ if (*spSrc != bkSrc) *spDst = *spSrc | atDst; } else { for (; numcopied-- > 0; spSrc++, spDst++) *spDst = *spSrc | atDst; } } else { /* ... copy all chtypes */ (void) memcpy((char *)&_yDst[yDst][minColDst], (char *)&_ySrc[ySrc][minColSrc], width_bytes); } /* note that the line has changed */ if (minColDst < Dstwin->_firstch[yDst]) /*LINTED*/ Dstwin->_firstch[yDst] = (short)minColDst; if (maxColDst > Dstwin->_lastch[yDst]) /*LINTED*/ Dstwin->_lastch[yDst] = (short)maxColDst; } #ifdef _VR3_COMPAT_CODE if (_y16update) { (*_y16update)(Dstwin, (maxRowDst - minRowDst) + 1, (maxColDst - minColDst) + 1, minRowDst, minColDst); } #endif /* _VR3_COMPAT_CODE */ /* note that something in Dstwin has changed */ Dstwin->_flags |= _WINCHANGED; if (Dstwin->_sync) wsyncup(Dstwin); return (Dstwin->_immed ? wrefresh(Dstwin) : OK); }
int waddch(WINDOW *win, chtype c) { short x = win->_curx; short y = win->_cury; chtype rawc = _CHAR(c); chtype rawattrs = _ATTR(c); int rv = OK; bool savimmed = win->_immed; bool savsync = win->_sync; win->_immed = win->_sync = FALSE; #ifdef DEBUG if (outf) if (c == rawc) fprintf(outf, "'%c'", rawc); else fprintf(outf, "'%c' %o, raw %o", c, c, rawc); #endif /* DEBUG */ win->_insmode = FALSE; if (_scrmax > 1 && _mbvalid(win) == ERR) goto next; if (_mbtrue && ISMBIT(rawc)) { rv = _mbaddch(win, rawattrs, RBYTE(rawc)); win->_immed = savimmed; win->_sync = savsync; goto nextw; } switch (rawc) { case '\n': (void) wclrtoeol(win); goto new_line; case '\r': goto move_to_begin_line; case '\b': if (--x < 0) move_to_begin_line: x = 0; win->_curx = x; win->_flags |= _WINMOVED; goto out_move_only; default: if (rawc < ' ' || rawc == _CTRL('?')) { if (rawc == '\t') { int newx; chtype space = ' ' | rawattrs; if ((newx = x + (TABSIZE - (x % TABSIZE))) > win->_maxx) newx = win->_maxx; for (; x < newx; x++) if (waddch(win, space) == ERR) goto next; } else { if ((waddch(win, (chtype) '^'|rawattrs) == ERR) || (waddch(win, (chtype) _UNCTRL(rawc)|rawattrs) == ERR)) { next : rv = ERR; } } x = win->_curx; y = win->_cury; win->_immed = savimmed; win->_sync = savsync; break; } #ifdef DEBUG if ((win->_attrs) && outf) fprintf(outf, "(attrs %o, %o=>%o)", win->_attrs, c, c | win->_attrs); #endif /* DEBUG */ /* clear any partial multi-column character */ if (_scrmax > 1 && ISMBIT(win->_y[y][x]) && (rv = _mbclrch(win, y, x)) == ERR) { x = win->_curx; y = win->_cury; win->_immed = savimmed; win->_sync = savsync; break; } if ((c = _WCHAR(win, c)|rawattrs) != win->_y[y][x]) { if (x < win->_firstch[y]) win->_firstch[y] = x; if (x > win->_lastch[y]) win->_lastch[y] = x; win->_y[y][x] = c; #ifdef _VR3_COMPAT_CODE if (_y16update) /* LINTED */ win->_y16[y][x] = _TO_OCHTYPE(c); #endif /* _VR3_COMPAT_CODE */ } if (++x == win->_maxx) { new_line: if (y == win->_bmarg) { if (wscrl(win, 1) == ERR) { rv = ERR; if (x == win->_maxx) --x; #ifdef DEBUG if (outf) { int i; fprintf(outf, "ERR because " "(%d, %d) > (%d, %d)\n", x, y, win->_maxx, win->_maxy); fprintf(outf, "line: '"); for (i = 0; i < win->_maxy; i++) fprintf(outf, "%c", win->_y[y-1][i]); fprintf(outf, "'\n"); } #endif /* DEBUG */ break; } else savimmed = 1; } else y++; x = 0; } else savimmed += 2; #ifdef FULLDEBUG if (outf) fprintf(outf, "ADDCH: 2: y = %d, x = %d, " "firstch = %d, lastch = %d\n", y, x, win->_firstch[y], win->_lastch[y]); #endif /* FULLDEBUG */ break; } win->_cury = y; win->_curx = x; nextw: /* sync with ancestor structures */ if (win->_sync) wsyncup(win); if (savimmed == 3) return ((*_quick_ptr)(win, c)); win->_flags |= _WINCHANGED; out_move_only: return ((savimmed == 1) ? wrefresh(win) : rv); }