A nyomtatók az egyéb megjelenítő eszközökhöz képest számos eltérő jellemzővel bírnak. E eltérések közé tartozik, hogy a teljes kimenetet diszkrét egységekre, oldalakra bontják valamint, hogy a megjelenítés, leképezés folyamata az egyéb eszközökkel szemben nem pillanatszerűen, hanem adott esetben jelentős időt igénybe véve megy végbe. Szintén a nyomtatás sajátja, hogy a végeredmény megjelenítése nem lokális, hanem távoli, a hálózaton keresztül elért eszközön is végbemehet.

E eltéréseknek megfelelően a GDI függvénykészlete a standardhoz képest számos olyan eljárással is kibővül, amelyek kizárólag a nyomtatókkal, nyomtatással kapcsolatos folyamatok és egyedi jellemzők manipulálását, lekérdezését és megfigyelését teszik lehetővé.

Mint arról már korábban szó volt, a nyomtató-kimenet generálása alapvetően a GDI által biztosított, eszközkörnyezet-alapú absztrakciós interfészen keresztül, a sorozat korábbi részeiben megismert függvények felhasználásával készül. A grafikus kimenetet a nyomtató-meghajtó program alakítja át nyers nyomtató vezérlő-kódokká amelyek aztán a fizikai eszközköz kerülnek továbbításra. Ez utóbbi aztán a vezérlő-kód szekvenciákat dekódolva állítja elő a papíron a végső kimenetet.

A Windows nyomtatási rendszerének logikai architektúráját az alábbi ábra tartalmazza.

A nyomtatómeghajtó program más eszközmeghajtókhoz hasonlóan egy dinamikus csatolású könyvtár, amely a Windows GDI-hez az ún. eszköz-meghajtó interfészen (Device Driver Interface - DDI) keresztül kapcsolódik. E modul feladata az absztrakt GDI interfész a mindenkori nyomtató-hardverhez történő illesztése: annak a GDI által kiadott utasításoknak megfelelő vezérlése, ill. információk szolgáltatása.

A nyomtatóvezérlő mellett a Windows beépített nyomtató rendszere a következő négy fontos elemből épül fel:

  • nyomtatás-vezérlő (print spooler)
  • nyomtatás-feldolgozó (print processor)
  • grafikus motor (graphics engine)
  • csatoló monitor (port monitor)

A nyomtatás-vezérlő

A nyomtatási rendszer központját az ún. nyomtatás-vezérlő modul képezi. E modul feladata a nyomtató-meghajtók lokalizálása, a megfelelő meghajtó programok betöltése, és a nyomtatási feladatok kezelése: azok átvétele az alkalmazásoktól, nyilvántartása, és ütemezése.

Amikor egy alkalmazás megnyit egy nyomtatóhoz kapcsolódó eszközkörnyezetet, vagy létrehoz egy nyomtatási feladatot akkor a nyomtatás-vezérlő megkeresi, majd betölti az adott nyomtatóhoz tartozó eszközmeghajtó programot, és meghatározza a nyomtatási feladat tárolásához használandó adatformátumot.

A nyomtatási feladatokra azért van szükség, mert a nyomtató más eszközökhöz hasonlóan osztott erőforrás, ugyanakkor általában a nyomtatóra szánt kimenet generálása, és a kimenet tényleges elkészítése erősen aszinkron módon történik. Ha más eszközökhöz hasonlóan a programok közvetlenül kezelnék a nyomtatókat, akkor állandóan szinkronizálniuk kellene egymás között az ahhoz történő hozzáférést, ami a nyomtatók előbb említett tulajdonságát tekintve elég komplikált feladat lenne.

E problémát hidalja át a nyomtatás-vezérlő a nyomtatási feladat fogalmának bevezetésével. A megoldás lényege, hogy az alkalmazások nem közvetlenül a nyomtatóval, hanem a nyomtató-vezérlő programmal "beszélgetnek". Amikor az alkalmazás egy nyomtatási kimenet generálásába kezd, akkor azt valójában nem közvetlenül a nyomtatónak, hanem a nyomtatóvezérlőnek küldi el. A nyomtatóvezérlő a kimenetet valamilyen köztes formátumban a merevlemezen vagy a memóriában tárolja, és amikor a nyomtató elérhetővé és/vagy szabaddá válik (pl. az előző feladat kinyomtatása befejeződött), akkor küldi el ténylegesen az adatokat a nyomtató felé. Amennyiben a nyomtató már a nyomtatás megkezdésének pillanatában is azonnal elérhető, a kimenet abban az esetben is pufferelésre kerül, ám az oldalak befejeztével azok azonnal továbbításra kerülnek a nyomtató felé.

Így a nyomtató-vezérlő alapvetően három funkciót lát el:

  • szinkronizálja az alkalmazások hozzáférését az osztott nyomtatóhoz úgy, hogy az esetlegesen párhuzamosan érkező nyomtatási feladatokat sorba állítja, és egymás után küldi el a nyomtatónak
  • puffereli az alkalmazások által generált nyomtatási feladatokat egészen addig, amíg a nyomtató nem képes azok feldolgozására, ezáltal biztosítva a háttérben történő nyomtatás egyszerű megvalósítását (amikor is a nyomtatási kimenet legenerálása után a programok azonnal képesek lesznek újabb feladatok elvégzésére, miközben esetleg a nyomtatás tényleges elvégzésére csak jóval később kerül sor, vagy jelentősen hosszabb ideig tart)
  • biztosítja a nyomtatási feladatok felügyeletét: azok megszakításának, törlésének, vagy éppen szüneteltetés utáni újraindításának lehetőségét
A nyomtatásvezérlő alapállapotban három köztes formátum használatát támogatja, amelyek azonban kiegészitő meghajtók és feldolgozók segítségével tetszőlegesen bővíthetők. Az alapértelmezett formátum az EMF (Enhanced MetaFile - Fejlesztett Metafájl) ami a már korábban megismert metafájl formátumban tárolja a nyomtatási kimenetet. E formátum lényege, hogy a tényleges leképezés a kimeneti eszközre csakis a tényleges nyomtatás (az oldal a fizikai eszközre történő elküldése) pillanatában zajlik. Az alapformátumok között található még a tisztán szöveges információk tárolásához használt ASCII, valamint a RAW (nyers) formátum is. Utóbbin a nyomtatásvezérlő már semmilyen további feldolgozást nem végez, így lehetővé téve nyomtató-specifikus szekvenciák (pl. PostScript, PCL, stb.) használatát a kimenetben.

Az alkalmazások a nyomtatási feladatokat a StartDoc() függvényhívással kezdik, és az EndDoc() hívással zárják. Továbbá minden lap elején és végén a StartPage() ill. EndPage() függvényeket hívják meg, ezáltal a teljes dokumentumot diszkrét lapokra "darabolva". A GDI utasítások közé tetszőleges egyedi, eszközfüggő szekvenciákat is szúrhatnak az Escape() ill. ExtEscape() függvények felhasználásával, amely azonban értelemszerűen eszközfüggővé teszi az amúgy teljes eszközfüggetlen kimenetet. A már megkezdett nyomtatási folyamat megszakítása az AbortDoc() hívás segítségével lehetséges, amelynek hatására a nyomtatásvezérlő törli az adott feladatot a sorból.

A nyomtatás-feldolgozó

Amikor a nyomtató szabaddá/elérhetővé válik a nyomtatás-vezérlő előveszi a következő feldolgozandó nyomtatási feladatot és a megfelelő nyomtatás-feldolgozóhoz továbbítja. A nyomtatás-feldolgozó feladata a köztes formátumban (EMF, RAW, stb.) tárolt kimenet feldolgozása és az annak megfelelő kimenet legenerálása a nyomtató-meghajtó program felhasználásával, tehát a kimenet eszköz-függő szekvenciákká történő átalakítása.

A nyomtatás-feldolgozó szorosan együttműködik a nyomtató-meghajtó programmal, így általában azzal együtt kerül a rendszerben telepítésre.

A legtöbb nyomtató-meghajtó ún. minidriver program, amely valójában a Windows beépített nyomtatás-feldolgozó és általános nyomtató-meghajtó moduljaira épít ill. az azok által létrehozott architektúrába épül be, és amely kizárólag a GDI hívások eszköz-specifikus vezérlőszekvenciákká történő átalakítását végzi, de a nyomtatóval közvetlen kapcsolatban nem áll.

A grafikus motor

A grafikus motor feladata a beépített nyomtatás-feldolgozó kimenetének eszközmeghajtó hívásokká történő átalakítása. E hívások sorozatát tároló folyamot szokás ún. journal fájlnak hívni.

Az eszközmeghajtó program feladat e journal fájl feldolgozása, az azokban tárolt eszközfüggő hívások az eszköz által közvetlenül értelmezhető parancsokká történő átalakítása. Az így előálló kimenet készen áll a nyomtatóhoz történő elküldésre, amelynek ütemezését szintén a nyomtatás-vezérlő végzi el.

Csatoló monitor

A csatoló monitor a nyomtatóhoz kapcsolódó fizikai csatoló eszközt vezérlő modul. Feladata a nyomtatómeghajtó által előállított eszközvezérlő parancsokból álló folyam továbbítása a fizikai nyomtató eszközhöz. E továbbítás történhet soros ill. párhuzamos porton, hálózaton, vagy egyedi csatolómonitor telepítésével bármilyen egyéb kommunikációs eszközön keresztül.

(folytatjuk)